ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

MySQL 5.6.51 Community Generic 在 Linux 上的完整安装手册

MySQL 5.6.51 Community Generic 在 Linux 上的完整安装手册

接手一台还在生产环境跑 MySQL 的老机器时,最头疼的往往不是业务本身,而是版本被人为锁定在了一个比较旧的节点上。MySQL 5.6.51 这个版本属于 5.6 系列,很多发行版的软件源里根本没有这个二进制包,yum 或 apt 装不上指定版本,源码编译又费时费力。这时候官方的 Community Generic 安装包反而是最省心的方案:它是预编译好的 Linux 通用二进制,不依赖某个发行版专属的包管理,解压、初始化、配置三步走就能把实例跑起来。这份教程就针对 MySQL 5.6.51 Community Generic 在 Linux 上的完整安装,把下载校验、用户和目录规划、my.cnf 编写、数据目录初始化、systemd 托管、安全加固以及常见排错都过一遍,适合需要手动部署或维护 5.6 老实例的运维和开发参考。

1. 安装前先想清楚:为什么选 Generic 安装包

1.1 三种常见安装方式的取舍

很多刚开始接触 MySQL 部署的朋友会习惯性先敲 yum install mysql-server,遇到版本不对才意识到出了问题。这里我先把主流安装方式摆出来对比一下,你看完就明白为什么在生产环境锁定版本时,Generic tar 包往往比包管理器更可靠。

安装方式优点缺点适用场景
yum / apt 安装命令简单,依赖自动处理仓库里的版本通常比较旧,无法精确安装 5.6.51测试环境、对版本不敏感的场景
源码编译可自定义编译参数和安装路径耗时长,依赖工具链复杂,容易编译失败特殊硬件、特殊优化需求
Generic tar 包官方预编译,版本精确,目录可控,升级切换方便需要手动管理权限、systemd 服务、日志轮转生产环境标准部署、版本锁定

Generic 包在官方文档里也常被称为“Linux Generic”,本质上是一套基于 glibc 编译的二进制文件集合。它不像 RPM 包那样把文件散落到系统目录里,而是集中在单一文件夹下,这样你要迁移、升级或彻底卸载时都会非常干净。

1.2 版本兼容与系统环境判断

安装前先确认两件事:操作系统架构和 glibc 版本。MySQL 5.6.51 的 Generic 包命名一般是 mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz,这个命名就明确告诉你了它要求系统的 glibc 版本不低于 2.12。绝大多数 CentOS 7、Ubuntu 16.04 及更新版本都满足要求。

检查 glibc 版本可以用一行命令:

ldd --version

如果输出里能看到类似“Linux 2.12”的字样或者更高的版本号,那说明系统可以正常支撑这个包。另外,需要注意磁盘空间。MySQL 5.6 的安装包本身只有几百 MB,但初始化后的数据目录、binlog、错误日志会持续增长,我建议先确认数据盘至少有 10GB 以上可用空间,并且最好把数据目录单独放在一个分区上,避免和系统盘抢占 I/O。

2. 下载、校验与环境准备

2.1 下载安装包并核对校验值

下载 MySQL 5.6.51 的官方地址在 MySQL 官网的历史版本下载页面里,搜索时记得带上“Archives”或“5.6”关键字。直接在服务器上拉取时,建议用 wget 下载:

wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz

下载完成后,一定不要急着解压,先做校验。官方页面会提供 MD5 和 SHA256 校验值,我们实际执行:

md5sum mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz sha256sum mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz

然后把输出结果和官网给的校验值做对比。这一步很关键,网络传输过程中文件损坏虽然概率低,但一旦发生,解压或初始化时会报出各种莫名其妙的错误。更严重的是,如果下载源被污染,文件可能被替换,校验能帮你避免这种情况。

2.2 系统依赖检查与安装

MySQL 5.6 在运行时依赖一些基础库,最常见的是 libaio、ncurses 和 perl。缺少这些依赖时,初始化阶段会出现找不到 libaio.so.1 之类的报错。在基于 RHEL 的发行版上执行:

yum install -y libaio libaio-devel ncurses-libs perl

如果是 Debian 或 Ubuntu 系列,则执行:

apt-get install -y libaio1 libncurses5 perl

这里我特别强调一下 libaio,它是异步 I/O 的支撑库,MySQL 的 InnoDB 引擎在启动时会尝试加载它。如果缺失,mysqld 会直接拒绝启动。所以提前装好能省掉后面很多排查时间。

2.3 创建专用用户并规划目录结构

MySQL 进程绝对不能以 root 身份运行,这是基本的安全底线。创建专用系统用户:

groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql

注意这里用了 -s /sbin/nologin,即使用户被攻破或误操作,也无法直接登录系统 shell,这是一个额外的安全保险。

