On Fri, 2007-06-01 at 19:11 +0400, Teodor Sigaev wrote: > > <2007-06-01 16:28:51.708 CEST:%> LOG: GIN incomplete split root:11118 > > l:45303 r:111740 at redo CA/C8243C28 > ... > > <2007-06-01 16:38:23.133 CEST:%> LOG: GIN incomplete split root:11118 > > l:45303 r:111740 at redo CA/C8243C28 > > Looks like a bug in GIN. I'll play with it. Can you provide more details about > your test? Agreed, sorry about that. I note that forgetIncompleteSplit doesn't report anything if it fails to find an incomplete split when it looks for it. ISTM that either we have 1) sometimes a starting split, but no ending split 2) a starting split, but we try to remove the wrong split later, for some reason. i.e. we make the change correctly, just misjudge the xlog somehow. (1) would show up on data retrieval tests, but (2) would show up only on recovery. So I would think it is (2). I'd suggest we throw an error, as shown in the enclosed patch. Frank, can you give that a whirl to provide Teodor with something more to work with? Thanks. Neither GIST nor B-tree seems to throw an error in corresponding locations also, so the potential for not being able to track this is high. I'd want to throw errors in those locations also. -- Simon Riggs EnterpriseDB http://www.enterprisedb.com
Index: src/backend/access/gin/ginxlog.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/access/gin/ginxlog.c,v retrieving revision 1.6 diff -c -r1.6 ginxlog.c *** src/backend/access/gin/ginxlog.c 5 Jan 2007 22:19:21 -0000 1.6 --- src/backend/access/gin/ginxlog.c 1 Jun 2007 16:22:42 -0000 *************** *** 26,37 **** BlockNumber leftBlkno; BlockNumber rightBlkno; BlockNumber rootBlkno; } ginIncompleteSplit; static List *incomplete_splits; static void ! pushIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber rightBlkno, BlockNumber rootBlkno) { ginIncompleteSplit *split; --- 26,41 ---- BlockNumber leftBlkno; BlockNumber rightBlkno; BlockNumber rootBlkno; + XLogRecPtr lsn; } ginIncompleteSplit; static List *incomplete_splits; + static void gin_dump_incomplete_splits(void); + static void ! pushIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, ! BlockNumber rightBlkno, BlockNumber rootBlkno, XLogRecPtr lsn) { ginIncompleteSplit *split; *************** *** 43,48 **** --- 47,53 ---- split->leftBlkno = leftBlkno; split->rightBlkno = rightBlkno; split->rootBlkno = rootBlkno; + split->lsn = lsn; incomplete_splits = lappend(incomplete_splits, split); *************** *** 53,58 **** --- 58,64 ---- forgetIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber updateBlkno) { ListCell *l; + bool found = false; foreach(l, incomplete_splits) { *************** *** 61,69 **** --- 67,83 ---- if (RelFileNodeEquals(node, split->node) && leftBlkno == split->leftBlkno && updateBlkno == split->rightBlkno) { incomplete_splits = list_delete_ptr(incomplete_splits, split); + found = true; break; } } + + if (!found) + { + gin_dump_incomplete_splits(); + elog(ERROR, "failed to identify corresponding split record for %u/%u/%u", + node.relNode, leftBlkno, updateBlkno); + } } static void *************** *** 324,330 **** UnlockReleaseBuffer(rootBuf); } else ! pushIncompleteSplit(data->node, data->lblkno, data->rblkno, data->rootBlkno); UnlockReleaseBuffer(rbuffer); UnlockReleaseBuffer(lbuffer); --- 338,344 ---- UnlockReleaseBuffer(rootBuf); } else ! pushIncompleteSplit(data->node, data->lblkno, data->rblkno, data->rootBlkno, lsn); UnlockReleaseBuffer(rbuffer); UnlockReleaseBuffer(lbuffer); *************** *** 600,605 **** --- 614,637 ---- gin_safe_restartpoint(void) { if (incomplete_splits) + { + gin_dump_incomplete_splits(); return false; + } return true; } + + static void + gin_dump_incomplete_splits(void) + { + ListCell *l; + int nsplits = list_length(incomplete_splits); + + elog(LOG,"GIN incomplete splits=%d", nsplits); + foreach(l, incomplete_splits) + { + ginIncompleteSplit *split = (ginIncompleteSplit *) lfirst(l); + elog(LOG,"GIN incomplete split root:%u l:%u r:%u at redo %X/%X", + split->rootBlkno, split->leftBlkno, split->rightBlkno, split->lsn.xlogid, split->lsn.xrecoff); + } + }