Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbf5ccf3

Browse files
committed
- Add check of already changed page while replay WAL. This touches only
ginRedoInsert(), because other ginRedo* functions rewrite whole page ormake changes which could be applied several times without consistent's loss- Remove check of identifying of corresponding split record:it's possible that replaying of WAL starts after actual page split, but beforeremoving of that split from incomplete splits list. In this case, that checkcause FATAL error.Per stress test which reproduces bug reported by Craig McElroy<craig.mcelroy@contegix.com>
1 parentf7967d4 commitbf5ccf3

File tree

1 file changed

+60
-52
lines changed

1 file changed

+60
-52
lines changed

‎src/backend/access/gin/ginxlog.c

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gin/ginxlog.c,v 1.9 2007/09/20 17:56:30 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gin/ginxlog.c,v 1.10 2007/10/29 19:26:57 teodor Exp $
1212
*-------------------------------------------------------------------------
1313
*/
1414
#include"postgres.h"
@@ -53,7 +53,6 @@ static void
5353
forgetIncompleteSplit(RelFileNodenode,BlockNumberleftBlkno,BlockNumberupdateBlkno)
5454
{
5555
ListCell*l;
56-
boolfound= false;
5756

5857
foreach(l,incomplete_splits)
5958
{
@@ -62,16 +61,9 @@ forgetIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber updat
6261
if (RelFileNodeEquals(node,split->node)&&leftBlkno==split->leftBlkno&&updateBlkno==split->rightBlkno)
6362
{
6463
incomplete_splits=list_delete_ptr(incomplete_splits,split);
65-
found= true;
6664
break;
6765
}
6866
}
69-
70-
if (!found)
71-
{
72-
elog(ERROR,"failed to identify corresponding split record for %u/%u/%u",
73-
node.relNode,leftBlkno,updateBlkno);
74-
}
7567
}
7668

7769
staticvoid
@@ -129,7 +121,7 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
129121
Bufferbuffer;
130122
Pagepage;
131123

132-
/* nothing else to do if page was backed up(and no info to do it with)*/
124+
/* nothing else to do if page was backed up */
133125
if (record->xl_info&XLR_BKP_BLOCK_1)
134126
return;
135127

@@ -143,74 +135,90 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
143135
Assert(data->isDelete== FALSE);
144136
Assert(GinPageIsData(page));
145137

146-
if (data->isLeaf)
138+
if ( !XLByteLE(lsn,PageGetLSN(page)))
147139
{
148-
OffsetNumberi;
149-
ItemPointerData*items= (ItemPointerData*) (XLogRecGetData(record)+sizeof(ginxlogInsert));
140+
if (data->isLeaf)
141+
{
142+
OffsetNumberi;
143+
ItemPointerData*items= (ItemPointerData*) (XLogRecGetData(record)+sizeof(ginxlogInsert));
150144

151-
Assert(GinPageIsLeaf(page));
152-
Assert(data->updateBlkno==InvalidBlockNumber);
145+
Assert(GinPageIsLeaf(page));
146+
Assert(data->updateBlkno==InvalidBlockNumber);
153147

154-
for (i=0;i<data->nitem;i++)
155-
GinDataPageAddItem(page,items+i,data->offset+i);
156-
}
157-
else
158-
{
159-
PostingItem*pitem;
148+
for (i=0;i<data->nitem;i++)
149+
GinDataPageAddItem(page,items+i,data->offset+i);
150+
}
151+
else
152+
{
153+
PostingItem*pitem;
160154

161-
Assert(!GinPageIsLeaf(page));
155+
Assert(!GinPageIsLeaf(page));
162156

163-
if (data->updateBlkno!=InvalidBlockNumber)
164-
{
165-
/* update link to right page after split */
166-
pitem= (PostingItem*)GinDataPageGetItem(page,data->offset);
167-
PostingItemSetBlockNumber(pitem,data->updateBlkno);
168-
}
157+
if (data->updateBlkno!=InvalidBlockNumber)
158+
{
159+
/* update link to right page after split */
160+
pitem= (PostingItem*)GinDataPageGetItem(page,data->offset);
161+
PostingItemSetBlockNumber(pitem,data->updateBlkno);
162+
}
169163

170-
pitem= (PostingItem*) (XLogRecGetData(record)+sizeof(ginxlogInsert));
164+
pitem= (PostingItem*) (XLogRecGetData(record)+sizeof(ginxlogInsert));
171165

172-
GinDataPageAddItem(page,pitem,data->offset);
166+
GinDataPageAddItem(page,pitem,data->offset);
167+
}
168+
}
173169

