简介
MySQL Shell的导入程序util.loadDump(url[, options])
,在MySQL Shell 8.0.21中引入,支持导入MySQL并行导入数据、进度状态跟踪、恢复和重置功能。
备注:
- 导入工具使用的是
LOAD DATA LOCAL INFILE
语法,所以需要设置local_infile
参数为ON,设置方式:set global local_infile=ON;
sql_require_primary_key
系统变量如果ON,且导入的表中存在没有主键的表,则导入会报错,默认这个值为OFF,查看方式:show variables like 'sql_require_primary_key';
- 导入程序不会将源MySQL实例中的gtid_executed GTID集应用到目标MySQL实例上。如果要在目标MySQL实例上保留这些gtid以供复制使用,请将转储加载实用程序的skipBinlog选项设置为true,以便在导入时防止生成新的gtid。导入之后,使用主gtid_executed更新目标MySQL实例上的gtid_purged GTID集,设置方式为:
\sql SET @@GLOBAL.gtid_purged= "+*gtidExecuted_set*";
MySQL Shell的util.loadDump(url[, options])
使用通过util.dumpInstance()
和util.dumpSchemas()
导出的ddl文件以及.tsv
的数据文件,然后在目标MySQL实例中设置服务器Instance或Schema,然后加载数据。
- 可以选择要导入或从导入中排除的单个表或schema。
- 用户以及角色的授权默认不会导入
- 可以为目标MySQL实例中的数据指定与备份文件中不同的字符集。
- 即使已经加载了数据,也可以更新
ANALYZE TABLE
直方图。 - 导入时可以选择跳过binlog,需要设置
SET sql_log_bin=0
导入的过程是存储在持久化文件中的,记录了整体成功/失败的进度,这个文件默认是备份目录下的loadprogress.server_uuid.json
,也可以配置不同的目录以及文件名,在恢复或重试导入时,导入程序会引用进度状态文件,并跳过完成的步骤。对部分加载的表自动管理重复数据删除。如果您使用Ctrl + C
中断正在进行的转储,那么在第一次使用该组合键时,该导入程序不会启动新的任务,但现有的任务会继续执行。再次按下Ctrl + C
将停止现有的任务,并产生错误信息。在这两种情况下,实用程序仍然可以从停止导入的地方恢复导入。
可以选择重置进度状态,并重新导入,但是在这种情况下,导入程序不会跳过已经创建的对象,也不会删除重复数据。如果重新导入,为了确保正确的导入,必须手动从目标MySQL实例中删除所有之前导入的对象,包括schema、表、用户、视图、触发器、例程和事件。否则,如果导入的文件中的对象已经存在于目标MySQL实例中,导入将停止并出现错误。在适当的注意下,您可以使用ignoreExistingObjects选项来让导入程序报告重复的对象,但是跳过会它们并继续导入。请注意,该导入程序不会检查目标MySQL实例中的对象内容和转储文件中的对象内容是否不同,因此结果导入可能包含不正确或无效的数据。
DDL文件的加载是单线程的,后续的导入数据操作才是并行的。为了进一步提高数据加载性能,从MySQL 8.0.21开始,你可以在导入过程中在目标MySQL实例上禁用InnoDB重做日志。注意,这应该只在新的MySQL服务器实例(而不是生产系统)上执行
示例
恢复单schema
# mysqlsh连接目标实例
# mysqlsh 127.0.0.1:3306
# /tmp/sbtest是使用util.dumpSchemas()导出的
# 开启local_infile参数;
MySQL 127.0.0.1:3306 JS > \sql set global local_infile=ON;
# 为了加快可以临时关闭redo log
MySQL 127.0.0.1:3306 JS > \sql ALTER INSTANCE DISABLE INNODB REDO_LOG;
# 查看redo log是否关闭成功
MySQL 127.0.0.1:3306 JS > \sql SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
# 使用util.loadDump()导入数据,并行度为4
MySQL 127.0.0.1:3306 JS > util.loadDump("/tmp/sbtest", {"threads": 4})
# 如果需要重置导入进程可以使用util.loadDump("/tmp/sbtest", {"threads": 4,resetProgress:true})
# 打开redo log
MySQL 127.0.0.1:3306 JS > \sql ALTER INSTANCE ENABLE INNODB REDO_LOG;
# # 查看redo log是否开启成功
MySQL 127.0.0.1:3306 JS > \sql SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
恢复实例也是一样的操作,大同小异。其中redo log的关闭非必要操作,只是能更快执行完成
参考文档
- https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-load-dump.html