Add experimental chunk replication view

A new view in the experimental schema shows information related to
chunk replication. The view can be used to learn the replication
status of a chunk while also providing a way to easily find nodes to
move or copy chunks between in order to ensure a fully replicated
multi-node cluster.

Tests have been added to illustrate the potential usage.
This commit is contained in:
Erik Nordström 2021-06-24 10:56:22 +02:00 committed by Dmitry Simonenko
parent 478404def5
commit b4710501dd
6 changed files with 106 additions and 2 deletions

View File

@ -54,6 +54,7 @@ set(SOURCE_FILES
metadata.sql
dist_internal.sql
views.sql
views_experimental.sql
gapfill.sql
maintenance_utils.sql
partialize_finalize.sql

View File

@ -1,4 +1,3 @@
DROP SCHEMA IF EXISTS timescaledb_experimental CASCADE;
DROP FUNCTION IF EXISTS _timescaledb_internal.block_new_chunks;
DROP FUNCTION IF EXISTS _timescaledb_internal.allow_new_chunks;
DROP FUNCTION IF EXISTS _timescaledb_internal.refresh_continuous_aggregate;
@ -12,6 +11,8 @@ DROP PROCEDURE IF EXISTS timescaledb_experimental.move_chunk;
DROP PROCEDURE IF EXISTS timescaledb_experimental.copy_chunk;
DROP TABLE IF EXISTS _timescaledb_catalog.chunk_copy_activity;
DROP SEQUENCE IF EXISTS _timescaledb_catalog.chunk_copy_activity_id_seq;
DROP VIEW IF EXISTS timescaledb_experimental.chunk_replication_status;
DROP SCHEMA IF EXISTS timescaledb_experimental CASCADE;
-- We need to rewrite all continuous aggregates to make sure that the
-- queries do not contain qualification. They will be re-written in

View File

@ -0,0 +1,28 @@
-- 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 VIEW timescaledb_experimental.chunk_replication_status AS
SELECT
h.schema_name AS hypertable_schema,
h.table_name AS hypertable_name,
c.schema_name AS chunk_schema,
c.table_name AS chunk_name,
h.replication_factor AS desired_num_replicas,
count(cdn.chunk_id) AS num_replicas,
array_agg(cdn.node_name) AS replica_nodes,
-- compute the set of data nodes that doesn't have the chunk
(SELECT array_agg(node_name) FROM
(SELECT node_name FROM _timescaledb_catalog.hypertable_data_node hdn
WHERE hdn.hypertable_id = h.id
EXCEPT
SELECT node_name FROM _timescaledb_catalog.chunk_data_node cdn
WHERE cdn.chunk_id = c.id
ORDER BY node_name) nodes) AS non_replica_nodes
FROM _timescaledb_catalog.chunk c
INNER JOIN _timescaledb_catalog.chunk_data_node cdn ON (cdn.chunk_id = c.id)
INNER JOIN _timescaledb_catalog.hypertable h ON (h.id = c.hypertable_id)
GROUP BY h.id, c.id, hypertable_schema, hypertable_name, chunk_schema, chunk_name
ORDER BY h.id, c.id, hypertable_schema, hypertable_name, chunk_schema, chunk_name;
GRANT SELECT ON ALL TABLES IN SCHEMA timescaledb_experimental TO PUBLIC;

View File

@ -545,6 +545,7 @@ WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND
ORDER BY objid::text DESC;
objid
---------------------------------------------------
timescaledb_experimental.chunk_replication_status
timescaledb_information.compression_settings
timescaledb_information.dimensions
timescaledb_information.chunks
@ -561,7 +562,7 @@ WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND
_timescaledb_internal.bgw_policy_chunk_stats
_timescaledb_internal.bgw_job_stat
_timescaledb_catalog.tablespace_id_seq
(16 rows)
(17 rows)
-- Make sure we can't run our restoring functions as a normal perm user as that would disable functionality for the whole db
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER

View File

@ -164,3 +164,49 @@ SELECT * FROM hypertable_index_size( 'dist_table_time_idx') ;
114688
(1 row)
-- Test chunk_replication_status view
SELECT * FROM timescaledb_experimental.chunk_replication_status
ORDER BY chunk_schema, chunk_name
LIMIT 4;
hypertable_schema | hypertable_name | chunk_schema | chunk_name | desired_num_replicas | num_replicas | replica_nodes | non_replica_nodes
-------------------+-----------------+-----------------------+-----------------------+----------------------+--------------+---------------------------+-------------------
public | dist_table | _timescaledb_internal | _dist_hyper_1_1_chunk | 2 | 2 | {view_node_1,view_node_2} | {view_node_3}
public | dist_table | _timescaledb_internal | _dist_hyper_1_2_chunk | 2 | 2 | {view_node_2,view_node_3} | {view_node_1}
public | dist_table | _timescaledb_internal | _dist_hyper_1_3_chunk | 2 | 2 | {view_node_3,view_node_1} | {view_node_2}
public | quote'tab | _timescaledb_internal | _dist_hyper_2_4_chunk | 2 | 2 | {view_node_1,view_node_2} | {view_node_3}
(4 rows)
-- drop one chunk replica
SELECT _timescaledb_internal.chunk_drop_replica(format('%I.%I', chunk_schema, chunk_name)::regclass, replica_nodes[1])
FROM timescaledb_experimental.chunk_replication_status
ORDER BY chunk_schema, chunk_name
LIMIT 1;
chunk_drop_replica
--------------------
(1 row)
SELECT * FROM timescaledb_experimental.chunk_replication_status
WHERE num_replicas < desired_num_replicas
ORDER BY chunk_schema, chunk_name;
hypertable_schema | hypertable_name | chunk_schema | chunk_name | desired_num_replicas | num_replicas | replica_nodes | non_replica_nodes
-------------------+-----------------+-----------------------+-----------------------+----------------------+--------------+---------------+---------------------------
public | dist_table | _timescaledb_internal | _dist_hyper_1_1_chunk | 2 | 1 | {view_node_2} | {view_node_1,view_node_3}
(1 row)
-- Example usage of finding data nodes to copy/move chunks between
SELECT
format('%I.%I', chunk_schema, chunk_name)::regclass AS chunk,
replica_nodes[1] AS copy_from_node,
non_replica_nodes[1] AS copy_to_node
FROM
timescaledb_experimental.chunk_replication_status
WHERE
num_replicas < desired_num_replicas
ORDER BY
chunk_schema, chunk_name;
chunk | copy_from_node | copy_to_node
---------------------------------------------+----------------+--------------
_timescaledb_internal._dist_hyper_1_1_chunk | view_node_2 | view_node_1
(1 row)

View File

@ -60,3 +60,30 @@ SELECT create_hypertable( 'special#tab', 'a', 'b', replication_factor=>2, chunk_
INSERT into "special#tab" select generate_series( '2020-02-02 10:00', '2020-02-05 10:00' , '1 day'::interval), 10;
SELECT * FROM chunks_detailed_size( '"special#tab"') ORDER BY chunk_name, node_name;
SELECT * FROM hypertable_index_size( 'dist_table_time_idx') ;
-- Test chunk_replication_status view
SELECT * FROM timescaledb_experimental.chunk_replication_status
ORDER BY chunk_schema, chunk_name
LIMIT 4;
-- drop one chunk replica
SELECT _timescaledb_internal.chunk_drop_replica(format('%I.%I', chunk_schema, chunk_name)::regclass, replica_nodes[1])
FROM timescaledb_experimental.chunk_replication_status
ORDER BY chunk_schema, chunk_name
LIMIT 1;
SELECT * FROM timescaledb_experimental.chunk_replication_status
WHERE num_replicas < desired_num_replicas
ORDER BY chunk_schema, chunk_name;
-- Example usage of finding data nodes to copy/move chunks between
SELECT
format('%I.%I', chunk_schema, chunk_name)::regclass AS chunk,
replica_nodes[1] AS copy_from_node,
non_replica_nodes[1] AS copy_to_node
FROM
timescaledb_experimental.chunk_replication_status
WHERE
num_replicas < desired_num_replicas
ORDER BY
chunk_schema, chunk_name;