diff options
Diffstat (limited to 'src/backend/utils/misc/guc.c')
-rw-r--r-- | src/backend/utils/misc/guc.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index c53aededcb4..de85eca6a8f 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -28,9 +28,11 @@ #include "access/commit_ts.h" #include "access/gin.h" +#include "access/rmgr.h" #include "access/transam.h" #include "access/twophase.h" #include "access/xact.h" +#include "access/xlog_internal.h" #include "catalog/namespace.h" #include "commands/async.h" #include "commands/prepare.h" @@ -147,6 +149,10 @@ static bool call_enum_check_hook(struct config_enum * conf, int *newval, static bool check_log_destination(char **newval, void **extra, GucSource source); static void assign_log_destination(const char *newval, void *extra); +static bool check_wal_consistency_checking(char **newval, void **extra, + GucSource source); +static void assign_wal_consistency_checking(const char *newval, void *extra); + #ifdef HAVE_SYSLOG static int syslog_facility = LOG_LOCAL0; #else @@ -3572,6 +3578,17 @@ static struct config_string ConfigureNamesString[] = check_cluster_name, NULL, NULL }, + { + {"wal_consistency_checking", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Sets the WAL resource managers for which WAL consistency checks are done."), + gettext_noop("Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay."), + GUC_LIST_INPUT | GUC_NOT_IN_SAMPLE + }, + &wal_consistency_checking_string, + "", + check_wal_consistency_checking, assign_wal_consistency_checking, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL @@ -9889,6 +9906,86 @@ call_enum_check_hook(struct config_enum * conf, int *newval, void **extra, */ static bool +check_wal_consistency_checking(char **newval, void **extra, GucSource source) +{ + char *rawstring; + List *elemlist; + ListCell *l; + bool newwalconsistency[RM_MAX_ID + 1]; + + /* Initialize the array */ + MemSet(newwalconsistency, 0, (RM_MAX_ID + 1) * sizeof(bool)); + + /* Need a modifiable copy of string */ + rawstring = pstrdup(*newval); + + /* Parse string into list of identifiers */ + if (!SplitIdentifierString(rawstring, ',', &elemlist)) + { + /* syntax error in list */ + GUC_check_errdetail("List syntax is invalid."); + pfree(rawstring); + list_free(elemlist); + return false; + } + + foreach(l, elemlist) + { + char *tok = (char *) lfirst(l); + bool found = false; + RmgrId rmid; + + /* Check for 'all'. */ + if (pg_strcasecmp(tok, "all") == 0) + { + for (rmid = 0; rmid <= RM_MAX_ID; rmid++) + if (RmgrTable[rmid].rm_mask != NULL) + newwalconsistency[rmid] = true; + found = true; + } + else + { + /* + * Check if the token matches with any individual resource + * manager. + */ + for (rmid = 0; rmid <= RM_MAX_ID; rmid++) + { + if (pg_strcasecmp(tok, RmgrTable[rmid].rm_name) == 0 && + RmgrTable[rmid].rm_mask != NULL) + { + newwalconsistency[rmid] = true; + found = true; + } + } + } + + /* If a valid resource manager is found, check for the next one. */ + if (!found) + { + GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); + pfree(rawstring); + list_free(elemlist); + return false; + } + } + + pfree(rawstring); + list_free(elemlist); + + /* assign new value */ + *extra = guc_malloc(ERROR, (RM_MAX_ID + 1) * sizeof(bool)); + memcpy(*extra, newwalconsistency, (RM_MAX_ID + 1) * sizeof(bool)); + return true; +} + +static void +assign_wal_consistency_checking(const char *newval, void *extra) +{ + wal_consistency_checking = (bool *) extra; +} + +static bool check_log_destination(char **newval, void **extra, GucSource source) { char *rawstring; |