Move replication slot structures/enums/macros to a new header file for better usability by external tools/modules
Hi,
While working on pg_replslotdata tool [1]/messages/by-id/CALj2ACW0rV5gWK8A3m6_X62qH+Vfaq5hznC=i0R5Wojt5+yhyw@mail.gmail.com, it was observed that some
of the replication slot structures/enums/macros such as
ReplicationSlotPersistentData, ReplicationSlotPersistency,
ReplicationSlotOnDisk, ReplicationSlotOnDiskXXXX etc. are currently in
replication/slot.h and replication/slot.c. This makes the replication
slot on disk data structures unusable by the external tools/modules.
How about moving these structures to a new header file called
slot_common.h as attached in the patch here?
Thoughts?
PS: I'm planning to have the tool separately, as it was rejected to be in core.
[1]: /messages/by-id/CALj2ACW0rV5gWK8A3m6_X62qH+Vfaq5hznC=i0R5Wojt5+yhyw@mail.gmail.com
Regards,
Bharath Rupireddy.
Attachments:
v1-0001-Add-new-header-file-for-replication-slot-common-d.patchapplication/x-patch; name=v1-0001-Add-new-header-file-for-replication-slot-common-d.patchDownload
From 8cdae73e6126118d2826b68a5e0037effa209b29 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Date: Sun, 6 Feb 2022 05:41:43 +0000
Subject: [PATCH v1] Add new header file for replication slot common data
structures
This makes the external tools/modules to use the replication
slot data structures.
---
src/backend/replication/slot.c | 39 --------
src/include/replication/slot.h | 82 +---------------
src/include/replication/slot_common.h | 135 ++++++++++++++++++++++++++
3 files changed, 136 insertions(+), 120 deletions(-)
create mode 100644 src/include/replication/slot_common.h
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index e5e0cf8768..42dc297a03 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -50,45 +50,6 @@
#include "storage/procarray.h"
#include "utils/builtins.h"
-/*
- * Replication slot on-disk data structure.
- */
-typedef struct ReplicationSlotOnDisk
-{
- /* first part of this struct needs to be version independent */
-
- /* data not covered by checksum */
- uint32 magic;
- pg_crc32c checksum;
-
- /* data covered by checksum */
- uint32 version;
- uint32 length;
-
- /*
- * The actual data in the slot that follows can differ based on the above
- * 'version'.
- */
-
- ReplicationSlotPersistentData slotdata;
-} ReplicationSlotOnDisk;
-
-/* size of version independent data */
-#define ReplicationSlotOnDiskConstantSize \
- offsetof(ReplicationSlotOnDisk, slotdata)
-/* size of the part of the slot not covered by the checksum */
-#define ReplicationSlotOnDiskNotChecksummedSize \
- offsetof(ReplicationSlotOnDisk, version)
-/* size of the part covered by the checksum */
-#define ReplicationSlotOnDiskChecksummedSize \
- sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskNotChecksummedSize
-/* size of the slot data that is version dependent */
-#define ReplicationSlotOnDiskV2Size \
- sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskConstantSize
-
-#define SLOT_MAGIC 0x1051CA1 /* format identifier */
-#define SLOT_VERSION 2 /* version for new files */
-
/* Control array for replication slot management */
ReplicationSlotCtlData *ReplicationSlotCtl = NULL;
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index f833b1d6dc..657d91f44d 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -15,89 +15,9 @@
#include "storage/lwlock.h"
#include "storage/shmem.h"
#include "storage/spin.h"
+#include "replication/slot_common.h"
#include "replication/walreceiver.h"
-/*
- * Behaviour of replication slots, upon release or crash.
- *
- * Slots marked as PERSISTENT are crash-safe and will not be dropped when
- * released. Slots marked as EPHEMERAL will be dropped when released or after
- * restarts. Slots marked TEMPORARY will be dropped at the end of a session
- * or on error.
- *
- * EPHEMERAL is used as a not-quite-ready state when creating persistent
- * slots. EPHEMERAL slots can be made PERSISTENT by calling
- * ReplicationSlotPersist(). For a slot that goes away at the end of a
- * session, TEMPORARY is the appropriate choice.
- */
-typedef enum ReplicationSlotPersistency
-{
- RS_PERSISTENT,
- RS_EPHEMERAL,
- RS_TEMPORARY
-} ReplicationSlotPersistency;
-
-/*
- * On-Disk data of a replication slot, preserved across restarts.
- */
-typedef struct ReplicationSlotPersistentData
-{
- /* The slot's identifier */
- NameData name;
-
- /* database the slot is active on */
- Oid database;
-
- /*
- * The slot's behaviour when being dropped (or restored after a crash).
- */
- ReplicationSlotPersistency persistency;
-
- /*
- * xmin horizon for data
- *
- * NB: This may represent a value that hasn't been written to disk yet;
- * see notes for effective_xmin, below.
- */
- TransactionId xmin;
-
- /*
- * xmin horizon for catalog tuples
- *
- * NB: This may represent a value that hasn't been written to disk yet;
- * see notes for effective_xmin, below.
- */
- TransactionId catalog_xmin;
-
- /* oldest LSN that might be required by this replication slot */
- XLogRecPtr restart_lsn;
-
- /* restart_lsn is copied here when the slot is invalidated */
- XLogRecPtr invalidated_at;
-
- /*
- * Oldest LSN that the client has acked receipt for. This is used as the
- * start_lsn point in case the client doesn't specify one, and also as a
- * safety measure to jump forwards in case the client specifies a
- * start_lsn that's further in the past than this value.
- */
- XLogRecPtr confirmed_flush;
-
- /*
- * LSN at which we enabled two_phase commit for this slot or LSN at which
- * we found a consistent point at the time of slot creation.
- */
- XLogRecPtr two_phase_at;
-
- /*
- * Allow decoding of prepared transactions?
- */
- bool two_phase;
-
- /* plugin name */
- NameData plugin;
-} ReplicationSlotPersistentData;
-
/*
* Shared memory state of a single replication slot.
*
diff --git a/src/include/replication/slot_common.h b/src/include/replication/slot_common.h
new file mode 100644
index 0000000000..67067cece3
--- /dev/null
+++ b/src/include/replication/slot_common.h
@@ -0,0 +1,135 @@
+/*-------------------------------------------------------------------------
+ * slot_common.h
+ * Replication slot common data structures.
+ *
+ * Copyright (c) 2017-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/include/replication/slot_common.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef SLOT_COMMON_H
+#define SLOT_COMMON_H
+
+/*
+ * Behaviour of replication slots, upon release or crash.
+ *
+ * Slots marked as PERSISTENT are crash-safe and will not be dropped when
+ * released. Slots marked as EPHEMERAL will be dropped when released or after
+ * restarts. Slots marked TEMPORARY will be dropped at the end of a session
+ * or on error.
+ *
+ * EPHEMERAL is used as a not-quite-ready state when creating persistent
+ * slots. EPHEMERAL slots can be made PERSISTENT by calling
+ * ReplicationSlotPersist(). For a slot that goes away at the end of a
+ * session, TEMPORARY is the appropriate choice.
+ */
+typedef enum ReplicationSlotPersistency
+{
+ RS_PERSISTENT,
+ RS_EPHEMERAL,
+ RS_TEMPORARY
+} ReplicationSlotPersistency;
+
+/*
+ * On-Disk data of a replication slot, preserved across restarts.
+ */
+typedef struct ReplicationSlotPersistentData
+{
+ /* The slot's identifier */
+ NameData name;
+
+ /* database the slot is active on */
+ Oid database;
+
+ /*
+ * The slot's behaviour when being dropped (or restored after a crash).
+ */
+ ReplicationSlotPersistency persistency;
+
+ /*
+ * xmin horizon for data
+ *
+ * NB: This may represent a value that hasn't been written to disk yet;
+ * see notes for effective_xmin, below.
+ */
+ TransactionId xmin;
+
+ /*
+ * xmin horizon for catalog tuples
+ *
+ * NB: This may represent a value that hasn't been written to disk yet;
+ * see notes for effective_xmin, below.
+ */
+ TransactionId catalog_xmin;
+
+ /* oldest LSN that might be required by this replication slot */
+ XLogRecPtr restart_lsn;
+
+ /* restart_lsn is copied here when the slot is invalidated */
+ XLogRecPtr invalidated_at;
+
+ /*
+ * Oldest LSN that the client has acked receipt for. This is used as the
+ * start_lsn point in case the client doesn't specify one, and also as a
+ * safety measure to jump forwards in case the client specifies a
+ * start_lsn that's further in the past than this value.
+ */
+ XLogRecPtr confirmed_flush;
+
+ /*
+ * LSN at which we enabled two_phase commit for this slot or LSN at which
+ * we found a consistent point at the time of slot creation.
+ */
+ XLogRecPtr two_phase_at;
+
+ /*
+ * Allow decoding of prepared transactions?
+ */
+ bool two_phase;
+
+ /* plugin name */
+ NameData plugin;
+} ReplicationSlotPersistentData;
+
+/*
+ * Replication slot on-disk data structure.
+ */
+typedef struct ReplicationSlotOnDisk
+{
+ /* first part of this struct needs to be version independent */
+
+ /* data not covered by checksum */
+ uint32 magic;
+ pg_crc32c checksum;
+
+ /* data covered by checksum */
+ uint32 version;
+ uint32 length;
+
+ /*
+ * The actual data in the slot that follows can differ based on the above
+ * 'version'.
+ */
+
+ ReplicationSlotPersistentData slotdata;
+} ReplicationSlotOnDisk;
+
+/* size of version independent data */
+#define ReplicationSlotOnDiskConstantSize \
+ offsetof(ReplicationSlotOnDisk, slotdata)
+/* size of the part of the slot not covered by the checksum */
+#define ReplicationSlotOnDiskNotChecksummedSize \
+ offsetof(ReplicationSlotOnDisk, version)
+/* size of the part covered by the checksum */
+#define ReplicationSlotOnDiskChecksummedSize \
+ sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskNotChecksummedSize
+/* size of the slot data that is version dependent */
+#define ReplicationSlotOnDiskV2Size \
+ sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskConstantSize
+
+#define SLOT_MAGIC 0x1051CA1 /* format identifier */
+#define SLOT_VERSION 2 /* version for new files */
+
+#endif /* SLOT_COMMON_H */
--
2.25.1
On Mon, Feb 7, 2022 at 4:22 PM Bharath Rupireddy
<bharath.rupireddyforpostgres@gmail.com> wrote:
Hi,
While working on pg_replslotdata tool [1], it was observed that some
of the replication slot structures/enums/macros such as
ReplicationSlotPersistentData, ReplicationSlotPersistency,
ReplicationSlotOnDisk, ReplicationSlotOnDiskXXXX etc. are currently in
replication/slot.h and replication/slot.c. This makes the replication
slot on disk data structures unusable by the external tools/modules.
How about moving these structures to a new header file called
slot_common.h as attached in the patch here?Thoughts?
PS: I'm planning to have the tool separately, as it was rejected to be in core.
[1] /messages/by-id/CALj2ACW0rV5gWK8A3m6_X62qH+Vfaq5hznC=i0R5Wojt5+yhyw@mail.gmail.com
Regards,
Bharath Rupireddy.
Recently I was also looking to add some new enums but I found it
was difficult to find any good place to put them where they could be
shared by the replication code and the pg_recvlogical tool.
So +1 to your suggestion to have a common header, but I wonder can it
have a more generic name (e.g. repl_common.h? ...) since the
stuff I wanted to put there was not really "slot" related.
------
Kind Regards,
Peter Smith.
Fujitsu Australia.
On Wed, Feb 9, 2022 at 2:16 AM Peter Smith <smithpb2250@gmail.com> wrote:
On Mon, Feb 7, 2022 at 4:22 PM Bharath Rupireddy
<bharath.rupireddyforpostgres@gmail.com> wrote:Hi,
While working on pg_replslotdata tool [1], it was observed that some
of the replication slot structures/enums/macros such as
ReplicationSlotPersistentData, ReplicationSlotPersistency,
ReplicationSlotOnDisk, ReplicationSlotOnDiskXXXX etc. are currently in
replication/slot.h and replication/slot.c. This makes the replication
slot on disk data structures unusable by the external tools/modules.
How about moving these structures to a new header file called
slot_common.h as attached in the patch here?Thoughts?
PS: I'm planning to have the tool separately, as it was rejected to be in core.
[1] /messages/by-id/CALj2ACW0rV5gWK8A3m6_X62qH+Vfaq5hznC=i0R5Wojt5+yhyw@mail.gmail.com
Recently I was also looking to add some new enums but I found it
was difficult to find any good place to put them where they could be
shared by the replication code and the pg_recvlogical tool.So +1 to your suggestion to have a common header, but I wonder can it
have a more generic name (e.g. repl_common.h? ...) since the
stuff I wanted to put there was not really "slot" related.
Thanks. repl_common.h sounds cool and generic IMO too, so I changed
it. Another important note here is to let this file have only
replication data structures and functions that are meant/supposed to
be usable across entire postgres modules - core, tools, contrib
modules, the internal data structures can be added elsewhere.
Attaching v2 patch.
I will add a CF entry a day or two later.
Regards,
Bharath Rupireddy.
Attachments:
v2-0001-Add-new-header-file-for-replication-slot-common-d.patchapplication/x-patch; name=v2-0001-Add-new-header-file-for-replication-slot-common-d.patchDownload
From 087de72a5aa9cb8c53729d4c15ea0f481fbc97a2 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Date: Thu, 10 Feb 2022 04:18:53 +0000
Subject: [PATCH v2] Add new header file for replication slot common data
structures
This makes the external tools/modules to use the replication
slot data structures.
---
src/backend/replication/slot.c | 39 --------
src/include/replication/repl_common.h | 138 ++++++++++++++++++++++++++
src/include/replication/slot.h | 82 +--------------
3 files changed, 139 insertions(+), 120 deletions(-)
create mode 100644 src/include/replication/repl_common.h
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index e5e0cf8768..42dc297a03 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -50,45 +50,6 @@
#include "storage/procarray.h"
#include "utils/builtins.h"
-/*
- * Replication slot on-disk data structure.
- */
-typedef struct ReplicationSlotOnDisk
-{
- /* first part of this struct needs to be version independent */
-
- /* data not covered by checksum */
- uint32 magic;
- pg_crc32c checksum;
-
- /* data covered by checksum */
- uint32 version;
- uint32 length;
-
- /*
- * The actual data in the slot that follows can differ based on the above
- * 'version'.
- */
-
- ReplicationSlotPersistentData slotdata;
-} ReplicationSlotOnDisk;
-
-/* size of version independent data */
-#define ReplicationSlotOnDiskConstantSize \
- offsetof(ReplicationSlotOnDisk, slotdata)
-/* size of the part of the slot not covered by the checksum */
-#define ReplicationSlotOnDiskNotChecksummedSize \
- offsetof(ReplicationSlotOnDisk, version)
-/* size of the part covered by the checksum */
-#define ReplicationSlotOnDiskChecksummedSize \
- sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskNotChecksummedSize
-/* size of the slot data that is version dependent */
-#define ReplicationSlotOnDiskV2Size \
- sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskConstantSize
-
-#define SLOT_MAGIC 0x1051CA1 /* format identifier */
-#define SLOT_VERSION 2 /* version for new files */
-
/* Control array for replication slot management */
ReplicationSlotCtlData *ReplicationSlotCtl = NULL;
diff --git a/src/include/replication/repl_common.h b/src/include/replication/repl_common.h
new file mode 100644
index 0000000000..b59a70811a
--- /dev/null
+++ b/src/include/replication/repl_common.h
@@ -0,0 +1,138 @@
+/*-------------------------------------------------------------------------
+ * repl_common.h
+ *
+ * This header file is meant to hold replication data structures and
+ * functions usable across the entire Postgres modules i.e. core, tools,
+ * and contrib modules.
+ *
+ * Copyright (c) 2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/include/replication/repl_common.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef REPL_COMMON_H
+#define REPL_COMMON_H
+
+/*
+ * Behaviour of replication slots, upon release or crash.
+ *
+ * Slots marked as PERSISTENT are crash-safe and will not be dropped when
+ * released. Slots marked as EPHEMERAL will be dropped when released or after
+ * restarts. Slots marked TEMPORARY will be dropped at the end of a session
+ * or on error.
+ *
+ * EPHEMERAL is used as a not-quite-ready state when creating persistent
+ * slots. EPHEMERAL slots can be made PERSISTENT by calling
+ * ReplicationSlotPersist(). For a slot that goes away at the end of a
+ * session, TEMPORARY is the appropriate choice.
+ */
+typedef enum ReplicationSlotPersistency
+{
+ RS_PERSISTENT,
+ RS_EPHEMERAL,
+ RS_TEMPORARY
+} ReplicationSlotPersistency;
+
+/*
+ * On-Disk data of a replication slot, preserved across restarts.
+ */
+typedef struct ReplicationSlotPersistentData
+{
+ /* The slot's identifier */
+ NameData name;
+
+ /* database the slot is active on */
+ Oid database;
+
+ /*
+ * The slot's behaviour when being dropped (or restored after a crash).
+ */
+ ReplicationSlotPersistency persistency;
+
+ /*
+ * xmin horizon for data
+ *
+ * NB: This may represent a value that hasn't been written to disk yet;
+ * see notes for effective_xmin, below.
+ */
+ TransactionId xmin;
+
+ /*
+ * xmin horizon for catalog tuples
+ *
+ * NB: This may represent a value that hasn't been written to disk yet;
+ * see notes for effective_xmin, below.
+ */
+ TransactionId catalog_xmin;
+
+ /* oldest LSN that might be required by this replication slot */
+ XLogRecPtr restart_lsn;
+
+ /* restart_lsn is copied here when the slot is invalidated */
+ XLogRecPtr invalidated_at;
+
+ /*
+ * Oldest LSN that the client has acked receipt for. This is used as the
+ * start_lsn point in case the client doesn't specify one, and also as a
+ * safety measure to jump forwards in case the client specifies a
+ * start_lsn that's further in the past than this value.
+ */
+ XLogRecPtr confirmed_flush;
+
+ /*
+ * LSN at which we enabled two_phase commit for this slot or LSN at which
+ * we found a consistent point at the time of slot creation.
+ */
+ XLogRecPtr two_phase_at;
+
+ /*
+ * Allow decoding of prepared transactions?
+ */
+ bool two_phase;
+
+ /* plugin name */
+ NameData plugin;
+} ReplicationSlotPersistentData;
+
+/*
+ * Replication slot on-disk data structure.
+ */
+typedef struct ReplicationSlotOnDisk
+{
+ /* first part of this struct needs to be version independent */
+
+ /* data not covered by checksum */
+ uint32 magic;
+ pg_crc32c checksum;
+
+ /* data covered by checksum */
+ uint32 version;
+ uint32 length;
+
+ /*
+ * The actual data in the slot that follows can differ based on the above
+ * 'version'.
+ */
+
+ ReplicationSlotPersistentData slotdata;
+} ReplicationSlotOnDisk;
+
+/* size of version independent data */
+#define ReplicationSlotOnDiskConstantSize \
+ offsetof(ReplicationSlotOnDisk, slotdata)
+/* size of the part of the slot not covered by the checksum */
+#define ReplicationSlotOnDiskNotChecksummedSize \
+ offsetof(ReplicationSlotOnDisk, version)
+/* size of the part covered by the checksum */
+#define ReplicationSlotOnDiskChecksummedSize \
+ sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskNotChecksummedSize
+/* size of the slot data that is version dependent */
+#define ReplicationSlotOnDiskV2Size \
+ sizeof(ReplicationSlotOnDisk) - ReplicationSlotOnDiskConstantSize
+
+#define SLOT_MAGIC 0x1051CA1 /* format identifier */
+#define SLOT_VERSION 2 /* version for new files */
+
+#endif /* REPL_COMMON_H */
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index f833b1d6dc..183cb025b8 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -15,89 +15,9 @@
#include "storage/lwlock.h"
#include "storage/shmem.h"
#include "storage/spin.h"
+#include "replication/repl_common.h"
#include "replication/walreceiver.h"
-/*
- * Behaviour of replication slots, upon release or crash.
- *
- * Slots marked as PERSISTENT are crash-safe and will not be dropped when
- * released. Slots marked as EPHEMERAL will be dropped when released or after
- * restarts. Slots marked TEMPORARY will be dropped at the end of a session
- * or on error.
- *
- * EPHEMERAL is used as a not-quite-ready state when creating persistent
- * slots. EPHEMERAL slots can be made PERSISTENT by calling
- * ReplicationSlotPersist(). For a slot that goes away at the end of a
- * session, TEMPORARY is the appropriate choice.
- */
-typedef enum ReplicationSlotPersistency
-{
- RS_PERSISTENT,
- RS_EPHEMERAL,
- RS_TEMPORARY
-} ReplicationSlotPersistency;
-
-/*
- * On-Disk data of a replication slot, preserved across restarts.
- */
-typedef struct ReplicationSlotPersistentData
-{
- /* The slot's identifier */
- NameData name;
-
- /* database the slot is active on */
- Oid database;
-
- /*
- * The slot's behaviour when being dropped (or restored after a crash).
- */
- ReplicationSlotPersistency persistency;
-
- /*
- * xmin horizon for data
- *
- * NB: This may represent a value that hasn't been written to disk yet;
- * see notes for effective_xmin, below.
- */
- TransactionId xmin;
-
- /*
- * xmin horizon for catalog tuples
- *
- * NB: This may represent a value that hasn't been written to disk yet;
- * see notes for effective_xmin, below.
- */
- TransactionId catalog_xmin;
-
- /* oldest LSN that might be required by this replication slot */
- XLogRecPtr restart_lsn;
-
- /* restart_lsn is copied here when the slot is invalidated */
- XLogRecPtr invalidated_at;
-
- /*
- * Oldest LSN that the client has acked receipt for. This is used as the
- * start_lsn point in case the client doesn't specify one, and also as a
- * safety measure to jump forwards in case the client specifies a
- * start_lsn that's further in the past than this value.
- */
- XLogRecPtr confirmed_flush;
-
- /*
- * LSN at which we enabled two_phase commit for this slot or LSN at which
- * we found a consistent point at the time of slot creation.
- */
- XLogRecPtr two_phase_at;
-
- /*
- * Allow decoding of prepared transactions?
- */
- bool two_phase;
-
- /* plugin name */
- NameData plugin;
-} ReplicationSlotPersistentData;
-
/*
* Shared memory state of a single replication slot.
*
--
2.25.1
Hi,
On 2022-02-07 10:52:08 +0530, Bharath Rupireddy wrote:
While working on pg_replslotdata tool [1], it was observed that some
of the replication slot structures/enums/macros such as
ReplicationSlotPersistentData, ReplicationSlotPersistency,
ReplicationSlotOnDisk, ReplicationSlotOnDiskXXXX etc. are currently in
replication/slot.h and replication/slot.c. This makes the replication
slot on disk data structures unusable by the external tools/modules.
FWIW, I still don't see a point in pg_replslotdata. And I don't think these
datastructures should ever be accessed outside the server environment.
Greetings,
Andres Freund