简介:这份资源是 MySQL 4.1.18 的 Linux 二进制安装包,面向需要在 PC 架构 Linux 系统上搭建关系型数据库的初学者与小型项目开发者。它基于 GNU 工具链并依赖 glibc23 库,解压后即可按官方文档完成配置与安装,省去自行编译的繁琐,适合用作数据库管理入门、SQL 基础练习或轻量级应用后台的实践环境。压缩包共 1269 个文件,约 24.48MB,内含可执行程序、测试用例、配置模板与文档手册等多类内容:result、test 等文件对应功能验证与回归测试,h、inc 等为开发头文件,cnf、cfg 提供配置样例,readme、txt 则记录安装与使用说明,目录结构完整,便于按模块查阅。目前已有 131 人学习下载。通过该包,读者可实际运行 mysqld、mysqladmin、mysqldump 等工具,熟悉 root 账户初始化、权限分配与数据备份流程,并借助自带测试脚本理解索引、视图、触发器和存储过程等基础特性,为后续版本升级与运维打下扎实根基。
1. 老 i686 机器上跑 MySQL:这个 tar 包到底解决什么问题
手里有一台还在服役的 32 位 x86 老机器,或者一个跑着老版本国产 Linux 的隔离环境,想装个 MySQL 存点业务数据,结果mysql官网下载页翻到底也找不到能用的二进制包——这个场景我遇到过不止一次。mysql-standard-4.1.18-pc-linux-gnu-i686-glibc23.tar就是为这种局面准备的:它是 MySQL 4.1.18 官方编译好的 32 位 Linux 二进制发行包,i686说明目标 CPU 是 32 位 x86 架构,glibc23说明它链接的是 glibc 2.3 时代的 C 运行库,tar说明它是个解压即用的绿色包,不需要rpm或apt参与。它解决的核心问题是:在没有包管理器、没有编译工具链、甚至没有网络的老环境里,把一套能跑的 MySQL 服务端和客户端落到磁盘上。适合谁?适合维护老旧工控机、内网隔离设备、教学实验环境的运维和嵌入式工程师。不适合谁?不适合追求新特性、需要 JSON 字段或窗口函数的生产系统——4.1 这个版本连存储过程都还没有。
2. 拆开这个 tar 包:目录结构、依赖链和选型判断
2.1 解压后你会看到什么
先把包解开,别急着初始化。用tar -zxvf解到/usr/local下,这是老版本 MySQL 二进制包的惯例路径。
# 解压到 /usr/local,注意 -C 指定目标目录 tar -zxvf mysql-standard-4.1.18-pc-linux-gnu-i686-glibc23.tar -C /usr/local # 解压后会得到一个长名字目录,改短方便后续引用 cd /usr/local mv mysql-standard-4.1.18-pc-linux-gnu-i686-glibc23 mysql解压完ls /usr/local/mysql,你会看到几个关键目录:bin放mysqld、mysql、mysqladmin这些可执行文件;scripts放mysql_install_db初始化脚本;share放错误信息文件和字符集;support-files放启动脚本模板和示例配置。没有data目录,因为数据目录要你自己初始化生成。这个结构和现代 MySQL 8.x 的 tar 包逻辑一致,只是少了lib下的插件目录。
参数说明:-z表示用 gzip 解压,-x是提取,-v显示过程,-f指定文件名。顺序上-f必须紧跟文件名,写成tar -zxvf file.tar没问题,但tar -zxfv file.tar在某些老 tar 上会报错。如果目标机器连tar都没有(热词里有人搜「linux没有tar命令」),那得先想办法把tar二进制弄进去,或者用busybox tar替代。
2.2 glibc23 这个标签意味着什么
glibc23不是随便写的。它表示这个二进制包在编译时链接的是 glibc 2.3.x 系列。glibc 是 Linux 上最底层的 C 库,几乎所有用户态程序都依赖它。二进制程序在运行时需要找到对应版本的libc.so.6,如果目标系统的 glibc 版本低于编译时的版本,程序会直接报FATAL: kernel too old或者version GLIBC_2.3 not found。
这里有个反直觉的点:glibc 版本号不是越高越好。高版本 glibc 编译出来的程序,拿到低版本系统上跑不了;反过来,低版本编译的程序在高版本系统上通常能跑。所以glibc23这个包的可移植性其实不错——只要目标系统的 glibc 不低于 2.3,基本都能启动。现代发行版比如 openEuler、麒麟 V10 的 glibc 都在 2.28 以上,跑这个包没问题。但要注意热词里提到的fatal glibc error: cpu does not support x86-64-v2——那是 64 位系统上 CPU 指令集的问题,和这个 32 位包无关,别混为一谈。
2.3 为什么选二进制包而不是源码编译
在老机器上编译 MySQL 源码是件痛苦的事。4.1 时代的源码编译需要gcc、make、ncurses、openssl一堆依赖,编译一次动辄半小时以上,中间还可能因为缺少某个头文件中断。二进制包的优势是:解压即用,不依赖编译工具链,不挑内核小版本。代价是:你没法针对特定 CPU 做指令集优化,也没法裁剪不需要的存储引擎。
我一般会这样判断:如果目标机器有完整的开发工具链且 CPU 性能尚可,源码编译能拿到更好的性能;如果目标机器是个连gcc都没装的精简系统,或者你只是临时搭个测试库,二进制包是唯一现实的选择。这个i686包还有个隐藏好处:它能在 64 位系统上以 32 位模式运行,前提是系统装了 32 位兼容库(glibc.i686、libstdc++.i686)。有些国产 Linux 默认不装 32 位库,需要手动补。
3. 从解压到能连上:初始化、配置和启动的完整命令链
3.1 创建 mysql 用户和初始化数据目录
MySQL 不允许以 root 身份运行mysqld,这是硬性安全策略。先建用户和组。
# 创建 mysql 组和用户,-r 表示系统用户,-s 指定不可登录 shell groupadd mysql useradd -r -g mysql -s /bin/false mysql # 进入 mysql 目录,执行初始化脚本 cd /usr/local/mysql ./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/datamysql_install_db这个脚本会做几件事:创建data目录、生成mysql系统库(存用户权限)、生成test库、写入初始的root@localhost和root@主机名账号。注意 4.1 版本的mysql_install_db是 shell 脚本,不是后来 5.7 的二进制程序,参数写法不一样。
参数说明:--user=mysql指定运行身份,--basedir指定安装根目录,--datadir指定数据目录。如果datadir路径不存在,脚本会尝试创建,但父目录权限不对会失败。初始化完成后,data目录下会出现ibdata1、ib_logfile0、ib_logfile1和mysql子目录。ibdata1是 InnoDB 的共享表空间,4.1 默认存储引擎还是 MyISAM,但 InnoDB 已经内置了。
3.2 配置文件 my.cnf 的关键参数
4.1 版本会按顺序读/etc/my.cnf、/usr/local/mysql/etc/my.cnf、~/.my.cnf。我一般把配置放在/etc/my.cnf,内容精简到只写必要项。
[mysqld] basedir = /usr/local/mysql datadir = /usr/local/mysql/data port = 3306 socket = /tmp/mysql.sock user = mysql # 老机器内存有限,key_buffer 别设太大 key_buffer = 16M max_connections = 50 # 4.1 默认字符集是 latin1,要存中文必须改 default-character-set = utf8key_buffer是 MyISAM 索引缓存,4.1 时代大部分表还是 MyISAM,这个值直接决定索引查询性能。老机器内存可能只有 256M 或 512M,设 16M 到 32M 比较稳妥,设太大反而会触发 swap。max_connections默认是 100,老机器扛不住,降到 50 减少内存占用。default-character-set必须改成utf8,否则中文会变成乱码——这是血泪经验,4.1 的默认字符集是latin1,建库时不指定字符集,存进去的中文取出来就是问号。
3.3 启动服务并验证连接
启动方式有两种:直接用mysqld_safe后台拉起,或者用support-files/mysql.server脚本。我倾向后者,因为它带start、stop、restart子命令,管理起来规范。
# 复制启动脚本到 init.d 并赋予执行权限 cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql chmod +x /etc/init.d/mysql # 启动服务 /etc/init.d/mysql start # 验证进程和端口 ps aux | grep mysqld netstat -tlnp | grep 3306 # 用客户端连接 /usr/local/mysql/bin/mysql -u root -p第一次连接时 root 没有密码,直接回车即可。连上后立刻设密码:SET PASSWORD FOR 'root'@'localhost' = PASSWORD('你的密码');。4.1 的密码哈希算法和 5.x 不同,PASSWORD()函数生成的是 16 位哈希,后来 5.7 改成了 41 位。如果你用现代客户端连 4.1 服务端,可能会遇到认证失败,因为客户端默认用新算法。解决办法是在客户端加--default-auth=mysql_old_password,或者升级服务端——但升级服务端又受限于 glibc 版本,这是个死循环,后面避坑章节细说。
验证连接时如果报ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock',说明服务端没起来或者 socket 路径不对。先看/usr/local/mysql/data/主机名.err这个错误日志,里面会写具体原因。常见原因是datadir权限不对——mysql用户对data目录没有写权限,mysqld启动到一半就退了。
4. 避坑与排查:老版本 MySQL 在国产 Linux 上的五个翻车现场
4.1 启动报错 "FATAL: kernel too old"
现象:执行mysqld或mysql_install_db时直接输出FATAL: kernel too old,进程退出。
原因:这个二进制包编译时假设内核版本不低于 2.4,但目标系统的内核可能更老,或者虽然内核版本够但 glibc 的ld.so检测到了不兼容的 ABI。另一种可能是目标系统是 64 位,但没装 32 位兼容库,ld.so找不到 32 位的libc.so.6。
解决:先uname -r看内核版本,低于 2.4 的基本没救,只能换机器。如果是 64 位系统缺 32 位库,在 openEuler 或麒麟上执行yum install glibc.i686 libstdc++.i686或dnf install glibc.i686。装完后用ldd /usr/local/mysql/bin/mysqld检查依赖是否全部解析,输出里出现not found就是还缺库。
4.2 中文乱码:建库时没指定字符集
现象:插入中文数据后,用SELECT查出来全是???或者乱码方块。
原因:4.1 的服务端默认字符集是latin1,客户端连接时如果没显式指定--default-character-set=utf8,整个连接链路的字符集都是latin1。中文经过latin1编码再解码,必然丢失。
解决:三个层面都要改。服务端my.cnf里加default-character-set=utf8;建库时写CREATE DATABASE mydb DEFAULT CHARACTER SET utf8;;客户端连接时加--default-character-set=utf8。已经建好的库可以用ALTER DATABASE mydb DEFAULT CHARACTER SET utf8;改默认字符集,但已有表的字符集不会自动变,需要ALTER TABLE ... CONVERT TO CHARACTER SET utf8;逐表转换。转换前务必备份,这个操作不可逆。
4.3 客户端连不上:socket 路径和 TCP 端口的混淆
现象:mysql -u root -p报ERROR 2002,但netstat显示 3306 端口在监听。
原因:MySQL 客户端默认优先走 Unix socket 连接,而不是 TCP。如果my.cnf里socket指定的路径和客户端默认查找的路径不一致,就会连不上。4.1 客户端默认找/tmp/mysql.sock,但有些发行版的my.cnf把 socket 放在/var/lib/mysql/mysql.sock。
解决:要么在客户端连接时显式指定-S /tmp/mysql.sock,要么在my.cnf的[client]段也写上socket = /tmp/mysql.sock,让服务端和客户端用同一个路径。如果走 TCP 连接,加-h 127.0.0.1强制走网络,但 4.1 的root账号默认只允许localhost通过 socket 登录,TCP 登录需要额外授权root@127.0.0.1。
4.4 内存不足导致 mysqld 被 OOM Killer 杀掉
现象:服务运行一段时间后突然断开,ps里找不到mysqld进程,系统日志/var/log/messages里有Out of memory: Kill process mysqld。
原因:老机器内存小,key_buffer、innodb_buffer_pool_size、max_connections加起来超过了物理内存,内核的 OOM Killer 会挑占用最大的进程杀掉。4.1 默认的innodb_buffer_pool_size是 8M,不算大,但max_connections默认 100,每个连接都要分配线程栈和排序缓冲区,累积起来很可观。
解决:把max_connections降到 30 到 50,key_buffer控制在 16M 以内,sort_buffer_size和read_buffer_size显式设成 256K 或 512K。如果业务确实需要更多连接,考虑在前面加个连接池,或者换台内存更大的机器。另外可以给mysqld进程设oom_score_adj为 -1000,降低被杀的优先级,但这只是权宜之计。
4.5 用现代客户端连 4.1 服务端认证失败
现象:用 MySQL 5.7 或 8.0 的客户端连 4.1 服务端,报Client does not support authentication protocol requested by server。
原因:4.1 用的是旧版密码哈希算法(16 位),5.7 之后的客户端默认用新版算法(41 位),两者不兼容。服务端说“我只会旧算法”,客户端说“我只会新算法”,握手就失败了。
解决:在客户端连接参数里加--default-auth=mysql_old_password,让客户端降级用旧算法。如果客户端版本太新已经移除了旧算法支持(MySQL 8.0 客户端就移除了),那就只能用 4.1 自带的mysql客户端,或者装一个 5.6 版本的客户端作为桥梁。这也是为什么我不建议在同一个环境里混用不同大版本的 MySQL 客户端和服务端——认证协议、字符集、SQL 语法都可能对不上。
5. 让这套老环境多撑几年:备份策略、字符集统一和迁移判断
5.1 用 mysqldump 做逻辑备份的固定套路
4.1 自带的mysqldump功能有限,但做基础逻辑备份够用。我一般写个脚本,每天凌晨跑一次,保留最近 7 天。
#!/bin/bash # 备份脚本:每天全量导出,按日期命名 BACKUP_DIR=/backup/mysql DATE=$(date +%Y%m%d) MYSQL_BIN=/usr/local/mysql/bin mkdir -p $BACKUP_DIR # --opt 启用快速导出,--single-transaction 对 InnoDB 表做一致性快照 $MYSQL_BIN/mysqldump -u root -p'你的密码' \ --opt --single-transaction --default-character-set=utf8 \ --all-databases > $BACKUP_DIR/all_$DATE.sql # 删除 7 天前的备份 find $BACKUP_DIR -name "all_*.sql" -mtime +7 -delete--opt是个组合参数,等价于开启--quick、--add-drop-table、--extended-insert等,能显著加快导出速度。--single-transaction只对 InnoDB 有效,它通过启动一个事务来保证导出期间数据一致,不会锁表。但 4.1 里很多表还是 MyISAM,MyISAM 不支持事务,导出时还是会加读锁。如果业务对锁敏感,只能在低峰期跑备份。
恢复时用mysql -u root -p < all_20250101.sql。注意 4.1 的mysqldump导出的 SQL 里可能包含/*!40101 SET ... */这种版本注释,现代 MySQL 能识别并忽略,但反过来现代mysqldump导出的文件拿到 4.1 上恢复,可能因为语法太新而报错。跨版本迁移时,导出方和导入方的版本差距最好不超过两个大版本。
5.2 字符集统一:从建库到连接的全链路检查
字符集问题在老系统里是玄学,同一个库,用不同客户端连,查出来的中文可能一个正常一个乱码。根因是字符集在服务端、库、表、列、连接五个层面各有一套设置,任何一层不一致都会出问题。
排查时按这个顺序查:
| 检查项 | 命令 | 期望值 |
|---|---|---|
| 服务端默认字符集 | SHOW VARIABLES LIKE 'character_set_server'; | utf8 |
| 客户端连接字符集 | SHOW VARIABLES LIKE 'character_set_client'; | utf8 |
| 连接结果字符集 | SHOW VARIABLES LIKE 'character_set_results'; | utf8 |
| 数据库字符集 | SHOW CREATE DATABASE mydb; | DEFAULT CHARSET=utf8 |
| 表字符集 | SHOW CREATE TABLE mytable; | DEFAULT CHARSET=utf8 |
如果character_set_client是latin1,说明客户端连接时没指定字符集。在my.cnf的[client]段加default-character-set=utf8能解决大部分情况。已经存进去的乱码数据没法自动修复,只能重新导入正确编码的数据。
5.3 什么时候该放弃 4.1 换新版本
4.1 是 2004 年的版本,距今超过 20 年。它没有存储过程、没有触发器、没有视图、没有information_schema(只有SHOW命令)、没有utf8mb4(存不了 emoji)、没有InnoDB的行锁优化。如果你的业务开始需要这些特性,或者数据量超过 10GB 导致 MyISAM 表锁成为瓶颈,就该考虑迁移了。
迁移的难点不在数据本身,而在 glibc 依赖链。新版本 MySQL 需要 glibc 2.17 以上,而老机器可能跑着 glibc 2.3 的系统。升级 glibc 是高风险操作,搞不好整个系统都起不来。我的建议是:如果机器还能换,直接换一台跑现代 Linux 的新机器,用mysqldump把数据导过去;如果机器不能换(比如工控设备绑定硬件),那就维持 4.1,但把数据量控制在单表 500 万行以内,定期做OPTIMIZE TABLE减少碎片。
我自己的习惯是:接手任何老 MySQL 环境,第一件事是mysqldump全量备份,第二件事是记录SHOW VARIABLES的所有输出,第三件事是在测试环境复现一遍启动流程。这三件事做完,后面无论出什么幺蛾子,都有后悔药可吃。希望帮到你。
本文还有配套的精品资源,点击获取