Я изо всех сил пытаюсь разобраться в проблеме тупика, которую мы имели, когда мы отправляем материализацию некоторых столбцов, когда что-то изменилось в другом месте в базе данных.MySQL тупик при обновлении всей таблицы
По существу, процедура материализации сбрасывает соответствующие столбцы в 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
, выполненный вскоре после завершения запроса.
Мои единственные идеи - удалить заказ, что не имеет значения в этих случаях. И, возможно, посмотрите на индексы?
У меня есть подозрение, что это происходит, когда несколько запросов запускают эти материализации примерно в одно и то же время, и они наступают друг на друга.
Пожалуйста, дайте мне знать, какую другую информацию вам будет удобно знать.
UPDATE
Вот вывод (или начало его) из 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;;
UPDATE 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
UPDATE 3
Мое подозрение в том, что большой запрос выше заказывает отличается от остальных запросов. Я исправил это в своем производственном коде, чтобы узнать, устраняет ли это проблему.
Какой двигатель хранения вы используете? – SpacePhoenix
Можете ли вы показать нам, какие запросы вызывают тупик? Вы можете найти по «SHOW ENGINE INNODB STATUS», см. [Здесь] (http://dba.stackexchange.com/a/1740/89670) для получения дополнительной информации (при условии, что вы используете движок INNODB). Из этого вы можете найти, действительно ли это два запроса одновременно, которые вызывают взаимоблокировки (скорее всего, IMO) или что-то еще. – BoraMa
@SpacePhoenix: Innodb. –