Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 23c4978

Browse files
committed
Rename MaxTupleSize to MaxHeapTupleSize to clarify that it's not meant to
describe the maximum size of index tuples (which is typically AM-dependent anyway); and consequently remove the bogus deduction for "special space" that was built into it. Adjust TOAST_TUPLE_THRESHOLD and TOAST_MAX_CHUNK_SIZE to avoid wasting two bytes per toast chunk, and to ensure that the calculation correctly tracks any future changes in page header size. The computation had been inaccurate in a way that didn't cause any harm except space wastage, but future changes could have broken it more drastically. Fix the calculation of BTMaxItemSize, which was formerly computed as 1 byte more than it could safely be. This didn't cause any harm in practice because it's only compared against maxalign'd lengths, but future changes in the size of page headers or btree special space could have exposed the problem. initdb forced because of change in TOAST_MAX_CHUNK_SIZE, which alters the storage of toast tables.
1 parent a2e092e commit 23c4978

File tree

8 files changed

+65
-47
lines changed

8 files changed

+65
-47
lines changed

src/backend/access/heap/heapam.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.226 2007/02/04 20:00:37 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.227 2007/02/05 04:22:18 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -3463,7 +3463,7 @@ heap_xlog_insert(XLogRecPtr lsn, XLogRecord *record)
34633463
struct
34643464
{
34653465
HeapTupleHeaderData hdr;
3466-
char data[MaxTupleSize];
3466+
char data[MaxHeapTupleSize];
34673467
} tbuf;
34683468
HeapTupleHeader htup;
34693469
xl_heap_header xlhdr;
@@ -3505,7 +3505,7 @@ heap_xlog_insert(XLogRecPtr lsn, XLogRecord *record)
35053505
elog(PANIC, "heap_insert_redo: invalid max offset number");
35063506

35073507
newlen = record->xl_len - SizeOfHeapInsert - SizeOfHeapHeader;
3508-
Assert(newlen <= MaxTupleSize);
3508+
Assert(newlen <= MaxHeapTupleSize);
35093509
memcpy((char *) &xlhdr,
35103510
(char *) xlrec + SizeOfHeapInsert,
35113511
SizeOfHeapHeader);
@@ -3551,7 +3551,7 @@ heap_xlog_update(XLogRecPtr lsn, XLogRecord *record, bool move)
35513551
struct
35523552
{
35533553
HeapTupleHeaderData hdr;
3554-
char data[MaxTupleSize];
3554+
char data[MaxHeapTupleSize];
35553555
} tbuf;
35563556
xl_heap_header xlhdr;
35573557
int hsize;
@@ -3668,7 +3668,7 @@ newsame:;
36683668
hsize += (2 * sizeof(TransactionId));
36693669

36703670
newlen = record->xl_len - hsize;
3671-
Assert(newlen <= MaxTupleSize);
3671+
Assert(newlen <= MaxHeapTupleSize);
36723672
memcpy((char *) &xlhdr,
36733673
(char *) xlrec + SizeOfHeapUpdate,
36743674
SizeOfHeapHeader);

src/backend/access/heap/hio.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.64 2007/01/05 22:19:22 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.65 2007/02/05 04:22:18 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -118,12 +118,12 @@ RelationGetBufferForTuple(Relation relation, Size len,
118118
/*
119119
* If we're gonna fail for oversize tuple, do it right away
120120
*/
121-
if (len > MaxTupleSize)
121+
if (len > MaxHeapTupleSize)
122122
ereport(ERROR,
123123
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
124124
errmsg("row is too big: size %lu, maximum size %lu",
125125
(unsigned long) len,
126-
(unsigned long) MaxTupleSize)));
126+
(unsigned long) MaxHeapTupleSize)));
127127

