暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL Shell 工具

原创 谭磊Terry 恩墨学院 2022-08-02
3490

MySQL Shell介绍

什么是 MySQL Shell

MyySQL Shell 是 MySQL 的一个高级客户端和代码编辑器,是第二代 MySQL 客户端。第一代 MySQL 客户端即我们常用的 mysql。

相比于 mysql,MySQL Shell 不仅支持 SQL,还具有以下关键特性:

  1. 支持 Python 和 JavaScript 两种语言模式。基于此,我们可以很容易地进行一些脚本开发工作。
  2. 支持 AdminAPI。AdminAPI 可用来管理 InnoDB Cluster、InnoDB ClusterSet 和 InnoDB ReplicaSet。
  3. 支持 X DevAPI。X DevAPI 可对文档( Document )和表( Table )进行 CRUD(Create,Read,Update,Delete)操作。

除此之外,MySQL Shell 还内置了很多实用工具,包括:

  • checkForServerUpgrade:检测目标实例能否升级到指定版本。
  • dumpInstance:备份实例。 dumpSchemas:备份指定库。
  • dumpTables:备份指定表。
  • loadDump:恢复通过上面三个工具生成的备份。
  • exportTable:将指定的表导出到文本文件中。只支持单表,效果同
  • SELECT INTO OUTFILE 一样。
  • importTable:将指定文本的数据导入到表中。
    • 在线上,如果我们有个大文件需要导入,建议使用这个工具。它会将单个文件进行拆分,然后多线程并行执行 LOAD DATA LOCAL INFILE 操作。不仅提升了导入速度,还规避了大事务的问题
  • importJson:将 JSON 格式的数据导入到 MySQL 中,譬如将 MongoDB 中通过 mongoexport 导出的数据导入到 MySQL 中。

MySQL Shell

下载地址:https://dev.mysql.com/downloads/shell/

支持各种系统的安装,同 MySQL 一样,提供了多个版本的下载。这里使用 Linux 二进制版本( Linux - Generic )。

wget https://dev.mysql.com/get/Downloads/MySQL-Shell/mysql-shell-8.0.29-linux-glibc2.12-x86-64bit.tar.gz 
tar xvf mysql-shell-8.0.29-linux-glibc2.12-x86-64bit.tar.gz -C /usr/local/ 
ln -s /usr/local/mysql-shell-8.0.29-linux-glibc2.12-x86-64bit /usr/local/mysql-shell export PATH=$PATH:/usr/local/mysql-shell/bin   

echo "export PATH=$PATH:/usr/local/mysql-shell/bin" >> /root/.bashrc 
source /root/.bashrc   

[root@docker35 local]# mysqlsh --help 
MySQL Shell 8.0.29

Usage examples: 
$ mysqlsh root@localhost/schema
$ mysqlsh mysqlx://root@some.server:3307/world_x
$ mysqlsh --uri root@localhost --py -f sample.py sample param 
$ mysqlsh root@targethost:33070 -s world_x -f sample.js 
$ mysqlsh -- util check-for-server-upgrade root@localhost --output-format=JSON 
$ mysqlsh mysqlx://user@host/db --import ~/products.json shop

MySQL shell模块对象

MySQL shell 中模块对象众多,使用也比较复杂,我当前关注的是 dba、AdminAPI、mysqlx、X DevAPI、mysql 这几个模块、API,足够我用来创建管理 InnoDB Cluster、ReplicaSet、文档型数据就行,下面分别介绍。

全局对象

Shell 启动时,可以使用以下模块和对象:

  • dba:用于InnoDB Cluster、ReplicaSet 管理;
  • mysql:支持使用经典 MySQL 协议连接到 MySQL 服务器,允许执行 SQL;
  • mysqlx:用于通过 MySQL X DevAPI 处理 X 协议会话;
  • os:允许访问允许与操作系统交互的功能;
  • session:代表当前打开的MySQL会话;
  • shell:允许访问通用功能和属性; sys:允许访问系统特定的参数;
  • util:对诸如升级检查器和JSON导入之类的各种工具进行了分组。

AdminAPI

简单的说 AdminAPI 提供管理 InnoDB cluster、InnoDB ReplicaSet 的功能,包含 dba、Cluster、ReplicaSet 对象。使用 \help 命令查看如何使用:

JS > \help AdminAPI 
... 
For more information about the dba object use: \? dba 
In the AdminAPI, an InnoDB cluster is represented as an instance of the Cluster class, while replicasets are represented as an instance of the ReplicaSet class. 
For more information about the Cluster class use: \? Cluster 
For more information about the ReplicaSet class use: \? ReplicaSet ...

