English Version

Глава 7. Конкурентные транзакции.

Ещё один часто встречающийся пример подобной проблемы - ошибка "Lock wait timeout exceeded" при использовании InnoDB таблиц. Чаще всего достаточно комнды SHOW ENGINE INNODB STATUS, которая покажет последние транзакции. Но вывод этой команды не содержит информации о всех запросах в транзакции, а только о текущем. Что делать если SHOW ENGINE INNODB STATUS не даёт всей информации?

mysql> insert into t1 values(2,'1994-12-30', '1994-12-03');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> show engine innodb status \G
****************** 1. row ******************
  Type: InnoDB
  Name: 
Status:
=====================================
091001 15:54:26 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 15 seconds
....
------------
TRANSACTIONS
------------
Trx id counter 0 295696
Purge done for trx's n:o < 0 295690 undo n:o < 0 0
History list length 4
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, OS thread id 101121024
MySQL thread id 1314, query id 217 localhost root
show engine innodb status
---TRANSACTION 0 295695, not started, OS thread id 101606912
MySQL thread id 1311, query id 216 localhost root
---TRANSACTION 0 295694, ACTIVE 13 sec, OS thread id 101122048
2 lock struct(s), heap size 320, 1 row lock(s), undo log entries 1

MySQL thread id 1312, query id 215 localhost root

Мы видим здесь информацию о конкурирующей транзакции, но не видим в чём конкретно проблема. General query log снова наш помощник:

mysql> select * from mysql.general_log where thread_id = 1312 order by event_time \G
******************* 1. row *******************
  event_time: 2009-10-01 15:54:11
   user_host: root[root] @ localhost []
   thread_id: 1312
   server_id: 51
command_type: Query
    argument: begin
******************* 2. row *******************
  event_time: 2009-10-01 15:54:13
   user_host: root[root] @ localhost []
   thread_id: 1312
   server_id: 51
command_type: Query
    argument: insert into t1 values(2,'1994-12-30', '1994-12-03')
2 rows in set (0.12 sec)

Или проще:

mysql> select argument from mysql.general_log where thread_id = 1312 order by event_time;
+-----------------------------------------------------+
| argument                                            |
+-----------------------------------------------------+
| begin                                               |
| insert into t1 values(2,'1994-12-30', '1994-12-03') |
+-----------------------------------------------------+
2 rows in set (0.01 sec)

Что делать? Опять-таки развести запросы по времени.

Приём №13: используйте SHOW ENGINE INNODB STATUS чтобы получить информацию о транзакциях.

Приём №14: используйте general query log если в выводе SHOW ENGINE INNODB STATUS только часть информации о проблемной транзакции.

Назад Содержание Вперёд



Автор 2009 Света Смирнова
COPYRIGHT © 2009 С.Смирнова и С.Ласунов
sveta_гав_js-client_точка_com