Requires N:M multi-map for complete solution

This mapping is unfinished: 302 of 15327 nodes are still unmarked.

Before

…lines 1–190 unchanged (190 lines)
191/*
192 * If necessary, update the local synced slot's metadata based on the data
193 * from the remote slot.
194 *
195 * If no update was needed (the data of the remote slot is the same as the
196 * local slot) return false, otherwise true.
197 *
198 * *found_consistent_snapshot will be true iff the remote slot's LSN or xmin is
199 * modified, and decoding from the corresponding LSN's can reach a
200 * consistent snapshot.
201 *
202 * *remote_slot_precedes will be true if the remote slot's LSN or xmin
203 * precedes locally reserved position.
204 */
205static bool
206update_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid,
207 bool *found_consistent_snapshot,
208 bool *remote_slot_precedes)
209{
210 ReplicationSlot *slot = MyReplicationSlot;
211 bool updated_xmin_or_lsn = false;
212 bool updated_config = false;
213 SlotSyncSkipReason skip_reason = SS_SKIP_NONE;
214
215 Assert(slot->data.invalidated == RS_INVAL_NONE);
216
217 if (found_consistent_snapshot)
218 *found_consistent_snapshot = false;
219
220 if (remote_slot_precedes)
221 *remote_slot_precedes = false;
222
223 /*
224 * Don't overwrite if we already have a newer catalog_xmin and
225 * restart_lsn.
226 */
227 if (remote_slot->restart_lsn < slot->data.restart_lsn ||
…lines 228–258 unchanged (31 lines)
259 errdetail("Synchronization could lead to data loss, because the remote slot needs WAL at LSN %X/%08X and catalog xmin %u, but the standby has LSN %X/%08X and catalog xmin %u.",
260 LSN_FORMAT_ARGS(remote_slot->restart_lsn),
261 remote_slot->catalog_xmin,
262 LSN_FORMAT_ARGS(slot->data.restart_lsn),
263 slot->data.catalog_xmin));
264
265 if (remote_slot_precedes)
266 *remote_slot_precedes = true;
267
268 /*
269 * Skip updating the configuration. This is required to avoid syncing
270 * two_phase_at without syncing confirmed_lsn. Otherwise, the prepared
271 * transaction between old confirmed_lsn and two_phase_at will
272 * unexpectedly get decoded and sent to the downstream after
…lines 273–301 unchanged (29 lines)
302 SpinLockAcquire(&slot->mutex);
303 slot->data.restart_lsn = remote_slot->restart_lsn;
304 slot->data.confirmed_flush = remote_slot->confirmed_lsn;
305 slot->data.catalog_xmin = remote_slot->catalog_xmin;
306 SpinLockRelease(&slot->mutex);
307
308 if (found_consistent_snapshot)
309 *found_consistent_snapshot = true;
310 }
311 else
312 {
313 LogicalSlotAdvanceAndCheckSnapState(remote_slot->confirmed_lsn,
314 found_consistent_snapshot);
315
316 /* Sanity check */
317 if (slot->data.confirmed_flush != remote_slot->confirmed_lsn)
318 ereport(ERROR,
319 errmsg_internal("synchronized confirmed_flush for slot \"%s\" differs from remote slot",
320 remote_slot->name),
321 errdetail_internal("Remote slot has LSN %X/%08X but local slot has LSN %X/%08X.",
322 LSN_FORMAT_ARGS(remote_slot->confirmed_lsn),
323 LSN_FORMAT_ARGS(slot->data.confirmed_flush)));
324
325 /*
326 * If we can't reach a consistent snapshot, the slot won't be
327 * persisted. See update_and_persist_local_synced_slot().
328 */
329 if (found_consistent_snapshot && !(*found_consistent_snapshot))
330 skip_reason = SS_SKIP_NO_CONSISTENT_SNAPSHOT;
331 }
332
333 updated_xmin_or_lsn = true;
334 }
335
336 /* Update slot sync skip stats */
…lines 337–615 unchanged (279 lines)
616 */
617static bool
618update_and_persist_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid,
619 bool *slot_persistence_pending)
620{
621 ReplicationSlot *slot = MyReplicationSlot;
622 bool found_consistent_snapshot = false;
623 bool remote_slot_precedes = false;
624
625 /* Slotsync skip stats are handled in function update_local_synced_slot() */
626 (void) update_local_synced_slot(remote_slot, remote_dbid,
627 &found_consistent_snapshot,
628 &remote_slot_precedes);
629
630 /*
631 * Check if the primary server has caught up. Refer to the comment atop
632 * the file for details on this check.
633 */
634 if (remote_slot_precedes)
635 {
636 /*
637 * The remote slot didn't catch up to locally reserved position.
638 *
639 * We do not drop the slot because the restart_lsn can be ahead of the
640 * current location when recreating the slot in the next cycle. It may
641 * take more time to create such a slot. Therefore, we keep this slot
642 * and attempt the synchronization in the next cycle.
643 *
644 * We also update the slot_persistence_pending parameter, so the SQL
645 * function can retry.
646 */
647 if (slot_persistence_pending)
648 *slot_persistence_pending = true;
649
650 return false;
651 }
652
653 /*
654 * Don't persist the slot if it cannot reach the consistent point from the
655 * restart_lsn. See comments atop this file.
656 */
657 if (!found_consistent_snapshot)
658 {
659 ereport(LOG,
660 errmsg("could not synchronize replication slot \"%s\"", remote_slot->name),
661 errdetail("Synchronization could lead to data loss, because the standby could not build a consistent snapshot to decode WALs at LSN %X/%08X.",
662 LSN_FORMAT_ARGS(slot->data.restart_lsn)));
663
664 /* Set this, so that SQL function can retry */
665 if (slot_persistence_pending)
666 *slot_persistence_pending = true;
667
668 return false;
669 }
670
671 ReplicationSlotPersist();
672
673 ereport(LOG,
674 errmsg("newly created replication slot \"%s\" is sync-ready now",
675 remote_slot->name));
…lines 676–694 unchanged (19 lines)
695 */
696static bool
697synchronize_one_slot(RemoteSlot *remote_slot, Oid remote_dbid,
698 bool *slot_persistence_pending)
699{
700 ReplicationSlot *slot;
701 XLogRecPtr latestFlushPtr = GetStandbyFlushRecPtr(NULL);
702 bool slot_updated = false;
703
704 /* Search for the named slot */
705 if ((slot = SearchNamedReplicationSlot(remote_slot->name, true)))
706 {
707 bool synced;
…lines 708–815 unchanged (108 lines)
816 errmsg_internal("cannot synchronize local slot \"%s\"",
817 remote_slot->name),
818 errdetail_internal("Local slot's start streaming location LSN(%X/%08X) is ahead of remote slot's LSN(%X/%08X).",
819 LSN_FORMAT_ARGS(slot->data.confirmed_flush),
820 LSN_FORMAT_ARGS(remote_slot->confirmed_lsn)));
821
822 slot_updated = update_local_synced_slot(remote_slot, remote_dbid,
823 NULL, NULL);
824 }
825 }
826 /* Otherwise create the slot first. */
827 else
828 {
829 NameData plugin_name;
…lines 830–2052 unchanged (1223 lines)

After

…lines 1–183 unchanged (183 lines)
184 {
185 SpinLockAcquire(&slot->mutex);
186 slot->slotsync_skip_reason = skip_reason;
187 SpinLockRelease(&slot->mutex);
188 }
189}
190
191/*
192 * If necessary, update the local synced slot's metadata based on the data
193 * from the remote slot.
194 *
195 * If no update was needed (the data of the remote slot is the same as the
196 * local slot) return false, otherwise true.
197 */
198static bool
199update_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid)
200{
201 ReplicationSlot *slot = MyReplicationSlot;
202 bool updated_xmin_or_lsn = false;
203 bool updated_config = false;
204 SlotSyncSkipReason skip_reason = SS_SKIP_NONE;
205 XLogRecPtr latestFlushPtr = GetStandbyFlushRecPtr(NULL);
206
207 Assert(slot->data.invalidated == RS_INVAL_NONE);
208
209 /*
210 * Make sure that concerned WAL is received and flushed before syncing
211 * slot to target lsn received from the primary server.
212 */
213 if (remote_slot->confirmed_lsn > latestFlushPtr)
214 {
…lines 215–266 unchanged (52 lines)
267 remote_slot->name),
268 errdetail("Synchronization could lead to data loss, because the remote slot needs WAL at LSN %X/%08X and catalog xmin %u, but the standby has LSN %X/%08X and catalog xmin %u.",
269 LSN_FORMAT_ARGS(remote_slot->restart_lsn),
270 remote_slot->catalog_xmin,
271 LSN_FORMAT_ARGS(slot->data.restart_lsn),
272 slot->data.catalog_xmin));
273
274 /*
275 * Skip updating the configuration. This is required to avoid syncing
276 * two_phase_at without syncing confirmed_lsn. Otherwise, the prepared
277 * transaction between old confirmed_lsn and two_phase_at will
278 * unexpectedly get decoded and sent to the downstream after
279 * promotion. See comments in ReorderBufferFinishPrepared.
…lines 280–306 unchanged (27 lines)
307 */
308 SpinLockAcquire(&slot->mutex);
309 slot->data.restart_lsn = remote_slot->restart_lsn;
310 slot->data.confirmed_flush = remote_slot->confirmed_lsn;
311 slot->data.catalog_xmin = remote_slot->catalog_xmin;
312 SpinLockRelease(&slot->mutex);
313 }
314 else
315 {
316 bool found_consistent_snapshot;
317
318 LogicalSlotAdvanceAndCheckSnapState(remote_slot->confirmed_lsn,
319 &found_consistent_snapshot);
320
321 /* Sanity check */
322 if (slot->data.confirmed_flush != remote_slot->confirmed_lsn)
323 ereport(ERROR,
324 errmsg_internal("synchronized confirmed_flush for slot \"%s\" differs from remote slot",
325 remote_slot->name),
326 errdetail_internal("Remote slot has LSN %X/%08X but local slot has LSN %X/%08X.",
327 LSN_FORMAT_ARGS(remote_slot->confirmed_lsn),
328 LSN_FORMAT_ARGS(slot->data.confirmed_flush)));
329
330 /*
331 * If we can't reach a consistent snapshot, the slot won't be
332 * persisted. See update_and_persist_local_synced_slot().
333 */
334 if (!found_consistent_snapshot)
335 {
336 Assert(MyReplicationSlot->data.persistency == RS_TEMPORARY);
337
338 ereport(LOG,
339 errmsg("could not synchronize replication slot \"%s\"",
340 remote_slot->name),
341 errdetail("Synchronization could lead to data loss, because the standby could not build a consistent snapshot to decode WALs at LSN %X/%08X.",
342 LSN_FORMAT_ARGS(slot->data.restart_lsn)));
343
344 skip_reason = SS_SKIP_NO_CONSISTENT_SNAPSHOT;
345 }
346 }
347
348 updated_xmin_or_lsn = true;
349 }
350
351 /* Update slot sync skip stats */
…lines 352–630 unchanged (279 lines)
631 */
632static bool
633update_and_persist_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid,
634 bool *slot_persistence_pending)
635{
636 ReplicationSlot *slot = MyReplicationSlot;
637
638 /* Slotsync skip stats are handled in function update_local_synced_slot() */
639 (void) update_local_synced_slot(remote_slot, remote_dbid);
640
641 /*
642 * Check if the slot cannot be synchronized. Refer to the comment atop the
643 * file for details on this check.
644 */
645 if (slot->slotsync_skip_reason != SS_SKIP_NONE)
646 {
647 /*
648 * We reach this point when the remote slot didn't catch up to locally
649 * reserved position, or it cannot reach the consistent point from the
650 * restart_lsn, or the WAL prior to the remote confirmed flush LSN has
651 * not been received and flushed.
652 *
653 * We do not drop the slot because the restart_lsn and confirmed_lsn
654 * can be ahead of the current location when recreating the slot in
655 * the next cycle. It may take more time to create such a slot or
656 * reach the consistent point. Therefore, we keep this slot and
657 * attempt the synchronization in the next cycle.
658 *
659 * We also update the slot_persistence_pending parameter, so the SQL
660 * function can retry.
661 */
662 if (slot_persistence_pending)
663 *slot_persistence_pending = true;
664
665 return false;
666 }
667
668 ReplicationSlotPersist();
669
670 ereport(LOG,
671 errmsg("newly created replication slot \"%s\" is sync-ready now",
672 remote_slot->name));
673
…lines 674–783 unchanged (110 lines)
784 errmsg_internal("cannot synchronize local slot \"%s\"",
785 remote_slot->name),
786 errdetail_internal("Local slot's start streaming location LSN(%X/%08X) is ahead of remote slot's LSN(%X/%08X).",
787 LSN_FORMAT_ARGS(slot->data.confirmed_flush),
788 LSN_FORMAT_ARGS(remote_slot->confirmed_lsn)));
789
790 slot_updated = update_local_synced_slot(remote_slot, remote_dbid);
791 }
792 }
793 /* Otherwise create the slot first. */
794 else
795 {
796 NameData plugin_name;
…lines 797–1991 unchanged (1195 lines)

Before

translation_unit
comment "/*----------------------------------------------------------"...
preproc_include
#include "#include"
string_literal
" "\""
string_content "postgres.h"
" "\""
preproc_include
#include "#include"
system_lib_string "<time.h>"
preproc_include
#include "#include"
string_literal
" "\""
string_content "access/xlog_internal.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "access/xlogrecovery.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "catalog/pg_database.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "libpq/pqsignal.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "pgstat.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "postmaster/interrupt.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "replication/logical.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "replication/slotsync.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "replication/snapbuild.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/ipc.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/lmgr.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/proc.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/procarray.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "tcop/tcopprot.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/builtins.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/memutils.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/pg_lsn.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/ps_status.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/timeout.h"
" "\""
comment "/*\n * Struct for sharing information to control slot synchro"...
type_definition (+30 nodes collapsed)
declaration
storage_class_specifier
static "static"
type_identifier "SlotSyncCtxStruct"
init_declarator
pointer_declarator
* "*"
identifier "SlotSyncCtx"
= "="
null
NULL "NULL"
; ";"
comment "/* GUC variable */"
declaration
primitive_type "bool"
init_declarator
identifier "sync_replication_slots"
= "="
false "false"
; ";"
comment "/*\n * The sleep time (ms) between slot-sync cycles varies dy"...
preproc_def
#define "#define"
identifier "MIN_SLOTSYNC_WORKER_NAPTIME_MS"
preproc_arg "200"
preproc_def
#define "#define"
identifier "MAX_SLOTSYNC_WORKER_NAPTIME_MS"
preproc_arg "30000\t"
comment "/* 30s */"
declaration
storage_class_specifier
static "static"
sized_type_specifier
long "long"
init_declarator
identifier "sleep_ms"
= "="
identifier "MIN_SLOTSYNC_WORKER_NAPTIME_MS"
; ";"
comment "/* The restart interval for slot sync work used by postmaste"...
preproc_def
#define "#define"
identifier "SLOTSYNC_RESTART_INTERVAL_SEC"
preproc_arg "10"
comment "/*\n * Flag to tell if we are syncing replication slots. Unli"...
declaration
storage_class_specifier
static "static"
primitive_type "bool"
init_declarator
identifier "syncing_slots"
= "="
false "false"
; ";"
comment "/*\n * Structure to hold information fetched from the primary"...
type_definition (+57 nodes collapsed)
declaration
storage_class_specifier
static "static"
primitive_type "void"
function_declarator
identifier "slotsync_failure_callback"
parameter_list
( "("
parameter_declaration
primitive_type "int"
identifier "code"
, ","
parameter_declaration
type_identifier "Datum"
identifier "arg"
) ")"
; ";"
declaration
storage_class_specifier
static "static"
primitive_type "void"
function_declarator
identifier "update_synced_slots_inactive_since"
parameter_list
( "("
parameter_declaration
primitive_type "void"
) ")"
; ";"
comment "/*\n * Update slot sync skip stats. This function requires th"...
function_definition (+104 nodes collapsed)
comment "/*\n * If necessary, update the local synced slot's metadata "...
function_definition
storage_class_specifier
static "static"
primitive_type "bool"
function_declarator
identifier "update_local_synced_slot"
parameter_list
( "("
parameter_declaration
type_identifier "RemoteSlot"
pointer_declarator
* "*"
identifier "remote_slot"
, ","
parameter_declaration
type_identifier "Oid"
identifier "remote_dbid"
, ","
parameter_declaration
primitive_type "bool"
pointer_declarator
* "*"
identifier "found_consistent_snapshot"
, ","
parameter_declaration
primitive_type "bool"
pointer_declarator
* "*"
identifier "remote_slot_precedes"
) ")"
compound_statement
{ "{"
declaration
type_identifier "ReplicationSlot"
init_declarator
pointer_declarator
* "*"
identifier "slot"
= "="
identifier "MyReplicationSlot"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "updated_xmin_or_lsn"
= "="
false "false"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "updated_config"
= "="
false "false"
; ";"
declaration
type_identifier "SlotSyncSkipReason"
init_declarator
identifier "skip_reason"
= "="
identifier "SS_SKIP_NONE"
; ";"
expression_statement
call_expression
identifier "Assert"
argument_list
( "("
binary_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "invalidated"
== "=="
identifier "RS_INVAL_NONE"
) ")"
; ";"
if_statement
if "if"
parenthesized_expression
( "("
identifier "found_consistent_snapshot"
) ")"
expression_statement
assignment_expression
pointer_expression
* "*"
identifier "found_consistent_snapshot"
= "="
false "false"
; ";"
if_statement
if "if"
parenthesized_expression
( "("
identifier "remote_slot_precedes"
) ")"
expression_statement
assignment_expression
pointer_expression
* "*"
identifier "remote_slot_precedes"
= "="
false "false"
; ";"
comment "/*\n\t * Don't overwrite if we already have a newer catalog_xm"...
if_statement
if "if"
parenthesized_expression (+35 nodes collapsed)
compound_statement
{ "{"
comment "/* Update slot sync skip stats */"
expression_statement
call_expression
identifier "update_slotsync_skip_stats"
argument_list
( "("
identifier "SS_SKIP_WAL_OR_ROWS_REMOVED"
) ")"
; ";"
comment "/*\n\t\t * This can happen in following situations:\n\t\t *\n\t\t * I"...
expression_statement (+86 nodes collapsed)
if_statement
if "if"
parenthesized_expression
( "("
identifier "remote_slot_precedes"
) ")"
expression_statement
assignment_expression
pointer_expression
* "*"
identifier "remote_slot_precedes"
= "="
true "true"
; ";"
comment "/*\n\t\t * Skip updating the configuration. This is required to"...
return_statement
return "return"
false "false"
; ";"
} "}"
comment "/*\n\t * Attempt to sync LSNs and xmins only if remote slot is"...
if_statement
if "if"
parenthesized_expression (+50 nodes collapsed)
compound_statement
{ "{"
comment "/*\n\t\t * We can't directly copy the remote slot's LSN or xmin"...
if_statement
if "if"
parenthesized_expression
( "("
call_expression
identifier "SnapBuildSnapshotExists"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "restart_lsn"
) ")"
) ")"
compound_statement
{ "{"
comment "/*\n\t\t\t * Update the slot info directly if there is a seriali"...
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "restart_lsn"
= "="
field_expression
identifier "remote_slot"
-> "->"
field_identifier "restart_lsn"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "confirmed_flush"
= "="
field_expression
identifier "remote_slot"
-> "->"
field_identifier "confirmed_lsn"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "catalog_xmin"
= "="
field_expression
identifier "remote_slot"
-> "->"
field_identifier "catalog_xmin"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
if_statement
if "if"
parenthesized_expression
( "("
identifier "found_consistent_snapshot"
) ")"
expression_statement
assignment_expression
pointer_expression
* "*"
identifier "found_consistent_snapshot"
= "="
true "true"
; ";"
} "}"
else_clause
else "else"
compound_statement
{ "{"
expression_statement
call_expression
identifier "LogicalSlotAdvanceAndCheckSnapState"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "confirmed_lsn"
, ","
identifier "found_consistent_snapshot"
) ")"
; ";"
comment "/* Sanity check */"
if_statement (+78 nodes collapsed)
comment "/*\n\t\t\t * If we can't reach a consistent snapshot, the slot w"...
if_statement
if "if"
parenthesized_expression
( "("
binary_expression
identifier "found_consistent_snapshot"
&& "&&"
unary_expression
! "!"
parenthesized_expression
( "("
pointer_expression
* "*"
identifier "found_consistent_snapshot"
) ")"
) ")"
expression_statement
assignment_expression
identifier "skip_reason"
= "="
identifier "SS_SKIP_NO_CONSISTENT_SNAPSHOT"
; ";"
} "}"
expression_statement
assignment_expression
identifier "updated_xmin_or_lsn"
= "="
true "true"
; ";"
} "}"
comment "/* Update slot sync skip stats */"
expression_statement
call_expression
identifier "update_slotsync_skip_stats"
argument_list
( "("
identifier "skip_reason"
) ")"
; ";"
if_statement (+235 nodes collapsed)
comment "/*\n\t * We have to write the changed xmin to disk *before* we"...
if_statement (+26 nodes collapsed)
comment "/*\n\t * Now the new xmin is safely on disk, we can let the gl"...
if_statement (+62 nodes collapsed)
return_statement
return "return"
binary_expression
identifier "updated_config"
|| "||"
identifier "updated_xmin_or_lsn"
; ";"
} "}"
comment "/*\n * Get the list of local logical slots that are synchroni"...
function_definition (+135 nodes collapsed)
comment "/*\n * Helper function to check if local_slot is required to "...
function_definition (+163 nodes collapsed)
comment "/*\n * Drop local obsolete slots.\n *\n * Drop the local slots "...
function_definition (+236 nodes collapsed)
comment "/*\n * Reserve WAL for the currently active local slot using "...
function_definition (+242 nodes collapsed)
comment "/*\n * If the remote restart_lsn and catalog_xmin have caught"...
function_definition
storage_class_specifier
static "static"
primitive_type "bool"
function_declarator
identifier "update_and_persist_local_synced_slot"
parameter_list
( "("
parameter_declaration
type_identifier "RemoteSlot"
pointer_declarator
* "*"
identifier "remote_slot"
, ","
parameter_declaration
type_identifier "Oid"
identifier "remote_dbid"
, ","
parameter_declaration
primitive_type "bool"
pointer_declarator
* "*"
identifier "slot_persistence_pending"
) ")"
compound_statement
{ "{"
declaration
type_identifier "ReplicationSlot"
init_declarator
pointer_declarator
* "*"
identifier "slot"
= "="
identifier "MyReplicationSlot"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "found_consistent_snapshot"
= "="
false "false"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "remote_slot_precedes"
= "="
false "false"
; ";"
comment "/* Slotsync skip stats are handled in function update_local_"...
expression_statement
cast_expression
( "("
type_descriptor
primitive_type "void"
) ")"
call_expression
identifier "update_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
, ","
pointer_expression
& "&"
identifier "found_consistent_snapshot"
, ","
pointer_expression
& "&"
identifier "remote_slot_precedes"
) ")"
; ";"
comment "/*\n\t * Check if the primary server has caught up. Refer to t"...
if_statement
if "if"
parenthesized_expression
( "("
identifier "remote_slot_precedes"
) ")"
compound_statement
{ "{"
comment "/*\n\t\t * The remote slot didn't catch up to locally reserved "...
if_statement
if "if"
parenthesized_expression
( "("
identifier "slot_persistence_pending"
) ")"
expression_statement
assignment_expression
pointer_expression
* "*"
identifier "slot_persistence_pending"
= "="
true "true"
; ";"
return_statement
return "return"
false "false"
; ";"
} "}"
comment "/*\n\t * Don't persist the slot if it cannot reach the consist"...
if_statement
if "if"
parenthesized_expression
( "("
unary_expression
! "!"
identifier "found_consistent_snapshot"
) ")"
compound_statement
{ "{"
expression_statement (+49 nodes collapsed)
comment "/* Set this, so that SQL function can retry */"
if_statement
if "if"
parenthesized_expression
( "("
identifier "slot_persistence_pending"
) ")"
expression_statement
assignment_expression
pointer_expression
* "*"
identifier "slot_persistence_pending"
= "="
true "true"
; ";"
return_statement
return "return"
false "false"
; ";"
} "}"
expression_statement
call_expression
identifier "ReplicationSlotPersist"
argument_list
( "("
) ")"
; ";"
expression_statement (+27 nodes collapsed)
return_statement
return "return"
true "true"
; ";"
} "}"
comment "/*\n * Synchronize a single slot to the given position.\n *\n *"...
function_definition
storage_class_specifier
static "static"
primitive_type "bool"
function_declarator
identifier "synchronize_one_slot"
parameter_list
( "("
parameter_declaration
type_identifier "RemoteSlot"
pointer_declarator
* "*"
identifier "remote_slot"
, ","
parameter_declaration
type_identifier "Oid"
identifier "remote_dbid"
, ","
parameter_declaration
primitive_type "bool"
pointer_declarator
* "*"
identifier "slot_persistence_pending"
) ")"
compound_statement
{ "{"
declaration
type_identifier "ReplicationSlot"
pointer_declarator
* "*"
identifier "slot"
; ";"
declaration
type_identifier "XLogRecPtr"
init_declarator
identifier "latestFlushPtr"
= "="
call_expression
identifier "GetStandbyFlushRecPtr"
argument_list
( "("
null
NULL "NULL"
) ")"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "slot_updated"
= "="
false "false"
; ";"
comment "/* Search for the named slot */"
if_statement
if "if"
parenthesized_expression
( "("
parenthesized_expression
( "("
assignment_expression
identifier "slot"
= "="
call_expression
identifier "SearchNamedReplicationSlot"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "name"
, ","
true "true"
) ")"
) ")"
) ")"
compound_statement
{ "{"
declaration
primitive_type "bool"
identifier "synced"
; ";"
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
identifier "synced"
= "="
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "synced"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
comment "/* User-created slot with the same name exists, raise ERROR."...
if_statement (+47 nodes collapsed)
comment "/*\n\t\t * The slot has been synchronized before.\n\t\t *\n\t\t * It "...
expression_statement
call_expression
identifier "ReplicationSlotAcquire"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "name"
, ","
true "true"
, ","
false "false"
) ")"
; ";"
expression_statement
call_expression
identifier "Assert"
argument_list
( "("
binary_expression
identifier "slot"
== "=="
identifier "MyReplicationSlot"
) ")"
; ";"
comment "/*\n\t\t * Copy the invalidation cause from remote only if loca"...
if_statement (+89 nodes collapsed)
comment "/* Skip the sync of an invalidated slot */"
if_statement (+37 nodes collapsed)
comment "/*\n\t\t * Make sure that concerned WAL is received and flushed"...
if_statement (+100 nodes collapsed)
comment "/* Slot not ready yet, let's attempt to make it sync-ready n"...
if_statement
if "if"
parenthesized_expression
( "("
binary_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "persistency"
== "=="
identifier "RS_TEMPORARY"
) ")"
compound_statement
{ "{"
expression_statement
assignment_expression
identifier "slot_updated"
= "="
call_expression
identifier "update_and_persist_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
, ","
identifier "slot_persistence_pending"
) ")"
; ";"
} "}"
comment "/* Slot ready for sync, so sync it. */"
else_clause
else "else"
compound_statement
{ "{"
comment "/*\n\t\t\t * Sanity check: As long as the invalidations are hand"...
if_statement (+77 nodes collapsed)
expression_statement
assignment_expression
identifier "slot_updated"
= "="
call_expression
identifier "update_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
, ","
null
NULL "NULL"
, ","
null
NULL "NULL"
) ")"
; ";"
} "}"
} "}"
comment "/* Otherwise create the slot first. */"
else_clause
else "else"
compound_statement
{ "{"
declaration
type_identifier "NameData"
identifier "plugin_name"
; ";"
declaration
type_identifier "TransactionId"
init_declarator
identifier "xmin_horizon"
= "="
identifier "InvalidTransactionId"
; ";"
comment "/* Skip creating the local slot if remote_slot is invalidate"...
if_statement
if "if"
parenthesized_expression
( "("
binary_expression
field_expression
identifier "remote_slot"
-> "->"
field_identifier "invalidated"
!= "!="
identifier "RS_INVAL_NONE"
) ")"
return_statement
return "return"
false "false"
; ";"
comment "/*\n\t\t * We create temporary slots instead of ephemeral slots"...
expression_statement (+27 nodes collapsed)
comment "/* For shorter lines. */"
expression_statement
assignment_expression
identifier "slot"
= "="
identifier "MyReplicationSlot"
; ";"
comment "/* Avoid expensive operations while holding a spinlock. */"
expression_statement
call_expression
identifier "namestrcpy"
argument_list
( "("
pointer_expression
& "&"
identifier "plugin_name"
, ","
field_expression
identifier "remote_slot"
-> "->"
field_identifier "plugin"
) ")"
; ";"
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "database"
= "="
identifier "remote_dbid"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "plugin"
= "="
identifier "plugin_name"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
call_expression
identifier "reserve_wal_for_local_slot"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "restart_lsn"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockAcquire"
argument_list
( "("
identifier "ReplicationSlotControlLock"
, ","
identifier "LW_EXCLUSIVE"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockAcquire"
argument_list
( "("
identifier "ProcArrayLock"
, ","
identifier "LW_EXCLUSIVE"
) ")"
; ";"
expression_statement
assignment_expression
identifier "xmin_horizon"
= "="
call_expression
identifier "GetOldestSafeDecodingTransactionId"
argument_list
( "("
true "true"
) ")"
; ";"
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
field_expression
identifier "slot"
-> "->"
field_identifier "effective_catalog_xmin"
= "="
identifier "xmin_horizon"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "catalog_xmin"
= "="
identifier "xmin_horizon"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
call_expression
identifier "ReplicationSlotsComputeRequiredXmin"
argument_list
( "("
true "true"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockRelease"
argument_list
( "("
identifier "ProcArrayLock"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockRelease"
argument_list
( "("
identifier "ReplicationSlotControlLock"
) ")"
; ";"
comment "/*\n\t\t * Make sure that concerned WAL is received and flushed"...
if_statement (+100 nodes collapsed)
expression_statement
call_expression
identifier "update_and_persist_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
, ","
identifier "slot_persistence_pending"
) ")"
; ";"
expression_statement
assignment_expression
identifier "slot_updated"
= "="
true "true"
; ";"
} "}"
expression_statement
call_expression
identifier "ReplicationSlotRelease"
argument_list
( "("
) ")"
; ";"
return_statement
return "return"
identifier "slot_updated"
; ";"
} "}"
comment "/*\n * Fetch remote slots.\n *\n * If slot_names is NIL, fetche"...
function_definition (+877 nodes collapsed)
comment "/*\n * Synchronize slots.\n *\n * This function takes a list of"...
function_definition (+126 nodes collapsed)
comment "/*\n * Checks the remote server info.\n *\n * We ensure that th"...
function_definition (+458 nodes collapsed)
comment "/*\n * Checks if dbname is specified in 'primary_conninfo'.\n "...
function_definition (+89 nodes collapsed)
comment "/*\n * Return true if all necessary GUCs for slot synchroniza"...
function_definition (+275 nodes collapsed)
comment "/*\n * Re-read the config file for slot synchronization.\n *\n "...
function_definition (+343 nodes collapsed)
comment "/*\n * Interrupt handler for process performing slot synchron"...
function_definition (+116 nodes collapsed)
comment "/*\n * Connection cleanup function for slotsync worker.\n *\n *"...
function_definition (+48 nodes collapsed)
comment "/*\n * Cleanup function for slotsync worker.\n *\n * Called on "...
function_definition (+107 nodes collapsed)
comment "/*\n * Sleep for long enough that we believe it's likely that"...
function_definition (+99 nodes collapsed)
comment "/*\n * Emit an error if a concurrent sync call is in progress"...
function_definition (+131 nodes collapsed)
comment "/*\n * Reset syncing flag.\n */"
function_definition (+64 nodes collapsed)
comment "/*\n * The main loop of our worker process.\n *\n * It connects"...
function_definition (+695 nodes collapsed)
comment "/*\n * Update the inactive_since property for synced slots.\n "...
function_definition (+199 nodes collapsed)
comment "/*\n * Shut down slot synchronization.\n *\n * This function se"...
function_definition (+244 nodes collapsed)
comment "/*\n * SlotSyncWorkerCanRestart\n *\n * Return true, indicating"...
function_definition (+79 nodes collapsed)
comment "/*\n * Is current process syncing replication slots?\n *\n * Co"...
function_definition
primitive_type "bool"
function_declarator
identifier "IsSyncingReplicationSlots"
parameter_list
( "("
parameter_declaration
primitive_type "void"
) ")"
compound_statement
{ "{"
return_statement
return "return"
identifier "syncing_slots"
; ";"
} "}"
comment "/*\n * Amount of shared memory required for slot synchronizat"...
function_definition (+21 nodes collapsed)
comment "/*\n * Allocate and initialize the shared memory of slot sync"...
function_definition (+99 nodes collapsed)
comment "/*\n * Error cleanup callback for slot sync SQL function.\n */"
function_definition (+90 nodes collapsed)
comment "/*\n * Helper function to extract slot names from a list of r"...
function_definition (+80 nodes collapsed)
comment "/*\n * Synchronize the failover enabled replication slots usi"...
function_definition (+253 nodes collapsed)

After

translation_unit
comment "/*----------------------------------------------------------"...
preproc_include
#include "#include"
string_literal
" "\""
string_content "postgres.h"
" "\""
preproc_include
#include "#include"
system_lib_string "<time.h>"
preproc_include
#include "#include"
string_literal
" "\""
string_content "access/xlog_internal.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "access/xlogrecovery.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "catalog/pg_database.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "libpq/pqsignal.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "pgstat.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "postmaster/interrupt.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "replication/logical.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "replication/slotsync.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "replication/snapbuild.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/ipc.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/lmgr.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/proc.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "storage/procarray.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "tcop/tcopprot.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/builtins.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/memutils.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/pg_lsn.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/ps_status.h"
" "\""
preproc_include
#include "#include"
string_literal
" "\""
string_content "utils/timeout.h"
" "\""
comment "/*\n * Struct for sharing information to control slot synchro"...
type_definition (+30 nodes collapsed)
declaration
storage_class_specifier
static "static"
type_identifier "SlotSyncCtxStruct"
init_declarator
pointer_declarator
* "*"
identifier "SlotSyncCtx"
= "="
null
NULL "NULL"
; ";"
comment "/* GUC variable */"
declaration
primitive_type "bool"
init_declarator
identifier "sync_replication_slots"
= "="
false "false"
; ";"
comment "/*\n * The sleep time (ms) between slot-sync cycles varies dy"...
preproc_def
#define "#define"
identifier "MIN_SLOTSYNC_WORKER_NAPTIME_MS"
preproc_arg "200"
preproc_def
#define "#define"
identifier "MAX_SLOTSYNC_WORKER_NAPTIME_MS"
preproc_arg "30000\t"
comment "/* 30s */"
declaration
storage_class_specifier
static "static"
sized_type_specifier
long "long"
init_declarator
identifier "sleep_ms"
= "="
identifier "MIN_SLOTSYNC_WORKER_NAPTIME_MS"
; ";"
comment "/* The restart interval for slot sync work used by postmaste"...
preproc_def
#define "#define"
identifier "SLOTSYNC_RESTART_INTERVAL_SEC"
preproc_arg "10"
comment "/*\n * Flag to tell if we are syncing replication slots. Unli"...
declaration
storage_class_specifier
static "static"
primitive_type "bool"
init_declarator
identifier "syncing_slots"
= "="
false "false"
; ";"
comment "/*\n * Structure to hold information fetched from the primary"...
type_definition (+57 nodes collapsed)
declaration
storage_class_specifier
static "static"
primitive_type "void"
function_declarator
identifier "slotsync_failure_callback"
parameter_list
( "("
parameter_declaration
primitive_type "int"
identifier "code"
, ","
parameter_declaration
type_identifier "Datum"
identifier "arg"
) ")"
; ";"
declaration
storage_class_specifier
static "static"
primitive_type "void"
function_declarator
identifier "update_synced_slots_inactive_since"
parameter_list
( "("
parameter_declaration
primitive_type "void"
) ")"
; ";"
comment "/*\n * Update slot sync skip stats. This function requires th"...
function_definition (+104 nodes collapsed)
comment "/*\n * If necessary, update the local synced slot's metadata "...
function_definition
storage_class_specifier
static "static"
primitive_type "bool"
function_declarator
identifier "update_local_synced_slot"
parameter_list
( "("
parameter_declaration
type_identifier "RemoteSlot"
pointer_declarator
* "*"
identifier "remote_slot"
, ","
parameter_declaration
type_identifier "Oid"
identifier "remote_dbid"
) ")"
compound_statement
{ "{"
declaration
type_identifier "ReplicationSlot"
init_declarator
pointer_declarator
* "*"
identifier "slot"
= "="
identifier "MyReplicationSlot"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "updated_xmin_or_lsn"
= "="
false "false"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "updated_config"
= "="
false "false"
; ";"
declaration
type_identifier "SlotSyncSkipReason"
init_declarator
identifier "skip_reason"
= "="
identifier "SS_SKIP_NONE"
; ";"
declaration
type_identifier "XLogRecPtr"
init_declarator
identifier "latestFlushPtr"
= "="
call_expression
identifier "GetStandbyFlushRecPtr"
argument_list
( "("
null
NULL "NULL"
) ")"
; ";"
expression_statement
call_expression
identifier "Assert"
argument_list
( "("
binary_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "invalidated"
== "=="
identifier "RS_INVAL_NONE"
) ")"
; ";"
comment "/*\n\t * Make sure that concerned WAL is received and flushed "...
if_statement (+93 nodes collapsed)
comment "/*\n\t * Don't overwrite if we already have a newer catalog_xm"...
if_statement
if "if"
parenthesized_expression (+35 nodes collapsed)
compound_statement
{ "{"
comment "/* Update slot sync skip stats */"
expression_statement
call_expression
identifier "update_slotsync_skip_stats"
argument_list
( "("
identifier "SS_SKIP_WAL_OR_ROWS_REMOVED"
) ")"
; ";"
comment "/*\n\t\t * This can happen in following situations:\n\t\t *\n\t\t * I"...
expression_statement (+86 nodes collapsed)
comment "/*\n\t\t * Skip updating the configuration. This is required to"...
return_statement
return "return"
false "false"
; ";"
} "}"
comment "/*\n\t * Attempt to sync LSNs and xmins only if remote slot is"...
if_statement
if "if"
parenthesized_expression (+50 nodes collapsed)
compound_statement
{ "{"
comment "/*\n\t\t * We can't directly copy the remote slot's LSN or xmin"...
if_statement
if "if"
parenthesized_expression
( "("
call_expression
identifier "SnapBuildSnapshotExists"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "restart_lsn"
) ")"
) ")"
compound_statement
{ "{"
comment "/*\n\t\t\t * Update the slot info directly if there is a seriali"...
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "restart_lsn"
= "="
field_expression
identifier "remote_slot"
-> "->"
field_identifier "restart_lsn"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "confirmed_flush"
= "="
field_expression
identifier "remote_slot"
-> "->"
field_identifier "confirmed_lsn"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "catalog_xmin"
= "="
field_expression
identifier "remote_slot"
-> "->"
field_identifier "catalog_xmin"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
} "}"
else_clause
else "else"
compound_statement
{ "{"
declaration
primitive_type "bool"
identifier "found_consistent_snapshot"
; ";"
expression_statement
call_expression
identifier "LogicalSlotAdvanceAndCheckSnapState"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "confirmed_lsn"
, ","
pointer_expression
& "&"
identifier "found_consistent_snapshot"
) ")"
; ";"
comment "/* Sanity check */"
if_statement (+78 nodes collapsed)
comment "/*\n\t\t\t * If we can't reach a consistent snapshot, the slot w"...
if_statement
if "if"
parenthesized_expression
( "("
unary_expression
! "!"
identifier "found_consistent_snapshot"
) ")"
compound_statement
{ "{"
expression_statement
call_expression
identifier "Assert"
argument_list
( "("
binary_expression
field_expression
field_expression
identifier "MyReplicationSlot"
-> "->"
field_identifier "data"
. "."
field_identifier "persistency"
== "=="
identifier "RS_TEMPORARY"
) ")"
; ";"
expression_statement (+49 nodes collapsed)
expression_statement
assignment_expression
identifier "skip_reason"
= "="
identifier "SS_SKIP_NO_CONSISTENT_SNAPSHOT"
; ";"
} "}"
} "}"
expression_statement
assignment_expression
identifier "updated_xmin_or_lsn"
= "="
true "true"
; ";"
} "}"
comment "/* Update slot sync skip stats */"
expression_statement
call_expression
identifier "update_slotsync_skip_stats"
argument_list
( "("
identifier "skip_reason"
) ")"
; ";"
if_statement (+235 nodes collapsed)
comment "/*\n\t * We have to write the changed xmin to disk *before* we"...
if_statement (+26 nodes collapsed)
comment "/*\n\t * Now the new xmin is safely on disk, we can let the gl"...
if_statement (+62 nodes collapsed)
return_statement
return "return"
binary_expression
identifier "updated_config"
|| "||"
identifier "updated_xmin_or_lsn"
; ";"
} "}"
comment "/*\n * Get the list of local logical slots that are synchroni"...
function_definition (+135 nodes collapsed)
comment "/*\n * Helper function to check if local_slot is required to "...
function_definition (+163 nodes collapsed)
comment "/*\n * Drop local obsolete slots.\n *\n * Drop the local slots "...
function_definition (+236 nodes collapsed)
comment "/*\n * Reserve WAL for the currently active local slot using "...
function_definition (+242 nodes collapsed)
comment "/*\n * If the remote restart_lsn and catalog_xmin have caught"...
function_definition
storage_class_specifier
static "static"
primitive_type "bool"
function_declarator
identifier "update_and_persist_local_synced_slot"
parameter_list
( "("
parameter_declaration
type_identifier "RemoteSlot"
pointer_declarator
* "*"
identifier "remote_slot"
, ","
parameter_declaration
type_identifier "Oid"
identifier "remote_dbid"
, ","
parameter_declaration
primitive_type "bool"
pointer_declarator
* "*"
identifier "slot_persistence_pending"
) ")"
compound_statement
{ "{"
declaration
type_identifier "ReplicationSlot"
init_declarator
pointer_declarator
* "*"
identifier "slot"
= "="
identifier "MyReplicationSlot"
; ";"
comment "/* Slotsync skip stats are handled in function update_local_"...
expression_statement
cast_expression
( "("
type_descriptor
primitive_type "void"
) ")"
call_expression
identifier "update_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
) ")"
; ";"
comment "/*\n\t * Check if the slot cannot be synchronized. Refer to th"...
if_statement
if "if"
parenthesized_expression
( "("
binary_expression
field_expression
identifier "slot"
-> "->"
field_identifier "slotsync_skip_reason"
!= "!="
identifier "SS_SKIP_NONE"
) ")"
compound_statement
{ "{"
comment "/*\n\t\t * We reach this point when the remote slot didn't catc"...
if_statement
if "if"
parenthesized_expression
( "("
identifier "slot_persistence_pending"
) ")"
expression_statement
assignment_expression
pointer_expression
* "*"
identifier "slot_persistence_pending"
= "="
true "true"
; ";"
return_statement
return "return"
false "false"
; ";"
} "}"
expression_statement
call_expression
identifier "ReplicationSlotPersist"
argument_list
( "("
) ")"
; ";"
expression_statement (+27 nodes collapsed)
return_statement
return "return"
true "true"
; ";"
} "}"
comment "/*\n * Synchronize a single slot to the given position.\n *\n *"...
function_definition
storage_class_specifier
static "static"
primitive_type "bool"
function_declarator
identifier "synchronize_one_slot"
parameter_list
( "("
parameter_declaration
type_identifier "RemoteSlot"
pointer_declarator
* "*"
identifier "remote_slot"
, ","
parameter_declaration
type_identifier "Oid"
identifier "remote_dbid"
, ","
parameter_declaration
primitive_type "bool"
pointer_declarator
* "*"
identifier "slot_persistence_pending"
) ")"
compound_statement
{ "{"
declaration
type_identifier "ReplicationSlot"
pointer_declarator
* "*"
identifier "slot"
; ";"
declaration
primitive_type "bool"
init_declarator
identifier "slot_updated"
= "="
false "false"
; ";"
comment "/* Search for the named slot */"
if_statement
if "if"
parenthesized_expression
( "("
parenthesized_expression
( "("
assignment_expression
identifier "slot"
= "="
call_expression
identifier "SearchNamedReplicationSlot"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "name"
, ","
true "true"
) ")"
) ")"
) ")"
compound_statement
{ "{"
declaration
primitive_type "bool"
identifier "synced"
; ";"
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
identifier "synced"
= "="
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "synced"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
comment "/* User-created slot with the same name exists, raise ERROR."...
if_statement (+47 nodes collapsed)
comment "/*\n\t\t * The slot has been synchronized before.\n\t\t *\n\t\t * It "...
expression_statement
call_expression
identifier "ReplicationSlotAcquire"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "name"
, ","
true "true"
, ","
false "false"
) ")"
; ";"
expression_statement
call_expression
identifier "Assert"
argument_list
( "("
binary_expression
identifier "slot"
== "=="
identifier "MyReplicationSlot"
) ")"
; ";"
comment "/*\n\t\t * Copy the invalidation cause from remote only if loca"...
if_statement (+89 nodes collapsed)
comment "/* Skip the sync of an invalidated slot */"
if_statement (+37 nodes collapsed)
comment "/* Slot not ready yet, let's attempt to make it sync-ready n"...
if_statement
if "if"
parenthesized_expression
( "("
binary_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "persistency"
== "=="
identifier "RS_TEMPORARY"
) ")"
compound_statement
{ "{"
expression_statement
assignment_expression
identifier "slot_updated"
= "="
call_expression
identifier "update_and_persist_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
, ","
identifier "slot_persistence_pending"
) ")"
; ";"
} "}"
comment "/* Slot ready for sync, so sync it. */"
else_clause
else "else"
compound_statement
{ "{"
comment "/*\n\t\t\t * Sanity check: As long as the invalidations are hand"...
if_statement (+77 nodes collapsed)
expression_statement
assignment_expression
identifier "slot_updated"
= "="
call_expression
identifier "update_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
) ")"
; ";"
} "}"
} "}"
comment "/* Otherwise create the slot first. */"
else_clause
else "else"
compound_statement
{ "{"
declaration
type_identifier "NameData"
identifier "plugin_name"
; ";"
declaration
type_identifier "TransactionId"
init_declarator
identifier "xmin_horizon"
= "="
identifier "InvalidTransactionId"
; ";"
comment "/* Skip creating the local slot if remote_slot is invalidate"...
if_statement
if "if"
parenthesized_expression
( "("
binary_expression
field_expression
identifier "remote_slot"
-> "->"
field_identifier "invalidated"
!= "!="
identifier "RS_INVAL_NONE"
) ")"
return_statement
return "return"
false "false"
; ";"
comment "/*\n\t\t * We create temporary slots instead of ephemeral slots"...
expression_statement (+27 nodes collapsed)
comment "/* For shorter lines. */"
expression_statement
assignment_expression
identifier "slot"
= "="
identifier "MyReplicationSlot"
; ";"
comment "/* Avoid expensive operations while holding a spinlock. */"
expression_statement
call_expression
identifier "namestrcpy"
argument_list
( "("
pointer_expression
& "&"
identifier "plugin_name"
, ","
field_expression
identifier "remote_slot"
-> "->"
field_identifier "plugin"
) ")"
; ";"
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "database"
= "="
identifier "remote_dbid"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "plugin"
= "="
identifier "plugin_name"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
call_expression
identifier "reserve_wal_for_local_slot"
argument_list
( "("
field_expression
identifier "remote_slot"
-> "->"
field_identifier "restart_lsn"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockAcquire"
argument_list
( "("
identifier "ReplicationSlotControlLock"
, ","
identifier "LW_EXCLUSIVE"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockAcquire"
argument_list
( "("
identifier "ProcArrayLock"
, ","
identifier "LW_EXCLUSIVE"
) ")"
; ";"
expression_statement
assignment_expression
identifier "xmin_horizon"
= "="
call_expression
identifier "GetOldestSafeDecodingTransactionId"
argument_list
( "("
true "true"
) ")"
; ";"
expression_statement
call_expression
identifier "SpinLockAcquire"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
assignment_expression
field_expression
identifier "slot"
-> "->"
field_identifier "effective_catalog_xmin"
= "="
identifier "xmin_horizon"
; ";"
expression_statement
assignment_expression
field_expression
field_expression
identifier "slot"
-> "->"
field_identifier "data"
. "."
field_identifier "catalog_xmin"
= "="
identifier "xmin_horizon"
; ";"
expression_statement
call_expression
identifier "SpinLockRelease"
argument_list
( "("
pointer_expression
& "&"
field_expression
identifier "slot"
-> "->"
field_identifier "mutex"
) ")"
; ";"
expression_statement
call_expression
identifier "ReplicationSlotsComputeRequiredXmin"
argument_list
( "("
true "true"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockRelease"
argument_list
( "("
identifier "ProcArrayLock"
) ")"
; ";"
expression_statement
call_expression
identifier "LWLockRelease"
argument_list
( "("
identifier "ReplicationSlotControlLock"
) ")"
; ";"
expression_statement
call_expression
identifier "update_and_persist_local_synced_slot"
argument_list
( "("
identifier "remote_slot"
, ","
identifier "remote_dbid"
, ","
identifier "slot_persistence_pending"
) ")"
; ";"
expression_statement
assignment_expression
identifier "slot_updated"
= "="
true "true"
; ";"
} "}"
expression_statement
call_expression
identifier "ReplicationSlotRelease"
argument_list
( "("
) ")"
; ";"
return_statement
return "return"
identifier "slot_updated"
; ";"
} "}"
comment "/*\n * Fetch remote slots.\n *\n * If slot_names is NIL, fetche"...
function_definition (+877 nodes collapsed)
comment "/*\n * Synchronize slots.\n *\n * This function takes a list of"...
function_definition (+126 nodes collapsed)
comment "/*\n * Checks the remote server info.\n *\n * We ensure that th"...
function_definition (+458 nodes collapsed)
comment "/*\n * Checks if dbname is specified in 'primary_conninfo'.\n "...
function_definition (+89 nodes collapsed)
comment "/*\n * Return true if all necessary GUCs for slot synchroniza"...
function_definition (+275 nodes collapsed)
comment "/*\n * Re-read the config file for slot synchronization.\n *\n "...
function_definition (+343 nodes collapsed)
comment "/*\n * Interrupt handler for process performing slot synchron"...
function_definition (+116 nodes collapsed)
comment "/*\n * Connection cleanup function for slotsync worker.\n *\n *"...
function_definition (+48 nodes collapsed)
comment "/*\n * Cleanup function for slotsync worker.\n *\n * Called on "...
function_definition (+107 nodes collapsed)
comment "/*\n * Sleep for long enough that we believe it's likely that"...
function_definition (+99 nodes collapsed)
comment "/*\n * Emit an error if a concurrent sync call is in progress"...
function_definition (+131 nodes collapsed)
comment "/*\n * Reset syncing flag.\n */"
function_definition (+64 nodes collapsed)
comment "/*\n * The main loop of our worker process.\n *\n * It connects"...
function_definition (+695 nodes collapsed)
comment "/*\n * Update the inactive_since property for synced slots.\n "...
function_definition (+199 nodes collapsed)
comment "/*\n * Shut down slot synchronization.\n *\n * This function se"...
function_definition (+244 nodes collapsed)
comment "/*\n * SlotSyncWorkerCanRestart\n *\n * Return true, indicating"...
function_definition (+79 nodes collapsed)
comment "/*\n * Is current process syncing replication slots?\n *\n * Co"...
function_definition
primitive_type "bool"
function_declarator
identifier "IsSyncingReplicationSlots"
parameter_list
( "("
parameter_declaration
primitive_type "void"
) ")"
compound_statement
{ "{"
return_statement
return "return"
identifier "syncing_slots"
; ";"
} "}"
comment "/*\n * Amount of shared memory required for slot synchronizat"...
function_definition (+21 nodes collapsed)
comment "/*\n * Allocate and initialize the shared memory of slot sync"...
function_definition (+99 nodes collapsed)
comment "/*\n * Error cleanup callback for slot sync SQL function.\n */"
function_definition (+90 nodes collapsed)
comment "/*\n * Helper function to extract slot names from a list of r"...
function_definition (+80 nodes collapsed)
comment "/*\n * Synchronize the failover enabled replication slots usi"...
function_definition (+253 nodes collapsed)