前言
Greenplum 是基于 PostgreSQL 构建的 MPP 分布式分析型数据库,由 Coordinator、Standby Coordinator、Primary Segment 和 Mirror Segment 等组件组成。DBA 日常工作不仅包括数据库对象和 SQL,还需要关注 Segment 状态、数据分布、资源组、膨胀、统计信息、备份恢复及故障恢复。
下面整理 Greenplum DBA 常用的 100 条命令,主要面向 Greenplum 6/7 系列。不同发行版在术语上可能使用 Master/Coordinator,部分系统视图、资源管理方式和工具参数也可能不同,执行前应确认版本。开源 Greenplum 原项目仓库目前已归档,商业发行版应以对应 Broadcom Tanzu Greenplum 文档为最终依据。
文中的主机、端口、目录、数据库和表名均为示例。停止集群、恢复 Segment、切换 Standby、调整配置、重分布和恢复备份等操作,应先确认影响范围并准备回退方案。
一、连接与基础信息
1. 使用 psql 连接 Greenplum
1psql -h 192.168.1.10 -p 5432 -U gpadmin -d postgres
客户端应连接 Coordinator,不要直接连接 Segment 处理业务数据。
2. 查看数据库版本
3. 查看当前数据库
1SELECT current_database();
4. 查看当前用户
1SELECT current_user, session_user;
5. 查看当前时间
1SELECT now(), current_timestamp;
6. 查看连接地址和端口
1SELECT inet_server_addr(), inet_server_port(),
2 inet_client_addr(), inet_client_port();
7. 查看搜索路径
8. 查看所有数据库
9. 查看 Schema
10. 查看已安装扩展
二、集群状态与节点
11. 查看集群概要状态
12. 查看集群详细状态
13. 查看异常 Segment
14. 查看 Primary 与 Mirror 映射
15. 查看 Standby 状态
16. 查看端口和数据目录
17. 从系统表查看 Segment
1SELECT dbid, content, role, preferred_role, mode, status,
2 hostname, address, port, datadir
3FROM gp_segment_configuration
4ORDER BY content, role;
18. 查看异常 Segment 配置
1SELECT dbid, content, role, preferred_role, mode, status,
2 hostname, port, datadir
3FROM gp_segment_configuration
4WHERE status <> 'u'
5 OR role <> preferred_role
6 OR mode <> 's'
7ORDER BY content, role;
19. 查看各主机 Segment 数量
1SELECT hostname, role, count(*) AS segment_count
2FROM gp_segment_configuration
3WHERE content >= 0
4GROUP BY hostname, role
5ORDER BY hostname, role;
20. 查看集群配置历史
1SELECT *
2FROM gp_configuration_history
3ORDER BY time DESC
4LIMIT 50;
三、数据库、表与分布
21. 创建数据库
22. 查看数据库大小
1SELECT datname,
2 pg_size_pretty(pg_database_size(datname)) AS size
3FROM pg_database
4ORDER BY pg_database_size(datname) DESC;
23. 查看数据库连接数
1SELECT datname, count(*) AS connections
2FROM pg_stat_activity
3GROUP BY datname
4ORDER BY connections DESC;
24. 查看表
25. 查看表定义
1pg_dump -s -t app.orders appdb
26. 创建 Hash 分布表
1CREATE TABLE app.orders (
2 order_id BIGINT,
3 customer_id BIGINT,
4 order_time TIMESTAMP,
5 amount NUMERIC(18,2)
6)
7DISTRIBUTED BY (order_id);
27. 创建随机分布表
1CREATE TABLE app.event_stage (
2 event_id BIGINT,
3 payload TEXT
4)
5DISTRIBUTED RANDOMLY;
28. 创建复制表
1CREATE TABLE app.dim_status (
2 status_code VARCHAR(20),
3 status_name VARCHAR(100)
4)
5DISTRIBUTED REPLICATED;
复制表适合体量较小、更新不频繁的维表。
29. 创建 AO 行存表
1CREATE TABLE app.order_history (
2 order_id BIGINT,
3 order_time TIMESTAMP,
4 amount NUMERIC(18,2)
5)
6WITH (appendoptimized=true, orientation=row)
7DISTRIBUTED BY (order_id);
30. 创建 AO 列存压缩表
1CREATE TABLE app.fact_sales (
2 sale_id BIGINT,
3 sale_date DATE,
4 amount NUMERIC(18,2)
5)
6WITH (
7 appendoptimized=true,
8 orientation=column,
9 compresstype=zlib,
10 compresslevel=5
11)
12DISTRIBUTED BY (sale_id);
31. 创建范围分区表
1CREATE TABLE app.fact_log (
2 log_id BIGINT,
3 log_date DATE,
4 message TEXT
5)
6DISTRIBUTED BY (log_id)
7PARTITION BY RANGE (log_date)
8(
9 START (DATE '2026-01-01')
10 INCLUSIVE END (DATE '2027-01-01')
11 EXCLUSIVE EVERY (INTERVAL '1 month')
12);
分区语法在不同大版本存在差异,执行前应在测试环境验证。
32. 查看表的分布键
1SELECT n.nspname AS schema_name,
2 c.relname AS table_name,
3 pg_get_table_distributedby(c.oid) AS distributed_by
4FROM pg_class c
5JOIN pg_namespace n ON n.oid = c.relnamespace
6WHERE n.nspname = 'app'
7 AND c.relname = 'orders';
33. 查看分区层级
1SELECT *
2FROM pg_partitions
3WHERE schemaname = 'app'
4 AND tablename = 'fact_log'
5ORDER BY partitionrank;
34. 查看表存储方式
1SELECT n.nspname, c.relname, c.relstorage
2FROM pg_class c
3JOIN pg_namespace n ON n.oid = c.relnamespace
4WHERE n.nspname = 'app'
5ORDER BY c.relname;
relstorage 的取值含义与版本有关,可结合 pg_appendonly 判断 AO 表属性。
35. 查看 AO 表属性
1SELECT n.nspname, c.relname, a.*
2FROM pg_appendonly a
3JOIN pg_class c ON c.oid = a.relid
4JOIN pg_namespace n ON n.oid = c.relnamespace
5WHERE n.nspname = 'app';
四、容量、倾斜与膨胀
36. 查看表总大小
1SELECT pg_size_pretty(
2 pg_total_relation_size('app.orders')
3 ) AS total_size;
37. 查看 Schema 容量
1SELECT sotdschemaname AS schemaname,
2 pg_size_pretty(
3 SUM(sotdsize + sotdtoastsize + sotdadditionalsize)::BIGINT
4 ) AS total_size
5FROM gp_toolkit.gp_size_of_table_and_indexes_disk
6GROUP BY sotdschemaname
7ORDER BY SUM(sotdsize + sotdtoastsize + sotdadditionalsize) DESC;
38. 查看大表排行
1SELECT sotdschemaname AS schemaname,
2 sotdtablename AS tablename,
3 pg_size_pretty(
4 sotdsize + sotdtoastsize + sotdadditionalsize
5 ) AS size
6FROM gp_toolkit.gp_size_of_table_and_indexes_disk
7ORDER BY sotdsize + sotdtoastsize + sotdadditionalsize DESC
8LIMIT 20;
39. 查看表在各 Segment 的行数
1SELECT gp_segment_id, count(*) AS rows
2FROM app.orders
3GROUP BY gp_segment_id
4ORDER BY gp_segment_id;
40. 计算表的数据倾斜
1SELECT gp_segment_id, count(*) AS rows
2FROM app.orders
3GROUP BY gp_segment_id
4ORDER BY rows DESC;
最大值与平均值差距过大时,应重新评估分布键。
41. 查看倾斜系数
1SELECT *
2FROM gp_toolkit.gp_skew_coefficients
3WHERE skcnamespace = 'app'
4ORDER BY skccoeff DESC;
42. 查看空闲倾斜
1SELECT *
2FROM gp_toolkit.gp_skew_idle_fractions
3WHERE sifnamespace = 'app'
4ORDER BY siffraction DESC;
43. 查看 Heap 表膨胀估算
1SELECT *
2FROM gp_toolkit.gp_bloat_diag
3WHERE bdirelname = 'orders';
44. 查看 AO 表隐藏行
1SELECT *
2FROM gp_toolkit.__gp_aovisimap_compaction_info(
3 'app.orders'::regclass
4);
该内部工具函数的可用性和返回列与版本有关。
45. 查看各主机文件系统
1gpssh -f hostfile -e 'df -h'
五、会话、锁与 SQL
46. 查看活动会话
1SELECT pid, usename, datname, client_addr,
2 state, query_start, wait_event_type, wait_event, query
3FROM pg_stat_activity
4WHERE state <> 'idle'
5ORDER BY query_start;
Greenplum 6 的部分视图仍可能使用 procpid 等旧字段。
47. 查看长时间运行 SQL
1SELECT pid, usename, datname,
2 now() - query_start AS elapsed,
3 state, query
4FROM pg_stat_activity
5WHERE state <> 'idle'
6 AND query_start < now() - interval '5 minutes'
7ORDER BY query_start;
48. 取消正在运行的 SQL
1SELECT pg_cancel_backend(12345);
49. 终止会话
1SELECT pg_terminate_backend(12345);
50. 查看锁
1SELECT locktype, database, relation::regclass,
2 mode, granted, pid
3FROM pg_locks
4ORDER BY granted, pid;
51. 查看阻塞关系
1SELECT blocked.pid AS blocked_pid,
2 blocker.pid AS blocker_pid,
3 blocked.query AS blocked_sql,
4 blocker.query AS blocker_sql
5FROM pg_stat_activity blocked
6JOIN pg_locks bl ON bl.pid = blocked.pid AND NOT bl.granted
7JOIN pg_locks kl
8 ON kl.locktype = bl.locktype
9 AND kl.database IS NOT DISTINCT FROM bl.database
10 AND kl.relation IS NOT DISTINCT FROM bl.relation
11 AND kl.granted
12JOIN pg_stat_activity blocker ON blocker.pid = kl.pid
13WHERE blocked.pid <> blocker.pid;
52. 查看关系锁
1SELECT *
2FROM gp_toolkit.gp_locks_on_relation
3ORDER BY lorrelname;
53. 查看执行计划
1EXPLAIN
2SELECT *
3FROM app.orders
4WHERE order_id = 10001;
54. 查看实际执行计划
1EXPLAIN (ANALYZE, VERBOSE, BUFFERS)
2SELECT customer_id, sum(amount)
3FROM app.orders
4GROUP BY customer_id;
ANALYZE 会真正执行 SQL,修改类语句必须放在可回滚事务中测试。
55. 查看资源队列
1SELECT *
2FROM gp_toolkit.gp_resqueue_status;
56. 查看资源组
1SELECT *
2FROM gp_toolkit.gp_resgroup_status;
资源队列与资源组的使用取决于版本和集群配置。
57. 查看资源组运行状态
1SELECT *
2FROM gp_toolkit.gp_resgroup_status_per_host;
58. 查看当前数据库日志
1SELECT logtime, logseverity, loguser, logdatabase,
2 logmessage
3FROM gp_toolkit.gp_log_database
4WHERE logtime > now() - interval '1 hour'
5ORDER BY logtime DESC;
59. 查看失效索引
1SELECT n.nspname, c.relname AS index_name,
2 i.indisvalid, i.indisready
3FROM pg_index i
4JOIN pg_class c ON c.oid = i.indexrelid
5JOIN pg_namespace n ON n.oid = c.relnamespace
6WHERE NOT i.indisvalid OR NOT i.indisready;
60. 查看缺少统计信息的表
1SELECT schemaname, relname
2FROM pg_stat_all_tables
3WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
4 AND last_analyze IS NULL
5 AND last_autoanalyze IS NULL
6ORDER BY schemaname, relname;
六、统计信息与表维护
61. 收集单表统计信息
62. 收集指定列统计信息
1ANALYZE app.orders (customer_id, order_time);
63. 收集数据库统计信息
64. 查看统计信息更新时间
1SELECT schemaname, relname,
2 last_analyze, last_autoanalyze
3FROM pg_stat_all_tables
4WHERE schemaname = 'app'
5ORDER BY relname;
65. 清理表中的失效行
66. 执行 VACUUM ANALYZE
1VACUUM ANALYZE app.orders;
67. 重写 Heap 表回收空间
该命令会持有强锁并重写表,应在维护窗口执行。
68. 压缩 AO 表
1VACUUM app.order_history;
AO 表的 VACUUM 会根据隐藏行比例执行压缩,实际行为取决于版本和阈值。
69. 重建索引
1REINDEX TABLE app.orders;
70. 修改表的分布键
1ALTER TABLE app.orders
2SET DISTRIBUTED BY (customer_id);
该操作通常需要重分布全表数据,应评估空间、锁和执行时间。
七、配置与集群启停
71. 查看数据库参数
72. 查看集群统一参数
1gpconfig -s max_connections
73. 修改动态参数
1gpconfig -c log_min_duration_statement -v 3000
是否动态生效取决于参数上下文。
74. 修改 Coordinator 与 Segment 参数
1gpconfig -c max_connections -m 200 -v 1000
75. 重新加载配置
76. 启动集群
77. 停止集群
78. 快速模式停止集群
Fast 模式会回滚活动事务,执行前应通知业务。
79. 重启集群
80. 查看所有主机的 Greenplum 进程
1gpssh -f hostfile -e 'ps -ef | grep "[p]ostgres"'
八、备份、恢复与数据装载
81. 执行全库备份
82. 备份指定 Schema
1gpbackup --dbname appdb --include-schema app
83. 备份指定表
1gpbackup --dbname appdb --include-table app.orders
84. 指定备份目录
1gpbackup --dbname appdb --backup-dir /backup/greenplum
85. 恢复备份
1gprestore --timestamp 20260727103000
86. 恢复并创建数据库
1gprestore --timestamp 20260727103000 --create-db
87. 仅恢复指定表
1gprestore --timestamp 20260727103000 \
2 --include-table app.orders
88. 启动 gpfdist
1gpfdist -d /data/load -p 8081 -l /tmp/gpfdist.log
89. 创建可读外部表
1CREATE EXTERNAL TABLE app.ext_orders (
2 order_id BIGINT,
3 customer_id BIGINT,
4 amount NUMERIC(18,2)
5)
6LOCATION ('gpfdist://etl01:8081/orders.csv')
7FORMAT 'CSV' (HEADER);
90. 使用 gpload 装载数据
1gpload -f load_orders.yml -l load_orders.log
九、高可用、恢复与扩容
91. 恢复故障 Segment
先通过 gpstate -e 确认故障范围和主机状态。
92. 执行全量 Segment 恢复
全量恢复开销较大,仅在增量恢复不可用或数据目录重建时使用。
93. 将 Segment 恢复到首选角色
94. 添加 Mirror
1gpaddmirrors -i mirror_config
应先用工具生成并审核配置文件,再正式执行。
95. 初始化 Standby Coordinator
1gpinitstandby -s gpstandby
96. 激活 Standby Coordinator
仅在确认原 Coordinator 不再提供服务且 Standby 同步正常后执行。
97. 生成扩容配置
98. 初始化新增 Segment
1gpexpand -i gpexpand_inputfile
99. 执行数据重分布
参数和工作流在不同版本存在差异,应以当前发行版扩容手册为准。
100. 执行集群快速巡检
1gpstate -s
2gpstate -e
3gpstate -f
4gpconfig -s max_connections
5gpssh -f hostfile -e 'df -h'
6psql -d postgres -c \
7"SELECT content, role, preferred_role, mode, status, hostname
8 FROM gp_segment_configuration ORDER BY content, role;"
巡检还应检查数据库容量、数据倾斜、长 SQL、锁、统计信息、膨胀、备份状态和主机资源。
结语
Greenplum 运维的核心是把 PostgreSQL 单库视角扩展到整个 MPP 集群。遇到问题时,应依次检查 Coordinator、Segment、Mirror、数据分布、资源管理和 SQL 执行计划,避免只在 Coordinator 上观察局部现象。
对于 Segment 恢复、Standby 激活、扩容和全表重分布等高风险操作,应使用与当前发行版匹配的官方手册,并在执行前完成备份、空间评估和回退设计。