接下来规划目录结构。我不建议把数据文件放在安装目录下,而是把“程序”和“数据”分离:

  • /usr/local/mysql 程序目录,存放二进制文件
  • /data/mysql/data 数据目录,存放 InnoDB 表空间、系统表
  • /data/mysql/logs 日志目录,存放错误日志和 binlog

这样做的原因很实际:当 MySQL 需要升级时,程序目录可以直接替换;而数据目录独立,最大限度避免误操作。后面所有目录记得把属主和属组都改成 mysql。

3. 解压安装、编写配置与初始化数据目录

3.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-5.6.51 ln -s /usr/local/mysql-5.6.51 /usr/local/mysql

接着创建数据目录和日志目录,并设置属主:

mkdir -p /data/mysql/data mkdir -p /data/mysql/logs mkdir -p /data/mysql/run chown -R mysql:mysql /data/mysql chown -R mysql:mysql /usr/local/mysql

这里要提醒一下:ln -s 这个软链接的做法很值得保留。以后如果要从 5.6 升级到 5.7,只需要把软链接指向新目录,再按官方步骤完成数据升级即可,减少路径调整带来的风险。

3.2 手写一份实用的 my.cnf

MySQL 的配置集中在一个 my.cnf 文件里。我倾向于在初始化之前就把核心参数都写清楚,避免启动后再改来改去。下面是一份在中小型生产环境中实测可用的配置:

[client] port = 3306 socket = /tmp/mysql.sock default-character-set = utf8mb4 [mysqld] user = mysql basedir = /usr/local/mysql datadir = /data/mysql/data socket = /tmp/mysql.sock pid-file = /data/mysql/run/mysql.pid log-error = /data/mysql/logs/error.log character-set-server = utf8mb4 collation-server = utf8mb4_general_ci server-id = 100 log-bin = /data/mysql/logs/binlog binlog_format = row symbolic-links = 0 max_connections = 500 innodb_buffer_pool_size = 1G innodb_log_file_size = 256M skip-name-resolve

逐项说明几个核心参数的意义。basedir 和 datadir 是必须明确指出的,它们是 MySQL 找程序和数据的根。socket 和 pid-file 路径要保证目录存在,否则启动会报错。log-error 指定错误日志位置,排错时这是第一手信息。

字符集设置 utf8mb4 是为了兼容现代应用中常见的 emoji 和生僻字。innodb_buffer_pool_size 建议设置为物理内存的 50% 到 70%,比如物理内存是 4G,那设置 2G 左右比较合理,我这里写 1G 作为保守示例。log-bin 开启二进制日志后,数据目录会额外占用空间,但对于后续主从复制和基于时间点的恢复是必需品。binlog_format 设置为 row,虽然会占用更多日志空间,但安全性最高,不会因为语句执行顺序问题导致主从不一致。

3.3 初始化数据目录并处理初始状态

初始化是 MySQL 5.6 最容易出错的环节。注意,5.6 版本不支持 mysqld --initialize 这种新式初始化命令,必须使用 scripts 目录下的 mysql_install_db 工具:

/usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/data/mysql/data --user=mysql

执行时一定要用绝对路径指定 basedir 和 datadir,避免它去猜默认的 /usr/local/mysql 或 /var/lib/mysql。如果一切正常,屏幕上会出现 “Installing MySQL system tables” 和 “OK” 之类的输出,最后提示初始化完成。

初始化完成后,数据目录里会出现 mysql、performance_schema 等系统库文件和 ibdata1 表空间文件。此时 root 用户的初始状态是空密码,但不要立刻用远程方式连接,先在本地通过 socket 登录验证:

/usr/local/mysql/bin/mysql -uroot -S /tmp/mysql.sock

如果登录成功,说明初始化基本没问题。接下来的步骤就是修改密码和做安全加固。

4. 启动服务、配置开机自启与路径

4.1 手工试启动并验证运行状态

正式写入 systemd 之前,我建议先手工启动一次,确认二进制、配置文件和目录权限都没问题。MySQL 5.6 官方推荐的启动入口是 mysqld_safe,它是一个包装脚本,会在后台启动 mysqld,并在进程崩溃时尝试重启:

/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &

启动后不要急着操作,等两三秒再检查错误日志:

tail -f /data/mysql/logs/error.log

看到类似 “ready for connections” 的字样时,说明服务已经正常监听。再验证端口和进程:

netstat -tnlp | grep 3306 ps -ef | grep mysqld

这里我实际遇到过的坑是:配置文件里写的 socket 路径和客户端连接时指定的 socket 路径不一致,导致明明服务在跑,客户端却报找不到 socket。所以手工启动时一定要确认 my.cnf 里的 socket 是 /tmp/mysql.sock,后续客户端统一用这个路径。