就像帮助信息里说的,可以分别再用 \help xxx 方式查看更具体的帮助文档:

JS > \help dba 
JS > \help Cluster 
JS > \help ReplicaSet

如果要看以上每个对象、类的命令列表,可以用通配符,比如列出所有 dba 对象的命令:

JS > \help dba*
Found several entries matching dba*   
The following topics were found at the AdminAPI category:  
- dba 
- dba.checkInstanceConfiguration 
- dba.configureInstance 
- dba.configureLocalInstance 
- dba.configureReplicaSetInstance 
- dba.createCluster 
- dba.createReplicaSet 
- dba.deleteSandboxInstance 
- dba.deploySandboxInstance 
- dba.dropMetadataSchema 
- dba.getCluster 
- dba.getReplicaSet 
- dba.help 
- dba.killSandboxInstance 
- dba.rebootClusterFromCompleteOutage 
- dba.startSandboxInstance 
- dba.stopSandboxInstance
- dba.upgradeMetadata 
- dba.verbose  

For help on a specific topic use: \?  

e.g.: \? dba

如果要更详细的某个命令的帮助手册,则可以 \help 后接具体的命令:

JS > \help dba.createCluster 

可以看出 dba 对象命令可以创建 Innodb Cluster、ReplicaSet。

创建后,dba.getCluster() 和 dba.getReplicaSet() 获取管理对象,然后 Cluster、ReplicaSet 对象提供具体的管理 Innodb Cluster、ReplicaSet 的命令,可以用 \help 命令简单查看:

JS > \help Cluster* 
Found several entries matching Cluster*   

The following topics were found at the AdminAPI category:   
- Cluster 
- Cluster.addInstance 
- Cluster.checkInstanceState 
- Cluster.describe 
- ... 
JS > \help Replica* 
Found several entries matching Replica*   

The following topics were found at the AdminAPI category:   
- ReplicaSet 
- ReplicaSet.addInstance 
- ReplicaSet.disconnect 
- ReplicaSet.forcePrimaryInstance 
- ReplicaSet.getName ...

X DevAPI

X DevAPI 是 mysqlx 模块上包含的函数和类的集合,当 mysql shell 启动时,该模块会自动加载。要使用X DevAPI,必须:

  1. MySQL Server 启用 X Protocol
  2. 连接到 X Protocol 定义的端口

X DevAPI 的简化了将 MySQL 作为文档型数据库存取数据的使用,功能有: 1. 与启用X协议的MySQL服务器建立会话
2. 管理 schema
3. 管理集合
4. 对集合(文档型数据)和表(关系型数据)的CRUD操作

使用 \help 可以查看:

JS > \help X DevAPI 
... To work on a MySQL Server with the X DevAPI, start by creating a session using: 
mysqlx.getSession(...).   

For more details about the mysqlx module use: \? mysqlx  

For more details about how to create a session with the X DevAPI use: \? 
...   

JS > \help mysqlx 
... 
CLASSES 
- BaseResult       Base class for the different types of results returned by the server. 
- Collection       A Collection is a container that may be used to store Documents in a MySQL database. 
- CollectionAdd    Operation to insert documents into a Collection. 
- CollectionFind   Operation to retrieve documents from a Collection. ... 
- Table            Represents a Table on an Schema, retrieved with a session created using mysqlx module. 
- TableDelete      Operation to delete data from a table. 
- TableInsert      Operation to insert data into a table. 
...

mysql模块

mysql 模块支持使用经典 MySQL 协议连接到 MySQL 服务器,允许执行 SQL(切换到 SQL 模式)。

比如可以用 help 查看 SQL 命令使用方式:

JS > \help SQL Syntax/SELECT 
Syntax: SELECT     
    [ALL | DISTINCT | DISTINCTROW ]       
    [HIGH_PRIORITY]       
    [STRAIGHT_JOIN]       
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]       [SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]    
    select_expr [, select_expr ...] ...    

切换到 SQL 模式,可以执行所有 SQL 命令:

JS > \sql 
Switching to SQL mode... Commands end with ; 
MySQL  172.16.22.2:3306 ssl  SQL > show databases;
+-------------------------------+ 
|        Database               | 
+-------------------------------+ 
| hucq                          | 
| information_schema            | 
| mysql                         | 
| mysql_innodb_cluster_metadata | 
| mysqlslap                     | 
| performance_schema            | 
| sys                           | 
| world_x                       | 
+-------------------------------+ 
8 rows in set (0.0041 sec)

MySQL Shell基本使用

