Skip to content

Commit

Permalink
Add GUC for hypercore_use_access_method default
Browse files Browse the repository at this point in the history
Add the GUC `timescaledb.hypercore_use_access_method` for dealing with
the default value to use for functions accepting the
`hypercore_use_access_method` parameter (`compress_chunk`,
`add_compression_policy`, etc.)

Value can be "on" (use the hypercore access method) or "off" (do not
use the hypercore access method) and can be overridden by the parameter
to the functions by explicitly providing a value. If no value is
chosen, the default will be picked.

Make GUC a boolean instead
  • Loading branch information
mkindahl committed Nov 13, 2024
1 parent a81cb28 commit 48a64e6
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 17 deletions.
1 change: 1 addition & 0 deletions .unreleased/pr_7412
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implements: #7412 Add GUC for hypercore_use_access_method default
14 changes: 14 additions & 0 deletions src/guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "guc.h"
#include "hypertable_cache.h"
#include "license_guc.h"

#ifdef USE_TELEMETRY
#include "telemetry/telemetry.h"
#endif
Expand Down Expand Up @@ -139,6 +140,7 @@ bool ts_guc_enable_custom_hashagg = false;
TSDLLEXPORT bool ts_guc_enable_compression_indexscan = false;
TSDLLEXPORT bool ts_guc_enable_bulk_decompression = true;
TSDLLEXPORT bool ts_guc_auto_sparse_indexes = true;
TSDLLEXPORT bool ts_guc_default_hypercore_use_access_method = false;
bool ts_guc_enable_chunk_skipping = false;
TSDLLEXPORT bool ts_guc_enable_segmentwise_recompression = true;

Expand Down Expand Up @@ -1117,6 +1119,18 @@ _guc_init(void)
/* show_hook= */ NULL);
#endif

DefineCustomBoolVariable(MAKE_EXTOPTION("default_hypercore_use_access_method"),
gettext_noop("Enable to always use Hypercore TAM when compressing."),
gettext_noop("Sets the global default for using Hypercore TAM when "
"compressing chunks."),
&ts_guc_default_hypercore_use_access_method,
false,
/* context= */ PGC_USERSET,
/* flags= */ 0,
/* check_hook= */ NULL,
/* assign_hook= */ NULL,
/* show_hook= */ NULL);

/* register feature flags */
ts_feature_flag_add(FEATURE_HYPERTABLE);
ts_feature_flag_add(FEATURE_HYPERTABLE_COMPRESSION);
Expand Down
17 changes: 17 additions & 0 deletions src/guc.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
#include "config.h"
#include "export.h"

/*
* Decide if the access method should be used for compression, or if it is
* undefined. Used for parameter values to PostgreSQL functions and is a
* nullable boolean.
*
* Using explicit values of TRUE = 1 and FALSE = 0 since this enum is cast to
* boolean value in the code.
*/
typedef enum UseAccessMethod
{
USE_AM_FALSE = 0,
USE_AM_TRUE = 1,
USE_AM_NULL = 2,
} UseAccessMethod;

#ifdef USE_TELEMETRY
extern bool ts_telemetry_on(void);
extern bool ts_function_telemetry_on(void);
Expand Down Expand Up @@ -102,6 +117,7 @@ extern TSDLLEXPORT DebugRequireOption ts_guc_debug_require_vector_agg;

extern TSDLLEXPORT bool ts_guc_debug_compression_path_info;
extern TSDLLEXPORT bool ts_guc_enable_rowlevel_compression_locking;
extern TSDLLEXPORT bool ts_guc_default_hypercore_use_access_method;

extern TSDLLEXPORT bool ts_guc_debug_require_batch_sorted_merge;

Expand All @@ -121,4 +137,5 @@ typedef enum
extern TSDLLEXPORT void ts_feature_flag_check(FeatureFlagType);
extern TSDLLEXPORT Oid ts_guc_default_segmentby_fn_oid(void);
extern TSDLLEXPORT Oid ts_guc_default_orderby_fn_oid(void);

extern TSDLLEXPORT bool ts_is_whitelisted_indexam(const char *amname);
3 changes: 2 additions & 1 deletion tsl/src/bgw_policy/compression_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
#pragma once

#include <postgres.h>
#include "compression/api.h"
#include <utils/jsonb.h>
#include <utils/timestamp.h>

#include "guc.h"

