Bug #55289 mysqlbinlog ignores errors while writing output
Submitted: 15 Jul 2010 15:10 Modified: 31 May 2012 17:34
Reporter: Mark Callaghan Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Command-line Clients Severity:S2 (Serious)
Version:5.1.47 OS:Any
Assigned to: Alfranio Junior CPU Architecture:Any
Tags: error, IGNORE, mysqlbinlog

[15 Jul 2010 15:10] Mark Callaghan
Description:
mysqlbinlog cannot be used in an automated fashion (shell, python or perl script) because it ignores errors while writing binlog events to stdout. As stdout may be a file, errors can occur while writing to it.

Perhaps Domas will provide the test case. For now, read the code.

How to repeat:
The code does not support returning an error.

From log_event.h, the print functions return nothing.

  /* print*() functions are used by mysqlbinlog */
  virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;

From log_event.cc:

void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
  Write_on_release_cache cache(&print_event_info->head_cache, file);

  print_query_header(&cache, print_event_info);
  my_b_write(&cache, (uchar*) query, q_len);
  my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
}

From mysqlbinlog.cc:

    default:
      ev->print(result_file, print_event_info);
[15 Jul 2010 15:15] Domas Mituzas
The testcase:

===
#!/usr/bin/python

import os
os.popen("mysqlbinlog  mysqld-relay-bin....")
===

(Same in other languages)
[15 Jul 2010 20:17] Sveta Smirnova
Thank you for the report.

Verified as described.

To repeat I modified source:

$bzr diff
=== modified file 'sql/log_event.cc'
--- sql/log_event.cc    2010-05-19 23:50:42 +0000
+++ sql/log_event.cc    2010-07-15 20:08:29 +0000
@@ -2961,6 +2961,7 @@
 
   print_query_header(&cache, print_event_info);
   my_b_write(&cache, (uchar*) query, q_len);
+sleep(20);
   my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 }
 #endif /* MYSQL_CLIENT */

Then run mysqlbinlog command:

$mysqlbinlog  master-bin.000001 -r bug55289.sql

Then in another terminal issues

rm bug55289.sql

In first terminal mysqlbinlog was still running, then it finished I checked return value and got no error:

$echo $?
0
[31 May 2012 17:34] Paul DuBois
Noted in 5.1.64, 5.5.26, 5.6.6 changelogs.

mysqlbinlog exited with no error code if file write errors occurred.
[26 Jan 2013 3:36] Andrew Garner
This is not fixed - the check only verifies if the head_cache hit an error, but not the body cache, even in mysql-5.6.9-rc.

This is trivially seen when writing to a full disk:

# mysqlbinlog -r binlog.sql /var/lib/mysql/mysqld-bin.000193
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
mysqlbinlog: Error writing file 'binlog.sql' (Errcode: 28)
...
# echo $?
0

A patch that also verifies if &print_event_info->body_cache->error is set (along with head->error) fixes many more of the cases but I think this is still not a full fix.