Parameter toast_tuple_target controls TOAST for new rows
Specifies the point at which we try to move long column values into TOAST tables. No effect on existing rows. Discussion: https://postgr.es/m/CANP8+jKsVmw6CX6YP9z7zqkTzcKV1+Uzr3XjKcZW=2Ya00OyQQ@mail.gmail.com Author: Simon Riggs <simon@2ndQudrant.com> Reviewed-by: Andrew Dunstan <andrew.dunstan@2ndQuadrant.com>
This commit is contained in:
parent
52f63bd916
commit
c2513365a0
@ -629,7 +629,7 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<literal>SHARE UPDATE EXCLUSIVE</literal> lock will be taken for
|
<literal>SHARE UPDATE EXCLUSIVE</literal> lock will be taken for
|
||||||
fillfactor and autovacuum storage parameters, as well as the
|
fillfactor, toast and autovacuum storage parameters, as well as the
|
||||||
following planner related parameters:
|
following planner related parameters:
|
||||||
<varname>effective_io_concurrency</varname>, <varname>parallel_workers</varname>, <varname>seq_page_cost</varname>,
|
<varname>effective_io_concurrency</varname>, <varname>parallel_workers</varname>, <varname>seq_page_cost</varname>,
|
||||||
<varname>random_page_cost</varname>, <varname>n_distinct</varname> and <varname>n_distinct_inherited</varname>.
|
<varname>random_page_cost</varname>, <varname>n_distinct</varname> and <varname>n_distinct_inherited</varname>.
|
||||||
|
@ -1200,6 +1200,27 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>toast_tuple_target</> (<type>integer</>)</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The toast_tuple_target specifies the minimum tuple length required before
|
||||||
|
we try to move long column values into TOAST tables, and is also the
|
||||||
|
target length we try to reduce the length below once toasting begins.
|
||||||
|
This only affects columns marked as either External or Extended
|
||||||
|
and applies only to new tuples - there is no effect on existing rows.
|
||||||
|
By default this parameter is set to allow at least 4 tuples per block,
|
||||||
|
which with the default blocksize will be 2040 bytes. Valid values are
|
||||||
|
between 128 bytes and the (blocksize - header), by default 8160 bytes.
|
||||||
|
Changing this value may not be useful for very short or very long rows.
|
||||||
|
Note that the default setting is often close to optimal, and
|
||||||
|
it is possible that setting this parameter could have negative
|
||||||
|
effects in some cases.
|
||||||
|
This parameter cannot be set for TOAST tables.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>parallel_workers</literal> (<type>integer</type>)</term>
|
<term><literal>parallel_workers</literal> (<type>integer</type>)</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "access/nbtree.h"
|
#include "access/nbtree.h"
|
||||||
#include "access/reloptions.h"
|
#include "access/reloptions.h"
|
||||||
#include "access/spgist.h"
|
#include "access/spgist.h"
|
||||||
|
#include "access/tuptoaster.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/tablespace.h"
|
#include "commands/tablespace.h"
|
||||||
@ -290,6 +291,15 @@ static relopt_int intRelOpts[] =
|
|||||||
},
|
},
|
||||||
-1, -1, INT_MAX
|
-1, -1, INT_MAX
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"toast_tuple_target",
|
||||||
|
"Sets the target tuple length at which external columns will be toasted",
|
||||||
|
RELOPT_KIND_HEAP,
|
||||||
|
ShareUpdateExclusiveLock
|
||||||
|
},
|
||||||
|
TOAST_TUPLE_TARGET, 128, TOAST_TUPLE_TARGET_MAIN
|
||||||
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"pages_per_range",
|
"pages_per_range",
|
||||||
@ -1344,6 +1354,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
|||||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_table_age)},
|
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_table_age)},
|
||||||
{"log_autovacuum_min_duration", RELOPT_TYPE_INT,
|
{"log_autovacuum_min_duration", RELOPT_TYPE_INT,
|
||||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)},
|
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)},
|
||||||
|
{"toast_tuple_target", RELOPT_TYPE_INT,
|
||||||
|
offsetof(StdRdOptions, toast_tuple_target)},
|
||||||
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
|
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
|
||||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)},
|
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)},
|
||||||
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
|
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
|
||||||
|
@ -727,7 +727,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
|
|||||||
hoff += sizeof(Oid);
|
hoff += sizeof(Oid);
|
||||||
hoff = MAXALIGN(hoff);
|
hoff = MAXALIGN(hoff);
|
||||||
/* now convert to a limit on the tuple data size */
|
/* now convert to a limit on the tuple data size */
|
||||||
maxDataLen = TOAST_TUPLE_TARGET - hoff;
|
maxDataLen = RelationGetToastTupleTarget(rel, TOAST_TUPLE_TARGET) - hoff;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look for attributes with attstorage 'x' to compress. Also find large
|
* Look for attributes with attstorage 'x' to compress. Also find large
|
||||||
|
@ -277,6 +277,7 @@ typedef struct StdRdOptions
|
|||||||
{
|
{
|
||||||
int32 vl_len_; /* varlena header (do not touch directly!) */
|
int32 vl_len_; /* varlena header (do not touch directly!) */
|
||||||
int fillfactor; /* page fill factor in percent (0..100) */
|
int fillfactor; /* page fill factor in percent (0..100) */
|
||||||
|
int toast_tuple_target; /* target for tuple toasting */
|
||||||
AutoVacOpts autovacuum; /* autovacuum-related options */
|
AutoVacOpts autovacuum; /* autovacuum-related options */
|
||||||
bool user_catalog_table; /* use as an additional catalog relation */
|
bool user_catalog_table; /* use as an additional catalog relation */
|
||||||
int parallel_workers; /* max number of parallel workers */
|
int parallel_workers; /* max number of parallel workers */
|
||||||
@ -285,6 +286,14 @@ typedef struct StdRdOptions
|
|||||||
#define HEAP_MIN_FILLFACTOR 10
|
#define HEAP_MIN_FILLFACTOR 10
|
||||||
#define HEAP_DEFAULT_FILLFACTOR 100
|
#define HEAP_DEFAULT_FILLFACTOR 100
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RelationGetToastTupleTarget
|
||||||
|
* Returns the relation's toast_tuple_target. Note multiple eval of argument!
|
||||||
|
*/
|
||||||
|
#define RelationGetToastTupleTarget(relation, defaulttarg) \
|
||||||
|
((relation)->rd_options ? \
|
||||||
|
((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RelationGetFillFactor
|
* RelationGetFillFactor
|
||||||
* Returns the relation's fillfactor. Note multiple eval of argument!
|
* Returns the relation's fillfactor. Note multiple eval of argument!
|
||||||
|
@ -1166,6 +1166,53 @@ SELECT substr(f1, 99995, 10) from toasttest;
|
|||||||
567890
|
567890
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
|
TRUNCATE TABLE toasttest;
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
SELECT pg_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
blocks
|
||||||
|
--------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks;
|
||||||
|
blocks
|
||||||
|
--------
|
||||||
|
3
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT pg_total_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
blocks
|
||||||
|
--------
|
||||||
|
9
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
TRUNCATE TABLE toasttest;
|
||||||
|
ALTER TABLE toasttest set (toast_tuple_target = 4080);
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
SELECT pg_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
blocks
|
||||||
|
--------
|
||||||
|
2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks;
|
||||||
|
blocks
|
||||||
|
--------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT pg_total_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
blocks
|
||||||
|
--------
|
||||||
|
6
|
||||||
|
(1 row)
|
||||||
|
|
||||||
DROP TABLE toasttest;
|
DROP TABLE toasttest;
|
||||||
--
|
--
|
||||||
-- test substr with toasted bytea values
|
-- test substr with toasted bytea values
|
||||||
|
@ -366,6 +366,25 @@ SELECT substr(f1, 99995) from toasttest;
|
|||||||
-- string length
|
-- string length
|
||||||
SELECT substr(f1, 99995, 10) from toasttest;
|
SELECT substr(f1, 99995, 10) from toasttest;
|
||||||
|
|
||||||
|
TRUNCATE TABLE toasttest;
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
SELECT pg_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
select pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks;
|
||||||
|
SELECT pg_total_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
|
||||||
|
TRUNCATE TABLE toasttest;
|
||||||
|
ALTER TABLE toasttest set (toast_tuple_target = 4080);
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
INSERT INTO toasttest values (repeat('1234567890',400));
|
||||||
|
SELECT pg_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
select pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks;
|
||||||
|
SELECT pg_total_relation_size('toasttest')/current_setting('block_size')::integer as blocks;
|
||||||
|
|
||||||
DROP TABLE toasttest;
|
DROP TABLE toasttest;
|
||||||
|
|
||||||
--
|
--
|
||||||
|
Loading…
x
Reference in New Issue
Block a user