From cc41bd453338ada9315974ed56aee25291ac5bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Nordstr=C3=B6m?= Date: Fri, 21 May 2021 16:46:01 +0200 Subject: [PATCH] Release 2.3.0 This release adds major new features since the 2.2.1 release. We deem it moderate priority for upgrading. This release adds support for inserting data into compressed chunks and improves performance when inserting data into distributed hypertables. Distributed hypertables now also support triggers and compression policies. The bug fixes in this release address issues related to the handling of privileges on compressed hypertables, locking, and triggers with transition tables. **Features** * #3116 Add distributed hypertable compression policies * #3162 Use COPY when executing distributed INSERTs * #3199 Add GENERATED column support on distributed hypertables * #3210 Add trigger support on distributed hypertables * #3230 Support for inserts into compressed chunks **Bugfixes** * #3213 Propagate grants to compressed hypertables * #3229 Use correct lock mode when updating chunk * #3243 Fix assertion failure in decompress_chunk_plan_create * #3250 Fix constraint triggers on hypertables * #3251 Fix segmentation fault due to incorrect call to chunk_scan_internal * #3252 Fix blocking triggers with transition tables **Thanks** * @yyjdelete for reporting a crash with decompress_chunk and identifying the bug in the code --- CHANGELOG.md | 25 ++++++- sql/CMakeLists.txt | 1 + sql/updates/2.2.1--2.3.0.sql | 131 +++++++++++++++++++++++++++++++++++ sql/updates/latest-dev.sql | 131 ----------------------------------- version.config | 2 +- 5 files changed, 155 insertions(+), 135 deletions(-) create mode 100644 sql/updates/2.2.1--2.3.0.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 5949628fb8c..eb64e536af6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,31 @@ accidentally triggering the load of a previous DB version.** ## Unreleased +# 2.3.0 (2021-05-25) + +This release adds major new features since the 2.2.1 release. We deem +it moderate priority for upgrading. + +This release adds support for inserting data into compressed chunks +and improves performance when inserting data into distributed +hypertables. Distributed hypertables now also support triggers and +compression policies. + +The bug fixes in this release address issues related to the handling +of privileges on compressed hypertables, locking, and triggers with +transition tables. + **Features** -* #3230 Support inserts into compressed chunks +* #3116 Add distributed hypertable compression policies +* #3162 Use COPY when executing distributed INSERTs +* #3199 Add GENERATED column support on distributed hypertables +* #3210 Add trigger support on distributed hypertables +* #3230 Support for inserts into compressed chunks **Bugfixes** -* #3209 Propagate grants to compressed hypertables -* #3241 Fix assertion failure in decompress_chunk_plan_create +* #3213 Propagate grants to compressed hypertables +* #3229 Use correct lock mode when updating chunk +* #3243 Fix assertion failure in decompress_chunk_plan_create * #3250 Fix constraint triggers on hypertables * #3251 Fix segmentation fault due to incorrect call to chunk_scan_internal * #3252 Fix blocking triggers with transition tables diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index f06ec0e14dc..c6e0070592d 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -110,6 +110,7 @@ set(MOD_FILES updates/2.1.0--2.1.1.sql updates/2.1.1--2.2.0.sql updates/2.2.0--2.2.1.sql + updates/2.2.1--2.3.0.sql ) set(MODULE_PATHNAME "$libdir/timescaledb-${PROJECT_VERSION_MOD}") diff --git a/sql/updates/2.2.1--2.3.0.sql b/sql/updates/2.2.1--2.3.0.sql new file mode 100644 index 00000000000..2598b56484e --- /dev/null +++ b/sql/updates/2.2.1--2.3.0.sql @@ -0,0 +1,131 @@ +-- Recreate _timescaledb_catalog.chunk table -- +CREATE TABLE _timescaledb_catalog.chunk_tmp +AS SELECT * from _timescaledb_catalog.chunk; + +CREATE TABLE tmp_chunk_seq_value AS +SELECT last_value, is_called FROM _timescaledb_catalog.chunk_id_seq; + +--drop foreign keys on chunk table +ALTER TABLE _timescaledb_catalog.chunk_constraint DROP CONSTRAINT +chunk_constraint_chunk_id_fkey; +ALTER TABLE _timescaledb_catalog.chunk_index DROP CONSTRAINT +chunk_index_chunk_id_fkey; +ALTER TABLE _timescaledb_catalog.chunk_data_node DROP CONSTRAINT +chunk_data_node_chunk_id_fkey; +ALTER TABLE _timescaledb_internal.bgw_policy_chunk_stats DROP CONSTRAINT +bgw_policy_chunk_stats_chunk_id_fkey; +ALTER TABLE _timescaledb_catalog.compression_chunk_size DROP CONSTRAINT +compression_chunk_size_chunk_id_fkey; +ALTER TABLE _timescaledb_catalog.compression_chunk_size DROP CONSTRAINT +compression_chunk_size_compressed_chunk_id_fkey; + +--drop dependent views +DROP VIEW IF EXISTS timescaledb_information.hypertables; +DROP VIEW IF EXISTS timescaledb_information.chunks; +DROP VIEW IF EXISTS _timescaledb_internal.hypertable_chunk_local_size; +DROP VIEW IF EXISTS _timescaledb_internal.compressed_chunk_stats; + +ALTER EXTENSION timescaledb DROP TABLE _timescaledb_catalog.chunk; +ALTER EXTENSION timescaledb DROP SEQUENCE _timescaledb_catalog.chunk_id_seq; +DROP TABLE _timescaledb_catalog.chunk; + +CREATE SEQUENCE IF NOT EXISTS _timescaledb_catalog.chunk_id_seq MINVALUE 1; + +-- now create table without self referential foreign key +CREATE TABLE IF NOT EXISTS _timescaledb_catalog.chunk ( + id integer PRIMARY KEY DEFAULT nextval('_timescaledb_catalog.chunk_id_seq'), + hypertable_id int NOT NULL REFERENCES _timescaledb_catalog.hypertable (id), + schema_name name NOT NULL, + table_name name NOT NULL, + compressed_chunk_id integer , + dropped boolean NOT NULL DEFAULT FALSE, + status integer NOT NULL DEFAULT 0, + UNIQUE (schema_name, table_name) +); + +INSERT INTO _timescaledb_catalog.chunk +( id, hypertable_id, schema_name, table_name, + compressed_chunk_id, dropped, status) +SELECT id, hypertable_id, schema_name, table_name, + compressed_chunk_id, dropped, ( + CASE + WHEN compressed_chunk_id IS NULL THEN 0 + ELSE 1 + END + ) +FROM _timescaledb_catalog.chunk_tmp; + +--add indexes to the chunk table +CREATE INDEX IF NOT EXISTS chunk_hypertable_id_idx ON _timescaledb_catalog.chunk (hypertable_id); +CREATE INDEX IF NOT EXISTS chunk_compressed_chunk_id_idx ON _timescaledb_catalog.chunk (compressed_chunk_id); + +ALTER SEQUENCE _timescaledb_catalog.chunk_id_seq OWNED BY _timescaledb_catalog.chunk.id; +SELECT setval('_timescaledb_catalog.chunk_id_seq', last_value, is_called) FROM tmp_chunk_seq_value; + +-- add self referential foreign key +ALTER TABLE _timescaledb_catalog.chunk ADD CONSTRAINT chunk_compressed_chunk_id_fkey FOREIGN KEY ( compressed_chunk_id ) + REFERENCES _timescaledb_catalog.chunk( id ); +SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.chunk', ''); +SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.chunk_id_seq', ''); + +--add the foreign key constraints +ALTER TABLE _timescaledb_catalog.chunk_constraint ADD CONSTRAINT +chunk_constraint_chunk_id_fkey FOREIGN KEY (chunk_id) REFERENCES _timescaledb_catalog.chunk(id); +ALTER TABLE _timescaledb_catalog.chunk_index ADD CONSTRAINT +chunk_index_chunk_id_fkey FOREIGN KEY (chunk_id) +REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.chunk_data_node ADD CONSTRAINT +chunk_data_node_chunk_id_fkey FOREIGN KEY (chunk_id) REFERENCES _timescaledb_catalog.chunk(id); +ALTER TABLE _timescaledb_internal.bgw_policy_chunk_stats ADD CONSTRAINT +bgw_policy_chunk_stats_chunk_id_fkey FOREIGN KEY (chunk_id) +REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.compression_chunk_size ADD CONSTRAINT +compression_chunk_size_chunk_id_fkey FOREIGN KEY (chunk_id) +REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.compression_chunk_size ADD CONSTRAINT +compression_chunk_size_compressed_chunk_id_fkey FOREIGN KEY (compressed_chunk_id) +REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; + +--cleanup +DROP TABLE _timescaledb_catalog.chunk_tmp; +DROP TABLE tmp_chunk_seq_value; + +GRANT SELECT ON _timescaledb_catalog.chunk_id_seq TO PUBLIC; +GRANT SELECT ON _timescaledb_catalog.chunk TO PUBLIC; + +-- end recreate _timescaledb_catalog.chunk table -- + +-- First we update the permissions of the compressed hypertables to +-- match the associated hypertable. +WITH + hypertables AS ( + SELECT format('%I.%I', ht.schema_name, ht.table_name)::regclass AS hypertable_oid, + format('%I.%I', ct.schema_name, ct.table_name)::regclass AS compressed_hypertable_oid + FROM _timescaledb_catalog.hypertable ht + JOIN _timescaledb_catalog.hypertable ct ON ht.compressed_hypertable_id = ct.id + ) +UPDATE pg_class + SET relacl = (SELECT relacl FROM pg_class WHERE oid = hypertable_oid) + FROM hypertables + WHERE oid = compressed_hypertable_oid; + +-- Now we update the permissions of chunks of both compressed and +-- uncompressed hypertables to match the permissions of the associated +-- hypertable. +WITH + chunks AS ( + SELECT format('%I.%I', ht.schema_name, ht.table_name)::regclass AS hypertable_oid, + format('%I.%I', ch.schema_name, ch.table_name)::regclass AS chunk_oid + FROM _timescaledb_catalog.hypertable ht + JOIN _timescaledb_catalog.chunk ch ON ht.id = ch.hypertable_id + WHERE NOT ch.dropped + ) +UPDATE pg_class + SET relacl = (SELECT relacl FROM pg_class WHERE oid = hypertable_oid) + FROM chunks + WHERE oid = chunk_oid; + +DROP FUNCTION IF EXISTS _timescaledb_internal.chunk_dml_blocker CASCADE; + +-- drop the view as view definition changed +DROP VIEW IF EXISTS _timescaledb_internal.hypertable_chunk_local_size; diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index 5d2614a6905..e69de29bb2d 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -1,131 +0,0 @@ --- Recreate _timescaledb_catalog.chunk table -- -CREATE TABLE _timescaledb_catalog.chunk_tmp -AS SELECT * from _timescaledb_catalog.chunk; - -CREATE TABLE tmp_chunk_seq_value AS -SELECT last_value, is_called FROM _timescaledb_catalog.chunk_id_seq; - ---drop foreign keys on chunk table -ALTER TABLE _timescaledb_catalog.chunk_constraint DROP CONSTRAINT -chunk_constraint_chunk_id_fkey; -ALTER TABLE _timescaledb_catalog.chunk_index DROP CONSTRAINT -chunk_index_chunk_id_fkey; -ALTER TABLE _timescaledb_catalog.chunk_data_node DROP CONSTRAINT -chunk_data_node_chunk_id_fkey; -ALTER TABLE _timescaledb_internal.bgw_policy_chunk_stats DROP CONSTRAINT -bgw_policy_chunk_stats_chunk_id_fkey; -ALTER TABLE _timescaledb_catalog.compression_chunk_size DROP CONSTRAINT -compression_chunk_size_chunk_id_fkey; -ALTER TABLE _timescaledb_catalog.compression_chunk_size DROP CONSTRAINT -compression_chunk_size_compressed_chunk_id_fkey; - ---drop dependent views -DROP VIEW IF EXISTS timescaledb_information.hypertables; -DROP VIEW IF EXISTS timescaledb_information.chunks; -DROP VIEW IF EXISTS _timescaledb_internal.hypertable_chunk_local_size; -DROP VIEW IF EXISTS _timescaledb_internal.compressed_chunk_stats; - -ALTER EXTENSION timescaledb DROP TABLE _timescaledb_catalog.chunk; -ALTER EXTENSION timescaledb DROP SEQUENCE _timescaledb_catalog.chunk_id_seq; -DROP TABLE _timescaledb_catalog.chunk; - -CREATE SEQUENCE IF NOT EXISTS _timescaledb_catalog.chunk_id_seq MINVALUE 1; - --- now create table without self referential foreign key -CREATE TABLE IF NOT EXISTS _timescaledb_catalog.chunk ( - id integer PRIMARY KEY DEFAULT nextval('_timescaledb_catalog.chunk_id_seq'), - hypertable_id int NOT NULL REFERENCES _timescaledb_catalog.hypertable (id), - schema_name name NOT NULL, - table_name name NOT NULL, - compressed_chunk_id integer , - dropped boolean NOT NULL DEFAULT FALSE, - status integer NOT NULL DEFAULT 0, - UNIQUE (schema_name, table_name) -); - -INSERT INTO _timescaledb_catalog.chunk -( id, hypertable_id, schema_name, table_name, - compressed_chunk_id, dropped, status) -SELECT id, hypertable_id, schema_name, table_name, - compressed_chunk_id, dropped, ( - CASE - WHEN compressed_chunk_id IS NULL THEN 0 - ELSE 1 - END - ) -FROM _timescaledb_catalog.chunk_tmp; - ---add indexes to the chunk table -CREATE INDEX IF NOT EXISTS chunk_hypertable_id_idx ON _timescaledb_catalog.chunk (hypertable_id); -CREATE INDEX IF NOT EXISTS chunk_compressed_chunk_id_idx ON _timescaledb_catalog.chunk (compressed_chunk_id); - -ALTER SEQUENCE _timescaledb_catalog.chunk_id_seq OWNED BY _timescaledb_catalog.chunk.id; -SELECT setval('_timescaledb_catalog.chunk_id_seq', last_value, is_called) FROM tmp_chunk_seq_value; - --- add self referential foreign key -ALTER TABLE _timescaledb_catalog.chunk ADD CONSTRAINT chunk_compressed_chunk_id_fkey FOREIGN KEY ( compressed_chunk_id ) - REFERENCES _timescaledb_catalog.chunk( id ); -SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.chunk', ''); -SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.chunk_id_seq', ''); - ---add the foreign key constraints -ALTER TABLE _timescaledb_catalog.chunk_constraint ADD CONSTRAINT -chunk_constraint_chunk_id_fkey FOREIGN KEY (chunk_id) REFERENCES _timescaledb_catalog.chunk(id); -ALTER TABLE _timescaledb_catalog.chunk_index ADD CONSTRAINT -chunk_index_chunk_id_fkey FOREIGN KEY (chunk_id) -REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; -ALTER TABLE _timescaledb_catalog.chunk_data_node ADD CONSTRAINT -chunk_data_node_chunk_id_fkey FOREIGN KEY (chunk_id) REFERENCES _timescaledb_catalog.chunk(id); -ALTER TABLE _timescaledb_internal.bgw_policy_chunk_stats ADD CONSTRAINT -bgw_policy_chunk_stats_chunk_id_fkey FOREIGN KEY (chunk_id) -REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; -ALTER TABLE _timescaledb_catalog.compression_chunk_size ADD CONSTRAINT -compression_chunk_size_chunk_id_fkey FOREIGN KEY (chunk_id) -REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; -ALTER TABLE _timescaledb_catalog.compression_chunk_size ADD CONSTRAINT -compression_chunk_size_compressed_chunk_id_fkey FOREIGN KEY (compressed_chunk_id) -REFERENCES _timescaledb_catalog.chunk(id) ON DELETE CASCADE; - ---cleanup -DROP TABLE _timescaledb_catalog.chunk_tmp; -DROP TABLE tmp_chunk_seq_value; - -GRANT SELECT ON _timescaledb_catalog.chunk_id_seq TO PUBLIC; -GRANT SELECT ON _timescaledb_catalog.chunk TO PUBLIC; - --- end recreate _timescaledb_catalog.chunk table -- - --- First we update the permissions of the compressed hypertables to --- match the associated hypertable. -WITH - hypertables AS ( - SELECT format('%I.%I', ht.schema_name, ht.table_name)::regclass AS hypertable_oid, - format('%I.%I', ct.schema_name, ct.table_name)::regclass AS compressed_hypertable_oid - FROM _timescaledb_catalog.hypertable ht - JOIN _timescaledb_catalog.hypertable ct ON ht.compressed_hypertable_id = ct.id - ) -UPDATE pg_class - SET relacl = (SELECT relacl FROM pg_class WHERE oid = hypertable_oid) - FROM hypertables - WHERE oid = compressed_hypertable_oid; - --- Now we update the permissions of chunks of both compressed and --- uncompressed hypertables to match the permissions of the associated --- hypertable. -WITH - chunks AS ( - SELECT format('%I.%I', ht.schema_name, ht.table_name)::regclass AS hypertable_oid, - format('%I.%I', ch.schema_name, ch.table_name)::regclass AS chunk_oid - FROM _timescaledb_catalog.hypertable ht - JOIN _timescaledb_catalog.chunk ch ON ht.id = ch.hypertable_id - WHERE NOT ch.dropped - ) -UPDATE pg_class - SET relacl = (SELECT relacl FROM pg_class WHERE oid = hypertable_oid) - FROM chunks - WHERE oid = chunk_oid; - -DROP FUNCTION IF EXISTS _timescaledb_internal.chunk_dml_blocker CASCADE; - --- drop the view as view definition changed -DROP VIEW IF EXISTS _timescaledb_internal.hypertable_chunk_local_size ; diff --git a/version.config b/version.config index 8a6273311d1..2fd22e3ab42 100644 --- a/version.config +++ b/version.config @@ -1,2 +1,2 @@ -version = 2.3.0-dev +version = 2.3.0 update_from_version = 2.2.1