1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-16 15:02:33 +03:00

Adjust btbulkdelete logic so that only one WAL record is issued while

deleting multiple index entries on a single index page.  This makes for
a very substantial reduction in the amount of WAL traffic during a
large delete operation.
This commit is contained in:
Tom Lane
2003-02-23 22:43:09 +00:00
parent 13dadef8b5
commit 3bbd6af37c
4 changed files with 135 additions and 107 deletions

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.61 2003/02/23 06:17:13 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.62 2003/02/23 22:43:08 tgl Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
@@ -618,26 +618,34 @@ _bt_metaproot(Relation rel, BlockNumber rootbknum, uint32 level)
}
/*
* Delete an item from a btree page.
* Delete item(s) from a btree page.
*
* This must only be used for deleting leaf items. Deleting an item on a
* non-leaf page has to be done as part of an atomic action that includes
* deleting the page it points to.
*
* This routine assumes that the caller has pinned and locked the buffer,
* and will write the buffer afterwards.
* and will write the buffer afterwards. Also, the given itemnos *must*
* appear in increasing order in the array.
*/
void
_bt_itemdel(Relation rel, Buffer buf, ItemPointer tid)
_bt_delitems(Relation rel, Buffer buf,
OffsetNumber *itemnos, int nitems)
{
Page page = BufferGetPage(buf);
OffsetNumber offno;
offno = ItemPointerGetOffsetNumber(tid);
int i;
/* No elog(ERROR) until changes are logged */
START_CRIT_SECTION();
PageIndexTupleDelete(page, offno);
/*
* Delete the items in reverse order so we don't have to think about
* adjusting item numbers for previous deletions.
*/
for (i = nitems - 1; i >= 0; i--)
{
PageIndexTupleDelete(page, itemnos[i]);
}
/* XLOG stuff */
if (!rel->rd_istemp)
@@ -646,17 +654,30 @@ _bt_itemdel(Relation rel, Buffer buf, ItemPointer tid)
XLogRecPtr recptr;
XLogRecData rdata[2];
xlrec.target.node = rel->rd_node;
xlrec.target.tid = *tid;
xlrec.node = rel->rd_node;
xlrec.block = BufferGetBlockNumber(buf);
rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeDelete;
rdata[0].next = &(rdata[1]);
/*
* The target-offsets array is not in the buffer, but pretend
* that it is. When XLogInsert stores the whole buffer, the offsets
* array need not be stored too.
*/
rdata[1].buffer = buf;
rdata[1].data = NULL;
rdata[1].len = 0;
if (nitems > 0)
{
rdata[1].data = (char *) itemnos;
rdata[1].len = nitems * sizeof(OffsetNumber);
}
else
{
rdata[1].data = NULL;
rdata[1].len = 0;
}
rdata[1].next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_DELETE, rdata);