Skip to content

Commit 3e059b3

Browse files
committed
1. WAL needs in zero-ed content of newly initialized page.
2. Log record for PageRepaireFragmentation now keeps array of !LP_USED offnums to redo cleanup properly.
1 parent 2783bd5 commit 3e059b3

File tree

5 files changed

+92
-40
lines changed

5 files changed

+92
-40
lines changed

src/backend/access/heap/heapam.c

Lines changed: 45 additions & 24 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.104 2000/12/30 06:52:33 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.105 2000/12/30 15:19:54 vadim Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -90,7 +90,8 @@
9090

9191
XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
9292
Buffer newbuf, HeapTuple newtup);
93-
XLogRecPtr log_heap_clean(Relation reln, Buffer buffer);
93+
XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
94+
char *unused, int unlen);
9495

9596
/* comments are in heap_update */
9697
static xl_heaptid _locked_tuple_;
@@ -2002,11 +2003,11 @@ heap_restrpos(HeapScanDesc scan)
20022003
}
20032004

20042005
XLogRecPtr
2005-
log_heap_clean(Relation reln, Buffer buffer)
2006+
log_heap_clean(Relation reln, Buffer buffer, char *unused, int unlen)
20062007
{
20072008
xl_heap_clean xlrec;
20082009
XLogRecPtr recptr;
2009-
XLogRecData rdata[2];
2010+
XLogRecData rdata[3];
20102011

20112012
xlrec.node = reln->rd_node;
20122013
xlrec.block = BufferGetBlockNumber(buffer);
@@ -2015,10 +2016,20 @@ log_heap_clean(Relation reln, Buffer buffer)
20152016
rdata[0].len = SizeOfHeapClean;
20162017
rdata[0].next = &(rdata[1]);
20172018

2018-
rdata[1].buffer = buffer;
2019-
rdata[1].data = NULL;
2020-
rdata[1].len = 0;
2021-
rdata[1].next = NULL;
2019+
if (unlen > 0)
2020+
{
2021+
rdata[1].buffer = buffer;
2022+
rdata[1].data = unused;
2023+
rdata[1].len = unlen;
2024+
rdata[1].next = &(rdata[2]);
2025+
}
2026+
else
2027+
rdata[0].next = &(rdata[2]);
2028+
2029+
rdata[2].buffer = buffer;
2030+
rdata[2].data = NULL;
2031+
rdata[2].len = 0;
2032+
rdata[2].next = NULL;
20222033

20232034
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_CLEAN, rdata);
20242035

@@ -2102,14 +2113,10 @@ log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
21022113
static void
21032114
heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record)
21042115
{
2105-
xl_heap_clean *xlrec = (xl_heap_clean*) XLogRecGetData(record);
2116+
xl_heap_clean *xlrec = (xl_heap_clean*) XLogRecGetData(record);
21062117
Relation reln;
21072118
Buffer buffer;
21082119
Page page;
2109-
OffsetNumber maxoff;
2110-
OffsetNumber offnum;
2111-
HeapTupleHeader htup;
2112-
ItemId lp;
21132120

21142121
if (!redo || (record->xl_info & XLR_BKP_BLOCK_1))
21152122
return;
@@ -2133,23 +2140,25 @@ heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record)
21332140
return;
21342141
}
21352142

2136-
maxoff = PageGetMaxOffsetNumber(page);
2137-
for (offnum = FirstOffsetNumber;
2138-
offnum <= maxoff;
2139-
offnum = OffsetNumberNext(offnum))
2143+
if (record->xl_len > SizeOfHeapClean)
21402144
{
2141-
lp = PageGetItemId(page, offnum);
2142-
2143-
if (!ItemIdIsUsed(lp))
2144-
continue;
2145+
char unbuf[BLCKSZ];
2146+
OffsetNumber *unused = (OffsetNumber*)unbuf;
2147+
char *unend;
2148+
ItemId lp;
21452149

2146-
htup = (HeapTupleHeader) PageGetItem(page, lp);
2150+
memcpy(unbuf, (char*)xlrec + SizeOfHeapClean, record->xl_len - SizeOfHeapClean);
2151+
unend = unbuf + (record->xl_len - SizeOfHeapClean);
21472152

2148-
if (!HeapTupleSatisfiesNow(htup))
2153+
while((char*)unused < unend)
2154+
{
2155+
lp = ((PageHeader) page)->pd_linp + *unused;
21492156
lp->lp_flags &= ~LP_USED;
2157+
unused++;
2158+
}
21502159
}
21512160

