【发布时间】:2018-07-11 07:53:27
【问题描述】:
对不起,很长的文字,我认为我在 mysql 数据库或 PDO/mysqli 内部遇到了一个错误,并尝试尽可能好地解释这种情况。 我故意没有发布代码,在那种情况下它不相关。
我有一个非常繁忙的 mysql 服务器,平均每秒查询 1000 个,每天大约有 100 万个连接。
我运行 mysql 5.5.42 和 php 5.6.33
我希望我可以升级,但它是一个生产环境,我不想在更新期间冒风险。
我使用 Innodb 作为数据库引擎(50GB 内存用于缓冲区)
现在我的问题是我有随机、可重复的死锁,没有并发查询,也没有使用事务。
它会影响几个表和脚本。
在 INSERT 和 UPDATE 期间发生死锁。
我已经缩小了一些位置,从 mysql 理论来看,在任何情况下都不会出现死锁。
不使用事务,在 WHERE 子句中的单个(主)ID 上进行简单的 INSERT 或 UPDATE。
我了解死锁是如何发生的,而且我遇到死锁的情况都没有风险。
我已对该问题进行了调试,因为它有时会导致我的脚本完全停止。
我尝试在死锁之后进行 sleep() 并再次插入/更新,但是我可以这样做一千次,但它不会工作,它会永久死锁。
如果我在新的 mysql 会话之外同时执行此操作,则查询有效!
解决此问题的唯一方法是检测死锁,关闭 PDO 连接 ($pdo = null;),重新连接到数据库并重复查询。
虽然这可行,但必须在任何地方引入这种逻辑是相当痛苦的。
我一直在浏览互联网,但找不到与我提到的问题类似的任何内容。所有的死锁通常都是正确的,原因可以理解。
第二个相关问题: 这个比较少见,但似乎相关,它是 INSERT 上的错误 DUPLICATE KEY 错误。它发生在百万分之一的插入中,因此非常罕见。 但在这些情况下,只有 PDO 重新连接才能解决问题。
我很想得到一些意见,也许有人理解这个问题,或者在没有像重新连接这样的黑客攻击的情况下解决了这个问题。
总结:根本没有使用事务(默认自动提交),没有并发查询,innodb 正在使用,简单的单个 INSERT 查询或 WHERE id=1234 的 UPDATE; 死锁只会影响随机行。
这似乎是 mysql 数据库内部的一个错误,可能是会话损坏。
这里的死锁日志: 第一个表也确实有一个死锁问题,每小时一次。 我可以将其追溯到一些非常简单的 UPDATE 查询,这些查询每小时进行一次,它们大约需要 0.05 秒才能完成。 另一个错误日志有数百个条目,没有进一步的细节。
RECORD LOCKS space id 1983 page no 32800 n bits 1616 index start of table `db`.`jobs` trx id 2083002285 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
Record lock, heap no 859 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259d6; asc Y ;;
Record lock, heap no 860 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259d7; asc Y ;;
Record lock, heap no 861 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259d8; asc Y ;;
Record lock, heap no 862 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259d9; asc Y ;;
Record lock, heap no 863 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259da; asc Y ;;
Record lock, heap no 864 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259db; asc Y ;;
Record lock, heap no 865 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259dc; asc Y ;;
Record lock, heap no 866 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259dd; asc Y ;;
Record lock, heap no 867 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259de; asc Y ;;
Record lock, heap no 868 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc ;;
1: len 4; hex 800259df; asc Y ;;
Innodb 状态:
InnoDB
=====================================
2018-02-07 17:21:27 0x7f5b0d32d700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 22 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 64463 srv_active, 0 srv_shutdown, 21 srv_idle
srv_master_thread log flush and writes: 64472
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 2040099
OS WAIT ARRAY INFO: signal count 3213946
RW-shared spins 0, rounds 2165320, OS waits 554744
RW-excl spins 0, rounds 40616534, OS waits 873123
RW-sx spins 532360, rounds 9261545, OS waits 97422
Spin rounds per wait: 2165320.00 RW-shared, 40616534.00 RW-excl, 17.40 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-02-07 17:15:05 0x7f5af7924700
*** (1) TRANSACTION:
TRANSACTION 2109880254, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 147614, OS thread handle 140029031933696, query id 36166552 localhost website Searching rows for update
UPDATE task SET result_delivered=1, result_data='DISABLED', result_gathered=1 WHERE result_data is NULL AND (assigned_counter >= 4 OR other_counter> 1)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 591 page no 20571555 n bits 88 index PRIMARY of table `db`.`task` trx id 2109880254 lock_mode X locks rec but not gap waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 24; compact format; info bits 0
0: len 4; hex 8611338d; asc 3 ;;
1: len 6; hex 00007dc237bc; asc } 7 ;;
2: len 7; hex 3300070012073a; asc 3 :;;
3: len 4; hex 800085dc; asc ;;
4: len 30; hex 226973742064617320776569c39f652042726175746b6c656964206e6963; asc "ist das wei e nic; (total 46 bytes);
5: len 7; hex 44656661756c74; asc Default;;
6: len 2; hex 656e; asc en;;
7: len 0; hex ; asc ;;
8: len 2; hex 8032; asc 2;;
9: len 1; hex b2; asc ;;
10: len 2; hex 8001; asc ;;
11: len 4; hex 80030ea7; asc ;;
12: len 19; hex 692d3036626437323830373833326335656230; asc i-06bd72807832c5eb0;;
13: SQL NULL;
14: len 30; hex 7b22636f756e745f6f7267616e6963223a31332c22636f756e745f637265; asc {"count_organic":13,"count_cre; (total 5060 bytes);
15: len 4; hex 5a7b3419; asc Z{4 ;;
16: len 1; hex 81; asc ;;
17: len 1; hex 80; asc ;;
18: len 1; hex 80; asc ;;
19: len 3; hex 80000d; asc ;;
20: len 3; hex 800000; asc ;;
21: len 1; hex 80; asc ;;
22: len 1; hex 81; asc ;;
23: len 1; hex 80; asc ;;
*** (2) TRANSACTION:
TRANSACTION 2109880252, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 146705, OS thread handle 140028677342976, query id 36166547 localhost ss updating
UPDATE task SET result_count_creative='0'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 591 page no 20571555 n bits 88 index PRIMARY of table `db`.`task` trx id 2109880252 lock_mode X locks rec but not gap
Record lock, heap no 5 PHYSICAL RECORD: n_fields 24; compact format; info bits 0
0: len 4; hex 8611338d; asc 3 ;;
1: len 6; hex 00007dc237bc; asc } 7 ;;
2: len 7; hex 3300070012073a; asc 3 :;;
3: len 4; hex 800085dc; asc ;;
4: len 30; hex 226973742064617320776569c39f652042726175746b6c656964206e6963; asc "ist das wei e nic; (total 46 bytes);
5: len 7; hex 44656661756c74; asc Default;;
6: len 2; hex 656e; asc en;;
7: len 0; hex ; asc ;;
8: len 2; hex 8032; asc 2;;
9: len 1; hex b2; asc ;;
10: len 2; hex 8001; asc ;;
11: len 4; hex 80030ea7; asc ;;
12: len 19; hex 692d3036626437323830373833326335656230; asc i-06bd72807832c5eb0;;
13: SQL NULL;
14: len 30; hex 7b22636f756e745f6f7267616e6963223a31332c22636f756e745f637265; asc {"count_organic":13,"count_cre; (total 5060 bytes);
15: len 4; hex 5a7b3419; asc Z{4 ;;
16: len 1; hex 81; asc ;;
17: len 1; hex 80; asc ;;
18: len 1; hex 80; asc ;;\
【问题讨论】:
-
动态设置全局 innodb_print_all_deadlocks=1;请花几个小时并发布生成的error.log。记住下班后,SET GLOBAL innodb_print_all_deadlocks=0;如果合适的话。
-
@WilsonHauck 我会将问题中的内容作为更新发布
-
感谢更新,这是 2 小时的 error.log 吗?我们还需要 SHOW ENGINE INNODB STATUS; ,请完整 my.cnf/ini。
-
@WilsonHauck 这只是一小部分,还有很多,主要是那些“物理”部分。我正在更新我的 q 中的状态。该查询“UPDATE task SET result_delivered=1, result_data='DISABLED', result_gathered=1 WHERE result_data is NULL AND (assigned_counter >= 4 OR other_counter> 1)”是导致死锁的查询之一。它们每分钟都是由 crontab 制作的。我已经对其进行了测试,它只需要几分之一秒即可完成。
-
似乎只发布了 SHOW ENGINE INNODB STATUS 的一部分。现在,请发布 A) SHOW CREATE TABLE 任务的完整结果; B:SHOW INDEX FROM 任务;用于分析可用索引。我认为您在欧洲是因为时间差异。