-- 连接 MySQL 
mysqlsh -uroot -plhr -h192.168.1.35 -P3415 
mysqlsh root:lhr@192.168.1.35:3415 
mysqlsh 
\connect --mysql root:lhr@192.168.1.35:3415 
\connect --mc root:lhr@192.168.1.35:3415   

-- 退出 
\q 
\exit 
\quit   

-- 其它命令
\sql show databases; 
-- 切换到sql模式就可以执行sql命令了
\sql

image.png

常用命令

命令 描述
shell.connect(‘root@172.16.9.51:3306’) 连接到实例
var cluster = dba.getCluster() 定义集群信息
cluster.status(); 查看集群状态

配置命令

命令 描述
dba.getCluster(); 查看集群名
cluster.status(); 查看集群状态
dba.checkInstanceConfiguration(‘root@172.16.9.52:3306’) 检查节点状态是否正常
dba.configureLocalInstance(); 检查/etc/my.cnf是否正常
var cluster = dba.createCluster(‘myCluster’); 创建一个名为myCluster的集群
dba.createCluster(‘st’); 创建一个名字为st的集群
cluster.addInstance(‘root@oratest52:3306’); 集群添加节点

通用命令

命令 别名/快捷方式 描述
\help \h or ? 打印有关MySQL Shell的帮助,或搜索联机帮助。
\quit \q or \exit 退出MySQL Shell
\ 在SQL模式下,开始多行模式。输入空行时缓存并执行代码
\status \s 显示当前的MySQL Shell状态
\js 将执行模式切换为JavaScript
\py 将执行模式切换为Python
\sql 将执行模式切换为SQL
\connect \c 连接到MySQL服务器
\reconnect 重新连接到同一个MySQL服务器
\use \u 指定要使用的架构
\source . 使用活动语言执行脚本文件
\warnings \W 显示语句生成的任何警告
\nowarnings \w 不要显示语句生成的任何警告
\history 查看和编辑命令行历史记录
\rehash 手动更新自动完成名称缓存
\option 查询和更改MySQL Shell配置选项
\show 使用提供的选项和参数运行指定的报告
\watch 使用提供的选项和参数运行指定的报告,并定期刷新结果

MySQL Shell Dump & Load 的使用

mysqldump 和 mydumper 是我们常用的两个逻辑备份工具。

无论是 mysqldump 还是 mydumper 都是将备份数据通过 INSERT 的方式写入到备份文件中。

恢复时,myloader( mydumper 中的恢复工具 ) 是多线程导入,且一个 INSERT 语句中包含多条记录,多个 INSERT 操作批量提交。基本上,凡是我们能想到的,有助于提升导入速度的,myloader 都会使用或有选项提供。 单就恢复速度而言,可以说,myloader 就是逻辑恢复工具的天花板。

既然如此,还有办法能继续提升逻辑恢复工具的恢复速度么?毕竟,备份的恢复速度直接影响着灾难发生时数据库服务的 RTO。

答案,有! 这个就是官方在 MySQL Shell 8.0.21 中推出的 Dump & Load 工具,该工具是官方出品,比 mydumper 更快的逻辑备份工具。

与 myloader 不一样的是,MySQL Shell Load 是通过 LOAD DATA LOCAL INFILE 命令来导入数据的。 而 LOAD DATA 操作,按照官方文档的说法,比 INSERT 操作快 20 倍。

MySQL Shell 8.0.21 包括一些新的易用、高性能和集成的工具(MySQL Shell Dump & Dump Loading Utility)用来创建逻辑转储和执行逻辑还原。该序列工具以 MySQL Shell 8.0.17 中引入的多线程 CSV 导入工具 util.importTable() 为基础构建以便轻松转储和加载整个数据库实例或一组 schema。该序列工具包括:

  • util.dumpInstance():备份整个数据库实例,包括用户
  • util.dumpSchemas():备份指定数据库 schema
  • util.dumpTables():备份指定的表或视图
  • util.loadDump():恢复备份

util.dumpInstance(outputUrl[, options])

备份实例。其中,outputUrl 是备份目录,不能为空。options 是可指定的选项。

首先,看一个简单的示例。

