мой сценарий тупика MySQL - нужен совет - PullRequest
1 голос
/ 11 апреля 2011

Мне нужен совет специалиста по этому вопросу.

Фоновая таблица PHP / Codeigniter MYSQLi Innodb - Tickets_table Хранимая процедура

Backend - PHP-скрипт cronjob написан для вставки / обновления данных (изсервис) в Tickets_table каждые несколько минут.(обычный запрос sql)

Внешний интерфейс - пользователи смогут читать эти данные (запрос записывается в форме хранимой процедуры, потому что он включает в себя объединение многих таблиц, поэтому моя хранимая процедура создала временную таблицу из операторов выбораиз тарифов_таблицы и соединены с другими таблицами)

Проблема

Deadlock found when trying to get lock; try restarting transaction

Может произойти тупик, если пользователь случайно наткнется на интерфейс, пока обновляется / вводится таблица тарифов,Блокировки случаются с оператором обновления

Блокировка вызвана тем, что хранимая процедура пытается дождаться снятия блокировки, пытаясь создать временные таблицы с инструкциями выбора из tar_table, в то время как сервер выполняет вставку или обновление, пытаясь дождаться блокировкивыпустить.

LATEST DETECTED DEADLOCK
------------------------
110408  9:05:45
*** (1) TRANSACTION:
TRANSACTION 0 203543446, ACTIVE 0 sec, OS thread id 6584 fetching rows
mysql tables in use 2, locked 2
LOCK WAIT 761 lock struct(s), heap size 60736, 30170 row lock(s)
MySQL thread id 86268, query id 135039790 XXXXXXX Copying to t
CREATE TEMPORARY TABLE tmp_tb1 AS SELECT MIN( fare ) as cheapest_fare,flighttype origin,destination ....
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 18433 n bits 240 index `PRIMARY` of table `db_name`.`fares_table`
Record lock, heap no 85 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 8025d996; asc  %  ;; 1: len 6; hex 00000c21d3a9; asc    !  ;; 2: len 7; hex 0000000b031

*** (2) TRANSACTION:
TRANSACTION 0 203543465, ACTIVE 0 sec, OS thread id 3080 updating or deleting, thread declared inside
mysql tables in use 1, locked 1
3 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1
MySQL thread id 85631, query id 135039816 XXXXX Updating
UPDATE `fares_table` SET `fare` = 2552.85, `currency` = 'AUD'..
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 18433 n bits 240 index `PRIMARY` of table `db_name`.`fares_table`
Record lock, heap no 85 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 8025d996; asc  %  ;; 1: len 6; hex 00000c21d3a9; asc    !  ;; 2: len 7; hex 0000000b031

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 2086 n bits 600 index `flighttype_idx` of table `db_name`.`fares_table`
Record lock, heap no 218 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 7; hex 4f6e6520776179; asc One way;; 1: len 3; hex 424e45; asc BNE;; 2: len 8; hex 8000124a588

*** WE ROLL BACK TRANSACTION (2)

Мое временное исправление

Перехватите ошибку базы данных 1213 и повторите запрос на обновление.Это работает сейчас, но я бы хотел найти гораздо лучшее решение для предотвращения тупика.Любой совет экспертизы?

Как изменить порядок, чтобы предотвратить тупик, или поможет дублирование индекса flighttype_idx?

1 Ответ

0 голосов
/ 11 апреля 2011

Поскольку запрос на создание временной таблицы должен по существу блокировать основные части таблицы из-за функции агрегирования MIN(fare), а обновление тарифа должно ждать его завершения, не существует простого переупорядочения, которое может разрешить тупиковые.

Лучше было бы окружить конфликт явным механизмом блокировки, возможно, для таблицы блокировки только для этой цели, а не позволять транзакциям конкурировать и затем откатываться назад. В частности, оператор create table нельзя откатить , как это ни странно. См. Документацию LOCK TABLE .

.

Чтобы аккуратно реализовать, переместите оператор (ы) обновления тарифов в хранимую процедуру и сделайте цикл хранимых процедур обновления тарифов и временных таблиц при проверке и установке блокировки, выполнении их работы, а затем разблокируйте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...