mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 19:13:16 +08:00
This change fixes a couple issues with the num_dist_tables column of the timescaledb_information.data_node view. The first fix will allow the column to correctly report 0 when no tables are yet created (it currently will count a NULL table as 1 in this case). The second fix addresses a bug in the dist_util_remote_hypertable_info function which was causing the code to only see the first hypertable returned. This second bug will also cause incorrect results for many of our usage reporting views and utilities when there are multiple distributed hypertables.
264 lines
14 KiB
SQL
264 lines
14 KiB
SQL
-- 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.
|
|
|
|
CREATE SCHEMA IF NOT EXISTS timescaledb_information;
|
|
|
|
-- Convenience view to list all hypertables and their space usage
|
|
CREATE OR REPLACE VIEW timescaledb_information.hypertable_size_info AS
|
|
SELECT ht.id, ht.schema_name AS table_schema,
|
|
ht.table_name,
|
|
t.tableowner AS table_owner,
|
|
ht.num_dimensions,
|
|
(SELECT count(1)
|
|
FROM _timescaledb_catalog.chunk ch
|
|
WHERE ch.hypertable_id=ht.id
|
|
) AS num_chunks,
|
|
(CASE WHEN ht.replication_factor > 0 THEN true ELSE false END) AS distributed,
|
|
bsize.table_bytes,
|
|
bsize.index_bytes,
|
|
bsize.toast_bytes,
|
|
bsize.total_bytes
|
|
FROM _timescaledb_catalog.hypertable ht
|
|
LEFT OUTER JOIN pg_tables t ON ht.table_name=t.tablename AND ht.schema_name=t.schemaname
|
|
LEFT OUTER JOIN LATERAL @extschema@.hypertable_relation_size(
|
|
CASE WHEN has_schema_privilege(ht.schema_name,'USAGE') THEN format('%I.%I',ht.schema_name,ht.table_name) ELSE NULL END
|
|
) bsize ON true;
|
|
|
|
-- Convenience view to list all hypertables and their space usage
|
|
CREATE OR REPLACE VIEW timescaledb_information.hypertable AS
|
|
WITH ht_size as (
|
|
SELECT ht.id, ht.table_schema,
|
|
ht.table_name,
|
|
ht.table_owner,
|
|
ht.num_dimensions,
|
|
(SELECT count(1)
|
|
FROM _timescaledb_catalog.chunk ch
|
|
WHERE ch.hypertable_id=ht.id
|
|
) AS num_chunks,
|
|
ht.table_bytes,
|
|
ht.index_bytes,
|
|
ht.toast_bytes,
|
|
ht.total_bytes,
|
|
ht.distributed
|
|
FROM timescaledb_information.hypertable_size_info ht
|
|
),
|
|
compht_size as
|
|
(
|
|
select srcht.id,
|
|
sum(map.compressed_heap_size) as heap_bytes,
|
|
sum(map.compressed_index_size) as index_bytes,
|
|
sum(map.compressed_toast_size) as toast_bytes,
|
|
sum(map.compressed_heap_size) + sum(map.compressed_toast_size) + sum(map.compressed_index_size) as total_bytes
|
|
FROM _timescaledb_catalog.chunk srcch, _timescaledb_catalog.compression_chunk_size map,
|
|
_timescaledb_catalog.hypertable srcht
|
|
where map.chunk_id = srcch.id and srcht.id = srcch.hypertable_id
|
|
group by srcht.id
|
|
)
|
|
select hts.table_schema, hts.table_name, hts.table_owner,
|
|
hts.num_dimensions, hts.num_chunks,
|
|
pg_size_pretty( COALESCE(hts.table_bytes + compht_size.heap_bytes, hts.table_bytes)) as table_size,
|
|
pg_size_pretty( COALESCE(hts.index_bytes + compht_size.index_bytes , hts.index_bytes, compht_size.index_bytes)) as index_size,
|
|
pg_size_pretty( COALESCE(hts.toast_bytes + compht_size.toast_bytes, hts.toast_bytes, compht_size.toast_bytes)) as toast_size,
|
|
pg_size_pretty( COALESCE(hts.total_bytes + compht_size.total_bytes, hts.total_bytes)) as total_size,
|
|
hts.distributed
|
|
FROM ht_size hts LEFT OUTER JOIN compht_size
|
|
ON hts.id = compht_size.id;
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.license AS
|
|
SELECT _timescaledb_internal.license_edition() as edition,
|
|
_timescaledb_internal.license_expiration_time() <= now() AS expired,
|
|
_timescaledb_internal.license_expiration_time() AS expiration_time;
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.drop_chunks_policies as
|
|
SELECT format('%1$I.%2$I', ht.schema_name, ht.table_name)::regclass as hypertable, p.older_than, p.cascade, p.job_id, j.schedule_interval,
|
|
j.max_runtime, j.max_retries, j.retry_period, p.cascade_to_materializations
|
|
FROM _timescaledb_config.bgw_policy_drop_chunks p
|
|
INNER JOIN _timescaledb_catalog.hypertable ht ON p.hypertable_id = ht.id
|
|
INNER JOIN _timescaledb_config.bgw_job j ON p.job_id = j.id;
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.reorder_policies as
|
|
SELECT format('%1$I.%2$I', ht.schema_name, ht.table_name)::regclass as hypertable, p.hypertable_index_name, p.job_id, j.schedule_interval,
|
|
j.max_runtime, j.max_retries, j.retry_period
|
|
FROM _timescaledb_config.bgw_policy_reorder p
|
|
INNER JOIN _timescaledb_catalog.hypertable ht ON p.hypertable_id = ht.id
|
|
INNER JOIN _timescaledb_config.bgw_job j ON p.job_id = j.id;
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.policy_stats as
|
|
SELECT format('%1$I.%2$I', ht.schema_name, ht.table_name)::regclass as hypertable, p.job_id, j.job_type, js.last_run_success, js.last_finish, js.last_successful_finish, js.last_start, js.next_start,
|
|
js.total_runs, js.total_failures
|
|
FROM (SELECT job_id, hypertable_id FROM _timescaledb_config.bgw_policy_reorder
|
|
UNION SELECT job_id, hypertable_id FROM _timescaledb_config.bgw_policy_drop_chunks
|
|
UNION SELECT job_id, hypertable_id FROM _timescaledb_config.bgw_policy_compress_chunks
|
|
UNION SELECT job_id, raw_hypertable_id FROM _timescaledb_catalog.continuous_agg) p
|
|
INNER JOIN _timescaledb_catalog.hypertable ht ON p.hypertable_id = ht.id
|
|
INNER JOIN _timescaledb_config.bgw_job j ON p.job_id = j.id
|
|
INNER JOIN _timescaledb_internal.bgw_job_stat js on p.job_id = js.job_id
|
|
ORDER BY ht.schema_name, ht.table_name;
|
|
|
|
-- views for continuous aggregate queries ---
|
|
CREATE OR REPLACE VIEW timescaledb_information.continuous_aggregates as
|
|
SELECT format('%1$I.%2$I', cagg.user_view_schema, cagg.user_view_name)::regclass as view_name,
|
|
viewinfo.viewowner as view_owner,
|
|
CASE _timescaledb_internal.get_time_type(cagg.raw_hypertable_id)
|
|
WHEN 'TIMESTAMP'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.refresh_lag)::TEXT
|
|
WHEN 'TIMESTAMPTZ'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.refresh_lag)::TEXT
|
|
WHEN 'DATE'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.refresh_lag)::TEXT
|
|
ELSE cagg.refresh_lag::TEXT
|
|
END AS refresh_lag,
|
|
bgwjob.schedule_interval as refresh_interval,
|
|
CASE _timescaledb_internal.get_time_type(cagg.raw_hypertable_id)
|
|
WHEN 'TIMESTAMP'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.max_interval_per_job)::TEXT
|
|
WHEN 'TIMESTAMPTZ'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.max_interval_per_job)::TEXT
|
|
WHEN 'DATE'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.max_interval_per_job)::TEXT
|
|
ELSE cagg.max_interval_per_job::TEXT
|
|
END AS max_interval_per_job,
|
|
CASE
|
|
WHEN cagg.ignore_invalidation_older_than = BIGINT '9223372036854775807'
|
|
THEN NULL
|
|
ELSE
|
|
CASE _timescaledb_internal.get_time_type(cagg.raw_hypertable_id)
|
|
WHEN 'TIMESTAMP'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.ignore_invalidation_older_than)::TEXT
|
|
WHEN 'TIMESTAMPTZ'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.ignore_invalidation_older_than)::TEXT
|
|
WHEN 'DATE'::regtype
|
|
THEN _timescaledb_internal.to_interval(cagg.ignore_invalidation_older_than)::TEXT
|
|
ELSE cagg.ignore_invalidation_older_than::TEXT
|
|
END
|
|
END AS ignore_invalidation_older_than,
|
|
cagg.materialized_only,
|
|
format('%1$I.%2$I', ht.schema_name, ht.table_name)::regclass as materialization_hypertable,
|
|
directview.viewdefinition as view_definition
|
|
FROM _timescaledb_catalog.continuous_agg cagg,
|
|
_timescaledb_catalog.hypertable ht, LATERAL
|
|
( select C.oid, pg_get_userbyid( C.relowner) as viewowner
|
|
FROM pg_class C LEFT JOIN pg_namespace N on (N.oid = C.relnamespace)
|
|
where C.relkind = 'v' and C.relname = cagg.user_view_name
|
|
and N.nspname = cagg.user_view_schema ) viewinfo, LATERAL
|
|
( select schedule_interval
|
|
FROM _timescaledb_config.bgw_job
|
|
where id = cagg.job_id ) bgwjob, LATERAL
|
|
( select pg_get_viewdef(C.oid) as viewdefinition
|
|
FROM pg_class C LEFT JOIN pg_namespace N on (N.oid = C.relnamespace)
|
|
where C.relkind = 'v' and C.relname = cagg.direct_view_name
|
|
and N.nspname = cagg.direct_view_schema ) directview
|
|
WHERE cagg.mat_hypertable_id = ht.id;
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.continuous_aggregate_stats as
|
|
SELECT format('%1$I.%2$I', cagg.user_view_schema, cagg.user_view_name)::regclass as view_name,
|
|
CASE _timescaledb_internal.get_time_type(cagg.raw_hypertable_id)
|
|
WHEN 'TIMESTAMP'::regtype
|
|
THEN _timescaledb_internal.to_timestamp_without_timezone(ct.watermark)::TEXT
|
|
WHEN 'TIMESTAMPTZ'::regtype
|
|
THEN _timescaledb_internal.to_timestamp(ct.watermark)::TEXT
|
|
WHEN 'DATE'::regtype
|
|
THEN _timescaledb_internal.to_date(ct.watermark)::TEXT
|
|
ELSE ct.watermark::TEXT
|
|
END AS completed_threshold,
|
|
CASE _timescaledb_internal.get_time_type(cagg.raw_hypertable_id)
|
|
WHEN 'TIMESTAMP'::regtype
|
|
THEN _timescaledb_internal.to_timestamp_without_timezone(it.watermark)::TEXT
|
|
WHEN 'TIMESTAMPTZ'::regtype
|
|
THEN _timescaledb_internal.to_timestamp(it.watermark)::TEXT
|
|
WHEN 'DATE'::regtype
|
|
THEN _timescaledb_internal.to_date(it.watermark)::TEXT
|
|
ELSE it.watermark::TEXT
|
|
END AS invalidation_threshold,
|
|
cagg.job_id as job_id,
|
|
bgw_job_stat.last_start as last_run_started_at,
|
|
bgw_job_stat.last_successful_finish as last_successful_finish,
|
|
CASE WHEN bgw_job_stat.last_finish < '4714-11-24 00:00:00+00 BC' THEN NULL
|
|
WHEN bgw_job_stat.last_finish IS NOT NULL THEN
|
|
CASE WHEN bgw_job_stat.last_run_success = 't' THEN 'Success'
|
|
WHEN bgw_job_stat.last_run_success = 'f' THEN 'Failed'
|
|
END
|
|
END as last_run_status,
|
|
CASE WHEN bgw_job_stat.last_finish < '4714-11-24 00:00:00+00 BC' THEN 'Running'
|
|
WHEN bgw_job_stat.next_start IS NOT NULL THEN 'Scheduled'
|
|
END as job_status,
|
|
CASE WHEN bgw_job_stat.last_finish > bgw_job_stat.last_start THEN (bgw_job_stat.last_finish - bgw_job_stat.last_start)
|
|
END as last_run_duration,
|
|
bgw_job_stat.next_start as next_scheduled_run,
|
|
bgw_job_stat.total_runs,
|
|
bgw_job_stat.total_successes,
|
|
bgw_job_stat.total_failures,
|
|
bgw_job_stat.total_crashes
|
|
FROM
|
|
_timescaledb_catalog.continuous_agg as cagg
|
|
LEFT JOIN _timescaledb_internal.bgw_job_stat as bgw_job_stat
|
|
ON ( cagg.job_id = bgw_job_stat.job_id )
|
|
LEFT JOIN _timescaledb_catalog.continuous_aggs_invalidation_threshold as it
|
|
ON ( cagg.raw_hypertable_id = it.hypertable_id)
|
|
LEFT JOIN _timescaledb_catalog.continuous_aggs_completed_threshold as ct
|
|
ON ( cagg.mat_hypertable_id = ct.materialization_id);
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.compressed_chunk_stats
|
|
AS
|
|
WITH mapq as
|
|
(select
|
|
chunk_id,
|
|
pg_size_pretty(map.uncompressed_heap_size) as uncompressed_heap_bytes,
|
|
pg_size_pretty(map.uncompressed_index_size) as uncompressed_index_bytes,
|
|
pg_size_pretty(map.uncompressed_toast_size) as uncompressed_toast_bytes,
|
|
pg_size_pretty(map.uncompressed_heap_size + map.uncompressed_toast_size + map.uncompressed_index_size) as uncompressed_total_bytes,
|
|
pg_size_pretty(map.compressed_heap_size) as compressed_heap_bytes,
|
|
pg_size_pretty(map.compressed_index_size) as compressed_index_bytes,
|
|
pg_size_pretty(map.compressed_toast_size) as compressed_toast_bytes,
|
|
pg_size_pretty(map.compressed_heap_size + map.compressed_toast_size + map.compressed_index_size) as compressed_total_bytes
|
|
FROM _timescaledb_catalog.compression_chunk_size map )
|
|
SELECT format('%1$I.%2$I', srcht.schema_name, srcht.table_name)::regclass as hypertable_name,
|
|
format('%1$I.%2$I', srcch.schema_name, srcch.table_name)::regclass as chunk_name,
|
|
CASE WHEN srcch.compressed_chunk_id IS NULL THEN 'Uncompressed'::TEXT ELSE 'Compressed'::TEXT END as compression_status,
|
|
mapq.uncompressed_heap_bytes,
|
|
mapq.uncompressed_index_bytes,
|
|
mapq.uncompressed_toast_bytes,
|
|
mapq.uncompressed_total_bytes,
|
|
mapq.compressed_heap_bytes,
|
|
mapq.compressed_index_bytes,
|
|
mapq.compressed_toast_bytes,
|
|
mapq.compressed_total_bytes
|
|
FROM _timescaledb_catalog.hypertable as srcht JOIN _timescaledb_catalog.chunk as srcch
|
|
ON srcht.id = srcch.hypertable_id and srcht.compressed_hypertable_id IS NOT NULL and srcch.dropped = false
|
|
LEFT JOIN mapq
|
|
ON srcch.id = mapq.chunk_id ;
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.compressed_hypertable_stats
|
|
AS
|
|
SELECT format('%1$I.%2$I', srcht.schema_name, srcht.table_name)::regclass as hypertable_name,
|
|
( select count(*) from _timescaledb_catalog.chunk where hypertable_id = srcht.id) as total_chunks,
|
|
count(*) as number_compressed_chunks,
|
|
pg_size_pretty(sum(map.uncompressed_heap_size)) as uncompressed_heap_bytes,
|
|
pg_size_pretty(sum(map.uncompressed_index_size)) as uncompressed_index_bytes,
|
|
pg_size_pretty(sum(map.uncompressed_toast_size)) as uncompressed_toast_bytes,
|
|
pg_size_pretty(sum(map.uncompressed_heap_size) + sum(map.uncompressed_toast_size) + sum(map.uncompressed_index_size)) as uncompressed_total_bytes,
|
|
pg_size_pretty(sum(map.compressed_heap_size)) as compressed_heap_bytes,
|
|
pg_size_pretty(sum(map.compressed_index_size)) as compressed_index_bytes,
|
|
pg_size_pretty(sum(map.compressed_toast_size)) as compressed_toast_bytes,
|
|
pg_size_pretty(sum(map.compressed_heap_size) + sum(map.compressed_toast_size) + sum(map.compressed_index_size)) as compressed_total_bytes
|
|
FROM _timescaledb_catalog.chunk srcch, _timescaledb_catalog.compression_chunk_size map,
|
|
_timescaledb_catalog.hypertable srcht
|
|
where map.chunk_id = srcch.id and srcht.id = srcch.hypertable_id
|
|
group by srcht.id;
|
|
|
|
CREATE OR REPLACE VIEW timescaledb_information.data_node AS
|
|
SELECT s.node_name, s.owner, s.options, s.node_up,
|
|
COUNT(size.table_name) AS num_dist_tables,
|
|
SUM(size.num_chunks) AS num_dist_chunks,
|
|
pg_size_pretty(SUM(size.total_bytes)) AS total_dist_size
|
|
FROM (SELECT srvname AS node_name, srvowner::regrole::name AS owner, srvoptions AS options, _timescaledb_internal.ping_data_node(srvname) AS node_up
|
|
FROM pg_catalog.pg_foreign_server AS srv, pg_catalog.pg_foreign_data_wrapper AS fdw
|
|
WHERE srv.srvfdw = fdw.oid
|
|
AND fdw.fdwname = 'timescaledb_fdw') AS s
|
|
LEFT OUTER JOIN LATERAL @extschema@.data_node_hypertable_info(CASE WHEN s.node_up THEN s.node_name ELSE NULL END) size ON TRUE
|
|
GROUP BY s.node_name, s.node_up, s.owner, s.options;
|
|
|
|
GRANT USAGE ON SCHEMA timescaledb_information TO PUBLIC;
|
|
GRANT SELECT ON ALL TABLES IN SCHEMA timescaledb_information TO PUBLIC;
|