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.
|
* LICENSE-APACHE for a copy of the license.
|
||||||
*/
|
*/
|
||||||
#include <postgres.h>
|
#include <postgres.h>
|
||||||
|
#include <catalog/pg_collation.h>
|
||||||
#include <catalog/pg_type.h>
|
#include <catalog/pg_type.h>
|
||||||
|
#include <fmgr.h>
|
||||||
#include <utils/array.h>
|
#include <utils/array.h>
|
||||||
#include <utils/builtins.h>
|
#include <utils/builtins.h>
|
||||||
|
#include <utils/fmgroids.h>
|
||||||
|
|
||||||
|
#include <compat/compat.h>
|
||||||
#include <debug_assert.h>
|
#include <debug_assert.h>
|
||||||
#include "array_utils.h"
|
#include "array_utils.h"
|
||||||
|
|
||||||
@ -29,6 +33,26 @@ ts_array_length(ArrayType *arr)
|
|||||||
return ARR_DIMS(arr)[0];
|
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
|
extern TSDLLEXPORT bool
|
||||||
ts_array_is_member(ArrayType *arr, const char *name)
|
ts_array_is_member(ArrayType *arr, const char *name)
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
extern TSDLLEXPORT int ts_array_length(ArrayType *arr);
|
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 bool ts_array_is_member(ArrayType *arr, const char *name);
|
||||||
extern TSDLLEXPORT int ts_array_position(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,
|
static HeapTuple compression_settings_formdata_make_tuple(const FormData_compression_settings *fd,
|
||||||
TupleDesc desc);
|
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 *
|
CompressionSettings *
|
||||||
ts_compression_settings_materialize(Oid ht_relid, Oid dst_relid)
|
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_get(Oid relid);
|
||||||
TSDLLEXPORT CompressionSettings *ts_compression_settings_materialize(Oid ht_relid, Oid dst_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_delete(Oid relid);
|
||||||
|
TSDLLEXPORT bool ts_compression_settings_equal(const CompressionSettings *left,
|
||||||
|
const CompressionSettings *right);
|
||||||
|
|
||||||
TSDLLEXPORT int ts_compression_settings_update(CompressionSettings *settings);
|
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)
|
compressed_chunk_interval + current_chunk_interval > max_chunk_interval)
|
||||||
return NULL;
|
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;
|
return previous_chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,3 +659,132 @@ SELECT count(*) FROM test8 WHERE series_id = 1;
|
|||||||
481
|
481
|
||||||
(1 row)
|
(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;
|
SET enable_bitmapscan TO ON;
|
||||||
|
|
||||||
SELECT count(*) FROM test8 WHERE series_id = 1;
|
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