Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как вычислить деадлок? / 25 сообщений из 28, страница 1 из 2
24.09.2013, 09:23:42
    #38405521
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
На большом проекте по мере возрастания нагрузки стали появляться деадлоки, анализ кода результатов не дал. Да и вообще не понятно в каком именно месте возникают дедлоки, в триггерах таблицы, на которую ругается мускуль есть несколько запросов и так понимаю проблема как раз в каком-то(каких-то) из них. Как вычислить?
...
Рейтинг: 0 / 0
24.09.2013, 09:24:19
    #38405522
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Вообще ошибка происходит при инесерте.
...
Рейтинг: 0 / 0
24.09.2013, 10:30:30
    #38405603
Shahriyar.R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Hett,

Please give us:

1. Which MySQL version?
2. Which storage engine?
3. Which insert?
4. which select?(if any)
5. table structure of main tables.

and any other valuable information...
...
Рейтинг: 0 / 0
24.09.2013, 10:53:19
    #38405635
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
MySQL 5.5, InnoDb

структуру таблиц и запросы все же выкладывать не хотелось бы, да и их слишком много, не думаю что кто-то захочет во всем этом копаться. Я думал может есть какие-то специализированные штучки-дрючки для выявления сих проблем.
...
Рейтинг: 0 / 0
24.09.2013, 11:03:29
    #38405649
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
нашел вроде тут :)

SHOW ENGINE INNODB STATUS
...
Рейтинг: 0 / 0
24.09.2013, 11:11:38
    #38405662
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Похоже что происходит в этом месте:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  IF NEW.parent_id THEN
    SELECT uf.level + 1, uf.tree_id
      INTO _new_level, _new_tree_id
    FROM fh_user_file uf
    WHERE id = NEW.parent_id;

    SET NEW.level = _new_level;
    SET NEW.tree_id = _new_tree_id;
  ELSE
    SET NEW.level = 0;
    SET NEW.tree_id = (SELECT MAX(tree_id)+1 FROM fh_user_file);
  END IF;




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
------------------------
LATEST DETECTED DEADLOCK
------------------------
130924  7:00:07
*** (1) TRANSACTION:
TRANSACTION B52E35C8, ACTIVE 1 sec inserting
mysql tables in use 9, locked 9
LOCK WAIT 8 lock struct(s), heap size 1248, 5 row lock(s), undo log entries 2
MySQL thread id 3468696, OS thread handle 0x7ff4e66ed700, query id 87285070 localhost 
INSERT INTO `fh_user_file`[вырезано]
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 961034 n bits 408 index `IX_user_file_tree_id_level` of table `fh_user_file` trx id B52E35C8 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) TRANSACTION:
TRANSACTION B52E33E8, ACTIVE 2 sec inserting
mysql tables in use 9, locked 9
9 lock struct(s), heap size 1248, 6 row lock(s), undo log entries 2
MySQL thread id 3468641, OS thread handle 0x7ff4e71d6700, query id 87284027 localhost 
INSERT INTO `fh_user_file` [вырезано]
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 961034 n bits 408 index `IX_user_file_tree_id_level` of table `fh_user_file` trx id B52E33E8 lock mode S
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 336 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 002418b7; asc  $  ;;
 1: len 1; hex 00; asc  ;;
 2: len 13; hex 35323431333836313163303736; asc 524138611c076;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 961034 n bits 408 index `IX_user_file_tree_id_level` of table `fh_user_file` trx id B52E33E8 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;
...
Рейтинг: 0 / 0
24.09.2013, 11:11:59
    #38405663
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
SQL код - это триггер BEFORE UPDATE ON fh_user_file
...
Рейтинг: 0 / 0
24.09.2013, 11:19:44
    #38405678
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Код: sql
1.
SET NEW.tree_id = (SELECT MAX(tree_id)+1 FROM fh_user_file);


За такое канделябрами еще не били?
Либо пересматривайте структуру хранения, либо хотя бы блокируйте всю таблицу fh_user_file перед выполнением SQL-запроса, который вызывает сработку этого триггера.
...
Рейтинг: 0 / 0
24.09.2013, 11:25:49
    #38405685
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Shahriyar.R
4. which select?(if any)



