离线环境部署MySQL 5.6全流程:从二进制包到my.cnf配置实践

发布时间:2026/9/18 18:44:52
离线环境部署MySQL 5.6全流程:从二进制包到my.cnf配置实践 做运维这些年最常遇到的场景之一就是要在内网或隔离环境里部署一套MySQL。没有外网、没法yum、apt也指望不上所有安装包都得提前备好拷进去。MySQL 5.6虽然已经是老版本了但存量项目还在跑很多公司内部的系统依然依赖它所以这套离线安装流程到现在依然有很现实的需求。这次我把自己在Linux环境下用纯离线方式部署MySQL 5.6的全过程完整记录下来从版本选型、依赖处理、目录规划到my.cnf配置、数据目录初始化、服务启动再到踩过的坑和排查思路都做了详细梳理。整个过程我实机验证过多次照着这套流程走基本不会出太大问题。适合需要在无网环境搭建MySQL的系统管理员、运维工程师也适合刚接触Linux数据库部署、想搞懂每一步原理的开发者参考。1. 离线安装的整体思路与方案选型很多人一提到安装MySQL第一反应就是yum install mysql-server或者apt install mysql-server。但在纯离线环境下没有软件源、没有网络这条路直接堵死。这时候需要提前想清楚用什么方式装、装哪个版本、需要带哪些文件进去这些决策直接决定了后续的安装效率。1.1 为什么选择二进制包而不是源码编译MySQL在Linux下的安装方式主要有三种RPM包、源码编译、二进制包。离线场景下RPM包依赖关系复杂经常需要一个个找依赖包而且不同发行版的RPM包还不能混用比较折腾。源码编译虽然灵活性高但耗时长、容易报错还需要gcc、cmake、ncurses等一堆编译工具链对一个内网环境来说代价太大。所以我优先推荐使用官方提供的Linux通用二进制包文件名一般是mysql-5.6.x-linux-glibc2.12-x86_64.tar.gz。这种包内部已经编译完成自带glibc依赖绑定解压后只需要简单配置就能跑起来对内网环境非常友好。它不依赖特定Linux发行版的软件包管理器只要内核和glibc版本满足要求就能运行兼容性也最省心。1.2 版本选型为什么是MySQL 5.6为什么选最后一个小版本MySQL 5.6在官方生命周期中发布的最后一个版本是5.6.51这也是我安装时优先选的版本。对还在维护老系统的团队来说选最后一个小版本意味着在这个大版本里Bug修复最全、已知问题最少。我的建议是既然都决定离线安装了下载安装包时优先找5.6.51别用早期版本避免因为旧版Bug白折腾。同时要注意MySQL 5.6对操作系统有glibc版本要求官方二进制包标识的glibc2.12意味着系统glibc不能低于2.12。CentOS 6和CentOS 7都满足这个条件Ubuntu 16.04及以上也没问题。如果系统太老或者太新后面会遇到一些兼容性问题这部分我在第4节做了详细说明。1.3 纯离线安装需要提前准备的东西离线安装最大的难点不在安装本身而在于“提前准备”。一旦进了没有外网的环境缺少任何一个小文件都可能导致流程中断。我常用的准备清单如下MySQL二进制包mysql-5.6.51-linux-glibc2.12-x86_64.tar.gzliba1依赖包libaio和libaio-develRPM包或deb包视系统而定perl相关依赖老版本初始化脚本可能需要perl、perl-devel文本编辑器vim或vi系统自带一般就有远程终端软件用于上传安装包到服务器这里重点说下libaio。MySQL 5.6的InnoDB存储引擎在启动时会动态加载libaio库如果系统没有这个库mysqld进程会直接报错。很多离线安装失败都卡在这一个依赖上所以提前把libaio的安装包装好带进去能省掉一大半麻烦。2. 安装前的环境检查与依赖处理整个安装过程里最容易被忽视的就是环境检查环节。跳过这一步直接解压安装后面各种诡异报错会让人欲哭无泪。我每次都会按以下三步走十分钟内就能确认环境是否满足条件。2.1 操作系统与glibc版本核对拿到一台机器我会先确认系统和内核版本命令如下cat /etc/redhat-release uname -a ldd --version | head -1在CentOS 7.x上cat /etc/redhat-release通常显示CentOS Linux release 7.xldd --version显示glibc 2.17这个环境跑MySQL 5.6的glibc2.12二进制包是完全没问题的。如果是CentOS 6glibc通常是2.12也满足。Ubuntu 16.04的glibc是2.23也没问题。关键是确认glibc不低于2.12这条底线。还有一个细节确认系统架构是x86_64还是aarch64。我这里讲的是x86_64架构如果你的机器是ARM架构需要找对应的ARM版本二进制包用法类似但安装包不能混用。2.2 libaio依赖的处理办法我在CentOS 7上遇到的最大坑之一就是libaio缺失。MySQL 5.6的InnoDB引擎启动时如果没有libaio会直接报错error while loading shared libraries: libaio.so.1: cannot open shared object file。解决办法很简单在联网机器上提前下载libaio和libaio-devel的RPM包拷进内网后通过rpm命令安装rpm -ivh libaio-*.rpm libaio-devel-*.rpm如果是Debian/Ubuntu系系统对应的是libaio1和libaio-dev这两个deb包用dpkg -i安装。判断系统缺不缺这个库可以执行ldconfig -p | grep libaio如果没有任何输出就说明确实没装。值得注意的是在CentOS 7最小化安装里libaio默认是装了的但CentOS 6上有些精简环境可能没有。所以不管什么系统我都建议在环境检查阶段确认一下别等到启动报错再回头查。2.3 系统用户、目录规划与权限设计安全习惯上MySQL不建议直接用root用户运行。虽然开发环境很多人图省事直接跑但生产环境用独立用户跑数据库是基本要求。这一步投入的时间成本很低但能避免很多权限类问题。我习惯创建mysql用户和mysql用户组groupadd mysql useradd -g mysql -s /sbin/nologin mysql接着把MySQL的安装目录和数据目录分开规划。安装目录放在/usr/local/mysql数据目录放在/data/mysql。这样设计的好处是系统盘通常挂载/只放程序文件数据盘/data专门放数据方便后续扩容和备份也避免系统盘满了连带数据库一起挂掉。mkdir -p /usr/local/mysql mkdir -p /data/mysql chown -R mysql:mysql /data/mysql为什么单独强调数据目录权限因为MySQL初始化时会往数据目录写系统库文件和redo log如果目录属主不是mysql用户初始化会报操作系统权限错误。这一点很多新手踩过坑下面实操部分还会再提到。3. MySQL 5.6的完整安装与配置实操环境准备好之后就可以进入正式安装流程了。这一节我按实际执行顺序写每一步的命令、参数含义、检查方法都列出来直接照着做就行。这个过程我已经重复验证过很多次可以说是“亲测有效”的稳定路径。3.1 解压分发与基础目录配置先把二进制包上传到服务器比如放到/opt目录然后解压cd /opt tar -xzf mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz mv mysql-5.6.51-linux-glibc2.12-x86_64/* /usr/local/mysql/这里我习惯把解压出来的内容直接放到/usr/local/mysql目录而不保留带版本号的目录名。原因很简单后续写脚本、配路径都直接用固定路径/usr/local/mysql升级或维护时不用反复改配置。当然如果你更习惯保留版本号目录然后做软链接方式也成立但固定路径的方式对新手更友好不容易出错。确认文件都到位之后给安装目录设置属主为mysqlchown -R mysql:mysql /usr/local/mysql3.2 my.cnf的编写思路与推荐配置my.cnf是MySQL的配置文件也是整个配置过程中最需要用心的地方。默认安装包里会提供一份my-default.cnf但内容很精简直接拿来生产环境用远远不够。我一般会自己写一份基础配置既能保证服务正常跑起来又能兼顾日常使用的性能。首先在/etc目录下创建my.cnfvim /etc/my.cnf一份经过实测、适用于大多数通用场景的配置模板如下[mysqld] basedir /usr/local/mysql datadir /data/mysql port 3306 server-id 1 socket /tmp/mysql.sock pid-file /data/mysql/mysql.pid character-set-server utf8mb4 collation-server utf8mb4_general_ci max_connections 500 back_log 300 wait_timeout 600 interactive_timeout 600 max_allowed_packet 64M slow_query_log 1 slow_query_log_file /data/mysql/slow.log long_query_time 2 log-error /data/mysql/error.log skip-name-resolve [client] default-character-set utf8mb4这里我挑几个关键参数说明一下。socket文件设置成/tmp/mysql.sock是很多客户端工具连接时的默认路径用这个路径能减少不少连接时的困惑。pid-file必须放在mysql用户可写的目录下所以放在了数据目录里。character-set-server和collation-server一起设置5.6虽然默认字符集是utf8但utf8在MySQL里最多存3个字节的字符存不了emoji这类4字节字符所以我直接设置成utf8mb4避免后续业务写入扩展字符时报错。skip-name-resolve这个参数建议开启它会让MySQL不进行反向DNS解析从而加快连接速度、减少DNS故障导致的连接延时代价是基于主机名的授权方式会失效实际场景下一般没问题。3.3 初始化数据目录mysql_install_db在MySQL 5.6里初始化数据目录用的是mysql_install_db脚本而不是5.7之后才有的mysqld --initialize。这点非常关键经常有从5.7版本过来的人在这个阶段用错命令导致初始化了但目录结构不对。执行命令如下/usr/local/mysql/scripts/mysql_install_db --basedir/usr/local/mysql --datadir/data/mysql --usermysql如果一切正常命令执行结束时会有两个OK提示Creating system tables和Filling help tables都显示OK同时在/data/mysql目录下能看到mysql、performance_schema等系统数据库的目录文件。初始化过程中最容易遇到的报错是缺少perl模块。因为mysql_install_db脚本是perl写的如果系统没有perl或者缺少相关依赖执行时会直接报错。解决办法是提前安装perlCentOS下用rpm -ivh perl相关的RPM包即可。3.4 启动服务与开机自启配置初始化完成后先不急着配置开机自启项目用命令方式第一次启动确认能正常跑起来再说。MySQL 5.6自带了一个mysql.server启动脚本位于安装目录下的support-files子目录/usr/local/mysql/support-files/mysql.server start执行后可以检查进程是否已经起来ps -ef | grep mysqld正常情况下能看到至少一个mysqld进程同时/data/mysql目录下会生成error.log和mysql.pid。如果进程没起来第一时间去查看error.log的内容大概率能直接定位原因。启动成功后建议再用mysqladmin ping命令测试一下服务是否真正可用/usr/local/mysql/bin/mysqladmin ping如果输出mysqld is alive说明服务状态正常可以继续后续设置。确认服务能稳定运行后再配置开机自启。将mysql.server复制到/etc/init.d/目录并赋予执行权限cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql chmod x /etc/init.d/mysql chkconfig --add mysql chkconfig mysql on这里使用chkconfig是因为CentOS 6和7都能用兼容性好。如果你的系统是CentOS 7也可以选择配置systemd的service文件但5.6自带脚本的方式更省事同时完全够用。配置完自启后可以尝试执行reboot重启机器来验证自启是否生效这是最直观的验证方式。3.5 重置root密码与远程访问授权MySQL 5.6刚初始化完成后root用户默认是空密码。这个时候要立刻设置密码避免数据库暴露在无密码状态下。设置密码前先通过socket方式免密登录/usr/local/mysql/bin/mysql -u root --socket/tmp/mysql.sock进入MySQL命令行后执行密码重置SET PASSWORD FOR rootlocalhost PASSWORD(你的强密码); FLUSH PRIVILEGES;设置完成后下次登录就要带密码/usr/local/mysql/bin/mysql -u root -p这里有一个常见问题明明设置了密码但下次登录还是能免密进去。这通常是因为设置密码时没有指定host默认改的是rootlocalhost之外的空账户或者之前存在root127.0.0.1的空密码账户。稳妥做法是检查并且重置所有root账户SELECT User, Host, Password FROM mysql.user WHERE Userroot;确保每个root账户要么设置强密码要么直接删除不需要的匿名账户。另外初始化时MySQL默认会创建几个匿名账户建议一并删除DELETE FROM mysql.user WHERE Password; FLUSH PRIVILEGES;如果应用服务器与MySQL不在同一台机器上还需要给应用账号授权允许远程访问GRANT ALL PRIVILEGES ON 你的数据库.* TO app_user% IDENTIFIED BY 应用密码; FLUSH PRIVILEGES;授权时host%表示允许任意IP访问。但生产环境里更严谨的做法是限制为具体IP段比如192.168.%.%减少不必要的暴露面。这里需要补充说明由于我在my.cnf里开启了skip-name-resolve使用host%方式不受影响但如果想用具体主机名来授权会不生效这是skip-name-resolve的一个已知行为。4. 常见问题与排查技巧实录装MySQL这件事顺利的话半小时收工不顺的话各种报错能让人怀疑人生。这一节我把离线安装过程中我最常遇到的问题、排查思路、解决办法整理成一个速查表再对其中几个典型场景展开分析。这些问题都是我在多台机器上实测过的照着排查会省很多时间。4.1 libaio.so.1缺失导致启动失败这个问题在第一节提到过因为它出现频率实在太高我把它放在最前面。现象是启动mysqld或mysql.server start时shell直接报error while loading shared libraries: libaio.so.1: cannot open shared object file。排查命令ldconfig -p | grep libaio如果输出为空说明系统确实没有libaio。解决办法就是在联网机器上提前下载libaio的RPM或deb包拷进内网后安装。CentOS 7可以用下面的方式在联网机器上只下载不安装yum install --downloadonly --downloaddir/opt/rpm libaio libaio-devel然后在离线机器上rpm -ivh安装。这一步做完再启动MySQL问题就解决了。4.2 mysql_install_db初始化报错或目录结构异常初始化时报错通常集中在两类一是缺少perl依赖执行脚本时提示cant locate strict.pm之类的perl模块缺失二是/data/mysql目录非空导致初始化中止。perl依赖问题解决方法是补装perlrpm -ivh perl-*.rpm目录非空的报错信息会提示datadir directory not empty。检查一下目录如果里面确实没有重要数据清空后重新初始化即可rm -rf /data/mysql/*另外也遇到过一种情况初始化命令返回OK但/data/mysql下只有少量文件连mysql系统库都不全。这多半是因为/data/mysql的属主不对mysql用户没有写权限。解决办法是重新执行chown -R mysql:mysql /data/mysql后再初始化。初始化完成后可以检查mysql库和performance_schema库是否生成确认这一步没有遗漏。4.3 Cant connect to local MySQL server through socket这个错误是客户端连接时最常遇到的。它表示客户端想通过socket文件连MySQL但连接不上。排查思路按顺序走ls -l /tmp/mysql.sock ps -ef | grep mysqld cat /data/mysql/error.log | tail -50第一步看socket文件是否存在如果不存在说明mysqld可能没启动或者启动后立即崩溃了第二步看mysqld进程是否存在第三步看错误日志通常能直接找到崩溃原因。一个常见场景是服务器异常重启后/tmp目录被清空mysql.sock文件不见了但mysqld进程已经起来了。这种情况下客户端照样连不上因为socket文件丢失。解决办法是重启mysqld进程让它重新生成socket文件/usr/local/mysql/support-files/mysql.server restart如果你不想依赖/tmp目录也可以在my.cnf里把socket路径改到数据目录下比如socket /data/mysql/mysql.sock然后在客户端连接时显式指定--socket参数这样即使系统清理/tmp目录也不受影响。不过要注意很多PHP、Java中间件默认会去/tmp/mysql.sock找MySQL改了路径就得多传一个socket参数各有取舍。4.4 误用5.7的初始化方式导致启动失败这个问题在跨版本经验的人身上特别常见。MySQL 5.7开始官方用mysqld --initialize替换了mysql_install_db初始化时如果不带--initialize参数mysqld启动会走到正常的启动流程但因为数据目录是空的会直接报错退出。具体现象是执行mysqld --usermysql后日志里报[ERROR] Aborting数据目录里只有少量文件没有任何系统库。有些人试了几次后以为安装包坏了其实是初始化根本没做完。解决方法是回到5.6的初始化逻辑重新执行rm -rf /data/mysql/* /usr/local/mysql/scripts/mysql_install_db --basedir/usr/local/mysql --datadir/data/mysql --usermysql这里踩过的另一个坑是初始化完成后忘了执行后续的密码设置步骤导致数据库处于root空密码状态。建议初始化成功后就立刻执行3.5节的密码重置流程。4.5 较新系统上运行5.6的兼容性问题处理MySQL 5.6官方二进制包绑定的glibc是2.12在CentOS 7glibc 2.17上运行毫无压力。但如果你的系统比较新比如Ubuntu 20.04、Debian 11或者CentOS 8glibc版本到了2.30以上偶尔会出现二进制兼容告警甚至有个别功能异常。我实测在Ubuntu 20.04上运行5.6.51会遇到一个资源限制方面的小问题打开文件数限制导致启动时提示File ./ib_logfile0: aio write returned OS error 201。解决办法有两个方向。一个是调整系统的文件描述符限制在/etc/security/limits.conf里增加配置mysql soft nofile 1024000 mysql hard nofile 1024000另一个是修改my.cnf把InnoDB的异步IO关掉innodb_use_native_aio 0这两个方式我建议先在测试环境验证再决定是否用到生产环境。实在不行就考虑换用Docker容器来做隔离在容器里跑一个CentOS 7再安装MySQL 5.6能从根本上绕开glibc兼容问题。这里也提醒一句在高并发或数据量大的生产场景下5.6本身已经有些跟不上时代如果项目没有历史包袱建议直接考虑5.7或8.0。但如果是存量系统不得不留在5.6上面这些兼容性处理手段就非常实用。5. 离线安装的常用命令速查与验证清单这部分我把安装过程中涉及的常用命令集中整理出来方便复制到自己的笔记里。同时也提供一份安装完成的验证清单确保每一步都做到位再交付。5.1 安装全流程命令速查从解压到启动我整理了一份浓缩版命令序列tar -xzf mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz mv mysql-5.6.51-linux-glibc2.12-x86_64/* /usr/local/mysql/ groupadd mysql useradd -g mysql -s /sbin/nologin mysql mkdir -p /data/mysql chown -R mysql:mysql /usr/local/mysql /data/mysql /usr/local/mysql/scripts/mysql_install_db --basedir/usr/local/mysql --datadir/data/mysql --usermysql /usr/local/mysql/support-files/mysql.server start cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql chmod x /etc/init.d/mysql chkconfig --add mysql chkconfig mysql on先不要急着复制执行应该逐行理解每条命令的用途。尤其是chown那一步很多人漏了导致后面权限类报错。如果你把数据目录放在系统根分区下比如/var/lib/mysql相应地调整目录路径即可。5.2 安装完成后的功能验证清单我在部署完MySQL之后会按下面这份清单逐项验证确认没遗漏ps -ef | grep mysqld能查看到mysqld进程/usr/local/mysql/bin/mysqladmin ping返回mysqld is alive/usr/local/mysql/bin/mysql -u root -p能带密码登录新建测试库和表插入一条数据再查询正常返回重启一次系统确认MySQL自动启动检查/data/mysql/error.log里没有新的ERROR级别日志最后一项别忽略。很多部署看似成功但error.log里已经堆满了警告或者错误如果不检查过几天业务一跑就出问题。养成查看error.log的习惯是数据库运维的基本素养。5.3 离线环境下维护5.6的额外建议MySQL 5.6官方已经停止维护这意味着即使发现高危漏洞也不再提供补丁。在离线环境下运行5.6一定要在架构设计上做保护数据库不要直接暴露在公网只允许内网网段访问定期做全量备份和增量备份给数据目录单独挂载磁盘避免系统盘故障连累数据。我见过不少团队因为在离线环境运行5.6就觉得非常安全、不用做加固。这种想法其实很危险。离线不等于绝对安全内网里同样可能发生误操作、恶意删除或者数据损坏。合理的做法是把“数据库版本老旧”当成一个已知风险去管理而不是忽略它。如果你后续有迁移升级的计划可以先把5.6的数据用mysqldump导出再导入到新版本环境。我试过从5.6直接dump数据导入8.0大部分情况下都能成功但要注意一些老语法在8.0里不再兼容比如部分group by写法。所以迁移前一定先在测试环境完整演练一遍别上来就动生产。6. 环境差异说明与灵活调整不同企业对服务器发行版的偏好不同有的用CentOS有的用Ubuntu有的用国内Linux发行版。虽然核心安装逻辑一致但细节上有一些差异需要单独说明。6.1 CentOS 6与CentOS 7的差异处理CentOS 6和CentOS 7是最常碰到MySQL 5.6的两个系统。CentOS 6的systemd还没普及init脚本方式chkconfig是主流而CentOS 7默认走systemd。我们前面使用chkconfig的方式在两种系统上都适用这点倒不用太纠结。CentOS 6上要注意selinux默认是强制模式enforcingMySQL如果被限制可能无法正常写数据目录。可以临时执行setenforce 0验证是否selinux导致问题如果是再按实际安全要求调整策略不建议直接永久关闭selinux。CentOS 7的selinux默认也是enforcing但MySQL 5.6在标准路径下通常不受影响只有当数据目录放在非标准位置时才有可能触发限制。6.2 Debian/Ubuntu系的差异处理Debian系的默认目录结构和RHEL系差异较大包括配置文件路径、服务管理方式都不同。在Ubuntu上离线安装MySQL 5.6我的经验是二进制包解压方式不变但数据目录放在/app/mysql或/opt/mysql这样的自定义位置避免和系统自带MySQL冲突。服务启动直接用mysqld_safe或者自己写一个systemd service文件。Ubuntu上最容易出错的是缺少libaio1和libncurses5这两个库。libaio1对应CentOS的libaiolibncurses5是mysql客户端在终端下的依赖。离线环境下提前下载libaio1和libncurses5的deb包安装后再启动MySQL就稳了。6.3 云服务器与虚拟机的注意事项不管是云服务器还是虚拟机只要内核是标准Linux这套流程都适用。但在云环境里要额外注意安全组或安全策略的配置。如果你在云上开了3306端口但my.cnf里没有设置bind-addressMySQL会默认监听所有网卡这时安全问题就会比较突出。我平时在my.cnf里会把bind-address明确写成内网IP比如bind-address 192.168.1.100这样即使安全组误开放了3306端口外部流量也无法访问到MySQL服务。如果确实需要远程连接再用SSH隧道或者跳板机方式对MySQL端口做隔离。顺便补充一点云服务器如果使用默认的yum源或apt源在离线环境下的处理方式与物理机完全一致不受到云厂商特殊组件的影响这在大多数情况下都能保证安装的一致性。7. 写在最后的一点经验MySQL 5.6的离线安装流程本质上是一套“预判依赖、准备齐全、按序执行、验证到位”的方法论。网上关于MySQL安装的教程非常多但离线环境下的坑往往不在MySQL本身而在系统环境、依赖库、目录权限这些“外围”地方。把这些前置条件理清楚后面的安装就是水到渠成的事。我个人在实际操作中最大的体会是一定要在安装前把环境检查做完不要为了赶进度跳过检查环节。很多坑在前面花五分钟检查就能避开硬着头皮往下装反而会花几个小时去排查。还有一点日志文件是最好的排查老师mysqld的error.log里几乎记录了所有启动失败的原因养成第一时间看日志的习惯会省掉很多弯路。这套流程我本人已经重复跑过多次从CentOS 6到CentOS 7再到Ubuntu基本没有遇到过跑不通的情况。如果你在离线环境安装MySQL 5.6时遇到问题建议先对照第4节的排查思路自查一遍绝大多数问题都能定位到具体环节。最后再分享一个小技巧把整个安装过程涉及到的命令、报错和解决方案整理成自己的笔记文档放进内网知识库下次接手新环境部署时照着笔记走一遍就能快速交付。