Bug #169 DELETE FROM t; does not lock 't' enough, causes bad order in binlog
Submitted: 19 Mar 2003 14:22 Modified: 24 Mar 2003 13:38
Reporter: Guilhem Bichot Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:3.23.56 and below (not in 4.0) OS:Any (all)
Assigned to: Guilhem Bichot CPU Architecture:Any

[19 Mar 2003 14:22] Guilhem Bichot
Description:
It's a race condition.'t' is a MyISAM table for example (not checked with other table types).
thread 1 does DELETE FROM t; (no WHERE clause)
thread 2 does INSERT INTO t values(10);
the INSERT is executed&binlogged after the DELETE is executed but before the DELETE is binlogged.
Consequence : in the master 't' finally contains 1 row, while in the binlog we have
INSERT
DELETE
which causes 't' to be empty on the slave.

Code in sql/sql_delete.cc seems different in 4.0 than in 3.23, so 4.0 may not be bugged; a person that knows this code well could tell.

How to repeat:
To provoke the race condition for sure, apply this patch to sql/sql_delete.cc :

===== sql_delete.cc 1.39 vs edited =====
*** /tmp/sql_delete.cc-1.39-7002        Fri Jul 19 20:57:52 2002
--- edited/sql_delete.cc        Wed Mar 19 21:32:22 2003
***************
*** 106,111 ****
--- 106,113 ----
    }
    if (!error)
    {
+     char s[10];
+     fscanf(stdin,"%s",s);
      mysql_update_log.write(thd,thd->query,thd->query_length);
      if (mysql_bin_log.is_open())
      {

Do CREATE TABLE t (a int); INSERT INTO t values(10); DELETE FROM t; on the master. The master will DELETE all rows from t,
but will wait for you to type something on the keyboard before writing to the binlog. But before typing something, open another 'mysql' client and send
INSERT INTO t VALUES(10);
This INSERT will be executed immediately, binlogged, and will return.
Then type something, and the DELETE will be binlogged. You have managed to
write to the binlog in the reverse order of execution. Example : see how timestamps are in wrong order :

# at 131
#030319 22:07:35 server id  1   Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1048108055;
insert into t values(10);
# at 189
#030319 22:07:32 server id  1   Query   thread_id=1     exec_time=5     error_code=0
SET TIMESTAMP=1048108052;
delete from t;

Suggested fix:
Monty, I send this to you for instant fix :)
[24 Mar 2003 13:38] Michael Widenius
Thank you for your bug report. This issue has been fixed in the latest
development tree for that product. You can find more information about
accessing our development trees at 
    http://www.mysql.com/doc/en/Installing_source_tree.html