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

Commitfb27643

Browse files
committed
Suppress useless searches for unused line pointers in PageAddItem. To do
this, add a 16-bit "flags" field to page headers by stealing some bits frompd_tli. We use one flag bit as a hint to indicate whether there are anyunused line pointers; the remaining 15 are available for future use.This is a cut-down form of an idea proposed by Hiroki Kataoka in July 2005.At the time it was rejected because the original patch increased the size ofpage headers and it wasn't clear that the benefit outweighed the distributedcost. The flag-bit approach gets most of the benefit without requiring anincrease in the page header size.Heikki Linnakangas and Tom Lane
1 parent44f72c6 commitfb27643

File tree

4 files changed

+82
-25
lines changed

4 files changed

+82
-25
lines changed

‎doc/src/sgml/storage.sgml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/storage.sgml,v 1.14 2007/01/31 20:56:19 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/storage.sgml,v 1.15 2007/03/02 00:48:44 tgl Exp $ -->
22

33
<chapter id="storage">
44

@@ -427,8 +427,8 @@ data. Empty in ordinary tables.</entry>
427427
The first 20 bytes of each page consists of a page header
428428
(PageHeaderData). Its format is detailed in <xref
429429
linkend="pageheaderdata-table">. The first two fields track the most
430-
recent WAL entry related to this page.They are followed by three2-byte
431-
integer fields
430+
recent WAL entry related to this page.Next is a2-byte field
431+
containing flag bits. This is followed by three 2-byteinteger fields
432432
(<structfield>pd_lower</structfield>, <structfield>pd_upper</structfield>,
433433
and <structfield>pd_special</structfield>). These contain byte offsets
434434
from the page start to the start
@@ -437,12 +437,13 @@ data. Empty in ordinary tables.</entry>
437437
The last 2 bytes of the page header,
438438
<structfield>pd_pagesize_version</structfield>, store both the page size
439439
and a version indicator. Beginning with
440-
<productname>PostgreSQL</productname> 8.1 the version number is 3;
440+
<productname>PostgreSQL</productname> 8.3 the version number is 4;
441+
<productname>PostgreSQL</productname> 8.1 and 8.2 used version number 3;
441442
<productname>PostgreSQL</productname> 8.0 used version number 2;
442443
<productname>PostgreSQL</productname> 7.3 and 7.4 used version number 1;
443444
prior releases used version number 0.
444-
(The basic page layout and header format has not changed inthese versions,
445-
but the layout of heap row headers has.) The page size
445+
(The basic page layout and header format has not changed inmost of these
446+
versions,but the layout of heap row headers has.) The page size
446447
is basically only present as a cross-check; there is no support for having
447448
more than one page size in an installation.
448449

@@ -470,9 +471,15 @@ data. Empty in ordinary tables.</entry>
470471
</row>
471472
<row>
472473
<entry>pd_tli</entry>
473-
<entry>TimeLineID</entry>
474-
<entry>4 bytes</entry>
475-
<entry>TLI of last change</entry>
474+
<entry>uint16</entry>
475+
<entry>2 bytes</entry>
476+
<entry>TimeLineID of last change (only its lowest 16 bits)</entry>
477+
</row>
478+
<row>
479+
<entry>pd_flags</entry>
480+
<entry>uint16</entry>
481+
<entry>2 bytes</entry>
482+
<entry>Flag bits</entry>
476483
</row>
477484
<row>
478485
<entry>pd_lower</entry>

‎src/backend/storage/page/bufpage.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/page/bufpage.c,v 1.71 2007/02/21 20:02:17 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/page/bufpage.c,v 1.72 2007/03/02 00:48:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -39,6 +39,7 @@ PageInit(Page page, Size pageSize, Size specialSize)
3939
/* Make sure all fields of page are zero, as well as unused space */
4040
MemSet(p,0,pageSize);
4141

