Обработка дедлоков в mysql
TRANSCRIPT
![Page 2: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/2.jpg)
• Дедлок - что это такое• Неправильная организация доступа к данным + пример
• Специфика работы блокировок MySql
• Узнаем больше (SHOW ENGINE INNODB STATUS)
Содержание
![Page 3: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/3.jpg)
Что это такоеДедлок - ситуация,
в которой 2 или более процесса ждут друг от другаосвобождения занятых ресурсов, или более двух процессов
ждут ресурсы в циклической порядке( http://en.wikipedia.org/wiki/Deadlock )
![Page 4: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/4.jpg)
Что это такое
Транзакция 1 Транзакция 2
select name from events where id = 1 for update
select name from eventswhere id = 2 for update
select name from eventswhere id = 2 for update
select name from events where id = 1 for updateFAIL
InnoDB автоматически распознает дедлокии откатывает одну из транзакций
простой пример
![Page 5: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/5.jpg)
Что это такоеЕще более простой пример
![Page 6: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/6.jpg)
Причины дедлоков
• Неправильная организация доступа к данным
• Специфика работы блокировок в БД
![Page 7: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/7.jpg)
Причины дедлоков
• Отсутствие фиксированного порядка обращения к таблицам и записям
• Некорректно спроектированная БД
Неправильная организация доступа к данным
Неправильная организация доступа к данным
![Page 8: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/8.jpg)
Неправильная организация доступа к
данным
![Page 9: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/9.jpg)
Что это такое
Транзакция 1 Транзакция 2
select name from events where id = 1 for update
select name from eventswhere id = 2 for update
select name from eventswhere id = 2 for update
select name from events where id = 1 for updateFAIL
Отсутствие фиксированного порядка доступа
В порядкевозрастания
В порядкеубывания
Неправильная организация доступа к данным
![Page 10: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/10.jpg)
Порядок доступа
• все манипуляции с данными лучше проводить в условленном порядке
• например, в порядке возрастания первичного ключа
• это снижает вероятность дедлоков
Неправильная организация доступа к данным
![Page 11: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/11.jpg)
• Отсутствие необходимых индексов• Иногда нужно разносить 1 таблицу на несколько, если она несет слишком много смысловой нагрузки
Некорректно спроектированная БД
Неправильная организация доступа к данным
![Page 12: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/12.jpg)
Пример(основан на реальных событиях)
![Page 13: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/13.jpg)
Исходная задача
• очередь событий (events)
• много операторов-клиентов, обрабатывающих события в режиме FIFO
(слегка анонимизирована)
Пример
![Page 14: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/14.jpg)
Структура данныхEVENTS
id title user_id event_time locked_at
... ... ... ... ...
Индекс по полю locked_at
Пример
![Page 15: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/15.jpg)
first_unprocessed, v1
SELECT id AS event_id, ... FROM events WHERE locked_at IS NULL OR locked_at < [1.minute.ago]ORDER BY event_time ASC LIMIT 1FOR UPDATE
UPDATE events SET locked_at = [Time.now] WHERE id = [event_id]
Находим первое необработанное событие, “занимаем” его и возвращаем оператору:
Пример
![Page 16: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/16.jpg)
touch v1
UPDATE events SET locked_at = [Time.now] WHERE id = [event_id]
Обновляем блокировку, если обработка занимает более одной минуты
(event_id получаем от клиента):
Пример
![Page 17: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/17.jpg)
DEADLOCK!
first_unprocessed touch
index_events_on_locked_at(при выборке
SELECT * ... FOR UPDATE)
PRIMARY_KEY(в условии UPDATE)
PRIMARY_KEY(при обновлении)
index_events_on_locked_at(при обновлении)
(Различные пути доступа к данным)
Пример
![Page 18: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/18.jpg)
touch v2
UPDATE events SET locked_at = [Time.now] WHERE id = [event_id]
Используем результат запроса из first_unprocessed в качестве семафора, после чего обновляем
блокировку:
SELECT id AS event_id FROM events WHERE ...FOR UPDATE
Пример
![Page 19: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/19.jpg)
Пример
![Page 20: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/20.jpg)
first_unapproved v2Новое требование:
выбирать события для указанного юзера.В запрос добавляется условие user_id = [user_id]
Новая проблема:Для пользователей с малым кол-вом записей
MySql использует индекс по user_id(снова различные пути доступа)
Решение? FORCE INDEX index_events_on_locked_at
Пример
![Page 21: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/21.jpg)
Проблемы
• снижение скорости работы при увеличении размеров таблицы
• конфликты с другими частями приложения, использующими Events
Пример
![Page 22: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/22.jpg)
Решение
• Отдельная таблица для блокировок• Записи добавляются/удаляются в
Event#after_create/update/destroy
EVENT_LOCKS
id event_id user_id event_time locked_at
... ... ... ... ...
Изменения в структуре БД
Пример
![Page 23: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/23.jpg)
Summary
• Унифицировать порядок обращения• Разнести конфликтующий функционал по разным таблицам
Дедлоки, обусловленные неправильной организациейдоступа к данным, можно устранить:
Неправильная организация доступа к данным
![Page 24: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/24.jpg)
Специфика работы блокировок в MySql
![Page 25: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/25.jpg)
Причины дедлоков
• MySql 5.0
• InnoDB
• InnoDB блокирует не строки таблицы, а записи индексов
• (если в таблице нет индексов, InnoDB создает скрытый)
специфика работы блокировок MySql
Cпецифика работы блокировок MySql
![Page 26: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/26.jpg)
Блокировки в MySql
Row Lock Блокировка записи индекса
Next-key LockRow lock + блокировка
“промежутка” записей индекса
Cпецифика работы блокировок MySql
![Page 27: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/27.jpg)
Row Lock• Блокируется только одна запись• Используется только при выборке с использованием уникального индекса
SELECT name FROM events WHERE id = 3(id - первичный ключ)
Cпецифика работы блокировок MySql
![Page 28: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/28.jpg)
Next-key Lock
(-inf.. 3] (3..5] (5..10] (10..15] (15..+inf)
Next-key Lock = блокировка записи (Row Lock) +блокировка “промежутка” перед записью
Пример
Cпецифика работы блокировок MySql
![Page 29: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/29.jpg)
Next-key Lockиспользуется для предотвращения phantom read
Транзакция 1 Транзакция 2
SELECT * FROM events WHERE another_id > 8 FOR UPDATE
INSERT INTO events (another_id) VALUES (9)
SELECT * FROM events WHERE another_id > 8 FOR UPDATE
FAIL2й запрос возвращает другие
данные
Cпецифика работы блокировок MySql
![Page 30: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/30.jpg)
Next-key Lock
... 3 3..5 5..10 10..15 15...
InnoDB блокирует все встреченные записи индекса, используемого в запросе
SELECT * FROM events WHERE another_id > 8FOR UPDATE
Cпецифика работы блокировок MySql
![Page 31: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/31.jpg)
Next-key LockЕсли не используется индекс, InnoDB фактически
блокирует все таблицу!
• изменить уровень изоляции на READ COMMITTED
• включить системную переменную innodb_locks_unsafe_for_binlog
Next-key lock можно отключить:(возможен phantom read)
Cпецифика работы блокировок MySql
![Page 32: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/32.jpg)
MySql 5.1
• меньше блокировок в READ-COMMITTED при DML операциях - блокируются только те строки, которые действительно изменяются
• более производительная блокировка для AUTO_INCREMENT полей
( подробнее тут - http://bit.ly/4iF2mu )
Cпецифика работы блокировок MySql
![Page 33: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/33.jpg)
ПроблемаМного блокировок
+
длинная транзакция
=
много дедлоков
Cпецифика работы блокировок MySql
![Page 34: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/34.jpg)
Решение
• Делаем мало блокировок (правильные индексы)
• Используем короткие транзакции
Cпецифика работы блокировок MySql
![Page 35: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/35.jpg)
Пример 1• better_nested_set
• не приспособлен к конкурентной модификации дерева - большие транзакции, update по всей таблице
• has_tree как альтернатива (данные об иерархии хранятся в отдельной таблице) http://github.com/dima-exe/has_tree
Cпецифика работы блокировок MySql
![Page 36: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/36.jpg)
Пример 2• counters в has_many
• update-ы в произвольном порядке, вероятность дедлоков выше при длинных транзакциях
• альтернатива - вынести счетчики в отдельную таблицу, уменьшить размеры транзакций
Cпецифика работы блокировок MySql
![Page 37: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/37.jpg)
Что делать
• deadlock_retry ( http://github.com/rails/deadlock_retry ) - если дедлоков мало
• LOCK TABLES - блокировки на уровне таблиц (think MyISAM)
• Использовать READ-COMMITTED (помним о phantom-read)
Cпецифика работы блокировок MySql
![Page 38: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/38.jpg)
Summary
• Используем индексы
• Короткие транзакции• Если дедлоков мало, их можно игнорировать, перезапуская транзакции
Cпецифика работы блокировок MySql
![Page 39: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/39.jpg)
Узнаем большеSHOW ENGINE INNODB STATUS
![Page 40: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/40.jpg)
![Page 41: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/41.jpg)
Описаны последние 2 транзакциии последние запросы из каждой
(не обязательно именно те, которые вызвали дедлок)
![Page 42: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/42.jpg)
Ресурсы• http://dev.mysql.com/doc/refman/5.0/en/
innodb-deadlocks.html
• http://www.mysqlperformanceblog.com/ ( http://bit.ly/wchKP , http://bit.ly/1Bz0AY )
• http://www.xaprb.com/blog/ ( http://bit.ly/Ldq2t , http://bit.ly/8nRFn , http://bit.ly/8nRFn )
![Page 43: Обработка дедлоков в MySql](https://reader035.vdocuments.net/reader035/viewer/2022081421/5561ee8cd8b42a9d068b5518/html5/thumbnails/43.jpg)