aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/parallel.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-07-18 12:15:16 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2018-07-18 12:15:16 -0400
commit3cb646264e8ced9f25557ce271284da512d92043 (patch)
treec3d59dca839c84eca33125fcb0d9d4e1c64316ac /src/backend/access/transam/parallel.c
parent6b387179baab8d0e5da6570678eefbe61f3acc79 (diff)
downloadpostgresql-3cb646264e8ced9f25557ce271284da512d92043.tar.gz
postgresql-3cb646264e8ced9f25557ce271284da512d92043.zip
Use a ResourceOwner to track buffer pins in all cases.
Historically, we've allowed auxiliary processes to take buffer pins without tracking them in a ResourceOwner. However, that creates problems for error recovery. In particular, we've seen multiple reports of assertion crashes in the startup process when it gets an error while holding a buffer pin, as for example if it gets ENOSPC during a write. In a non-assert build, the process would simply exit without releasing the pin at all. We've gotten away with that so far just because a failure exit of the startup process translates to a database crash anyhow; but any similar behavior in other aux processes could result in stuck pins and subsequent problems in vacuum. To improve this, institute a policy that we must *always* have a resowner backing any attempt to pin a buffer, which we can enforce just by removing the previous special-case code in resowner.c. Add infrastructure to make it easy to create a process-lifespan AuxProcessResourceOwner and clear out its contents at appropriate times. Replace existing ad-hoc resowner management in bgwriter.c and other aux processes with that. (Thus, while the startup process gains a resowner where it had none at all before, some other aux process types are replacing an ad-hoc resowner with this code.) Also use the AuxProcessResourceOwner to manage buffer pins taken during StartupXLOG and ShutdownXLOG, even when those are being run in a bootstrap process or a standalone backend rather than a true auxiliary process. In passing, remove some other ad-hoc resource owner creations that had gotten cargo-culted into various other places. As far as I can tell that was all unnecessary, and if it had been necessary it was incomplete, due to lacking any provision for clearing those resowners later. (Also worth noting in this connection is that a process that hasn't called InitBufferPoolBackend has no business accessing buffers; so there's more to do than just add the resowner if we want to touch buffers in processes not covered by this patch.) Although this fixes a very old bug, no back-patch, because there's no evidence of any significant problem in non-assert builds. Patch by me, pursuant to a report from Justin Pryzby. Thanks to Robert Haas and Kyotaro Horiguchi for reviews. Discussion: https://postgr.es/m/20180627233939.GA10276@telsasoft.com
Diffstat (limited to 'src/backend/access/transam/parallel.c')
-rw-r--r--src/backend/access/transam/parallel.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 4e32cfff500..30ddf94c952 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -37,7 +37,6 @@
#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/memutils.h"
-#include "utils/resowner.h"
#include "utils/snapmgr.h"
#include "utils/typcache.h"
@@ -1220,16 +1219,19 @@ ParallelWorkerMain(Datum main_arg)
Assert(ParallelWorkerNumber == -1);
memcpy(&ParallelWorkerNumber, MyBgworkerEntry->bgw_extra, sizeof(int));
- /* Set up a memory context and resource owner. */
- Assert(CurrentResourceOwner == NULL);
- CurrentResourceOwner = ResourceOwnerCreate(NULL, "parallel toplevel");
+ /* Set up a memory context to work in, just for cleanliness. */
CurrentMemoryContext = AllocSetContextCreate(TopMemoryContext,
"Parallel worker",
ALLOCSET_DEFAULT_SIZES);
/*
- * Now that we have a resource owner, we can attach to the dynamic shared
- * memory segment and read the table of contents.
+ * Attach to the dynamic shared memory segment for the parallel query, and
+ * find its table of contents.
+ *
+ * Note: at this point, we have not created any ResourceOwner in this
+ * process. This will result in our DSM mapping surviving until process
+ * exit, which is fine. If there were a ResourceOwner, it would acquire
+ * ownership of the mapping, but we have no need for that.
*/
seg = dsm_attach(DatumGetUInt32(main_arg));
if (seg == NULL)
@@ -1393,7 +1395,7 @@ ParallelWorkerMain(Datum main_arg)
/* Must exit parallel mode to pop active snapshot. */
ExitParallelMode();
- /* Must pop active snapshot so resowner.c doesn't complain. */
+ /* Must pop active snapshot so snapmgr.c doesn't complain. */
PopActiveSnapshot();
/* Shut down the parallel-worker transaction. */