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);