codekingpro/portable-devtools
114k
1/*-------------------------------------------------------------------------2 * slot.h3 * Replication slot management.4 *5 * Copyright (c) 2012-2023, PostgreSQL Global Development Group6 *7 *-------------------------------------------------------------------------8 */9#ifndef SLOT_H10#define SLOT_H11 12#include "access/xlog.h"13#include "access/xlogreader.h"14#include "storage/condition_variable.h"15#include "storage/lwlock.h"16#include "storage/shmem.h"17#include "storage/spin.h"18#include "replication/walreceiver.h"19 20/*21 * Behaviour of replication slots, upon release or crash.22 *23 * Slots marked as PERSISTENT are crash-safe and will not be dropped when24 * released. Slots marked as EPHEMERAL will be dropped when released or after25 * restarts. Slots marked TEMPORARY will be dropped at the end of a session26 * or on error.27 *28 * EPHEMERAL is used as a not-quite-ready state when creating persistent29 * slots. EPHEMERAL slots can be made PERSISTENT by calling30 * ReplicationSlotPersist(). For a slot that goes away at the end of a31 * session, TEMPORARY is the appropriate choice.32 */33typedef enum ReplicationSlotPersistency34{35 RS_PERSISTENT,36 RS_EPHEMERAL,37 RS_TEMPORARY38} ReplicationSlotPersistency;39 40/*41 * Slots can be invalidated, e.g. due to max_slot_wal_keep_size. If so, the42 * 'invalidated' field is set to a value other than _NONE.43 */44typedef enum ReplicationSlotInvalidationCause45{46 RS_INVAL_NONE,47 /* required WAL has been removed */48 RS_INVAL_WAL_REMOVED,49 /* required rows have been removed */50 RS_INVAL_HORIZON,51 /* wal_level insufficient for slot */52 RS_INVAL_WAL_LEVEL,53} ReplicationSlotInvalidationCause;54 55/*56 * On-Disk data of a replication slot, preserved across restarts.57 */58typedef struct ReplicationSlotPersistentData59{60 /* The slot's identifier */61 NameData name;62 63 /* database the slot is active on */64 Oid database;65 66 /*67 * The slot's behaviour when being dropped (or restored after a crash).68 */69 ReplicationSlotPersistency persistency;70 71 /*72 * xmin horizon for data73 *74 * NB: This may represent a value that hasn't been written to disk yet;75 * see notes for effective_xmin, below.76 */77 TransactionId xmin;78 79 /*80 * xmin horizon for catalog tuples81 *82 * NB: This may represent a value that hasn't been written to disk yet;83 * see notes for effective_xmin, below.84 */85 TransactionId catalog_xmin;86 87 /* oldest LSN that might be required by this replication slot */88 XLogRecPtr restart_lsn;89 90 /* RS_INVAL_NONE if valid, or the reason for having been invalidated */91 ReplicationSlotInvalidationCause invalidated;92 93 /*94 * Oldest LSN that the client has acked receipt for. This is used as the95 * start_lsn point in case the client doesn't specify one, and also as a96 * safety measure to jump forwards in case the client specifies a97 * start_lsn that's further in the past than this value.98 */99 XLogRecPtr confirmed_flush;100 101 /*102 * LSN at which we enabled two_phase commit for this slot or LSN at which103 * we found a consistent point at the time of slot creation.104 */105 XLogRecPtr two_phase_at;106 107 /*108 * Allow decoding of prepared transactions?109 */110 bool two_phase;111 112 /* plugin name */113 NameData plugin;114} ReplicationSlotPersistentData;115 116/*117 * Shared memory state of a single replication slot.118 *119 * The in-memory data of replication slots follows a locking model based120 * on two linked concepts:121 * - A replication slot's in_use flag is switched when added or discarded using122 * the LWLock ReplicationSlotControlLock, which needs to be hold in exclusive123 * mode when updating the flag by the backend owning the slot and doing the124 * operation, while readers (concurrent backends not owning the slot) need125 * to hold it in shared mode when looking at replication slot data.126 * - Individual fields are protected by mutex where only the backend owning127 * the slot is authorized to update the fields from its own slot. The128 * backend owning the slot does not need to take this lock when reading its129 * own fields, while concurrent backends not owning this slot should take the130 * lock when reading this slot's data.131 */132typedef struct ReplicationSlot133{134 /* lock, on same cacheline as effective_xmin */135 slock_t mutex;136 137 /* is this slot defined */138 bool in_use;139 140 /* Who is streaming out changes for this slot? 0 in unused slots. */141 pid_t active_pid;142 143 /* any outstanding modifications? */144 bool just_dirtied;145 bool dirty;146 147 /*148 * For logical decoding, it's extremely important that we never remove any149 * data that's still needed for decoding purposes, even after a crash;150 * otherwise, decoding will produce wrong answers. Ordinary streaming151 * replication also needs to prevent old row versions from being removed152 * too soon, but the worst consequence we might encounter there is153 * unwanted query cancellations on the standby. Thus, for logical154 * decoding, this value represents the latest xmin that has actually been155 * written to disk, whereas for streaming replication, it's just the same156 * as the persistent value (data.xmin).157 */158 TransactionId effective_xmin;159 TransactionId effective_catalog_xmin;160 161 /* data surviving shutdowns and crashes */162 ReplicationSlotPersistentData data;163 164 /* is somebody performing io on this slot? */165 LWLock io_in_progress_lock;166 167 /* Condition variable signaled when active_pid changes */168 ConditionVariable active_cv;169 170 /* all the remaining data is only used for logical slots */171 172 /*173 * When the client has confirmed flushes >= candidate_xmin_lsn we can174 * advance the catalog xmin. When restart_valid has been passed,175 * restart_lsn can be increased.176 */177 TransactionId candidate_catalog_xmin;178 XLogRecPtr candidate_xmin_lsn;179 XLogRecPtr candidate_restart_valid;180 XLogRecPtr candidate_restart_lsn;181} ReplicationSlot;182 183#define SlotIsPhysical(slot) ((slot)->data.database == InvalidOid)184#define SlotIsLogical(slot) ((slot)->data.database != InvalidOid)185 186/*187 * Shared memory control area for all of replication slots.188 */189typedef struct ReplicationSlotCtlData190{191 /*192 * This array should be declared [FLEXIBLE_ARRAY_MEMBER], but for some193 * reason you can't do that in an otherwise-empty struct.194 */195 ReplicationSlot replication_slots[1];196} ReplicationSlotCtlData;197 198/*199 * Pointers to shared memory200 */201extern PGDLLIMPORT ReplicationSlotCtlData *ReplicationSlotCtl;202extern PGDLLIMPORT ReplicationSlot *MyReplicationSlot;203 204/* GUCs */205extern PGDLLIMPORT int max_replication_slots;206 207/* shmem initialization functions */208extern Size ReplicationSlotsShmemSize(void);209extern void ReplicationSlotsShmemInit(void);210 211/* management of individual slots */212extern void ReplicationSlotCreate(const char *name, bool db_specific,213 ReplicationSlotPersistency persistency,214 bool two_phase);215extern void ReplicationSlotPersist(void);216extern void ReplicationSlotDrop(const char *name, bool nowait);217 218extern void ReplicationSlotAcquire(const char *name, bool nowait);219extern void ReplicationSlotRelease(void);220extern void ReplicationSlotCleanup(void);221extern void ReplicationSlotSave(void);222extern void ReplicationSlotMarkDirty(void);223 224/* misc stuff */225extern void ReplicationSlotInitialize(void);226extern bool ReplicationSlotValidateName(const char *name, int elevel);227extern void ReplicationSlotReserveWal(void);228extern void ReplicationSlotsComputeRequiredXmin(bool already_locked);229extern void ReplicationSlotsComputeRequiredLSN(void);230extern XLogRecPtr ReplicationSlotsComputeLogicalRestartLSN(void);231extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive);232extern void ReplicationSlotsDropDBSlots(Oid dboid);233extern bool InvalidateObsoleteReplicationSlots(ReplicationSlotInvalidationCause cause,234 XLogSegNo oldestSegno,235 Oid dboid,236 TransactionId snapshotConflictHorizon);237extern ReplicationSlot *SearchNamedReplicationSlot(const char *name, bool need_lock);238extern int ReplicationSlotIndex(ReplicationSlot *slot);239extern bool ReplicationSlotName(int index, Name name);240extern void ReplicationSlotNameForTablesync(Oid suboid, Oid relid, char *syncslotname, Size szslot);241extern void ReplicationSlotDropAtPubNode(WalReceiverConn *wrconn, char *slotname, bool missing_ok);242 243extern void StartupReplicationSlots(void);244extern void CheckPointReplicationSlots(void);245 246extern void CheckSlotRequirements(void);247extern void CheckSlotPermissions(void);248 249#endif /* SLOT_H */250 