pt-fk-error-logger的功能是记录MySQL外键错误。其原理、实现、功能以及用法同工具包里面的另一个工具pt-deadlock-logger(https://blog.csdn.net/sweeper_freedoman/article/details/79317758)一致,区别只是在于一个log外键错误另一个log死锁错误。
用法如下:
pt-fk-error-logger [OPTIONS] [DSN]
pt-fk-error-logger记录给出DSN(MySQL连接访问)上的外键错误信息。外键错误信息会打印到STDOUT,也可以通过指定“ --dest ”选项保存到一张表。除非指定了“ --run-time ”或者“ --iterations ”选项,否则工具会一直执行下去。
①打印host1上的外键错误信息(守护进程不会退出):
pt-fk-error-logger h=host1
②打印host1上的外键错误信息1次然后退出:
pt-fk-error-logger h=host1 --iterations 1
③把host1上的外键错误信息保存到host2的`percona_schema`.`fke`库表中:
pt-fk-error-logger h=host1 --dest h=host2,D=percona_schema,t=fke
pt-fk-error-logger打印或者保存的MySQL外键错误文本源自“ SHOW ENGINE INNODB STATUS ”。报错没有以任何方式解析或解释。外键错误分别由各自的时间戳唯一标识。只有新的(最近)报错才会被打印或者保存。
默认情况下,pt-fk-error-logger会一直执行下去,每“ --interval ”秒检查一次新的外键错误。指定“ --run-time ”和 / 或“ --iterations ”选项来限制该工具执行多长时间。
以下为个人本地环境的测试数据。
首先是创建两张有外键关联关系的父子表,然后再造一个子表的INSERT报错。
CREATE TABLE `player`.`tb_father` (
`f_pk` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`f_col` VARCHAR(50) NOT NULL,
PRIMARY KEY (`f_pk`)
);
CREATE TABLE `player`.`tb_child` (
`c_pk` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`c_f_pk` INT(10) UNSIGNED NOT NULL,
`c_col` VARCHAR(50) NOT NULL,
PRIMARY KEY (`c_pk`),
INDEX `FK_tb_child_tb_father` (`c_f_pk`),
CONSTRAINT `FK_tb_child_tb_father` FOREIGN KEY (`c_f_pk`) REFERENCES `tb_father` (`f_pk`) ON UPDATE CASCADE ON DELETE CASCADE
);
mysql> INSERT INTO `player`.`tb_child`(`c_pk`, `c_f_pk`, `c_col`) VALUES(NULL, 1024, 'bit');
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`player`.`tb_child`, CONSTRAINT `FK_tb_child_tb_f
ather` FOREIGN KEY (`c_f_pk`) REFERENCES `tb_father` (`f_pk`) ON DELETE CASCADE ON UPDATE CASCADE)
mysql>
终端命令行执行外键错误检测。
root@ubuntu:~# pt-fk-error-logger h=192.168.112.129, P=3306, u=root, p=123456
2018-03-31 14:13:33 0x7f59942d0700 Transaction:
TRANSACTION 5892, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 140022714795776, query id 12 localhost root update
INSERT INTO `player`.`tb_child`(`c_pk`, `c_f_pk`, `c_col`) VALUES(NULL, 1024, 'bit')
Foreign key constraint fails for table `player`.`tb_child`:
,
CONSTRAINT `FK_tb_child_tb_father` FOREIGN KEY (`c_f_pk`) REFERENCES `tb_father` (`f_pk`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index FK_tb_child_tb_father tuple:
DATA TUPLE: 2 fields;
0: len 4; hex 00000400; asc ;;
1: len 4; hex 00000001; asc ;;
But in parent table `player`.`tb_father`, in index PRIMARY,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 696e66696d756d00; asc infimum ;;
终端命令行执行外键错误检测,但只打印(迭代)1次。
root@ubuntu:~# pt-fk-error-logger h=192.168.112.129, P=3306, u=root, p=123456 --iterations=1
2018-03-31 14:13:33 0x7f59942d0700 Transaction:
TRANSACTION 5892, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 140022714795776, query id 12 localhost root update
INSERT INTO `player`.`tb_child`(`c_pk`, `c_f_pk`, `c_col`) VALUES(NULL, 1024, 'bit')
Foreign key constraint fails for table `player`.`tb_child`:
,
CONSTRAINT `FK_tb_child_tb_father` FOREIGN KEY (`c_f_pk`) REFERENCES `tb_father` (`f_pk`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index FK_tb_child_tb_father tuple:
DATA TUPLE: 2 fields;
0: len 4; hex 00000400; asc ;;
1: len 4; hex 00000001; asc ;;
But in parent table `player`.`tb_father`, in index PRIMARY,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 696e66696d756d00; asc infimum ;;
root@ubuntu:~#
将外键错误信息写入表中。这需要去“ --dest ”中手动创建表。
CREATE TABLE `player`.`foreign_key_errors` (
ts datetime NOT NULL,
error text NOT NULL,
PRIMARY KEY (ts)
);
root@ubuntu:~# pt-fk-error-logger h=192.168.112.129, P=3306, u=root, p=123456 --dest h=192.168.112.128,P=3306,u=root,p=123456,D=player,t=foreign_key_errors --iterations=1
2018-03-31 14:13:33 0x7f59942d0700 Transaction:
TRANSACTION 5892, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 140022714795776, query id 12 localhost root update
INSERT INTO `player`.`tb_child`(`c_pk`, `c_f_pk`, `c_col`) VALUES(NULL, 1024, 'bit')
Foreign key constraint fails for table `player`.`tb_child`:
,
CONSTRAINT `FK_tb_child_tb_father` FOREIGN KEY (`c_f_pk`) REFERENCES `tb_father` (`f_pk`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index FK_tb_child_tb_father tuple:
DATA TUPLE: 2 fields;
0: len 4; hex 00000400; asc ;;
1: len 4; hex 00000001; asc ;;
But in parent table `player`.`tb_father`, in index PRIMARY,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 696e66696d756d00; asc infimum ;;
root@ubuntu:~#
mysql> SELECT * FROM `player`.`foreign_key_errors`\G
*************************** 1. row ***************************
ts: 2018-03-31 14:13:33
error: 0x7f59942d0700 Transaction:
TRANSACTION 5892, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 140022714795776, query id 12 localhost root update
INSERT INTO `player`.`tb_child`(`c_pk`, `c_f_pk`, `c_col`) VALUES(NULL, 1024, 'bit')
Foreign key constraint fails for table `player`.`tb_child`:
,
CONSTRAINT `FK_tb_child_tb_father` FOREIGN KEY (`c_f_pk`) REFERENCES `tb_father` (`f_pk`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index FK_tb_child_tb_father tuple:
DATA TUPLE: 2 fields;
0: len 4; hex 00000400; asc ;;
1: len 4; hex 00000001; asc ;;
But in parent table `player`.`tb_father`, in index PRIMARY,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 696e66696d756d00; asc infimum ;;
1 row in set (0.00 sec)
mysql>
参考:
https://www.percona.com/doc/percona-toolkit/LATEST/pt-fk-error-logger.html