相比mysqldump,其优势如下:
1 速度快(好多资料都说快10倍,个人持保留意见);
2 支持多线程导出和导入myloader;
3 采用守护进程方式运行,可定时扫描和快照binlog(-snapshot-interval);
4 快速文件压缩;
也有稍许不足之处,如mydumper不处理MySQL的视图,触发器和存储过程,因此使用mydumper去导出schema并不可靠。
实际生产环境中,建议mydumper仅用于导出数据(使用 --no-schemas ),而通过mysqldump来导出schema。
mydumper除了为每个表会分别生成table.sql和table-schema.sql,还会生成一个.metadata文件,记录dump的开始和结束时间,以及binlog位置信息。
参数
-long-query-guard:长查询上限(默认60s),如果当前数据库存在运行时间大于此参数的查询则退出mydumper;
-kill-long-queries:杀死查出的长查询;
-daemon:启用守护进程模式;
-snapshot-interval:快照时间间隔,默认60s;
-t, --threads 使用的线程数,默认4
-C, --compress-protocol 在mysql连接上使用压缩
-e, --enable-binlog 启用二进制恢复数据
-r, --rows 将表分成多个文件批次导出,
1 确定表的行数,依据pk – uk – cardinality最高的索引(show index from table)选择索引,通过explain select index from table的rows字段确定行数;
2 已经total_rows和rows将表分成若干分块,每个分块可由不同worker并行执行,适用于大表;
安装
1 安装cmake,apt-get install cmake;
2 安装兼容包,如apt-get install libglib2.0-dev libmysqlclient15-dev,具体参照官网;
3 下载安装包并编译
#wget http://launchpad.net/mydumper/0.2/0.2.3/+download/mydumper-0.2.3.tar.gz
#tar xzvf mydumper-0.2.3.tar.gz
#cd mydumper-0.2.3/
#cmake .
#make
#make install
原理
Mysqldump是个单线程工具,只能逐个导出表,而mydumper支持多线程并行导出;
尽管mydumper主线程已经登录进入了mysql,但worker子线程必须再登录一次,因为libmysql是线程不安全的?
工作流程
1 连接目标数据库;
2 通过show processlist来判断是否有长查询,如果有长查询则退出dump(通过-long-query-guard指定),或者使用-kill-long-queries杀掉长查询;
3 锁定myisam表,flush tables with read lock; 针对innodb table开启事务,start transaction;
4 创建worker子线程;
5 确定候选表,根据类别分别插入innodb_table,non_innodb_table以及table_schemas链表(表结构);
6 将候选表通过g_async_queue_push加入任务队列(队列最后元素是thread shutdown),由worker子线程从队列中读取表信息并执行数据导出
for(;;) {
....
job=(struct job *)g_async_queue_pop(conf->queue);
....
switch (job->type) {
case JOB_DUMP:
....
dump_table_data_file(thrconn, tj->database, tj->table, tj->where, tj->filename);
....
case JOB_DUMP_NON_INNODB:
....
dump_table_data_file(thrconn, tj->database, tj->table, tj->where, tj->filename);
case JOB_SCHEMA:
....
dump_schema_data(thrconn, sj->database, sj->table, sj->filename);
}
当worker读取到job_shutdown任务时,则会执行如下
case JOB_SHUTDOWN:
g_message("Thread %d shutting down", td->thread_id);
if (thrconn)
mysql_close(thrconn);
g_free(job);
mysql_thread_end();
return NULL;
break;
7 执行unlock tables,处理完myisam表后立即解锁,以减少锁定时间;
Main_thread:记录myisam数量
for (non_innodb_table= g_list_first(non_innodb_table); non_innodb_table; non_innodb_table= g_list_next(non_innodb_table)) {
dbt= (struct db_table*) non_innodb_table->data;
dump_table(conn, dbt->database, dbt->table, &conf, FALSE);
g_atomic_int_inc(&non_innodb_table_counter);
}
child_thread:当队列中myisam为0时,加入unlock_tables任务
if (g_atomic_int_dec_and_test(&non_innodb_table_counter) && g_atomic_int_get(&non_innodb_done)) {
g_async_queue_push(conf->unlock_tables, GINT_TO_POINTER(1));
}
main_thread:主线程读取unlock_tables任务并执行
g_async_queue_pop(conf.unlock_tables);
g_message("Non-InnoDB dump complete, unlocking tables");
mysql_query(conn, "UNLOCK TABLES");
8 等待worker退出;
Myloader将数据导入数据库,原理与mydumper类似。
-queries-per-transaction
-directory
参考资料
http://www.hoterran.info/mydumper_usage