/* User-facing API functions */
extern Datum policy_compression_add(PG_FUNCTION_ARGS);
extern Datum policy_compression_remove(PG_FUNCTION_ARGS);
Expand Down
12 changes: 11 additions & 1 deletion tsl/src/compression/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -838,13 +838,23 @@ compress_hypercore(Chunk *chunk, bool rel_is_hypercore, UseAccessMethod useam,
return relid;
}

/*
* Check the value of the use_access_method argument and use the default value
* otherwise.
*/
static UseAccessMethod
check_useam(UseAccessMethod arg)
{
return arg == USE_AM_NULL ? (UseAccessMethod) ts_guc_default_hypercore_use_access_method : arg;
}

Datum
tsl_compress_chunk(PG_FUNCTION_ARGS)
{
Oid uncompressed_chunk_id = PG_ARGISNULL(0) ? InvalidOid : PG_GETARG_OID(0);
bool if_not_compressed = PG_ARGISNULL(1) ? true : PG_GETARG_BOOL(1);
bool recompress = PG_ARGISNULL(2) ? false : PG_GETARG_BOOL(2);
UseAccessMethod useam = PG_ARGISNULL(3) ? USE_AM_NULL : PG_GETARG_BOOL(3);
UseAccessMethod useam = check_useam(PG_ARGISNULL(3) ? USE_AM_NULL : PG_GETARG_BOOL(3));

ts_feature_flag_check(FEATURE_HYPERTABLE_COMPRESSION);

Expand Down
15 changes: 0 additions & 15 deletions tsl/src/compression/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,6 @@

#include "chunk.h"

/*
* Decide if the access method should be used for compression, or if it is
* undefined. Used for parameter values to PostgreSQL functions and is a
* nullable boolean.
*
* Using explicit values of TRUE = 1 and FALSE = 0 since this enum is cast to
* boolean value in the code.
*/
typedef enum UseAccessMethod
{
USE_AM_FALSE = 0,
USE_AM_TRUE = 1,
USE_AM_NULL = 2,
} UseAccessMethod;

extern Datum tsl_create_compressed_chunk(PG_FUNCTION_ARGS);
extern Datum tsl_compress_chunk(PG_FUNCTION_ARGS);
extern Datum tsl_decompress_chunk(PG_FUNCTION_ARGS);
Expand Down
2 changes: 2 additions & 0 deletions tsl/test/expected/hypercore.out
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ SELECT sum(_ts_meta_count) FROM :cchunk;

CALL recompress_chunk(:'chunk');
WARNING: procedure public.recompress_chunk(regclass,boolean) is deprecated and the functionality is now included in public.compress_chunk. this compatibility function will be removed in a future version.
NOTICE: cannot compress hypercore "_hyper_1_1_chunk" using heap, recompressing instead
-- Data should be returned even after recompress, but now from the
-- compressed relation. Still using index scan.
EXPLAIN (verbose, costs off)
Expand Down Expand Up @@ -575,6 +576,7 @@ SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
-- Can't recompress twice without new non-compressed rows
CALL recompress_chunk(:'chunk');
WARNING: procedure public.recompress_chunk(regclass,boolean) is deprecated and the functionality is now included in public.compress_chunk. this compatibility function will be removed in a future version.
NOTICE: cannot compress hypercore "_hyper_1_1_chunk" using heap, recompressing instead
NOTICE: chunk "_hyper_1_1_chunk" is already compressed
\set ON_ERROR_STOP 1
-- Compressed count after recompression
Expand Down
58 changes: 58 additions & 0 deletions tsl/test/expected/hypercore_create.out
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ select ctid from :chunk where created_at = '2022-06-01 10:01' and device_id = 6;
(1 row)

select compress_chunk(:'chunk');
NOTICE: cannot compress hypercore "_hyper_1_1_chunk" using heap, recompressing instead
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_1_1_chunk
Expand Down Expand Up @@ -921,3 +922,60 @@ select * from rides order by pickup_datetime;
745233436676 | Fri Jan 01 00:00:03 2016 PST | Fri Jan 01 00:11:14 2016 PST | 1 | 6.00 | -73.947151184082031 | 40.791046142578125 | 1 | -73.920768737792969 | 40.865577697753906 | 2 | 9 | 0.5 | 0.5 | 0 | 0 | 0.3 | 19.3
(3 rows)

-- All these are valid methods to set the default
show timescaledb.default_hypercore_use_access_method;
timescaledb.default_hypercore_use_access_method
-------------------------------------------------
off
(1 row)

set timescaledb.default_hypercore_use_access_method to on;
set timescaledb.default_hypercore_use_access_method to off;
set timescaledb.default_hypercore_use_access_method to true;
set timescaledb.default_hypercore_use_access_method to false;
set timescaledb.default_hypercore_use_access_method to yes;
set timescaledb.default_hypercore_use_access_method to no;
set timescaledb.default_hypercore_use_access_method to 0;
set timescaledb.default_hypercore_use_access_method to 1;
show timescaledb.default_hypercore_use_access_method;
timescaledb.default_hypercore_use_access_method
-------------------------------------------------
on
(1 row)

-- This should unset the value
reset timescaledb.default_hypercore_use_access_method;
show timescaledb.default_hypercore_use_access_method;
timescaledb.default_hypercore_use_access_method
-------------------------------------------------
off
(1 row)

-- Using GUC should compress using the hyperstore
set timescaledb.default_hypercore_use_access_method to on;
create table test5 (time timestamptz not null, device int, temp float);
select created from create_hypertable('test5', 'time');
created
---------
t
(1 row)

insert into test5 values ('2022-06-01', 1, 1.0), ('2022-08-01', 1, 1.0);
select ch as chunk from show_chunks('test5') ch limit 1 \gset
alter table test5 set (timescaledb.compress);
WARNING: there was some uncertainty picking the default segment by for the hypertable: You do not have any indexes on columns that can be used for segment_by and thus we are not using segment_by for compression. Please make sure you are not missing any indexes
NOTICE: default segment by for hypertable "test5" is set to ""
NOTICE: default order by for hypertable "test5" is set to ""time" DESC"
select compress_chunk(:'chunk');
compress_chunk
------------------------------------------
_timescaledb_internal._hyper_10_46_chunk
(1 row)

select * from amrels where relparent = 'test5'::regclass;
rel | amname | relparent
------------------------------------------+-----------+-----------
_timescaledb_internal._hyper_10_46_chunk | hypercore | test5
_timescaledb_internal._hyper_10_47_chunk | heap | test5
(2 rows)

2 changes: 2 additions & 0 deletions tsl/test/expected/hypercore_vacuum.out
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ insert into hystable (time, location, device, temp)
values ('2022-06-01 00:01', 1, 1, 1.0);
-- Recompress to get data back into compressed form
select compress_chunk(:'hystable_chunk');
NOTICE: cannot compress hypercore "_hyper_1_2_chunk" using heap, recompressing instead
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_1_2_chunk
Expand Down Expand Up @@ -310,6 +311,7 @@ select tuple_count from pgstattuple(:'hystable_device_chunk_idx');
-- rebuild indexes. It will optimize the structure of the index and
-- thus reduce the number of index tuples
select compress_chunk(:'hystable_chunk');
NOTICE: cannot compress hypercore "_hyper_1_2_chunk" using heap, recompressing instead
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_1_2_chunk
Expand Down
27 changes: 27 additions & 0 deletions tsl/test/sql/hypercore_create.sql
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,30 @@ analyze rides;
explain (costs off)
select * from rides order by pickup_datetime;
select * from rides order by pickup_datetime;

-- All these are valid methods to set the default
show timescaledb.default_hypercore_use_access_method;
set timescaledb.default_hypercore_use_access_method to on;
set timescaledb.default_hypercore_use_access_method to off;
set timescaledb.default_hypercore_use_access_method to true;
set timescaledb.default_hypercore_use_access_method to false;
set timescaledb.default_hypercore_use_access_method to yes;
set timescaledb.default_hypercore_use_access_method to no;
set timescaledb.default_hypercore_use_access_method to 0;
set timescaledb.default_hypercore_use_access_method to 1;
show timescaledb.default_hypercore_use_access_method;

-- This should unset the value
reset timescaledb.default_hypercore_use_access_method;
show timescaledb.default_hypercore_use_access_method;

-- Using GUC should compress using the hyperstore
set timescaledb.default_hypercore_use_access_method to on;
create table test5 (time timestamptz not null, device int, temp float);
select created from create_hypertable('test5', 'time');
insert into test5 values ('2022-06-01', 1, 1.0), ('2022-08-01', 1, 1.0);

select ch as chunk from show_chunks('test5') ch limit 1 \gset
alter table test5 set (timescaledb.compress);
select compress_chunk(:'chunk');
select * from amrels where relparent = 'test5'::regclass;

0 comments on commit 48a64e6

Please sign in to comment.