一.问题描述
将abc和abcb两个库的mydumper备份,利用myloader导入abc数据库时提示主键重复错误(很多表都有这个错误):
* (myloader:15557): CRITICAL **: Error restoring abcb.status_flow from file abcb.status_flow.sql: Duplicate entry '10203' for key 'PRIMARY'
** (myloader:15557): CRITICAL **: Error restoring abcb.task_creation_master from file abcb.task_creation_master.sql: Duplicate entry '280' for key 'PRIMARY'
导入脚本如下:
myloader -h localhost -P 3306 -u dba -p xxxx -S /tmp/mysql3306.sock -B abc -e -d /apps/mydumper_import/20171225010001 -o -t 8
版本:mariadb 10.1.18 + myloader 0.9.1
二.问题分析
从报错来看提示主键重复,先想到的是原来的库和表是否有drop掉,其实在导入前已经做了drop操作,不存在有库和表没有drop掉的问题,而且检查导入命令是正常的。尝试改成导入abcb库,同样提示主键重复,如是猜测abc库和abcb库两个库的名字前三个字相同,会有冲突引起?或是两个库下有相同的表冲突引起?再检查mydumper的备份文件,果然发现两个库存在相同表名:
apps@hcp50019 20171225010001]$ ls -al|grep status_flow
-rw-r--r--. 1 apps apps 1546 Dec 26 17:37 abcb.status_flow_detail-schema.sql
-rw-r--r--. 1 apps apps 162320 Dec 26 17:37 abcb.status_flow_detail.sql
-rw-r--r--. 1 apps apps 1509 Dec 26 17:37 abcb.status_flow-schema.sql
-rw-r--r--. 1 apps apps 19513 Dec 26 17:37 abcb.status_flow.sql
-rw-r--r--. 1 apps apps 1546 Dec 26 17:37 abc.status_flow_detail-schema.sql
-rw-r--r--. 1 apps apps 25078 Dec 26 17:37 abc.status_flow_detail.sql
-rw-r--r--. 1 apps apps 1509 Dec 26 17:37 abc.status_flow-schema.sql
-rw-r--r--. 1 apps apps 2825 Dec 26 17:37 abc.status_flow.sql
分别查看abc和abcb下的status_flow表定义和结构都相同:
show create table abcb.status_flow\G
*************************** 1. row ***************************
Table: status_flow
Create Table: CREATE TABLE `status_flow` (
`........
PRIMARY KEY (`id`),
KEY `idx1` (`code`,`WCode`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
show create table abc.status_flow\G
*************************** 1. row ***************************
Table: status_flow
Create Table: CREATE TABLE `status_flow` (
.......
PRIMARY KEY (`id`),
KEY `idx1` (`code`,`WCode`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
所以猜测为myloader导入时对两个库的相同表进行了重复导入处理,所以报主键重复。
通过上面的对比分析,大致清楚报错原因:在导出备份存在多个库,且多个库存在相同的表名和表结构时,myloader工具将两个库导入到一个库,而两个库中的表结构相同,所以就发生了这一问题。
重新查看一下-B参数的作用:
-B, --database An alternative database to restore into
在这里的作用就是将来源多个库合并导入到-B后面的库中。
三.问题解决
查看myloader命令带有的参数:
myloader --help
Application Options:
-d, --directory Directory of the dump to import
-q, --queries-per-transaction Number of queries per transaction, default 1000
-o, --overwrite-tables Drop tables if they already exist
-B, --database An alternative database to restore into
-s, --source-db Database to restore
-e, --enable-binlog Enable binary logging of the restore data
-h, --host The host to connect to
-u, --user Username with privileges to run the dump
-p, --password User password
-P, --port TCP/IP port to connect to
-S, --socket UNIX domain socket file to use for connection
-t, --threads Number of threads to use, default 4
-C, --compress-protocol Use compression on the MySQL connection
-V, --version Show the program version and exit
-v, --verbose Verbosity of output, 0 = silent, 1 = errors, 2 = warnings, 3 = info, default 2
发现-s参数可以指定来源数据库名,所以用下面命令导入后,问题不再发生:
myloader -h localhost -P 3306 -u dba -p xxxx -S /tmp/mysql3306.sock -s db1 -B db1 -e -d /apps/mydumper_import/20171225010001 -o -t 8
四.总结
当从来源多个库导入一个库到目标mysql时,推荐-s和-B参数组合使用,且在从库上设置复制过滤:set global replicate_do_db=abc.