首先说明,mysqldump的导出速度并不慢,经测试能达到50M/s的速度,10G数据花费3分钟的样子,可以看到瓶颈在于网络和磁盘IO,再怎样的导出工具也快不了多少,但是导入却花了60分钟,磁盘和网络大概只用到了20%,瓶颈在目标库写入速度(而一般顺序写入达不到IOPS限制),所以mypumpkin就诞生了 —— 兼顾myloader的导入速度和mysqldump导出的灵活性。
95712e0b0bc62c64b1fddfac486f9cb8
用python构造1个队列,将需要导出的所有表一次放到队列中,同时启动N个python线程,各自从这个Queue里取出表名,subprocess调用操作系统的mysqldump命令,导出数据到以 dbname.tablename.sql 命名的文件中。load in 与 dump out 类似,根据指定的库名或表名,从dump_dir目录找到所有sql文件,压进队列,N个线程同时调用mysql构造新的命令,模拟 70e1e70e30b39915ed731f1f9ecb5881 or < 不允许使用。dump-dir指定目录不存在时会尝试自动创建。
--threads=N,N指定并发导出或导入线程数。dump out 默认线程数2, mypumpkin load in 默认线程数是 cpu个数 * 2。
注:线程数不是越大越好,这里主要的衡量指标是网络带宽、磁盘IO、目标库IOPS,最好用 dstat 观察一下。
-B, --tables,--ignore-table,使用与mysqldump相同,如:
在mysqldump里面,--tables会覆盖--databases/-B选项
在mysqldump里面,--tables与--ignore-table不能同时出现
在mysqldump里面,如果没有指定-B,则--tables或--ignore-table必须紧跟db名之后
其它选项,mypumpkin会原封不动的保留下来,放到shell去执行。所以如果其它选项有错误,检查是交给原生mysqldump去做的,执行过程遇到一个失败则会退出线程。
4.2 example
导出:
## 导出源库所有db到visit_dumpdir2目录 (不包括information_schema和performance_schema) $ ./mypumpkin.py mysqldump -h dbhost_name -utest_user -pyourpassword -P3306 \ --single-transaction --opt -A --dump-dir visit_dumpdir2 ## 导出源库db1,db2,会从原库查询所有表名来过滤 $ ./mypumpkin.py mysqldump -h dbhost_name -utest_user -pyourpassword -P3306 \ --single-transaction --opt -B db1 db2 --dump-dir visit_dumpdir2 ## 只导出db1库的t1,t2表,如果指定表不存在则有提示 $ ./mypumpkin.py mysqldump -h dbhost_name -utest_user -pyourpassword -P3306 \ --single-transaction --opt -B db1 --tables t1 t2 --dump-dir visit_dumpdir2 ## 导出db1,db2库,但忽略 db1.t1, db2.t2, db2.t3表 ## mysqldump只支持--ignore-table=db1.t1这种,使用多个重复指令来指定多表。这里做了兼容扩展 $ ./mypumpkin.py mysqldump -h dbhost_name -utest_user -pyourpassword --single-transaction \ --opt -B db1 db2 --ignore-table=db1.t1 --ignore-table db2.t2 db2.t3 --dump-dir visit_dumpdir2 (如果-A表示全部db) ## 不带 -A/-B $ ./mypumpkin.py mysqldump -h dbhost_name -utest_user -pyourpassword -P3306 \ --single-transaction --opt db1 --ignore-table=db1.t1 --dump-dir=visit_dumpdir2 ## 其它选项不做处理 $ ./mypumpkin.py mysqldump -h dbhost_name -utest_user -pyourpassword -P3306 \ --single-transaction --set-gtid-purged=OFF --no-set-names --skip-add-locks -e -q -t -n --skip-triggers \ --max-allowed-packet=134217728 --net-buffer-length=1638400 --default-character-set=latin1 \ --insert-ignore --hex-blob --no-autocommit \ db1 --tables t1 --dump-dir visit_dumpdir2
导入:
-A, -B, --tables, --ignore-table, --threads, --dump-dir用法与作用与上面完全相同,举部分例子:
## 导入dump-dir目录下所有表 $ ./mypumpkin.py mysql -h dbhost_name -utest_user -pyourpassword --port 3307 -A \ --dump-dir=visit_dumpdir2 ## 导入db1库(所有表) $ ./mypumpkin.py mysql -h dbhost_name -utest_user -pyourpassword --port 3307 -B db1 \ --dump-dir=visit_dumpdir2 ## 只导入db.t1表 $ ./mypumpkin.py mysql -h dbhost_name -utest_user -pyourpassword --port 3307 \ --default-character-set=utf8mb4 --max-allowed-packet=134217728 --net-buffer-length=1638400 \ -B db1 --tables t1 --dump-dir=visit_dumpdir2 ## 导入db1,db2库,但忽略db1.t1表(会到dump-dir目录检查db1,db2有无对应的表存在,不在目标库检查) $ ./mypumpkin.py mysql -h dbhost_name -utest_user -pyourpassword --port 3307 \ -B db1 db2 --ignore-table=db1.t1 --dump-dir=visit_dumpdir2