MySQL Workbench 与 mysql CLI 客户端工具手册
从一次“只查订单”的线上排障开始
值班同学收到告警:订单状态积压,需要确认最近二十条记录以及查询是否走索引。他在 Workbench 中点开生产连接,执行查询成功,随后为了“验证账号真是只读”又准备新建一张测试表。这里真正决定事故是否发生的,不是编辑器颜色、Safe Updates 弹窗或操作人的谨慎,而是 MySQL 服务端授予这个账号的权限。
先把目标收紧为一条可审计链路:客户端版本可识别,目标主机与数据库明确,服务器身份经过 TLS 校验,账号只能读取必要对象,查询带时间范围和 LIMIT,执行计划不真实执行 SQL,结果不落入不受控文件。Workbench 适合观察对象、交互查询和 Visual Explain;mysql 适合把同一组事实做成可复现命令和项目检查。两者共享的是服务器权限与 MySQL 协议,不共享“安全承诺”。
安装并确认客户端身份
MySQL Workbench 8.0.47 是当前 8.0 系列稳定版本,从 Workbench 下载页 获取。Workbench 8.0 针对 MySQL Server 8.0 开发和测试;它可以连接 MySQL 8.4 及更高版本,但部分管理和可视化能力可能不适配,因此升级服务器前要用真实管理动作做兼容验证,而不能只看“Test Connection 成功”。Windows 安装还需要满足 .NET、Visual C++ 运行库与受支持系统;Linux 包依赖由包管理器解决,macOS 使用官方 DMG。
mysql 随 MySQL 客户端包提供。Oracle MySQL 软件仓库通常安装 mysql-community-client,部分 Linux 发行版使用自己的 mysql-client 包;团队应固定来源,避免同一项目里混用不同发行方和大版本。安装后先记录实际身份:
mysql --versionWorkbench 在 Help > About MySQL Workbench 查看版本,在 Help > System Info 查看图形渲染信息。建模功能可以离线使用,SQL 编辑、对象浏览和服务器管理则需要数据库连接。Workbench 的 Linux/macOS 服务器管理动作还可能调用 sudo;只做 SQL 排障的成员不应因此获得主机提权权限。
第一次启动不要导入同事的生产连接包。先创建开发库连接,确认本机密码保险库、企业 CA、VPN 或 SSH 密钥的归属,再单独申请生产只读入口。
把连接字段翻译成真实影响
Workbench 新建连接时,开发库优先选择 Standard TCP/IP。各字段不是通讯录信息,而是不同故障域:
| 字段 | 实际影响 | 配错后的第一证据 |
|---|---|---|
| Hostname / Port | 决定 TCP 终点;默认端口通常为 3306 | timeout 多指向路由、防火墙或监听地址;refused 多指向端口无监听 |
| Username | 决定认证身份与授权集合 | Access denied for user,错误中会显示来源主机 |
| Default Schema | 连接后默认 USE 的数据库,不会额外授权 | DATABASE() 为 NULL 或对象解析到错误数据库 |
| Connection Method | 直连、Unix socket、local pipe 或 SSH 隧道 | SSH 成功但数据库失败,说明隧道与数据库认证是两段链路 |
| SSL Mode | 决定是否加密、是否验证 CA、是否校验主机名 | VERIFY_IDENTITY 下证书名不匹配会在认证前失败 |
| SSH Host/User/Key | 只负责到跳板机的隧道身份 | SSH 日志成功不代表 MySQL 账号有权限 |
| Timeout | 控制建连或读取等待,不会让慢 SQL自动变快 | 客户端超时后,服务端语句仍可能继续运行 |
选择 Standard TCP/IP over SSH 时,要分别验证 SSH 主机指纹与 MySQL TLS 身份。Workbench 首次遇到 SSH 主机会请求确认指纹并写入 known_hosts;值班人员应从受控资产系统核对指纹,不能把“接受新指纹”当作排障动作。指纹变化会被 Workbench 拒绝,应先确认跳板机是否按计划重建或密钥是否遭到替换。SSH 只缩小数据库暴露面,不会替代数据库端 TLS、账号授权和审计;Workbench 的通用 Timeout 参数也不适用于这类 SSH 连接,隧道超时必须单独观察。
跨不可信网络使用 Require and Verify Identity,CLI 对应 --ssl-mode=VERIFY_IDENTITY。它既校验证书链,也校验连接主机名;仅 REQUIRED 只保证加密,不证明对端身份。连接示例把 CA 留在受控路径,密码仍由交互提示或登录路径提供:
mysql \
--host db-dev.example.test \
--port 3306 \
--user app_readonly \
--database app \
--ssl-mode=VERIFY_IDENTITY \
--ssl-ca ./certs/company-ca.pem \
--connect-timeout=5 \
--default-character-set=utf8mb4 \
--safe-updates \
--password输入密码后,立即确认连接落点和加密状态:
SELECT VERSION(), CURRENT_USER(), USER(), DATABASE();
SHOW SESSION STATUS LIKE 'Ssl_cipher';CURRENT_USER() 是服务器用于权限检查的已认证账户,USER() 是客户端提交的用户名与来源;二者不同常见于匿名用户、代理身份或匹配到意外的 user@host。Ssl_cipher 有值证明当前会话使用 TLS,但只有 VERIFY_IDENTITY 一类模式才同时证明服务器身份。
用登录路径保存连接,而不是泄漏密码
下面这种写法会让密码进入 shell history、进程参数、终端录屏或 CI 日志,生产环境应直接禁止:
mysql -h prod-db.example.com -u app -p'<plaintext-password>'mysql_config_editor 将选项写入当前操作系统用户的 .mylogin.cnf。文件内容经过混淆,避免普通文本读取,但它不是抵御同机高权限攻击者的密钥库,也不能代替账号轮换:
mysql_config_editor set \
--login-path=app-dev \
--host=db-dev.example.test \
--user=app_readonly \
--password
mysql_config_editor print --login-path=app-dev
mysql --login-path=app-dev --database=app --ssl-mode=VERIFY_IDENTITY --ssl-ca=./certs/company-ca.pem登录路径适合个人开发机。CI 更适合短期凭证、受保护的 secret 注入和到期回收;不要提交 .mylogin.cnf,也不要把真实连接 URI、CA 私钥或导出文件放进仓库。
正向实验:证明查询身份、计划和小结果集
在开发库或影子库准备一张一次性实验表;建表与授权由有权管理员执行,日常只读账号不参与准备:
CREATE DATABASE IF NOT EXISTS client_lab;
CREATE TABLE client_lab.app_order (
id BIGINT PRIMARY KEY,
created_at DATETIME NOT NULL,
status VARCHAR(16) NOT NULL,
KEY idx_order_created_at (created_at)
);
INSERT INTO client_lab.app_order VALUES
(1, NOW() - INTERVAL 2 HOUR, 'PAID'),
(2, NOW() - INTERVAL 1 HOUR, 'PENDING');
CREATE USER 'client_lab_ro'@'%' IDENTIFIED BY '<temporary-secret>';
GRANT SELECT ON client_lab.* TO 'client_lab_ro'@'%';使用该账号连接后连续执行:
SELECT CURRENT_USER(), DATABASE();
SELECT id, created_at, status
FROM client_lab.app_order
WHERE created_at >= NOW() - INTERVAL 1 DAY
ORDER BY created_at DESC
LIMIT 20;
EXPLAIN FORMAT=JSON
SELECT id, created_at, status
FROM client_lab.app_order
WHERE created_at >= NOW() - INTERVAL 1 DAY
ORDER BY created_at DESC
LIMIT 20;预期身份包含 client_lab_ro,结果集为两行,JSON 计划中能看到 idx_order_created_at 候选或实际访问键。数据量很小时优化器仍可能选择全表扫描,这不是客户端故障;需要结合行数估计、过滤比例和统计信息判断。Workbench 的 Visual Explain 消费同一份 EXPLAIN 信息,它能帮助阅读计划,但不会替代基于真实基线的性能判断。
不要为了看运行耗时随手改成写语句的 EXPLAIN ANALYZE。MySQL 的 EXPLAIN ANALYZE 会真实执行语句;在生产上先使用普通 EXPLAIN,再由查询成本、锁影响和数据敏感性决定是否进入受控验证。
反向实验:让只读边界留下服务器证据
仍在实验库,用 client_lab_ro 执行:
CREATE TABLE client_lab.should_fail(id INT);预期返回类似:
ERROR 1142 (42000): CREATE command denied to user 'client_lab_ro'@'...' for table 'should_fail'再执行:
UPDATE client_lab.app_order SET status = 'CANCELLED' WHERE id = 2;预期仍是 ERROR 1142,这才是只读账号的故障证据。若语句成功,立即 ROLLBACK 只在显式事务且尚未提交时有效;默认自动提交下,更新已经持久化,应由管理员按主键恢复数据并撤销错误授权:
REVOKE INSERT, UPDATE, DELETE, CREATE, DROP, ALTER
ON client_lab.* FROM 'client_lab_ro'@'%';Workbench 的 Safe Updates 和 mysql --safe-updates 主要拦截缺少键条件或 LIMIT 的部分更新与删除。Workbench 修改该选项后必须重连数据库才会生效;可在实验库执行 UPDATE client_lab.app_order SET status = 'CANCELLED',确认出现 Error Code: 1175。上面的按主键更新完全可能通过 Safe Updates,因此客户端保护只能减少误触,服务端 GRANT 才是权限边界。
临时拥有写权限的维护人员可把诊断放进显式只读事务:
START TRANSACTION READ ONLY;
SELECT id, status FROM client_lab.app_order WHERE id = 2;
UPDATE client_lab.app_order SET status = 'CANCELLED' WHERE id = 2;
ROLLBACK;隔离环境中的临时写账号应看到 Cannot execute statement in a READ ONLY transaction,随后确认数据未变化。MySQL 的只读事务仍允许修改或锁定 TEMPORARY 表,也不能撤销 DDL 的隐式提交语义;它是维护会话的第二道护栏,不是权限隔离。Workbench 同一连接下的多个查询页共享事务,需要独立提交边界时必须打开新连接。
把同一证据接入项目
项目仓库可以约定 MYSQL_LOGIN_PATH,但不保存密码文件。下面的 smoke 脚本只读取身份、TLS 和计划,--batch --raw --skip-column-names 让输出稳定,shell 的 set -e 保证客户端非零退出码能够阻断流水线:
#!/usr/bin/env bash
set -euo pipefail
: "${MYSQL_LOGIN_PATH:?set MYSQL_LOGIN_PATH to an existing local login path}"
mysql \
--login-path="${MYSQL_LOGIN_PATH}" \
--database=app \
--batch --raw --skip-column-names \
--connect-timeout=5 \
--execute="
SELECT CURRENT_USER(), DATABASE();
SHOW SESSION STATUS LIKE 'Ssl_cipher';
EXPLAIN FORMAT=JSON
SELECT id FROM app_order ORDER BY id DESC LIMIT 5;
"验收时保存退出码、目标环境标识、CURRENT_USER()、TLS cipher 和计划摘要,不保存业务结果。若脚本连接失败,先用 mysql --verbose 核对生效选项;不要在 CI 中开启会打印 secret 的 shell trace。
批量 SQL 文件先验证落点,再交给 mysql,并检查退出码:
set -euo pipefail
actual_db="$(mysql --login-path=app-dev --batch --skip-column-names \
--execute='SELECT DATABASE()' client_lab)"
test "${actual_db}" = "client_lab"
mysql --login-path=app-dev --database=client_lab --show-warnings < reviewed-import.sql不要加入 --force,否则中间失败后仍会继续执行。需要全成全败时,文件自身必须用事务包住可事务化的 DML;CREATE、ALTER、DROP 等语句可能隐式提交,不能宣称原子导入。PowerShell 重定向生成 SQL 时还要确认编码,旧式 Windows PowerShell 的某些输出方式会写 UTF-16。
小结果集可从 Workbench 结果网格导出,或用 CLI 生成受权限保护的制表符文本:
umask 077
mysql --login-path=app-dev --database=client_lab --batch \
--execute="SELECT id, status FROM app_order ORDER BY id LIMIT 20" \
> orders-sample.tsvmysql --batch 不是通用 CSV 生成器。Workbench 的 Data Export / Data Import 调用逻辑转储工具时,还要记录实际二进制版本、对象范围和恢复日志;导入先在隔离库核对行数、约束、字符集和抽样数据,导出文件按数据副本治理并及时清理。
从报错反推故障层
Can't connect to MySQL server 先区分 timeout 与 refused。前者检查 DNS、VPN、路由、防火墙和安全组,后者检查服务监听、端口和 bind_address。Access denied 已经越过网络层,应核对 user@host 匹配、认证插件、密码来源和数据库授权,反复改防火墙没有意义。
TLS 失败要保留完整错误,并分别核对 CA 链、证书有效性、主机名和客户端证书。临时改成 DISABLED 只会掩盖证书问题并扩大凭证暴露面。caching_sha2_password 认证异常时优先建立 TLS;允许客户端自动获取 RSA 公钥会改变中间人风险模型,不能作为长期默认值。
查询“卡住”时,客户端超时或关闭窗口不等于服务端语句结束。另开只读管理会话查看 SHOW PROCESSLIST 或由 DBA 查询 Performance Schema,确认语句状态、等待事件和线程 ID,再决定是否终止。Workbench 每个打开的服务器连接页为基础操作可能占用两条连接,使用管理功能时还可能再占两条;多个值班人员同时打开连接会消耗 max_connections,连接容量应计入工具治理。
导出慢或内存高时,先减小结果集。CLI 读取大结果可使用 --quick 流式取行,但这会让服务器连接保持更久,并不能降低数据库扫描成本。Workbench 导出的 CSV/JSON 是查询结果副本,mysqldump 是包含 DDL 和可执行 SQL 的逻辑转储;两者都可能含敏感数据,前者不是备份,后者也不能未经审查直接恢复。
清理实验与撤销本地痕迹
实验结束先由管理员删除临时身份和对象:
DROP USER IF EXISTS 'client_lab_ro'@'%';
DROP DATABASE IF EXISTS client_lab;然后在本机移除登录路径和 Workbench 测试连接:
mysql_config_editor remove --login-path=app-dev
mysql_config_editor print --all删除下载到本机的 CSV、SQL dump 和临时证书副本,清空系统回收站,并按组织留存规则处理 Workbench SQL History 与 ~/.mysql_history。不要机械清除需要审计的生产证据;应把必要的脱敏摘要归档到受控系统,再删除个人副本。Workbench 的密码保险库只解决本地保存,不能完成共享账号拆分、离职回收和凭证轮换。
架构师如何选择与治理
Workbench 的优势是对象浏览、数据建模、可视计划和交互效率,代价是较高的本机资源、额外连接占用、历史与导出落盘,以及对高版本服务器能力可能不完整。mysql 的优势是依赖小、可脚本化、退出码清晰和容易进入 CI,代价是操作反馈较少,脚本若缺少超时、限量和错误处理会稳定地放大错误。紧急人工诊断通常两者并用:GUI 建立上下文,CLI 固化证据。
团队连接模板应固定主机别名、端口、TLS 模式、CA 来源、默认数据库、只读账号命名、连接超时和 application 对应的审计标识;密码与私钥独立分发。生产账号按人或工作负载签发,默认只授予必要 schema 的 SELECT,临时写权限有到期时间。root 不进入日常客户端。
容量预算不仅看数据库 QPS,还要看 GUI 同时打开的物理连接、长结果集网络流量、客户端内存、导出磁盘和日志保留。成本则包含 Workbench/CLI 支持与培训、证书和账号轮换、跳板与代理、审计存储以及敏感导出的处置时间。每次服务器大版本升级都应回归连接、认证插件、TLS、对象浏览、Visual Explain 和导入导出;仅验证一条 SELECT 1 无法证明工具链仍可用。
最终可持续的边界很朴素:客户端负责建立连接、表达 SQL 和呈现结果;MySQL 服务端负责认证、授权、事务与资源执行;组织流程负责谁能拿到凭证、数据能否导出、证据保留多久以及权限何时回收。把三层职责混在一个“只读连接”标签里,迟早会在真正的故障现场付出代价。