42+
/* p->pd_flags = 0; done by above MemSet */
4243
p->pd_lower=SizeOfPageHeaderData;
4344
p->pd_upper=pageSize-specialSize;
4445
p->pd_special=pageSize-specialSize;
@@ -73,6 +74,7 @@ PageHeaderIsValid(PageHeader page)
7374
/* Check normal case */
7475
if (PageGetPageSize(page)==BLCKSZ&&
7576
PageGetPageLayoutVersion(page)==PG_PAGE_LAYOUT_VERSION&&
77+
(page->pd_flags& ~PD_VALID_FLAG_BITS)==0&&
7678
page->pd_lower >=SizeOfPageHeaderData&&
7779
page->pd_lower <=page->pd_upper&&
7880
page->pd_upper <=page->pd_special&&
@@ -165,14 +167,27 @@ PageAddItem(Page page,
165167
else
166168
{
167169
/* offsetNumber was not passed in, so find a free slot */
168-
/* look for "recyclable" (unused & deallocated) ItemId */
169-
for (offsetNumber=1;offsetNumber<limit;offsetNumber++)
170+
/* if no free slot, we'll put it at limit (1st open slot) */
171+
if (PageHasFreeLinePointers(phdr))
172+
{
173+
/* look for "recyclable" (unused & deallocated) ItemId */
174+
for (offsetNumber=1;offsetNumber<limit;offsetNumber++)
175+
{
176+
itemId=PageGetItemId(phdr,offsetNumber);
177+
if (!ItemIdIsUsed(itemId)&&ItemIdGetLength(itemId)==0)
178+
break;
179+
}
180+
if (offsetNumber >=limit)
181+
{
182+
/* the hint is wrong, so reset it */
183+
PageClearHasFreeLinePointers(phdr);
184+
}
185+
}
186+
else
170187
{
171-
itemId=PageGetItemId(phdr,offsetNumber);
172-
if (!ItemIdIsUsed(itemId)&&ItemIdGetLength(itemId)==0)
173-
break;
188+
/* don't bother searching if hint says there's no free slot */
189+
offsetNumber=limit;
174190
}
175-
/* if no free slot, we'll put it at limit (1st open slot) */
176191
}
177192

178193
if (offsetNumber>limit)
@@ -413,13 +428,19 @@ PageRepairFragmentation(Page page, OffsetNumber *unused)
413428
pfree(itemidbase);
414429
}
415430

431+
/* Set hint bit for PageAddItem */
432+
if (nused<nline)
433+
PageSetHasFreeLinePointers(page);
434+
else
435+
PageClearHasFreeLinePointers(page);
436+
416437
return (nline-nused);
417438
}
418439

419440
/*
420441
* PageGetFreeSpace
421442
*Returns the size of the free (allocatable) space on a page,
422-
*deducted by the space needed for a new line pointer.
443+
*reduced by the space needed for a new line pointer.
423444
*/
424445
Size
425446
PageGetFreeSpace(Pagepage)

‎src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.388 2007/02/20 17:32:17 tgl Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.389 2007/03/02 00:48:44 tgl Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO200702202
56+
#defineCATALOG_VERSION_NO200703011
5757

5858
#endif

