Bug #45923 | Innodb autocommits if query is aborted or killed midway executing UPDATE | ||
---|---|---|---|
Submitted: | 2 Jul 2009 21:25 | Modified: | 4 Jul 2009 9:14 |
Reporter: | Roland Bouman | Email Updates: | |
Status: | Duplicate | Impact on me: | |
Category: | MySQL Server: General | Severity: | S1 (Critical) |
Version: | 5.1.30 | OS: | Windows (XP) |
Assigned to: | CPU Architecture: | Any |
[2 Jul 2009 21:25]
Roland Bouman
[2 Jul 2009 22:24]
MySQL Verification Team
Thank you for the bug report. c:\dbs>c:\dbs\5.1\bin\mysql -uroot --port=3510 --prompt="mysql 5.1 >" Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.1.37-Win X64-log Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql 5.1 >use test Database changed mysql 5.1 >show variables like "%commit%"; +--------------------------------+-------+ | Variable_name | Value | +--------------------------------+-------+ | autocommit | ON | | innodb_commit_concurrency | 0 | | innodb_flush_log_at_trx_commit | 0 | +--------------------------------+-------+ 3 rows in set (0.00 sec) mysql 5.1 >CREATE TABLE `innodb_commit` ( -> `name` varchar(255) DEFAULT NULL -> ) ENGINE=InnoDB -> ; Query OK, 0 rows affected (0.24 sec) mysql 5.1 >INSERT INTO innodb_commit (name) VALUES (REPEAT('A',255)); Query OK, 1 row affected (0.00 sec) mysql 5.1 >INSERT INTO innodb_commit (name) SELECT name FROM innodb_commit; Query OK, 524288 rows affected (1 min 39.99 sec) Records: 524288 Duplicates: 0 Warnings: 0 mysql 5.1 >update innodb_commit set name = repeat('B',255 ); Query aborted by Ctrl+C ERROR 1317 (70100): Query execution was interrupted mysql 5.1 >select name , count(*) from innodb_commit group by name\G *************************** 1. row *************************** name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA count(*): 1023153 *************************** 2. row *************************** name: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
[3 Jul 2009 12:03]
Davi Arnaut
Duplicate of Bug#45309?
[3 Jul 2009 12:07]
Roland Bouman
Hi Alexander! yes- I am pretty sure this is a duplicate. Sorry for not noticing the existing report. kind regards, Roland
[3 Jul 2009 14:00]
Mikhail Izioumtchenko
making it a duplicate then and categorizing away from InnoDB. Regarding giving people chance to rollback, turning off autocommit should do it. With autocommit on, rollback on ctrl-c will still be a gamble even with the base bug fixed.
[3 Jul 2009 14:05]
Roland Bouman
Hi Michael, "Regarding giving people chance to rollback, turning off autocommit should do it. With autocommit on, rollback on ctrl-c will still be a gamble even with the base bug fixed." This doesn't sound like an acceptable solution. Basically you're saying you can't rely on transactions when autocommit is enabled, yet autocommit is the default!! BTW - just curious, is there any difference between aborting with Ctrl+C and the kill command? TIA, Roland
[3 Jul 2009 15:01]
Mikhail Izioumtchenko
Roland, you can rely on transactions,you just can't rely on ctrl-c to be delivered on time, in this sense it applies to interrupting cat(1) as well. As for kill, I don't know for sure, but iirc it's the same, this is done by setting a flag in the THD structure, then the thread issues a rollback as soon as it notices the flag. MySQL folks could correct me if I'm wrong. Apparently the base bug says MySQL doesn't seem to check the flag often enough.
[3 Jul 2009 15:10]
Roland Bouman
I Michael! thanks for replying. Ehm, I guess your prior comment confused me. Can you please point out to me in what way the behaviour in case of abort is different as compared to a statement that runs into a constraint violation? I mean, last time I checked, the latter will rollback the statement if autocommit is enabled, and if autocmmot is not enabled, the statement is rolled back but the transactions is still kept alive. You seem to imply this is not the case for an abort, even if http://bugs.mysql.com/bug.php?id=45309 would be fixed. Is that correct? My point is, a failing statement due to abort is no different from a failing statement due to a constraint violation at least from a logical point of view. tia, Roland.
[3 Jul 2009 15:24]
Mikhail Izioumtchenko
Roland, abort is different from a constraint violation in that for an abort there's a client involved. For a constraint violation there's a guarantee that the executing thread will notice the violation before the transaction is committed, irrespective of the autocommit value. On violation the executing thread will then roll back the transaction. When a client is involved as in case of ctrl-c, the abort has to be delivered to the executing thread which is not instantaneous. When you hit ctrl-c, the OS has to notice it, interrupt the client, client interrupt handler will generate a packet and send it to MySQL over the network or a socket, MySQL will do whatever it does... all this time the executing thread is running. If it manages to commit in the meantime, this is it, the statement execution is over, transaction is committed, it cannot be rolled back after the commit. So whatever MySQL does there's a small window of opportunity between you hit the ctrl-c but MySQL simply doesn't know it yet, in which the transaction may be committed because of the autocommit.
[4 Jul 2009 9:14]
Roland Bouman
Hi Michael, thanks for your explanation - I appreciate it a lot. Now this part in your explanation confuses me: "all this time the executing thread is running. If it manages to commit in the meantime, this is it, the statement execution is over, transaction is committed, it cannot be rolled back after the commit." I mean, the test case I posted clearly indicates that part of the set is changed and committed, and part is not. I mean, why the heck is the executing thread making permanent changes at all before all of the row-level actions corresponding to the statement have completed? I can understand that if the executing thread happens to be done executing all row-level changes and just made the changes permanently and then receives the abort message, there would be a slight problem, because at that point you would not be able to undo anything. But this problem is not an issue as far as data integrity is concerned - the statement still executed atomically. So to be clear, prematurely stopping statement execution should absolutely never break atomicity and consistency. It should not matter what the reason is for stopping the statement - wheter it is a constraint violation or an abort just shouldn't matter.
[6 Jul 2009 13:52]
Dmitriy Royzenberg
Addtionally, if you have a replication, and you isseu Ctrl-C on Master yuo slave is not receiving the transaction, hence Master and Slave become out of sync. I recommend to always use autocommit=0 for safety. Regards, Dmitriy Royzenberg
[6 Jul 2009 13:52]
Dmitriy Royzenberg
Additionally, if you have a replication, and you issue Ctrl-C on Master you slave is not receiving the transaction, hence Master and Slave become out of sync. I recommend to always use autocommit=0 for safety. Regards, Dmitriy Royzenberg