2016-04-08 3 views
0

Я изо всех сил пытаюсь разобраться в проблеме тупика, которую мы имели, когда мы отправляем материализацию некоторых столбцов, когда что-то изменилось в другом месте в базе данных.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

Мое подозрение в том, что большой запрос выше заказывает отличается от остальных запросов. Я исправил это в своем производственном коде, чтобы узнать, устраняет ли это проблему.

+0

Какой двигатель хранения вы используете? – SpacePhoenix

+1

Можете ли вы показать нам, какие запросы вызывают тупик? Вы можете найти по «SHOW ENGINE INNODB STATUS», см. [Здесь] (http://dba.stackexchange.com/a/1740/89670) для получения дополнительной информации (при условии, что вы используете движок INNODB). Из этого вы можете найти, действительно ли это два запроса одновременно, которые вызывают взаимоблокировки (скорее всего, IMO) или что-то еще. – BoraMa

+0

@SpacePhoenix: Innodb. –

ответ

0

В этом конкретном случае проблема заключалась в том, что в предложении ORDER BY возникла пара различных битов SQL, запущенных в одно и то же время. Я перепробовал неправильный порядок, и с тех пор все хорошо.

Смежные вопросы