Skip to content

Commit e3ba543

Browse files
committed
WAL fixes.
1 parent 433cd77 commit e3ba543

File tree

3 files changed

+109
-48
lines changed

3 files changed

+109
-48
lines changed

src/backend/access/heap/heapam.c

Lines changed: 94 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.91 2000/10/24 09:56:07 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.92 2000/10/29 18:33:39 vadim Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -2057,6 +2057,48 @@ log_heap_move(Relation reln, ItemPointerData from, HeapTuple newtup)
20572057
return(log_heap_update(reln, from, newtup, true));
20582058
}
20592059

2060+
static void
2061+
_heap_cleanup_page_(Page page)
2062+
{
2063+
OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
2064+
OffsetNumber offnum;
2065+
ItemId lp;
2066+
HeapTupleHeader htup;
2067+
2068+
for (offnum = FirstOffsetNumber;
2069+
offnum <= maxoff;
2070+
offnum = OffsetNumberNext(offnum))
2071+
{
2072+
lp = PageGetItemId(page, offnum);
2073+
2074+
if (!ItemIdIsUsed(lp))
2075+
continue;
2076+
2077+
htup = (HeapTupleHeader) PageGetItem(page, lp);
2078+
2079+
if (!HeapTupleSatisfiesNow(htup))
2080+
lp->lp_flags &= ~LP_USED;
2081+
}
2082+
2083+
PageRepairFragmentation(page);
2084+
2085+
}
2086+
2087+
static OffsetNumber
2088+
_heap_add_tuple_(Page page, HeapTupleHeader htup, uint32 len, OffsetNumber offnum)
2089+
{
2090+
ItemId lp = PageGetItemId(page, offnum);
2091+
2092+
if (len > PageGetFreeSpace(page) ||
2093+
lp->lp_flags & LP_USED || lp->lp_len != 0)
2094+
_heap_cleanup_page_(page);
2095+
2096+
offnum = PageAddItem(page, (Item)htup, len, offnum,
2097+
LP_USED | OverwritePageMode);
2098+
2099+
return(offnum);
2100+
}
2101+
20602102
static void
20612103
heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
20622104
{
@@ -2097,24 +2139,18 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
20972139
elog(STOP, "heap_delete_undo: bad page LSN");
20982140

20992141
offnum = ItemPointerGetOffsetNumber(&(xlrec->target.tid));
2100-
lp = PageGetItemId(page, offnum);
2142+
if (PageGetMaxOffsetNumber(page) >= offnum)
2143+
lp = PageGetItemId(page, offnum);
21012144

2102-
if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))
2145+
/* page removed by vacuum ? */
2146+
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsUsed(lp))
21032147
{
2104-
if (redo)
2105-
elog(STOP, "heap_delete_redo: unused/deleted target tuple");
2106-
if (!InRecovery)
2107-
elog(STOP, "heap_delete_undo: unused/deleted target tuple in rollback");
2108-
if (ItemIdDeleted(lp))
2109-
{
2110-
lp->lp_flags &= ~LP_USED;
2111-
PageRepairFragmentation(page);
2112-
UnlockAndWriteBuffer(buffer);
2113-
}
2114-
else
2115-
UnlockAndReleaseBuffer(buffer);
2148+
PageSetLSN(page, lsn);
2149+
PageSetSUI(page, ThisStartUpID);
2150+
UnlockAndWriteBuffer(buffer);
21162151
return;
21172152
}
2153+
21182154
htup = (HeapTupleHeader) PageGetItem(page, lp);
21192155

21202156
if (redo)
@@ -2189,6 +2225,16 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
21892225
return;
21902226
}
21912227

2228+
offnum = ItemPointerGetOffsetNumber(&(xlrec->target.tid));
2229+
/* page removed by vacuum ? */
2230+
if (PageGetMaxOffsetNumber(page) + 1 < offnum)
2231+
{
2232+
PageSetLSN(page, lsn);
2233+
PageSetSUI(page, ThisStartUpID);
2234+
UnlockAndWriteBuffer(buffer);
2235+
return;
2236+
}
2237+
21922238
memcpy(tbuf + offsetof(HeapTupleHeaderData, t_bits),
21932239
(char*)xlrec + SizeOfHeapInsert, newlen);
21942240
newlen += offsetof(HeapTupleHeaderData, t_bits);
@@ -2200,9 +2246,7 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
22002246
htup->t_xmax = htup->t_cmax = 0;
22012247
htup->t_infomask = HEAP_XMAX_INVALID | HEAP_XMIN_COMMITTED | xlrec->mask;
22022248

