PostgreSQL 18 常用 CLI 命令与工具详解

详解 PostgreSQL 18 常用的命令行工具(psql、pg_dump、pg_restore、pg_isready、vacuumdb、pgbench、pg_basebackup、pg_ctl),每个工具给出完整命令、真实输出与参数说明。所有命令均在真实 PostgreSQL 18 服务器环境实测,并以实际输出为准。

PostgreSQLPostgreSQL数据库参数调优2026/09/27

PostgreSQL 18 常用 CLI 命令与工具详解

目标:详解 PostgreSQL 18 常用的命令行工具(psql、pg_dump、pg_restore、pg_isready、vacuumdb、pgbench、pg_basebackup、pg_ctl),每个工具给出完整命令、真实输出与参数说明。所有命令均在真实服务器环境实测,并以实际输出为准。

环境信息

  • PostgreSQL 服务器:PostgreSQL 18.6(Debian 18.6-1.pgdg13+2),主机名 pg-srv(内网 IP 10.0.0.9)
  • 服务监听端口:5432(客户端与服务器之间需放行该端口)
  • 测试用户:app_user(数据库超级用户,库 app_db)
  • 密码注入方式:环境变量 $POSTGRES_PASSWORD(文档命令中以 ${PGPASSWORD} 占位,禁止明文写入配置文件)
  • 测试表:app_db.employees(5 条中文记录)

工具概览

工具主要用途位置
psql交互式/脚本 SQL 客户端内置
pg_dump逻辑备份(单库/单表导出)内置
pg_restore从 dump 文件恢复内置
pg_isready服务器健康探测内置
vacuumdb手动 VACUUM(清理/统计)内置
pgbench基准测试(TPC-B 风格)内置
pg_basebackup物理基准备份(流复制基础)内置
pg_ctl数据目录级启停管理内置

前置条件

  • 已部署 PostgreSQL 18(参考《PostgreSQL 18.6 Docker Compose 部署指南》),服务运行正常
  • 具备数据库管理权限(superuser 或对应库 owner)
  • 数据库属主主机上工具完整,无需额外安装

1. psql 客户端

psql 是 PostgreSQL 官方命令行客户端,支持丰富的元命令(\l、\d 等)与非交互参数。

1.1 连接方式

# 在数据库服务器本地以 app_user 连接 app_db
psql -U app_user -d app_db

# 远程连接(服务器 5432)
psql -h 127.0.0.1 -p 5432 -U app_user -d app_db

# 环境变量注入密码(推荐,避免 -W 交互)
export PGPASSWORD="${POSTGRES_PASSWORD}"
psql -U app_user -d app_db -c "SELECT 1;"

1.2 常用参数

参数说明
-c "SQL"非交互执行 SQL(可多次使用)
-f 文件执行 SQL 脚本文件
-l列出数据库
-A / -t无对齐边框 / 只输出行
-x扩展(垂直)显示
-At组合:无边框+仅数据,适合脚本
--echo-all回显 SQL

⚠️ 密码与特殊字符处理(避免踩坑):

  • PGPASSWORD 含特殊字符:必须引号包裹,$ 用单引号防变量展开:export PGPASSWORD='p@ssword'。
  • .pgpass 免密文件(推荐):格式 host:port:database:username:password,权限必须 0600:
    echo "127.0.0.1:5432:*:app_user:p@ssword" > ~/.pgpass && chmod 600 ~/.pgpass
    psql -h 127.0.0.1 -U app_user -d app_db   # 此后免交互认证
    

    若密码/字段内含 : 或 \,需在 .pgpass 中用 \ 转义。

  • URI 连接串:psql "postgresql://app_user:p%40ssword@127.0.0.1:5432/app_db"——密码中特殊字符(@、:、/、?、&)必须 URL 编码(@→%40、:→%3A、/→%2F),否则报 password authentication failed 或连接串解析错误。
  • @ 仅影响 URI 形式连接;PGPASSWORD/.pgpass 的 -p 交互认证不受影响。

1.3 实际测试输出

psql --version
psql -U app_user -d app_db -c "\l"
psql -U app_user -d app_db -c "\d employees"

执行结果:

psql (PostgreSQL) 18.6 (Debian 18.6-1.pgdg13+2)

                                   List of databases
   Name    |  Owner   | Encoding | Locale Provider |  Collate   |   Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+------------+------------+--------+-----------+-----------------------
 app_db    | app_user | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           |
 postgres  | app_user | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           |
 template0 | app_user | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/app_user          +
           |          |          |                 |            |            |        |           | app_user=CTc/app_user
 template1 | app_user | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/app_user          +
           |          |          |                 |            |            |        |           | app_user=CTc/app_user
(4 rows)

                                   Table "public.employees"
 Column |         Type          | Collation | Nullable |                Default
--------+-----------------------+-----------+----------+---------------------------------------
 id     | integer               |           | not null | nextval('employees_id_seq'::regclass)
 name   | character varying(50) |           | not null |
 dept   | character varying(30) |           |          |
 salary | numeric(10,2)         |           |          |
 hired  | date                  |           |          |
Indexes:
    "employees_pkey" PRIMARY KEY, btree (id)
# 脚本友好输出:-At 无边框、-x 垂直
psql -U app_user -d app_db -At -c "SELECT count(*) FROM employees;"
psql -U app_user -d app_db -x -c "SELECT * FROM employees WHERE id=1;"

执行结果:

5

-[ RECORD 1 ]------
id     | 1
name   | 张三
dept   | 研发部
salary | 25000.00
hired  | 2022-03-01

💡 命令解释:\l 列出数据库(含编码、locale);\d 表名 查看表结构(含默认值、索引);-At = 无对齐 + 仅数据,是脚本解析首选(如 psql -At -c "..." | awk ...);-x 垂直输出便于查看宽表。

2. pg_dump / pg_restore

逻辑备份与恢复工具,导出 SQL 文本或自定义压缩格式。

2.1 常用场景

# 仅导出表结构(同步 DDL)
pg_dump -U app_user -d app_db --schema-only -t employees

# 自定义压缩格式(-Fc,pg_restore 可选择性恢复、体积小)
pg_dump -U app_user -d app_db -Fc -f /tmp/backup/app_db.dump

# 仅导出数据(迁移数据用)
pg_dump -U app_user -d app_db -t employees --data-only

# 平文本 SQL 全量导出(可直接 psql 回放)
pg_dump -U app_user -d app_db -f /tmp/backup/app_db.sql

执行结果(-Fc 与文件):

-rw-r--r-- 1 root root 3.4K Sep 27 01:35 /tmp/backup/app_db.dump
-rw-r--r-- 1 root root 2.7K Sep 27 01:35 /tmp/backup/app_db.sql

执行结果(--schema-only 节选):

CREATE TABLE public.employees (
    id integer NOT NULL,
    name character varying(50) NOT NULL,
    dept character varying(30),
    salary numeric(10,2),
    hired date
);

2.2 pg_restore 恢复

# 创建目标库
createdb -U app_user restore_test

# 查看 dump 内容清单
pg_restore -U app_user -l /tmp/backup/app_db.dump | grep -E "TABLE|SEQUENCE"

# 恢复到目标库
pg_restore -U app_user -d restore_test /tmp/backup/app_db.dump

# 验证
psql -U app_user -d restore_test -c "SELECT count(*) FROM employees;"

执行结果:

221; 1259 16393 TABLE public employees app_user
220; 1259 16392 SEQUENCE public employees_id_seq app_user
3452; 0 0 SEQUENCE OWNED BY public employees_id_seq app_user
3445; 0 16393 TABLE DATA public employees app_user

 cnt
-----
   5
(1 row)

💡 命令解释:pg_dump -Fc 生成自定义压缩格式(二进制),配合 pg_restore -l 可查看内容、-t 表名 选择性恢复单表、--clean 恢复前先 DROP;--schema-only 只导结构;--data-only 只导数据。平文本 SQL 用 psql -f app_db.sql 回放。PG18 的 dump 文件开头带有 \restrict ... 伪指令,用于限制后续恢复对象,属正常内容。

3. pg_isready

服务器健康探测,常与脚本/监控配合使用。

pg_isready -h 127.0.0.1 -p 5432

执行结果:

127.0.0.1:5432 - accepting connections

💡 说明:accepting connections 表示就绪;no response / rejecting connections 表示启动中或拒绝连接。退出码 0=接受连接、1=拒绝、2=无响应、3=无法连接,脚本可据此判断。

4. vacuumdb

手动执行 VACUUM / ANALYZE,回收死元组、更新统计信息。PG18 支持 --parallel、--min-xid-age 等参数。

vacuumdb -U app_user -d app_db --verbose

执行结果(节选):

vacuumdb: vacuuming database "app_db"
INFO:  vacuuming "app_db.pg_catalog.pg_proc"
INFO:  finished vacuuming "app_db.pg_catalog.pg_proc": index scans: 0
pages: 0 removed, 102 remain, 1 scanned (0.98% of total), 0 eagerly scanned
tuples: 0 removed, 3413 remain, 0 are dead but not yet removable

