少敲一个字母,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 事件,能让你在下次登录时多瞄一眼命令行。

浙公网安备 33010602011771号