diff options
Diffstat (limited to 'src/backend/access')
-rw-r--r-- | src/backend/access/heap/heapam.c | 43 | ||||
-rw-r--r-- | src/backend/access/transam/xact.c | 26 |
2 files changed, 15 insertions, 54 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index e09f454e42d..0c2c5f0cd78 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -6115,24 +6115,6 @@ heap_inplace_update_and_unlock(Relation relation, if (oldlen != newlen || htup->t_hoff != tuple->t_data->t_hoff) elog(ERROR, "wrong tuple length"); - /* - * Construct shared cache inval if necessary. Note that because we only - * pass the new version of the tuple, this mustn't be used for any - * operations that could change catcache lookup keys. But we aren't - * bothering with index updates either, so that's true a fortiori. - */ - CacheInvalidateHeapTupleInplace(relation, tuple, NULL); - - /* - * Unlink relcache init files as needed. If unlinking, acquire - * RelCacheInitLock until after associated invalidations. By doing this - * in advance, if we checkpoint and then crash between inplace - * XLogInsert() and inval, we don't rely on StartupXLOG() -> - * RelationCacheInitFileRemove(). That uses elevel==LOG, so replay would - * neglect to PANIC on EIO. - */ - PreInplace_Inval(); - /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); @@ -6176,28 +6158,17 @@ heap_inplace_update_and_unlock(Relation relation, PageSetLSN(BufferGetPage(buffer), recptr); } - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - - /* - * Send invalidations to shared queue. SearchSysCacheLocked1() assumes we - * do this before UnlockTuple(). - * - * If we're mutating a tuple visible only to this transaction, there's an - * equivalent transactional inval from the action that created the tuple, - * and this inval is superfluous. - */ - AtInplace_Inval(); - END_CRIT_SECTION(); - UnlockTuple(relation, &tuple->t_self, InplaceUpdateTupleLock); - AcceptInvalidationMessages(); /* local processing of just-sent inval */ + heap_inplace_unlock(relation, oldtup, buffer); /* - * Queue a transactional inval. The immediate invalidation we just sent - * is the only one known to be necessary. To reduce risk from the - * transition to immediate invalidation, continue sending a transactional - * invalidation like we've long done. Third-party code might rely on it. + * Send out shared cache inval if necessary. Note that because we only + * pass the new version of the tuple, this mustn't be used for any + * operations that could change catcache lookup keys. But we aren't + * bothering with index updates either, so that's true a fortiori. + * + * XXX ROLLBACK discards the invalidation. See test inplace-inval.spec. */ if (!IsBootstrapProcessingMode()) CacheInvalidateHeapTuple(relation, tuple, NULL); diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index cda6e336138..ffe26e26f66 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -1249,24 +1249,14 @@ RecordTransactionCommit(void) /* * Transactions without an assigned xid can contain invalidation - * messages. While inplace updates do this, this is not known to be - * necessary; see comment at inplace CacheInvalidateHeapTuple(). - * Extensions might still rely on this capability, and standbys may - * need to process those invals. We can't emit a commit record - * without an xid, and we don't want to force assigning an xid, - * because that'd be problematic for e.g. vacuum. Hence we emit a - * bespoke record for the invalidations. We don't want to use that in - * case a commit record is emitted, so they happen synchronously with - * commits (besides not wanting to emit more WAL records). - * - * XXX Every known use of this capability is a defect. Since an XID - * isn't controlling visibility of the change that prompted invals, - * other sessions need the inval even if this transactions aborts. - * - * ON COMMIT DELETE ROWS does a nontransactional index_build(), which - * queues a relcache inval, including in transactions without an xid - * that had read the (empty) table. Standbys don't need any ON COMMIT - * DELETE ROWS invals, but we've not done the work to withhold them. + * messages (e.g. explicit relcache invalidations or catcache + * invalidations for inplace updates); standbys need to process those. + * We can't emit a commit record without an xid, and we don't want to + * force assigning an xid, because that'd be problematic for e.g. + * vacuum. Hence we emit a bespoke record for the invalidations. We + * don't want to use that in case a commit record is emitted, so they + * happen synchronously with commits (besides not wanting to emit more + * WAL records). */ if (nmsgs != 0) { |