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

Commit50406b1

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 parent02e6931 commit50406b1

File tree

2 files changed

+214
-197
lines changed

2 files changed

+214
-197
lines changed

‎src/test/perl/PostgresNode.pm

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

25112511
=pod
25122512
2513+
=item$node->write_wal($tli, $lsn, $segment_size, $data)
2514+
2515+
Write some arbitrary data in WAL for the given segment at $lsn (in bytes).
2516+
This should be called while the cluster is not running.
2517+
2518+
Returns the path of the WAL segment written to.
2519+
2520+
=cut
2521+
2522+
subwrite_wal
2523+
{
2524+
my ($self,$tli,$lsn,$segment_size,$data) =@_;
2525+
2526+
# Calculate segment number and offset position in segment based on the
2527+
# input LSN.
2528+
my$segment =$lsn /$segment_size;
2529+
my$offset =$lsn %$segment_size;
2530+
my$path =
2531+
sprintf("%s/pg_wal/%08X%08X%08X",$self->data_dir,$tli, 0,$segment);
2532+
2533+
openmy$fh,"+<:raw",$pathordie"could not open WAL segment$path";
2534+
seek($fh,$offset, SEEK_SET)ordie"could not seek WAL segment$path";
2535+
print$fh$data;
2536+
close$fh;
2537+
2538+
return$path;
2539+
}
2540+
2541+
=pod
2542+
2543+
=item$node->emit_wal($size)
2544+
2545+
Emit a WAL record of arbitrary size, using pg_logical_emit_message().
2546+
2547+
Returns the end LSN of the record inserted, in bytes.
2548+
2549+
=cut
2550+
2551+
subemit_wal
2552+
{
2553+
my ($self,$size) =@_;
2554+
2555+
returnint(
2556+
$self->safe_psql(
2557+
'postgres',
2558+
"SELECT pg_logical_emit_message(true, '', repeat('a',$size)) - '0/0'"
2559+
));
2560+
}
2561+
2562+
2563+
# Private routine returning the current insert LSN of a node, in bytes.
2564+
# Used by the routines below in charge of advancing WAL to arbitrary
2565+
# positions. The insert LSN is returned in bytes.
2566+
sub_get_insert_lsn
2567+
{
2568+
my ($self) =@_;
2569+
returnint(
2570+
$self->safe_psql(
2571+
'postgres',"SELECT pg_current_wal_insert_lsn() - '0/0'"));
2572+
}
2573+
2574+
=pod
2575+
2576+
=item$node->advance_wal_out_of_record_splitting_zone($wal_block_size)
2577+
2578+
Advance WAL at the end of a page, making sure that we are far away enough
2579+
from the end of a page that we could insert a couple of small records.
2580+
2581+
This inserts a few records of a fixed size, until the threshold gets close
2582+
enough to the end of the WAL page inserting records to.
2583+
2584+
Returns the end LSN up to which WAL has advanced, in bytes.
2585+
2586+
=cut
2587+
2588+
subadvance_wal_out_of_record_splitting_zone
2589+
{
2590+
my ($self,$wal_block_size) =@_;
2591+
2592+
my$page_threshold =$wal_block_size / 4;
2593+
my$end_lsn =$self->_get_insert_lsn();
2594+
my$page_offset =$end_lsn %$wal_block_size;
2595+
while ($page_offset >=$wal_block_size -$page_threshold)
2596+
{
2597+
$self->emit_wal($page_threshold);
2598+
$end_lsn =$self->_get_insert_lsn();
2599+
$page_offset =$end_lsn %$wal_block_size;
2600+
}
2601+
return$end_lsn;
2602+
}
2603+
2604+
=pod
2605+
2606+
=item$node->advance_wal_to_record_splitting_zone($wal_block_size)
2607+
2608+
Advance WAL so close to the end of a page that an XLogRecordHeader would not
2609+
fit on it.
2610+
2611+
Returns the end LSN up to which WAL has advanced, in bytes.
2612+
2613+
=cut
2614+
2615+
subadvance_wal_to_record_splitting_zone
2616+
{
2617+
my ($self,$wal_block_size) =@_;
2618+
2619+
# Size of record header.
2620+
my$RECORD_HEADER_SIZE = 24;
2621+
2622+
my$end_lsn =$self->_get_insert_lsn();
2623+
my$page_offset =$end_lsn %$wal_block_size;
2624+
2625+
# Get fairly close to the end of a page in big steps
2626+
while ($page_offset <=$wal_block_size - 512)
2627+
{
2628+
$self->emit_wal($wal_block_size -$page_offset - 256);
2629+
$end_lsn =$self->_get_insert_lsn();
2630+
$page_offset =$end_lsn %$wal_block_size;
2631+
}
2632+
2633+
# Calibrate our message size so that we can get closer 8 bytes at
2634+
# a time.
2635+
my$message_size =$wal_block_size - 80;
2636+
while ($page_offset <=$wal_block_size -$RECORD_HEADER_SIZE)
2637+
{
2638+
$self->emit_wal($message_size);
2639+
$end_lsn =$self->_get_insert_lsn();
2640+
2641+
my$old_offset =$page_offset;
2642+
$page_offset =$end_lsn %$wal_block_size;
2643+
2644+
# Adjust the message size until it causes 8 bytes changes in
2645+
# offset, enough to be able to split a record header.
2646+
my$delta =$page_offset -$old_offset;
2647+
if ($delta > 8)
2648+
{
2649+
$message_size -= 8;
2650+
}
2651+
elsif ($delta <= 0)
2652+
{
2653+
$message_size += 8;
2654+
}
2655+
}
2656+
return$end_lsn;
2657+
}
2658+
2659+
=pod
2660+
25132661
=item$node->wait_for_catchup(standby_name, mode, target_lsn)
25142662
25152663
Wait for the node with application_name standby_name (usually from node->name,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp