Citus 14.2 常用 CLI 命令与工具详解

Citus 14.2 常用命令实测详解:Citus 不带独立 CLI,3685 个管理 UDF 全部经 psql 调用,逐条实测集群管理(citus_add_node/健康检查)、分布表与分片操作(create_distributed_table/citus_tables)、搬迁重平衡与租户隔离、监控统计(citus_stat_activity/citus_stat_statements)等高频 UDF 与 GUC 默认值。

CitusPostgreSQL数据库Citus2026/10/20

Citus 14.2 常用 CLI 命令与工具详解

目标:系统梳理 Citus 14.2 的运维命令体系——先给出「Citus 没有独立命令行二进制、运维入口是 psql + SQL 管理 UDF」这一实测结论,再按「节点管理 / 表分布 / 分片与数据运维 / 监控统计」四大类逐条实测常用管理函数与监控视图,附签名、参数与真实回显,并沉淀每一条排障实录。已在 Ubuntu 22.04 + PostgreSQL 18.6 + Citus 14.2 三节点集群实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS,x86_64
  • PostgreSQL 版本:18.6(18.6-1.pgdg22.04+2)
  • Citus 版本:14.2(包 postgresql-18-citus-14.2,版本 14.2.0.citus-1;扩展版本 14.2-1;citus_version() 实测输出 Citus 14.2.0 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, 64-bit)
  • 集群形态:1 协调器(citus-node1)+ 2 工作节点(citus-node2/3),第九章扩容后另含 citus-node4;内网 10.89.61.0/24
  • 实测数据库:postgres 库,postgres 账号;示例表:orders(8 分片,16 行)、customers(与 orders 同置)、regions(引用表)、events、logs(columnar)

💡 本篇命令均在协调器 psql 会话执行(管理操作约定在协调器做;因元数据全同步,Citus 11+ 起其他节点也可执行查询类命令)。

二、工具概览

核心结论(实测):postgresql-18-citus-14.2 包内没有任何命令行二进制——dpkg -L postgresql-18-citus-14.2 | grep -E "/usr/bin|/usr/lib/postgresql/18/bin" 输出为空。Citus 的全部运维入口如下表:

入口内容典型用途
psql + 管理 UDF扩展安装的 SQL 函数(实测扩展共提供 3685 个函数,管理类集中在 pg_catalog)节点/表/分片管理
元数据系统表pg_dist_node、pg_dist_partition、pg_dist_shard、pg_dist_placement查看集群与分片布局
监控视图citus_tables、citus_shards、citus_stat_activity、citus_lock_waits 等运行状态观测
psql 元命令\dx、\df、\d+ 等探查扩展与函数签名
PG 原生工具psql、pg_dump、pg_restore、pgbench备份、压测等常规运维

💡 技术拓展:分布式数据库的「管理接口」常见三种形态——独立 CLI 二进制(如 etcd 的 etcdctl)、HTTP 管理 API(如 ES 的 _cat 接口)、SQL 管理命令(如 Citus 的 UDF 体系)。Citus 选择 SQL 形态的理由:管理命令与数据同协议、天然受 pg_hba/角色权限管控、可被 psql/pgAdmin 等既有工具直接使用。本方案(Citus 14.2)实际采用的就是第三种。

三、前置条件

  1. 已按本专栏安装篇完成 Citus 14.2 安装并 CREATE EXTENSION citus;(扩展在库级别生效,管理函数仅存在于创建了扩展的数据库中)。
  2. 能以 postgres 账号连接协调器:sudo -u postgres psql -d postgres。
  3. 查询函数签名用 psql 元命令 \df 函数名;所有管理 UDF 位于 pg_catalog schema(实测 \df create_distributed_table 的 Schema 列为 pg_catalog),无需加前缀。

四、版本与角色确认命令

4.1 citus_version():查看 Citus 版本

sudo -u postgres psql -d postgres -c "SELECT citus_version();"

执行结果:

                                                                                     citus_version
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Citus 14.2.0 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, 64-bit
(1 row)

4.2 citus_is_coordinator():判断当前节点角色

sudo -u postgres psql -d postgres -c "SELECT citus_is_coordinator();"

执行结果(协调器上,已注册 Worker):

 citus_is_coordinator
----------------------
 t
(1 row)

⚠️ 在尚未注册任何 Worker 的单机上该函数返回 f(实测)——协调器身份取决于元数据中是否已有集群,不是安装形态。

4.3 \dx:扩展登记信息(版本/Schema)

sudo -u postgres psql -d postgres -c "\dx citus"

执行结果:

                        List of installed extensions
 Name  | Version | Default version |   Schema   |        Description
-------+---------+-----------------+------------+----------------------------
 citus | 14.2-1  | 14.2-1          | pg_catalog | Citus distributed database
(1 row)

4.4 citus_coordinator_nodeid():协调器节点号

sudo -u postgres psql -d postgres -c "SELECT citus_coordinator_nodeid();"

执行结果:

 citus_coordinator_nodeid
--------------------------
                        0
(1 row)

返回 0 表示默认部署形态下协调器不占用节点编号(节点编号只分配给 Worker)。

五、节点管理命令

5.1 citus_add_node():注册工作节点

签名(实测 \df citus_add_node):

 pg_catalog | citus_add_node | integer | nodename text, nodeport integer, groupid integer DEFAULT '-1'::integer, noderole noderole DEFAULT 'primary'::noderole, nodecluster name DEFAULT 'default'::name | func
sudo -u postgres psql -d postgres -c "SELECT * FROM citus_add_node('citus-node2', 5432);"

执行结果(集群首次注册,返回节点组号 1):

 citus_add_node
----------------
              1
(1 row)

5.2 citus_get_active_worker_nodes():列出活跃工作节点

sudo -u postgres psql -d postgres -c "SELECT * FROM citus_get_active_worker_nodes();"

执行结果(扩容到 3 Worker 后):

  node_name  | node_port
-------------+-----------
 citus-node3 |      5432
 citus-node2 |      5432
 citus-node4 |      5432
(3 rows)

5.3 citus_nodes 视图与 pg_dist_node 表

sudo -u postgres psql -d postgres -c "SELECT * FROM citus_nodes;"
sudo -u postgres psql -d postgres -c "SELECT nodeid, groupid, nodename, nodeport, noderole, isactive, shouldhaveshards FROM pg_dist_node ORDER BY nodeid;"

执行结果:

  nodename   | nodeport |  role  | active
-------------+----------+--------+--------
 citus-node2 |     5432 | worker | t
 citus-node3 |     5432 | worker | t
(2 rows)

 nodeid | groupid |  nodename   | nodeport | noderole | isactive | shouldhaveshards
--------+---------+-------------+----------+----------+----------+------------------
      1 |       1 | citus-node2 |     5432 | primary  | t        | t
      2 |       2 | citus-node3 |     5432 | primary  | t        | t
(2 rows)

shouldhaveshards=t 表示重平衡时新分片可落该节点;把节点置为 f(citus_set_node_property)可让其仅承载存量分片。

5.4 citus_check_cluster_node_health():全链路健康检查

sudo -u postgres psql -d postgres -c "SELECT * FROM citus_check_cluster_node_health();"

执行结果(2 Worker 时代,4/4 全真):

 from_nodename | from_nodeport | to_nodename | to_nodeport | result
---------------+---------------+-------------+-------------+--------
 citus-node2   |          5432 | citus-node2 |        5432 | t
 citus-node2   |          5432 | citus-node3 |        5432 | t
 citus-node3   |          5432 | citus-node2 |        5432 | t
 citus-node3   |          5432 | citus-node3 |        5432 | t
(4 rows)

每个 Worker 作为发起方对其余节点各测一次连接,result=t 即通。

5.5 citus_disable_node():节点维护态(含 RF=1 保护实录)

sudo -u postgres psql -d postgres -c "SELECT citus_disable_node('citus-node3', 5432);"

执行结果(RF=1 时被保护机制拒绝,真实回显):

ERROR:  cannot remove or disable the node citus-node3:5432 because because it contains the only shard placement for shard 102011
DETAIL:  One of the table(s) that prevents the operation complete successfully is public.orders
HINT:  To proceed, either drop the tables or use undistribute_table() function to convert them to local tables

