Bug #21694 | DELETE FROM is not transaction safe | ||
---|---|---|---|
Submitted: | 17 Aug 2006 10:53 | Modified: | 21 Aug 2006 11:30 |
Reporter: | Radek Maciaszek | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 4-5 | OS: | Linux (Linux) |
Assigned to: | CPU Architecture: | Any | |
Tags: | delete from transaction safe |
[17 Aug 2006 10:53]
Radek Maciaszek
[17 Aug 2006 11:08]
Radek Maciaszek
Chnaged to InnoDB category
[17 Aug 2006 13:25]
Heikki Tuuri
Radek, yes, you are right that DELETE FROM should be transaction-safe. If you want fast removal of all records you can use TRUNCATE that is not transaction-safe. But I am not able to verify this: heikki@127:~/mysql-5.0/client$ ./mysql test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 to server version: 5.0.25 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create table m(a int) engine=innodb; Query OK, 0 rows affected (0.31 sec) mysql> set autocommit=0; Query OK, 0 rows affected (0.00 sec) mysql> insert into m values (10); Query OK, 1 row affected (0.01 sec) mysql> commit; Query OK, 0 rows affected (0.03 sec) mysql> delete from m; Query OK, 1 row affected (0.01 sec) mysql> Another client, run later: heikki@127:~/mysql-5.0/client$ ./mysql test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 to server version: 5.0.25 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> select * from m; +------+ | a | +------+ | 10 | +------+ 1 row in set (0.01 sec) mysql> Please check that your tables really are InnoDB and not MyISAM: SHOW CREATE TABLE ... Regards, Heikki
[17 Aug 2006 14:08]
Radek Maciaszek
Hey Heikki, What you wrote works for me. You are right that records which are deleted inside the transaction are visible outside this transaction till you commit it. However my point is a little bit different. I noticed that if you insert a record to the table _after_ you created a transaction the "DELETE FROM" will delete that record even because it was inserted outside it's transaction. Basically I noticed that I'm loosing some data and I didn't know why. What I'm doing is dumping data in transaction "START TRANSACTION; SELECT * from table INTO OUTFILE..; DELETE FROM table; COMMIT;" but in the meantime other records are inserted into this table. Looks like that DELETE FROM command deletes also those new records which are inserted between calling "SELECT * FROM INTO OUTFILE.." and "DELETE FROM". Please try to recreate it using the code I sent in last report. connection1 and connection2 are separate clients.
[18 Aug 2006 13:27]
Heikki Tuuri
Radek, but SELECT ... with no lock clause is a non-locking consistent read, and reads historical data. If you want to make sure no one deletes that data meanwhile, you must use SELECT ... LOCK IN SHARE MODE; I am marking this as not a bug. Regards, Heikki
[18 Aug 2006 13:55]
Radek Maciaszek
Hey again Haikki, So basically SELECT works in default mode as REPEATABLE READ but DELETE always works in READ COMMITTED mode which means it's possible that in the same transaction "DELETE FROM table" will delete more records than I will see using "SELECT * FROM table". Am I right? cheers Radek
[21 Aug 2006 11:30]
Radek Maciaszek
Looks like it's not a bug maybe but I think it is worth to mention on documentation page that this is an expected behaviour. Anyway just a small reproduction User A User B SET AUTOCOMMIT=0; SET AUTOCOMMIT=0; time | SELECT * FROM t; | empty set | INSERT INTO t VALUES (1, 2); | v SELECT * FROM t; empty set COMMIT; SELECT * FROM t; empty set SELECT * FROM t; --------------------- | 1 | 2 | --------------------- 1 row in set DELETE FROM t; Query OK, 1 row affected // ^ it deletes rows from // outside it's transaction COMMIT; SELECT * FROM t; empty set