mydumper学习总结
0 简介
mydumper 是一款社区开源的逻辑备份工具。该工具主要由 C 语言编写,目前由 MySQL 、Facebook 等公司人员开发维护。
mydumper 最突出的特性就是可采用多线程并行备份,极大提高了数据导出的速度。
包含2个工具命令:
mydumper
负责导出 MySQL 数据库的一致备份myloader
从 mydumper 读取备份,连接到目标数据库并导入备份。
1 安装
1.1下载
下载地址:Releases · mydumper/mydumper (github.com),此网站有各个版本的安装包,目前最新版本是v0.14.0-2
可以先下载后传到服务器,也可以使用wget命令来直接下载。
wget https://github.com/mydumper/mydumper/releases/download/v0.14.0-2/mydumper-0.14.0-2.el7.x86_64.rpm
1.2安装
安装依赖:
# ubuntu yum install glib2-devel mysql-devel gcc gcc-c++ zlib-devel pcre-devel openssl-devel libicu-dev cmake -y # centos8 yum install glib2-devel mysql-devel gcc gcc-c++ zlib-devel pcre-devel openssl-devel cmake -y
安装rpm包
rpm -ivh mydumper-0.14.0-2.el7.x86_64.rpm
也可以直接安装线上版本
yum install wget https://github.com/mydumper/mydumper/releases/download/v0.14.0-2/mydumper-0.14.0-2.el7.x86_64.rpm
1.3卸载
[root@gip 3308]# yum list installed |grep mydumper mydumper.x86_64 0.14.0-2 installed [root@gip 3308]# yum remove mydumper.x86_64
2 使用
备份命令 mydumper
常用重要选项
Filter Options
-x, --regex Regular expression for 'db.table' matching -T, --tables-list Comma delimited table list to dump (does not exclude regex option). Table name must include database name.
-B, --database Database to dump
-O, --omit-from-file File containing a list of database.table entries to skip
Lock Options
-k, --no-locks Do not execute the temporary shared read lock. WARNING: This will cause inconsistent backups
--less-locking Minimize locking time on InnoDB tables.
If long query running found
-l, --long-query-guard Set long query timer in seconds, default 60,长查询超过该时间会报错。
-K, --kill-long-queries Kill long running queries (instead of aborting)
Job Options
-r, --rows Try to split tables into chunks of this many rows.
--split-partitions Dump partitions into separate files. This options overrides the --rows option for partitioned tables.
Objects Options
-m, --no-schemas Do not dump table schemas with the data and triggers
-d, --no-data Do not dump table data
-G, --triggers Dump triggers. By default, it do not dump triggers
-E, --events Dump events. By default, it do not dump events
-R, --routines Dump stored procedures and functions. By default, it do not dump stored procedures nor functions
--views-as-tables Export VIEWs as they were tables
-W, --no-views Do not dump VIEWs
Application Options:
-o, --outputdir Directory to output files to
--stream It will stream over STDOUT once the files has been written. Since v0.12.7-1, accepts NO_DELETE, NO_STREAM_AND_NO_DELETE and TRADITIONAL which is the default value
-L, --logfile Log file name to use, by default stdout is used
--disk-limits Set the limit to pause and resume if determines there is no enough disk space.Accepts values like: '<resume>:<pause>' in MB.For instance: 100:500 will pause when there is only 100MB free and willresume if 500MB are available
-t, --threads Number of threads to use, default 4
导出后文件命名规则大致如下:
dbname-schema-create.sql:建库语句。 dbname-schema-post.sql:包含事件、存储过程及函数创建语句(若存在则有该文件)。 dbname.tbname.metadata:记录这个表的行数。 dbname.tbname-schema.sql:此表的创建语句。 dbname.tbname-schema-triggers.sql:创建触发器语句(若该表存在触发器 则有此文件)。 dbname.tbname.sql:该表的插入数据语句(若该表为空 则不存在此文件)。 dbname.viewname-schema.sql:创建视图语句(只列举出视图字段)。 dbname.viewname-schema-view.sql:创建视图的真正语句。 metadata:记录开始及结束备份的时间以及二进制日志位置。
使用举例:
备份指定表(test.tt1,test.tt2) (-T) mydumper -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -T test.tt1,test.tt2 --long-query-guard=1000 -o /mysql/backup/3308 备份指定库(benchmark,test) (-B) mydumper -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 8 -B benchmark,test --long-query-guard=1000 -o /mysql/backup/3308 备份时拆分大表 (-r 200000 指定大表按200000行进行拆分) mydumper -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 8 -B benchmark,test -r 200000 --long-query-guard=1000 -o /mysql/backup/3308 备份表结构(-d) mydumper -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 8 -B benchmark,test -d --long-query-guard=1000 -o /mysql/backup/3308 备份表数据,不带表结构 (-m) mydumper -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 8 -B benchmark,test -m --long-query-guard=1000 -o /mysql/backup/3308 备份整个实例(分两步:先备份用户权限,再备份业务数据库) (备份触发器,存储过程,函数,events 需指定选项-G -R -E) (1) /mysql/svr/mysql/bin/mysqlpump -uroot -pabc123 -S /mysql/dbdata/data3308/data/mysql3308.sock --set-gtid-purged=OFF --exclude-databases=% --users >/mysql/backup/3308/mysql_user.sql (2)mydumper -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 8 -G -R -E -B benchmark,test --long-query-guard=1000 -o /mysql/backup/3308
导入命令myloader
常用重要选项
Filter Options
-x, --regex Regular expression for 'db.table' matching -s, --source-db Database to restore
-O, --omit-from-file File containing a list of database.table entries to skip
--no-data Do not dump or import table data
--skip-triggers Do not import triggers. By default, it imports triggers
--skip-post Do not import events, stored procedures and functions. By default, it imports events, stored procedures nor functions
Execution Options
-e, --enable-binlog Enable binary logging of the restore data
--innodb-optimize-keys Creates the table without the indexes and it adds them at the end. Options: AFTER_IMPORT_PER_TABLE and AFTER_IMPORT_ALL_TABLES. Default: AFTER_IMPORT_PER_TABLE
--purge-mode This specify the truncate mode which can be: NONE, DROP, TRUNCATE and DELETE
--disable-redo-log Disables the REDO_LOG and enables it after, doesn't check initial status
-o, --overwrite-tables Drop tables if they already exist
--serialized-table-creation Table recreation will be executed in series, one thread at a time
--stream It will receive the stream from STDIN and creates the file in the disk before start processing. Since v0.12.7-1, accepts NO_DELETE, NO_STREAM_AND_NO_DELETE and TRADITIONAL which is the default value and used if no parameter is given
Threads Options
--max-threads-per-table Maximum number of threads per table to use, default 4
--max-threads-for-index-creation Maximum number of threads for index creation, default 4
Statement Options
-r, --rows Split the INSERT statement into this many rows.
--skip-definer Removes DEFINER from the CREATE statement. By default, statements are not modified
Application Options:
-d, --directory Directory of the dump to import
-L, --logfile Log file name to use, by default stdout is used
-t, --threads Number of threads to use, default 4
-B, --database An alternative database to restore into
--resume Expect to find resume file in backup dir and will only process those files
--defaults-file Use a specific defaults file. Default: /etc/mydumper.cnf
使用举例
导入指定表(无法使用-T 选项进行导入指定的表,可以控制导入目录中的文件,或者使用-x来匹配) myloader -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -e -v 3 -x test.tt* -d /mysql/backup/3308/test 导入指定库(-s) myloader -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 4 -s test -e -v 3 -d /mysql/backup/3308/test 将导出库还原到另一个库(-B) myloader -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 4 -s test -B test1 -e -v 3 -d /mysql/backup/3308/test 导入表结构(--no-data) myloader -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -s test --no-data -t 4 -e -v 3 -d /mysql/backup/3308/test 导入表数据,不带表结构 (删除导入目录中的表结构文件database.table-schema.sql,或者导出时不带表结构导出) myloader -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -s test -t 4 -e -v 3 -d /mysql/backup/3308/test 导入整个实例(分两步:先导入用户权限,再导入业务数据库) (1) mysql -uroot -pabc123 -S /mysql/dbdata/data3308/data/mysql3308.sock < /mysql/backup/3308/mysql_user.sql (2)myloader -u root -p abc123 -S /mysql/dbdata/data3308/data/mysql3308.sock -t 4 -e -v 3 -d /mysql/backup/3308
3 备份机制
与其他备份工具一样,mydumper 默认情况下是用 FTWRL (Flush Tables With Read Lock) 全局读锁来保证备份数据的一致性。FTWRL 锁对 MySQL 的杀伤力很大,特别是在读写负载比较高的场景,因而mydumper在加锁时会优先使用影响更小的备份锁,依次执行 LOCK TABLES FOR BACKUP
和LOCK TABLES FOR BINLOG
,如果导出实例支持的话。
在进行数据备份时,mydumper 的主逻辑由一个主线程和多个备份子线程共同完成,默认情况下为四个子线程。
其主线程的主要流程为:
- 连接数据库
FLUSH TABLES WITH READ LOCK
将脏页刷新到磁盘并获得只读锁START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT /
开启事务并获取一致性快照SHOW MASTER STATUS
获得binlog位点信息- 创建子线程并连接数据库
- 为子线程分配任务并 push 到队列
queue
中 - 在子线程处理完所有非 InnoDB 表之后,
UNLOCK TABLES
/ FTWRL / 释放锁 - thread.join() 等待子线程结束
备份子线程的主要流程是:
- 连接数据库
- 将 session 的隔离级别设置为 Repeatable Read
START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT /
开启事务并获取一致性快照- 从队列中 pop 任务并执行
- 在所有非 InnoDB 表执行完之后,将事件通知给主线程
值得注意的是,虽然 mydumper 支持表级别的并行操作,且在导出的时候会对大的表数据进行分块 chunk 导出,但是同一个表的 chunks 是在同一个线程中处理的,并非多线程并行的。
4 备份详细流程
一致性与锁
如流程图中所示,主线程会在开始时获取 FTWRL 全局只读锁,来保证确保接下来没有变更产生。 之后开启一致性读事务,创建子线程并确认子线程 session 隔离级别为 Repeatable Read、开启一致性读事务。这样保证了即使主线程在所有导出任务结束之前释放锁,子线程在处理 InnoDB 表时能利用 MySQL MVCC 特性继续执行,得到事务开启时间点的一致性数据视图。
接下来主线程会在自己的 session 里面读取数据库表结构、拆分任务,主线程UNLOCK TABLES
释放锁由非 InnoDB 表都处理完的事件来触发,确保所有的非事务表的数据一致性。
mydumper通过结合以上逻辑可以保证即使在多线程处理的情形下,备份数据仍是一致的。
--trx-consistency-only 选项
这个选项与 mysqldump 的--single-transaction
功能类似,将备份流程当作一个大事务来处理,可以看到流程中在主线程等待子线程创建完之后,主线程就会提前UNLOCK TABLES
释放锁了。
显然,这个时候无法保证非InnoDB表的数据一致性,这是因为MyISAM等非事务并不支持MVCC特性,无法实现一致性快照读。
--less-locking 模式
mydumper有一个比较有意思的--less-locking
选项,主要目的就是尽量减少 mydumper 中FTWRL整体的锁定时间。
这种模式的实现比较巧妙,在这种模式下,线程数量是用户指定线程数n的两倍,默认情况下也即是八个线程,新增的线程为专门处理非 InnoDB 表的一组线程less_locking_threads
。主要的流程为:
- 主线程
FLUSH TABLES WITH READ LOCK
获取全局只读锁 - 主线程
START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT /
开启事务并获取一致性快照 - 主线程
SHOW MASTER STATUS
获得binlog位点信息 - 主线程创建两组子线程并连接数据库,其中原来的一组线程
threads
会条件等待less_locking_threads
结束才开始工作,less_locking_threads
中结束一个就通知threads
中的一个线程开始工作 - 主线程将非InnoDB表按照表中数据量均分为与n份push到queue_less_locking
,其他表的导出任务还是按照原来的流程处理push到队列
queue`中 less_locking_threads
中每个线程会拿到一个非InnoDB表任务执行,直到执行完通知threads
中的一个线程开始执行queue
中的任务- 当所有
less_locking_threads
执行完时,主线程UNLOCK TABLES
/ FTWRL / 释放锁 - 主线程 thread.join() 等待子线程结束
可以看到在--less-locking
模式下,mydumper 会首先集中能力处理完所有非 InnoDB 表的任务,尽快满足主线程释放锁的条件。由于每个less_locking_threads
处理的任务量相当,这基本是最快的处理方式了。
注意:在执行备份任务时,如果没有非innodb表,带着--less-locking,会core。
5 特点
- 支持多线程导出数据,速度更快。
- 支持一致性备份。
- 支持将导出文件压缩,节约空间。
- 支持多线程恢复。
- 支持以守护进程模式工作,定时快照和连续二进制日志。
- 支持按照指定大小将备份文件切割。
- 数据与建表语句分离。
- 支持远程备份
局限性:
备份时需要获取全局只读锁
此工具需要单独安装,非mysql自带。
参考博客:
MyDumper原理简介 - 腾讯云开发者社区-腾讯云 (tencent.com)
MyDumper工具 - 忘川的彼岸 - 博客园 (cnblogs.com)