summaryrefslogtreecommitdiff
path: root/src/backend/utils/misc/guc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/misc/guc.c')
-rw-r--r--src/backend/utils/misc/guc.c97
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;