# mysqlsh -h 10.0.20.4 -P3306 -uroot -p mysql-js> util.dumpInstance('/data/backup/full',{compression: "none"}) 
Acquiring global read lock 
Global read lock acquired 
Initializing - done 
1 out of 5 schemas will be dumped and within them 1 table, 0 views. 
4 out of 7 users will be dumped. 
Gathering information - done 
All transactions have been started 
Locking instance for backup 
Global read lock has been released 
Writing global DDL files 
Writing users DDL 
Running data dump using 4 threads. 
NOTE: Progress information uses estimated values and may not be accurate. 
Writing schema metadata - done 
Writing DDL - done 
Writing table metadata - done 
Starting data dump 
101% (650.00K rows / ~639.07K rows), 337.30K rows/s, 65.89 MB/s 
Dump duration: 00:00:01s 
Total duration: 00:00:01s 
Schemas dumped: 1 
Tables dumped: 1 
Data size: 126.57 MB 
Rows written: 650000 
Bytes written: 126.57 MB 
Average throughput: 65.30 MB/s

命令中的 /data/backup/full 是备份目录,目标必须为空,compression: “none” 指的是不压缩,这里设置为不压缩主要是为了方便查看数据文件的内容。线上使用建议开启压缩。 接下来我们看看备份目录中的内容。

# ll /data/backup/full/ 
total 123652 
-rw-r----- 1 root root      273 May 25 21:13 @.done.json 
-rw-r----- 1 root root      854 May 25 21:13 @.json 
-rw-r----- 1 root root      240 May 25 21:13 @.post.sql 
-rw-r----- 1 root root      288 May 25 21:13 sbtest.json 
-rw-r----- 1 root root 63227502 May 25 21:13 sbtest@sbtest1@0.tsv 
-rw-r----- 1 root root      488 May 25 21:13 sbtest@sbtest1@0.tsv.idx 
-rw-r----- 1 root root 63339214 May 25 21:13 sbtest@sbtest1@@1.tsv 
-rw-r----- 1 root root      488 May 25 21:13 sbtest@sbtest1@@1.tsv.idx 
-rw-r----- 1 root root      633 May 25 21:13 sbtest@sbtest1.json 
-rw-r----- 1 root root      759 May 25 21:13 sbtest@sbtest1.sql 
-rw-r----- 1 root root      535 May 25 21:13 sbtest.sql 
-rw-r----- 1 root root      240 May 25 21:13 @.sql 
-rw-r----- 1 root root     6045 May 25 21:13 @.users.sql

其中,

  • @.done.json:会记录备份的结束时间,备份集的大小。备份结束时生成。
  • @.json:会记录备份的一些元数据信息,包括备份时的一致性位置点信息:binlogFile,binlogPosition 和 gtidExecuted,这些信息可用来建立复制。
  • @.sql,@.post.sql:这两个文件只有一些注释信息。不过在通过 util.loadDump 导入数据时,我们可以通过这两个文件自定义一些 SQL。其中,@.sql 是数据导入前执行,@.post.sql 是数据导入后执行。
  • sbtest.json:记录 sbtest 中已经备份的表、视图、定时器、函数和存储过程。
  • *.tsv:数据文件。我们看看数据文件的内容。
# head -2 sbtest@sbtest1@0.tsv 
1 6461363 68487932199-96439406143-93774651418-41631865787-96406072701-20604855487-25459966574-28203206787-41238978918-19503783441 22195207048-70116052123-74140395089-76317954521-98694025897 
2 1112248 13241531885-45658403807-79170748828-69419634012-13605813761-77983377181-01582588137-21344716829-87370944992-02457486289 28733802923-10548894641-11867531929-71265603657-36546888392

TSV 格式,每一行储存一条记录,字段与字段之间用制表符(\t)分隔。

  • sbtest@sbtest1.json:记录了表相关的一些元数据信息,如列名,字段之间的分隔符(fieldsTerminatedBy)等。
  • sbtest@sbtest1.sql:sbtest.sbtest1 的建表语句。
  • sbtest.sql:建库语句。如果这个库中存在存储过程、函数、定时器,也是写到这个文件中。
  • @.users.sql:创建账号及授权语句。默认不会备份 mysql.session,mysql.session,mysql.sys 这三个内部账号。

若mysqlsh在Windows平台,如下:

