1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-11 20:28:21 +03:00

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.
This commit is contained in:
Tom Lane
2001-06-29 21:08:25 +00:00
parent 0eab92c0e6
commit af5ced9cfd
12 changed files with 381 additions and 233 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.120 2001/06/27 23:31:38 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.121 2001/06/29 21:08:23 tgl Exp $
*
*
* INTERFACE ROUTINES
@ -202,8 +202,7 @@ heapgettup(Relation relation,
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
ItemPointerGetBlockNumber(tid),
false);
ItemPointerGetBlockNumber(tid));
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
@ -238,8 +237,7 @@ heapgettup(Relation relation,
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
page,
false);
page);
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
@ -280,8 +278,7 @@ heapgettup(Relation relation,
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
page,
false);
page);
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
@ -374,8 +371,7 @@ heapgettup(Relation relation,
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
page,
false);
page);
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
@ -1088,8 +1084,8 @@ heap_insert(Relation relation, HeapTuple tup)
heap_tuple_toast_attrs(relation, tup, NULL);
#endif
/* Find buffer for this tuple */
buffer = RelationGetBufferForTuple(relation, tup->t_len, 0);
/* Find buffer to insert this tuple into */
buffer = RelationGetBufferForTuple(relation, tup->t_len, InvalidBuffer);
/* NO ELOG(ERROR) from here till changes are logged */
START_CRIT_SECTION();
@ -1501,18 +1497,16 @@ l2:
* buffer locks on both old and new pages. To avoid deadlock against
* some other backend trying to get the same two locks in the other
* order, we must be consistent about the order we get the locks in.
* We use the rule "lock the higher-numbered page of the relation
* We use the rule "lock the lower-numbered page of the relation
* first". To implement this, we must do RelationGetBufferForTuple
* while not holding the lock on the old page, and we must tell it
* to give us a page beyond the old page.
* while not holding the lock on the old page, and we must rely on it
* to get the locks on both pages in the correct order.
*/
if (newtupsize > pagefree)
{
/* Assume there's no chance to put newtup on same page. */
newbuf = RelationGetBufferForTuple(relation, newtup->t_len,
BufferGetBlockNumber(buffer) + 1);
/* Now reacquire lock on old tuple's page. */
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
buffer);
}
else
{
@ -1529,8 +1523,7 @@ l2:
*/
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
newbuf = RelationGetBufferForTuple(relation, newtup->t_len,
BufferGetBlockNumber(buffer) + 1);
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
buffer);
}
else
{
@ -1550,7 +1543,8 @@ l2:
/*
* At this point newbuf and buffer are both pinned and locked,
* and newbuf has enough space for the new tuple.
* and newbuf has enough space for the new tuple. If they are
* the same buffer, only one pin is held.
*/
/* NO ELOG(ERROR) from here till changes are logged */