mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-14 17:43:34 +08:00
To increase schema security we do not want to mix our own internal objects with user objects. Since chunks are created in the _timescaledb_internal schema our internal functions should live in a different dedicated schema. This patch make the necessary adjustments for the following functions: - chunk_constraint_add_table_constraint(_timescaledb_catalog.chunk_constraint) - chunk_drop_replica(regclass,name) - chunk_index_clone(oid) - chunk_index_replace(oid,oid) - create_chunk_replica_table(regclass,name) - drop_stale_chunks(name,integer[]) - health() - hypertable_constraint_add_table_fk_constraint(name,name,name,integer) - process_ddl_event() - wait_subscription_sync(name,name,integer,numeric)
120 lines
5.1 KiB
PL/PgSQL
120 lines
5.1 KiB
PL/PgSQL
-- This file and its contents are licensed under the Apache License 2.0.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-APACHE for a copy of the license.
|
|
|
|
-- chunk - the OID of the chunk to be CLUSTERed
|
|
-- index - the OID of the index to be CLUSTERed on, or NULL to use the index
|
|
-- last used
|
|
CREATE OR REPLACE FUNCTION @extschema@.reorder_chunk(
|
|
chunk REGCLASS,
|
|
index REGCLASS=NULL,
|
|
verbose BOOLEAN=FALSE
|
|
) RETURNS VOID AS '@MODULE_PATHNAME@', 'ts_reorder_chunk' LANGUAGE C VOLATILE;
|
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.move_chunk(
|
|
chunk REGCLASS,
|
|
destination_tablespace Name,
|
|
index_destination_tablespace Name=NULL,
|
|
reorder_index REGCLASS=NULL,
|
|
verbose BOOLEAN=FALSE
|
|
) RETURNS VOID AS '@MODULE_PATHNAME@', 'ts_move_chunk' LANGUAGE C VOLATILE;
|
|
|
|
CREATE OR REPLACE FUNCTION _timescaledb_functions.create_compressed_chunk(
|
|
chunk REGCLASS,
|
|
chunk_table REGCLASS,
|
|
uncompressed_heap_size BIGINT,
|
|
uncompressed_toast_size BIGINT,
|
|
uncompressed_index_size BIGINT,
|
|
compressed_heap_size BIGINT,
|
|
compressed_toast_size BIGINT,
|
|
compressed_index_size BIGINT,
|
|
numrows_pre_compression BIGINT,
|
|
numrows_post_compression BIGINT
|
|
) RETURNS REGCLASS AS '@MODULE_PATHNAME@', 'ts_create_compressed_chunk' LANGUAGE C STRICT VOLATILE;
|
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.compress_chunk(
|
|
uncompressed_chunk REGCLASS,
|
|
if_not_compressed BOOLEAN = false
|
|
) RETURNS REGCLASS AS '@MODULE_PATHNAME@', 'ts_compress_chunk' LANGUAGE C STRICT VOLATILE;
|
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.decompress_chunk(
|
|
uncompressed_chunk REGCLASS,
|
|
if_compressed BOOLEAN = false
|
|
) RETURNS REGCLASS AS '@MODULE_PATHNAME@', 'ts_decompress_chunk' LANGUAGE C STRICT VOLATILE;
|
|
|
|
CREATE OR REPLACE FUNCTION _timescaledb_functions.recompress_chunk_segmentwise(
|
|
uncompressed_chunk REGCLASS,
|
|
if_compressed BOOLEAN = false
|
|
) RETURNS REGCLASS AS '@MODULE_PATHNAME@', 'ts_recompress_chunk_segmentwise' LANGUAGE C STRICT VOLATILE;
|
|
|
|
-- find the index on the compressed chunk that can be used to recompress efficiently
|
|
-- this index must contain all the segmentby columns and the meta_sequence_number column last
|
|
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_compressed_chunk_index_for_recompression(
|
|
uncompressed_chunk REGCLASS
|
|
) RETURNS REGCLASS AS '@MODULE_PATHNAME@', 'ts_get_compressed_chunk_index_for_recompression' LANGUAGE C STRICT VOLATILE;
|
|
-- Recompress a chunk
|
|
--
|
|
-- Will give an error if the chunk was not already compressed. In this
|
|
-- case, the user should use compress_chunk instead. Note that this
|
|
-- function cannot be executed in an explicit transaction since it
|
|
-- contains transaction control commands.
|
|
--
|
|
-- Parameters:
|
|
-- chunk: Chunk to recompress.
|
|
-- if_not_compressed: Print notice instead of error if chunk is already compressed.
|
|
CREATE OR REPLACE PROCEDURE @extschema@.recompress_chunk(chunk REGCLASS,
|
|
if_not_compressed BOOLEAN = false)
|
|
AS $$
|
|
DECLARE
|
|
status INT;
|
|
chunk_name TEXT[];
|
|
compressed_chunk_index REGCLASS;
|
|
BEGIN
|
|
|
|
-- procedures with SET clause cannot execute transaction
|
|
-- control so we adjust search_path in procedure body
|
|
SET LOCAL search_path TO pg_catalog, pg_temp;
|
|
|
|
status := _timescaledb_functions.chunk_status(chunk);
|
|
|
|
-- Chunk names are in the internal catalog, but we only care about
|
|
-- the chunk name here.
|
|
-- status bits:
|
|
-- 1: compressed
|
|
-- 2: compressed unordered
|
|
-- 4: frozen
|
|
-- 8: compressed partial
|
|
|
|
chunk_name := parse_ident(chunk::text);
|
|
CASE
|
|
WHEN status = 0 THEN
|
|
RAISE EXCEPTION 'call compress_chunk instead of recompress_chunk';
|
|
WHEN status = 1 THEN
|
|
IF if_not_compressed THEN
|
|
RAISE NOTICE 'nothing to recompress in chunk "%"', chunk_name[array_upper(chunk_name,1)];
|
|
RETURN;
|
|
ELSE
|
|
RAISE EXCEPTION 'nothing to recompress in chunk "%"', chunk_name[array_upper(chunk_name,1)];
|
|
END IF;
|
|
WHEN status = 3 OR status = 9 OR status = 11 THEN
|
|
-- first check if there's an index. Might have to use a heuristic to determine if index usage would be efficient,
|
|
-- or if we'd better fall back to decompressing & recompressing entire chunk
|
|
SELECT _timescaledb_functions.get_compressed_chunk_index_for_recompression(chunk) INTO STRICT compressed_chunk_index;
|
|
IF compressed_chunk_index IS NOT NULL THEN
|
|
PERFORM _timescaledb_functions.recompress_chunk_segmentwise(chunk);
|
|
ELSE
|
|
PERFORM @extschema@.decompress_chunk(chunk);
|
|
COMMIT;
|
|
-- SET LOCAL is only active until end of transaction.
|
|
-- While we could use SET at the start of the function we do not
|
|
-- want to bleed out search_path to caller, so we do SET LOCAL
|
|
-- again after COMMIT
|
|
SET LOCAL search_path TO pg_catalog, pg_temp;
|
|
PERFORM @extschema@.compress_chunk(chunk, if_not_compressed);
|
|
END IF;
|
|
ELSE
|
|
RAISE EXCEPTION 'unexpected chunk status % in chunk "%"', status, chunk_name[array_upper(chunk_name,1)];
|
|
END CASE;
|
|
END
|
|
$$ LANGUAGE plpgsql;
|