128128
/* Compute desired extra freespace due to fillfactor option */
129129
saveFreeSpace = RelationGetTargetPageFreeSpace(relation,
@@ -147,7 +147,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
147147
* When use_fsm is false, we either put the tuple onto the existing target
148148
* page or extend the relation.
149149
*/
150-
if (len + saveFreeSpace <= MaxTupleSize)
150+
if (len + saveFreeSpace <= MaxHeapTupleSize)
151151
targetBlock = relation->rd_targblock;
152152
else
153153
{

src/backend/commands/vacuum.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.344 2007/02/01 19:10:26 momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.345 2007/02/05 04:22:18 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -1236,7 +1236,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
12361236
nunused;
12371237
double free_space,
12381238
usable_free_space;
1239-
Size min_tlen = MaxTupleSize;
1239+
Size min_tlen = MaxHeapTupleSize;
12401240
Size max_tlen = 0;
12411241
bool do_shrinking = true;
12421242
VTupleLink vtlinks = (VTupleLink) palloc(100 * sizeof(VTupleLinkData));

src/include/access/htup.h

Lines changed: 9 additions & 11 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/access/htup.h,v 1.89 2007/01/09 22:01:00 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/access/htup.h,v 1.90 2007/02/05 04:22:18 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -314,19 +314,17 @@ do { \
314314
#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8)
315315

316316
/*
317-
* MaxTupleSize is the maximum allowed size of a tuple, including header and
318-
* MAXALIGN alignment padding. Basically it's BLCKSZ minus the other stuff
319-
* that has to be on a disk page. The "other stuff" includes access-method-
320-
* dependent "special space", which we assume will be no more than
321-
* MaxSpecialSpace bytes (currently, on heap pages it's actually zero).
317+
* MaxHeapTupleSize is the maximum allowed size of a heap tuple, including
318+
* header and MAXALIGN alignment padding. Basically it's BLCKSZ minus the
319+
* other stuff that has to be on a disk page. Since heap pages use no
320+
* "special space", there's no deduction for that.
322321
*
323322
* NOTE: we do not need to count an ItemId for the tuple because
324-
* sizeof(PageHeaderData) includes the first ItemId on the page.
323+
* sizeof(PageHeaderData) includes the first ItemId on the page. But beware
324+
* of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
325+
* on the same page.
325326
*/
326-
#define MaxSpecialSpace 32
327-
328-
#define MaxTupleSize \
329-
(BLCKSZ - MAXALIGN(sizeof(PageHeaderData) + MaxSpecialSpace))
327+
#define MaxHeapTupleSize (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))
330328

331329
/*
332330
* MaxHeapTuplesPerPage is an upper bound on the number of tuples that can

src/include/access/nbtree.h

Lines changed: 9 additions & 4 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/access/nbtree.h,v 1.109 2007/01/20 18:43:35 neilc Exp $
10+
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.110 2007/02/05 04:22:18 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -99,13 +99,18 @@ typedef struct BTMetaPageData
9999
#define BTREE_VERSION 2 /* current version number */
100100

101101
/*
102+
* Maximum size of a btree index entry, including its tuple header.
103+
*
102104
* We actually need to be able to fit three items on every page,
103105
* so restrict any one item to 1/3 the per-page available space.
106+
*
107+
* Note: sizeof(PageHeaderData) includes the first ItemId, but we have
108+
* to allow for 2 more, as well as the end-of-page special space.
104109
*/
105110
#define BTMaxItemSize(page) \
106-
((PageGetPageSize(page) - \
107-
sizeof(PageHeaderData) - \
108-
MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData))
111+
MAXALIGN_DOWN((PageGetPageSize(page) - \
112+
MAXALIGN(sizeof(PageHeaderData) + 2*sizeof(ItemIdData)) - \
113+
MAXALIGN(sizeof(BTPageOpaqueData))) / 3)
109114

110115
/*
111116
* The leaf-page fillfactor defaults to 90% but is user-adjustable.

src/include/access/tuptoaster.h

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
88
*
9-
* $PostgreSQL: pgsql/src/include/access/tuptoaster.h,v 1.31 2007/02/04 20:00:37 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/access/tuptoaster.h,v 1.32 2007/02/05 04:22:18 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -29,40 +29,47 @@
2929
* TOAST_TUPLE_TARGET bytes. Both numbers include all tuple header overhead
3030
* and between-fields alignment padding, but we do *not* consider any
3131
* end-of-tuple alignment padding; hence the values can be compared directly
32-
* to a tuple's t_len field. (Note that the symbol values are not
33-
* necessarily MAXALIGN multiples.)
32+
* to a tuple's t_len field. We choose TOAST_TUPLE_THRESHOLD with the
33+
* knowledge that toast-table tuples will be exactly that size, and we'd
34+
* like to fit four of them per page with minimal space wastage.
3435
*
3536
* The numbers need not be the same, though they currently are.
37+
*
38+
* Note: sizeof(PageHeaderData) includes the first ItemId, but we have
39+
* to allow for 3 more, if we want to fit 4 tuples on a page.
3640
*/
37-
#define TOAST_TUPLE_THRESHOLD (MaxTupleSize / 4)
41+
#define TOAST_TUPLE_THRESHOLD \
42+
MAXALIGN_DOWN((BLCKSZ - \
43+
MAXALIGN(sizeof(PageHeaderData) + 3 * sizeof(ItemIdData))) \
44+
/ 4)
3845

39-
#define TOAST_TUPLE_TARGET (MaxTupleSize / 4)
46+
#define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD
4047

4148
/*
4249
* If an index value is larger than TOAST_INDEX_TARGET, we will try to
4350
* compress it (we can't move it out-of-line, however). Note that this
4451
* number is per-datum, not per-tuple, for simplicity in index_form_tuple().
4552
*/
46-
#define TOAST_INDEX_TARGET (MaxTupleSize / 16)
53+
#define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16)
4754

4855
/*
4956
* When we store an oversize datum externally, we divide it into chunks
5057
* containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must*
5158
* be small enough that the completed toast-table tuple (including the
52-
* ID and sequence fields and all overhead) is no more than MaxTupleSize
59+
* ID and sequence fields and all overhead) is no more than MaxHeapTupleSize
5360
* bytes. It *should* be small enough to make toast-table tuples no more
5461
* than TOAST_TUPLE_THRESHOLD bytes, else heapam.c will uselessly invoke
55-
* the toaster on toast-table tuples.
62+
* the toaster on toast-table tuples. The current coding ensures that the
63+
* maximum tuple length is exactly TOAST_TUPLE_THRESHOLD bytes.
5664
*
5765
* NB: you cannot change this value without forcing initdb, at least not
5866
* if your DB contains any multi-chunk toasted values.
5967
*/
6068
#define TOAST_MAX_CHUNK_SIZE (TOAST_TUPLE_THRESHOLD - \
61-
MAXALIGN( \
62-
MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + \
63-
sizeof(Oid) + \
64-
sizeof(int32) + \
65-
VARHDRSZ))
69+
MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) - \
70+
sizeof(Oid) - \
71+
sizeof(int32) - \
72+
VARHDRSZ)
6673

