Отображение открытых транзакций в MySQL


96

Я сделал несколько запросов без фиксации. Потом приложение было остановлено.

Как я могу отобразить эти открытые транзакции и зафиксировать или отменить их?


Я думаю, что все ваши транзакции отменяются при отключении, но не уверен на 100%.
Johan

Какие типы таблиц вы используете? MyISAM, InnoDB и т. Д.?
cdeszaq

@cdeszaq, очевидно не MyISAM в нем нет транзакций, к тому же вопрос действительно не имеет отношения к таблицам.
Johan

2
@Johan - Я привел MyISAM только в качестве примера типа таблицы. И это очень делает дело, потому что не все таблицы , которые поддерживают транзакции ведут себя так же , как в отношении операций по потере связи.
cdeszaq

@cdeszaq, в документации MySQL говорится совсем другое.
Johan

Ответы:


61

Как я могу отобразить эти открытые транзакции и зафиксировать или отменить их?

Нет открытой транзакции, MySQL откатит транзакцию при отключении.
Вы не можете зафиксировать транзакцию (IFAIK).

Вы отображаете темы, используя

SHOW FULL PROCESSLIST  

См .: http://dev.mysql.com/doc/refman/5.1/en/thread-information.html

Это вам не поможет, потому что вы не можете зафиксировать транзакцию из-за разорванного соединения.

Что происходит при разрыве соединения
Из документации MySQL: http://dev.mysql.com/doc/refman/5.0/en/mysql-tips.html

4.5.1.6.3. Отключение автоматического переподключения mysql

Если клиент mysql теряет соединение с сервером при отправке оператора, он немедленно и автоматически пытается повторно подключиться к серверу и отправить запрос еще раз. Однако , даже если mysql успешно восстановит соединение, ваше первое соединение завершится, и все ваши предыдущие объекты и настройки сеанса будут потеряны : временные таблицы, режим автофиксации, а также пользовательские переменные и переменные сеанса. Также любая текущая транзакция откатывается .

Такое поведение может быть опасным для вас, как в следующем примере, где сервер был выключен и перезапущен между первым и вторым операторами без вашего ведома:

См. Также: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html

Как диагностировать и исправить это
Чтобы проверить автоматическое переподключение:

Если автоматическое переподключение происходит (например, в результате вызова mysql_ping ()), явного указания на это нет. Чтобы проверить повторное подключение, позвоните, mysql_thread_id()чтобы получить исходный идентификатор подключения, перед вызовом mysql_ping(), затем позвоните еще mysql_thread_id()раз, чтобы узнать, изменился ли идентификатор.

Убедитесь, что вы сохранили свой последний запрос (транзакцию) в клиенте, чтобы при необходимости можно было отправить его повторно.
И отключите режим автоматического переподключения, поскольку это опасно, вместо этого реализуйте собственное переподключение, чтобы вы знали, когда происходит сбой, и могли повторно отправить этот запрос.


Это не имеет отношения к вопросу. Это влияет только на клиента mysql, а OP говорит об общем приложении, что, вероятно, означает его приложение. Кроме того, поскольку вызывающее приложение остановилось, как оно сможет сохранить транзакцию в памяти?
cdeszaq

@cdeszaq, это имеет отношение к вопросу. Приложение обычно использует mysqld.dllAKA клиент. И вы храните SQL-оператор , содержащий полную транзакцию, в памяти, чтобы вы могли воспроизвести его при разрыве соединения. Или вы храните его локально на диске, чтобы после перезапуска вы могли повторно отправить его.
Johan

В SHOW FULL PROCESSLIST отображается только моя команда списка процессов. Так что, думаю, открытых транзакций просто нет. Самое забавное, что autoincrement_ids, кажется, потеряны.
Alex

@alex официальные документы утверждают, что это задокументированное поведение. См. Ссылки.
Johan

Прекрасно, Йохан. Ответил на вопрос и показал некоторые последствия и способы их устранения, все в нескольких абзацах.
Gerard ONeill

54

Хотя в этом случае не будет оставшейся транзакции, как сказал @Johan, вы можете увидеть текущий список транзакций в InnoDB с запросом ниже, если хотите.

SELECT * FROM information_schema.innodb_trx\G

Из документа :

Таблица INNODB_TRX содержит информацию о каждой транзакции (исключая транзакции только для чтения), которые в настоящее время выполняются внутри InnoDB, в том числе, ожидает ли транзакция блокировки, когда транзакция началась, и SQL-запрос, который транзакция выполняет, если есть.


Не предполагайте, что есть способ узнать, принадлежат ли транзакции в этой таблице вашему конкретному запросу / сеансу?
Captain Hypertext

1
Обратите внимание, что \Gмодификатор в конце полезен только в том случае, если вы хотите отформатировать вывод запроса в инструменте mysql CLI. Если вы используете инструмент с графическим интерфейсом, такой как Mysql Workbench, он вам не нужен.
barell

29

Вы можете использовать show innodb status(или show engine innodb statusдля более новых версий mysql), чтобы получить список всех действий, ожидающих в настоящее время внутри движка InnoDB. В стене вывода будут скрыты транзакции и то, под каким внутренним идентификатором процесса они работают.

Вы не сможете принудительно выполнить фиксацию или откат этих транзакций, но вы МОЖЕТЕ убить процесс MySQL, выполняющий их, что по сути сводится к откату. Он уничтожает соединение процессов и заставляет MySQL убирать оставшийся беспорядок.

Вот что вам нужно искать:

------------
TRANSACTIONS
------------
Trx id counter 0 140151
Purge done for trx's n:o < 0 134992 undo n:o < 0 0
History list length 10
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, process no 17004, OS thread id 140621902116624
MySQL thread id 10594, query id 10269885 localhost marc
show innodb status

В этом случае сейчас есть только одно соединение с движком InnoDB (мой логин, выполнение showзапроса). Если бы эта строка была фактическим соединением / зависшей транзакцией, которую вы хотите прервать, вы бы сделали kill 10594.


На самом деле нет необходимости активно уничтожать соединение по истечении тайм-аута, соединение все равно будет прервано, и ожидающая транзакция из разорванного соединения не может быть зафиксирована, поэтому их можно повторно отправить, не опасаясь дублирования.
Johan

3
Лучше уничтожить зависшие транзакции, не дожидаясь тайм-аута для очистки - иначе вы рискуете завязать блокировку.
Marc B

Ах да, +1 за этот комментарий. Забыл на минутку об этих тупиках.
Johan

@MarcB, зачем поменяли на show engine innodb status?
Pacerier

1

Используя этот запрос, вы можете увидеть все открытые транзакции.

Список всех:

SHOW FULL PROCESSLIST  

если вы хотите убить идентификатор транзакции копии зависшей транзакции и уничтожить транзакцию с помощью этой команды:

KILL <id>    // e.g KILL 16543
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.