information_schema是会话级虚拟库,仅反映当前连接实例的元数据,不跨实例也不聚合;需通过多连接分别查询,推荐mysqlsh AdminAPI并行处理。
MySQL 多实例下 information_schema 为什么查不到其他实例的库?
因为 information_schema 是会话级虚拟库,只反映当前连接的 mysql 实例元数据。连 a 实例,就只能看到 a 的库表;换到 b 实例,information_schema 内容完全重置——它不跨实例,也不“聚合”。想靠一条 sql 扫遍所有服务器的库名?原生做不到。
实操建议:
- 必须主动建立多个连接,分别执行
SELECT schema_name FROM information_schema.schemata - 不能依赖中间件或代理层自动合并结果(如 ProxySQL、MaxScale 默认不提供跨实例元数据查询)
- 若用 Python 脚本批量操作,别在同一个
connection对象上反复change_db()——那只是切换默认库,不影响information_schema范围
用 mysqlsh + JavaScript 模式做跨实例库名搜索最省事
mysqlsh 的 AdminAPI 和 Cluster API 原生支持多实例管理,且内置了并行连接和结果聚合能力。比手写 Shell + mysql -h 组合更稳,也比 Python 自建连接池少处理超时、认证失败等边界。
实操建议:
- 先用
mysqlsh --js进入交互模式 - 逐个添加实例:
shell.connect('mysql://user:pass@host1:3306'),再session.runSql("SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('mysql','sys','information_schema','performance_schema')") - 更推荐用脚本方式批量执行:把实例列表写进数组,用
for循环 +try/catch包裹每次连接和查询,出错跳过不中断 - 注意
mysqlsh默认启用 X Protocol,确保目标实例已开启mysqlx插件(5.7.12+ / 8.0+ 默认开)
Shell 脚本调 mysql 命令时,ERROR 1045 (28000) 高频但容易误判
这个错误表面是权限问题,但在多服务器场景下,大概率是凭据文件或命令行参数没对齐——比如 ~/.my.cnf 只配置了主库,扫从库时复用导致认证失败;或者密码含特殊字符未转义,被 Shell 提前截断。
实操建议:
- 绝对不要依赖全局
~/.my.cnf,每个mysql命令显式指定配置文件:mysql --defaults-file=/tmp/my.cnf.host2 -e "SELECT ..." - 密码用
--password='p@ss!word'形式传入,单引号包裹,避免 Shell 解析 - 加
-sN参数(静默 + 无列名)让输出更干净,方便后续grep或awk处理 - 务必检查每台服务器的
max_connections和wait_timeout,短时高频连接可能触发拒绝
为什么不用 pt-show-grants 或 mysqldump --no-data 替代?
这两个工具目的不同:pt-show-grants 输出的是用户权限语句,不是库名列表;mysqldump --no-data 虽能列出库,但要先成功连接并触发 dump 流程,开销大、速度慢,且遇到某个实例不可达时整个命令就卡住或报错退出,不适合快速探查。
实操建议:
- 真要导出结构,用
mysql -e "SHOW DATABASES"就够了,轻量、快、失败可控 - 如果需要带库字符集或创建时间等扩展信息,才值得上
information_schema.schemata查询,但必须接受它只服务单实例 - 别指望任何客户端工具自动帮你“发现”新加入的 MySQL 实例——IP 列表、端口、账号都得你事先维护好
跨实例搜索本质是 I/O 密集型任务,瓶颈不在 SQL,而在连接建立和网络往返。最容易被忽略的是 DNS 解析延迟和 TCP TIME_WAIT 积压,尤其当一次扫几十台时,别用同步串行方式硬扛。











