Skip to content

Commit

Permalink
Add GUC for segmentwise recompression
Browse files Browse the repository at this point in the history
Add GUC option to enable or disable segmentwise recompression. If
disabled, then a full recompression is done instead when recompression
is attempted through `compress_chunk`. If `recompress_chunk_segmentwise`
is used when GUC is disabled, then an error is thrown.
  • Loading branch information
kpan2034 committed Nov 1, 2024
1 parent 76e3b27 commit bcaea08
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 1 deletion.
1 change: 1 addition & 0 deletions .unreleased/pr_7413
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implements: #7413: Add GUC for segmentwise recompression.
12 changes: 12 additions & 0 deletions src/guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ TSDLLEXPORT bool ts_guc_enable_compression_indexscan = false;
TSDLLEXPORT bool ts_guc_enable_bulk_decompression = true;
TSDLLEXPORT bool ts_guc_auto_sparse_indexes = true;
bool ts_guc_enable_chunk_skipping = false;
TSDLLEXPORT bool ts_guc_enable_segmentwise_recompression = true;

/* Enable of disable columnar scans for columnar-oriented storage engines. If
* disabled, regular sequence scans will be used instead. */
Expand Down Expand Up @@ -703,6 +704,17 @@ _guc_init(void)
NULL,
NULL);

DefineCustomBoolVariable(MAKE_EXTOPTION("enable_segmentwise_recompression"),
"Enable segmentwise recompression functionality",
"Enable segmentwise recompression",
&ts_guc_enable_segmentwise_recompression,
true,
PGC_USERSET,
0,
NULL,
NULL,
NULL);

/*
* Define the limit on number of invalidation-based refreshes we allow per
* refresh call. If this limit is exceeded, fall back to a single refresh that
Expand Down
1 change: 1 addition & 0 deletions src/guc.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ extern bool ts_guc_enable_tss_callbacks;
extern TSDLLEXPORT bool ts_guc_enable_delete_after_compression;
extern TSDLLEXPORT bool ts_guc_enable_merge_on_cagg_refresh;
extern bool ts_guc_enable_chunk_skipping;
extern TSDLLEXPORT bool ts_guc_enable_segmentwise_recompression;

#ifdef USE_TELEMETRY
typedef enum TelemetryLevel
Expand Down
18 changes: 17 additions & 1 deletion tsl/src/compression/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* compress and decompress chunks
*/
#include <postgres.h>
#include "guc.h"
#include <access/tableam.h>
#include <access/xact.h>
#include <catalog/dependency.h>
Expand Down Expand Up @@ -919,12 +920,19 @@ tsl_compress_chunk_wrapper(Chunk *chunk, bool if_not_compressed, bool recompress
return uncompressed_chunk_id;
}

if (ts_chunk_is_partial(chunk) && get_compressed_chunk_index_for_recompression(chunk))
if (ts_guc_enable_segmentwise_recompression && ts_chunk_is_partial(chunk) &&
get_compressed_chunk_index_for_recompression(chunk))
{
uncompressed_chunk_id = recompress_chunk_segmentwise_impl(chunk);
}
else
{
if (!ts_guc_enable_segmentwise_recompression)
elog(NOTICE,
"segmentwise recompression is disabled, performing full recompression on "
"chunk \"%s.%s\"",
NameStr(chunk->fd.schema_name),
NameStr(chunk->fd.table_name));
decompress_chunk_impl(chunk, false);
compress_chunk_impl(chunk->hypertable_relid, chunk->table_id);
}
Expand Down Expand Up @@ -1257,6 +1265,14 @@ tsl_recompress_chunk_segmentwise(PG_FUNCTION_ARGS)
}
else
{
if (!ts_guc_enable_segmentwise_recompression)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("segmentwise recompression functionality disabled, "
"enable it by first setting "
"timescaledb.enable_segmentwise_recompression to on")));
}
uncompressed_chunk_id = recompress_chunk_segmentwise_impl(chunk);
}