6774

6875
/* ----------

src/include/c.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
15-
* $PostgreSQL: pgsql/src/include/c.h,v 1.217 2007/01/25 03:30:43 momjian Exp $
15+
* $PostgreSQL: pgsql/src/include/c.h,v 1.218 2007/02/05 04:22:18 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -537,12 +537,12 @@ typedef NameData *Name;
537537

538538
/* ----------------
539539
* Alignment macros: align a length or address appropriately for a given type.
540+
* The fooALIGN() macros round up to a multiple of the required alignment,
541+
* while the fooALIGN_DOWN() macros round down. The latter are more useful
542+
* for problems like "how many X-sized structures will fit in a page?".
540543
*
541-
* There used to be some incredibly crufty platform-dependent hackery here,
542-
* but now we rely on the configure script to get the info for us. Much nicer.
543-
*
544-
* NOTE: TYPEALIGN will not work if ALIGNVAL is not a power of 2.
545-
* That case seems extremely unlikely to occur in practice, however.
544+
* NOTE: TYPEALIGN[_DOWN] will not work if ALIGNVAL is not a power of 2.
545+
* That case seems extremely unlikely to be needed in practice, however.
546546
* ----------------
547547
*/
548548

@@ -557,6 +557,14 @@ typedef NameData *Name;
557557
/* MAXALIGN covers only built-in types, not buffers */
558558
#define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN))
559559

560+
#define TYPEALIGN_DOWN(ALIGNVAL,LEN) \
561+
(((long) (LEN)) & ~((long) ((ALIGNVAL) - 1)))
562+
563+
#define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN))
564+
#define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN))
565+
#define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN))
566+
#define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN))
567+
#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN))
560568

561569
/* ----------------------------------------------------------------
562570
* Section 6: widely useful macros

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.379 2007/02/03 14:06:55 petere Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.380 2007/02/05 04:22:18 tgl Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 200702031
56+
#define CATALOG_VERSION_NO 200702041
5757

5858
#endif

0 commit comments

Comments
 (0)