💡 命令解释:--verbose 打印每个对象处理详情;-z 只做 ANALYZE、-Z -t 表名 只分析指定表。生产环境一般由 autovacuum 自动执行,vacuumdb 用于手工干预(如大量删除后立即回收)。

5. pgbench

内置基准测试工具,模拟并发事务,衡量 TPS / 延迟。

# 初始化测试数据(建 pgbench_accounts 等 4 张表)
pgbench -U app_user -d app_db -i

# 压测:10 并发、2 线程、每客户端 100 事务
pgbench -U app_user -d app_db -c 10 -j 2 -t 100

执行结果:

vacuuming...
creating primary keys...
done in 0.14 s (drop tables 0.00 s, create tables 0.00 s, client-side generate 0.07 s, vacuum 0.04 s, primary keys 0.03 s).

number of transactions per client: 100
number of transactions actually processed: 1000/1000
latency average = 6.937 ms

💡 命令解释:-i 初始化(生成标准测试表),-c 并发客户端数、-j 线程数(建议 ≤ CPU 核数)、-t 每客户端事务数、-T 按秒数压测(如 -T 60)、-n 跳过初始化 VACUUM。latency average 平均事务延迟,可换算 TPS≈1000/(6.937ms×并发关系);压测完成可 DROP TABLE pgbench_*; 清理测试表。

6. pg_basebackup

物理级基准备份,是流复制备库/时间点恢复的基础。

pg_basebackup --version
# 备份到 /tmp/pgbk(目录需不存在或为空)
pg_basebackup -U app_user -D /tmp/pgbk -Fp -P

执行结果(真实环境):

pg_basebackup (PostgreSQL) 18.6 (Debian 18.6-1.pgdg13+2)
waiting for checkpoint
pg_basebackup: error: could not create directory "/tmp/pgbk/pg_replslot": File exists
pg_basebackup: removing contents of data directory "/tmp/pgbk"

⚠️ 错误分析:目标目录 /tmp/pgbk 已存在时 pg_basebackup 报错并要求清理,因此目标目录必须不存在或为空(删除后重试即可)。备份成功后目录内包含完整数据文件,可用于 -R 生成流复制备库,或配合 WAL 归档做 PITR。

7. pg_ctl(补充)

数据目录级的管理工具,需以数据库属主(非 root)运行。

pg_ctl -D /var/lib/postgresql/18/main status

执行结果:

pg_ctl: cannot be run as root
Please log in (using, e.g., "su") as the (unprivileged) user that will

💡 说明:pg_ctl 拒绝以 root 运行,需切换到数据库属主用户(数据库服务器上为 postgres)执行:su postgres -c "pg_ctl -D /var/lib/postgresql/18/main status"。常用子命令 start/stop/restart/reload/status/promote。

注意事项

  • 密码安全:推荐 export PGPASSWORD=... 或 ~/.pgpass 注入,避免 -W 交互;命令中 ${POSTGRES_PASSWORD} 占位由环境变量注入,禁止明文。
  • pg_basebackup 目标目录:必须不存在或为空,否则报 File exists。
  • pg_ctl 不能以 root 运行:需切到 postgres 属主用户。
  • PG18 dump 新增 \restrict 伪指令:位于导出文件开头,用于限定后续恢复对象,正常现象。
  • pgbench 测试表:-i 会创建 pgbench_* 表,压测后建议清理。

常见问题

问题 1:pg_basebackup 报 could not create directory ... File exists

原因: 目标目录已存在且非空。

解决:

rm -rf /tmp/pgbk
pg_basebackup -U app_user -D /tmp/pgbk -Fp -P

问题 2:pg_ctl: cannot be run as root

原因: pg_ctl 出于安全限制拒绝 root 运行。

解决: 切换到属主用户执行:

su postgres -c "pg_ctl -D /var/lib/postgresql/18/main status"

问题 3:远程连接 psql 报 password authentication failed

原因: 密码错误,或 POSTGRES_PASSWORD 只在数据目录首次初始化时生效(改环境变量不改变已存在集群的密码)。

解决: 通过 SQL 修改:

ALTER USER app_user WITH PASSWORD '新密码';

问题 4:pgbench 压测报 relation "pgbench_accounts" does not exist

原因: 未先初始化测试数据。

解决:

pgbench -U app_user -d app_db -i

参考链接


本文档由 www.quzuo.net 平台开发