mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-21 05:04:32 +08:00
Verify compression configuration on compression rollup
Add a check to verify compression settings for chunks to be rolled up are identical.
This commit is contained in:
parent
4934941f75
commit
83ff9662dc
@ -4,10 +4,14 @@
|
||||
* LICENSE-APACHE for a copy of the license.
|
||||
*/
|
||||
#include <postgres.h>
|
||||
#include <catalog/pg_collation.h>
|
||||
#include <catalog/pg_type.h>
|
||||
#include <fmgr.h>
|
||||
#include <utils/array.h>
|
||||
#include <utils/builtins.h>
|
||||
#include <utils/fmgroids.h>
|
||||
|
||||
#include <compat/compat.h>
|
||||
#include <debug_assert.h>
|
||||
#include "array_utils.h"
|
||||
|
||||
@ -29,6 +33,26 @@ ts_array_length(ArrayType *arr)
|
||||
return ARR_DIMS(arr)[0];
|
||||
}
|
||||
|
||||
extern TSDLLEXPORT bool
|
||||
ts_array_equal(ArrayType *left, ArrayType *right)
|
||||
{
|
||||
/* Quick exit if both are NULL or point to same thing. */
|
||||
if (left == right)
|
||||
return true;
|
||||
|
||||
if (left == NULL || right == NULL)
|
||||
return false;
|
||||
|
||||
Assert(left != NULL && right != NULL && ARR_NDIM(left) == 1 && ARR_NDIM(right) == 1);
|
||||
|
||||
Datum result = OidFunctionCall2Coll(F_ARRAY_EQ,
|
||||
DEFAULT_COLLATION_OID,
|
||||
PointerGetDatum(left),
|
||||
PointerGetDatum(right));
|
||||
|
||||
return DatumGetBool(result);
|
||||
}
|
||||
|
||||
extern TSDLLEXPORT bool
|
||||
ts_array_is_member(ArrayType *arr, const char *name)
|
||||
{
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
extern TSDLLEXPORT int ts_array_length(ArrayType *arr);
|
||||
extern TSDLLEXPORT bool ts_array_equal(ArrayType *left, ArrayType *right);
|
||||
extern TSDLLEXPORT bool ts_array_is_member(ArrayType *arr, const char *name);
|
||||
extern TSDLLEXPORT int ts_array_position(ArrayType *arr, const char *name);
|
||||
|
||||
|
@ -19,6 +19,15 @@ static ScanTupleResult compression_settings_tuple_update(TupleInfo *ti, void *da
|
||||
static HeapTuple compression_settings_formdata_make_tuple(const FormData_compression_settings *fd,
|
||||
TupleDesc desc);
|
||||
|
||||
bool
|
||||
ts_compression_settings_equal(const CompressionSettings *left, const CompressionSettings *right)
|
||||
{
|
||||
return ts_array_equal(left->fd.segmentby, right->fd.segmentby) &&
|
||||
ts_array_equal(left->fd.orderby, right->fd.orderby) &&
|
||||
ts_array_equal(left->fd.orderby_desc, right->fd.orderby_desc) &&
|
||||
ts_array_equal(left->fd.orderby_nullsfirst, right->fd.orderby_nullsfirst);
|
||||
}
|
||||
|
||||
CompressionSettings *
|
||||
ts_compression_settings_materialize(Oid ht_relid, Oid dst_relid)
|
||||
{
|
||||
|
@ -23,6 +23,8 @@ TSDLLEXPORT CompressionSettings *ts_compression_settings_create(Oid relid, Array
|
||||
TSDLLEXPORT CompressionSettings *ts_compression_settings_get(Oid relid);
|
||||
TSDLLEXPORT CompressionSettings *ts_compression_settings_materialize(Oid ht_relid, Oid dst_relid);
|
||||
TSDLLEXPORT bool ts_compression_settings_delete(Oid relid);
|
||||
TSDLLEXPORT bool ts_compression_settings_equal(const CompressionSettings *left,
|
||||
const CompressionSettings *right);
|
||||
|
||||
TSDLLEXPORT int ts_compression_settings_update(CompressionSettings *settings);
|
||||
|
||||
|
@ -385,6 +385,13 @@ find_chunk_to_merge_into(Hypertable *ht, Chunk *current_chunk)
|
||||
compressed_chunk_interval + current_chunk_interval > max_chunk_interval)
|
||||
return NULL;
|
||||
|
||||
/* Get reloid of the previous compressed chunk */
|
||||
Oid prev_comp_reloid = ts_chunk_get_relid(previous_chunk->fd.compressed_chunk_id, false);
|
||||
CompressionSettings *prev_comp_settings = ts_compression_settings_get(prev_comp_reloid);
|
||||
CompressionSettings *ht_comp_settings = ts_compression_settings_get(ht->main_table_relid);
|
||||
if (!ts_compression_settings_equal(ht_comp_settings, prev_comp_settings))
|
||||
return NULL;
|
||||
|
||||
return previous_chunk;
|
||||
}
|
||||
|
||||
|
@ -659,3 +659,132 @@ SELECT count(*) FROM test8 WHERE series_id = 1;
|
||||
481
|
||||
(1 row)
|
||||
|
||||
-- Verify rollup is prevented when compression settings differ
|
||||
CREATE TABLE test9(time TIMESTAMPTZ NOT NULL, value DOUBLE PRECISION NOT NULL, series_id BIGINT NOT NULL);
|
||||
SELECT create_hypertable('test9', 'time', chunk_time_interval => INTERVAL '1 h');
|
||||
create_hypertable
|
||||
---------------------
|
||||
(17,public,test9,t)
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE test9 set (timescaledb.compress,
|
||||
timescaledb.compress_segmentby = 'series_id',
|
||||
timescaledb.compress_orderby = 'time',
|
||||
timescaledb.compress_chunk_time_interval = '1 day');
|
||||
-- create chunk and compress
|
||||
INSERT INTO test9 (time, series_id, value) SELECT '2020-01-01 00:00:00'::TIMESTAMPTZ, 1, 1;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
compress_chunk
|
||||
-------------------------------------------
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
(1 row)
|
||||
|
||||
INSERT INTO test9 (time, series_id, value) SELECT '2020-01-01 01:00:00'::TIMESTAMPTZ, 1, 1;
|
||||
-- should be 2 chunk before rollup
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
hypertable_name | range_start | range_end
|
||||
-----------------+------------------------------+------------------------------
|
||||
test9 | Wed Jan 01 00:00:00 2020 PST | Wed Jan 01 01:00:00 2020 PST
|
||||
test9 | Wed Jan 01 01:00:00 2020 PST | Wed Jan 01 02:00:00 2020 PST
|
||||
(2 rows)
|
||||
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
NOTICE: chunk "_hyper_17_320_chunk" is already compressed
|
||||
compress_chunk
|
||||
-------------------------------------------
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
(2 rows)
|
||||
|
||||
-- should be 1 chunk because of rollup
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
hypertable_name | range_start | range_end
|
||||
-----------------+------------------------------+------------------------------
|
||||
test9 | Wed Jan 01 00:00:00 2020 PST | Wed Jan 01 02:00:00 2020 PST
|
||||
(1 row)
|
||||
|
||||
INSERT INTO test9 (time, series_id, value) SELECT '2020-01-01 02:00:00'::TIMESTAMPTZ, 1, 1;
|
||||
-- should be 2 chunks again
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
hypertable_name | range_start | range_end
|
||||
-----------------+------------------------------+------------------------------
|
||||
test9 | Wed Jan 01 00:00:00 2020 PST | Wed Jan 01 02:00:00 2020 PST
|
||||
test9 | Wed Jan 01 02:00:00 2020 PST | Wed Jan 01 03:00:00 2020 PST
|
||||
(2 rows)
|
||||
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = '');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
NOTICE: chunk "_hyper_17_320_chunk" is already compressed
|
||||
compress_chunk
|
||||
-------------------------------------------
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
_timescaledb_internal._hyper_17_323_chunk
|
||||
(2 rows)
|
||||
|
||||
-- should not be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
hypertable_name | range_start | range_end
|
||||
-----------------+------------------------------+------------------------------
|
||||
test9 | Wed Jan 01 00:00:00 2020 PST | Wed Jan 01 02:00:00 2020 PST
|
||||
test9 | Wed Jan 01 02:00:00 2020 PST | Wed Jan 01 03:00:00 2020 PST
|
||||
(2 rows)
|
||||
|
||||
ROLLBACK;
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = 'series_id', timescaledb.compress_orderby = 'time DESC');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
NOTICE: chunk "_hyper_17_320_chunk" is already compressed
|
||||
compress_chunk
|
||||
-------------------------------------------
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
_timescaledb_internal._hyper_17_323_chunk
|
||||
(2 rows)
|
||||
|
||||
-- should not be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
hypertable_name | range_start | range_end
|
||||
-----------------+------------------------------+------------------------------
|
||||
test9 | Wed Jan 01 00:00:00 2020 PST | Wed Jan 01 02:00:00 2020 PST
|
||||
test9 | Wed Jan 01 02:00:00 2020 PST | Wed Jan 01 03:00:00 2020 PST
|
||||
(2 rows)
|
||||
|
||||
ROLLBACK;
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = 'series_id', timescaledb.compress_orderby = 'time NULLS FIRST');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
NOTICE: chunk "_hyper_17_320_chunk" is already compressed
|
||||
compress_chunk
|
||||
-------------------------------------------
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
_timescaledb_internal._hyper_17_323_chunk
|
||||
(2 rows)
|
||||
|
||||
-- should not be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
hypertable_name | range_start | range_end
|
||||
-----------------+------------------------------+------------------------------
|
||||
test9 | Wed Jan 01 00:00:00 2020 PST | Wed Jan 01 02:00:00 2020 PST
|
||||
test9 | Wed Jan 01 02:00:00 2020 PST | Wed Jan 01 03:00:00 2020 PST
|
||||
(2 rows)
|
||||
|
||||
ROLLBACK;
|
||||
-- reset back to original settings
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = 'series_id', timescaledb.compress_orderby = 'time');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
NOTICE: chunk "_hyper_17_320_chunk" is already compressed
|
||||
compress_chunk
|
||||
-------------------------------------------
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
_timescaledb_internal._hyper_17_320_chunk
|
||||
(2 rows)
|
||||
|
||||
-- should be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
hypertable_name | range_start | range_end
|
||||
-----------------+------------------------------+------------------------------
|
||||
test9 | Wed Jan 01 00:00:00 2020 PST | Wed Jan 01 03:00:00 2020 PST
|
||||
(1 row)
|
||||
|
||||
ROLLBACK;
|
||||
|
@ -233,3 +233,57 @@ SET enable_seqscan TO OFF;
|
||||
SET enable_bitmapscan TO ON;
|
||||
|
||||
SELECT count(*) FROM test8 WHERE series_id = 1;
|
||||
|
||||
-- Verify rollup is prevented when compression settings differ
|
||||
CREATE TABLE test9(time TIMESTAMPTZ NOT NULL, value DOUBLE PRECISION NOT NULL, series_id BIGINT NOT NULL);
|
||||
SELECT create_hypertable('test9', 'time', chunk_time_interval => INTERVAL '1 h');
|
||||
|
||||
ALTER TABLE test9 set (timescaledb.compress,
|
||||
timescaledb.compress_segmentby = 'series_id',
|
||||
timescaledb.compress_orderby = 'time',
|
||||
timescaledb.compress_chunk_time_interval = '1 day');
|
||||
|
||||
-- create chunk and compress
|
||||
INSERT INTO test9 (time, series_id, value) SELECT '2020-01-01 00:00:00'::TIMESTAMPTZ, 1, 1;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
INSERT INTO test9 (time, series_id, value) SELECT '2020-01-01 01:00:00'::TIMESTAMPTZ, 1, 1;
|
||||
|
||||
-- should be 2 chunk before rollup
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
-- should be 1 chunk because of rollup
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
|
||||
INSERT INTO test9 (time, series_id, value) SELECT '2020-01-01 02:00:00'::TIMESTAMPTZ, 1, 1;
|
||||
-- should be 2 chunks again
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = '');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
-- should not be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
ROLLBACK;
|
||||
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = 'series_id', timescaledb.compress_orderby = 'time DESC');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
-- should not be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
ROLLBACK;
|
||||
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = 'series_id', timescaledb.compress_orderby = 'time NULLS FIRST');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
-- should not be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
ROLLBACK;
|
||||
|
||||
-- reset back to original settings
|
||||
ALTER TABLE test9 SET (timescaledb.compress_segmentby = 'series_id', timescaledb.compress_orderby = 'time');
|
||||
BEGIN;
|
||||
SELECT compress_chunk(show_chunks('test9'), true);
|
||||
-- should be rolled up
|
||||
SELECT hypertable_name, range_start, range_end FROM timescaledb_information.chunks WHERE hypertable_name = 'test9' ORDER BY 2;
|
||||
ROLLBACK;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user