From 33bbdccdcd7ad805c3463ba6426dea0510497ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabr=C3=ADzio=20de=20Royes=20Mello?= Date: Mon, 7 Mar 2022 11:12:46 -0300 Subject: [PATCH] Refactor function `hypertable_local_size` Reorganize the code and fix minor bug that was not computing the size of FSM, VM and INIT forks of the parent hypertable. Fixed the bug by exposing the `ts_relation_size` function to the SQL level to encapsulate the logic to compute `heap`, `indexes` and `toast` sizes. --- sql/size_utils.sql | 190 +++++++++++++++++---------- sql/updates/latest-dev.sql | 5 + sql/updates/reverse-dev.sql | 2 + src/telemetry/stats.c | 3 +- src/utils.c | 49 ++++++- src/utils.h | 3 +- test/expected/relocate_extension.out | 2 +- test/expected/size_utils.out | 39 +++++- test/sql/size_utils.sql | 8 +- tsl/src/compression/compress_utils.c | 4 +- tsl/test/expected/compression.out | 2 +- tsl/test/expected/dist_util.out | 82 ++++++++++++ tsl/test/sql/dist_util.sql | 14 ++ 13 files changed, 320 insertions(+), 83 deletions(-) diff --git a/sql/size_utils.sql b/sql/size_utils.sql index a9ff9db0a..fa47ff693 100644 --- a/sql/size_utils.sql +++ b/sql/size_utils.sql @@ -5,55 +5,65 @@ -- This file contains utility functions to get the relation size -- of hypertables, chunks, and indexes on hypertables. -CREATE OR REPLACE VIEW _timescaledb_internal.hypertable_chunk_local_size AS -SELECT *, - compressed_total_size - COALESCE(compressed_index_size, 0) - COALESCE(compressed_toast_size, 0) as compressed_heap_size +CREATE OR REPLACE FUNCTION _timescaledb_internal.relation_size(relation REGCLASS) +RETURNS TABLE (total_size BIGINT, heap_size BIGINT, index_size BIGINT, toast_size BIGINT) +AS '@MODULE_PATHNAME@', 'ts_relation_size' LANGUAGE C VOLATILE; + +CREATE OR REPLACE VIEW _timescaledb_internal.hypertable_chunk_local_size AS +WITH chunks AS ( + SELECT + h.schema_name AS hypertable_schema, + h.table_name AS hypertable_name, + h.id AS hypertable_id, + c.id AS chunk_id, + c.schema_name AS chunk_schema, + c.table_name AS chunk_name, + format('%I.%I', c.schema_name, c.table_name)::regclass AS relid, + CASE WHEN comp.schema_name IS NOT NULL AND comp.table_name IS NOT NULL THEN + format('%I.%I', comp.schema_name, comp.table_name)::regclass + ELSE + NULL::regclass + END AS relidcomp, + c.compressed_chunk_id + FROM + _timescaledb_catalog.hypertable h + JOIN _timescaledb_catalog.chunk c ON h.id = c.hypertable_id + AND c.dropped IS FALSE + LEFT JOIN _timescaledb_catalog.chunk comp ON comp.id = c.compressed_chunk_id +), +sizes AS ( + SELECT + ch.hypertable_schema, + ch.hypertable_name, + ch.hypertable_id, + ch.chunk_id, + ch.chunk_schema, + ch.chunk_name, + _timescaledb_internal.relation_size(ch.relid) AS relsize, + _timescaledb_internal.relation_size(ch.relidcomp) AS relcompsize + FROM + chunks ch +) +SELECT + hypertable_schema, + hypertable_name, + hypertable_id, + chunk_id, + chunk_schema, + chunk_name, + COALESCE((relsize).total_size, 0) AS total_bytes, + COALESCE((relsize).heap_size, 0) AS heap_bytes, + COALESCE((relsize).index_size, 0) AS index_bytes, + COALESCE((relsize).toast_size, 0) AS toast_bytes, + COALESCE((relcompsize).total_size, 0) AS compressed_total_size, + COALESCE((relcompsize).heap_size, 0) AS compressed_heap_size, + COALESCE((relcompsize).index_size, 0) AS compressed_index_size, + COALESCE((relcompsize).toast_size, 0) AS compressed_toast_size FROM -( SELECT - h.schema_name AS hypertable_schema, - h.table_name AS hypertable_name, - h.id as hypertable_id, - c.id as chunk_id, - c.schema_name as chunk_schema, - c.table_name as chunk_name, - pg_total_relation_size(format('%I.%I', c.schema_name, c.table_name))::bigint AS total_bytes, - pg_indexes_size(format('%I.%I', c.schema_name, c.table_name))::bigint AS index_bytes, - pg_total_relation_size(pgc.reltoastrelid)::bigint AS toast_bytes, - CASE WHEN map.table_name IS NOT NULL - THEN pg_total_relation_size(format('%I.%I', map.schema_name, map.table_name))::bigint - ELSE 0 - END AS compressed_total_size, - CASE WHEN map.table_name IS NOT NULL - THEN pg_indexes_size(format('%I.%I', map.schema_name, map.table_name))::bigint - ELSE 0 - END AS compressed_index_size, - CASE WHEN map.reltoastrelid IS NOT NULL - THEN pg_total_relation_size(map.reltoastrelid)::bigint - ELSE 0 - END AS compressed_toast_size -FROM - _timescaledb_catalog.hypertable h - INNER JOIN - _timescaledb_catalog.chunk c - ON h.id = c.hypertable_id - and c.dropped = false - INNER JOIN - pg_class pgc - ON pgc.relname = c.table_name - INNER JOIN - pg_namespace pns - ON pns.oid = pgc.relnamespace - AND pns.nspname = c.schema_name - LEFT OUTER JOIN - ( SELECT comp.id, comp.schema_name, comp.table_name, reltoastrelid - FROM _timescaledb_catalog.chunk comp, pg_class, pg_namespace - WHERE comp.table_name = pg_class.relname - AND comp.schema_name = pg_namespace.nspname - AND pg_namespace.oid = pg_class.relnamespace ) map - ON map.id = c.compressed_chunk_id ) subq; + sizes; GRANT SELECT ON _timescaledb_internal.hypertable_chunk_local_size TO PUBLIC; - + CREATE OR REPLACE FUNCTION _timescaledb_internal.data_node_hypertable_info( node_name NAME, schema_name_in name, @@ -85,22 +95,64 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.hypertable_local_size( schema_name_in name, table_name_in name) RETURNS TABLE ( - table_bytes bigint, - index_bytes bigint, - toast_bytes bigint, - total_bytes bigint) + table_bytes BIGINT, + index_bytes BIGINT, + toast_bytes BIGINT, + total_bytes BIGINT) LANGUAGE SQL VOLATILE STRICT AS $BODY$ + /* get the main hypertable id and sizes */ + WITH _hypertable AS ( + SELECT + id, + _timescaledb_internal.relation_size(format('%I.%I', schema_name, table_name)::regclass) AS relsize + FROM + _timescaledb_catalog.hypertable + WHERE + schema_name = schema_name_in + AND table_name = table_name_in + ), + /* project the size of the parent hypertable */ + _hypertable_sizes AS ( + SELECT + id, + COALESCE((relsize).total_size, 0) AS total_bytes, + COALESCE((relsize).heap_size, 0) AS heap_bytes, + COALESCE((relsize).index_size, 0) AS index_bytes, + COALESCE((relsize).toast_size, 0) AS toast_bytes, + 0::BIGINT AS compressed_total_size, + 0::BIGINT AS compressed_index_size, + 0::BIGINT AS compressed_toast_size, + 0::BIGINT AS compressed_heap_size + FROM + _hypertable + ), + /* calculate the size of the hypertable chunks */ + _chunk_sizes AS ( + SELECT + chunk_id, + COALESCE(ch.total_bytes, 0) AS total_bytes, + COALESCE(ch.heap_bytes, 0) AS heap_bytes, + COALESCE(ch.index_bytes, 0) AS index_bytes, + COALESCE(ch.toast_bytes, 0) AS toast_bytes, + COALESCE(ch.compressed_total_size, 0) AS compressed_total_size, + COALESCE(ch.compressed_index_size, 0) AS compressed_index_size, + COALESCE(ch.compressed_toast_size, 0) AS compressed_toast_size, + COALESCE(ch.compressed_heap_size, 0) AS compressed_heap_size + FROM + _timescaledb_internal.hypertable_chunk_local_size ch + JOIN _hypertable_sizes ht ON ht.id = ch.hypertable_id + ) + /* calculate the SUM of the hypertable and chunk sizes */ SELECT - (COALESCE(sum(ch.total_bytes), 0) - COALESCE(sum(ch.index_bytes), 0) - COALESCE(sum(ch.toast_bytes), 0) + COALESCE(sum(ch.compressed_heap_size), 0))::bigint + pg_relation_size(format('%I.%I', schema_name_in, table_name_in)::regclass)::bigint AS heap_bytes, - (COALESCE(sum(ch.index_bytes), 0) + COALESCE(sum(ch.compressed_index_size), 0))::bigint + pg_indexes_size(format('%I.%I', schema_name_in, table_name_in)::regclass)::bigint AS index_bytes, - (COALESCE(sum(ch.toast_bytes), 0) + COALESCE(sum(ch.compressed_toast_size), 0))::bigint AS toast_bytes, - (COALESCE(sum(ch.total_bytes), 0) + COALESCE(sum(ch.compressed_total_size), 0))::bigint + pg_total_relation_size(format('%I.%I', schema_name_in, table_name_in)::regclass)::bigint AS total_bytes + (SUM(heap_bytes) + SUM(compressed_heap_size))::BIGINT AS heap_bytes, + (SUM(index_bytes) + SUM(compressed_index_size))::BIGINT AS index_bytes, + (SUM(toast_bytes) + SUM(compressed_toast_size))::BIGINT AS toast_bytes, + (SUM(total_bytes) + SUM(compressed_total_size))::BIGINT AS total_bytes FROM - _timescaledb_internal.hypertable_chunk_local_size ch - WHERE - hypertable_schema = schema_name_in - AND hypertable_name = table_name_in + (SELECT * FROM _hypertable_sizes + UNION ALL + SELECT * FROM _chunk_sizes) AS sizes; $BODY$ SET search_path TO pg_catalog; CREATE OR REPLACE FUNCTION _timescaledb_internal.hypertable_remote_size( @@ -190,7 +242,7 @@ $BODY$ SET search_path TO pg_catalog; --- returns total-bytes for a hypertable (includes table + index) CREATE OR REPLACE FUNCTION @extschema@.hypertable_size( hypertable REGCLASS) -RETURNS BIGINT +RETURNS BIGINT LANGUAGE SQL VOLATILE STRICT AS $BODY$ -- One row per data node is returned (in case of a distributed @@ -219,7 +271,7 @@ $BODY$ (ch.total_bytes - COALESCE( ch.index_bytes , 0 ) - COALESCE( ch.toast_bytes, 0 ) + COALESCE( ch.compressed_heap_size , 0 ))::bigint as heap_bytes, (COALESCE( ch.index_bytes, 0 ) + COALESCE( ch.compressed_index_size , 0) )::bigint as index_bytes, (COALESCE( ch.toast_bytes, 0 ) + COALESCE( ch.compressed_toast_size, 0 ))::bigint as toast_bytes, - (ch.total_bytes + COALESCE( ch.compressed_total_size, 0 ))::bigint as total_bytes + (ch.total_bytes + COALESCE( ch.compressed_total_size, 0 ))::bigint as total_bytes FROM _timescaledb_internal.hypertable_chunk_local_size ch WHERE @@ -274,7 +326,7 @@ $BODY$ SET search_path TO pg_catalog; -- Returns: -- chunk_schema - schema name for chunk -- chunk_name - chunk table name --- table_bytes - Disk space used by chunk table +-- table_bytes - Disk space used by chunk table -- index_bytes - Disk space used by indexes -- toast_bytes - Disk space of toast tables -- total_bytes - Disk space used in total @@ -310,12 +362,12 @@ BEGIN END IF; CASE WHEN is_distributed THEN - RETURN QUERY SELECT ch.chunk_schema, ch.chunk_name, ch.table_bytes, ch.index_bytes, - ch.toast_bytes, ch.total_bytes, ch.node_name + RETURN QUERY SELECT ch.chunk_schema, ch.chunk_name, ch.table_bytes, ch.index_bytes, + ch.toast_bytes, ch.total_bytes, ch.node_name FROM _timescaledb_internal.chunks_remote_size(schema_name, table_name) ch; ELSE - RETURN QUERY SELECT chl.chunk_schema, chl.chunk_name, chl.table_bytes, chl.index_bytes, - chl.toast_bytes, chl.total_bytes, NULL::NAME + RETURN QUERY SELECT chl.chunk_schema, chl.chunk_name, chl.table_bytes, chl.index_bytes, + chl.toast_bytes, chl.total_bytes, NULL::NAME FROM _timescaledb_internal.chunks_local_size(schema_name, table_name) chl; END CASE; END; @@ -569,7 +621,7 @@ CREATE OR REPLACE FUNCTION @extschema@.hypertable_compression_stats (hypertable node_name name) LANGUAGE SQL STABLE STRICT - AS + AS $BODY$ SELECT count(*)::bigint AS total_chunks, @@ -599,13 +651,13 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.indexes_local_size( index_name_in NAME ) RETURNS TABLE ( hypertable_id INTEGER, - total_bytes BIGINT ) + total_bytes BIGINT ) LANGUAGE SQL VOLATILE STRICT AS $BODY$ WITH chunk_index_size (num_bytes) AS ( SELECT COALESCE(sum(pg_relation_size(c.oid)), 0)::bigint - FROM + FROM pg_class c, pg_namespace n, _timescaledb_catalog.chunk ch, @@ -616,7 +668,7 @@ $BODY$ AND c.relname = ci.index_name AND ch.id = ci.chunk_id AND h.id = ci.hypertable_id - AND h.schema_name = schema_name_in + AND h.schema_name = schema_name_in AND ci.hypertable_index_name = index_name_in ) SELECT h.id, diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index e69de29bb..ad0e79c61 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -0,0 +1,5 @@ +CREATE FUNCTION _timescaledb_internal.relation_size(relation REGCLASS) +RETURNS TABLE (total_size BIGINT, heap_size BIGINT, index_size BIGINT, toast_size BIGINT) +AS '@MODULE_PATHNAME@', 'ts_relation_size' LANGUAGE C VOLATILE; + +DROP VIEW IF EXISTS _timescaledb_internal.hypertable_chunk_local_size; diff --git a/sql/updates/reverse-dev.sql b/sql/updates/reverse-dev.sql index e69de29bb..f82f91c00 100644 --- a/sql/updates/reverse-dev.sql +++ b/sql/updates/reverse-dev.sql @@ -0,0 +1,2 @@ +DROP VIEW _timescaledb_internal.hypertable_chunk_local_size; +DROP FUNCTION _timescaledb_internal.relation_size(relation REGCLASS); diff --git a/src/telemetry/stats.c b/src/telemetry/stats.c index 2e894248e..ce23e111f 100644 --- a/src/telemetry/stats.c +++ b/src/telemetry/stats.c @@ -204,7 +204,8 @@ add_storage(StorageStats *stats, Form_pg_class class) { RelationSize relsize; - relsize = ts_relation_size(class->oid); + relsize = ts_relation_size_impl(class->oid); + stats->relsize.total_size += relsize.total_size; stats->relsize.heap_size += relsize.heap_size; stats->relsize.toast_size += relsize.toast_size; stats->relsize.index_size += relsize.index_size; diff --git a/src/utils.c b/src/utils.c index 8443536ff..52dfeed91 100644 --- a/src/utils.c +++ b/src/utils.c @@ -904,19 +904,56 @@ ts_subtract_integer_from_now(PG_FUNCTION_ARGS) return Int64GetDatum(res); } -RelationSize -ts_relation_size(Oid relid) +TS_FUNCTION_INFO_V1(ts_relation_size); +Datum +ts_relation_size(PG_FUNCTION_ARGS) { - int64 tot_size; - RelationSize relsize; + Oid relid = PG_ARGISNULL(0) ? InvalidOid : PG_GETARG_OID(0); + RelationSize relsize = { 0 }; + TupleDesc tupdesc; + HeapTuple tuple; + Datum values[4] = { 0 }; + bool nulls[4] = { false }; + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + + if (!OidIsValid(relid)) + PG_RETURN_NULL(); + + relsize = ts_relation_size_impl(relid); + + tupdesc = BlessTupleDesc(tupdesc); + + values[0] = Int64GetDatum(relsize.total_size); + values[1] = Int64GetDatum(relsize.heap_size); + values[2] = Int64GetDatum(relsize.index_size); + values[3] = Int64GetDatum(relsize.toast_size); + + tuple = heap_form_tuple(tupdesc, values, nulls); + + return HeapTupleGetDatum(tuple); +} + +RelationSize +ts_relation_size_impl(Oid relid) +{ + RelationSize relsize = { 0 }; Datum reloid = ObjectIdGetDatum(relid); Relation rel; /* Open relation earlier to keep a lock during all function calls */ rel = try_relation_open(relid, AccessShareLock); + if (!rel) + return relsize; + /* Get to total relation size to be our calculation base */ - tot_size = DatumGetInt64(DirectFunctionCall1(pg_total_relation_size, reloid)); + relsize.total_size = DatumGetInt64(DirectFunctionCall1(pg_total_relation_size, reloid)); /* Get the indexes size of the relation (don't consider TOAST indexes) */ relsize.index_size = DatumGetInt64(DirectFunctionCall1(pg_indexes_size, reloid)); @@ -932,7 +969,7 @@ ts_relation_size(Oid relid) relation_close(rel, AccessShareLock); /* Calculate the HEAP size based on the total size and indexes plus toast */ - relsize.heap_size = tot_size - (relsize.index_size + relsize.toast_size); + relsize.heap_size = relsize.total_size - (relsize.index_size + relsize.toast_size); return relsize; } diff --git a/src/utils.h b/src/utils.h index f38f7fbf5..983835db3 100644 --- a/src/utils.h +++ b/src/utils.h @@ -186,12 +186,13 @@ TryRegisterCustomScanMethods(const CustomScanMethods *methods) typedef struct RelationSize { + int64 total_size; int64 heap_size; int64 toast_size; int64 index_size; } RelationSize; -extern TSDLLEXPORT RelationSize ts_relation_size(Oid relid); +extern TSDLLEXPORT RelationSize ts_relation_size_impl(Oid relid); extern TSDLLEXPORT const char *ts_get_node_name(Node *node); diff --git a/test/expected/relocate_extension.out b/test/expected/relocate_extension.out index efa735ac8..946098fe0 100644 --- a/test/expected/relocate_extension.out +++ b/test/expected/relocate_extension.out @@ -160,7 +160,7 @@ SELECT * FROM test_dt ORDER BY time; SELECT * FROM "testSchema0".hypertable_detailed_size('test_ts'); table_bytes | index_bytes | toast_bytes | total_bytes | node_name -------------+-------------+-------------+-------------+----------- - 16384 | 81920 | 16384 | 122880 | + 16384 | 81920 | 24576 | 122880 | (1 row) -- testing hypertable_detailed_size END diff --git a/test/expected/size_utils.out b/test/expected/size_utils.out index a41cbfdd9..624cca020 100644 --- a/test/expected/size_utils.out +++ b/test/expected/size_utils.out @@ -45,7 +45,7 @@ INSERT 0 1 SELECT * FROM hypertable_detailed_size('"public"."two_Partitions"'); table_bytes | index_bytes | toast_bytes | total_bytes | node_name -------------+-------------+-------------+-------------+----------- - 32768 | 475136 | 32768 | 548864 | + 32768 | 475136 | 40960 | 548864 | (1 row) SELECT * FROM hypertable_index_size('"public"."two_Partitions_device_id_timeCustom_idx"'); @@ -153,6 +153,7 @@ SELECT * FROM chunks_detailed_size('toast_test'); _timescaledb_internal | _hyper_4_9_chunk | 8192 | 16384 | 24576 | 49152 | (1 row) +-- -- Tests for approximate_row_count() -- -- Regular table @@ -495,6 +496,12 @@ SELECT * FROM hypertable_index_size(0); (1 row) +SELECT * FROM _timescaledb_internal.relation_size(0); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + | | | +(1 row) + SELECT * FROM hypertable_size(1); hypertable_size ----------------- @@ -527,6 +534,12 @@ SELECT * FROM hypertable_index_size(1); (1 row) +SELECT * FROM _timescaledb_internal.relation_size(1); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 0 | 0 | 0 | 0 +(1 row) + -- Test size functions with NULL input SELECT * FROM hypertable_size(NULL); hypertable_size @@ -560,6 +573,12 @@ SELECT * FROM hypertable_index_size(NULL); (1 row) +SELECT * FROM _timescaledb_internal.relation_size(NULL); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + | | | +(1 row) + -- Test size functions on regular table CREATE TABLE hypersize(time timestamptz, device int); CREATE INDEX hypersize_time_idx ON hypersize (time); @@ -572,6 +591,12 @@ SELECT pg_relation_size('hypersize'), pg_table_size('hypersize'), pg_indexes_siz 0 | 0 | 8192 | 8192 | 8192 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('hypersize'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + SELECT * FROM hypertable_size('hypersize'); hypertable_size ----------------- @@ -620,6 +645,12 @@ SELECT pg_relation_size('hypersize'), pg_table_size('hypersize'), pg_indexes_siz 0 | 0 | 8192 | 8192 | 8192 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('hypersize'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + SELECT * FROM hypertable_size('hypersize'); hypertable_size ----------------- @@ -669,6 +700,12 @@ ORDER BY ch; 8192 | 8192 | 16384 | 24576 (1 row) +SELECT * FROM show_chunks('hypersize') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON true; + ch | total_size | heap_size | index_size | toast_size +-----------------------------------------+------------+-----------+------------+------------ + _timescaledb_internal._hyper_6_11_chunk | 24576 | 8192 | 16384 | 0 +(1 row) + SELECT * FROM hypertable_size('hypersize'); hypertable_size ----------------- diff --git a/test/sql/size_utils.sql b/test/sql/size_utils.sql index f388bc403..eb14dbbd3 100644 --- a/test/sql/size_utils.sql +++ b/test/sql/size_utils.sql @@ -21,7 +21,6 @@ INSERT INTO timestamp_partitioned VALUES('2004-10-19 10:23:54', '10'); INSERT INTO timestamp_partitioned VALUES('2004-12-19 10:23:54', '30'); SELECT * FROM chunks_detailed_size('timestamp_partitioned') order by chunk_name; - CREATE TABLE timestamp_partitioned_2(time TIMESTAMP, value CHAR(9)); SELECT * FROM create_hypertable('timestamp_partitioned_2', 'time', 'value', 2); @@ -40,6 +39,7 @@ this must be over 2k. this must be over 2k. this must be over 2k. this must be o $$); SELECT * FROM chunks_detailed_size('toast_test'); +-- -- Tests for approximate_row_count() -- @@ -213,6 +213,7 @@ SELECT * FROM chunks_detailed_size(0) ORDER BY node_name; SELECT * FROM hypertable_compression_stats(0) ORDER BY node_name; SELECT * FROM chunk_compression_stats(0) ORDER BY node_name; SELECT * FROM hypertable_index_size(0); +SELECT * FROM _timescaledb_internal.relation_size(0); SELECT * FROM hypertable_size(1); SELECT * FROM hypertable_detailed_size(1) ORDER BY node_name; @@ -220,6 +221,7 @@ SELECT * FROM chunks_detailed_size(1) ORDER BY node_name; SELECT * FROM hypertable_compression_stats(1) ORDER BY node_name; SELECT * FROM chunk_compression_stats(1) ORDER BY node_name; SELECT * FROM hypertable_index_size(1); +SELECT * FROM _timescaledb_internal.relation_size(1); -- Test size functions with NULL input SELECT * FROM hypertable_size(NULL); @@ -228,6 +230,7 @@ SELECT * FROM chunks_detailed_size(NULL) ORDER BY node_name; SELECT * FROM hypertable_compression_stats(NULL) ORDER BY node_name; SELECT * FROM chunk_compression_stats(NULL) ORDER BY node_name; SELECT * FROM hypertable_index_size(NULL); +SELECT * FROM _timescaledb_internal.relation_size(NULL); -- Test size functions on regular table CREATE TABLE hypersize(time timestamptz, device int); @@ -236,6 +239,7 @@ CREATE INDEX hypersize_time_idx ON hypersize (time); \set VERBOSITY default \set SHOW_CONTEXT never SELECT pg_relation_size('hypersize'), pg_table_size('hypersize'), pg_indexes_size('hypersize'), pg_total_relation_size('hypersize'), pg_relation_size('hypersize_time_idx'); +SELECT * FROM _timescaledb_internal.relation_size('hypersize'); SELECT * FROM hypertable_size('hypersize'); SELECT * FROM hypertable_detailed_size('hypersize') ORDER BY node_name; SELECT * FROM chunks_detailed_size('hypersize') ORDER BY node_name; @@ -248,6 +252,7 @@ SELECT * FROM hypertable_index_size('hypersize_time_idx'); -- Test size functions on empty hypertable SELECT * FROM create_hypertable('hypersize', 'time'); SELECT pg_relation_size('hypersize'), pg_table_size('hypersize'), pg_indexes_size('hypersize'), pg_total_relation_size('hypersize'), pg_relation_size('hypersize_time_idx'); +SELECT * FROM _timescaledb_internal.relation_size('hypersize'); SELECT * FROM hypertable_size('hypersize'); SELECT * FROM hypertable_detailed_size('hypersize') ORDER BY node_name; SELECT * FROM chunks_detailed_size('hypersize') ORDER BY node_name; @@ -261,6 +266,7 @@ SELECT pg_relation_size('hypersize'), pg_table_size('hypersize'), pg_indexes_siz SELECT pg_relation_size(ch), pg_table_size(ch), pg_indexes_size(ch), pg_total_relation_size(ch) FROM show_chunks('hypersize') ch ORDER BY ch; +SELECT * FROM show_chunks('hypersize') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON true; SELECT * FROM hypertable_size('hypersize'); SELECT * FROM hypertable_detailed_size('hypersize') ORDER BY node_name; SELECT * FROM chunks_detailed_size('hypersize') ORDER BY node_name; diff --git a/tsl/src/compression/compress_utils.c b/tsl/src/compression/compress_utils.c index 79bf30683..4803e1504 100644 --- a/tsl/src/compression/compress_utils.c +++ b/tsl/src/compression/compress_utils.c @@ -246,7 +246,7 @@ compress_chunk_impl(Oid hypertable_relid, Oid chunk_relid) FormData_hypertable_compression *fd = (FormData_hypertable_compression *) lfirst(lc); colinfo_array[i++] = fd; } - before_size = ts_relation_size(cxt.srcht_chunk->table_id); + before_size = ts_relation_size_impl(cxt.srcht_chunk->table_id); cstat = compress_chunk(cxt.srcht_chunk->table_id, compress_ht_chunk->table_id, colinfo_array, @@ -268,7 +268,7 @@ compress_chunk_impl(Oid hypertable_relid, Oid chunk_relid) * directly on the hypertable or chunks. */ ts_chunk_drop_fks(cxt.srcht_chunk); - after_size = ts_relation_size(compress_ht_chunk->table_id); + after_size = ts_relation_size_impl(compress_ht_chunk->table_id); compression_chunk_size_catalog_insert(cxt.srcht_chunk->fd.id, &before_size, compress_ht_chunk->fd.id, diff --git a/tsl/test/expected/compression.out b/tsl/test/expected/compression.out index 74a55f87c..8278b4ab6 100644 --- a/tsl/test/expected/compression.out +++ b/tsl/test/expected/compression.out @@ -450,7 +450,7 @@ from hypertable_detailed_size('conditions'); -[ RECORD 1 ]--+------- pg_size_pretty | 16 kB pg_size_pretty | 56 kB -pg_size_pretty | 32 kB +pg_size_pretty | 40 kB pg_size_pretty | 112 kB select * from timescaledb_information.hypertables diff --git a/tsl/test/expected/dist_util.out b/tsl/test/expected/dist_util.out index f269489be..c1eefb8f7 100644 --- a/tsl/test/expected/dist_util.out +++ b/tsl/test/expected/dist_util.out @@ -256,6 +256,17 @@ FROM show_chunks('disttable') ch; ---------------+------------------+-----------------+------------------------ (0 rows) +SELECT * FROM _timescaledb_internal.relation_size('disttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 0 | 0 | 0 | 0 +(1 row) + +SELECT * FROM show_chunks('disttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; + ch | total_size | heap_size | index_size | toast_size +----+------------+-----------+------------+------------ +(0 rows) + SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); pg_table_size | pg_relation_size | pg_indexes_size | pg_total_relation_size ---------------+------------------+-----------------+------------------------ @@ -268,6 +279,17 @@ FROM show_chunks('nondisttable') ch; ---------------+------------------+-----------------+------------------------ (0 rows) +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 0 | 0 | 0 | 0 +(1 row) + +SELECT * FROM show_chunks('nondisttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; + ch | total_size | heap_size | index_size | toast_size +----+------------+-----------+------------+------------ +(0 rows) + SELECT * FROM hypertable_size('disttable'); hypertable_size ----------------- @@ -334,12 +356,24 @@ SELECT pg_table_size('disttable'), pg_relation_size('disttable'), pg_indexes_siz 0 | 0 | 8192 | 8192 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('disttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); pg_table_size | pg_relation_size | pg_indexes_size | pg_total_relation_size ---------------+------------------+-----------------+------------------------ 0 | 0 | 8192 | 8192 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + -- Note that the empty disttable is three times the size of the -- nondisttable since it has primary key indexes on two data nodes in -- addition to the access node. @@ -427,6 +461,18 @@ FROM show_chunks('disttable') ch; 0 | 0 | 0 | 0 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('disttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + +SELECT * FROM show_chunks('disttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; + ch | total_size | heap_size | index_size | toast_size +---------------------------------------------+------------+-----------+------------+------------ + _timescaledb_internal._dist_hyper_2_2_chunk | 0 | 0 | 0 | 0 +(1 row) + SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); pg_table_size | pg_relation_size | pg_indexes_size | pg_total_relation_size ---------------+------------------+-----------------+------------------------ @@ -440,6 +486,18 @@ FROM show_chunks('nondisttable') ch; 8192 | 8192 | 16384 | 24576 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + +SELECT * FROM show_chunks('nondisttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; + ch | total_size | heap_size | index_size | toast_size +----------------------------------------+------------+-----------+------------+------------ + _timescaledb_internal._hyper_1_1_chunk | 24576 | 8192 | 16384 | 0 +(1 row) + SELECT * FROM hypertable_size('disttable'); hypertable_size ----------------- @@ -484,6 +542,18 @@ FROM show_chunks('disttable') ch; 0 | 0 | 0 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('disttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + +SELECT * FROM show_chunks('disttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; + ch | total_size | heap_size | index_size | toast_size +---------------------------------------------+------------+-----------+------------+------------ + _timescaledb_internal._dist_hyper_2_2_chunk | 0 | 0 | 0 | 0 +(1 row) + SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); pg_table_size | pg_relation_size | pg_indexes_size | pg_total_relation_size ---------------+------------------+-----------------+------------------------ @@ -497,6 +567,18 @@ FROM show_chunks('nondisttable') ch; 0 | 0 | 8192 | 8192 (1 row) +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); + total_size | heap_size | index_size | toast_size +------------+-----------+------------+------------ + 8192 | 0 | 8192 | 0 +(1 row) + +SELECT * FROM show_chunks('nondisttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; + ch | total_size | heap_size | index_size | toast_size +----------------------------------------+------------+-----------+------------+------------ + _timescaledb_internal._hyper_1_1_chunk | 8192 | 0 | 8192 | 0 +(1 row) + SELECT * FROM hypertable_size('disttable'); hypertable_size ----------------- diff --git a/tsl/test/sql/dist_util.sql b/tsl/test/sql/dist_util.sql index 70963b7fb..c77a0877a 100644 --- a/tsl/test/sql/dist_util.sql +++ b/tsl/test/sql/dist_util.sql @@ -128,9 +128,13 @@ ORDER BY hypertable_schema, hypertable_name; SELECT pg_table_size('disttable'), pg_relation_size('disttable'), pg_indexes_size('disttable'), pg_total_relation_size('disttable'); SELECT pg_table_size(ch), pg_relation_size(ch), pg_indexes_size(ch), pg_total_relation_size(ch) FROM show_chunks('disttable') ch; +SELECT * FROM _timescaledb_internal.relation_size('disttable'); +SELECT * FROM show_chunks('disttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); SELECT pg_table_size(ch), pg_relation_size(ch), pg_indexes_size(ch), pg_total_relation_size(ch) FROM show_chunks('nondisttable') ch; +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); +SELECT * FROM show_chunks('nondisttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; SELECT * FROM hypertable_size('disttable'); SELECT * FROM hypertable_size('nondisttable'); @@ -149,7 +153,9 @@ ALTER TABLE nondisttable ADD CONSTRAINT nondisttable_pkey PRIMARY KEY (time); ALTER TABLE disttable ADD CONSTRAINT disttable_pkey PRIMARY KEY (time); SELECT pg_table_size('disttable'), pg_relation_size('disttable'), pg_indexes_size('disttable'), pg_total_relation_size('disttable'); +SELECT * FROM _timescaledb_internal.relation_size('disttable'); SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); -- Note that the empty disttable is three times the size of the -- nondisttable since it has primary key indexes on two data nodes in @@ -175,9 +181,13 @@ INSERT INTO disttable SELECT * FROM nondisttable; SELECT pg_table_size('disttable'), pg_relation_size('disttable'), pg_indexes_size('disttable'), pg_total_relation_size('disttable'); SELECT pg_table_size(ch), pg_relation_size(ch), pg_indexes_size(ch), pg_total_relation_size(ch) FROM show_chunks('disttable') ch; +SELECT * FROM _timescaledb_internal.relation_size('disttable'); +SELECT * FROM show_chunks('disttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); SELECT pg_table_size(ch), pg_relation_size(ch), pg_indexes_size(ch), pg_total_relation_size(ch) FROM show_chunks('nondisttable') ch; +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); +SELECT * FROM show_chunks('nondisttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; SELECT * FROM hypertable_size('disttable'); SELECT * FROM hypertable_detailed_size('disttable') ORDER BY node_name; @@ -193,9 +203,13 @@ VACUUM FULL ANALYZE disttable; SELECT pg_table_size('disttable'), pg_relation_size('disttable'), pg_indexes_size('disttable'), pg_total_relation_size('disttable'); SELECT pg_table_size(ch), pg_relation_size(ch), pg_indexes_size(ch) FROM show_chunks('disttable') ch; +SELECT * FROM _timescaledb_internal.relation_size('disttable'); +SELECT * FROM show_chunks('disttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; SELECT pg_table_size('nondisttable'), pg_relation_size('nondisttable'), pg_indexes_size('nondisttable'), pg_total_relation_size('nondisttable'); SELECT pg_table_size(ch), pg_relation_size(ch), pg_indexes_size(ch), pg_total_relation_size(ch) FROM show_chunks('nondisttable') ch; +SELECT * FROM _timescaledb_internal.relation_size('nondisttable'); +SELECT * FROM show_chunks('nondisttable') ch JOIN LATERAL _timescaledb_internal.relation_size(ch) ON TRUE; SELECT * FROM hypertable_size('disttable'); SELECT * FROM hypertable_detailed_size('disttable') ORDER BY node_name;