MySQL  192.168.1.35:3417 ssl  JS > util.dumpInstance('d\:\\tmp',{compression: "none"})
NOTE: Backup lock is not supported in MySQL 5.7 and DDL changes will not be blocked. The dump may fail with an error if schema changes are made while dumping. 
Acquiring global read lock 
Global read lock acquired 
Initializing - done 
3 out of 7 schemas will be dumped and within them 19 tables, 0 views. 
3 out of 5 users will be dumped. 
Gathering information - done 
All transactions have been started 
Global read lock has been released 
Writing global DDL files Writing users DDL
NOTE: Could not select columns to be used as an index for table `lhrdb`.`test`. Chunking has been disabled for this table, data will be dumped to a single file. 
Running data dump using 4 threads. 
NOTE: Progress information uses estimated values and may not be accurate. 
NOTE: Table statistics not available for `canal_manager`.`canal_cluster`, chunking operation may be not optimal. Please consider running 'ANALYZE TABLE `canal_manager`.`canal_cluster`;' first. 
NOTE: Table statistics not available for `canal_manager`.`canal_user`, chunking operation may be not optimal. Please consider running 'ANALYZE TABLE `canal_manager`.`canal_user`;' first. 
Writing schema metadata - done 
Writing DDL - done 
Writing table metadata - done 
Starting data dump 101% (1.00M rows / ~987.14K rows), 68.90K rows/s, 13.41 MB/s 
Dump duration: 00:00:12s 
Total duration: 00:00:12s
Schemas dumped: 3 
Tables dumped: 19 
Data size: 191.91 MB 
Rows written: 1000024 Bytes written: 191.91 MB
Average throughput: 15.27 MB/s

util.dumpSchemas(schemas, outputUrl[, options])

备份指定库的数据。

用法同 util.dumpInstance 类似。其中,第一个参数必须为数组,即使只需备份一个库,如,

util.dumpSchemas(['sbtest'],'/data/backup/schema')

支持的配置大部分与 util.dumpInstance 相同。

从 MySQL Shell 8.0.28 开始,可直接使用 util.dumpInstance 中的 includeSchemas 选项进行指定库的备份。

示例:

MySQL 192.168.1.35:3417 ssl JS > util.dumpSchemas(['sbtest'],'d\:\\tmp')
NOTE: Backup lock is not supported in MySQL 5.7 and DDL changes will not be blocked. The dump may fail with an error if schema changes are made while dumping. 
Acquiring global read lock 
Global read lock acquired 
Initializing - done 
1 schemas will be dumped and within them 11 tables, 0 views. 
Gathering information - done 
All transactions have been started 
Global read lock has been released 
Writing global DDL files 
Running data dump using 4 threads. 
NOTE: Progress information uses estimated values and may not be accurate. 
Writing schema metadata - done 
Writing DDL - done 
Writing table metadata - done 
Starting data dump 101% (1.00M rows / ~987.12K rows), 78.66K rows/s, 16.36 MB/s uncompressed, 7.47 MB/s compressed Dump 
duration: 00:00:14s 
Total duration: 00:00:15s 
Schemas dumped: 1 
Tables dumped: 11 
Uncompressed data size: 191.89 MB 
Compressed data size: 87.48 MB 
Compression ratio: 2.2 
Rows written: 1000002 Bytes written: 87.48 MB 
Average uncompressed throughput: 13.64 MB/s 
Average compressed throughput: 6.22 MB/s

util.dumpTables(schema, tables, outputUrl[, options])

备份指定表的数据。 用法同 util.dumpInstance 类似。其中,第二个参数必须为数组,如,

util.dumpTables('sbtest',['sbtest1'],'/data/backup/table')

支持的配置大部分与 util.dumpInstance 相同。 从 MySQL Shell 8.0.28 开始,可直接使用 util.dumpInstance 中的 includeTables 选项进行指定表的备份。

MySQL  192.168.1.35:3417 ssl  JS > util.dumpTables('sbtest',['sbtest1'],'d\:\\tmp') 
NOTE: Backup lock is not supported in MySQL 5.7 and DDL changes will not be blocked. The dump may fail with an error if schema changes are made while dumping. 
Acquiring global read lock 
Global read lock acquired 
Initializing - done 1 tables and 0 views will be dumped. 
Gathering information - done 
All transactions have been started 
Global read lock has been released 
Writing global DDL files 
Running data dump using 4 threads. 
NOTE: Progress information uses estimated values and may not be accurate. 
Writing schema metadata - done 
Writing DDL - done 
Writing table metadata - done 
Starting data dump 101% (100.00K rows / ~98.71K rows), 42.50K rows/s, 9.72 MB/s uncompressed, 4.43 MB/s compressed 
Dump duration: 00:00:02s 
Total duration: 00:00:02s
Schemas dumped: 1 
Tables dumped: 1 
Uncompressed data size: 19.19 MB Compressed data size: 8.75 MB Compression ratio: 2.2 
Rows written: 100000 
Bytes written: 8.75 MB 
Average uncompressed throughput: 9.14 MB/s 
Average compressed throughput: 4.16 MB/s 
MySQL  192.168.1.35:3417 ssl  JS >

util.loadDump(url[, options])

导入通过 dump 命令生成的备份集。如,

