/* acquire replication slot, this will check for conflicting names */
ReplicationSlotCreate(name, false,
temporary ? RS_TEMPORARY : RS_PERSISTENT, false, false, false);
if (immediately_reserve)
{ /* Reserve WAL as the user asked for it */ if (XLogRecPtrIsInvalid(restart_lsn))
ReplicationSlotReserveWal(); else
MyReplicationSlot->data.restart_lsn = restart_lsn;
/* Write this slot to disk */
ReplicationSlotMarkDirty();
ReplicationSlotSave();
}
}
/* *SQLfunctionforcreatinganewphysical(streamingreplication) *replicationslot.
*/
Datum
pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
{
Name name = PG_GETARG_NAME(0); bool immediately_reserve = PG_GETARG_BOOL(1); bool temporary = PG_GETARG_BOOL(2);
Datum values[2]; bool nulls[2];
TupleDesc tupdesc;
HeapTuple tuple;
Datum result;
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
/* determine how many segments can be kept by slots */
slotKeepSegs = XLogMBVarToSegs(max_slot_wal_keep_size_mb, wal_segment_size); /* ditto for wal_keep_size */
keepSegs = XLogMBVarToSegs(wal_keep_size_mb, wal_segment_size);
/* *SQLfunctionformovingthepositioninareplicationslot.
*/
Datum
pg_replication_slot_advance(PG_FUNCTION_ARGS)
{
Name slotname = PG_GETARG_NAME(0);
XLogRecPtr moveto = PG_GETARG_LSN(1);
XLogRecPtr endlsn;
XLogRecPtr minlsn;
TupleDesc tupdesc;
Datum values[2]; bool nulls[2];
HeapTuple tuple;
Datum result;
Assert(!MyReplicationSlot);
CheckSlotPermissions();
if (XLogRecPtrIsInvalid(moveto))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid target WAL LSN")));
/* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
/* Acquire the slot so we "own" it */
ReplicationSlotAcquire(NameStr(*slotname), true, true);
/* A slot whose restart_lsn has never been reserved cannot be advanced */ if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn))
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("replication slot \"%s\" cannot be advanced",
NameStr(*slotname)),
errdetail("This slot has never previously reserved WAL, or it has been invalidated.")));
if (moveto < minlsn)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("cannot advance replication slot to %X/%X, minimum is %X/%X",
LSN_FORMAT_ARGS(moveto), LSN_FORMAT_ARGS(minlsn))));
/* Do the actual slot update, depending on the slot type */ if (OidIsValid(MyReplicationSlot->data.database))
endlsn = pg_logical_replication_slot_advance(moveto); else
endlsn = pg_physical_replication_slot_advance(moveto);
/* Check type of replication slot */ if (src_islogical != logical_slot)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
src_islogical ?
errmsg("cannot copy physical replication slot \"%s\" as a logical replication slot",
NameStr(*src_name)) :
errmsg("cannot copy logical replication slot \"%s\" as a physical replication slot",
NameStr(*src_name))));
/* Copying non-reserved slot doesn't make sense */ if (XLogRecPtrIsInvalid(src_restart_lsn))
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("cannot copy a replication slot that doesn't reserve WAL")));
/* for existence check */
copy_name = NameStr(second_slot_contents.data.name);
copy_islogical = SlotIsLogical(&second_slot_contents);
/* *Checkifthesourceslotstillexistsandisvalid.Weregarditas *invalidifthetypeofreplicationslotornamehasbeenchanged, *ortherestart_lsneitherisinvalidorhasgonebackward.(The *restart_lsncouldgobackwardsifthesourceslotisdroppedand *copiedfromanolderslotduringinstallation.) * *Sinceerroringoutwillreleaseanddropthedestinationslotwe *don'tneedtoreleaseithere.
*/ if (copy_restart_lsn < src_restart_lsn ||
src_islogical != copy_islogical ||
strcmp(copy_name, NameStr(*src_name)) != 0)
ereport(ERROR,
(errmsg("could not copy replication slot \"%s\"",
NameStr(*src_name)),
errdetail("The source replication slot was modified incompatibly during the copy operation.")));
/* The source slot must have a consistent snapshot */ if (src_islogical && XLogRecPtrIsInvalid(copy_confirmed_flush))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot copy unfinished logical replication slot \"%s\"",
NameStr(*src_name)),
errhint("Retry when the source replication slot's confirmed_flush_lsn is valid.")));
/* *Copyinganinvalidslotdoesn'tmakesense.Notethatthesource *slotcanbecomeinvalidafterwecreatethenewslotandcopythe *dataofsourceslot.Thisispossiblebecausetheoperationsin *InvalidateObsoleteReplicationSlots()arenotserializedwiththis *function.Eventhoughwecan'tdetectsuchacasehere,thecopied *slotwillbecomeinvalidinthenextcheckpointcycle.
*/ if (second_slot_contents.data.invalidated != RS_INVAL_NONE)
ereport(ERROR,
errmsg("cannot copy replication slot \"%s\"",
NameStr(*src_name)),
errdetail("The source replication slot was invalidated during the copy operation."));
/* target slot fully created, mark as persistent if needed */ if (logical_slot && !temporary)
ReplicationSlotPersist();
/* All done. Set up the return values */
values[0] = NameGetDatum(dst_name);
nulls[0] = false; if (!XLogRecPtrIsInvalid(MyReplicationSlot->data.confirmed_flush))
{
values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
nulls[1] = false;
} else
nulls[1] = true;
tuple = heap_form_tuple(tupdesc, values, nulls);
result = HeapTupleGetDatum(tuple);
ReplicationSlotRelease();
PG_RETURN_DATUM(result);
}
/* The wrappers below are all to appease opr_sanity */
Datum
pg_copy_logical_replication_slot_a(PG_FUNCTION_ARGS)
{ return copy_replication_slot(fcinfo, true);
}
Datum
pg_copy_logical_replication_slot_b(PG_FUNCTION_ARGS)
{ return copy_replication_slot(fcinfo, true);
}
Datum
pg_copy_logical_replication_slot_c(PG_FUNCTION_ARGS)
{ return copy_replication_slot(fcinfo, true);
}
Datum
pg_copy_physical_replication_slot_a(PG_FUNCTION_ARGS)
{ return copy_replication_slot(fcinfo, false);
}
Datum
pg_copy_physical_replication_slot_b(PG_FUNCTION_ARGS)
{ return copy_replication_slot(fcinfo, false);
}
if (!RecoveryInProgress())
ereport(ERROR,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("replication slots can only be synchronized to a standby server"));
ValidateSlotSyncParams(ERROR);
/* Load the libpq-specific functions */
load_file("libpqwalreceiver", false);
(void) CheckAndGetDbnameFromConninfo();
initStringInfo(&app_name); if (cluster_name[0])
appendStringInfo(&app_name, "%s_slotsync", cluster_name); else
appendStringInfoString(&app_name, "slotsync");
/* Connect to the primary server. */
wrconn = walrcv_connect(PrimaryConnInfo, false, false, false,
app_name.data, &err);
if (!wrconn)
ereport(ERROR,
errcode(ERRCODE_CONNECTION_FAILURE),
errmsg("synchronization worker \"%s\" could not connect to the primary server: %s",
app_name.data, err));
pfree(app_name.data);
SyncReplicationSlots(wrconn);
walrcv_disconnect(wrconn);
PG_RETURN_VOID();
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.