4.2 编写 systemd 单元文件实现托管

手工启动能跑通,不代表生产环境可以这么用。需要把 MySQL 托管给 systemd,这样开机自启、崩溃拉起和日志查看都统一了。

新建文件 /etc/systemd/system/mysqld.service:

[Unit] Description=MySQL 5.6.51 Community Server After=network.target [Service] Type=forking User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf ExecStop=/usr/local/mysql/bin/mysqladmin -uroot -S /tmp/mysql.sock shutdown TimeoutSec=300 PrivateTmp=true [Install] WantedBy=multi-user.target

这里有几个关键点。Type=forking 是因为 mysqld_safe 启动后会 fork 出 mysqld 子进程,然后自己常驻,systemd 需要知道这个行为才能正确判断服务是否启动完成。ExecStop 使用 mysqladmin 优雅关闭,而不是粗暴 kill 进程,这样可以保证 InnoDB 完成崩溃恢复流程,避免数据损坏。

写好单元文件后执行:

systemctl daemon-reload systemctl start mysqld systemctl enable mysqld

如果启动失败,先执行 systemctl status mysqld 查看状态,再结合错误日志定位问题。整体而言,systemd 托管后的操作就统一了:以后启停只需要 systemctl start mysqld 和 systemctl stop mysqld。

4.3 环境变量与后续命令便利

安装完成后,为了让 mysql、mysqldump 等命令在任意目录都能直接使用,配置一下 PATH 环境变量。新建文件 /etc/profile.d/mysql.sh:

export PATH=/usr/local/mysql/bin:$PATH

保存后执行 source /etc/profile 或重新登录当前会话即可。这里我特别提醒一点:不要在生产环境把 /usr/local/mysql/lib 直接加入到 LD_LIBRARY_PATH,因为这样可能影响系统里其他软件加载的动态库版本,引发难以排查的兼容性问题。MySQL 客户端通常不需要额外设置库路径,保持简单才是上策。

5. 安全加固与连接配置

5.1 修改 root 密码并验证登录

刚初始化的 MySQL,root 用户密码为空,这是很危险的状态。第一件要做的事就是改密码。通过本地 socket 登录:

/usr/local/mysql/bin/mysql -uroot -S /tmp/mysql.sock

在 MySQL 命令行中执行:

mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('YourStrongPass123!'); mysql> FLUSH PRIVILEGES;

MySQL 5.6 还在使用 PASSWORD 函数和 mysql_native_password 插件,所以不能用 8.0 时代的 ALTER USER 语法。这一点在后续迁移到高版本时尤其要注意,旧密码哈希格式和新版本不完全兼容,升级前必须做好密码策略的确认。

修改完成后,退出并用密码重新登录验证一次:

/usr/local/mysql/bin/mysql -uroot -p -S /tmp/mysql.sock

如果本地能正常登录,说明密码设置生效。此时还要考虑客户端工具,后面写脚本或使用程序连接时,密码中如果有特殊字符记得做转义。

5.2 用 mysql_secure_installation 快速加固

MySQL 官方提供了一个交互式安全加固工具,叫做 mysql_secure_installation,它会引导你完成几项基础安全设置。执行命令:

/usr/local/mysql/bin/mysql_secure_installation

工具会依次问你:

加固项建议操作
设置 root 密码如果前面没设过,在这里设置
删除匿名用户选择 Y,去除无认证入口
禁止 root 远程登录选 Y,root 只允许本机连接
删除 test 数据库选 Y,避免测试库残留
重新加载权限表选 Y,使配置立即生效

这个工具适合刚入门的朋友,一步步操作不容易漏。但生产环境如果要批量部署,交互式工具就显得低效,我通常会把对应的 SQL 直接整理成脚本:

DELETE FROM mysql.user WHERE User=''; DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); DROP DATABASE IF EXISTS test; DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'; FLUSH PRIVILEGES;

这套脚本和交互式工具的效果是一致的,执行之前建议先备份 mysql.user 表,避免误删导致登录异常。

5.3 创建应用账号并开放远程访问

业务程序一般不建议使用 root 连接数据库,而是创建独立账号并限定权限。在数据库执行:

CREATE USER 'appuser'@'192.168.1.%' IDENTIFIED BY 'AppUserPass2024'; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'appuser'@'192.168.1.%'; FLUSH PRIVILEGES;

这里把主机限定为 192.168.1.% 网段,而不是直接写成 %,最大程度减少数据库暴露面。如果应用服务器和数据库在同一内网,这种写法既能正常连接,又不会让整个互联网的客户端都能尝试认证。

远程访问还需要确认 MySQL 的 bind-address 配置。默认情况下,MySQL 只监听 127.0.0.1,外部机器无法连接。如果需要内网访问,在 my.cnf 的 [mysqld] 下加上:

bind-address = 0.0.0.0

然后重启服务。注意,监听所有网卡虽然方便,但一定要靠防火墙限制端口 3306 的访问来源。用 iptables 或云安全组只开放给必要的应用服务器网段,这才是安全的核心手段。

6. 常见问题与实战排查

6.1 初始化阶段的经典报错

我见到的初始化失败,大多数集中在依赖缺失、目录权限和已存在数据这几个原因上。

报错信息原因解决方法
error while loading shared libraries: libaio.so.1缺少 libaioyum install -y libaio 或 apt install -y libaio1
Could not find mysql_install_db路径不对使用绝对路径 /usr/local/mysql/scripts/mysql_install_db
ERROR: The partition where /data/mysql/data resides is too full空间不足清理磁盘或换数据盘
mysqld: Can't create/write to file数据目录权限不对chown -R mysql:mysql /data/mysql
Fatal error: Can't open and lock privilege tables系统表初始化异常清空数据目录重新初始化,但要确认磁盘数据可丢弃

这些问题的共同点在于,错误信息都已经直接指明了方向。我的排查习惯是:先看最后几行报错,再用 ldd 检查依赖,最后确认权限。不要一上来就重装几次,容易把数据目录搞乱。

6.2 启动阶段的连接与权限问题

启动阶段的报错往往更隐蔽,因为服务可能已经在跑了,但客户端连不上。最常见的提示是:

Can't connect to local MySQL server through socket '/tmp/mysql.sock'

这个报错出现时,先确认 mysqld 是否真的在运行,再看 socket 路径是否和 my.cnf 一致。我遇到过 config 里写的是 /var/lib/mysql/mysql.sock,但客户端默认连 /tmp/mysql.sock,两边各说各话,自然连不上。

还有一类问题来自 SELinux。CentOS 7 默认开启 SELinux,它可能会阻止 mysqld 读取我们自定义的 /data/mysql 目录。出现权限问题时,可以用 restorecon 重新打标签:

restorecon -R /data/mysql

如果依然有问题,再在 SELinux 的布尔值里放行:

setsebool -P mysqld_disable_trans 1

不过这个方法放行范围比较大,建议优先用 restorecon 解决路径上下文问题。对于 Ubuntu 系统,对应要留意 AppArmor,它默认会限制 mysqld 可访问的目录,自定义数据目录时经常需要调整 AppArmor 配置。

6.3 忘记 root 密码的恢复流程

运维过程中总会遇到一次忘记 root 密码的情况。MySQL 5.6 提供了 skip-grant-tables 来跳过权限验证,但使用时要格外谨慎。恢复流程:

systemctl stop mysqld /usr/local/mysql/bin/mysqld_safe --skip-grant-tables --skip-networking &

必须加上 --skip-networking,因为它只允许本机通过 socket 连接,禁止任何网络请求,防止在跳过权限验证期间被外部入侵。然后登录:

/usr/local/mysql/bin/mysql -uroot -S /tmp/mysql.sock

执行:

FLUSH PRIVILEGES; SET PASSWORD FOR 'root'@'localhost' = PASSWORD('NewPass123!');

注意,在 skip-grant-tables 状态下,直接执行 SET PASSWORD 可能没有效果,必须先执行 FLUSH PRIVILEGES 让权限表生效。改完密码后,重启 MySQL 恢复正常模式,再用新密码登录验证一次。

6.4 关于 5.6 停维护状态的提醒

这里必须把丑话说在前头:MySQL 5.6 的官方维护周期早已结束,意味着后续不会再收到社区版的安全补丁。5.6.51 是 5.6 系列后期的重要版本,对于必须运行在老旧环境里的业务,它能作为临时稳定节点,但不应作为长期方案。

如果这台实例还要扛比较长的时间,我的建议是尽快规划升级路线。方向有两个:一是直接升级到 MySQL 5.7 或 8.0,二是迁移到兼容 MySQL 5.6 协议的社区分支。不管是哪条路,都要先做一次全量备份,再在测试环境完整演练数据迁移和业务回归。尤其是密码认证方式、字符集排序规则、SQL_MODE 的差异,这些在实际升级中踩坑最多。

我个人在实际操作中的体会是:Generic 安装包本身非常简单,真正考验人的是后续的系统集成工作,比如 systemd 托管、SELinux 上下文、日志轮转、监控打通、备份策略。安装不是终点,服务能稳定跑一年、数据能随时恢复,才是部署的价值所在。

最后再分享一个小习惯:每次初始化完成、修改完配置之后,都立刻执行一次全量备份并验证备份文件可恢复。别把备份留到上线以后,因为那时候你根本没时间处理备份链条上的问题。在 /data/mysql/logs 目录留一份完整的错误日志历史,排查问题时你会感谢当时的自己。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进