⚠️ 排障实录:分片副本因子为 1 时,节点上存在「唯一副本」分片则禁止 disable/remove。处理:先 rebalance_table_shards() 腾空该节点,或部署时 RF=2。另注意 Citus 14.2 没有 citus_enable_node(实测 function citus_enable_node(unknown, integer) does not exist)——下线的节点恢复用 citus_activate_node(针对 inactive 节点)。

六、表分布命令

6.1 create_distributed_table():建哈希分布表

签名(实测 \df create_distributed_table):

 pg_catalog | create_distributed_table | void | table_name regclass, distribution_column text, distribution_type citus.distribution_type DEFAULT 'hash'::citus.distribution_type, colocate_with text DEFAULT 'default'::text, shard_count integer DEFAULT NULL::integer | func

基础用法(分片数走会话 GUC):

sudo -u postgres psql -d postgres <<'EOF'
SET citus.shard_count = 8;
CREATE TABLE orders (id bigint PRIMARY KEY, customer text, region_id int, amount numeric(12,2), created timestamptz DEFAULT now());
SELECT create_distributed_table('orders', 'id');
EOF

执行结果:

SET
CREATE TABLE
 create_distributed_table
--------------------------

(1 row)

指定同置组分片数(与 orders 同置本地 JOIN,实测):

sudo -u postgres psql -d postgres <<'EOF'
SET citus.shard_count = 8;
CREATE TABLE customers (id bigint PRIMARY KEY, name text NOT NULL);
SELECT create_distributed_table('customers', 'id', colocate_with => 'orders');
EOF

执行结果:

SET
CREATE TABLE
 create_distributed_table
--------------------------

(1 row)

⚠️ 排障实录:不显式指定 colocate_with 时新表按当前默认分片数(32)入组,与 8 分片的 orders 不同组,JOIN 报 the query contains a join that requires repartitioning(HINT:开 citus.enable_repartition_joins)。需要本地 JOIN 的表在建表时就锁定同置组。

6.2 create_reference_table():引用表广播

sudo -u postgres psql -d postgres -c "SELECT create_reference_table('regions');"

执行结果(NOTICE 为实测逐行):

NOTICE:  Copying data from local table...
NOTICE:  copying the data has completed
DETAIL:  The local data in the table is no longer visible, but is still on disk.
HINT:  To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.regions$$)
 create_reference_table
------------------------

(1 row)

执行后整表广播到所有 Worker(实测同一 shardid 102048 同时出现在 citus-node2/3)。

6.3 alter_distributed_table():在线改分片数

签名(实测):

 pg_catalog | alter_distributed_table | void | table_name regclass, distribution_column text DEFAULT NULL::text, shard_count integer DEFAULT NULL::integer, colocate_with text DEFAULT NULL::text, cascade_to_colocated boolean DEFAULT NULL::boolean | func

把 4 分片的 events 表在线扩到 8 分片(实测):

sudo -u postgres psql -d postgres -c "SELECT alter_distributed_table('events', shard_count => 8);"
sudo -u postgres psql -d postgres -c "SELECT table_name, shard_count FROM citus_tables WHERE table_name = 'events'::regclass;"

执行结果(NOTICE 为实测逐行):

NOTICE:  creating a new table for public.events
NOTICE:  moving the data of public.events
NOTICE:  dropping the old public.events
NOTICE:  renaming the new table to public.events
 alter_distributed_table
-------------------------

(1 row)

 table_name | shard_count
------------+-------------
 events     |           8
(1 row)

原理是「建影子表 → 迁数据 → 改名」,全程函数内部完成。

6.4 alter_table_set_access_method():切换列存

⚠️ 前置排障实录:columnar 是独立访问方法,未创建扩展时报错(实测回显):

ERROR:  access method "columnar" does not exist

先执行 CREATE EXTENSION citus_columnar; 再切换。

sudo -u postgres psql -d postgres -c "CREATE EXTENSION citus_columnar;"
sudo -u postgres psql -d postgres -c "SELECT alter_table_set_access_method('logs', 'columnar');"
sudo -u postgres psql -d postgres -c "SELECT table_name, access_method FROM citus_tables WHERE table_name = 'logs'::regclass;"

执行结果(实测逐行):

