在管道传输到 mysql 的同时对 mysql 转储执行 head

Perform a head on mysqldump at the same time as piping to mysql

在 Ubuntu 14.04 终端上使用 bash,我能够从主 mysql 数据库转储到从:

mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --user=myuser --password=[password] --host=127.0.0.1 mydb | mysql --max_allowed_packet=128M -h 192.168.1.110 -u myuser -p[password] otherdb

但我同时想将 mysql 转储输出重定向到 head -30 > /tmp/pointintime.log 以便我可以获得时间点信息:

--
-- Position to start replication or point-in-time recovery from
--

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.049868', MASTER_LOG_POS=107;

如何做到这一点?我尝试使用 tee 但这会导致从属导入端出现 sql 语法错误(好像它破坏了输出并且没有发送完整的语句):

mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --user=myuser --password=[password] --host=127.0.0.1 mydb | tee >(head -30 >/tmp/pointintime.log) | mysql --max_allowed_packet=128M -h 192.168.1.110 -u myuser -p[password] otherdb

如何 mysqldump 导入从 mysql 数据库并同时检索转储的 head -30?我不想先转储到文件,因为数据库很大,通过网络进行管道传输效率更高。

我也试过使用多个 tee 重定向但有相同的语法错误:

mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --user=myuser --password=[password] --host=127.0.0.1 mydb | tee >(mysql --max_allowed_packet=128M -h 192.168.1.110 -u myuser -p[password] otherdb) >(head -30 >/tmp/pointintime.log)

ERROR 1064 (42000) at line 47: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near..

您不能使用 teehead 执行此操作,因为 head 会在输出请求的行数后关闭其输入句柄,从而破坏管道。这是您使用所编写的命令应该看到的内容。

mysqldump: Got errno 32 on write

错误 32 是 "Broken pipe."

另一个错误 - 我怀疑 - 是因为损坏的管道导致 mysql 的输入句柄被关闭,部分输出行已经写入,并且它收到的文件结束时发生这种情况被解释为语句过早结束。

中间需要一些不会破坏管道的东西。建议:瑞士军用电锯... Perl.

替换为:

| tee >(head -30 >/tmp/pointintime.log) | 

有了这个:

| perl -p -e 'print STDERR $_ unless $. > 30' 2>/tmp/pointintime.log |

-e 开关告诉 Perl 不是从文件加载 Perl 脚本,而是脚本在后面的引号字符串中。 -p 开关使这个小的 one-line "program" 对于每一行 STDIN 变为 运行,之后每一行输入将被打印到 STDOUT,输入行瞬时出现在每行经过的变量 $_ 中,变量 $. 表示 运行ning 行计数器。当然 STDERR 是第二个输出流,我们用 2> 捕获它并重定向到您的日志文件,一旦 $. > 30 为真,就不会再向您的日志写入任何行...但它们都写入了输出。

就这么简单。

以这种方式通过 Perl 传输 mysqldump 是完全安全的——它不会以任何方式操作数据,它会完全按照输入的方式写出数据。当我需要修改备份流时,我经常这样做在飞行中。