diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2007-06-04 15:56:28 +0000 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2007-06-04 15:56:28 +0000 |
commit | 853d1c3103fa961ae6219f0281885b345593d101 (patch) | |
tree | 464fedaf8f2bd9ee41344e57c4be16ec874155e5 /src/backend/access/gin/ginxlog.c | |
parent | aae5403278f995e240d956848cdf95fc173693ae (diff) | |
download | postgresql-853d1c3103fa961ae6219f0281885b345593d101.tar.gz postgresql-853d1c3103fa961ae6219f0281885b345593d101.zip |
Fix bundle bugs of GIN:
- Fix possible deadlock between UPDATE and VACUUM queries. Bug never was
observed in 8.2, but it still exist there. HEAD is more sensitive to
bug after recent "ring" of buffer improvements.
- Fix WAL creation: if parent page is stored as is after split then
incomplete split isn't removed during replay. This happens rather rare, only
on large tables with a lot of updates/inserts.
- Fix WAL replay: there was wrong test of XLR_BKP_BLOCK_* for left
page after deletion of page. That causes wrong rightlink field: it pointed
to deleted page.
- add checking of match of clearing incomplete split
- cleanup incomplete split list after proceeding
All of this chages doesn't change on-disk storage, so backpatch...
But second point may be an issue for replaying logs from previous version.
Diffstat (limited to 'src/backend/access/gin/ginxlog.c')
-rw-r--r-- | src/backend/access/gin/ginxlog.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c index a9ff2a4a4dd..9d246783d6a 100644 --- a/src/backend/access/gin/ginxlog.c +++ b/src/backend/access/gin/ginxlog.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gin/ginxlog.c,v 1.6 2007/01/05 22:19:21 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/gin/ginxlog.c,v 1.7 2007/06/04 15:56:28 teodor Exp $ *------------------------------------------------------------------------- */ #include "postgres.h" @@ -53,6 +53,7 @@ static void forgetIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber updateBlkno) { ListCell *l; + bool found = false; foreach(l, incomplete_splits) { @@ -61,9 +62,16 @@ forgetIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber updat if (RelFileNodeEquals(node, split->node) && leftBlkno == split->leftBlkno && updateBlkno == split->rightBlkno) { incomplete_splits = list_delete_ptr(incomplete_splits, split); + found = true; break; } } + + if (!found) + { + elog(ERROR, "failed to identify corresponding split record for %u/%u/%u", + node.relNode, leftBlkno, updateBlkno); + } } static void @@ -416,7 +424,7 @@ ginRedoDeletePage(XLogRecPtr lsn, XLogRecord *record) UnlockReleaseBuffer(buffer); } - if (!(record->xl_info & XLR_BKP_BLOCK_2) && data->leftBlkno != InvalidBlockNumber) + if (!(record->xl_info & XLR_BKP_BLOCK_3) && data->leftBlkno != InvalidBlockNumber) { buffer = XLogReadBuffer(reln, data->leftBlkno, false); page = BufferGetPage(buffer); @@ -594,6 +602,7 @@ gin_xlog_cleanup(void) MemoryContextSwitchTo(topCtx); MemoryContextDelete(opCtx); + incomplete_splits = NIL; } bool |