Ubuntu 20.04.5升级mysql-server-8.0后APT/DPKG损坏的修复求助(需保留MySQL数据)
我完全懂你现在的焦虑——MySQL明明运行正常,但APT/DPKG却因为升级时的权限问题卡住了,还不敢轻易碰卸载操作,生怕弄丢重要数据。咱们先把问题理清楚,再一步步安全修复:
先还原你的问题场景
During monthly patching [security updates only], it updated mysql-server-8.0 from [0/8.0.36/0ubuntu0.20.04.1/X86_64] to mysql-server-8.0[0:8.0.37-0ubuntu0.20.04.3] however as it tries to continue patching I get the following error:
Setting up mysql-server-8.0 (8.0.37-0ubuntu0.20.04.3) ...
/var/lib/dpkg/info/mysql-server-8.0.postinst: line 56: kill: (2401867) - Permission deniedHowever, even though mysql seems to be updated & running okay, this update broke dpkg...
E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem.
WARNING: Could not install the python3-apt, this may cause the patching operation to fail.
failed to run commands: exit status 1When I trying to run dpkg --configure -a [after sudo su root], I hit the same permission denied issue...
可能的原因
root用户执行kill命令还被拒,大概率是安全模块限制(比如AppArmor)或者进程的特殊系统保护机制:
- AppArmor可能阻止了dpkg的postinst脚本直接杀死MySQL进程
- 或者MySQL进程处于不可中断状态(这种情况比较少见)
- 也有可能是postinst脚本用了非root身份执行kill(但你已经切到root了,这个可能性很低)
安全修复步骤(优先保证数据安全)
1. 先做个紧急数据备份(保险起见)
虽然MySQL现在正常运行,备份一下心里更踏实:
# 导出所有数据库到sql文件,输入root密码即可 mysqldump -u root -p --all-databases > mysql_full_backup_$(date +%Y%m%d).sql
2. 先确认MySQL进程的状态
先找到当前MySQL的PID(之前的2401867可能已经失效):
ps aux | grep mysqld
然后检查进程的安全上下文(看是否受AppArmor限制):
# 替换成你查到的PID ps -Z <mysql_pid>
3. 尝试通过systemd管理进程,绕开直接kill的权限问题
dpkg的postinst脚本可能是直接kill进程,而不是通过systemd停止服务,导致权限被拒。咱们换个方式:
# 先正常停止MySQL服务 systemctl stop mysql # 再执行dpkg配置命令 dpkg --configure -a # 配置完成后启动MySQL systemctl start mysql
4. 如果还是不行,临时调整AppArmor规则
如果检查到AppArmor处于enforced状态,临时切换到complain模式(只告警不阻止):
# 查看mysql的AppArmor状态 aa-status | grep mysql # 临时设置为complain模式 aa-complain /usr/sbin/mysqld # 再次执行dpkg配置 dpkg --configure -a # 配置完成后恢复enforced模式(安全起见) aa-enforce /usr/sbin/mysqld
5. 修复后验证APT状态
确保后续升级正常:
apt update && apt upgrade --dry-run
注意事项
- 绝对不要轻易执行
apt purge mysql-server-8.0,除非万不得已——purge会删除配置文件,虽然数据在/var/lib/mysql不会丢,但后续恢复更麻烦 - 如果以上步骤都不行,可以查看postinst脚本的第56行具体做了什么:
cat /var/lib/dpkg/info/mysql-server-8.0.postinst | sed -n '56p',看看它是怎么kill进程的,再针对性解决
备注:内容来源于stack exchange,提问作者Alice




