在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