Commit dbab0c07 authored by Michael Paquier's avatar Michael Paquier

Remove forced toast recompression in VACUUM FULL/CLUSTER

The extra checks added by the recompression of toast data introduced in
bbe0a81d is proving to have a performance impact on VACUUM or CLUSTER
even if no recompression is done.  This is more noticeable with more
toastable columns that contain non-NULL values.

Improvements could be done to make those extra checks less expensive,
but that's not material for 14 at this stage, and we are not sure either
if the code path of VACUUM FULL/CLUSTER is adapted for this job.

Per discussion with several people, including Andres Freund, Robert
Haas, Álvaro Herrera, Tom Lane and myself.

Discussion: https://postgr.es/m/20210527003144.xxqppojoiwurc2iz@alap3.anarazel.de
parent f807e341
...@@ -394,8 +394,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM ...@@ -394,8 +394,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
values inserted in future will be compressed (if the storage mode values inserted in future will be compressed (if the storage mode
permits compression at all). permits compression at all).
This does not cause the table to be rewritten, so existing data may still This does not cause the table to be rewritten, so existing data may still
be compressed with other compression methods. If the table is rewritten with be compressed with other compression methods. If the table is restored
<command>VACUUM FULL</command> or <command>CLUSTER</command>, or restored
with <application>pg_restore</application>, then all values are rewritten with <application>pg_restore</application>, then all values are rewritten
with the configured compression method. with the configured compression method.
However, when data is inserted from another relation (for example, However, when data is inserted from another relation (for example,
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/detoast.h"
#include "access/genam.h" #include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/heaptoast.h" #include "access/heaptoast.h"
...@@ -27,7 +26,6 @@ ...@@ -27,7 +26,6 @@
#include "access/rewriteheap.h" #include "access/rewriteheap.h"
#include "access/syncscan.h" #include "access/syncscan.h"
#include "access/tableam.h" #include "access/tableam.h"
#include "access/toast_compression.h"
#include "access/tsmapi.h" #include "access/tsmapi.h"
#include "access/xact.h" #include "access/xact.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
...@@ -2463,64 +2461,14 @@ reform_and_rewrite_tuple(HeapTuple tuple, ...@@ -2463,64 +2461,14 @@ reform_and_rewrite_tuple(HeapTuple tuple,
TupleDesc newTupDesc = RelationGetDescr(NewHeap); TupleDesc newTupDesc = RelationGetDescr(NewHeap);
HeapTuple copiedTuple; HeapTuple copiedTuple;
int i; int i;
bool values_free[MaxTupleAttributeNumber];
memset(values_free, 0, newTupDesc->natts * sizeof(bool));
heap_deform_tuple(tuple, oldTupDesc, values, isnull); heap_deform_tuple(tuple, oldTupDesc, values, isnull);
/* Be sure to null out any dropped columns */
for (i = 0; i < newTupDesc->natts; i++) for (i = 0; i < newTupDesc->natts; i++)
{ {
/* Be sure to null out any dropped columns */
if (TupleDescAttr(newTupDesc, i)->attisdropped) if (TupleDescAttr(newTupDesc, i)->attisdropped)
isnull[i] = true; isnull[i] = true;
else if (!isnull[i] && TupleDescAttr(newTupDesc, i)->attlen == -1)
{
/*
* Use this opportunity to force recompression of any data that's
* compressed with some TOAST compression method other than the
* one configured for the column. We don't actually need to
* perform the compression here; we just need to decompress. That
* will trigger recompression later on.
*/
struct varlena *new_value;
ToastCompressionId cmid;
char cmethod;
char targetmethod;
new_value = (struct varlena *) DatumGetPointer(values[i]);
cmid = toast_get_compression_id(new_value);
/* nothing to be done for uncompressed data */
if (cmid == TOAST_INVALID_COMPRESSION_ID)
continue;
/* convert existing compression id to compression method */
switch (cmid)
{
case TOAST_PGLZ_COMPRESSION_ID:
cmethod = TOAST_PGLZ_COMPRESSION;
break;
case TOAST_LZ4_COMPRESSION_ID:
cmethod = TOAST_LZ4_COMPRESSION;
break;
default:
elog(ERROR, "invalid compression method id %d", cmid);
cmethod = '\0'; /* keep compiler quiet */
}
/* figure out what the target method is */
targetmethod = TupleDescAttr(newTupDesc, i)->attcompression;
if (!CompressionMethodIsValid(targetmethod))
targetmethod = default_toast_compression;
/* if compression method doesn't match then detoast the value */
if (targetmethod != cmethod)
{
values[i] = PointerGetDatum(detoast_attr(new_value));
values_free[i] = true;
}
}
} }
copiedTuple = heap_form_tuple(newTupDesc, values, isnull); copiedTuple = heap_form_tuple(newTupDesc, values, isnull);
...@@ -2528,13 +2476,6 @@ reform_and_rewrite_tuple(HeapTuple tuple, ...@@ -2528,13 +2476,6 @@ reform_and_rewrite_tuple(HeapTuple tuple,
/* The heap rewrite module does the rest */ /* The heap rewrite module does the rest */
rewrite_heap_tuple(rwstate, tuple, copiedTuple); rewrite_heap_tuple(rwstate, tuple, copiedTuple);
/* Free any value detoasted previously */
for (i = 0; i < newTupDesc->natts; i++)
{
if (values_free[i])
pfree(DatumGetPointer(values[i]));
}
heap_freetuple(copiedTuple); heap_freetuple(copiedTuple);
} }
......
...@@ -297,7 +297,7 @@ SELECT pg_column_compression(f1) FROM cmpart2; ...@@ -297,7 +297,7 @@ SELECT pg_column_compression(f1) FROM cmpart2;
lz4 lz4
(2 rows) (2 rows)
--vacuum full to recompress the data -- VACUUM FULL does not recompress
SELECT pg_column_compression(f1) FROM cmdata; SELECT pg_column_compression(f1) FROM cmdata;
pg_column_compression pg_column_compression
----------------------- -----------------------
...@@ -309,7 +309,7 @@ VACUUM FULL cmdata; ...@@ -309,7 +309,7 @@ VACUUM FULL cmdata;
SELECT pg_column_compression(f1) FROM cmdata; SELECT pg_column_compression(f1) FROM cmdata;
pg_column_compression pg_column_compression
----------------------- -----------------------
lz4 pglz
lz4 lz4
(2 rows) (2 rows)
......
...@@ -293,7 +293,7 @@ SELECT pg_column_compression(f1) FROM cmpart2; ...@@ -293,7 +293,7 @@ SELECT pg_column_compression(f1) FROM cmpart2;
----------------------- -----------------------
(0 rows) (0 rows)
--vacuum full to recompress the data -- VACUUM FULL does not recompress
SELECT pg_column_compression(f1) FROM cmdata; SELECT pg_column_compression(f1) FROM cmdata;
pg_column_compression pg_column_compression
----------------------- -----------------------
......
...@@ -126,7 +126,7 @@ INSERT INTO cmpart VALUES (repeat('123456789', 4004)); ...@@ -126,7 +126,7 @@ INSERT INTO cmpart VALUES (repeat('123456789', 4004));
SELECT pg_column_compression(f1) FROM cmpart1; SELECT pg_column_compression(f1) FROM cmpart1;
SELECT pg_column_compression(f1) FROM cmpart2; SELECT pg_column_compression(f1) FROM cmpart2;
--vacuum full to recompress the data -- VACUUM FULL does not recompress
SELECT pg_column_compression(f1) FROM cmdata; SELECT pg_column_compression(f1) FROM cmdata;
VACUUM FULL cmdata; VACUUM FULL cmdata;
SELECT pg_column_compression(f1) FROM cmdata; SELECT pg_column_compression(f1) FROM cmdata;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment