跳至内容

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 用 \qCtrl-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

本节验收

从一个新终端完成以下闭环:

  1. 用 URI 进入 postgres,执行 \conninfo
  2. \l+ 查看实例中的数据库,再用 \c postgres 明确重连;
  3. \dn+ 找到 public 与系统模式,用系统目录查询复核;
  4. 把当前数据库名以无表头单值形式保存到文件;
  5. 运行 SELECT pg_sleep(10);,用一次 Ctrl-C 取消;
  6. 执行上下文查询确认连接可用,最后用 \q 退出。

验收文件中数据库名必须精确为 postgres,且终端中没有遗留失败事务提示。1.7 创建 pg36_shop 后,再用同一组命令完成章级验收。

参考资料


上一节:Pigsty 的资源模型 · 返回本章目录 · 下一节:实战:建立 pg36_shop 地图与实验基线 · 查看全书目录 · 查看索引中心

最后更新于