174-
if (data->updateBlkno!=InvalidBlockNumber)
175-
forgetIncompleteSplit(data->node,PostingItemGetBlockNumber(pitem),data->updateBlkno);
170+
if (!data->isLeaf&&data->updateBlkno!=InvalidBlockNumber)
171+
{
172+
PostingItem*pitem= (PostingItem*) (XLogRecGetData(record)+sizeof(ginxlogInsert));
173+
forgetIncompleteSplit(data->node,PostingItemGetBlockNumber(pitem),data->updateBlkno);
176174
}
175+
177176
}
178177
else
179178
{
180179
IndexTupleitup;
181180

182181
Assert(!GinPageIsData(page));
183182

184-
if (data->updateBlkno!=InvalidBlockNumber)
183+
if ( !XLByteLE(lsn,PageGetLSN(page)))
185184
{
186-
/* update link to right page after split */
187-
Assert(!GinPageIsLeaf(page));
188-
Assert(data->offset >=FirstOffsetNumber&&data->offset <=PageGetMaxOffsetNumber(page));
189-
itup= (IndexTuple)PageGetItem(page,PageGetItemId(page,data->offset));
190-
ItemPointerSet(&itup->t_tid,data->updateBlkno,InvalidOffsetNumber);
191-
}
185+
if (data->updateBlkno!=InvalidBlockNumber)
186+
{
187+
/* update link to right page after split */
188+
Assert(!GinPageIsLeaf(page));
189+
Assert(data->offset >=FirstOffsetNumber&&data->offset <=PageGetMaxOffsetNumber(page));
190+
itup= (IndexTuple)PageGetItem(page,PageGetItemId(page,data->offset));
191+
ItemPointerSet(&itup->t_tid,data->updateBlkno,InvalidOffsetNumber);
192+
}
192193

193-
if (data->isDelete)
194-
{
195-
Assert(GinPageIsLeaf(page));
196-
Assert(data->offset >=FirstOffsetNumber&&data->offset <=PageGetMaxOffsetNumber(page));
197-
PageIndexTupleDelete(page,data->offset);
198-
}
194+
if (data->isDelete)
195+
{
196+
Assert(GinPageIsLeaf(page));
197+
Assert(data->offset >=FirstOffsetNumber&&data->offset <=PageGetMaxOffsetNumber(page));
198+
PageIndexTupleDelete(page,data->offset);
199+
}
199200

200-
itup= (IndexTuple) (XLogRecGetData(record)+sizeof(ginxlogInsert));
201+
itup= (IndexTuple) (XLogRecGetData(record)+sizeof(ginxlogInsert));
201202

202-
if (PageAddItem(page, (Item)itup,IndexTupleSize(itup),data->offset, false, false)==InvalidOffsetNumber)
203-
elog(ERROR,"failed to add item to index page in %u/%u/%u",
204-
data->node.spcNode,data->node.dbNode,data->node.relNode);
203+
if (PageAddItem(page, (Item)itup,IndexTupleSize(itup),data->offset, false, false)==InvalidOffsetNumber)
204+
elog(ERROR,"failed to add item to index page in %u/%u/%u",
205+
data->node.spcNode,data->node.dbNode,data->node.relNode);
206+
}
205207

206208
if (!data->isLeaf&&data->updateBlkno!=InvalidBlockNumber)
209+
{
210+
itup= (IndexTuple) (XLogRecGetData(record)+sizeof(ginxlogInsert));
207211
forgetIncompleteSplit(data->node,GinItemPointerGetBlockNumber(&itup->t_tid),data->updateBlkno);
212+
}
208213
}
209214

210-
PageSetLSN(page,lsn);
211-
PageSetTLI(page,ThisTimeLineID);
215+
if ( !XLByteLE(lsn,PageGetLSN(page)) )
216+
{
217+
PageSetLSN(page,lsn);
218+
PageSetTLI(page,ThisTimeLineID);
212219

213-
MarkBufferDirty(buffer);
220+
MarkBufferDirty(buffer);
221+
}
214222
UnlockReleaseBuffer(buffer);
215223
}
216224

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp