Bug #49336 mysqlbinlog does not accept input from stdin when stdin is a pipe
Submitted: 2 Dec 2009 11:33 Modified: 10 Aug 2012 23:53
Reporter: Heikki Hannikainen Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Command-line Clients Severity:S3 (Non-critical)
Version:5.1.40, 5.0, 5.1, next-mr bzr OS:Linux
Assigned to: CPU Architecture:Any

[2 Dec 2009 11:33] Heikki Hannikainen
Description:
This seems to be #7853 reoccurring. It's impossible to feed mysqlbinlog from zcat/bzip2/gzip - instead, files need to be first decompressed on disk and then fed to mysqlbinlog. Which requires additional wall-clock time, more disk IO and disk space.

'mysqlbinlog - < binlog.uncompressed' seems to work fine, but 'gzip -dc binlog.gz | mysqlbinlog -' fails with "ERROR: Failed reading header; probably an empty file." When the same file is first uncompressed and then given to mysqlbinlog through stdin, it is processed nicely, so the bug seems rather small - it almost works.

strace of the failing process shows an illegal seek of stdin:
_llseek(0, 0, 0xbfa5abd4, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
_llseek(0, 0, 0xbfa5ab40, SEEK_SET)     = -1 ESPIPE (Illegal seek)
write(2, "ERROR: "..., 7)               = 7
write(2, "Failed reading header; probably a"..., 46) = 46

When a file is given on stdin, it only seeks to 0 and proceeds to read the header, which does not fail:
_llseek(0, 0, [0], SEEK_CUR)            = 0
_llseek(0, 0, [0], SEEK_SET)            = 0
read(0, "\376binQ\23\25K\17\24\0\0\0f\0\0\0j\0\0\0\0\0\4\0005.1.40-l"..., 65536) = 65536

How to repeat:
$ gzip -dc binlog-tango2-aprs-bu-1.005893.gz | strace -o binlog.strace3 /opt/mysql/bin/mysqlbinlog - |head -20
ERROR: Failed reading header; probably an empty file.

$ gzip -dc binlog-tango2-aprs-bu-1.005893.gz > binlogi
$ strace -o binlog.strace4 /opt/mysql/bin/mysqlbinlog - < binlogi  |head -20
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
... works fine!
[3 Dec 2009 8:42] Sveta Smirnova
Thank you for the report.

Verified as described:

$gzip -dc mysql-bin.000030.gz | ../../../build/mysql-5.1/bin/mysqlbinlog - | less
mysqlbinlog: mf_iocache.c:498: _my_b_read: Assertion `my_errno != 29' failed.
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
(END)
[8 Dec 2009 11:35] Sveta Smirnova
Yes, I can reproduce the problem.

This is not a regression, version 4.1 fails in same manner.

Error which I got is different because I use debug version.
[10 Aug 2012 23:53] Paul DuBois
Noted in 5.1.66, 5.5.28, 5.6.7, 5.7.0 changelogs.

mysqlbinlog did not accept input on the standard input when the
standard input was a pipe.