006_commit_ts.pl.txt
text/plain
Filename: 006_commit_ts.pl.txt
Type: text/plain
Part: 0
# Copyright (c) 2025, PostgreSQL Global Development Group
# Tests for handling the default char signedness during upgrade.
use strict;
use warnings FATAL => 'all';
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
sub command_output
{
my ($cmd) = @_;
my ($stdout, $stderr);
print("# Running: " . join(" ", @{$cmd}) . "\n");
my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr;
ok($result, "@$cmd exit code 0");
is($stderr, '', "@$cmd no stderr");
return $stdout;
}
# Can be changed to test the other modes
my $mode = $ENV{PG_TEST_PG_UPGRADE_MODE} || '--copy';
# Initialize old cluster
my $old = PostgreSQL::Test::Cluster->new('old');
$old->init;
$old->append_conf('postgresql.conf', 'track_commit_timestamp = on');
$old->start;
$old->command_ok([ 'pgbench', '-i', '-s', '1' ], 'init pgbench');
$old->command_ok([ 'pgbench', '-t', '100', '-j', '2' ], 'pgbench it');
$old->stop;
# Initialize new cluster
my $new = PostgreSQL::Test::Cluster->new('new');
$new->init;
$new->append_conf('postgresql.conf', 'track_commit_timestamp = on');
command_ok(
[
'pg_upgrade', '--no-sync',
'-d', $old->data_dir,
'-D', $new->data_dir,
'-b', $old->config_data('--bindir'),
'-B', $new->config_data('--bindir'),
'-s', $new->host,
'-p', $old->port,
'-P', $new->port,
$mode
],
'run of pg_upgrade');
$new->start;
$new->command_ok([ 'pgbench', '-t', '10' ], 'pgbench it');
$new->stop;
sub xact_commit_ts
{
my ($node) = @_;
my ($oldest, $newest);
my $out = command_output([ 'pg_controldata', '-D', $node->data_dir ]);
if ($out =~ /oldestCommitTsXid:(\d+)/) {
$oldest = $1;
}
if ($out =~ /newestCommitTsXid:(\d+)/) {
$newest= $1;
}
for my $line (grep { /\S/ } split /\n/, $out) {
if ($line =~ /Latest checkpoint's NextXID:/) {
print $line . "\n";
}
if ($line =~ /Latest checkpoint's oldestXID:/) {
print $line . "\n";
}
if ($line =~ /Latest checkpoint's oldestCommitTsXid/) {
print $line . "\n";
}
if ($line =~ /Latest checkpoint's newestCommitTsXid:/) {
print $line . "\n";
}
}
$node->start;
my $res = $node->safe_psql('postgres', "
WITH xids AS (
SELECT v::text::xid AS x
FROM generate_series($oldest, $newest) v
)
SELECT x, pg_xact_commit_timestamp(x::text::xid)
FROM xids;
");
$node->stop;
return grep { /\S/ } split /\n/, $res;
}
my @a = xact_commit_ts($old);
my @b = xact_commit_ts($new);
my %h1 = map { $_ => 1 } @a;
my %h2 = map { $_ => 1 } @b;
#
# All timestamps from the old cluster should appear in the new one.
#
my $count = 0;
print "Commit timestamp only in old cluster:\n";
for my $line (@a) {
unless ($h2{$line}) {
print "$line\n";
$count = $count + 1;
}
}
ok($count == 0, "all the timestamp transferred successfully");
#
# The new cluster should contain timestamps created during the pg_upgrade and
# some more created by the pgbench.
#
print "\nCommit timestamp only in new cluster:\n";
for my $line (@b) {
print "$line\n" unless $h1{$line};
}
done_testing();