在MySQL Shell8.0.17中引入了一个多线程CSV导入工具:util.importTable()。在使用之前需要先开启local_infile参数,下面就是一个简单的示例
 | 
 | 
更多关于util.importTable()的用法,可参考util.importTable
在此基础上,MySQL Shell8.0.21又引入了逻辑转储还原工具,具有易用性、高性能、集成性的特点,接下来将重点谈谈该工具。工具中包含:
- util.dumpInstance():转储整个数据库实例,包含用户
 - util.dumpSchemas():转储一组schema
 - util.loadDump():将转储数据加载到目标实例
 
MySQL Shell dump/load具有多种强大的功能:
- 多线程转储,将大表拆分chunk
 - 并行加载chunk,结合MySQL8.0.21中Disable redo_log提升加载性能
 - 加载时转储仍在进行中
 - 暂停和恢复加载
 - 内置压缩,可以选择zstd或gzip
 - 加载数据时延迟创建二级索引
 - 直接从OCI对象存储中进行转储和加载
 
测试案例
对于util.dumpSchemas()或util.dumpInstance()需要满足以下要求:
- 原实例和目标实例版本需要MySQL5.7或更高
 - 实例对象名或schema对象名字符集需要为latin或utf8
 - 转储程序会将不安全的数据类型(例如:文本形式存储的列)转换为base64,因此列的大小不能超过max_allowed_packet的0.74倍
 - 设置ocimds=true选项,确保与MySQL数据库服务的兼容性
 - 仅对innodb存储引擎的表保证数据一致性,所有表必须使用innodb存储引擎
 
 | 
 | 
| 选项 | 可选值 | 说明 | 
|---|---|---|
| dryRun | [true/false] | 显示转储内容的信息,以及有关 MySQL 数据库服务兼容性检查的结果,但不执行转储 | 
| osBucketName | [string] | 转储到Oracle Cloud时对象存储存储桶名称 | 
| osNamespace | [string] | 由对象存储存储存储桶命名的 Oracle Cloud命名空间 | 
| threads | [int] | 用于从 MySQL 实例转储数据的并行线程数 | 
| maxRate | [string] | 转储期间每个线程的数据读取吞吐量的最大字节数 | 
| showProgress | [true/false] | 显示转储的进度信息 | 
| compression | [string] | 转储使用的压缩格式,默认为ztsd | 
| excludeSchemas | [string] | 排除指定的schema | 
| excludeTables | [string] | 排除指定的table | 
| users | [true/false] | 转储包含用户及权限 | 
| events | [true/false] | 转储包含事件 | 
| routines | [true/false] | 转储包含函数和存储过程 | 
| triggers | [true/false] | 转储包含触发器 | 
| defaultCharacterSet | [string] | 转储使用的会话字符集 | 
| tzUtc | [true/false] | 在转储开始时将时区设置为UTC | 
| consistent | [true/false] | 在转储期间锁定实例进行备份,默认为true。通过FLUSH TABLE WITH READ LOCK进行全局锁定,转储会话设置RR隔离级别以及启动一致性快照事务,当所有会话启动事务后,释放全局读锁并启动备份锁进行转储 | 
| ddlOnly | [true/false] | 仅包括转储中转储项的DDL,并且不转储数据 | 
| dataOnly | [true/false] | 仅包括转储数据 | 
| chunking | [true/false] | 转储时将表拆分为多个chunk | 
| bytesPerChunk | [string] | 写入每个chunk数据文件的近似字节数 | 
| ocimds | [true/false] | 启用检查和修改与MySQL数据库服务兼容 | 
| compatibility | [force_innodb/strip_definers/strip_restricted_grants/strip_role_admin/strip_tablespaces] | 针对兼容性要求做出的要求,可设置多值。force_innodb为更改表为innodb;strip_definers为从视图、例程、事件和触发器中删除子句,以便使用默认定义器创建这些对象;strip_restricted_grants为从grant中删除指定权限;strip_role_admin为从grant语句中删除role_admin权限;strip_tablespaces为从grant语句中删除tablespace子句; | 
在导出的文件中,主要分为三种文件:json文件主要记录schema或表的的结构信息,例如:schema下的表,视图等对象,表下面的字段,主键,触发器等;sql文件主要为对象的创建语句;tsv.zst和tsv.zst.idx主要为表数据以及索引
在通过util.loadDump()加载转储数据时,可以选择导入或排除单个表或schema,默认情况下,用户及其权限不导入,可以手动选择导入。
加载支持暂停和恢复,加载进度存放在持久化文件中,记录了成功完成的步骤和中断或失败的步骤,加载程序在恢复或重试导入时引用进度状态文件,并跳过已完成的步骤,对于已加载的表,将自动消除重复数据。第一次按ctrl+C,不会启动新任务,但当前任务依旧在执行,再按Ctrl+C再次停止现有任务,出现错误信息
 | 
 | 
转储的DDL由单个线程执行,数据则按指定线程数并行加载,如果拆分了chunk则可以使用多个线程处理表,否则每个线程一次只能加载一张表。为了进一步加快加载速度,我们可以设置延迟创建索引,MySQL8.0还支持disable redo_log(非生产环境)
 | 
 | 
| 选项 | 可选值 | 描述 | 
|---|---|---|
| progressFile | [string] | 转储加载的进度状态文件的本地文件位置,它保留导入的进度状态 | 
| resetProgress | [true/false] | 设置此选项以重置进度状态,然后从头开始再次启动导入 | 
| waitDumpTimeout | [int] | 通过指定一个超时(以秒为单位)来激活并发加载,该超时在转储位置中的所有上载数据块都已处理后,加载将等待进一步的数据,这允许实用程序在转储仍在创建过程中导入转储 | 
| ignoreExistingObjects | [true/false] | 忽略已经存在的对象,仅报告重复对象,不产生错误 | 
| ignoreVersion | [true/false] | 忽略转储和加载的MySQL版本不一致的情况 | 
| skipBinlog | [true/false] | 跳过目标 MySQL 实例上在导入过程中使用的会话的二进制日志记录 | 
| loadIndexes | [true/false] | 创建二级索引,当需要在加载 DDL 文件后对表结构进行更改可以设置该参数,后续再通过再次运行转储加载来创建索引 | 
| deferTableIndexes | [true/false] | 将辅助索引的创建推迟到加载表数据之后 | 
| analyzeTables | [true/false] | 加载表后分析表 | 
| characterSet | [string] | 用于导入目标 MySQL 实例的字符集 | 
| excludeSchemas | [array] | 从导入中排除指定的schema | 
| includeSchemas | [array] | 仅从转储文件加载指定schema | 
| excludeTables | [array] | 从导入中排除指定表 | 
| includeTables | [array] | 仅从转储文件加载指定表 | 
| loadDdl | [true/false] | 仅从转储导入 DDL 文件 | 
| loadData | [true/false] | 仅从转储导入数据文件 | 
| loadUsers | [true/false] | 导入用于及权限 | 
加载不会在目标MySQL应用源MySQL的gtid_executed中的GTID集,在加载之后,使用下列MySQL Shell命令从转储文件元数据复制GTID集:
\sql SET @@GLOBAL.gtid_purged= "+gtidExecuted_set";MySQL5.7需要忽略加号并且gtid_executed GTID设置必须为空
性能比较
DUMP

LOAD

上述测试结果来源于Benchmark Results,其中MySQL Shell的表现非常好,在大多数场景下都取得了不错的成绩
更多内容可参考以下链接: 1、MySQL Shell Dump & Load 2、Instance Dump Utility and Schema Dump Utility