From b82d6d59e59e743eb5adf62b06be1aa5f8b64fde Mon Sep 17 00:00:00 2001 From: xueyi Date: Mon, 3 Jul 2023 11:17:05 +0000 Subject: [PATCH 2/3] Add test case for abort transaction across checkpoint. --- ...000_abort_transaction_across_checkpoint.pl | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/test/recovery/t/000_abort_transaction_across_checkpoint.pl diff --git a/src/test/recovery/t/000_abort_transaction_across_checkpoint.pl b/src/test/recovery/t/000_abort_transaction_across_checkpoint.pl new file mode 100644 index 0000000000..47cfdb1907 --- /dev/null +++ b/src/test/recovery/t/000_abort_transaction_across_checkpoint.pl @@ -0,0 +1,95 @@ +use strict; +use warnings; +use PostgreSQL::Test::Utils; +use PostgreSQL::Test::Cluster; +use Test::More; +use Test::More tests => 2; + +sub kill_process +{ + my ($ppid, $process_name) = @_; + my @childs = `ps -o pid,cmd --ppid $ppid` or die "command failed!"; + my $pid = 0; + foreach my $child (@childs) + { + if (index($child, $process_name) > 0) + { + ($pid, ) = split(' ', $child); + print "## kill process ($child) with signal 19\n"; + system_or_bail('kill', '-19', $pid); + last; + } + } + die "Not find process $process_name\n" unless $pid > 0; +} + +my $sql_dir = $ENV{PWD} . '/sql'; +my $regress_db = 'postgres'; + +my $node_primary = PostgreSQL::Test::Cluster->new('primary'); +$node_primary->init(allows_streaming => 1); + +$node_primary->append_conf('postgresql.conf', 'synchronous_commit=on'); +$node_primary->append_conf('postgresql.conf', 'full_page_writes=off'); +$node_primary->append_conf('postgresql.conf', 'log_min_messages=debug2'); + +$node_primary->start; + +my $psql_h = $node_primary->background_psql($regress_db); +# begin an transaction +$psql_h->query_safe(q(begin;)); + +# create one table and insert some data +$psql_h->query_safe( + q( +create table test (id int, name char(128) default 'A'); +insert into test select generate_series(1,64); +)); + +# do a successful commit transaction to flush all the above wal records +my $timeout = 60; +$node_primary->safe_psql( + $regress_db, + "checkpoint;", + timeout => $timeout); + +# sigstop checkpoint: No more checkpoint +kill_process($node_primary->{_pid}, 'checkpointer'); + +# insert more data +$psql_h->query_safe(q(insert into test values (65);)); + +# do a successful commit transaction to flush all the above wal records +$node_primary->safe_psql( + $regress_db, + "create table temp_test (id int);", + timeout => $timeout); + +# sigstop walwriter: do not flush the following abort record +kill_process($node_primary->{_pid}, 'walwriter'); + +# get the file path of test +my $file_path = $psql_h->query_safe(q(select pg_relation_filepath('test');)); +$file_path =~ s/^\s+|\s+$//g; +print "rel file path is $file_path\n"; + +# abort the above transaction +$psql_h->query_safe(q(abort;)); + +# close connection +$psql_h->quit; + +# immediate shutdown primary: do not flush the above abort record +$node_primary->stop('immediate'); + +my $log_location = -s $node_primary->logfile; +# start +$node_primary->start; + +$node_primary->log_check('find invalid page for rel file path', $log_location, + log_like => [qr/page [0-9]+ of relation $file_path does not exist/]); + +$node_primary->log_check('find dropped invalid page for rel file path', $log_location, + log_like => [qr/page [0-9]+ of relation $file_path has been dropped/]); + +$node_primary->stop(); -- 2.19.1.6.gb485710b