CREATE EXTENSION
NOTICE:  creating a new table for public.logs
NOTICE:  moving the data of public.logs
NOTICE:  dropping the old public.logs
NOTICE:  renaming the new table to public.logs
 alter_table_set_access_method
-------------------------------

(1 row)

 table_name | access_method
------------+---------------
 logs       | columnar
(1 row)

切换后继续读写正常(实测写入 1000 行后 SELECT count(*) FROM logs; 返回 1000)。

6.5 undistribute_table():还原为普通表

sudo -u postgres psql -d postgres -c "SELECT undistribute_table('temp_stats');"
sudo -u postgres psql -d postgres -c "SELECT table_name FROM citus_tables WHERE table_name = 'temp_stats'::regclass;"

执行结果(实测逐行):

NOTICE:  creating a new table for public.temp_stats
NOTICE:  moving the data of public.temp_stats
NOTICE:  dropping the old public.temp_stats
NOTICE:  renaming the new table to public.temp_stats
 undistribute_table
--------------------

(1 row)

 table_name
------------
(0 rows)

还原后 citus_tables 中已查不到该表,数据完整保留为本地普通表。

七、分片与数据运维命令

7.1 citus_tables / citus_shards 视图:集群清单与分片布局

sudo -u postgres psql -d postgres -c "SELECT * FROM citus_tables;"

执行结果(orders/customers/regions 三表时代实测):

 table_name | citus_table_type | distribution_column | colocation_id | table_size | shard_count | table_owner | access_method
------------+------------------+---------------------+---------------+------------+-------------+-------------+---------------
 customers  | distributed      | id                  |             1 | 176 kB     |           8 | postgres    | heap
 orders     | distributed      | id                  |             1 | 240 kB     |           8 | postgres    | heap
 regions    | reference        | <none>              |             3 | 64 kB      |           1 | postgres    | heap
(3 rows)

orders 与 customers 同置组 id=1,regions 是引用表(type=reference、colocation 3)。

sudo -u postgres psql -d postgres -c "SELECT table_name, shardid, shard_name, nodename, nodeport FROM citus_shards WHERE table_name = 'orders'::regclass ORDER BY shardid LIMIT 4;"

执行结果:

 table_name | shardid |  shard_name   |  nodename   | nodeport
------------+---------+---------------+-------------+----------
 orders     |  102008 | orders_102008 | citus-node2 |     5432
 orders     |  102009 | orders_102009 | citus-node3 |     5432
 orders     |  102010 | orders_102010 | citus-node2 |     5432
 orders     |  102011 | orders_102011 | citus-node3 |     5432
(4 rows)

⚠️ 排障实录:该视图端口列名是 nodeport 而非 node_port——写 node_port 时报 column "node_port" does not exist(HINT 提示改用 citus_shards.nodeport,实测)。

7.2 get_shard_id_for_distribution_column() / shard_name():定位分片

sudo -u postgres psql -d postgres -c "SELECT get_shard_id_for_distribution_column('orders', 3::bigint) AS shard_for_id3;"
sudo -u postgres psql -d postgres -c "SELECT shard_name('orders', 102011) AS shard_name_102011;"

执行结果:

 shard_for_id3
---------------
        102011
(1 row)

 shard_name_102011
-------------------
 orders_102011
(1 row)

与 6.x 的执行计划互相印证:WHERE id = 3 正是路由到分片 102011。排障时用它快速回答「某行在哪」。

7.3 run_command_on_shards():批量下发命令到全部分片

sudo -u postgres psql -d postgres -c "SELECT run_command_on_shards('orders', 'SELECT count(*) FROM %s');"

执行结果(实测逐行):

 run_command_on_shards
-----------------------
 (102008,t,3)
 (102009,t,2)
 (102010,t,4)
 (102011,t,1)
 (102012,t,0)
 (102013,t,2)
 (102014,t,1)
 (102015,t,3)
(8 rows)

返回三元组(分片号、是否成功、命令结果),8 个分片行数合计 16 与总量一致。%s 为分片表名占位符。

7.4 citus_table_size() / citus_shard_sizes():尺寸查看

