Skip to content

Commit

Permalink
Release 2.3.0
Browse files Browse the repository at this point in the history
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**
* timescale#3116 Add distributed hypertable compression policies
* timescale#3162 Use COPY when executing distributed INSERTs
* timescale#3199 Add GENERATED column support on distributed hypertables
* timescale#3210 Add trigger support on distributed hypertables
* timescale#3230 Support for inserts into compressed chunks

**Bugfixes**
* timescale#3213 Propagate grants to compressed hypertables
* timescale#3229 Use correct lock mode when updating chunk
* timescale#3243 Fix assertion failure in decompress_chunk_plan_create
* timescale#3250 Fix constraint triggers on hypertables
* timescale#3251 Fix segmentation fault due to incorrect call to chunk_scan_internal
* timescale#3252 Fix blocking triggers with transition tables

**Thanks**
* @yyjdelete for reporting a crash with decompress_chunk and identifying the bug in the code
  • Loading branch information
erimatnor committed May 25, 2021
1 parent fe872cb commit cc41bd4
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 135 deletions.
25 changes: 22 additions & 3 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions sql/CMakeLists.txt
Expand Up @@ -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}")
Expand Down
131 changes: 131 additions & 0 deletions 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;
131 changes: 0 additions & 131 deletions 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 ;
2 changes: 1 addition & 1 deletion version.config
@@ -1,2 +1,2 @@
version = 2.3.0-dev
version = 2.3.0
update_from_version = 2.2.1

0 comments on commit cc41bd4

Please sign in to comment.