2203-
offnum = PageAddItem(page, (Item)htup, newlen,
2204-
ItemPointerGetOffsetNumber(&(xlrec->target.tid)),
2205-
LP_USED | OverwritePageMode);
2249+
offnum = _heap_add_tuple_(page, htup, newlen, offnum);
22062250
if (offnum == InvalidOffsetNumber)
22072251
elog(STOP, "heap_insert_redo: failed to add tuple");
22082252
PageSetLSN(page, lsn);
@@ -2258,6 +2302,9 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
22582302
xl_heap_update *xlrec = (xl_heap_update*) XLogRecGetData(record);
22592303
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
22602304
Buffer buffer;
2305+
bool samepage =
2306+
(ItemPointerGetBlockNumber(&(xlrec->newtid)) ==
2307+
ItemPointerGetBlockNumber(&(xlrec->target.tid)));
22612308
Page page;
22622309
OffsetNumber offnum;
22632310
ItemId lp;
@@ -2266,13 +2313,6 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
22662313
if (!RelationIsValid(reln))
22672314
return;
22682315

2269-
/*
2270-
* Currently UPDATE is DELETE + INSERT and so code below are near
2271-
* exact sum of code in heap_xlog_delete & heap_xlog_insert. We could
2272-
* re-structure code better, but keeping in mind upcoming overwriting
2273-
* smgr separate heap_xlog_update code seems to be Good Thing.
2274-
*/
2275-
22762316
/* Deal with old tuple version */
22772317

22782318
buffer = XLogReadBuffer(false, reln,
@@ -2283,6 +2323,8 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
22832323
page = (Page) BufferGetPage(buffer);
22842324
if (PageIsNew((PageHeader) page))
22852325
{
2326+
if (samepage)
2327+
goto newsame;
22862328
PageInit(page, BufferGetPageSize(buffer), 0);
22872329
PageSetLSN(page, lsn);
22882330
PageSetSUI(page, ThisStartUpID);
@@ -2295,29 +2337,26 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
22952337
if (XLByteLE(lsn, PageGetLSN(page))) /* changes are applied */
22962338
{
22972339
UnlockAndReleaseBuffer(buffer);
2340+
if (samepage)
2341+
return;
22982342
goto newt;
22992343
}
23002344
}
23012345
else if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied ?! */
23022346
elog(STOP, "heap_update_undo: bad old tuple page LSN");
23032347

23042348
offnum = ItemPointerGetOffsetNumber(&(xlrec->target.tid));
2305-
lp = PageGetItemId(page, offnum);
2349+
if (PageGetMaxOffsetNumber(page) >= offnum)
2350+
lp = PageGetItemId(page, offnum);
23062351

2307-
if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))
2352+
/* page removed by vacuum ? */
2353+
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsUsed(lp))
23082354
{
2309-
if (redo)
2310-
elog(STOP, "heap_update_redo: unused/deleted old tuple");
2311-
if (!InRecovery)
2312-
elog(STOP, "heap_update_undo: unused/deleted old tuple in rollback");
2313-
if (ItemIdDeleted(lp))
2314-
{
2315-
lp->lp_flags &= ~LP_USED;
2316-
PageRepairFragmentation(page);
2317-
UnlockAndWriteBuffer(buffer);
2318-
}
2319-
else
2320-
UnlockAndReleaseBuffer(buffer);
2355+
if (samepage)
2356+
goto newsame;
2357+
PageSetLSN(page, lsn);
2358+
PageSetSUI(page, ThisStartUpID);
2359+
UnlockAndWriteBuffer(buffer);
23212360
goto newt;
23222361
}
23232362
htup = (HeapTupleHeader) PageGetItem(page, lp);
@@ -2338,6 +2377,8 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
23382377
htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
23392378
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
23402379
}
2380+
if (samepage)
2381+
goto newsame;
23412382
PageSetLSN(page, lsn);
23422383
PageSetSUI(page, ThisStartUpID);
23432384
UnlockAndWriteBuffer(buffer);
@@ -2377,6 +2418,8 @@ newt:;
23772418
return;
23782419

23792420
page = (Page) BufferGetPage(buffer);
2421+
2422+
newsame:;
23802423
if (PageIsNew((PageHeader) page))
23812424
{
23822425
PageInit(page, BufferGetPageSize(buffer), 0);
@@ -2401,6 +2444,16 @@ newt:;
24012444
return;
24022445
}
24032446

2447+
offnum = ItemPointerGetOffsetNumber(&(xlrec->newtid));
2448+
/* page removed by vacuum ? */
2449+
if (PageGetMaxOffsetNumber(page) + 1 < offnum)
2450+
{
2451+
PageSetLSN(page, lsn);
2452+
PageSetSUI(page, ThisStartUpID);
2453+
UnlockAndWriteBuffer(buffer);
2454+
return;
2455+
}
2456+
24042457
hsize = SizeOfHeapUpdate;
24052458
if (move)
24062459
hsize += sizeof(TransactionId);
@@ -2431,9 +2484,8 @@ newt:;
24312484
htup->t_infomask = HEAP_XMAX_INVALID | xlrec->mask;
24322485
}
24332486

