很久没更了(先写点简单的)
简单概述一下mydumper和myloader的使用方法及原理
安装
yum install -y glib2-devel mysql-devel zlib-devel pcre-devel openssl-devel cmake gcc gcc-c++
git clone https://github.com/maxbube/mydumper
cd mydumper
cmake .
make && make install复制
备份
用法十分简单,如需要做全实例备份:
mydumper -u $user -p $password -h $host -G -E -R -c -o /data/backup --less-locking
复制
使用的时候,需要隔开选项和对应的值,比如-uroot要写成-u root,否则会报错
option parsing failed: Error parsing option -r, try --help
复制
-u -p -S/-h
这个肯定要指定,含义和mysqldump
、mysql
、mysqladmin
等工具一致
-B 指定数据库 (如果没有-B,默认就是全库表)
-G 备份trigger
-E 备份event
-R 备份routine
-c 压缩(gzip)
-x 正则,比如备份多个指定的库:-x 'test|mysql',比如指定某些库不参与备份:-x '^(?!(sys|mysql))'
-T 指定表,如-T test.tb1
-t 线程数,默认4
-l 设置长查询的阈值
-K 加上这个参数,会考虑-l指定的时间,如果超过这个阈值,会将阻塞备份进程的会话干掉
--less-locking 减少InnoDB表的锁时间
--trx-consistency-only 代表本次备份只对事务表做一致性保证
--skip-tz-utc 不加的话,会在dump的时候加上SET TIME_ZONE='+00:00'复制
如果想看dump时详细的信息输出,可以指定--verbose=3
,日志级别为info
,默认不指定,为warning(2)
备份输出格式及内容
metadata
记录的内容,基本上等同于mysqldump
的--master-data
和--set-gtid-purged
# cat metadata
Started dump at: 2019-03-25 16:23:48
SHOW MASTER STATUS:
Log: mysql57-bin.000012
Pos: 749818446
GTID:ba5fdbe3-4949-11e8-8d33-525400652955:1-2
Finished dump at: 2019-03-25 16:24:04复制
*-schema.sql.gz
为表结构
# zcat mysql.gtid_executed-schema.sql.gz
/*!40101 SET NAMES binary*/;
/*!40014 SET FOREIGN_KEY_CHECKS=0*/;
/*!40103 SET TIME_ZONE='+00:00' */;
CREATE TABLE `gtid_executed` (
`source_uuid` char(36) NOT NULL COMMENT 'uuid of the source where the transaction was originally executed.',
`interval_start` bigint(20) NOT NULL COMMENT 'First number of interval.',
`interval_end` bigint(20) NOT NULL COMMENT 'Last number of interval.',
PRIMARY KEY (`source_uuid`,`interval_start`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0;复制
.sql.gz
为表数据
# zcat mysql.gtid_executed.sql.gz | head -5
/*!40101 SET NAMES binary*/;
/*!40014 SET FOREIGN_KEY_CHECKS=0*/;
/*!40103 SET TIME_ZONE='+00:00' */;
INSERT INTO `gtid_executed` VALUES
("ba5fdbe3-4949-11e8-8d33-525400652955",1,2);复制
在加了-B或者默认全库备份的场景下,还会有一个创建schema的文件:
# zcat mysql-schema-create.sql.gz
CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */;复制
恢复
myloader -u $user -p $password -h $host -d /data/backup/
复制
常用可选参数:
-e,加了-e之后,导入的时候会记录binlog
-t 同样是线程数,这个默认也是4复制
备份和恢复速度
这个没测了。
同事测了,反正就是快。(当然没xtrabackup
快)
原理
老规矩,策略是用general_log
分析一下:
SET GLOBAL general_log=ON;
SET GLOBAL log_output='TABLE';
TRUNCATE TABLE mysql.general_log;复制
再在备份的时候开启--verbose=3
,为了简明,我去掉了-G -E -R,意思是不备份trigger、event、routine
,且dump线程指定为2个。
测试库为test,表为a_myisam(MyISAM)、b_myisam(MyISAM)、t_1(InnoDB)、t_db_backup(InnoDB)
原理分析,主要是围绕加与不加--trx-consistency-only
和--less-locking
,并且为了了解如何并行dump,和对存在非事务引擎时,如何拿到逻辑一致性的备份。
先分析过程,如果不想细看可以直接拉到底看结论:
① 不加--less-locking:
测试命令:
mydumper -u $user -p $password -h $host -c -o /data/backup/ --verbose=3 -B test -t 2
复制
根据mysql.general_log
的thread_id
和argument
一起分析一下:
SELECT thread_id, command_type, left(argument,80)
FROM mysql.general_log;
复制
跑上述sql,可以拉到如下结果:
① 可以看到,主线程374,先把wait_timeout
和net_write_timeout
给调大,然后跑个其他备份工具都爱加的全局读锁:FTWRL
,成功后,再来个START TRANSACTION *!40108 WITH CONSISTENT SNAPSHOT */
,保证是一致性读,接下来看master status
,记录下log_file
和log_pos
,如果为slave,也拉了slave的信息(此处未测slave的环境)
② 然后此处我指定的-t 2
,意思是分两个dump线程来备份,此处可以看到375和376连上来了:同样先调大timeout
两个参数,并先将隔离级别改为RR,无论关引擎,因现在还没开始判断表引擎。
③ 主线程374开始判断表引擎,SHOW TABLE STATUS
,这样可以告诉dump线程,哪些是非事务引擎,因为需要在FTWRL
的情况下先备份
④ 两个dump线程开始备份非事务引擎,此处是a_myisam
和b_myisam
,直至备份结束。
④ 主线程374开始unlock tables
,之后,业务可写。同时,接下来的事情也和主线程没关系了,quit退出。
⑤ 两个dump线程继续备份剩余的事务表
这样,多个线程并行dump时,所读到的内容在时间上是一致性的。
虽然这样备份,备份是一致性的,但如果非事务引擎的表很多且很大,这样备份,会不会有点不妥?要等非事务引擎备份完,才可UNLOCK TABLES
然后dump事务表。
然后,mydumper
就多了这样一个参数--less-locking
(mydumper 0.6.x后支持)
② 加上--less-locking:
测试命令:
mydumper -u $user -p $password -h $host -c -o /data/backup/ --verbose=3 -B test -t 2 --less-locking
复制
同样,看一下general log输出
可以很明显发现,虽然指定了dump并发数为2,但是总共有5个线程。
翻了下percona的博客,发现--less-locking
的选项的加入,为每个dump thread
,多分配了一个LL dump thread
(即less-locking dump thread
)。
那么整个过程就变成了:
① 主线程377依然先调两个timeout
参数,然后申请全局读锁FTWRL
,并开启一个事务,记录file和pos点,这一步与不加--less-locking
一致
② less-lokcing dump线程378、379连上来,设置timeout
,并等待主线程push非事务表到队列中。(这里就不需要开事务了,因为LL dump线程是负责非事务引擎的)
③ dump线程380、381连上来,设置timeout
,改隔离级别为RR,开启事务,并等待主线程分配事务表(380和381则只负责事务表)
④ 主线程377开始通过SHOW TABLE STATUS
判断非事务表和事务表
⑤ less-locking dump线程378、379拿到了两张非事务表的任务,开始单独地拿两张非事务表的锁,每个线程一个拿到后,就可以开始备份非事务引擎了。
⑥ 因为非事务引擎表被单独的less-locking dump线程拿到了锁,对于主线程377,可以执行UNLOCK TABLES
了,这时,全局读锁FTWRL
被释放,整个过程就减少了事务表的锁时间。
⑦ 开始备份剩下没备份的事务表,直至退出
引入less-locking dump线程,不仅依然可以拿到非事务引擎和事务引擎混合的一致性备份,也可以减少对事务引擎锁的时间。
实际上,②和③顺序也是可以调换的(应该是并行的),在mydumper跑备份的时候,输出里stdout可以体现,节选如下:
…………
** Message: Thread 3 connected using MySQL connection ID 378
** Message: Thread 4 connected using MySQL connection ID 379
** Message: Thread 1 connected using MySQL connection ID 380
** Message: Thread 2 connected using MySQL connection ID 381
** Message: Thread 4 dumping data for `test`.`b_myisam`
** Message: Thread 3 dumping data for `test`.`a_myisam`
…………复制
③ 加--trx-consistency-only,(此处加不加--less-locking,过程和结果是一样的)
首先看一下这个参数是什么个意思:
WARNING **: Using trx_consistency_only, binlog coordinates will not be accurate if you are
writing to non transactional tables.复制
那么实际上和隔壁的--single-transaction
的效果是一样的——只管事务表,如果在备份过程中对非事务表有写操作,那binlog位置点不准。
所以,加不加--less-locking
就无所谓了,因为不对非事务引擎负责,过程均一致,大致如下:
这种情况,如果有非事务表,且存在写入的情况下,备份就不是一致性的了,整个过程十分简单:
① 主线程调两个timeout
参数,然后依然申请全局读锁FTWRL
,再开启事务,记录file和pos点
② dump线程389、390开事务
③ 主线程释放全局读锁并退出,此处还特意说明了trx-only
④ dump线程开始备份
总结
不加--less-locking:
① 主线程:FTWRL;
② dump线程:START TRANSACTION WITH CONSISTENT SNAPSHOT; dump non-InnoDB tables;
③ 主线程:UNLOCK TABLES;
④ dump线程:dump InnoDB tables;复制
加--less-locking:
① 主线程:FTWRL;
② dump线程:START TRANSACTION WITH CONSISTENT SNAPSHOT;
③ LL dump线程:LOCK TABLES non-InnoDB;
④ 主线程:UNLOCK TABLES
⑤ LL dump线程:dump non-InnoDB tables; UNLOCK non-INNODB;
⑥ dump线程:dump InnoDB tables;复制
平时用的话,似乎也可以不用判断是否有非事务引擎(当然最好不要用!),直接less-locking应该就能够满足需求了,日志级别我习惯设置为info。
对TokuDB似乎是可以支持的,但以前粗浅测过,且没细看。好像仍是拿不到一致性点的情况,这一点后续待校验。
mydumper -u $user -p $password -h $host -G -E -R -c --less-locking -o /data/backup/ \
--verbose=3 -B test -t 8 -L /tmp/mydumper_`date +%Y%m%d%H%M%S`.log复制
其他
mydumper版本:0.9.5
MySQL版本:5.7.21
参考文档
mydumper-less-locking:
https://www.percona.com/blog/2014/06/13/mydumper-less-locking/
-- the end --
戳阅读原文查看历史推送。