更新整个表

时间:2016-04-08 05:34:28

标签: mysql ruby-on-rails database-deadlocks

当我们在数据库中其他地方发生某些变化时,我们一直在实现某些列时,我一直在努力解决我们遇到的死锁问题。

实质上,实现例程会将相关列重置为NULL,然后在必要时添加值(对于大多数项,列将保持为NULL)。

以下是几个示例查询:

UPDATE `component_instances` SET `view_user_ids` = NULL, `edit_user_ids` = NULL ORDER BY component_instances.ancestry, position

UPDATE `component_instances` SET `edit_user_ids` = '9,6' WHERE (((`component_instances`.`id` = 3 OR `component_instances`.`ancestry` LIKE '1/3/%') OR `component_instances`.`ancestry` = '1/3')) ORDER BY component_instances.ancestry, position

我只看到了生产中的问题(使其更难以排除故障),并且当我将实现作为请求的一部分更改其他相关数据时,它比我排队时更频繁地发生在请求完成后不久执行delayed_job

我唯一的想法是删除顺序,这在这些情况下无关紧要。可能看一下索引?

我有一种预感,当多个请求几乎同时触发这些物质化并且他们踩到彼此的脚趾时会发生这种情况吗?

请让我知道其他哪些信息会很方便。

更新

以下是SHOW ENGINE INNODB STATUS的输出(或其开头):

LATEST DETECTED DEADLOCK
------------------------
160406 23:03:05
*** (1) TRANSACTION:
TRANSACTION 3A787847, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1248, 4 row lock(s)
MySQL thread id 437042, OS thread handle 0x7f488b80c700, query id 13820202 localhost xxxxxxxxxxxx init
UPDATE `component_instances` SET `edit_user_ids` = '3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,29,30,35,37,38,39,40' WHERE (((`component_instances`.`id` = 125 OR `component_instances`.`ancestry` LIKE '1/14/22/125/%') OR `component_instances`.`ancestry` = '1/14/22/125')) ORDER BY component_instances.ancestry, position
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 124313 n bits 152 index `PRIMARY` of table `450273b5d362920c`.`component_instances` trx id 3A787847 lock_mode X locks rec but not gap waiting
Record lock, heap no 19 PHYSICAL RECORD: n_fields 19; compact format; info bits 0
0: len 4; hex 8000007d; asc    };;
1: len 6; hex 00003a787842; asc   :xxB;;
2: len 7; hex 54000217c52716; asc T    ' ;;
3: len 1; hex 81; asc  ;;
4: len 4; hex 80000021; asc    !;;
5: SQL NULL;
6: len 4; hex 50616765; asc Page;;
7: len 4; hex 80000003; asc     ;;
8: SQL NULL;
9: SQL NULL;
10: SQL NULL;
11: len 4; hex 80000001; asc     ;;
12: len 7; hex 312f31342f3232; asc 1/14/22;;
13: len 4; hex 80000003; asc     ;;
14: len 30; hex 4c6974657261637920617420546175706f205072696d617279205363686f; asc Literacy at XXXXXXXXXXX Scho; (total 32 bytes);
15: SQL NULL;
16: len 6; hex 332c342c3135; asc 3,4,15;;
17: len 1; hex 81; asc  ;;
18: SQL NULL;

*** (2) TRANSACTION:
TRANSACTION 3A787846, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
180 lock struct(s), heap size 31160, 12416 row lock(s)
MySQL thread id 437041, OS thread handle 0x7f488b6e6700, query id 13820201 localhost xxxxxxxxxxxxxxx init
UPDATE `component_instances` SET `view_user_ids` = NULL, `edit_user_ids` = NULL ORDER BY component_instances.ancestry, position
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 124313 n bits 152 index `PRIMARY` of table `450273b5d362920c`.`component_instances` trx id 3A787846 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;;

更新2

目前ancestry列上有一个索引,就是它(除ID之外)。

目前没有围绕这些更新的交易:

UPDATE `component_instances` SET `view_user_ids` = NULL, `edit_user_ids` = NULL ORDER BY component_instances.ancestry, position
  Permission Exists (0.4ms)  SELECT 1 AS one FROM `permissions` LIMIT 1
  ComponentInstance Load (17.0ms)  SELECT component_instances.*, GROUP_CONCAT(DISTINCT view_groups_users.user_id) AS calculated_view_user_ids, GROUP_CONCAT(DISTINCT edit_groups_users.user_id) AS calculated_edit_user_ids FROM `component_instances` LEFT OUTER JOIN permissions ON permissions.component_instance_id = component_instances.id LEFT OUTER JOIN groups view_groups ON view_groups.id = permissions.group_id AND permissions.view = 1 LEFT OUTER JOIN groups edit_groups ON edit_groups.id = permissions.group_id AND permissions.edit = 1 LEFT OUTER JOIN groups_users view_groups_users ON view_groups_users.group_id = view_groups.id LEFT OUTER JOIN groups_users edit_groups_users ON edit_groups_users.group_id = edit_groups.id GROUP BY component_instances.id ORDER BY component_instances.ancestry
  SQL (4.5ms)  UPDATE `component_instances` SET `edit_user_ids` = '6' WHERE (((`component_instances`.`id` = 2 OR `component_instances`.`ancestry` LIKE '1/2/%') OR `component_instances`.`ancestry` = '1/2')) ORDER BY component_instances.ancestry, position
  SQL (6.9ms)  UPDATE `component_instances` SET `edit_user_ids` = '9,6' WHERE (((`component_instances`.`id` = 3 OR `component_instances`.`ancestry` LIKE '1/3/%') OR `component_instances`.`ancestry` = '1/3')) ORDER BY component_instances.ancestry, position
  SQL (0.9ms)  UPDATE `component_instances` SET `edit_user_ids` = '9' WHERE (((`component_instances`.`id` = 6 OR `component_instances`.`ancestry` LIKE '1/3/6/%') OR `component_instances`.`ancestry` = '1/3/6')) ORDER BY component_instances.ancestry, position
  SQL (0.7ms)  UPDATE `component_instances` SET `view_user_ids` = '6' WHERE (((`component_instances`.`id` = 9 OR `component_instances`.`ancestry` LIKE '1/3/9/%') OR `component_instances`.`ancestry` = '1/3/9')) ORDER BY component_instances.ancestry, position
  SQL (1.4ms)  UPDATE `component_instances` SET `view_user_ids` = '9' WHERE (((`component_instances`.`id` = 118 OR `component_instances`.`ancestry` LIKE '1/118/%') OR `component_instances`.`ancestry` = '1/118')) ORDER BY component_instances.ancestry, position
  SQL (1.5ms)  UPDATE `component_instances` SET `view_user_ids` = '9,6' WHERE (((`component_instances`.`id` = 120 OR `component_instances`.`ancestry` LIKE '1/120/%') OR `component_instances`.`ancestry` = '1/120')) ORDER BY component_instances.ancestry, position
  SQL (2.3ms)  UPDATE `component_instances` SET `edit_user_ids` = '9' WHERE (((`component_instances`.`id` = 120 OR `component_instances`.`ancestry` LIKE '1/120/%') OR `component_instances`.`ancestry` = '1/120')) ORDER BY component_instances.ancestry, position
  SQL (1.0ms)  UPDATE `component_instances` SET `view_user_ids` = '9' WHERE (((`component_instances`.`id` = 119 OR `component_instances`.`ancestry` LIKE '1/120/119/%') OR `component_instances`.`ancestry` = '1/120/119')) ORDER BY component_instances.ancestry, position
  SQL (0.7ms)  UPDATE `component_instances` SET `edit_user_ids` = '9' WHERE (((`component_instances`.`id` = 119 OR `component_instances`.`ancestry` LIKE '1/120/119/%') OR `component_instances`.`ancestry` = '1/120/119')) ORDER BY component_instances.ancestry, position
  SQL (0.7ms)  UPDATE `component_instances` SET `view_user_ids` = '6' WHERE (((`component_instances`.`id` = 121 OR `component_instances`.`ancestry` LIKE '1/120/121/%') OR `component_instances`.`ancestry` = '1/120/121')) ORDER BY component_instances.ancestry, position
  SQL (0.8ms)  UPDATE `component_instances` SET `edit_user_ids` = '6' WHERE (((`component_instances`.`id` = 121 OR `component_instances`.`ancestry` LIKE '1/120/121/%') OR `component_instances`.`ancestry` = '1/120/121')) ORDER BY component_instances.ancestry, position
  SQL (3.9ms)  UPDATE `component_instances` SET `recursively_visible` = 1 ORDER BY component_instances.ancestry, position
  ComponentInstance Load (0.6ms)  SELECT `component_instances`.* FROM `component_instances` WHERE `component_instances`.`visible` = 0 ORDER BY component_instances.ancestry, position

更新3

我怀疑上面的大型查询与其他查询的排序方式不同。我已经在我的生产代码中修复了这个问题,看看这是否解决了这个问题。

1 个答案:

答案 0 :(得分:0)

在这种特殊情况下,问题是SQL的几个不同位的ORDER BY子句在同一时间运行时存在差异。我覆盖了不正确的订单,一切都很顺利。