# mysqlsh -S /data/mysql/3307/data/mysql.sock 
mysql-js> util.loadDump("/data/backup/full",{loadUsers: true})
Loading DDL, Data and Users from '/data/backup/full' using 4 threads. 
Opening dump... 
Target is MySQL 8.0.27. Dump was produced from MySQL 8.0.27
Scanning metadata - done 
Checking for pre-existing objects... 
Executing common preamble SQL 
Executing DDL - done 
Executing view DDL - done 
Starting data load 2 thds loading - 100% (126.57 MB / 126.57 MB), 11.43 MB/s, 0 / 1 tables done 
Recreating indexes - done 
Executing user accounts SQL... 
NOTE: Skipping CREATE/ALTER USER statements for user 'root'@'localhost' 
NOTE: Skipping GRANT statements for user 'root'@'localhost' 
Executing common postamble SQL
2 chunks (650.00K rows, 126.57 MB) for 1 tables in 1 schemas were loaded in 10 sec (avg throughput 13.96 MB/s) 
0 warnings were reported during the load.

命令中的 /data/backup/full 是备份目录,loadUsers: true 是导入账号,默认不会导入。

util.dumpInstance 详细介绍

关键特性

util.dumpInstance 的关键特性如下:

  1. 多线程备份。并发线程数由 threads 决定,默认是 4。
  2. 支持单表 chunk 级别的并行备份,前提是表上存在主键或唯一索引。
  3. 默认是压缩备份。
  4. 支持备份限速。可通过 maxRate 限制单个线程的数据读取速率。

备份流程

19d59e4150f1fdaa09f9ac3596caf513_202205311128765.png

不难看出,util.dumpInstance 的备份流程与 mysqldump 大致相同,不同的地方主要体现在以下两点:

  1. util.dumpInstance 会加备份锁。备份锁可用来阻塞备份过程中的 DDL。
  2. util.dumpInstance 是并行备份,相对于 mysqldump 的单线程备份,备份效率更高。

参数解析

util.dumpInstance 的参数可分为如下几类:

过滤相关
  • 以下是过滤相关的选项。 excludeSchemas:忽略某些库的备份,多个库之间用逗号隔开,如,
excludeSchemas: ["db1", "db2"] 
  • includeSchemas:指定某些库的备份。
  • excludeTables:忽略某些表的备份,表必须是 schema.table 的格式,多个表之间用逗号隔开,如,
excludeTables: ["sbtest.sbtest1", "sbtest.sbtest2"]
  • includeTables:指定某些表的备份。
  • events:是否备份定时器,默认为 true。
  • excludeEvents:忽略某些定时器的备份。
  • includeEvents:指定某些定时器的备份。
  • routines:是否备份函数和存储过程,默认为 true。
  • excludeRoutines:忽略某些函数和存储过程的备份。
  • includeRoutines:指定某些函数和存储过程的备份。
  • users:是否备份账号信息,默认为 true。
  • excludeUsers:忽略某些账号的备份,可指定多个账号。
  • includeUsers:指定某些账号的备份,可指定多个账号。
  • triggers:是否备份触发器,默认为 true。
  • excludeTriggers:忽略某些触发器的备份。
  • includeTriggers:指定某些触发器的备份。
  • ddlOnly:是否只备份表结构,默认为 false。
  • dataOnly:是否只备份数据,默认为 false
并行备份相关
  • chunking:是否开启 chunk 级别的并行备份功能,默认为 true。
  • bytesPerChunk:每个 chunk 文件的大小,默认 64M。
  • threads:并发线程数,默认为 4。
OCI(甲骨文云)相关
  • ocimds:是否检查备份集与 MySQL Database Service(甲骨文云的 MySQL 云服务,简称 MDS )的兼容性,默认为false,不检查。如果设置为 true,会输出所有的不兼容项及解决方法。不兼容项可通过下面的 compatibility 来解决。
  • compatibility:如果要将备份数据导入到 MDS 中,为了保证与后者的兼容性,可在导出的过程中进行相应地调整。具体来说:
    • create_invisible_pks:对于没有主键的表,会创建一个隐藏主键:my_row_id BIGINT UNSIGNED AUTO_INCREMENT INVISIBLE PRIMARY KEY。隐藏列是 MySQL 8.0.23 引入的。
    • force_innodb:将表的引擎强制设置为 InnoDB。
    • ignore_missing_pks:忽略主键缺失导致的错误,与 create_invisible_pks 互斥,不能同时指定。
    • skip_invalid_accounts:忽略没有密码,或者使用了 MDS 不支持的认证插件的账号。
    • strip_definers:去掉视图、存储过程、函数、定时器、触发器中的 DEFINER=account 子句。
    • strip_restricted_grants:去掉 MDS 中不允许 GRANT 的权限。
    • strip_tablespaces:去掉建表语句中的 TABLESPACE=xxx 子句。
  • osBucketName,osNamespace,ociConfigFile,ociProfile,ociParManifest,ociParExpireTime:OCI 对象存储相关。
