1.6 最小 psql 生存卡
psql 同时是交互式终端、脚本执行器和 PostgreSQL 取证工具。本节只保留完成第 1 章所需的最小操作;变量、条件、服务文件、失败即停、批量输入输出和可靠脚本会在 ch02《psql 与可复现工作流》中系统展开。
先区分两种输入:
- 以反斜线开头的是
psql元命令,由客户端解释,通常不加分号; - SQL 发送给 PostgreSQL 服务器,以分号结束,受事务与权限约束。
看到一个命令时先问“它由客户端还是服务器执行”,很多困惑会自动消失。
1.6.1 用 URI 连接,用 \l、\dn、\d 看对象
使用连接 URI 可以让终端、应用驱动和文档共享同一种参数表达:
psql -X "$PG36_BOOTSTRAP_URL"连接成功后,第一条元命令应是:
\conninfo它显示当前数据库、角色、主机或 socket、端口以及 TLS 等连接信息。随后按从大到小的顺序探索对象:
\l+
\dn+
\d
\dt shop.*
\d+ shop.orders
\du+
\dx它们依次列出数据库、当前数据库中的模式、可见关系、shop 模式中的表、指定对象详情、角色和已安装扩展;+ 表示请求更详细的信息。对象尚未创建时,\d+ shop.orders 会明确报错。
\d 系列支持 psql 自己的对象模式匹配,不是 SQL 的 LIKE。例如 shop.* 表示模式 shop 下的对象;大小写与引号仍遵循 PostgreSQL 标识符规则。
元命令适合人类快速探索,系统目录查询适合明确筛选、保存和自动验证。两者应互相复核:
SELECT nspname
FROM pg_catalog.pg_namespace
ORDER BY nspname;若 \dn 与查询结果看起来不同,先检查 \dn 是否过滤系统模式、用户是否有可见性权限,以及是否连接了同一个数据库,不要立即断言工具出错。
1.6.2 用 \c 切库,用 -c 与 -f 执行
在交互会话中切换数据库:
\c pg36_shop
\conninfo\c 实际上会断开当前连接并建立新连接。未显式指定的主机、端口和角色通常沿用当前值;所以切换后必须再次执行 \conninfo 或上下文快照。若切换失败,psql 在交互模式下通常保留原连接,不要误以为已经进入目标库。
从 shell 执行一条 SQL:
psql -X "$PG36_BOOTSTRAP_URL" \
-c 'SELECT current_database(), session_user, current_user;'执行一个 SQL 文件:
psql -X "$PG36_BOOTSTRAP_URL" \
-v ON_ERROR_STOP=1 \
-f setup.sql-c 适合短小、可见的一次性观察;-f 让错误消息包含文件与行号,适合可审查脚本。ON_ERROR_STOP=1 要求 psql 遇到脚本错误后停止,避免第一步失败后继续执行一串建立在错误前提上的语句。
不要把多行复杂 SQL 塞进 shell 的 -c 参数:shell 引号、SQL 引号和变量展开叠在一起,很容易产生与屏幕看起来不同的实际输入。复杂内容放入版本控制的 .sql 文件,并在执行前查看差异。
交互会话内也可以执行文件:
\i setup.sql但自动化与验收更适合从 shell 使用 -f,因为调用方可以读取退出码并保存标准输出、标准错误。
1.6.3 用 \o 或 -A -t 保存输出
人读的表格与机器读的结果需要不同输出形式。
交互式保存随后产生的查询输出:
\o pg36-connection.txt
SELECT current_database(), current_user, pg_is_in_recovery();
\o第二个不带文件名的 \o 恢复到终端输出。忘记恢复时,后续查询“没有输出”往往只是仍在写文件。
从 shell 生成机器友好的单值或逐行结果:
psql -X "$PG36_BOOTSTRAP_URL" \
-A -t \
-v ON_ERROR_STOP=1 \
-c 'SELECT current_database();'-A使用不对齐输出,去掉表格边框;-t只输出元组,去掉列名与行数提示;-X避免个人psqlrc改写格式;ON_ERROR_STOP让失败产生可判断的非成功退出。
若有多列,显式选择分隔符和空值表示,或者直接输出 JSON;不要让下游脚本解析为人类排版的表格:
psql -X "$PG36_BOOTSTRAP_URL" -A -t -c "
SELECT jsonb_build_object(
'database', current_database(),
'user', current_user,
'in_recovery', pg_is_in_recovery()
);"保存输出不等于保存证据上下文。文件旁还应记录采集时间、客户端入口、服务端版本和命令来源,否则一行 false 很快会失去解释价值。
1.6.4 用 \q、Ctrl-C 安全退出与中断
正常退出:
\q如果正在输入但尚未发送一条 SQL,Ctrl-C 会清空当前查询缓冲区并回到提示符。可以先用 \p 查看缓冲区内容,用 \r 主动清空:
\p
\r前者显示尚未发送的查询,后者重置查询缓冲区。
如果服务器正在执行查询,Ctrl-C 会请求取消当前语句,而不是粗暴终止服务器进程。取消可能需要等待服务器到达可中断位置;网络中断时,客户端也未必能确认取消请求是否送达。
取消事务中的语句通常会让当前事务进入失败状态。此时后续 SQL 会收到“current transaction is aborted”,必须明确回滚:
ROLLBACK;不要连续按键后在不知道状态的情况下继续操作。中断后立即执行:
SELECT
current_database(),
current_user,
pg_is_in_recovery();若查询能正常执行,说明连接仍可用且不在失败事务中;若连接已经断开,由 psql 明确重连后再重新采集上下文。
Ctrl-Z 只是把本地 psql 挂起,服务器连接和可能的事务仍然存在。它不是安全退出手段。遗留的 idle in transaction 会话可能长期持有快照和锁,是后续并发与膨胀问题的常见来源。
一张够用的生存卡
| 目标 | 命令 |
|---|---|
| 看当前连接 | \conninfo |
| 看数据库/模式/关系 | \l+、\dn+、\d |
| 看角色/扩展 | \du+、\dx |
| 切换数据库 | \c <database>,随后再次 \conninfo |
| 执行短 SQL/脚本 | shell 中 -c/-f |
| 脚本失败即停 | -v ON_ERROR_STOP=1 |
| 保存交互输出 | \o <file>,完成后 \o |
| 输出机器可读单值 | -X -A -t |
| 取消/退出 | Ctrl-C/\q |
本节验收
从一个新终端完成以下闭环:
- 用 URI 进入
postgres,执行\conninfo; - 用
\l+查看实例中的数据库,再用\c postgres明确重连; - 用
\dn+找到public与系统模式,用系统目录查询复核; - 把当前数据库名以无表头单值形式保存到文件;
- 运行
SELECT pg_sleep(10);,用一次Ctrl-C取消; - 执行上下文查询确认连接可用,最后用
\q退出。
验收文件中数据库名必须精确为 postgres,且终端中没有遗留失败事务提示。1.7 创建 pg36_shop 后,再用同一组命令完成章级验收。
参考资料
上一节:Pigsty 的资源模型 · 返回本章目录 · 下一节:实战:建立 pg36_shop 地图与实验基线 ·
查看全书目录 · 查看索引中心