diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index ebc1cce09e9..94bdfc407c2 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -2144,6 +2144,16 @@ ltrmark:; buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); + /* + * Although we already know this tuple is valid, we must lock the + * buffer to ensure that no one has a buffer cleanup lock; otherwise + * they might move the tuple while we try to copy it. But we can + * release the lock before actually doing the heap_copytuple call, + * since holding pin is sufficient to prevent anyone from getting a + * cleanup lock they don't already hold. + */ + LockBuffer(buffer, BUFFER_LOCK_SHARE); + dp = (PageHeader) BufferGetPage(buffer); lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid)); @@ -2153,6 +2163,8 @@ ltrmark:; tuple.t_len = ItemIdGetLength(lp); tuple.t_self = *tid; tuple.t_tableOid = RelationGetRelid(relation); + + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); } result = heap_copytuple(&tuple);