Skip to content

Commit 6a8fa5f

Browse files
huansongreshke
authored andcommitted
Toasting for AO tables should still use custom toast_tuple_target
In commit a0684da we made a change to use the fixed TOAST_TUPLE_TARGET instead of custom toast_tuple_target that's calculated based on the the blocksize of the AO table for toasting AO table tuples. This caused an issue that some tuples that are well beyond the toast_tuple_target are not being toasted (because they're smaller than TOAST_TUPLE_TARGET). This is ok when the tuples can still fit into the AO table's blocksize. But if not, an error would occur. E.g.: postgres=# create table t (a int, b int[]) WITH (appendonly=true, blocksize=8192); CREATE TABLE postgres=# insert into t select 1, array_agg(x) from generate_series(1, 2030) x; ERROR: item too long (check #1): length 8160, maxBufferLen 8168 CONTEXT: Append-Only table 't' Therefore, we should revert those changes, including: 1. Still use the toast_tuple_target for toasting 'x' and 'e' columns for AO tables. There's also a GPDB_12_MERGE_FIXME in the original comment suggesting to use RelationGetToastTupleTarget for AO table (in order to unify the logic to calculate maxDataLen for heap and AO tuples, I suppose). But that's not possible currently because the calculated toast_tuple_target is stored in AppendOnlyInsertDesc and we cannot get it from the Relation struct. And it seems to me that we won't have a way to do that easily. Therefore, keep this FIXME comment being removed. 2. Still use the toast_tuple_target for toasting 'm' columns for AO tables. Also restore the FIXME comment suggesting that we should use a bigger target size for 'm' columns. This should be something that worth investigating more into. Commit a0684da also includes a change to use custom toast_tuple_target for heap tables, which should be a valid change. I think that fixed an oversight when merging the upstream commit c251336.
1 parent 3471e67 commit 6a8fa5f

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

src/backend/access/heap/heaptoast.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,8 @@ heap_toast_insert_or_update_generic(Relation rel, void *newtup, void *oldtup,
210210
}
211211
else
212212
{
213-
/* Since reloptions for AO table is not permitted, so using TOAST_TUPLE_TARGET */
214-
hoff = sizeof(MemTupleData);
215-
hoff = MAXALIGN(hoff);
216-
maxDataLen = TOAST_TUPLE_TARGET - hoff;
213+
maxDataLen = toast_tuple_target;
214+
hoff = -1; /* keep compiler quiet about using 'hoff' uninitialized */
217215
}
218216

219217
/*
@@ -295,7 +293,15 @@ heap_toast_insert_or_update_generic(Relation rel, void *newtup, void *oldtup,
295293
* increase the target tuple size, so that MAIN attributes aren't stored
296294
* externally unless really necessary.
297295
*/
298-
maxDataLen = TOAST_TUPLE_TARGET_MAIN - hoff;
296+
/*
297+
* FIXME: Should we do something like this with memtuples on
298+
* AO tables too? Currently we do not increase the target tuple size for AO
299+
* table, so there are occasions when columns of type 'm' will be stored
300+
* out-of-line but they could otherwise be accommodated in-block
301+
* c.f. upstream Postgres commit ca7c8168de76459380577eda56a3ed09b4f6195c
302+
*/
303+
if (!ismemtuple)
304+
maxDataLen = TOAST_TUPLE_TARGET_MAIN - hoff;
299305

300306
while (heap_compute_data_size(tupleDesc,
301307
toast_values, toast_isnull) > maxDataLen &&

src/test/regress/expected/toast.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ SELECT char_length(a), char_length(b), c FROM toastable_ao ORDER BY c;
3939
10000000 | 10000032 | 3
4040
(3 rows)
4141

42+
-- Check that small tuples can be correctly toasted as long as it's beyond the toast
43+
-- target size (about 1/4 of the table's blocksize)
44+
CREATE TABLE toastable_ao2(a int, b int[]) WITH (appendonly=true, blocksize=8192);
45+
INSERT INTO toastable_ao2 SELECT 1, array_agg(x) from generate_series(1, 1000) x;
46+
INSERT INTO toastable_ao2 SELECT 1, array_agg(x) from generate_series(1, 2030) x;
47+
SELECT gp_segment_id, get_rel_toast_count('toastable_ao2') FROM gp_dist_random('gp_id') order by gp_segment_id;
48+
gp_segment_id | get_rel_toast_count
49+
---------------+---------------------
50+
0 | 0
51+
1 | 2
52+
2 | 0
53+
(3 rows)
54+
4255
-- UPDATE
4356
-- (heap rel only) and toast the large tuple
4457
UPDATE toastable_heap SET a=repeat('A',100000) WHERE c=1;

src/test/regress/sql/toast.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ CREATE TABLE toastable_heap(a text, b varchar, c int) distributed by (b);
33
CREATE TABLE toastable_ao(a text, b varchar, c int) with(appendonly=true, compresslevel=1) distributed by (b);
44
ALTER TABLE toastable_ao ALTER COLUMN a SET STORAGE EXTERNAL;
55

6+
-- start_ignore
7+
create language plpython3u;
8+
-- end_ignore
9+
610
-- Helper function to generate a random string with given length. (Due to the
711
-- implementation, the length is rounded down to nearest multiple of 32.
812
-- That's good enough for our purposes.)
@@ -33,6 +37,14 @@ INSERT INTO toastable_ao VALUES(randomtext(10000000), randomtext(10000032), 3);
3337
SELECT char_length(a), char_length(b), c FROM toastable_heap ORDER BY c;
3438
SELECT char_length(a), char_length(b), c FROM toastable_ao ORDER BY c;
3539

40+
-- Check that small tuples can be correctly toasted as long as it's beyond the toast
41+
-- target size (about 1/4 of the table's blocksize)
42+
CREATE TABLE toastable_ao2(a int, b int[]) WITH (appendonly=true, blocksize=8192);
43+
INSERT INTO toastable_ao2 SELECT 1, array_agg(x) from generate_series(1, 1000) x;
44+
INSERT INTO toastable_ao2 SELECT 1, array_agg(x) from generate_series(1, 2030) x;
45+
SELECT gp_segment_id, get_rel_toast_count('toastable_ao2') FROM gp_dist_random('gp_id') order by gp_segment_id;
46+
47+
3648
-- UPDATE
3749
-- (heap rel only) and toast the large tuple
3850
UPDATE toastable_heap SET a=repeat('A',100000) WHERE c=1;

0 commit comments

Comments
 (0)