其它选项
  • tzUtc:是否设置 TIME_ZONE = ‘+00:00’,默认为 true。
  • consistent:是否开启一致性备份,默认为 true。若设置为 false,则不会加全局读锁,也不会开启事务的一致性快照。
  • dryRun:试运行。此时只会打印备份信息,不会执行备份操作。
  • maxRate:限制单个线程的数据读取速率,单位 byte,默认为 0,不限制。
  • showProgress:是否打印进度信息,如果是 TTY 设备(命令行终端),则为 true,反之,则为 false。
  • defaultCharacterSet:字符集,默认为 utf8mb4。
  • compression:备份文件的压缩算法,默认为 zstd。也可设置为 gzip 或 none(不压缩)。

util.loadDump

关键特性

util.loadDump 的关键特性如下:

  1. 多线程恢复。并发线程数由 threads 决定,默认是 4。
  2. 支持断点续传功能。
    • 在导入的过程中,会在备份目录生成一个进度文件,用于记录导入过程中的进度信息。 文件名由 progressFile 指定,默认是 load-progress…progress。
    • 导入时,如果备份目录中存在 progressFile,默认会从上次完成的地方继续执行。如果要从头开始执行,需将 resetProgress 设置为 true。
  3. 支持延迟创建二级索引。
  4. 支持边备份,边导入。
  5. 通过 LOAD DATA LOCAL INFILE 命令来导入数据。
  6. 如果单个文件过大,util.loadDump 在导入时会自动进行切割,以避免产生大事务。

参数解析

util.loadDump 的参数可分为如下几类:

过滤相关
  • excludeEvents:忽略某些定时器的导入。
  • excludeRoutines:忽略某些函数和存储过程的导入。
  • excludeSchemas:忽略某些库的导入。
  • excludeTables:忽略某些表的导入。
  • excludeTriggers:忽略某些触发器的导入。
  • excludeUsers:忽略某些账号的导入。
  • includeEvents:导入指定定时器。
  • includeRoutines:导入指定函数和存储过程。
  • includeSchemas:导入指定库。 includeTables:导入指定表。
  • includeTriggers:导入指定触发器。 includeUsers:导入指定账号。
  • loadData:是否导入数据,默认为 true。
  • loadDdl:是否导入 DDL 语句,默认为 true。
  • loadUsers:是否导入账号,默认为 false。注意,即使将 loadUsers 设置为 true,也不会导入当前正在执行导入操作的用户。
  • ignoreExistingObjects:是否忽略已经存在的对象,默认为 off。
并行导入相关
  • backgroundThreads:获取元数据和 DDL文件内容的线程数。备份集如果存储在本地,backgroundThreads 默认和 threads 一致。
  • threads:并发线程数,默认为 4。
  • maxBytesPerTransaction:指定单个 LOAD DATA 操作可加载的最大字节数。默认与 bytesPerChunk 一致。这个参数可用来规避大事务。
断点续传相关
  • progressFile:在导入的过程中,会在备份目录生成一个progressFile,用于记录加载过程中的进度信息,这个进度信息可用来实现断点续传功能。默认为 load-progress…progress。
  • resetProgress:如果备份目录中存在progressFile,默认会从上次完成的地方继续执行。如果要从头开始执行,需将 resetProgress 设置为 true。该参数默认为 off。
OCI 相关

osBucketName,osNamespace,ociConfigFile,ociProfile。

二级索引相关
  • deferTableIndexes:是否延迟(数据加载完毕后)创建二级索引。可设置:off(不延迟),fulltext(只延迟创建全文索引,默认值),all(延迟创建所有索引)。
  • loadIndexes:与 deferTableIndexes 一起使用,用来决定数据加载完毕后,最后的二级索引是否创建,默认为 true。