2152-
PageRepairFragmentation(page);
2161+
PageRepairFragmentation(page, NULL);
21532162
UnlockAndWriteBuffer(buffer);
21542163
}
21552164

@@ -2247,7 +2256,10 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
22472256
uint32 newlen;
22482257

22492258
if (record->xl_info & XLOG_HEAP_INIT_PAGE)
2259+
{
22502260
PageInit(page, BufferGetPageSize(buffer), 0);
2261+
PageZero(page);
2262+
}
22512263

22522264
if (XLByteLE(lsn, PageGetLSN(page))) /* changes are applied */
22532265
{
@@ -2401,7 +2413,10 @@ newsame:;
24012413
uint32 newlen;
24022414

24032415
if (record->xl_info & XLOG_HEAP_INIT_PAGE)
2416+
{
24042417
PageInit(page, BufferGetPageSize(buffer), 0);
2418+
PageZero(page);
2419+
}
24052420

24062421
if (XLByteLE(lsn, PageGetLSN(page))) /* changes are applied */
24072422
{
@@ -2583,6 +2598,12 @@ heap_desc(char *buf, uint8 xl_info, char* rec)
25832598
ItemPointerGetBlockNumber(&(xlrec->newtid)),
25842599
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
25852600
}
2601+
else if (info == XLOG_HEAP_CLEAN)
2602+
{
2603+
xl_heap_clean *xlrec = (xl_heap_clean*) rec;
2604+
sprintf(buf + strlen(buf), "clean: node %u/%u; blk %u",
2605+
xlrec->node.tblNode, xlrec->node.relNode, xlrec->block);
2606+
}
25862607
else
25872608
strcat(buf, "UNKNOWN");
25882609
}

src/backend/commands/vacuum.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.180 2000/12/28 13:00:18 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.181 2000/12/30 15:19:55 vadim Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -47,7 +47,8 @@
4747
#include "utils/syscache.h"
4848
#include "utils/temprel.h"
4949

50-
extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer);
50+
extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
51+
char *unused, int unlen);
5152
extern XLogRecPtr log_heap_move(Relation reln,
5253
Buffer oldbuf, ItemPointerData from,
5354
Buffer newbuf, HeapTuple newtup);
@@ -878,7 +879,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
878879

879880
if (tempPage != (Page) NULL)
880881
{ /* Some tuples are gone */
881-
PageRepairFragmentation(tempPage);
882+
PageRepairFragmentation(tempPage, NULL);
882883
vacpage->free = ((PageHeader) tempPage)->pd_upper - ((PageHeader) tempPage)->pd_lower;
883884
free_size += vacpage->free;
884885
reap_page(vacuum_pages, vacpage);
@@ -1898,6 +1899,10 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
18981899
if (vacpage->blkno == (BlockNumber) (blkno - 1) &&
18991900
vacpage->offsets_free > 0)
19001901
{
1902+
char unbuf[BLCKSZ];
1903+
OffsetNumber *unused = (OffsetNumber*)unbuf;
1904+
int uncnt;
1905+
19011906
buf = ReadBuffer(onerel, vacpage->blkno);
19021907
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
19031908
START_CRIT_CODE;
@@ -1928,9 +1933,11 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
19281933

19291934
}
19301935
Assert(vacpage->offsets_free == num_tuples);
1931-
PageRepairFragmentation(page);
1936+
uncnt = PageRepairFragmentation(page, unused);
19321937
{
1933-
XLogRecPtr recptr = log_heap_clean(onerel, buf);
1938+
XLogRecPtr recptr;
1939+
recptr = log_heap_clean(onerel, buf, (char*)unused,
1940+
(char*)(&(unused[uncnt])) - (char*)unused);
19341941
PageSetLSN(page, recptr);
19351942
PageSetSUI(page, ThisStartUpID);
19361943
}
@@ -2039,9 +2046,12 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
20392046
static void
20402047
vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage)
20412048
{
2042-
Page page = BufferGetPage(buffer);
2043-
ItemId itemid;
2044-
int i;
2049+
char unbuf[BLCKSZ];
2050+
OffsetNumber *unused = (OffsetNumber*)unbuf;
2051+
int uncnt;
2052+
Page page = BufferGetPage(buffer);
2053+
ItemId itemid;
2054+
int i;
20452055

20462056
/* There shouldn't be any tuples moved onto the page yet! */
20472057
Assert(vacpage->offsets_used == 0);
@@ -2052,9 +2062,11 @@ vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage)
20522062
itemid = &(((PageHeader) page)->pd_linp[vacpage->offsets[i] - 1]);
20532063
itemid->lp_flags &= ~LP_USED;
20542064
}
2055-
PageRepairFragmentation(page);
2065+
uncnt = PageRepairFragmentation(page, unused);
20562066
{
2057-
XLogRecPtr recptr = log_heap_clean(onerel, buffer);
2067+
XLogRecPtr recptr;
2068+
recptr = log_heap_clean(onerel, buffer, (char*)unused,
2069+
(char*)(&(unused[uncnt])) - (char*)unused);
20582070
PageSetLSN(page, recptr);
20592071
PageSetSUI(page, ThisStartUpID);
20602072
}

