可行,但需规避gpg默认缓冲与交互阻塞:必须用--batch、stdbuf -oL强制行缓冲、--passphrase-fd 0安全传密,禁用--trust-model always仅限内网;对称加密更稳定。

直接用 gpg 对数据库备份文件做流式加密是可行的,但“异步”不是 gpg 自身的特性,而是靠管道与后台进程协作实现;关键在于避免写死临时文件、控制密钥加载时机、防止密码短语暴露。
为什么不能直接 gpg --encrypt + mysqldump 管道?
常见错误是写成:mysqldump db | gpg --encrypt --recipient alice@example.com > backup.sql.gpg。这看似流式,但实际会卡住——因为 gpg 在读取完全部输入前,不会输出任何加密数据(它要先生成会话密钥、处理 IV、打包 packet),而 mysqldump 可能因缓冲区满或 SIGPIPE 被杀。
真正可行的流式加密必须满足两个条件:输入不阻塞、输出不缓存。默认 gpg 不满足后者。
-
gpg默认使用完整缓冲模式,不支持--flush或--no-buffers类参数 - 若目标公钥未被信任(
gpg: WARNING: recipient key not found),整个管道会静默失败,无输出也无报错 - 私钥密码短语若需交互输入,会阻塞管道(尤其在 cron 或 systemd service 中)
gpg --batch --passphrase-fd 配合 stdbuf 强制流式输出
绕过缓冲问题的核心方法是让 gpg 进入批处理模式,并用 stdbuf 控制其 stdout 行为。适用于定时备份脚本:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
mysqldump --single-transaction myapp | \
stdbuf -oL gpg --batch --yes --trust-model always \
--encrypt --recipient sxana@qq.com \
--passphrase-fd 0 2>/dev/null \
< /path/to/passphrase.txt > backup_$(date +%s).sql.gpg-
--batch禁用所有交互,--yes自动确认覆盖等操作 -
--trust-model always跳过公钥有效性检查(仅限可信内网环境;生产环境应提前gpg --import-ownertrust) -
--passphrase-fd 0表示从 stdin 读密码,所以把密码文件重定向进去(注意权限:密码文件必须chmod 600) -
stdbuf -oL强制行缓冲 stdout,缓解输出延迟(对大 dump 文件效果明显)
更安全的替代:先 tar 再 gpg -c 对称加密
如果不需要公钥分发(比如只用于本地归档或单人管理),用对称加密反而更稳、更流、更少坑:
tar -cf - /var/lib/mysql/myapp | \
gpg --batch --cipher-algo AES256 --compress-algo 1 \
--passphrase-fd 0 --symmetric \
< /path/to/symkey.txt > mysql_myapp_$(date +%Y%m%d).tar.gpg-
--symmetric启用对称加密,不依赖公钥环,避免gpg: key "xxx" not found报错 -
--cipher-algo AES256显式指定强算法(默认 CAST5 已不够安全) -
--compress-algo 1对应 ZIP 压缩(比默认的 zlib 更兼容旧版gpg) - 整个过程内存占用低,
tar流进、gpg流出,无中间文件
恢复时别漏掉 --pinentry-mode loopback
用 systemd 或 cron 执行加密备份后,解密恢复容易失败,典型报错:gpg: decryption failed: No secret key 或卡在 pinentry。这是因为守护进程环境下缺少 GUI/TTY pinentry。
解决方法是在解密命令中显式指定:
gpg --pinentry-mode loopback --batch --passphrase-fd 0 \
--decrypt backup.sql.gpg < /path/to/passphrase.txt | mysql myapp-
--pinentry-mode loopback是 GnuPG 2.1+ 的关键开关,允许非交互式读取密码 - 但前提是
gpg-agent已配置启用 loopback(需在~/.gnupg/gpg-agent.conf加allow-loopback-pinentry并重启 agent) - 没配这个,哪怕密码文件正确,
gpg也会静默退出并返回 2
最易被忽略的是:gpg 的流式行为高度依赖输入源是否真正“流式”。mysqldump 默认缓冲,pg_dump 默认不缓冲——PostgreSQL 用户可直接用 pg_dump | gpg 管道,MySQL 用户则建议加 --skip-extended-insert 减少单行长度,再配合 stdbuf。

















