You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell管道与重定向原理解析及mysqldump errno 32错误调试

解析MySQL备份管道的工作原理,以及调试"Got errno 32 on write"错误

首先,先把完整的代码块放出来,咱们逐行拆解它的逻辑:

PULSE=$(mktemp -t shield-pipe.XXXXX)
trap "rm -f ${PULSE}" QUIT TERM INT
set -o pipefail
mysqldump ... | tee >(tail -c1 >$PULSE) | bzip2 | s3 stream ...

一、代码逐行工作原理

  1. 创建临时文件:PULSE=$(mktemp -t shield-pipe.XXXXX)
    用mktemp生成一个唯一的临时文件,-t参数指定了文件名模板,最终会生成类似/tmp/shield-pipe.xyz78的路径,把这个路径存在PULSE变量里。这个临时文件用来做后续的“输出有效性检测”。

  2. 清理临时文件的陷阱:trap "rm -f ${PULSE}" QUIT TERM INT
    设置信号捕获,当脚本收到QUIT(Ctrl+\)、TERM(系统终止信号)、INT(Ctrl+C)时,自动执行rm -f删除临时文件,避免备份中断后残留垃圾文件。

  3. 开启管道失败检测:set -o pipefail
    默认情况下,Bash管道的返回值只看最后一个命令的状态,哪怕前面的命令失败了,只要最后一个命令成功,整个管道就会返回成功。开启pipefail后,只要管道里任意一个命令失败,整个管道的返回值就会是那个失败命令的退出码,这样就能准确判断整个备份流程是否真的成功了。

  4. 核心备份管道流程:mysqldump ... | tee >(tail -c1 >$PULSE) | bzip2 | s3 stream ...
    这是一条串联的数据流管道,咱们从左到右看:

    • mysqldump ...:执行MySQL导出命令,把数据库内容输出到标准输出。
    • | tee >(tail -c1 >$PULSE):tee命令的作用是“分流”——它会把收到的输入同时发送到两个地方:一个是继续往后传给管道的下一个命令(bzip2),另一个是传给进程替换(>(...))里的命令。进程替换里的tail -c1会读取输入的最后1个字节,然后写入到$PULSE临时文件。这么做的目的是验证mysqldump是否有实际输出:如果备份成功,PULSE文件大小会是1字节;如果mysqldump没输出(比如导出失败),这个文件就是空的,后续脚本可以通过检查这个文件来判断备份有效性。
    • | bzip2:把tee传过来的原始备份数据进行bzip2压缩,减少数据体积。
    • | s3 stream ...:把压缩后的数据流通过s3 stream工具直接上传到对象存储,实现“流式备份”(不用先写本地磁盘再上传,节省空间)。

二、调试"Got errno 32 on write"错误

这个错误对应的是Linux系统的EPIPE(Broken pipe,管道断裂),意思是mysqldump往标准输出写数据的时候,管道后面的某个进程已经提前退出了,导致管道“断了”,mysqldump无法继续写数据。咱们一步步排查:

1. 先确认管道失败状态

因为开启了pipefail,执行备份命令后,用echo $?查看整个管道的返回码。如果返回非0,说明管道里某个环节确实失败了,接下来逐个排查。

2. 逐个隔离管道环节,定位问题点

  • 单独测试mysqldump:先跳过后面的所有管道,直接把导出结果写到本地文件,看mysqldump本身是否正常:

    mysqldump --your-actual-options-here > test-dump.sql
    

    如果这一步就报错,那问题出在mysqldump本身——比如数据库连接失败、权限不足、表损坏、磁盘空间不足(写test-dump.sql的时候)等,根据mysqldump的报错信息修复即可。

  • 测试mysqldump + 压缩:如果mysqldump单独运行正常,再加上bzip2压缩:

    mysqldump ... | bzip2 > test-dump.sql.bz2
    

    如果这里失败,可能是bzip2出问题(比如损坏),或者本地磁盘空间不足无法写入压缩文件。

  • 测试mysqldump + tee + 压缩:加上tee的进程替换部分,去掉s3 stream:

    mysqldump ... | tee >(tail -c1 >/tmp/test-pulse) | bzip2 > test-dump.sql.bz2
    

    执行完后检查/tmp/test-pulse的大小(用ls -l /tmp/test-pulse),如果大小是1,说明前面的流程都正常,问题大概率出在s3 stream环节。

  • 单独测试s3 stream:验证上传工具是否能正常接收数据流:

    echo "test backup data" | s3 stream --your-upload-options-here
    

    如果这一步失败,说明s3 stream有问题——比如对象存储桶不存在、权限配置错误、网络连接中断、工具本身bug等,查看s3 stream的错误输出就能找到原因。

3. 增加日志输出,获取更多细节

把s3 stream的错误输出重定向到日志文件,方便排查:

mysqldump ... | tee >(tail -c1 >$PULSE) | bzip2 | s3 stream ... 2>> s3-upload-error.log

执行备份后查看s3-upload-error.log,里面会有上传过程中的具体错误信息,比如“权限不足”“连接超时”等。

4. 检查系统资源

有时候进程提前退出是因为系统资源不足:

  • 用dmesg命令查看是否有OOM Killer(内存不足时系统自动杀掉进程)的日志,如果有,说明备份时内存被占满,需要优化备份参数(比如分表导出)或者增加系统内存。
  • 检查磁盘IO、CPU使用率,备份时如果资源被占满,可能导致某个进程超时退出。

内容的提问来源于stack exchange,提问作者Sybil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:29:31