sudo -u postgres psql -d postgres -c "SELECT citus_table_size('orders') AS orders_size, citus_table_size('regions') AS regions_size;"
sudo -u postgres psql -d postgres -c "SELECT * FROM citus_shard_sizes() ORDER BY shard_id LIMIT 5;"

执行结果:

 orders_size | regions_size
-------------+--------------
      122880 |        32768
(1 row)

 shard_id | size
----------+-------
   102008 | 32768
   102009 | 32768
   102010 | 32768
   102011 | 32768
   102012 | 16384
(5 rows)

⚠️ citus_shard_sizes 在 14.2 是无参函数(签名 OUT shard_id integer, OUT size bigint),不是视图;带 regclass 参数调用会报 function citus_shard_sizes(regclass) does not exist(实测)。它返回全部分片的尺寸,按需过滤。

7.5 citus_move_shard_placement():在线迁移单分片

签名(实测 \df citus_move_shard_placement,两种重载):

 pg_catalog | citus_move_shard_placement | void | shard_id bigint, source_node_id integer, target_node_id integer, transfer_mode citus.shard_transfer_mode DEFAULT 'auto'::citus.shard_transfer_mode | func
 pg_catalog | citus_move_shard_placement | void | shard_id bigint, source_node_name text, source_node_port integer, target_node_name text, target_node_port integer, shard_transfer_mode citus.shard_transfer_mode DEFAULT 'auto'::citus.shard_transfer_mode | func

把分片 102012 从 citus-node2 迁到 citus-node3(实测):

sudo -u postgres psql -d postgres -c "SELECT citus_move_shard_placement(102012, 'citus-node2', 5432, 'citus-node3', 5432);"

执行结果:

 citus_move_shard_placement
----------------------------

(1 row)

迁移后同置组分片一并搬迁(orders_102012 与 customers_102052 同到 node3,实测 citus_shards 验证)。该命令依赖:回环 replication 信任、wal_level=logical、PG 18 的 output_plugin_libraries='citus' 三项配置,缺一报错(排障实录见集群部署篇 8.2/8.3)。

7.6 rebalance_table_shards():全库/单表重平衡

签名(实测):

 pg_catalog | rebalance_table_shards | void | relation regclass DEFAULT NULL::regclass, threshold real DEFAULT NULL::real, max_shard_moves integer DEFAULT 1000000, excluded_shard_list bigint[] DEFAULT '{}'::bigint[], shard_transfer_mode citus.shard_transfer_mode DEFAULT 'auto'::citus.shard_transfer_mode, drain_only boolean DEFAULT false, rebalance_strategy name DEFAULT NULL::name | func

先看计划再执行(实测):

sudo -u postgres psql -d postgres -c "SELECT * FROM get_rebalance_table_shards_plan('orders');"

执行结果:

 table_name | shardid | shard_size | sourcename  | sourceport | targetname  | targetport
------------+---------+------------+-------------+------------+-------------+------------
 orders     |  102009 |          0 | citus-node3 |       5432 | citus-node2 |       5432
 customers  |  102050 |          0 | citus-node3 |       5432 | citus-node2 |       5432
(2 rows)
sudo -u postgres psql -d postgres -c "SELECT rebalance_table_shards();"

执行结果(实测逐行):

NOTICE:  Moving shard 102009 from citus-node3:5432 to citus-node2:5432 ...
 rebalance_table_shards
------------------------

(1 row)

集群含无主键分布表时需 rebalance_table_shards(shard_transfer_mode => 'force_logical');(实测 NOTICE:Moving shard 102008/102011/102062/102061/102074 到新节点成功)。扩容后的完整重平衡实测(含前后分布对照、数据一致性校验)见集群部署篇第九章。后台任务状态用 SELECT * FROM citus_rebalance_status(); 查看(无进行中任务时返回 0 行,实测)。

7.7 isolate_tenant_to_new_shard():大租户独立分片

签名(实测):

 pg_catalog | isolate_tenant_to_new_shard | bigint | table_name regclass, tenant_id "any", cascade_option text DEFAULT ''::text, shard_transfer_mode citus.shard_transfer_mode DEFAULT 'auto'::citus.shard_transfer_mode | func

⚠️ 排障实录:events 表无主键时隔离失败(真实回显):