Expand Down
33 changes: 33 additions & 0 deletions tsl/test/expected/recompress_chunk_segmentwise.out
Original file line number Diff line number Diff line change
Expand Up @@ -593,3 +593,36 @@ select * from :compressed_chunk_name;
2 | 1 | | Sat Jan 01 01:00:00 2022 PST | Sat Jan 01 01:00:00 2022 PST | BAAAAneAR/JEAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAA7gAE7wCP5IgAAATvAI/kh/8= | BAEAAAAAAAAABAAAAAAAAAAEAAAAAQAAAAEAAAAAAAAABAAAAAAAAAAIAAAAAgAAAAEAAAAAAAAAAQAAAAAAAAAB
(5 rows)

--- Test behaviour when enable_segmentwise_recompression GUC if OFF
CREATE TABLE guc_test(time timestamptz not null, a int, b int, c int);
SELECT create_hypertable('guc_test', by_range('time', INTERVAL '1 day'));
create_hypertable
-------------------
(18,t)
(1 row)

ALTER TABLE guc_test set (timescaledb.compress, timescaledb.compress_segmentby = 'a, b');
NOTICE: default order by for hypertable "guc_test" is set to ""time" DESC"
INSERT INTO guc_test VALUES ('2024-10-30 14:04:00.501519-06'::timestamptz, 1, 1, 1);
SELECT show_chunks as chunk_to_compress FROM show_chunks('guc_test') LIMIT 1 \gset
SELECT compress_chunk(:'chunk_to_compress');
compress_chunk
------------------------------------------
_timescaledb_internal._hyper_18_20_chunk
(1 row)

INSERT INTO guc_test VALUES ('2024-10-30 14:14:00.501519-06'::timestamptz, 1, 1, 2);
-- When GUC is OFF, recompress function should throw an error
SET timescaledb.enable_segmentwise_recompression TO OFF;
\set ON_ERROR_STOP 0
SELECT _timescaledb_functions.recompress_chunk_segmentwise(:'chunk_to_compress');
ERROR: segmentwise recompression functionality disabled, enable it by first setting timescaledb.enable_segmentwise_recompression to on
\set ON_ERROR_STOP 1
-- When GUC is OFF, entire chunk should be fully uncompressed and compressed instead
SELECT compress_chunk(:'chunk_to_compress');
NOTICE: segmentwise recompression is disabled, performing full recompression on chunk "_timescaledb_internal._hyper_18_20_chunk"
compress_chunk
------------------------------------------
_timescaledb_internal._hyper_18_20_chunk
(1 row)

18 changes: 18 additions & 0 deletions tsl/test/sql/recompress_chunk_segmentwise.sql
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,21 @@ select * from :compressed_chunk_name;
insert into nullseg_many values (:'start_time', 1, NULL, NULL);
SELECT compress_chunk(:'chunk_to_compress');
select * from :compressed_chunk_name;

--- Test behaviour when enable_segmentwise_recompression GUC if OFF
CREATE TABLE guc_test(time timestamptz not null, a int, b int, c int);
SELECT create_hypertable('guc_test', by_range('time', INTERVAL '1 day'));

ALTER TABLE guc_test set (timescaledb.compress, timescaledb.compress_segmentby = 'a, b');
INSERT INTO guc_test VALUES ('2024-10-30 14:04:00.501519-06'::timestamptz, 1, 1, 1);
SELECT show_chunks as chunk_to_compress FROM show_chunks('guc_test') LIMIT 1 \gset
SELECT compress_chunk(:'chunk_to_compress');

INSERT INTO guc_test VALUES ('2024-10-30 14:14:00.501519-06'::timestamptz, 1, 1, 2);
-- When GUC is OFF, recompress function should throw an error
SET timescaledb.enable_segmentwise_recompression TO OFF;
\set ON_ERROR_STOP 0
SELECT _timescaledb_functions.recompress_chunk_segmentwise(:'chunk_to_compress');
\set ON_ERROR_STOP 1
-- When GUC is OFF, entire chunk should be fully uncompressed and compressed instead
SELECT compress_chunk(:'chunk_to_compress');

0 comments on commit bcaea08

Please sign in to comment.