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

Commite546989

Browse files
committed
Add 'no_error' argument to pg_wal_replay_wait()
This argument allow skipping throwing an error. Instead, the result statuscan be obtained using pg_wal_replay_wait_status() function.Catversion is bumped.Reported-by: Michael PaquierDiscussion:https://postgr.es/m/ZtUF17gF0pNpwZDI%40paquier.xyzReviewed-by: Pavel Borisov
1 parent73da6b8 commite546989

File tree

7 files changed

+118
-14
lines changed

7 files changed

+118
-14
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28989,12 +28989,15 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2898928989
</para>
2899028990

2899128991
<table id="recovery-synchronization-procedure-table">
28992-
<title>Recovery Synchronization Procedure</title>
28992+
<title>Recovery Synchronization Procedure and Function</title>
2899328993
<tgroup cols="1">
2899428994
<thead>
2899528995
<row>
2899628996
<entry role="func_table_entry"><para role="func_signature">
28997-
Procedure
28997+
Procedure or Function
28998+
</para>
28999+
<para>
29000+
Type
2899829001
</para>
2899929002
<para>
2900029003
Description
@@ -29010,8 +29013,11 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2901029013
</indexterm>
2901129014
<function>pg_wal_replay_wait</function> (
2901229015
<parameter>target_lsn</parameter> <type>pg_lsn</type>,
29013-
<parameter>timeout</parameter> <type>bigint</type> <literal>DEFAULT</literal> <literal>0</literal>)
29014-
<returnvalue>void</returnvalue>
29016+
<parameter>timeout</parameter> <type>bigint</type> <literal>DEFAULT</literal> <literal>0</literal>,
29017+
<parameter>no_error</parameter> <type>bool</type> <literal>DEFAULT</literal> <literal>false</literal>)
29018+
</para>
29019+
<para>
29020+
Procedure
2901529021
</para>
2901629022
<para>
2901729023
Waits until recovery replays <literal>target_lsn</literal>.
@@ -29022,7 +29028,30 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2902229028
procedure waits until <literal>target_lsn</literal> is reached or
2902329029
the specified <parameter>timeout</parameter> has elapsed.
2902429030
On timeout, or if the server is promoted before
29025-
<literal>target_lsn</literal> is reached, an error is emitted.
29031+
<literal>target_lsn</literal> is reached, an error is emitted,
29032+
as soon as <parameter>no_error</parameter> is false.
29033+
If <parameter>no_error</parameter> is set to true, then the procedure
29034+
doesn't throw errors. The last result status could be read
29035+
with <function>pg_wal_replay_wait_status</function>.
29036+
</para></entry>
29037+
</row>
29038+
29039+
<row>
29040+
<entry role="func_table_entry"><para role="func_signature">
29041+
<indexterm>
29042+
<primary>pg_wal_replay_wait_status</primary>
29043+
</indexterm>
29044+
<function>pg_wal_replay_wait_status</function> ()
29045+
<returnvalue>text</returnvalue>
29046+
</para>
29047+
<para>
29048+
Function
29049+
</para>
29050+
<para>
29051+
Returns the last result status for
29052+
<function>pg_wal_replay_wait</function> procedure. The possible
29053+
values are <literal>success</literal>, <literal>timeout</literal>,
29054+
and <literal>not in recovery</literal>.
2902629055
</para></entry>
2902729056
</row>
2902829057
</tbody>
@@ -29044,7 +29073,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2904429073
<para>
2904529074
<function>pg_wal_replay_wait</function> should be called on standby.
2904629075
If a user calls <function>pg_wal_replay_wait</function> on primary, it
29047-
will error out. However, if <function>pg_wal_replay_wait</function> is
29076+
will error out as soon as <parameter>no_error</parameter> is false.
29077+
However, if <function>pg_wal_replay_wait</function> is
2904829078
called on primary promoted from standby and <literal>target_lsn</literal>
2904929079
was already replayed, then <function>pg_wal_replay_wait</function> just
2905029080
exits immediately.
@@ -29090,6 +29120,20 @@ postgres=# CALL pg_wal_replay_wait('0/306EE20', 100);
2909029120
ERROR: timed out while waiting for target LSN 0/306EE20 to be replayed; current replay LSN 0/306EA60
2909129121
</programlisting>
2909229122