src/backend/storage/page/bufpage.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.33 2000/10/21 15:43:29 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.34 2000/12/30 15:19:55 vadim Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -48,6 +48,19 @@ PageInit(Page page, Size pageSize, Size specialSize)
4848
p->pd_upper = pageSize - specialSize;
4949
p->pd_special = pageSize - specialSize;
5050
PageSetPageSize(page, pageSize);
51+
52+
p->pd_lsn.xlogid = p->pd_lsn.xrecoff = 0;
53+
p->pd_sui = 0;
54+
}
55+
56+
/*
57+
* WAL needs in zero-ed page data content
58+
*/
59+
void
60+
PageZero(Page page)
61+
{
62+
MemSet((char*)page + ((PageHeader)page)->pd_lower, 0,
63+
((PageHeader)page)->pd_special - ((PageHeader)page)->pd_lower);
5164
}
5265

5366
/* ----------------
@@ -251,8 +264,8 @@ itemidcompare(const void *itemidp1, const void *itemidp2)
251264
* This routine is usable for heap pages only.
252265
*
253266
*/
254-
void
255-
PageRepairFragmentation(Page page)
267+
int
268+
PageRepairFragmentation(Page page, OffsetNumber *unused)
256269
{
257270
int i;
258271
struct itemIdSortData *itemidbase,
@@ -272,6 +285,8 @@ PageRepairFragmentation(Page page)
272285
(*lp).lp_flags &= ~(LP_USED | LP_DELETE);
273286
if ((*lp).lp_flags & LP_USED)
274287
nused++;
288+
else if (unused)
289+
unused[i - nused] = (OffsetNumber)i;
275290
}
276291

277292
if (nused == 0)
@@ -328,6 +343,8 @@ PageRepairFragmentation(Page page)
328343

329344
pfree(itemidbase);
330345
}
346+
347+
return(nline - nused);
331348
}
332349

333350
/*

src/include/access/htup.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: htup.h,v 1.43 2000/12/28 13:00:25 vadim Exp $
10+
* $Id: htup.h,v 1.44 2000/12/30 15:19:56 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -131,6 +131,7 @@ typedef struct xl_heap_clean
131131
{
132132
RelFileNode node;
133133
BlockNumber block;
134+
/* UNUSED OFFSET NUMBERS FOLLOW AT THE END */
134135
} xl_heap_clean;
135136

136137
#define SizeOfHeapClean (offsetof(xl_heap_clean, block) + sizeof(BlockNumber))

src/include/storage/bufpage.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: bufpage.h,v 1.37 2000/11/30 08:46:26 vadim Exp $
10+
* $Id: bufpage.h,v 1.38 2000/12/30 15:19:57 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -314,11 +314,12 @@ typedef enum
314314
*/
315315

316316
extern void PageInit(Page page, Size pageSize, Size specialSize);
317+
extern void PageZero(Page page);
317318
extern OffsetNumber PageAddItem(Page page, Item item, Size size,
318319
OffsetNumber offsetNumber, ItemIdFlags flags);
319320
extern Page PageGetTempPage(Page page, Size specialSize);
320321
extern void PageRestoreTempPage(Page tempPage, Page oldPage);
321-
extern void PageRepairFragmentation(Page page);
322+
extern int PageRepairFragmentation(Page page, OffsetNumber *unused);
322323
extern Size PageGetFreeSpace(Page page);
323324
extern void PageIndexTupleDelete(Page page, OffsetNumber offset);
324325
extern void IndexPageCleanup(Buffer buffer);

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