少敲一个字母,GreatSQL 对所有查询“已读不回”

深夜报错:数据库“哑巴”了

现场 DBA反馈数据库出现如下报错 :

greatsql > SELECT user,host FROM mysql.user;
Ignoring query to other database

无论查系统表、业务表,还是 show slave hosts;,客户端都像被按了静音键,只回一句:

Ignoring query to other database

greatsql客户端明明登录成功,为什么没有查询输出哪?

找到元凶:一条“正常”的登录命令

仔细核对后,发现 DBA 当时敲的命令是:

greatsql -root -p

不是 -uroot,而是 -root。DBA手滑少敲了一个字母 u,-root 改为 -uroot 后,数据库查询正常。

这里有两个让人困惑的地方:

  • 为什么 -root 能登录成功?
  • 为什么登录后所有查询都不执行

困惑一:为什么 -root 能登录成功?

MySQL/GreatSQL 客户端在指定用户名时,需要显式使用 --user-u。如果命令行里既没有 --user,也没有 -u,客户端会默认使用当前操作系统的登录用户名作为数据库账号。

现场的 OS 用户正好是 root

测试操作系统root用户,登录数据库不指定--user-u:

greatsql -p -h 127.0.0.1 -P 3336

登录后,查询用户信息:

greatsql > SELECT user(), current_user();
+-----------------+----------------+
| user()          | current_user() |
+-----------------+----------------+
| root@172.18.0.1 | root@%         |
+-----------------+----------------+

-root 里的 root 并没有被解析成用户名,真正让用户登录的是“操作系统用户名为 root”这一默认行为。

等效于:

greatsql -u root -p -h 127.0.0.1 -P 3336

困惑二:为什么登录后所有查询都不执行?

这才是整件事最精妙(也最坑人)的地方。

mysql/greatsql 客户端的短选项支持拼接-root 会被拆成:

-r -oo -t

分别对应:

短选项 长选项 含义
-r --raw 关闭转义输出,\n\t\0 等原样输出
-o --one-database 只执行与命令行指定数据库同名的库上的 SQL
-o --one-database 再来一次
-t --table 强制以表格格式输出

其中 --one-database 的机制是:

客户端只在“当前默认数据库”与命令行上指定的数据库名一致时才执行语句;否则直接跳过,并提示 Ignoring query to other database

关键点是:过滤逻辑只认 USE db_name 切换后的默认库,不看 SQL 语句本身操作的是哪个库。而如果在命令行里没有指定数据库名,就相当于在最开头没有插入有效的 USE,于是所有语句都被判定为“操作了其他数据库”。

所以 -root 最终等效于:

greatsql --raw --one-database --one-database --table -p

并且没有指定目标数据库——所有查询被忽略了。

结束语

少敲一个字母,换来深夜的紧急排查,也借此认识了 --one-database 参数。

数据库很少真的“哑巴”,更多时候是我们给了错误的指令。希望我的这次 -root 事件,能让你在下次登录时多瞄一眼命令行。


posted @ 2026-08-28 09:26  GreatSQL  阅读(114)  评论(0)    收藏  举报