‎src/include/storage/bufpage.h

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/bufpage.h,v 1.71 2007/02/21 20:02:17 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/bufpage.h,v 1.72 2007/03/02 00:48:44 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -90,6 +90,7 @@ typedef uint16 LocationIndex;
9090
*
9191
*pd_lsn- identifies xlog record for last change to this page.
9292
*pd_tli- ditto.
93+
*pd_flags- flag bits.
9394
*pd_lower- offset to start of free space.
9495
*pd_upper- offset to end of free space.
9596
*pd_special- offset to start of special space.
@@ -98,8 +99,9 @@ typedef uint16 LocationIndex;
9899
* The LSN is used by the buffer manager to enforce the basic rule of WAL:
99100
* "thou shalt write xlog before data". A dirty buffer cannot be dumped
100101
* to disk until xlog has been flushed at least as far as the page's LSN.
101-
* We also store the TLI for identification purposes (it is not clear that
102-
* this is actually necessary, but it seems like a good idea).
102+
* We also store the 16 least significant bits of the TLI for identification
103+
* purposes (it is not clear that this is actually necessary, but it seems
104+
* like a good idea).
103105
*
104106
* The page version number and page size are packed together into a single
105107
* uint16 field. This is for historical reasons: before PostgreSQL 7.3,
@@ -119,7 +121,9 @@ typedef struct PageHeaderData
119121
/* XXX LSN is member of *any* block, not only page-organized ones */
120122
XLogRecPtrpd_lsn;/* LSN: next byte after last byte of xlog
121123
* record for last change to this page */
122-
TimeLineIDpd_tli;/* TLI of last change */
124+
uint16pd_tli;/* least significant bits of the TimeLineID
125+
* containing the LSN */
126+
uint16pd_flags;/* flag bits, see below */
123127
LocationIndexpd_lower;/* offset to start of free space */
124128
LocationIndexpd_upper;/* offset to end of free space */
125129
LocationIndexpd_special;/* offset to start of special space */
@@ -129,12 +133,25 @@ typedef struct PageHeaderData
129133

130134
typedefPageHeaderData*PageHeader;
131135

136+
/*
137+
* pd_flags contains the following flag bits. Undefined bits are initialized
138+
* to zero and may be used in the future.
139+
*
140+
* PD_HAS_FREE_LINES is set if there are any not-LP_USED line pointers before
141+
* pd_lower. This should be considered a hint rather than the truth, since
142+
* changes to it are not WAL-logged.
143+
*/
144+
#definePD_HAS_FREE_LINES0x0001/* are there any unused line pointers? */
145+
146+
#definePD_VALID_FLAG_BITS0x0001/* OR of all valid pd_flags bits */
147+
132148
/*
133149
* Page layout version number 0 is for pre-7.3 Postgres releases.
134150
* Releases 7.3 and 7.4 use 1, denoting a new HeapTupleHeader layout.
135151
* Release 8.0 uses 2; it changed the HeapTupleHeader layout again.
136152
* Release 8.1 uses 3; it redefined HeapTupleHeader infomask bits.
137-
* Release 8.3 uses 4; it changed the HeapTupleHeader layout again.
153+
* Release 8.3 uses 4; it changed the HeapTupleHeader layout again, and
154+
* added the pd_flags field (by stealing some bits from pd_tli).
138155
*/
139156
#definePG_PAGE_LAYOUT_VERSION4
140157

@@ -299,15 +316,27 @@ typedef PageHeaderData *PageHeader;
299316
((((PageHeader) (page))->pd_lower - SizeOfPageHeaderData) \
300317
/ sizeof(ItemIdData)))
301318

319+
/*
320+
* Additional macros for access to page headers
321+
*/
302322
#definePageGetLSN(page) \
303323
(((PageHeader) (page))->pd_lsn)
304324
#definePageSetLSN(page,lsn) \
305325
(((PageHeader) (page))->pd_lsn = (lsn))
306326

327+
/* NOTE: only the 16 least significant bits are stored */
307328
#definePageGetTLI(page) \
308329
(((PageHeader) (page))->pd_tli)
309330
#definePageSetTLI(page,tli) \
310-
(((PageHeader) (page))->pd_tli = (tli))
331+
(((PageHeader) (page))->pd_tli = (uint16) (tli))
332+
333+
#definePageHasFreeLinePointers(page) \
334+
(((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES)
335+
#definePageSetHasFreeLinePointers(page) \
336+
(((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES)
337+
#definePageClearHasFreeLinePointers(page) \
338+
(((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES)
339+
311340

312341
/* ----------------------------------------------------------------
313342
*extern declarations

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp