我见过最危险的一类数据库操作,终端没有报错,SQL 也执行得很顺。等数据改完才发现:命令是对的,库是错的。
Ksql 出现提示符,只能证明客户端和某个数据库建立了连接。至于是不是目标主机、目标库、目标账号,还得自己确认。这篇就把这套确认动作固定下来。
— 先认清当前身份,再碰业务对象。
第一眼别只看提示符
提示符通常会带数据库名称,看起来很直观,但它不够回答四个问题:
- 当前服务在哪台主机上?
- 使用的是哪个端口?
- 当前数据库是什么?
- 当前用户是谁?
先执行 Ksql 元命令:
\conninfo它用于输出当前连接信息。随后再让服务端回答一次:
SELECTcurrent_database()ASdb_name,current_userASlogin_user;两边信息一致,可信度才够。\conninfo反映客户端当前连接,SQL 结果来自服务端会话,二者组合比盯着提示符稳得多。
如果是刚接手的环境,我还会补一条:
SELECTversion();这不是为了背版本号,而是确认你连接的服务与变更单、部署记录一致。文章、工单和截图里如果需要展示,记得遮掉内网地址、账号等不宜公开的信息。
切换连接时,参数写完整
Ksql 可以在交互会话中用\c或\connect建立新连接:
\c appdb app_readonly 192.0.2.25 54321这四个位置依次是数据库名、用户名、主机和端口。官方手册说明,省略部分参数时,Ksql 默认可能复用前一条连接的值。
这个设计很方便,也很容易埋雷。你原来在测试主机,切库时只写了数据库名,自以为去了生产环境,实际上还留在原主机。我的习惯是:跨环境切换时四项全部写出,不靠复用。
新连接成功后,旧连接才会关闭。交互模式下,如果新连接失败,Ksql 可以保留原连接。这个保护能避免会话直接断掉,但也带来一个误区:失败后你仍然看到提示符,不代表已经切换成功。马上再跑一次\conninfo,别靠感觉。
还要检查对象解析范围
连对数据库和用户之后,我会查看当前对象解析路径:
SHOWsearch_path;同名表出现在不同模式时,未限定模式名的 SQL 可能访问到不是你预期的对象。重要脚本里尽量写完整对象名:
SELECTCOUNT(*)FROMapp_core.orders;app_core.orders比单写orders多不了几个字符,却能把对象范围钉死。尤其是部署脚本、数据修复脚本和截图演示,显式模式名能少掉很多争论。
如果环境允许不受信任的用户创建公共对象,还要按官方安全提示评估search_path。这不是让所有人机械清空路径,而是提醒你:对象名解析本身也是安全边界,不能只盯用户名和密码。
给脚本加一道“身份闸门”
人工操作能看输出,自动脚本更应该主动校验。一个稳妥思路是把期望环境作为变量传入,脚本开头先查询当前数据库和用户,值不一致就停止,不继续执行变更语句。
例如在 SQL 文件里先打开遇错即停:
\set ON_ERROR_STOP on然后只做身份查询并核对输出。更严格的做法是在受控存储过程或外层 PowerShell 中比较期望值,任何一项不符都返回非零退出码。
不要把环境判断写成“某张业务表存在就算生产”。表结构可能被同步,测试库也可能有同名表。主机、端口、数据库、用户和模式范围应该一起判断。
哪些操作不能拿来探测
我不建议用下面这些动作验证连接:
- 随手创建一张临时业务表;
- 更新一行数据再回滚;
- 用高权限账号查询所有模式;
- 运行没有过滤条件的大表统计。
连接验证的目标只是确认身份与可达性。只读、低成本、可重复的探针已经够用,没必要给生产环境增加锁、日志和审计噪声。
切库完成的成功标志
— 新旧连接要有明确分界,脚本失败也要能停下来。
我会把下面五项作为交接证据:
- 保存切换前的
\conninfo结果; - 新连接参数完整,没有隐式复用关键值;
- 切换后再次核对数据库和用户;
search_path与对象完整名符合预期;- 脚本在身份不符时返回失败,而不是继续往下跑。
连错库往往没有技术含量,却能造成很实在的事故。把核对动作变成固定步骤,比要求所有人“细心一点”靠谱得多。
参考资料
- KES 官方产品手册:Ksql 快速启动
- KES 官方产品手册:Ksql 命令参考