ERROR:  cannot use logical replication to transfer shards of the relation events since it doesn't have a REPLICA IDENTITY or PRIMARY KEY
DETAIL:  UPDATE and DELETE commands on the shard will error out during logical replication unless there is a REPLICA IDENTITY or PRIMARY KEY.
HINT:  If you wish to continue without a replica identity set the shard_transfer_mode to 'force_logical' or 'block_writes'.

注意:报错里的 HINT 提到的 mode 需按命名参数传入(第 3 个位置参数是 cascade_option,实测按位置传 'force_logical' 仍报同样错误)。规范做法:先补含分布列的主键(分布式表主键必须包含分片键),再用默认模式隔离。

sudo -u postgres psql -d postgres -c "ALTER TABLE events ADD PRIMARY KEY (event_id, tenant_id);"
sudo -u postgres psql -d postgres -c "SELECT isolate_tenant_to_new_shard('events', 1);"
sudo -u postgres psql -d postgres -c "SELECT table_name, shardid, nodename FROM citus_shards WHERE table_name='events'::regclass ORDER BY shardid DESC LIMIT 3;"

执行结果(实测逐行):

ALTER TABLE

 isolate_tenant_to_new_shard
-----------------------------
                      102085
(1 row)

 table_name | shardid |  nodename
------------+---------+-------------
 events     |  102086 | citus-node4
 events     |  102085 | citus-node4
 events     |  102084 | citus-node4
(3 rows)

返回值是新分片 id 102085:原分片被一分为二,tenant_id=1 的行独占新分片(实测 102085/102086 均已落到目标节点)。

八、监控与统计命令

8.1 citus_stat_activity:跨节点活动会话

sudo -u postgres psql -d postgres -c "SELECT * FROM citus_stat_activity LIMIT 3;"

执行结果(宽表,实测输出节选,保留能读全的关键行):

     global_pid      | nodeid | is_worker_query | datid | datname  | pid  | usename  |            application_name            | client_addr |         backend_start         | wait_event_type | wait_event | state | backend_type
---------------------+--------+-----------------+-------+----------+------+----------+----------------------------------------+-------------+-------------------------------+-----------------+------------+-------+---------------
  10000006240        |      1 | t               |     5 | postgres | 6241 | postgres | citus_internal gpid=10000006240        | 10.89.61.3  | 2026-10-19 17:15:56.397354+00 | Client          | ClientRead | idle  | client backend
 999999990000006641  |      1 | t               |     5 | postgres | 6242 | postgres | citus_internal gpid=999999990000006641 | 10.89.61.2  | 2026-10-19 17:15:58.097891+00 | Client          | ClientRead | idle  | client backend
 20000006284         |      1 | t               |     5 | postgres | 6268 | postgres | citus_internal gpid=20000006284        | 10.89.61.4  | 2026-10-19 17:17:13.103755+00 | Client          | ClientRead | idle  | client backend
(3 rows)

global_pid 全局唯一标识会话(跨节点串联),application_name=citus_internal ... 的连接是 Citus 内部管理连接;排障时用 client_addr 定位来源节点。同族视图还有 citus_dist_stat_activity(分布式查询的任务级视图)、citus_lock_waits(跨节点锁等待链)。

8.2 citus_remote_connection_stats():到各节点的连接数

sudo -u postgres psql -d postgres -c "SELECT * FROM citus_remote_connection_stats();"

执行结果:

  hostname   | port | database_name | connection_count_to_node
-------------+------+---------------+--------------------------
 citus-node2 | 5432 | postgres      |                        2
 citus-node3 | 5432 | postgres      |                        2
 citus-node4 | 5432 | postgres      |                        2
(3 rows)

⚠️ 它同样是无参函数(实测按视图名直接 SELECT 会报 relation "citus_remote_connection_stats" does not exist,需带括号调用)。

8.3 citus_stat_statements:分布式 SQL 统计

⚠️ 三个前置条件缺一即空/报错(全部实测验证):

  1. postgresql.conf 预加载 pg_stat_statements(shared_preload_libraries = 'citus,pg_stat_statements',需重启);

  2. 目标库 CREATE EXTENSION pg_stat_statements;——未装时查询报(实测回显):

    ERROR:  pg_stat_statements is not installed
    HINT:  install pg_stat_statements extension and try again
    CONTEXT:  PL/pgSQL function citus_stat_statements() line 13 at RAISE
    
  3. 打开跟踪 SET citus.stat_statements_track = 'all';(默认 none 不采集,实测)。