其它选项
  • analyzeTables:表加载完毕后,是否执行 ANALYZE TABLE 操作。默认是 off(不执行),也可设置为 on 或 histogram(只对有直方图信息的表执行)。
  • characterSet:字符集,无需显式设置,默认会从备份集中获取。
  • createInvisiblePKs:是否创建隐式主键,默认从备份集中获取。这个与备份时是否指定了
  • create_invisible_pks 有关,若指定了则为 true,反之为 false。 dryRun:试运行。
  • ignoreVersion:忽略 MySQL 的版本检测。默认情况下,要求备份实例和导入实例的大版本一致。
  • schema:将表导入到指定 schema 中,适用于通过 util.dumpTables 创建的备份。
  • showMetadata:导入时是否打印一致性备份时的位置点信息。
  • showProgress:是否打印进度信息。
  • skipBinlog:是否设置 sql_log_bin=0 ,默认 false。这一点与 mysqldump、mydumper 不同,后面这两个工具默认会禁用 Binlog。
  • updateGtidSet:更新 GTID_PURGED。可设置:off(不更新,默认值), replace(替代目标实例的 GTID_PURGED), append(追加)。
  • waitDumpTimeout:util.loadDump 可导入当前正在备份的备份集。处理完所有文件后,如果备份还没有结束(具体来说,是备份集中没有生成 @.done.json),util.loadDump 会报错退出,可指定 waitDumpTimeout 等待一段时间,单位秒。

MySQL Shell Dump & Load 的注意事项

  1. 表上存在主键或唯一索引才能进行 chunk 级别的并行备份。字段的数据类型不限。不像 mydumper,分片键只能是整数类型。
  2. 对于不能进行并行备份的表,目前会备份到一个文件中。如果该文件过大,不用担心大事务的问题,util.loadDump 在导入时会自动进行切割。
  3. util.dumpInstance 只能保证 InnoDB 表的备份一致性。
  4. 默认不会备份 information_schema,mysql,ndbinfo,performance_schema,sys。
  5. 备份实例支持 MySQL 5.6 及以上版本,导入实例支持 MySQL 5.7 及以上版本。
  6. 备份的过程中,会将 BLOB 等非文本安全的列转换为 Base64,由此会导致转换后的数据大小超过原数据。
  7. 导入时,注意 max_allowed_packet 的限制。 导入之前,需将目标实例的 local_infile 设置为 ON。
  8. 该工具属于客户端工具,生成的文件在客户端。
  9. 导出的时候,导出路径下不能有文件。

 

提高恢复的速度

很多时候提高逻辑备份的恢复速度采用的方法和提高MySQL实例的联机交易速度的方法一样。例如增加 InnoDB Buffer 的大小,增加 logfile 的大小。

禁用日志

禁用日志可以减少导入过程中的 IO,从而提高导入的速度,这里的禁用日志包括二进制日志、联机日志和 InnoDB 的 Double write。

1、禁用二进制日志

MySQL 8.0 二进制日志默认是激活的,但导出的文件通常有下面的语句禁用在导入过程中记录二进制日志。

SET @@SESSION.SQL_LOG_BIN=0;

如果导出的文件没有这样的语句,可以在实例启动时增加 –skip-log-bin–disable-log-bin 参数来禁止二进制日志

如果使用 source 执行加载的 SQL 语句,可以在执行之前禁用二进制日志,执行完成后打开二进制日志,例如:

mysql> set SQL_LOG_BIN=0;
mysql> source backup.sql;
mysql> set SQL_LOG_BIN=1;

2、禁用 InnoDB 的 Double Write

InnoDB 的 Double Write 机制是为了保证 InnoDB 的原子写二产生的,在数据导入过程中,为了提高效率,可以禁用 InnoDB 的 Double Write。通过设置系统参数 innodb_doublewrite 为 off 禁用 InnoDB 的 Double Write,如下所示:

mysql > set persist_only innodb_doublewrite = off;

系统参数 innodb_doublewrite 是静态参数,设置完成后需要重新启动 MySQL 实例,也可以在启动 MySQL 实例时使用参数 --skip-innodb-doublewrite 禁用 InnoDB 的 Double Write。注意,数据导入完成后要取消该设置。

3、禁用联机日志

在 MySQL 8.0.21 中新增了禁用联机日志的功能,同时会禁用 InnoDB 的 Double Write。禁用联机日志是实例级,不支持表级。启动这项功能的命令如下:

mysql>alter instance disable redo_log;

可以使用状态参数 Innodb_redo_log_enabled 检查联机日志的使用情况,相应 SQL 语句及运行结果如下:

mysql> show global status like 'Innodb_redo_log_enabled';

重新激活联机日志的命令如下:

mysql> alter instance enable innodb redo_log;

禁用联机日志时可以正常地关闭和重启实例,但在异常宕机的情况下,可能会导致数据丢失或页面损坏,禁用联机日志时,异常宕机的实例可能需要废弃重建。

对应压缩的备份集,不要再完成解压后再进行加载,应该在单个操作中同时完成解压和加载,这样会快很多:

$gzip -d back.sql.gz|mysql
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论