Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit af5ced9

Browse files
committed
Further work on connecting the free space map (which is still just a
stub) into the rest of the system. Adopt a cleaner approach to preventing deadlock in concurrent heap_updates: allow RelationGetBufferForTuple to select any page of the rel, and put the onus on it to lock both buffers in a consistent order. Remove no-longer-needed isExtend hack from API of ReleaseAndReadBuffer.
1 parent 0eab92c commit af5ced9

File tree

12 files changed

+379
-231
lines changed

12 files changed

+379
-231
lines changed

src/backend/access/heap/heapam.c

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.120 2001/06/27 23:31:38 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.121 2001/06/29 21:08:23 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -202,8 +202,7 @@ heapgettup(Relation relation,
202202

203203
*buffer = ReleaseAndReadBuffer(*buffer,
204204
relation,
205-
ItemPointerGetBlockNumber(tid),
206-
false);
205+
ItemPointerGetBlockNumber(tid));
207206
if (!BufferIsValid(*buffer))
208207
elog(ERROR, "heapgettup: failed ReadBuffer");
209208

@@ -238,8 +237,7 @@ heapgettup(Relation relation,
238237

239238
*buffer = ReleaseAndReadBuffer(*buffer,
240239
relation,
241-
page,
242-
false);
240+
page);
243241
if (!BufferIsValid(*buffer))
244242
elog(ERROR, "heapgettup: failed ReadBuffer");
245243

@@ -280,8 +278,7 @@ heapgettup(Relation relation,
280278

281279
*buffer = ReleaseAndReadBuffer(*buffer,
282280
relation,
283-
page,
284-
false);
281+
page);
285282
if (!BufferIsValid(*buffer))
286283
elog(ERROR, "heapgettup: failed ReadBuffer");
287284

@@ -374,8 +371,7 @@ heapgettup(Relation relation,
374371

375372
*buffer = ReleaseAndReadBuffer(*buffer,
376373
relation,
377-
page,
378-
false);
374+
page);
379375
if (!BufferIsValid(*buffer))
380376
elog(ERROR, "heapgettup: failed ReadBuffer");
381377

@@ -1088,8 +1084,8 @@ heap_insert(Relation relation, HeapTuple tup)
10881084
heap_tuple_toast_attrs(relation, tup, NULL);
10891085
#endif
10901086

1091-
/* Find buffer for this tuple */
1092-
buffer = RelationGetBufferForTuple(relation, tup->t_len, 0);
1087+
/* Find buffer to insert this tuple into */
1088+
buffer = RelationGetBufferForTuple(relation, tup->t_len, InvalidBuffer);
10931089

10941090
/* NO ELOG(ERROR) from here till changes are logged */
10951091
START_CRIT_SECTION();
@@ -1501,18 +1497,16 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
15011497
* buffer locks on both old and new pages. To avoid deadlock against
15021498
* some other backend trying to get the same two locks in the other
15031499
* order, we must be consistent about the order we get the locks in.
1504-
* We use the rule "lock the higher-numbered page of the relation
1500+
* We use the rule "lock the lower-numbered page of the relation
15051501
* first". To implement this, we must do RelationGetBufferForTuple
1506-
* while not holding the lock on the old page, and we must tell it
1507-
* to give us a page beyond the old page.
1502+
* while not holding the lock on the old page, and we must rely on it
1503+
* to get the locks on both pages in the correct order.
15081504
*/
15091505
if (newtupsize > pagefree)
15101506
{
15111507
/* Assume there's no chance to put newtup on same page. */
15121508
newbuf = RelationGetBufferForTuple(relation, newtup->t_len,
1513-
BufferGetBlockNumber(buffer) + 1);
1514-
/* Now reacquire lock on old tuple's page. */
1515-
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
1509+
buffer);
15161510
}
15171511
else
15181512
{
@@ -1529,8 +1523,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
15291523
*/
15301524
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
15311525
newbuf = RelationGetBufferForTuple(relation, newtup->t_len,
1532-
BufferGetBlockNumber(buffer) + 1);
1533-
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
1526+
buffer);
15341527
}
15351528
else
15361529
{
@@ -1550,7 +1543,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
15501543

15511544
/*
15521545
* At this point newbuf and buffer are both pinned and locked,
1553-
* and newbuf has enough space for the new tuple.
1546+
* and newbuf has enough space for the new tuple. If they are
1547+
* the same buffer, only one pin is held.
15541548
*/
15551549

15561550
/* NO ELOG(ERROR) from here till changes are logged */

0 commit comments

Comments
 (0)