2434-
offnum = PageAddItem(page, (Item)htup, newlen,
2435-
ItemPointerGetOffsetNumber(&(xlrec->newtid)),
2436-
LP_USED | OverwritePageMode);
2487+
offnum = _heap_add_tuple_(page, htup, newlen,
2488+
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
24372489
if (offnum == InvalidOffsetNumber)
24382490
elog(STOP, "heap_update_redo: failed to add tuple");
24392491
PageSetLSN(page, lsn);

src/backend/access/nbtree/nbtree.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.67 2000/10/21 15:43:18 vadim Exp $
15+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.68 2000/10/29 18:33:40 vadim Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -787,6 +787,7 @@ _bt_add_item(Page page, OffsetNumber offno,
787787
if (PageAddItem(page, (Item) item, size, offno,
788788
LP_USED) == InvalidOffsetNumber)
789789
{
790+
#ifdef NOT_USED /* it's not valid code currently */
790791
/* ops, not enough space - try to deleted dead tuples */
791792
bool result;
792793

@@ -795,6 +796,7 @@ _bt_add_item(Page page, OffsetNumber offno,
795796
result = _bt_cleanup_page(page, hnode);
796797
if (!result || PageAddItem(page, (Item) item, size, offno,
797798
LP_USED) == InvalidOffsetNumber)
799+
#endif
798800
return(false);
799801
}
800802

@@ -868,7 +870,7 @@ _bt_fix_left_page(Page page, XLogRecord *record, bool onleft)
868870
(sizeof(BTItemData) - sizeof(IndexTupleData));
869871
itemsz = MAXALIGN(itemsz);
870872

871-
if (item + itemsz < (char*)record + record->xl_len)
873+
if (item + itemsz < (char*)xlrec + record->xl_len)
872874
{
873875
previtem = item;
874876
item += itemsz;
@@ -1173,6 +1175,8 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
11731175
else
11741176
pageop->btpo_next = ItemPointerGetBlockNumber(&(xlrec->target.tid));
11751177

1178+
pageop->btpo_flags &= ~BTP_ROOT;
1179+
11761180
PageSetLSN(page, lsn);
11771181
PageSetSUI(page, ThisStartUpID);
11781182
UnlockAndWriteBuffer(buffer);
@@ -1245,7 +1249,7 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
12451249
}
12461250

12471251
for (item = (char*)xlrec + hsize;
1248-
item < (char*)record + record->xl_len; )
1252+
item < (char*)xlrec + record->xl_len; )
12491253
{
12501254
memcpy(&btdata, item, sizeof(BTItemData));
12511255
itemsz = IndexTupleDSize(btdata.bti_itup) +
@@ -1283,7 +1287,7 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
12831287

12841288
item = (char*)xlrec + SizeOfBtreeSplit +
12851289
sizeof(CommandId) + sizeof(RelFileNode);
1286-
for (cnt = 0; item < (char*)record + record->xl_len; )
1290+
for (cnt = 0; item < (char*)xlrec + record->xl_len; )
12871291
{
12881292
BTItem btitem = (BTItem)
12891293
(tbuf + cnt * (MAXALIGN(sizeof(BTItemData))));
@@ -1306,6 +1310,9 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
13061310

13071311
/* Right (next) page */
13081312
blkno = BlockIdGetBlockNumber(&(xlrec->rightblk));
1313+
if (blkno == P_NONE)
1314+
return;
1315+
13091316
buffer = XLogReadBuffer(false, reln, blkno);
13101317
if (!BufferIsValid(buffer))
13111318
elog(STOP, "btree_split_%s: lost next right page", op);
@@ -1385,7 +1392,7 @@ btree_xlog_newroot(bool redo, XLogRecPtr lsn, XLogRecord *record)
13851392
char *item;
13861393

13871394
for (item = (char*)xlrec + SizeOfBtreeNewroot;
1388-
item < (char*)record + record->xl_len; )
1395+
item < (char*)xlrec + record->xl_len; )
13891396
{
13901397
memcpy(&btdata, item, sizeof(BTItemData));
13911398
itemsz = IndexTupleDSize(btdata.bti_itup) +

src/backend/access/transam/xact.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.78 2000/10/28 16:20:53 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.79 2000/10/29 18:33:41 vadim Exp $
1212
*
1313
* NOTES
1414
* Transaction aborts can now occur two ways:
@@ -1807,8 +1807,10 @@ xact_desc(char *buf, uint8 xl_info, char* rec)
18071807
void
18081808
XactPushRollback(void (*func) (void *), void* data)
18091809
{
1810+
#ifdef XLOG_II
18101811
if (_RollbackFunc != NULL)
18111812
elog(STOP, "XactPushRollback: already installed");
1813+
#endif
18121814

18131815
_RollbackFunc = func;
18141816
_RollbackData = data;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy