Bug #2452 Empty LOAD DATA INFILE failes with the master in 3.23.x
Submitted: 20 Jan 2004 3:56 Modified: 20 Jan 2004 6:46
Reporter: Masaki Fujimoto Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:4.0.17 OS:Linux (Debian GNU Linux (Woody))
Assigned to: Guilhem Bichot CPU Architecture:Any

[20 Jan 2004 3:56] Masaki Fujimoto
Description:
LOAD DATA INFILE statement causes slave servers to emit error and stop replication with the following conditions:

* replication consists with mysql-3.23.xx(master) and mysql-4.0.17(slaves)
* target INFILE is empty (0 bytes)

Error Message is as follows:
040120 20:45:49  Slave: Error in Exec_load event: could not open file '/tmp/SQL_LOAD-2-1-1.info', Error_code: 2
040120 20:45:49  Error running query, slave SQL thread aborted. Fix the problem, and restart the slave
 SQL thread with "SLAVE START". We stopped at log 'mysql-bin.001' position 79

How to repeat:
my.cnf(master)(version 3.23.58):
server-id       = 1
log-bin         = /usr/local/mysql/log/mysql-bin.log

my.cnf(slave)(version 4.0.17):
server-id               = 2
master-host             = master.example.com
master-user             = repl
master-password         =
master-port             = 3306
replicate-do-db         = test

master$ cp /dev/null /tmp/infile.empty
master$ /usr/local/mysql/bin/mysql -uroot test
...
mysql> create table t1 (col1 int);
...
mysql> load data infile '/tmp/infile.empty' into table t1;
...

slave$ cat /usr/local/mysql/log/mysqld.err
040120 20:45:36  mysqld started
/usr/local/mysql/bin/mysqld: ready for connections.
Version: '4.0.17-standard-log'  socket: '/usr/local/mysql-4.0.17-std/data/mysqld.sock'  port: 33306
040120 20:45:37  Slave I/O thread: connected to master 'repl@nx.eth.jp:13306',  replication started in log 'FIRST'
at position 4
040120 20:45:49  Slave: Error in Exec_load event: could not open file '/tmp/SQL_LOAD-2-1-1.info', Error_code: 2
040120 20:45:49  Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread w
ith "SLAVE START". We stopped at log 'mysql-bin.001' position 79

Suggested fix:
[we need Create_file_log_event in any case...]

$ diff -u slave.cc.bak slave.cc
--- slave.cc.bak        Tue Jan 20 20:51:24 2004
+++ slave.cc    Tue Jan 20 20:53:59 2004
@@ -2836,20 +2836,6 @@
                        cev->fname);
        goto err;
       }
-      if (unlikely(!num_bytes)) /* eof */
-      {
-       send_ok(net); /* 3.23 master wants it */
-       Execute_load_log_event xev(thd,0,0);
-       xev.log_pos = mi->master_log_pos;
-       if (unlikely(mi->rli.relay_log.append(&xev)))
-       {
-         sql_print_error("Slave I/O: error writing Exec_load event to \
-relay log");
-         goto err;
-       }
-       mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
-       break;
-      }
       if (unlikely(cev_not_written))
       {
        cev->block = (char*)net->read_pos;
@@ -2864,7 +2850,21 @@
        cev_not_written=0;
        mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
       }
-      else
+      if (unlikely(!num_bytes)) /* eof */
+      {
+       send_ok(net); /* 3.23 master wants it */
+       Execute_load_log_event xev(thd,0,0);
+       xev.log_pos = mi->master_log_pos;
+       if (unlikely(mi->rli.relay_log.append(&xev)))
+       {
+         sql_print_error("Slave I/O: error writing Exec_load event to \
+relay log");
+         goto err;
+       }
+       mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+       break;
+      }
+      if (unlikely(!cev_not_written))
       {
        aev.block = (char*)net->read_pos;
        aev.block_len = num_bytes;
[20 Jan 2004 6:44] Guilhem Bichot
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

Thanks for this very good bug report.
I just fixed the bug with this slightly different patch (we simply skip an empty file):
--- 1.262/sql/slave.cc  Wed Dec 17 17:29:08 2003
+++ 1.263/sql/slave.cc  Tue Jan 20 15:41:20 2004
@@ -2840,6 +2840,14 @@
       if (unlikely(!num_bytes)) /* eof */
       {
        send_ok(net); /* 3.23 master wants it */
+       /*
+         If we wrote Create_file_log_event, then we need to write
+         Execute_load_log_event. If we did not write Create_file_log_event,
+         then this is an empty file and we can just do as if the LOAD DATA
+         INFILE had not existed, i.e. write nothing.
+       */
+       if (unlikely(cev_not_written))
+         break;
        Execute_load_log_event xev(thd,0,0);
        xev.log_pos = mi->master_log_pos;
        if (unlikely(mi->rli.relay_log.append(&xev)))
[20 Jan 2004 6:46] Guilhem Bichot
ChangeSet@1.1685.1.1, 2004-01-20 15:41:22-05:00, guilhem@mysql.com