Відображення відкритих транзакцій у MySQL


95

Я зробив кілька запитів без коміту. Потім заявку зупинили.

Як я можу відобразити ці відкриті транзакції та здійснити або скасувати їх?


Я думаю, що всі ваші транзакції скасовуються після відключення, але не впевнені на 100%.
Йохан

Який тип таблиць ви використовуєте? MyISAM, InnoDB тощо?
cdeszaq,

@cdeszaq, очевидно, не MyISAM не має транзакцій, до того ж питання насправді не має нічого спільного з таблицями.
Йохан

2
@Johan - я лише дав MyISAM як приклад типу таблиці. І це дуже робить справу, тому що не всі таблиці , які підтримують транзакції поводяться так само , як по відношенню до операцій по втраті зв'язку.
cdeszaq,

@cdeszaq, Документи MySQL зазначають щось зовсім інше.
Йохан

Відповіді:


60

Як я можу відобразити ці відкриті транзакції та здійснити або скасувати їх?

Немає відкритої транзакції, 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-оператор, який містить повну транзакцію в пам'яті, так що ви можете відтворювати його, коли з'єднання перестає. Або ви зберігаєте його локально на диску, щоб після перезапуску ви могли надіслати його повторно.
Йохан

У SHOW FULL PROCESSLIST відображається лише моя команда списку процесів. Тому я думаю, що відкритих транзакцій просто немає. Кумедна частина полягає в тому, що autoincrement_ids, здається, загублені.
Alex

@alex офіційні документи стверджують, що це документує поведінку. Дивіться посилання.
Йохан

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

53

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

SELECT * FROM information_schema.innodb_trx\G

З документа :

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


Не думайте, що існує спосіб визначити, чи транзакції в цій таблиці належать до вашого конкретного запиту / сесії?
Капітан Гіпертекст

1
Зверніть увагу, що \Gмодифікатор в кінці корисний лише в тому випадку, якщо ви хочете відформатувати вихідний запит в інструменті CLI mysql. Якщо ви використовуєте графічний інтерфейс, такий як 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.


Насправді немає необхідності активно вбивати підключення після закінчення тайм-ауту, зв’язок все одно буде перервано, і очікувана транзакція через розірваний зв’язок не може бути здійснена, тому їх можна повторно надіслати, не боячись дублювання.
Йохан

3
Краще вбивати застряглі транзакції, не чекаючи тайм-ауту для очищення - інакше ви ризикуєте тупиковими ситуаціями.
Marc B

Ах так, +1 за цей коментар. На хвилину забув про ці безвихідні ситуації.
Йохан,

@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.