add_check_hook.patch
application/octet-stream
Filename: add_check_hook.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/transam/xloglevelworker.c | 20 | 0 |
| src/backend/replication/walsender.c | 22 | 0 |
| src/backend/utils/misc/guc_tables.c | 1 | 1 |
| src/include/replication/walsender.h | 1 | 0 |
| src/include/utils/guc_hooks.h | 1 | 0 |
diff --git a/src/backend/access/transam/xloglevelworker.c b/src/backend/access/transam/xloglevelworker.c
index 286ee411f6..cca0587012 100644
--- a/src/backend/access/transam/xloglevelworker.c
+++ b/src/backend/access/transam/xloglevelworker.c
@@ -28,6 +28,7 @@
#include "postmaster/pgarch.h"
#include "replication/logicalxlog.h"
#include "replication/slot.h"
+#include "replication/walsender.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/procsignal.h"
@@ -612,3 +613,22 @@ show_wal_level(void)
else
return "logical";
}
+
+bool
+check_wal_level(int *newval, void **extra, GucSource source)
+{
+ int newWalLevel = *newval;
+
+ if (newWalLevel >= wal_level)
+ return true;
+
+ if (newWalLevel == WAL_LEVEL_MINIMAL && DoesWalSndExists())
+ {
+ GUC_check_errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE);
+ GUC_check_errmsg("wal_level cannot be set to \"minimal\" while walsender exists");
+ return false;
+ }
+
+ return true;
+
+}
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 9d0b33cf83..5a8e0b001f 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -3529,6 +3529,28 @@ WalSndRqstFileReload(void)
}
}
+bool
+DoesWalSndExists(void)
+{
+ bool result = false;
+
+ for (int i = 0; i < max_wal_senders; i++)
+ {
+ WalSnd *walsnd = &WalSndCtl->walsnds[i];
+
+ SpinLockAcquire(&walsnd->mutex);
+ if (walsnd->pid == 0)
+ {
+ SpinLockRelease(&walsnd->mutex);
+ result = true;
+ break;
+ }
+ SpinLockRelease(&walsnd->mutex);
+ }
+
+ return result;
+}
+
/*
* Handle PROCSIG_WALSND_INIT_STOPPING signal.
*/
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index b181bb7b6a..6fc0440535 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -5069,7 +5069,7 @@ struct config_enum ConfigureNamesEnum[] =
},
&wal_level,
WAL_LEVEL_REPLICA, wal_level_options,
- NULL, NULL, show_wal_level
+ check_wal_level, NULL, show_wal_level
},
{
diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h
index d6d426915e..b2ed9b430a 100644
--- a/src/include/replication/walsender.h
+++ b/src/include/replication/walsender.h
@@ -49,6 +49,7 @@ extern void WalSndInitStopping(void);
extern void WalSndWaitStopping(void);
extern void HandleWalSndInitStopping(void);
extern void WalSndRqstFileReload(void);
+extern bool DoesWalSndExists(void);
/*
* Remember that we want to wakeup walsenders later
diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h
index 22180b2016..b5bb692068 100644
--- a/src/include/utils/guc_hooks.h
+++ b/src/include/utils/guc_hooks.h
@@ -169,6 +169,7 @@ extern bool check_wal_buffers(int *newval, void **extra, GucSource source);
extern bool check_wal_consistency_checking(char **newval, void **extra,
GucSource source);
extern void assign_wal_consistency_checking(const char *newval, void *extra);
+extern bool check_wal_level(int *newval, void **extra, GucSource source);
extern const char *show_wal_level(void);
extern bool check_wal_segment_size(int *newval, void **extra, GucSource source);
extern void assign_wal_sync_method(int new_wal_sync_method, void *extra);