ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux下彻底卸载MySQL:从包清理到残留文件清扫的完整指南

Linux下彻底卸载MySQL:从包清理到残留文件清扫的完整指南 搞Linux运维的估计没人没跟MySQL卸载这件事较过劲。尤其那种“明明把服务停了、rpm包也删了重装却还是各种报错到头大”的情况十有八九就是卸得不够彻底——甚至很多时候你以为自己卸干净了其实系统里还埋着一堆雷等着你下一次重装时踩响。我这几年的实战体会是卸载MySQL这件事难点从来不在“卸载”本身而在于“怎么确认卸干净了”。包管理器卸掉的是软件本体配置、数据、运行痕迹、开机自启脚本这些都散落在系统的各个角落里一两个残留文件就能让重装后的MySQL起不来。这篇文章我就按自己真实操作过的路径来讲从确认安装方式、清理服务与软件包、清扫残留文件到验证是否卸干净、重装前准备每一步都给你说清楚原理和坑在哪。1. 为什么“明明卸过了”重装还是失败很多朋友第一次卸MySQL用的是最简单的方式systemctl stop mysqld然后yum remove mysql或rpm -e mysql一把梭感觉软件包没了就是卸完了。等到重装时发现各种诡异问题——初始化mysqld --initialize报权限错误、mysql命令连接不上socket、本来已经删掉的3306端口还在被占用这才意识到事情没那么简单又回头来翻日志、查系统来回折腾半天。按我自己的操作习惯来说“彻底卸载”至少包含四个层面的东西软件包层面rpm包、deb包或者编译安装产生的二进制文件这是大多数人理解的“卸载”。配置层面/etc/my.cnf、/etc/mysql/目录等配置文件。哪怕只有一个残留的my.cnf带着旧的socket路径和参数重装后的MySQL就会按它的逻辑走非常容易埋坑。数据层面/var/lib/mysql数据目录。这里存放着实际的数据库文件如果不清理可能带着之前的权限属性新装的MySQL初始化时直接报错。运行痕迹层面/tmp/mysql.socksocket文件、pid文件、/var/log/mysql日志、systemd残留的服务配置、开机自启脚本等。这些不清理干净服务状态会混乱3306端口也可能莫名其妙被占用。一句话说透了MySQL在Linux上不是说删了软件包就没了的它像搬家后在老房子里留下的水电煤气绑定、家具杂物和墙上的钉子——你光拎包走了不算搬完得把所有痕迹都收拾利索才算数。下面我就按实际操作顺序一步步拆解怎么把这些“钉子”全拔干净。2. 动手前先确认安装方式卸载策略的第一步分岔路都说“磨刀不误砍柴工”卸载MySQL也一样——先搞清楚这个MySQL是怎么装上去的接下来的操作才有针对性。装法不一样卸载时该从哪里下手完全不同。2.1 常见安装方式有哪几类我平时接触到的Linux服务器上MySQL的安装方式基本分三类RPM或Yum方式安装这是Red Hat系发行版CentOS、RHEL、Rocky Linux、AlmaLinux等最常见的装法。特点是软件包分散在mysql-community-server、mysql-community-client、mysql-community-libs、mysql-community-common等多个rpm包中rpm包之间还有依赖关系。源码编译方式安装自己下载源码包cmake、make、make install三步走。二进制文件通常被放在了自定义目录比如/usr/local/mysql卸载时没有系统包管理器能管它全得手动删目录。通用二进制包方式安装tar.gz解压从官网下载mysql-5.7.x-linux-glibc2.12-x86_64.tar.gz这类二进制包解压后简单配置就直接用。卸载方式跟源码编译类似也是纯手动清理。另外还有一类是Docker容器安装的MySQL这个虽然也常见但它本质上是容器管理范畴卸载时直接docker rm容器、删掉镜像就行不涉及系统包管理器我不把它跟物理机安装混在一起讲后面单独说一句。2.2 怎么快速判断当前MySQL的安装方式在动手卸载之前先在服务器上执行几组命令把MySQL现在的安装情况摸个底。# 查看rpm或yum安装的MySQL包Debian系请用dpkg -l | grep mysql rpm -qa | grep mysql rpm -qa | grep mariadb # 确认MySQL服务名和安装路径 systemctl status mysqld systemctl status mysql # 查看mysql二进制文件的真实路径 which mysql ls -l /usr/sbin/mysqld ls -l /usr/local/mysql/bin/mysqld # 查看配置文件有哪些 ls -l /etc/my.cnf ls -l /etc/mysql/ # 如果是纯源码或二进制包安装看看/usr/local/mysql目录是否存在 ls -d /usr/local/mysql # Docker方式安装的确认 docker ps -a | grep mysql docker images | grep mysql这几条命令执行完基本就能判断出MySQL到底属于哪种安装方式。我见过不少新手上来就在/usr/local/mysql里翻找数据目录结果压根是yum装的默认路径也有反过来yum卸载了半天才发现是之前源码编译装的rpm命令根本查不到任何包白白浪费时间。3. 停止服务与包管理器层面的彻底清理不管哪种安装方式卸载的第一步永远是先停服务。这个过程看似套路但有一个必须警惕的坑停服务前建议先把关键数据目录备份一下。我在文章前面特意强调过数据层面的概念这里再说得直接点——卸载不是删库跑路如果库里还有需要的数据请先mysqldump导出备份或者直接整个拷贝一份/var/lib/mysql目录。确认数据已备份之后再来谈接下来的清理。提示如果这个MySQL实例是你自己的学习环境或测试机无所谓备份不备份。但生产环境请一定建立备份习惯。别等到rm命令执行完才后悔——那时候想让数据回来可就很难了。3.1 停止并禁用MySQL服务# 停止服务。不同发行版/安装方式服务名可能是mysqld、mysql多试一下就知道 systemctl stop mysqld systemctl stop mysql # 确认服务确实已经停了显示inactive或dead就说明停了 systemctl status mysqld # 关闭开机自启。摘掉它的系统拉线和油门让它在重启之后不会自己蹦起来 systemctl disable mysqld systemctl disable mysql3.2 RPM包依赖顺序为什么不能无脑rpm -e接下来执行rpm -qa | grep mysql这时候会看到一系列包名。以最常见的社区版为例无外乎这几个mysql-community-server-5.7.44-1.el7.x86_64 mysql-community-client-5.7.44-1.el7.x86_64 mysql-community-libs-5.7.44-1.el7.x86_64 mysql-community-common-5.7.44-1.el7.x86_64很多兄弟卸载时习惯性一个rpm -e挨个删或者图省事直接yum remove mysql。实际上yum remove在这里不够“彻底”的关键点在于它会自动根据依赖关系删掉一批包但有时某些没被它识别为依赖的零散包就漏网了。而且如果用了第三方源装的MySQLyum remove也未必能把所有相关包都找全。我处理rpm包时习惯直接手动按依赖顺序来卸而且从server往common方向卸是比较稳的顺序rpm -e mysql-community-server rpm -e mysql-community-client rpm -e mysql-community-libs rpm -e mysql-community-common为什么这个顺序更重要因为server包通常依赖client和libs如果一开始就删libs会提示依赖失败。这也是rpm卸载中最常见的“卡壳”原因——不是不能删是顺序不对。3.3 libs包的特殊情况一个容易牵连无辜的坑mysql-community-libs这个包经常会跟系统里其他软件扯上依赖关系。我以前在一台跑了Web服务的机器上卸载MySQL时rpm -e mysql-community-libs直接报错说被postfix等软件依赖着硬删会把这些依赖它的软件也搞得不能正常用。处理方式有两条路其一临时用rpm -e --nodeps mysql-community-libs强制删除但要清楚这个操作只是删掉了libs包本身不处理它跟postfix的关联postfix后续是否还能正常用需要自行观察。其二如果只是嫌某个版本库文件过期或冲突其实不用卸直接用新版本的libs包rpm -Uvh替换升级也一样效果。这里要说明一点--nodeps这招属于“暴力拆迁”不是不能用但用了之后系统里就可能出现其他软件运行时找不到库文件的隐患。我更倾向于建议先看看到底谁依赖它有没有更优雅的路可以走。3.4 Yum方式卸载时的建议命令如果你倾向偷懒省事用yum也不是不行。但别指望一条命令干完所有事卸完还要自己检查一遍漏网之鱼# 先看yum会动哪些包 yum remove mysql-community-server 这个命令实际可能因为依赖关系把client也带走 # 更建议直接一次性把核心包都点名 yum remove mysql-community-server mysql-community-client mysql-community-libs mysql-community-commonDebian系Ubuntu、Debian的朋友对应逻辑是dpkg -l | grep mysql看包名然后apt-get remove --purge mysql-server mysql-client mysql-common注意--purge参数它会把配置文件一并清掉比裸apt-get remove干净得多。3.5 源码编译安装和二进制包安装的“卸载”方式这类安装方式在rpm -qa里查不到任何MySQL包所以包管理器层面的清理主要是靠make uninstall如果源码目录还在且有uninstall目标的话或者干脆直接删目录。二进制解压安装的尤其典型——MySQL原本就在/usr/local/mysql目录下软件层面把它整个删掉就行rm -rf /usr/local/mysql同时/usr/local/mysql/bin下的mysql、mysqld等命令如果之前做过软链接到/usr/bin或/usr/local/bin也得一并删掉软链接。这个我会在后面“残留文件清扫”里详细展开先不急着跳这里大家心里先有个数rpm包层面清理完成后真正的重头戏才开始。4. 残留文件清扫数据、配置与运行痕迹很多“卸载不彻底”问题根源都在这一步没做好。前面删包只是把可执行程序和库文件拿掉了配置文件、数据文件、日志、socket、systemd服务脚本这些还在系统里躺着。它们就像一个个埋在地下的小地雷平时看不出毛病重装MySQL时一踩一个准。4.1 数据目录/var/lib/mysql最容易被忽视的重灾区数据目录是MySQL真正的“心脏”——所有库、表、数据文件都堆在这里。/var/lib/mysql如果没清理会带来一个典型的麻烦重装MySQL后执行mysqld --initialize初始化时系统本来要新建数据文件并设定权限为mysql用户所有。结果旧数据目录里的文件还带着旧的属主、属组或权限属性可能导致初始化失败日志里报Permission denied之类错误。处理方式很直接rm -rf /var/lib/mysql但这里有个习惯我强烈建议各位养成别直接rm整个目录而是把目录改个名留几天观察。mv /var/lib/mysql /var/lib/mysql.bak.$(date %Y%m%d)为什么不直接删因为任何人都有脑子短路或操作失误的时候把目录改名为自己留一个后悔药的空窗期确认新装的MySQL跑得完全正常之后再回头删除这个备份目录风险就小很多了。这个习惯救过我很多次尤其在忙乱的多任务操作场景下。4.2 配置文件/etc/my.cnf和相关目录配置文件是另一个高频残留点。rpm或yum卸载时/etc/my.cnf经常不会被自动删掉apt的--purge会删但rpm未必。残留的my.cnf可能会导致新装的MySQL沿用旧参数。另外还要注意/etc/mysql/这个目录Debian系会把多处配置分散在/etc/mysql/mysql.conf.d/、/etc/mysql/conf.d/等子目录里。# 彻底检查这些位置存在就删 ls -l /etc/my.cnf ls -l /etc/mysql/ rm -rf /etc/my.cnf /etc/my.cnf.d /etc/mysql有些服务端还会生成/etc/my.cnf.rpmnew或/etc/my.cnf.rpmsave这类备份文件也一并清掉。我用find扫一遍更稳妥find /etc -maxdepth 2 -name *my.cnf* -o -name *mysql*4.3 日志、socket文件和pid文件MySQL运行时会留下这些文件卸载了软件包它们还在原地# 常见日志位置 /var/log/mysql/ /var/log/mysqld.log # socket与pid文件很多环境下在/tmp或/run目录 /tmp/mysql.sock /run/mysqld/mysqld.sock /run/mysqld/mysqld.pid # 一并清理 rm -rf /var/log/mysql /var/log/mysqld.log rm -rf /tmp/mysql.sock /tmp/mysql.sock.* rm -rf /run/mysqld为什么要清socket文件有个特别典型的重装场景启动新MySQL时如果socket文件路径和旧的冲突或者旧socket文件被某个进程占用服务可能起不来或连接报Cant connect to local MySQL server through socket /var/run/mysqld/mysqld.sock。把残留socket和pid文件清掉能省去这类莫名其妙的麻烦。4.4 systemd服务残留很多朋友不知道即使rpm包删了/usr/lib/systemd/system/mysqld.service也可能还留在系统里。结果就是systemctl daemon-reload之后依然能看到mysqld相关的unit。处理方式是手动删掉再重载daemonrm -rf /usr/lib/systemd/system/mysqld.service rm -rf /lib/systemd/system/mysql.service systemctl daemon-reload注意如果你打算立刻重装新版本MySQL新版本的rpm包会重新生成这个service文件那时直接让新包覆盖写入就行不一定非得提前删。但如果你确认不再装MySQL或想彻底把痕迹清光就要删掉。4.5 命令软链接、man手册和头文件如果之前手动把mysql、mysqldump等命令做了软链接到/usr/local/bin或/usr/bin卸载后这些链接就变成失效状态。虽然不影响系统正常运行但对你后续安装新版本时判断路径会造成干扰。清掉不用的软链接避免重装时出现“两个路径、两个同款命令”的岔路问题# 检查相关命令是否还存在which不到说明shell里已经找不到了软链接残留文件还在则需要手动删 which mysql which mysqldump ls -l /usr/bin/mysql rm -f /usr/bin/mysql /usr/bin/mysqldump # man手册和头文件源码编译/二进制安装尤其常见 rm -rf /usr/share/man/man1/mysql.1.gz rm -rf /usr/include/mysql5. 验证卸载干净的标准方法别再用“好像没了”来做判断清理工作做完最重要的一环就是验证。我见过太多人卸载后只执行一句rpm -qa | grep mysql看到没有输出就宣布“卸载完成”这判断太早了。下面五组检查每一组都值得认真过一遍。5.1 软件包层面的复查# 逐项检查rpm包里是否还有mysql或mariadb相关包 rpm -qa | grep -iE mysql|mariadb # Debian系用 dpkg -l | grep -iE mysql|mariadb除了MySQL本身还有一个极容易被忽略的坑是Mariadb。CentOS 7等发行版默认自带Mariadb的lib库rpm -qa | grep mariadb经常能看到结果。多数情况下Mariadb的包跟MySQL本身不同源不同命但之前MySQL的libs包如果已被替换或装过Mariadb的兼容库这里也会出现连带关系。严格来说Mariadb不应该被算作MySQL残留但如果你的目标就是让系统回归到“没有数据库服务”的状态Mariadb也可以一并考虑处理掉。5.2 端口与服务状态检查# 用ss或netstat确认3306端口不再监听 ss -lntp | grep 3306 netstat -lntp | grep 3306 # 再次确认真实状态 systemctl status mysqld systemctl status mysql如果3306端口仍然有进程监听说明清理有遗漏或之前的连接进程还活着继续深挖用lsof -i:3306看看是谁占着它。5.3 目录和文件残留扫描这一步就是“扫地雷”了重点关注我们前面提过的每一个位置find / -maxdepth 3 -name my.cnf 2/dev/null ls -d /var/lib/mysql 2/dev/null ls -d /etc/mysql 2/dev/null ls -l /usr/lib/systemd/system/mysqld.service 2/dev/null另外像locate mysql这种通过updatedb数据库查询的方式也能帮上忙不过locate依赖系统的文件索引刚新生成的或者索引没更新时可能查不准还是find最可靠。也建议检查一下/usr/local/mysql目录是否还残留ls -ld /usr/local/mysql 2/dev/null5.4 环境中还包含一个关键表项这里我整理一个快速自检表每次卸完MySQL之后对照过一遍基本可以确定系统处于干净状态检查项命令期望结果rpm包列表rpm -qa | grep -iE mysql|mariadb无输出或只剩不相关的mariadb-libs服务状态systemctl status mysqld显示未安装或inactive配置文件ls /etc/my.cnf /etc/mysql文件不存在数据目录ls -d /var/lib/mysql目录不存在日志与socketls /var/log/mysql /tmp/mysql.sock不存在端口监听ss -lntp | grep 3306无输出systemd unitls /lib/systemd/system/mysqld.service不存在或已被新包覆盖5.5 systemd reload后仍可能出现的“幽灵服务”还有一个容易让人疑惑的点即使你已经把mysqld.service删了systemctl list-unit-files | grep mysql有时还是能看到一些残留条目。这是因为systemd除了从/usr/lib/systemd/system读取unit文件还可能从/etc/systemd/system等目录读取或者某些unit文件之前被enable过符号链接残留在/etc/systemd/system/multi-user.target.wants/等目录下。处理方式除了删除unit文件还要清理启用的软链接rm -rf /etc/systemd/system/*.wants/*mysqld* rm -rf /etc/systemd/system/*.wants/*mysql* systemctl daemon-reload再执行systemctl list-unit-files | grep mysql复查这回应该就干净了。6. 卸完后的几个特殊情况与重装前准备本来到这里整篇卸载主流程已经讲完。但结合我自己的实际运维经历和网上常被问到的点有几个特殊情况必须单独点名尤其是那些会让新手反复踩坑的场景。6.1 源码编译安装的“防漏网”检查前面提过源码编译或二进制包安装的卸载方式不太一样这里再展开说细一点。源码编译安装时如果编译参数里设置了-DCMAKE_INSTALL_PREFIX/usr/local/mysql那么整个MySQL安装树都在这一个目录下面删掉目录就相当于删了软件本体。但残留的隐患通常在这些位置/usr/local/mysql整个目录删掉之前先确认数据目录是独立存放的还是在里面。/usr/local/mysql/bin下如果有软链接被指向/usr/local/bin或/usr/bin也要删软链接。编译时生成的/etc/init.d/mysql或/etc/init.d/mysqld启动脚本老一些的版本很常见。日志和数据目录如果手工指定过参数可能不在默认位置用find / -name *.err -o -name *.pid 2/dev/null扫一遍更放心。源码编译安装这种情况虽然RPM和Yum路径都没有问题但很多人最后卡在“明明卸载了which mysql还是有结果”这样的怪相。所以再次提醒查一遍软链接很关键。6.2 Docker方式安装的MySQL怎么“卸载”如果你是用docker run启动的MySQL卸载逻辑完全不同。它是在宿主机上隔离运行不会污染系统里的目录和systemd服务。停止和移除流程大概是# 停容器并删除 docker stop container_name docker rm container_name # 删除volume数据卷时注意如果只是想换个镜像版本而保留数据就别删volume如果彻底不要了就一起删 docker volume ls docker volume rm volume_name # 删除镜像 docker images | grep mysql docker rmi mysql:tag用Docker方式安装的好处就是卸载确实干净镜像、容器、volume一删宿主机干干净净。但从另一个角度看它也在宿主机上留下了若干网络和目录挂载的痕迹比如挂载到宿主机/data/mysql之类的目录这些是你自己指定的挂载路径不属于Docker自动生成真要彻底清就得手动删挂载目录。6.3 重装前的最终检查清单如果你卸载MySQL是为了重装一个新版本那么在yum install或解压新包之前再做几个小动作防止重装时新老痕迹打架配置文件先清空如果/etc/my.cnf还存在尽量不要留着它直接装新版让新包生成默认配置最稳妥。已备份的配置也建议等新版本安装成功后再对比设置而不是提前拷回去。数据目录可迁移不可混用旧数据备份目录如/var/lib/mysql.bak.xxx不要直接改回原名让新包使用——不同大版本的MySQL数据目录格式不一定兼容比如5.7升到8.0区别就很大。需要数据时用mysqldump导出的SQL文件来做迁移才是正常路径。清理防火墙和服务残留如果之前配置过firewalld或iptables开放3306端口理论上重装后新的MySQL还会用同样端口不需要重复配置但如果之前改动过乱七八糟的规则顺手firewall-cmd --list-all确认一下也好。检查用户和组MySQL安装时会创建名为mysql的系统用户和组。卸载并不需要把用户也删掉因为重装还要用但如果你确实打算彻底不装了有一天想让系统恢复到最干净的状态顺手把这个用户也一并清理掉userdel mysql groupdel mysql确认磁盘空间MySQL数据目录可能非常大卸载后要释放空间就必须确保/var/lib/mysql备份目录最终也被你删掉了。很多服务器卸完之后空间没释放就是因为数据目录其实只是被改了名。6.4 卸载过程中的日志和报错排查思路最后这点是我特别想分享给新手的经验如果卸载过程中出现奇怪的报错别急着用--nodeps硬刚先把/var/log/messages、/var/log/yum.log或dnf.log翻一下。很多卸载失败的根源都是依赖关系导致的连锁问题。比如rpm -e mysql-community-server时报告“Failed dependencies”查看一下具体是哪个包在依赖它就可以决定是先把那个依赖包卸掉还是用--nodeps跳过检查。大部分情况下跳过依赖检查不是不可行但你要清楚它到底绕过了什么——这就像拔钉子时你知道这颗钉子连着的木条是哪一根才能决定要不要连木条一起丢。我自己的习惯是先卸载依赖者再卸载被依赖者把依赖链理顺rpm卸载会顺利得多。实在理不顺的才用--nodeps点到为止地强删绝不一上来就无脑绕过依赖检查。7. 卸载MySQL之后的下一步路怎么走到了这一步MySQL已经从你的Linux系统里彻底离开了。我建议把备份目录再留几个星期确认新环境或新版本跑得够稳定再回头删掉那些.bak备份目录。这段缓冲期是你最后一道后悔药防线别做让自己觉得可惜的决定。根据我这几年在Linux上跟MySQL打交道总结的经验卸载这件事最消耗时间的从来不是那些执行命令的几秒钟而是排查“哪里没删干净”的分析过程。第一次装卸MySQL的新手多半会经历一个“卸载时感觉啥都没删完、重装时感觉哪哪都在报错——然后回头再卸载一遍”的循环过程。这很正常因为MySQL毕竟是由十几个包、多个目录、多种运行文件组合起来的服务栈它的“卸载”本来就不像删除一个普通软件那么简单。把本文提供的卸载步骤按顺序执行一遍再对照自查表过一遍检查项基本可以避免绝大多数重装时的诡异问题。吃透这套思路你再去处理其他类似有复杂运行结构的服务端软件Redis、Nginx、PostgreSQL都会遇到同样类型的残留问题就会有种“深谙此道”的感觉——所有这类服务本质上都逃不掉“包、配置、数据、运行痕迹”这四个层面的清理思路。
返回列表