SELECT-ы для этого не нужны. Они не будут участвовать в deadlock-ах.
...
Рейтинг: 0 / 0
24.09.2013, 11:29:16
    #38405690
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
miksoft
Код: sql
1.
SET NEW.tree_id = (SELECT MAX(tree_id)+1 FROM fh_user_file);


За такое канделябрами еще не били?
Либо пересматривайте структуру хранения, либо хотя бы блокируйте всю таблицу fh_user_file перед выполнением SQL-запроса, который вызывает сработку этого триггера.

+1. вот он и deadlock.
...
Рейтинг: 0 / 0
24.09.2013, 12:23:11
    #38405815
Shahriyar.R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
MasterZiv,

with selects i mean maybe some lock for selects exist before insert or smth else.
i found here:
mysql tables in use 9, locked 9

if it is means that at the moment of deadlock there was 9 table lock,maybe some other process executing with this one..
because i see only 1 table here in trigger. or i am wrong?
...
Рейтинг: 0 / 0
24.09.2013, 12:25:04
    #38405823
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Да я уж понял, это место сразу не понравилось. К тому же велика вероятность дубликата. Когда нагрузка была совсем маленькой этой проблемой никто не заморачивался, видимо. Как теперь это переделать малой кровью что-то ума не приложу, автоинкремент сюда никак не приделать, есть ли какие счетчики?
...
Рейтинг: 0 / 0
24.09.2013, 12:27:11
    #38405827
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Shahriyar.Rbecause i see only 1 table here in trigger. or i am wrong?
я выложил только часть триггера
...
Рейтинг: 0 / 0
24.09.2013, 12:36:15
    #38405847
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
miksoftлибо хотя бы блокируйте всю таблицу fh_user_file перед выполнением SQL-запроса
Где-то тут создавал тему на счет того, что при удалении больших данных из одной таблицы, запись или чтенеи из другой начинает лажать. В случае блокировки WRITE боюсь вообще из этой таблицы никто ничего не сможет прочитать, в таких случаях.
...
Рейтинг: 0 / 0
24.09.2013, 12:55:17
    #38405896
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Можно синхронизировать с помощью http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock
...
Рейтинг: 0 / 0
24.09.2013, 13:27:49
    #38405970
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Как бы это ужасно не было, лучше способа не придумал.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  IF GET_LOCK("Lock_insert_user_file", 60) THEN
    IF NEW.parent_id THEN
      SELECT uf.level + 1, uf.tree_id
        INTO _new_level, _new_tree_id
      FROM fh_user_file uf
      WHERE id = NEW.parent_id;

      SET NEW.level = _new_level;
      SET NEW.tree_id = _new_tree_id;
    ELSE
      SET NEW.level = 0;
      SET NEW.tree_id = (SELECT value FROM fh_settings WHERE param = "user_file_tree_max_id");
      UPDATE fh_settings SET value = value + 1 WHERE param = "user_file_tree_max_id";
    END IF;
  END IF;

  SET lock_result = RELEASE_LOCK("Lock_insert_user_file");
...
Рейтинг: 0 / 0
24.09.2013, 13:59:48
    #38406047
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Лучше так, но общей сути не меняет

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
  IF NEW.parent_id THEN
    SELECT uf.level + 1, uf.tree_id
      INTO _new_level, _new_tree_id
    FROM fh_user_file uf
    WHERE id = NEW.parent_id;

    SET NEW.level = _new_level;
    SET NEW.tree_id = _new_tree_id;
  ELSE
    IF GET_LOCK("Lock_insert_user_file", 60) THEN
      SET NEW.level = 0;
      SET NEW.tree_id = (SELECT value FROM fh_settings WHERE param = "user_file_tree_max_id");
      UPDATE fh_settings SET value = value + 1 WHERE param = "user_file_tree_max_id";
      SET lock_result = RELEASE_LOCK("Lock_insert_user_file");
    END IF;
  END IF;
...
Рейтинг: 0 / 0
24.09.2013, 15:58:36
    #38406256
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Shahriyar.RMasterZiv,

with selects i mean maybe some lock for selects exist before insert or smth else.


