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