3

情况:MTS复制上的死锁

我们在Percona MySQL 5.6.32-78.1上使用GTID进行主 - 主复制。在服务器上,大约有10个数据库,我们设置了slave_parallel_workers=5。一台服务器用于前端处理,另一台用于后端。一个星期两两三次,在后端服务器上复制错误

2016-10-25 10:00:01 165238 [Warning] Slave SQL: Worker 4 failed executing transaction '0e7b97a8-a689-11e5-8b79-901b0e8b0f53:22506262' at master log mysql-bin.011888, end_log_pos 9306420; Could not execute Update_rows event on table shop.sessions; Deadlock found when trying to get lock; try restarting transaction, Error_code: 1213; handler error HA_ERR_LOCK_DEADLOCK; the event's master log mysql-bin.011888, end_log_pos 9306420, Error_code: 1213 2016-10-25 10:00:01 165238 [ERROR] Slave SQL: ... The slave coordinator and worker threads are stopped, possibly leaving data in inconsistent state. A restart should restore consistency automatically, although using non-transactional storage for data or info tables or DDL queries could lead to problems. In such cases you have to examine your data (see documentation for details). Error_code: 1756 2016-10-25 10:00:01 165238 [Note] Error reading relay log event: slave SQL thread was killed

可能是什么原因死了?没有跨数据库的DML语句,我想通过使用MTS,每个数据库只使用一个线程(MTS的好处是在多个数据库中使用并行复制)?为什么复制会导致死锁?

编辑2016年10月28日:

表的模式,看起来像

CREATE TABLE `sessions` (
    `id` int(11) NOT NULL, 
    `session_id` char(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, 
    `crypt_iv` blob NOT NULL, 
    `data` mediumblob NOT NULL, 
    `user_id` int(11) NOT NULL, 
    `last_refresh` datetime NOT NULL, 
    `timeout` datetime NOT NULL, 
    `closed` tinyint(4) NOT NULL, 
    `inserted` datetime NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
ALTER TABLE `sessions` 
    ADD PRIMARY KEY (`id`), 
    ADD UNIQUE KEY `session_id` (`session_id`), 
    ADD KEY `user_id` (`user_id`), 
    ADD KEY `timeout` (`timeout`); 
ALTER TABLE `sessions` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 

在时间这个错误只发生在后端侧,从来没有前端服务器上。目前,由于二进制日志被清除,我无法粘贴确切的语句。但是这个GTID事务中唯一的声明是表中的一个基于行的UPDATE。

+0

你使用“基于行的复制”吗? EVENT做什么?我们来看看SHOW CREATE TABLE的问题。 –

+0

在两台机器上是否宣布事件?他们应该是? (触发器通常不应该) –

回答

1

我想所有会话都是在前端服务器上创建的。在后端服务器上是否有会话清理作业?所以你在两台机器的表上都有写入。如果你有一个写入繁重的表格作为会话,你只能将它写在一台机器上以避免这种死锁。

实际上,您应该始终只在一台机器上执行所有写操作,除了故障切换情况下,当一台主机出现故障时。

haproxy和运行状况检查有很好的设置,让您的客户可以自动处理故障转移并且透明。

+0

真的,有一个会话清理工作,但它已经在前端服务器上运行了。在发生死锁时(大多是午夜),我们的员工在家,没有人在管理员后台工作,因此会话表中唯一的写入来自前端服务器。 – rabudde

+0

是否有另一份工作在后端主文件上进行写入?如果是在午夜,它可能是一个cronjob。也许一些备份相关的任务。我已经看到只有在多个主机上写入同一个db的死锁。这也是为什么percona建议在一个时间点在单台机器上进行所有写入操作的原因。 – edlerd

+0

每日备份运行时,大多数死锁都会在mignight上发生。但是我们使用Perconas'innobackupex'应该可以防止这种故障。但是在中午也有一些僵局,这不能用正在运行的备份来解释。 – rabudde