Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit149ed87

Browse files
committed
Move routines to manipulate WAL into PostgreSQL::Test::Cluster
These facilities were originally in the recovery TAP test039_end_of_wal.pl. A follow-up bug fix with a TAP test doing similarWAL manipulations requires them, and all these had better not beduplicated due to their complexity. The routine names are tweaked touse "wal" more consistently, similarly to the existing "advance_wal".In v14 and v13, the new routines are moved to PostgresNode.pm.039_end_of_wal.pl is updated to use the refactored routines, withoutchanging its coverage.Reviewed-by: Alexander KukushkinDiscussion:https://postgr.es/m/CAFh8B=mozC+e1wGJq0H=0O65goZju+6ab5AU7DEWCSUA2OtwDg@mail.gmail.comBackpatch-through: 13
1 parenta0dfeae commit149ed87

File tree

2 files changed

+214
-191
lines changed

2 files changed

+214
-191
lines changed

‎src/test/perl/PostgreSQL/Test/Cluster.pm

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2837,6 +2837,154 @@ sub lsn
28372837

28382838
=pod
28392839
2840+
=item$node->write_wal($tli, $lsn, $segment_size, $data)
2841+
2842+
Write some arbitrary data in WAL for the given segment at $lsn (in bytes).
2843+
This should be called while the cluster is not running.
2844+
2845+
Returns the path of the WAL segment written to.
2846+
2847+
=cut
2848+
2849+
subwrite_wal
2850+
{
2851+
my ($self,$tli,$lsn,$segment_size,$data) =@_;
2852+
2853+
# Calculate segment number and offset position in segment based on the
2854+
# input LSN.
2855+
my$segment =$lsn /$segment_size;
2856+
my$offset =$lsn %$segment_size;
2857+
my$path =
2858+
sprintf("%s/pg_wal/%08X%08X%08X",$self->data_dir,$tli, 0,$segment);
2859+
2860+
openmy$fh,"+<:raw",$pathordie"could not open WAL segment$path";
2861+
seek($fh,$offset, SEEK_SET)ordie"could not seek WAL segment$path";
2862+
print$fh$data;
2863+
close$fh;
2864+
2865+
return$path;
2866+
}
2867+
2868+
=pod
2869+
2870+
=item$node->emit_wal($size)
2871+
2872+
Emit a WAL record of arbitrary size, using pg_logical_emit_message().
2873+
2874+
Returns the end LSN of the record inserted, in bytes.
2875+
2876+
=cut
2877+
2878+
subemit_wal
2879+
{
2880+
my ($self,$size) =@_;
2881+
2882+
returnint(
2883+
$self->safe_psql(
2884+
'postgres',
2885+
"SELECT pg_logical_emit_message(true, '', repeat('a',$size)) - '0/0'"
2886+
));
2887+
}
2888+
2889+
2890+
# Private routine returning the current insert LSN of a node, in bytes.
2891+
# Used by the routines below in charge of advancing WAL to arbitrary
2892+
# positions. The insert LSN is returned in bytes.
2893+
sub_get_insert_lsn
2894+
{
2895+
my ($self) =@_;
2896+
returnint(
2897+
$self->safe_psql(
2898+
'postgres',"SELECT pg_current_wal_insert_lsn() - '0/0'"));
2899+
}
2900+
2901+
=pod
2902+
2903+
=item$node->advance_wal_out_of_record_splitting_zone($wal_block_size)
2904+
2905+
Advance WAL at the end of a page, making sure that we are far away enough
2906+
from the end of a page that we could insert a couple of small records.
2907+
2908+
This inserts a few records of a fixed size, until the threshold gets close
2909+
enough to the end of the WAL page inserting records to.
2910+
2911+
Returns the end LSN up to which WAL has advanced, in bytes.
2912+
2913+
=cut
2914+
2915+
subadvance_wal_out_of_record_splitting_zone
2916+
{
2917+
my ($self,$wal_block_size) =@_;
2918+
2919+
my$page_threshold =$wal_block_size / 4;
2920+
my$end_lsn =$self->_get_insert_lsn();
2921+
my$page_offset =$end_lsn %$wal_block_size;
2922+
while ($page_offset >=$wal_block_size -$page_threshold)
2923+
{
2924+
$self->emit_wal($page_threshold);
2925+
$end_lsn =$self->_get_insert_lsn();
2926+
$page_offset =$end_lsn %$wal_block_size;
2927+
}
2928+
return$end_lsn;
2929+
}
2930+
2931+
=pod
2932+
2933+
=item$node->advance_wal_to_record_splitting_zone($wal_block_size)
2934+
2935+
Advance WAL so close to the end of a page that an XLogRecordHeader would not
2936+
fit on it.
2937+
2938+
Returns the end LSN up to which WAL has advanced, in bytes.
2939+
2940+
=cut
2941+
2942+
subadvance_wal_to_record_splitting_zone
2943+
{
2944+
my ($self,$wal_block_size) =@_;
2945+
2946+
# Size of record header.
2947+
my$RECORD_HEADER_SIZE = 24;
2948+
2949+
my$end_lsn =$self->_get_insert_lsn();
2950+
my$page_offset =$end_lsn %$wal_block_size;
2951+
2952+
# Get fairly close to the end of a page in big steps
2953+
while ($page_offset <=$wal_block_size - 512)
2954+
{
2955+
$self->emit_wal($wal_block_size -$page_offset - 256);
2956+
$end_lsn =$self->_get_insert_lsn();
2957+
$page_offset =$end_lsn %$wal_block_size;
2958+
}
2959+
2960+
# Calibrate our message size so that we can get closer 8 bytes at
2961+
# a time.
2962+
my$message_size =$wal_block_size - 80;
2963+
while ($page_offset <=$wal_block_size -$RECORD_HEADER_SIZE)
2964+
{
2965+
$self->emit_wal($message_size);
2966+
$end_lsn =$self->_get_insert_lsn();
2967+
2968+
my$old_offset =$page_offset;
2969+
$page_offset =$end_lsn %$wal_block_size;
2970+
2971+
# Adjust the message size until it causes 8 bytes changes in
2972+
# offset, enough to be able to split a record header.
2973+
my$delta =$page_offset -$old_offset;
2974+
if ($delta > 8)
2975+
{
2976+
$message_size -= 8;
2977+
}
2978+
elsif ($delta <= 0)
2979+
{
2980+
$message_size += 8;
2981+
}
2982+
}
2983+
return$end_lsn;
2984+
}
2985+
2986+
=pod
2987+
28402988
=item$node->wait_for_event(backend_type, wait_event_name)
28412989
28422990
Poll pg_stat_activity until backend_type reaches wait_event_name.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp