aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2013-11-29 11:26:41 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2013-11-29 21:47:15 -0300
commit1df0122daa6510eed4146033379a5055f66f5a8e (patch)
tree8784e3d301ca6cb27cf3dfc51e8285a4b1dde924 /src/backend/access/transam/xlog.c
parentf54106f77e6d71cbb3fa0924095e5142341fde2b (diff)
downloadpostgresql-1df0122daa6510eed4146033379a5055f66f5a8e.tar.gz
postgresql-1df0122daa6510eed4146033379a5055f66f5a8e.zip
Truncate pg_multixact/'s contents during crash recovery
Commit 9dc842f08 of 8.2 era prevented MultiXact truncation during crash recovery, because there was no guarantee that enough state had been setup, and because it wasn't deemed to be a good idea to remove data during crash recovery anyway. Since then, due to Hot-Standby, streaming replication and PITR, the amount of time a cluster can spend doing crash recovery has increased significantly, to the point that a cluster may even never come out of it. This has made not truncating the content of pg_multixact/ not defensible anymore. To fix, take care to setup enough state for multixact truncation before crash recovery starts (easy since checkpoints contain the required information), and move the current end-of-recovery actions to a new TrimMultiXact() function, analogous to TrimCLOG(). At some later point, this should probably done similarly to the way clog.c is doing it, which is to just WAL log truncations, but we can't do that for the back branches. Back-patch to 9.0. 8.4 also has the problem, but since there's no hot standby there, it's much less pressing. In 9.2 and earlier, this patch is simpler than in newer branches, because multixact access during recovery isn't required. Add appropriate checks to make sure that's not happening. Andres Freund
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rwxr-xr-xsrc/backend/access/transam/xlog.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index de19d2240fc..b68230d1969 100755
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6333,6 +6333,14 @@ StartupXLOG(void)
XLogCtl->ckptXid = checkPoint.nextXid;
/*
+ * Startup MultiXact. We need to do this early for two reasons: one
+ * is that we might try to access multixacts when we do tuple freezing,
+ * and the other is we need its state initialized because we attempt
+ * truncation during restartpoints.
+ */
+ StartupMultiXact();
+
+ /*
* Initialize unlogged LSN. On a clean shutdown, it's restored from the
* control file. On recovery, all unlogged relations are blown away, so
* the unlogged LSN counter can be reset too.
@@ -6532,8 +6540,9 @@ StartupXLOG(void)
ProcArrayInitRecovery(ShmemVariableCache->nextXid);
/*
- * Startup commit log and subtrans only. Other SLRUs are not
- * maintained during recovery and need not be started yet.
+ * Startup commit log and subtrans only. MultiXact has already
+ * been started up and other SLRUs are not maintained during
+ * recovery and need not be started yet.
*/
StartupCLOG();
StartupSUBTRANS(oldestActiveXID);
@@ -7197,8 +7206,8 @@ StartupXLOG(void)
/*
* Perform end of recovery actions for any SLRUs that need it.
*/
- StartupMultiXact();
TrimCLOG();
+ TrimMultiXact();
/* Reload shared-memory state for prepared transactions */
RecoverPreparedTransactions();
@@ -8620,6 +8629,21 @@ CreateRestartPoint(int flags)
LWLockRelease(ControlFileLock);
/*
+ * Due to an historical accident multixact truncations are not WAL-logged,
+ * but just performed everytime the mxact horizon is increased. So, unless
+ * we explicitly execute truncations on a standby it will never clean out
+ * /pg_multixact which obviously is bad, both because it uses space and
+ * because we can wrap around into pre-existing data...
+ *
+ * We can only do the truncation here, after the UpdateControlFile()
+ * above, because we've now safely established a restart point, that
+ * guarantees we will not need need to access those multis.
+ *
+ * It's probably worth improving this.
+ */
+ TruncateMultiXact(lastCheckPoint.oldestMulti);
+
+ /*
* Delete old log files (those no longer needed even for previous
* checkpoint/restartpoint) to prevent the disk holding the xlog from
* growing full.