简介:本资源为 MySQL 5.7.40 在 Linux-glibc2.12 环境下的 x86_64 离线安装包,面向需要在无外网或内网环境中部署关系型数据库的运维与后端开发人员。压缩包共 379 个文件,约 646.59MB,以 h 头文件、so 动态库、xml 配置、sql 脚本及 mysqld、mysql、mysqldump 等可执行程序为主,完整覆盖服务端、客户端与配套工具链,解压后即可获得可直接运行的目录结构。目前已有 748 人学习下载。资源内含初始化脚本、安全配置工具与多类命令行客户端,便于读者在离线条件下完成数据库初始化、权限设置与日常运维,同时可借助 InnoDB 引擎改进、JSON 支持及 TLS 1.2 加密等特性,搭建稳定且功能完整的数据库服务,适合作为内网部署与版本升级的参考包。
1. 离线环境里,为什么 MySQL 5.7 的 tar.gz 包依然是首选
在不少内网机房、专有云和工业控制场景里,服务器根本连不上外网,yum 或 apt 源形同虚设。这时候拿到一个mysql-5.7.40-linux-glibc2.12-x86-64.tar.gz,往往就是唯一能把数据库跑起来的办法。它不依赖系统包管理器,不挑发行版,只要 glibc 版本对得上,解压、初始化、配参数就能用。这篇文章面向的是需要在隔离网络里部署 MySQL 5.7 的运维和开发人员,我会把从解压到能远程连接的全过程拆开,包括初始化参数怎么设、配置文件写什么、权限怎么给,以及那些让我熬夜排查过的坑。读完你就能在一台干净的 Linux 机器上,用这个离线包把 MySQL 5.7 完整跑起来。
2. 解压之前先把系统依赖和用户组理清楚
2.1 确认 glibc 版本与包名含义
mysql-5.7.40-linux-glibc2.12-x86-64.tar.gz这个文件名本身就带着关键信息。glibc2.12表示这个二进制包是在 glibc 2.12 环境下编译的,通常能向下兼容到 CentOS 6.5 及以上、Ubuntu 14.04 及以上。但要注意,如果目标机器的 glibc 版本低于 2.12,比如某些老旧的嵌入式裁剪系统,直接运行会报GLIBC_2.14 not found之类的错误。我一般会先用一条命令确认:
ldd --version | head -n 1 # 输出示例:ldd (GNU libc) 2.17如果版本低于 2.12,这个包基本用不了,得换更老的编译版本或者升级系统。另外x86-64说明是 64 位包,32 位系统直接放弃。确认完这两点,再往下走。
2.2 创建专用用户和组,别用 root 跑 mysqld
MySQL 官方建议用非 root 用户运行 mysqld,这是血泪教训。曾经有一次我图省事直接用 root 启动,结果后续通过SELECT ... INTO OUTFILE写文件时权限混乱,清理起来非常麻烦。正确做法是先建组和用户:
groupadd mysql useradd -r -g mysql -s /bin/false mysql # -r 表示系统用户,-s /bin/false 禁止登录 shell然后检查/etc/passwd里 mysql 用户的 UID 和 GID,后面解压目录的属主必须和它一致。如果机器上已经有 mysql 用户,跳过创建,但要用id mysql确认一下。
2.3 解压到 /usr/local 并重命名
我习惯把 MySQL 放在/usr/local/mysql,这样后续配置路径统一,不容易乱。操作如下:
tar -zxvf mysql-5.7.40-linux-glibc2.12-x86-64.tar.gz -C /usr/local/ mv /usr/local/mysql-5.7.40-linux-glibc2.12-x86-64 /usr/local/mysql chown -R mysql:mysql /usr/local/mysql解压后可以看一眼目录结构,bin下是mysqld、mysql等可执行文件,support-files里有默认配置模板和启动脚本。这些后面都会用到。注意不要用--strip-components把顶层目录去掉,否则路径会乱。
3. 初始化数据目录:参数选错,后面全是坑
3.1 用 mysqld --initialize 还是 --initialize-insecure
MySQL 5.7 不再像 5.6 那样用mysql_install_db脚本,而是用mysqld --initialize。这个参数有两个变体:
--initialize:生成一个随机的 root 临时密码,写在错误日志里。--initialize-insecure:root 密码为空,首次登录后必须立刻改。
在内网离线环境,我通常用--initialize-insecure,因为随机密码要去日志里翻,容易出错。但生产环境建议用--initialize,强制走一次密码修改流程。初始化命令如下:
/usr/local/mysql/bin/mysqld --initialize-insecure \ --user=mysql \ --basedir=/usr/local/mysql \ --datadir=/usr/local/mysql/data \ --explicit_defaults_for_timestamp这里--explicit_defaults_for_timestamp是为了避免 TIMESTAMP 列的默认行为在 5.7 里出现警告,建议加上。--basedir和--datadir必须写绝对路径,否则 mysqld 可能找不到。
3.2 数据目录权限和 AppArmor/SELinux 的干扰
初始化完成后,data目录下会出现ibdata1、mysql、sys等文件。此时要再次确认属主:
chown -R mysql:mysql /usr/local/mysql/data chmod 750 /usr/local/mysql/data如果系统开了 SELinux 或 AppArmor,即使权限对,mysqld 也可能被拒绝访问。我遇到过 CentOS 7 上 SELinux 导致mysqld无法写ib_logfile的情况。临时排查可以用setenforce 0,但长期方案是给 MySQL 数据目录打上正确的 SELinux 上下文:
semanage fcontext -a -t mysqld_db_t "/usr/local/mysql/data(/.*)?" restorecon -Rv /usr/local/mysql/data如果semanage命令不存在,说明policycoreutils-python没装,离线环境只能先关 SELinux 或手动改/etc/selinux/config。
3.3 错误日志在哪里看
初始化过程中如果失败,错误不会直接打印到终端,而是写到数据目录下的*.err文件里。我一般会先tail -f这个文件:
ls /usr/local/mysql/data/*.err tail -n 50 /usr/local/mysql/data/*.err常见错误包括Can't create/write to file(权限问题)、InnoDB: Cannot allocate memory(内存不足)、unknown variable(参数拼写错误)。看到具体报错再针对性解决,比盲目重试快得多。
4. 配置文件与启动脚本:让 mysqld 按你的规矩跑
4.1 写一个最小可用的 my.cnf
MySQL 5.7 会按顺序读/etc/my.cnf、/etc/mysql/my.cnf、$basedir/my.cnf等。为了避免和系统自带的配置冲突,我通常在$basedir下新建一个my.cnf,然后用--defaults-file显式指定。最小配置如下:
[mysqld] basedir = /usr/local/mysql datadir = /usr/local/mysql/data socket = /tmp/mysql.sock port = 3306 pid-file = /usr/local/mysql/data/mysqld.pid log-error = /usr/local/mysql/data/mysqld.err character-set-server = utf8mb4 collation-server = utf8mb4_general_ci explicit_defaults_for_timestamp = true max_connections = 500 innodb_buffer_pool_size = 512Minnodb_buffer_pool_size建议设为物理内存的 50%~70%,但离线环境如果机器内存小,512M 起步比较稳妥。character-set-server用utf8mb4避免 emoji 乱码。socket路径不要放在/var/lib/mysql,因为那个目录可能不存在。
4.2 用 mysqld_safe 还是 systemd
离线包自带support-files/mysql.server脚本,可以拷贝到/etc/init.d/mysql然后用service mysql start。但在 CentOS 7 及以上,systemd 更规范。我一般直接写一个 unit 文件:
[Unit] Description=MySQL 5.7 Server After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/usr/local/mysql/my.cnf ExecStop=/bin/kill -SIGTERM $MAINPID Restart=on-failure LimitNOFILE=65535 [Install] WantedBy=multi-user.target保存为/etc/systemd/system/mysql.service,然后systemctl daemon-reload、systemctl start mysql。注意LimitNOFILE要设大,否则高并发时会出现Too many open files。
4.3 首次登录和改密码
如果用--initialize-insecure初始化,root 密码为空,直接登录:
/usr/local/mysql/bin/mysql -u root -S /tmp/mysql.sock进去后立刻改密码:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPassword123!'; FLUSH PRIVILEGES;如果要用mysql命令不带-S,需要把 socket 路径写进/etc/my.cnf的[client]段,或者设置环境变量MYSQL_UNIX_PORT。我一般会在[client]里也写一份 socket 和 port,方便本地工具连接。
5. 避坑与排查:那些让我重启了十几次的问题
5.1 启动报 “Can't open the mysql.plugin table”
现象:mysqld启动失败,错误日志里写Can't open the mysql.plugin table. Please run mysql_upgrade。 原因:数据目录没有正确初始化,或者datadir指向了空目录。 解决:确认datadir路径下有没有mysql子目录。如果没有,重新执行mysqld --initialize-insecure,并确保--datadir和配置文件里一致。
5.2 远程连接被拒:Host is not allowed
现象:本地能连,远程mysql -h 192.168.x.x -u root -p报Host '192.168.x.x' is not allowed to connect。 原因:MySQL 用户表里 root 只允许localhost登录。 解决:登录本地后执行:
CREATE USER 'root'@'%' IDENTIFIED BY 'YourStrongPassword123!'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;但生产环境不要用%,应该指定具体网段,比如'root'@'192.168.1.%'。
5.3 内存不足导致 InnoDB 初始化失败
现象:初始化时卡住,错误日志写InnoDB: Cannot allocate memory for the buffer pool。 原因:innodb_buffer_pool_size设得太大,超过了可用内存。 解决:临时调小到 128M 或 256M,初始化成功后再逐步调大。离线环境可以用free -m看可用内存,留出至少 1G 给系统。
5.4 时区不对导致时间差 8 小时
现象:SELECT NOW()返回的时间比本地时间少 8 小时。 原因:MySQL 默认时区是 UTC,而系统是 CST。 解决:在my.cnf的[mysqld]段加default-time-zone = '+08:00',然后重启。或者登录后执行SET GLOBAL time_zone = '+08:00';,但重启会失效。
5.5 忘记 root 密码怎么办
现象:改完密码后忘了,或者接手别人的机器不知道密码。 原因:没有记录密码。 解决:停掉 mysqld,用--skip-grant-tables启动:
/usr/local/mysql/bin/mysqld --defaults-file=/usr/local/mysql/my.cnf --skip-grant-tables &然后无密码登录,执行UPDATE mysql.user SET authentication_string = PASSWORD('NewPass') WHERE User = 'root';,再FLUSH PRIVILEGES;。最后正常重启。注意 5.7 的密码字段是authentication_string,不是password。
6. 进阶技巧:让离线部署更稳的几个习惯
6.1 用 mysql_config_editor 保存连接凭证
离线环境经常要连多个实例,每次输密码很烦。可以用mysql_config_editor把密码加密存到~/.mylogin.cnf:
/usr/local/mysql/bin/mysql_config_editor set --login-path=local --host=localhost --user=root --password # 输入密码后,以后用 mysql --login-path=local 即可这个文件是二进制加密的,比明文写在脚本里安全。但注意它绑定当前用户的家目录,换用户就失效。
6.2 定期用 mysqldump 做逻辑备份
离线环境没有云备份,我习惯每天凌晨用mysqldump导出一份 SQL 文件,保留 7 天:
/usr/local/mysql/bin/mysqldump --login-path=local \ --single-transaction --routines --triggers \ --databases your_db > /backup/your_db_$(date +%F).sql--single-transaction保证 InnoDB 表一致性,不锁表。--routines和--triggers把存储过程和触发器也带上。备份文件要放到另一块盘或远程挂载的存储上,别和数据目录放一起。
6.3 监控连接数和慢查询
MySQL 5.7 自带performance_schema,可以查当前连接数:
SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep';慢查询需要先在my.cnf里开:
slow_query_log = 1 slow_query_log_file = /usr/local/mysql/data/slow.log long_query_time = 2然后SET GLOBAL slow_query_log = ON;动态生效。我一般把long_query_time设为 2 秒,超过就记下来,后续用mysqldumpslow分析。
6.4 一个我踩过的坑:不要随意改 lower_case_table_names
有一次为了兼容大小写,我在my.cnf里加了lower_case_table_names = 1,结果重启后 InnoDB 报错,因为初始化时这个参数是 0,运行中改会导致表名映射混乱。这个参数只能在初始化前设定,初始化后改会直接启动失败。如果非要改,只能备份数据、删掉数据目录、重新初始化、再导入。所以我的习惯是:初始化之前就想清楚,之后绝不碰它。
6.5 验证部署是否成功的三个命令
最后,我一般用这三条命令确认 MySQL 5.7 离线部署真的稳了:
# 1. 检查进程和端口 ps -ef | grep mysqld | grep -v grep ss -tlnp | grep 3306 # 2. 检查版本和字符集 /usr/local/mysql/bin/mysql --login-path=local -e "SELECT VERSION(), @@character_set_server, @@time_zone;" # 3. 建库建表插数据再删掉 /usr/local/mysql/bin/mysql --login-path=local -e "CREATE DATABASE test_tmp; USE test_tmp; CREATE TABLE t1(id INT PRIMARY KEY, name VARCHAR(20)); INSERT INTO t1 VALUES(1,'a'); SELECT * FROM t1; DROP DATABASE test_tmp;"三条都通过,基本可以交付了。离线部署 MySQL 5.7 这件事,说难不难,但细节特别多,尤其是权限、SELinux、时区和密码这四块,我几乎每次都要重新确认一遍。希望帮到你。
本文还有配套的精品资源,点击获取