Ksql 已经连上了,但你真的连对库了吗

Ksql 已经连上了,但你真的连对库了吗

我见过最危险的一类数据库操作,终端没有报错,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 中比较期望值,任何一项不符都返回非零退出码。

不要把环境判断写成“某张业务表存在就算生产”。表结构可能被同步,测试库也可能有同名表。主机、端口、数据库、用户和模式范围应该一起判断。

哪些操作不能拿来探测

我不建议用下面这些动作验证连接:

  • 随手创建一张临时业务表;
  • 更新一行数据再回滚;
  • 用高权限账号查询所有模式;
  • 运行没有过滤条件的大表统计。

连接验证的目标只是确认身份与可达性。只读、低成本、可重复的探针已经够用,没必要给生产环境增加锁、日志和审计噪声。

切库完成的成功标志

— 新旧连接要有明确分界,脚本失败也要能停下来。

我会把下面五项作为交接证据:

  1. 保存切换前的\conninfo结果;
  2. 新连接参数完整,没有隐式复用关键值;
  3. 切换后再次核对数据库和用户;
  4. search_path与对象完整名符合预期;
  5. 脚本在身份不符时返回失败,而不是继续往下跑。

连错库往往没有技术含量,却能造成很实在的事故。把核对动作变成固定步骤,比要求所有人“细心一点”靠谱得多。

参考资料

  • KES 官方产品手册:Ksql 快速启动
  • KES 官方产品手册:Ksql 命令参考