В InnoDB select (без for update) проходит без блокировок. И дедлоков соотв. не может быть от него.
И дедлок может быть только на InnoDB.
Соответственно, SELECT никогда в дедлоках не участвует.
...
Рейтинг: 0 / 0
24.09.2013, 16:00:10
    #38406262
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
HettКак бы это ужасно не было, лучше способа не придумал.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  IF GET_LOCK("Lock_insert_user_file", 60) THEN
    IF NEW.parent_id THEN
      SELECT uf.level + 1, uf.tree_id
        INTO _new_level, _new_tree_id
      FROM fh_user_file uf
      WHERE id = NEW.parent_id;

      SET NEW.level = _new_level;
      SET NEW.tree_id = _new_tree_id;
    ELSE
      SET NEW.level = 0;
      SET NEW.tree_id = (SELECT value FROM fh_settings WHERE param = "user_file_tree_max_id");
      UPDATE fh_settings SET value = value + 1 WHERE param = "user_file_tree_max_id";
    END IF;
  END IF;

  SET lock_result = RELEASE_LOCK("Lock_insert_user_file");



Тем не менее это уже намного лучше, чем было.
...
Рейтинг: 0 / 0
24.09.2013, 16:02:22
    #38406268
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
HettЛучше так, но общей сути не меняет


Лучше -- так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
  IF NEW.parent_id THEN
    SELECT uf.level + 1, uf.tree_id
      INTO _new_level, _new_tree_id
    FROM fh_user_file uf
    WHERE id = NEW.parent_id;

    SET NEW.level = _new_level;
    SET NEW.tree_id = _new_tree_id;
  ELSE
    IF GET_LOCK("Lock_insert_user_file", 60) THEN
      SET NEW.level = 0;
      UPDATE fh_settings SET value = value + 1 WHERE param = "user_file_tree_max_id";
      SET NEW.tree_id = (SELECT value -1 FROM fh_settings WHERE param = "user_file_tree_max_id");
      SET lock_result = RELEASE_LOCK("Lock_insert_user_file");
    END IF;
  END IF;



И тогда GET_LOCK/ RELEASE_LOCK можно будет убрать.
Да, надеюсь, этот код весь в объемлющей транзакции.
...
Рейтинг: 0 / 0
24.09.2013, 17:02:44
    #38406359
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
В транзакции.
А чем ваш вариант лучше?
...
Рейтинг: 0 / 0
24.09.2013, 19:42:18
    #38406550
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
HettВ транзакции.
А чем ваш вариант лучше?

Блокирует сначала строку таблицы, откуда берётся ID, а потом из неё читает значение.

В твоём варианте всё наоборот -- сначала значение читается, потом блокируется.
В итоге одно значение ключа может быть использовано многими сессиями.

Можно и как ты делал, но надо добавить в SELECT фразу FOR UPDATE.
...
Рейтинг: 0 / 0
24.09.2013, 19:55:22
    #38406557
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
MasterZivHettВ транзакции.
А чем ваш вариант лучше?

Блокирует сначала строку таблицы, откуда берётся ID, а потом из неё читает значение.

В твоём варианте всё наоборот -- сначала значение читается, потом блокируется.
В итоге одно значение ключа может быть использовано многими сессиями.

Можно и как ты делал, но надо добавить в SELECT фразу FOR UPDATE.

Каким образом он ее блокирует?
...
Рейтинг: 0 / 0
24.09.2013, 20:11:00
    #38406568
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
HettMasterZivпропущено...


Блокирует сначала строку таблицы, откуда берётся ID, а потом из неё читает значение.

В твоём варианте всё наоборот -- сначала значение читается, потом блокируется.
В итоге одно значение ключа может быть использовано многими сессиями.

Можно и как ты делал, но надо добавить в SELECT фразу FOR UPDATE.

Каким образом он ее блокирует?

Накладывая UPDATE-блокировку, каким же ещё...
...
Рейтинг: 0 / 0
24.09.2013, 20:14:00
    #38406572
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вычислить деадлок?
Дык эта блокировка разве будет действовать после выполнения этого UPDATE запроса?
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как вычислить деадлок? / 25 сообщений из 28, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]