powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как вычислить деадлок?
25 сообщений из 28, страница 1 из 2
Как вычислить деадлок?
    #38405521
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На большом проекте по мере возрастания нагрузки стали появляться деадлоки, анализ кода результатов не дал. Да и вообще не понятно в каком именно месте возникают дедлоки, в триггерах таблицы, на которую ругается мускуль есть несколько запросов и так понимаю проблема как раз в каком-то(каких-то) из них. Как вычислить?
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #38405522
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще ошибка происходит при инесерте.
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #38405635
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MySQL 5.5, InnoDb

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

SHOW ENGINE INNODB STATUS
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #38405663
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL код - это триггер BEFORE UPDATE ON fh_user_file
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #38405678
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
SET NEW.tree_id = (SELECT MAX(tree_id)+1 FROM fh_user_file);


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



SELECT-ы для этого не нужны. Они не будут участвовать в deadlock-ах.
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #38405823
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да я уж понял, это место сразу не понравилось. К тому же велика вероятность дубликата. Когда нагрузка была совсем маленькой этой проблемой никто не заморачивался, видимо. Как теперь это переделать малой кровью что-то ума не приложу, автоинкремент сюда никак не приделать, есть ли какие счетчики?
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #38405827
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shahriyar.Rbecause i see only 1 table here in trigger. or i am wrong?
я выложил только часть триггера
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #38405847
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftлибо хотя бы блокируйте всю таблицу fh_user_file перед выполнением SQL-запроса
Где-то тут создавал тему на счет того, что при удалении больших данных из одной таблицы, запись или чтенеи из другой начинает лажать. В случае блокировки WRITE боюсь вообще из этой таблицы никто ничего не сможет прочитать, в таких случаях.
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #38405896
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно синхронизировать с помощью http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #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
Как вычислить деадлок?
    #38406359
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В транзакции.
А чем ваш вариант лучше?
...
Рейтинг: 0 / 0
Как вычислить деадлок?
    #38406550
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettВ транзакции.
А чем ваш вариант лучше?

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

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

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

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

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

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

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


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

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

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

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

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


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