MySQL Shell(mysqlsh)使用手册:常用功能速查
摘要
- MySQL Shell(
mysqlsh)是官方高级客户端:除 SQL 外,还支持 JavaScript / Python,并内置 AdminAPI、逻辑备份/恢复、升级检查等工具 - 本文基于 MySQL Shell 26.7 官方文档,按「日常最常用」整理安装、连接、模式切换、输出格式、
util.*工具与命令行 API 集成 - 与传统
mysql客户端的对比见 1.1:多数场景只装 Shell 即可,保留mysql主要为了兼容旧脚本 - 最新版
mysqlsh可配合任意 MySQL 8.0 GA 及以上 使用;InnoDB Cluster 实操见 MySQL 8.4 InnoDB Cluster 的构建方法,升级检查场景见 MySql--从Mysql5.7升级到Mysql8
1. mysqlsh 是什么
传统 mysql 客户端主要做 SQL 交互;MySQL Shell 在此之上增加了脚本语言、全局对象 API 和一批运维工具。官方功能概览见 MySQL Shell Features。
| 能力 | 说明 |
|---|---|
| 多语言 | SQL / JavaScript / Python(使用 Python 3;按平台使用系统 Python 或捆绑运行时) |
| 双协议 | Classic MySQL(默认 3306)与 X Protocol(默认 33060) |
| AdminAPI | 管理 InnoDB Cluster / ClusterSet / ReplicaSet(dba / cluster) |
| X DevAPI | 在 X Protocol 下操作关系数据与 Document Store |
| Utilities | util.*:升级检查、逻辑 dump/load、并行导入、诊断收集等 |
| 命令行 API | mysqlsh -- util dump-schemas ...,方便写 bash / CI |
| 输出格式 | table / tabbed / vertical / JSON,便于对接外部工具 |
官方建议始终使用最新的 MySQL Shell。Shell 版本可以高于 Server;很多 util 能力(尤其 dump/load)新特性只在新 Shell 里完整可用。
1.1 与 mysql 命令的区别:装了 mysqlsh 还要装 mysql 吗?
mysql |
mysqlsh |
|
|---|---|---|
| 定位 | 经典 SQL 客户端 | 高级客户端 + 脚本环境 + 运维工具 |
| 语言 | 基本只有 SQL | SQL / JavaScript / Python |
| 协议 | Classic(3306) | Classic + X Protocol(33060) |
| 集群 / 复制管理 | 手写 SQL、改配置 | AdminAPI(dba / cluster) |
| 备份恢复 | 通常配合 mysqldump 等 |
自带 util.dump* / loadDump 等 |
| 升级检查 | 无 | util.checkForServerUpgrade() |
| 体积 | 更轻 | 更重(内置脚本引擎) |
| 脚本生态 | 大量现成 bash 写的是 mysql -e |
新项目更合适;旧脚本要改 |
交互跑 SQL 时,mysqlsh --sql 可以当作增强版 mysql(\use、\source、结果格式、Tab 补全等)。
多数日常场景只装 mysqlsh 就够。 是否还要 mysql 命令,看兼容性而不是功能缺口:
-
可以不装
mysql:交互和批处理都用 Shell;备份用dump/load;没有脚本硬编码调用mysql。 -
建议仍保留
mysql客户端(不必为此再装一整套 Server):现有 CI/监控/文档写死了mysql -h ... -e;或容器里只想塞一个最轻的 SQL 客户端。
注意:mysql 客户端和 MySQL Server(mysqld) 是两回事。兼容旧脚本时,装客户端包 / 命令行工具即可。
实用建议:以 8.x 运维、Cluster、逻辑迁移为主 → 主用 mysqlsh;两者并存也很常见——Shell 做管理与工具,mysql 跑遗留脚本。
2. 安装
-
下载归档页 或当前发行包页面
-
Linux 通用包解压即可用;选包时注意 glibc 下限(与 Server 包同样规则)
1 | # 查看系统 glibc |
3. 连接与会话
文档:Connections、Sessions。
第一次连上实例后,Shell 会创建全局会话,在 SQL / JS / Python 三种模式下共用,变量名是 session。
3.1 启动时连接
1 | # URI 形式(推荐) |
3.2 会话内连接
1 | MySQL JS > \connect --mysql root@127.0.0.1:3306 |
JS / Python 里也可用:
1 | // 进 mysqlsh 后切到 JS |
3.3 协议怎么选(实操建议)
| 场景 | 建议 |
|---|---|
| 日常 SQL、升级检查、逻辑备份恢复、AdminAPI 搭集群 | Classic 3306(--mysql / mysql://) |
| Document Store、X DevAPI 开发 | X Protocol 33060(需开启 X Plugin) |
util.importTable() 并行导入 |
必须 Classic(依赖 LOAD DATA LOCAL) |
-
命令行里写
user:password@host会把密码暴露在进程列表与 shell 历史中,生产环境尽量交互输入,或用 login-path / Secret Store。 -
无密码账号要显式声明无密码,例如 URI 写成
user:@host:3306,或加--no-password。 -
Shell 默认会读 option file / login-path;不想读时加
--no-defaults。
3.4 为什么没输密码也能连上?
文档:Pluggable Password Store、login-path / Options Files。
mysqlsh user@host:3306 不问密码就连上,通常不是账号免密,而是本机某处已经提供了密码。常见来源有三类,互不替代:
| 来源 | 典型位置 | shell.listCredentials() 看不看得到 |
|---|---|---|
| option file | ~/.my.cnf 的 [client] / [mysqlsh] |
看不到 |
| login-path | ~/.mylogin.cnf(mysql_config_editor) |
默认 看不到(要把 helper 改成 login-path 再 list) |
| Secret Store | macOS 钥匙串 / Windows API / login-path Helper | 看得到(仅当前 helper 里的条目) |
连接参数优先级(后者可被前者覆盖)大致是:命令行 > login-path > option file > Shell 持久化选项。
因此 URI 里写了 user@远端:3307 时,user / host / port 用命令行的;若命令行没给密码,仍可能继续用 ~/.my.cnf [client] 里的 password。
这很容易踩坑:本机为 localhost 配的密码,会「顺带」用到所有未显式提供密码的远程连接——只要远端账号口令碰巧相同,就会表现为「免输密码连上了」。
1 | # 排除 option file / login-path 后再连:若开始要密码,说明之前靠的是配置文件 |
1 | // 查当前 Store(不是全部密码来源) |
希望密码自动存进 Secret Store
默认 credentialStore.savePasswords 是 prompt(连成功后问你是否保存)。改成 always 即可全自动写入当前 Helper(macOS 默认钥匙串):
1 | \js |
1 | # 或启动时指定 |
1 | shell.listCredentials() // 应能看到刚存的 user@host:port |
| 选项值 | 行为 |
|---|---|
prompt |
默认;成功后询问是否保存 |
always |
自动保存(已被 Store 命中或命中 excludeFilters 的除外) |
never |
不保存;非交互 / --no-wizard 时也相当于 never |
1 | // 删除某条已存凭据 |
-
[client]里的password是全局默认,不要指望它「只对 localhost 生效」。 -
远端实例建议用 Secret Store / login-path 按
user@host:port分别保存,而不是把同一份密码写进~/.my.cnf[client]。 -
listCredentials()为空 ≠ 没有自动填密;先查~/.my.cnf,再用--no-defaults对照。 -
Store 与
~/.my.cnf是两套机制:自动存进钥匙串后,仍可能被 option file 里的password抢先使用——排查时记得加--no-defaults。
4. 三种语言模式与常用 \ 命令
\ 开头的命令与当前语言无关,随时可用。
| 命令 | 作用 |
|---|---|
\sql / \js / \py |
切换到 SQL / JavaScript / Python |
\connect \c |
连接实例 |
\status \s |
看当前连接、协议、版本等 |
\use \u |
切换默认 schema |
\source \. |
按当前模式执行脚本文件 |
\help \h \? |
查帮助(可搜 dba、util、SQL 语法) |
\history |
查看/删除历史;跨会话保存需开 history.autoSave |
\rehash |
手动刷新自动补全用的名称缓存 |
\option |
查/改 Shell 配置(会话级或持久化) |
\show / \watch |
运行内置或自定义 report |
\system \! |
执行操作系统命令 |
\quit \q |
退出 |
1 | MySQL localhost:3306 SQL > \js |
从 MySQL Shell 8.4 起,默认启动模式是 SQL。
凡是要跑 util.* / dba.*,要么启动加 --js / --py,要么进壳后再 \js / \py。只写 -e "util...." 而不加 --js,会按 SQL 解析而失败。
4.1 代码自动补全(Tab)
mysqlsh 的「代码提示」是 按 Tab 补全,不是 IDE 那种边输入边弹浮层。默认开启。
| 模式 | 能补什么 |
|---|---|
| 任意模式 | \connect 等 \ 命令(如 \con + Tab → \connect) |
| SQL | 关键字、库/表/列/视图/存储过程等(表列等依赖当前 schema) |
| JS / Python | session、util、dba、shell 等全局对象及其成员、链式调用;X Protocol 会话还可补全 db |
用法:
-
先连上实例;需要表名/列名时先
\use your_db -
输入前缀后按 Tab;候选多个时再按一次列出;唯一匹配则直接补全
-
本会话新建了对象,或缓存不对时执行
\rehash
1 | SQL > SE<Tab><Tab> → 列出 SET / SELECT 等 |
若 Tab 完全没反应,检查名称缓存是否被关掉:
1 | \js |
重新打开并持久化:
1 | shell.options.setPersist('autocomplete.nameCache', true) |
-
启动时不要带
--no-name-cache/-A,否则补全名称缓存默认关闭,只能靠\rehash手动加载。 -
未
\use时,SQL 模式主要能补库名等全局对象,补不到「当前库」的表/列。 -
少数 IDE 内置终端会截获 Tab;可换系统 Terminal 验证。
5. 交互执行与批处理
1 | # 执行一句就退出 |
SQL 模式下,单独一行 \ 可进入多行输入,空行结束并执行。
6. 输出格式
文档:Output Formats。
| 方式 | 说明 |
|---|---|
| 交互默认 | 表格(table) |
| 批处理默认 | tab 分隔(tabbed) |
--table / --tabbed / --vertical |
启动时指定 |
--result-format=json 等 |
更细的结果集格式 |
--json |
整次会话输出都包成 JSON,方便被脚本解析 |
1 | mysqlsh user@host:3306 --sql --table -e "SELECT 1 AS n;" |
会话内可用 \option resultFormat table(或 tabbed / vertical / json)临时切换。
7. 全局对象一览
进入 JS / Python 后,最常用的是这些全局对象:
| 对象 | 用途 |
|---|---|
session |
当前全局连接;执行 SQL 可用 session.runSql(...)(Classic / X 脚本均可) |
db |
X Protocol 全局会话的当前 schema(需已指定默认库或执行 \use;Classic 会话没有此对象) |
shell |
Shell 自身:连接、状态、配置等 |
util |
运维工具集(本节重点) |
dba |
AdminAPI 入口(集群) |
mysql / mysqlx |
再建额外会话 |
1 | // JS 示例:与协议无关的 SQL 执行 |
8. 常用 Utilities(util)
文档总览:MySQL Shell Utilities。
util 只在 JS / Python 模式可用,SQL 模式没有。
8.1 升级检查:util.checkForServerUpgrade()
文档:Upgrade Checker。
升级前必跑;详细解读与 5.7→8.x 流程见 MySql--从Mysql5.7升级到Mysql8。
权限:账号至少要有 PROCESS、SELECT。
1 | # 检查当前全局会话连上的实例(目标版本默认对齐当前 Shell) |
也可列出将要执行的检查项:
1 | util.checkForServerUpgrade(null, {list: true, targetVersion: "8.4.0"}) |
8.2 逻辑备份与恢复:dump* / loadDump
这是日常替代 / 补充 mysqldump 的主力能力:
-
多线程并行、默认分块 + 压缩(如
.tsv.zst) -
可只导出 DDL 或只导出数据
-
默认一致性(
consistent: true),时间戳默认转 UTC -
支持本地目录,也可对接 OCI / S3 兼容 / Azure
-
loadDump可断点续传、边 dump 边 load(waitDumpTimeout)
1 | // 先 \js,并确保已连接到源库 |
恢复到目标实例(先连上目标库):
1 | # 目标侧通常需要允许 LOAD DATA LOCAL |
常用选项直觉:
| 选项 | 含义 |
|---|---|
threads |
并行度 |
compression |
压缩算法(默认通常已开启) |
consistent |
是否一致性快照(默认 true) |
excludeSchemas / includeTables 等 |
过滤对象 |
ddlOnly / dataOnly |
只要结构或只要数据 |
dryRun |
只检查不真正写文件 |
ocimds + compatibility |
迁云兼容检查与改写 |
-
dump/load 依赖全局会话拿连接信息,但真正干活时会自建多线程会话。
-
数据一致性对 InnoDB 有保证;MyISAM 等不要指望同等语义。
-
importTable与loadDump不同:前者导入「普通数据文件」;后者导入 Shell dump 产物(DDL + 分块数据 + 元数据)。
8.3 单表导出 / 并行导入:exportTable / importTable
适合「一张大表的文件级搬运」,比完整 dump 更轻。
1 | // 导出一张表到文件(可再配合 importTable) |
命令行集成示例:
1 | mysqlsh mysql://user@host:3306 -- util import-table /data/orders.tsv \ |
8.4 JSON 导入:util.importJSON()
把 JSON 文档导入 Collection(Document Store)或关系表。适合日志 / 埋点 / 半结构化数据。JSON 类型本身的存取与索引见 MySQL JSON 数据类型:存取、查询与索引速查。
该工具必须使用 X Protocol 连接,不能通过 Classic Protocol 执行。
源文件格式:按行 JSON(NDJSON,每行一个文档),例如:
1 | {"cid": 1001, "cname": "MySQL 基础", "user_id": 20001, "cstatus": "open"} |
| 目标 | 选项 | 要求 |
|---|---|---|
| Collection | collection: "name" |
Document Store;同 schema 下不能已有同名普通表,否则报 exists but is not a collection |
| 关系表 | table: "name"(可选 tableColumn) |
表须有 JSON 列;默认列名 doc。没有该列会报 Unknown column 'doc' |
1 | // 导入到 Collection |
导入关系表前,表结构需类似:
1 | CREATE TABLE events ( |
importJson 不会把 JSON 字段映射到 cid / cname 这类普通列。要进已有业务表,改用 util.importTable(CSV/TSV)或手写 INSERT。
8.5 诊断收集:util.debug.collectDiagnostics()
使用 MySQL root 账号连接后,可从实例收集诊断信息并打成 zip(TSV / YAML 等),便于工单或排障。还有 util.debug.collectHighLoadDiagnostics()、util.debug.collectSlowQueryDiagnostics() 等高负载 / 慢查询变体。
1 | util.debug.collectDiagnostics("/tmp/mysql_diag.zip") |
8.6 其它(按需)
| 函数 | 场景 |
|---|---|
util.copyInstance / copySchemas / copyTables |
实例间直接拷贝(不落本地 dump 也可) |
util.dumpBinlogs / loadBinlogs |
binlog 转储与加载 |
util.changePassword / upgradeAuthMethod |
改密、把账号迁到 caching_sha2_password |
9. AdminAPI(集群管理入口)
AdminAPI 通过 dba 全局对象管理:
-
InnoDB Cluster:Group Replication 高可用
-
InnoDB ClusterSet:跨地域容灾
-
InnoDB ReplicaSet:异步 GTID 复制集管理
1 | dba.checkInstanceConfiguration('root@node1:3306') |
完整搭建、切主、故障演练见 MySQL 8.4 InnoDB Cluster 的构建方法,此处不展开。
启动时也可:
1 | mysqlsh user@node1:3306 --cluster # 若已是 Cluster 成员,自动填充 cluster 全局变量 |
10. 命令行 API 集成(给脚本用)
文档:CLI Integration。
语法:
1 | mysqlsh [连接与 Shell 选项] -- <全局对象> <方法名> [位置参数] [--命名参数=值 ...] |
方法名在命令行里一般写成 kebab-case(checkForServerUpgrade → check-for-server-upgrade)。
1 | # 等价于 util.checkForServerUpgrade() |
不是所有 API 都适合 CLI:像 dba.getCluster() 这种「返回对象再链式调用」的,命令行集成支持有限,交互模式更合适。
11. 日常速查清单
1 | # 1) 连上并确认协议 / 版本 |
12. 常见坑
-
忘记切到 JS/Python:8.4+ 默认 SQL,
-e "util...."必须加--js或--py。 -
端口/协议搞错:X 默认 33060,没开 X Plugin 就用
mysql://host:3306或--mysql。 -
importTable连了 X Protocol:会失败;改用 Classic,并打开local_infile。 -
密码写进命令行:不安全;改用提示输入或 credential store。
-
~/.my.cnf[client]密码串用到远端:URI 只覆盖了主机端口,密码仍可能来自 option file;用--no-defaults可验证。详见 3.4。 -
listCredentials()为空却仍免密登录:Store 里没有,不代表~/.my.cnf/ login-path 没有。 -
dump 目录必须为空:目标目录已有文件会报错。
-
权限不足:dump 通常至少需要涉及库上的
SELECT、SHOW VIEW、TRIGGER、EVENT,以及一致性相关的RELOAD/LOCK TABLES/BACKUP_ADMIN等;缺REPLICATION CLIENT时仍可 dump,但元数据里可能没有 binlog 位点。 -
觉得没有代码提示:Shell 用的是 Tab 补全,不是 IDE 浮层;先
\use,再 Tab,必要时\rehash。详见 4.1。