另实测:Citus 14.2 不存在独立的 citus_stat_statements 预加载库——配置 shared_preload_libraries='citus,citus_stat_statements' 启动直接失败(FATAL: could not access file "citus_stat_statements": No such file or directory),这是旧版遗留写法。

启用后实测采集(在 citus-node1 上执行):

sudo -u postgres psql -d postgres -c "SET citus.stat_statements_track = 'all'; SELECT count(*) FROM orders WHERE id = 5; SELECT query, calls FROM citus_stat_statements ORDER BY calls DESC LIMIT 3;"

执行结果:

SET
 count
-------
     1
(1 row)

                   query                   | calls
-------------------------------------------+-------
 SELECT count(*) FROM orders WHERE id = $1 |     1
(1 row)

分布式查询(参数化后)被完整采集。重置用 SELECT citus_stat_statements_reset();(实测返回成功)。

九、常用 GUC 速查(实测默认值)

以下均为 SHOW <参数名>; 的实测默认值(Citus 14.2.0,单机起步配置):

GUC实测默认值说明
citus.shard_count32新建分布表的分片数(会话级可 SET,建表时固化)
citus.shard_replication_factor1分片副本因子(1=无冗余)
citus.max_adaptive_executor_pool_size16自适应执行器单查询最大并行连接数
citus.enable_repartition_joinsoff非同置 JOIN 是否允许重分布执行
citus.local_hostnamelocalhost节点访问自身的回环主机名(迁移链路依赖)
citus.stat_statements_tracknone分布式 SQL 统计开关(all 开启)
citus.enable_stat_countersoffstat_counters 计数器总开关
wal_level(PG 参数)replica → 需改 logical分片在线迁移/重平衡必需
output_plugin_libraries(PG 18 参数)空 → 需设 'citus'逻辑解码输出插件白名单

💡 多数 citus.* GUC 支持会话级 SET 与库级 ALTER DATABASE ... SET;涉及 wal_level/output_plugin_libraries 的必须写 postgresql.conf 并重启生效。

十、注意事项

  1. 管理函数在 pg_catalog:\df 查看签名最可靠;升级 Citus 后签名可能增参(如 14.x 的 citus_move_shard_placement 有 nodeid/nodeport 两种重载),脚本化时用命名参数。
  2. 调用位置:节点管理类命令只在协调器执行;元数据全同步后查询类视图各节点可查,但写类 UDF(add/remove/move/rebalance)统一在协调器操作,避免混乱。
  3. 在线迁移三件套:pg_hba 回环 replication 信任 + wal_level=logical + output_plugin_libraries='citus',任一缺失迁移链路报错(实录见集群部署篇 8.2/8.3)。
  4. RF=1 的保护限制:disable/remove/drain 节点会被「唯一副本保护」拒绝,先腾空再维护。
  5. 无参函数与视图分清:citus_shard_sizes()、citus_remote_connection_stats() 是函数(带括号),citus_tables、citus_shards 是视图(不带括号)。

十一、常见问题

Q1:报 function xxx does not exist? 先确认当前数据库已 CREATE EXTENSION citus;(扩展按库生效),再用 \df xxx 核对签名;citus_enable_node、独立 citus_stat_statements 库等旧版接口在 14.2 已不存在。

Q2:视图/函数报列不存在? 以 \d+ 视图名 或报错 HINT 为准(如 citus_shards 的端口列是 nodeport)。版本升级后列名/签名可能变化,不要跨版本硬编码。

Q3:管理操作执行很慢或卡住? 分片迁移依赖逻辑复制,观察 citus_stat_activity 中 application_name 带 citus_internal 的连接状态;重平衡后台任务用 citus_rebalance_status() 跟踪;锁冲突查 citus_lock_waits。

Q4:citus_stat_statements 一直为空? 按 8.3 三个前置逐项核对:预加载库 → 库内扩展 → stat_statements_track='all'。默认 track=none 不采集,是空表最常见原因。

十二、参考链接