29123+
The same example uses <function>pg_wal_replay_wait</function> with
29124+
<parameter>no_error</parameter> set to true. In this case, the result
29125+
status must be read with <function>pg_wal_replay_wait_status</function>.
29126+
29127+
<programlisting>
29128+
postgres=# CALL pg_wal_replay_wait('0/306EE20', 100, true);
29129+
CALL
29130+
postgres=# SELECT pg_wal_replay_wait_status();
29131+
pg_wal_replay_wait_status
29132+
---------------------------
29133+
timeout
29134+
(1 row)
29135+
</programlisting>
29136+
2909329137
</para>
2909429138

2909529139
<para>

‎src/backend/access/transam/xlogfuncs.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -751,15 +751,18 @@ pg_promote(PG_FUNCTION_ARGS)
751751
PG_RETURN_BOOL(false);
752752
}
753753

754+
staticWaitLSNResultlastWaitLSNResult=WAIT_LSN_RESULT_SUCCESS;
755+
754756
/*
755-
* Waits until recovery replays the target LSN with optional timeout.
757+
* Waits until recovery replays the target LSN with optional timeout. Unless
758+
* 'no_error' provided throws an error on failure
756759
*/
757760
Datum
758761
pg_wal_replay_wait(PG_FUNCTION_ARGS)
759762
{
760763
XLogRecPtrtarget_lsn=PG_GETARG_LSN(0);
761764
int64timeout=PG_GETARG_INT64(1);
762-
WaitLSNResultresult;
765+
boolno_error=PG_GETARG_BOOL(2);
763766

764767
if (timeout<0)
765768
ereport(ERROR,
@@ -800,13 +803,16 @@ pg_wal_replay_wait(PG_FUNCTION_ARGS)
800803
*/
801804
Assert(MyProc->xmin==InvalidTransactionId);
802805

803-
result=WaitForLSNReplay(target_lsn,timeout);
806+
lastWaitLSNResult=WaitForLSNReplay(target_lsn,timeout);
807+
808+
if (no_error)
809+
PG_RETURN_VOID();
804810

805811
/*
806812
* Process the result of WaitForLSNReplay(). Throw appropriate error if
807813
* needed.
808814
*/
809-
switch (result)
815+
switch (lastWaitLSNResult)
810816
{
811817
caseWAIT_LSN_RESULT_SUCCESS:
812818
/* Nothing to do on success */
@@ -832,3 +838,27 @@ pg_wal_replay_wait(PG_FUNCTION_ARGS)
832838

833839
PG_RETURN_VOID();
834840
}
841+
842+
Datum
843+
pg_wal_replay_wait_status(PG_FUNCTION_ARGS)
844+
{
845+
constchar*result_string="";
846+
847+
/* Process the result of WaitForLSNReplay(). */
848+
switch (lastWaitLSNResult)
849+
{
850+
caseWAIT_LSN_RESULT_SUCCESS:
851+
result_string="success";
852+
break;
853+
854+
caseWAIT_LSN_RESULT_TIMEOUT:
855+
result_string="timeout";
856+
break;
857+
858+
caseWAIT_LSN_RESULT_NOT_IN_RECOVERY:
859+
result_string="not in recovery";
860+
break;
861+
}
862+
863+
PG_RETURN_TEXT_P(cstring_to_text(result_string));
864+
}

‎src/backend/access/transam/xlogwait.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
*
33
* xlogwait.c
44
* Implements waiting for the given replay LSN, which is used in
5-
* CALL pg_wal_replay_wait(target_lsn pg_lsn, timeout float8).
5+
* CALL pg_wal_replay_wait(target_lsn pg_lsn,
6+
* timeout float8, no_error bool).
67
*
78
* Copyright (c) 2024, PostgreSQL Global Development Group
89
*

‎src/backend/catalog/system_functions.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,9 @@ CREATE OR REPLACE FUNCTION
414414
json_populate_recordset(base anyelement, from_json json, use_json_as_textboolean DEFAULT false)
415415
RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS100AS'json_populate_recordset' PARALLEL SAFE;
416416

417-
CREATEOR REPLACE PROCEDURE pg_wal_replay_wait(target_lsn pg_lsn, timeout int8 DEFAULT0)
417+
CREATEOR REPLACE PROCEDURE pg_wal_replay_wait(target_lsn pg_lsn,
418+
timeout int8 DEFAULT0,
419+
no_error bool DEFAULT false)
418420
LANGUAGE internalAS'pg_wal_replay_wait';
419421

420422
CREATE OR REPLACEFUNCTIONpg_logical_slot_get_changes(

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/*yyyymmddN */
60-
#defineCATALOG_VERSION_NO202410222
60+
#defineCATALOG_VERSION_NO202410241
6161

6262
#endif

‎src/include/catalog/pg_proc.dat

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6665,8 +6665,13 @@
66656665
{ oid => '8593',
66666666
descr => 'wait for the target LSN to be replayed on standby with an optional timeout',
66676667
proname => 'pg_wal_replay_wait', prokind => 'p', prorettype => 'void',
6668-
proargtypes => 'pg_lsn int8', proargnames => '{target_lsn,timeout}',
6668+
proargtypes => 'pg_lsn int8 bool', proargnames => '{target_lsn,timeout,no_error}',
66696669
prosrc => 'pg_wal_replay_wait' },
6670+
{ oid => '8594',
6671+
descr => 'the last result for pg_wal_replay_wait()',
6672+
proname => 'pg_wal_replay_wait_status', prorettype => 'text',
6673+
proargtypes => '',
6674+
prosrc => 'pg_wal_replay_wait_status' },
66706675

66716676
{ oid => '6224', descr => 'get resource managers loaded in system',
66726677
proname => 'pg_get_wal_resource_managers', prorows => '50', proretset => 't',

‎src/test/recovery/t/043_wal_replay_wait.pl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@
7777
ok($stderr =~/timed out while waiting for target LSN/,
7878
"get timeout on waiting for unreachable LSN");
7979

80+
$output =$node_standby->safe_psql(
81+
'postgres',qq[
82+
CALL pg_wal_replay_wait('${lsn2}', 10, true);
83+
SELECT pg_wal_replay_wait_status();]);
84+
ok($outputeq"success",
85+
"pg_wal_replay_wait_status() returns correct status after successful waiting"
86+
);
87+
$output =$node_standby->safe_psql(
88+
'postgres',qq[
89+
CALL pg_wal_replay_wait('${lsn3}', 10, true);
90+
SELECT pg_wal_replay_wait_status();]);
91+
ok($outputeq"timeout",
92+
"pg_wal_replay_wait_status() returns correct status after timeout");
93+
8094
# 4. Check that pg_wal_replay_wait() triggers an error if called on primary,
8195
# within another function, or inside a transaction with an isolation level
8296
# higher than READ COMMITTED.
@@ -193,6 +207,14 @@
193207

194208
ok(1,'wait for already replayed LSN exits immediately even after promotion');
195209

210+
$output =$node_standby->safe_psql(
211+
'postgres',qq[
212+
CALL pg_wal_replay_wait('${lsn4}', 10, true);
213+
SELECT pg_wal_replay_wait_status();]);
214+
ok($outputeq"not in recovery",
215+
"pg_wal_replay_wait_status() returns correct status after standby promotion"
216+
);
217+
196218
$node_standby->stop;
197219
$node_primary->stop;
198220

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp