| From: | Andres Freund <andres(at)2ndquadrant(dot)com> | 
|---|---|
| To: | pgsql-hackers(at)postgresql(dot)org | 
| Subject: | missing LockBuffer(buffer, BUFFER_LOCK_SHARE) in trigger.c GetTupleForTrigger? | 
| Date: | 2012-11-29 21:49:57 | 
| Message-ID: | 20121129214957.GD29711@awork2.anarazel.de | 
| Views: | Whole Thread | Raw Message | Download mbox | Resend email | 
| Thread: | |
| Lists: | pgsql-hackers | 
Hi,
while looking at trigger.c from the POV of foreign key locks I noticed
that GetTupleForTrigger commentless assumes it can just look at a pages
content without a
    LockBuffer(buffer, BUFFER_LOCK_SHARE);
That code path is only reached for AFTER ... FOR EACH ROW ... triggers,
so its fine it's not locking the tuple itself. That already needs to
have happened before.
The code in question:
if (newslot_which_is_passed_by_before_triggers)
	...
else
{
	Page		page;
	ItemId		lp;
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
	page = BufferGetPage(buffer);
	lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsNormal(lp));
	tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
	tuple.t_len = ItemIdGetLength(lp);
	tuple.t_self = *tid;
	tuple.t_tableOid = RelationGetRelid(relation);
}
result = heap_copytuple(&tuple);
ReleaseBuffer(buffer);
As can be seen in the excerpt above this is basically a very stripped
down heap_fetch(). But without any locking on the buffer we just read.
I can't believe this is safe? Just about anything but eviction could
happen to that buffer at that moment?
Am I missing something?
Andres
-- 
 Andres Freund	                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Merlin Moncure | 2012-11-29 21:52:11 | Re: json accessors | 
| Previous Message | Andrew Dunstan | 2012-11-29 21:24:13 | Re: Overlength socket paths (was Re: [COMMITTERS] pgsql: Refactor flex and bison make rules) |