简介:mysql-4.1.11.tar.gz 是 MySQL 4.1.11 版本的源码压缩包,面向需要在 Linux/Unix 环境下编译安装旧版数据库的开发者与运维人员,尤其适合维护遗留系统、复现历史环境或研究早期 MySQL 架构的技术人员。包内共 4541 个文件,以 C 源码(829 个)与头文件(441 个)为核心,辅以大量 hpp、cpp、cc 等 C++ 源文件,以及 result、test、tcl 测试用例和 java、sh、am 等构建与脚本文件,另有 readme、changelog 等说明文档,压缩包约 21.82MB,完整保留了源码目录结构与编译体系。已有 197 人学习下载。读者可据此完成从解压、configure、make 到初始化数据目录与启动服务的完整编译流程,并借助测试用例与配置脚本理解 4.1 分支的组件构成与参数设置,为旧版本迁移、兼容性验证和源码级排错提供一手材料。
1. 从一台老工控机说起:mysql-4.1.11.tar.gz 为什么还有人装
上周帮某实验室把一台跑数据采集的老工控机重新拉起来,系统是 CentOS 5 时代的底子,业务侧一个老采集程序只认 MySQL 4.1 的协议握手包,换 5.x 直接连不上。翻出mysql-4.1.11.tar.gz这个源码包,才发现网上能照着走完的安装笔记几乎绝迹,剩下的全是「解压、configure、make、make install」四步走,真跑起来全是坑。这篇就按我实际装一遍的顺序记下来:环境怎么备、源码怎么编、参数怎么给、装完怎么验证、翻车了怎么救。适合手里攥着老系统、老业务、又不想动数据库协议层的开发者,新手照着能走通,熟手能直接看版本差异和参数取舍。
2. 装前把环境列清:mysql-4.1.11 的编译依赖与版本取舍
2.1 为什么是源码包而不是二进制包
MySQL 4.1 时代的官方二进制包大多按特定 glibc 和 libstdc++ 编译,放到今天的机器上经常报GLIBC_2.3 not found这类符号缺失。源码包的好处是能在目标机上按本地库重新链接,坏处是把编译链的坑全暴露给你。我一般优先源码编译,尤其是目标机是老发行版、库版本对不上的时候。这里要明确一点:4.1.11 是 2005 年前后的版本,它的构建系统还是老式configure,不是 CMake,所以后面所有参数都走./configure那一套,别拿 5.7 之后的cmake -D...经验往上套,会直接卡在第一步。
2.2 依赖清单与版本对照
装之前先把编译依赖补齐,缺一个后面就多一次make重来。下面这张表是我在这类老版本上实际会核对的项,版本区间是「能编过」的经验范围,不是官方声明:
| 依赖 | 作用 | 经验版本 | 缺失时的典型报错 |
|---|---|---|---|
| gcc / g++ | C/C++ 编译器 | 3.4 ~ 4.1 | configure: error: no acceptable C compiler found |
| make | 构建驱动 | 3.80 以上 | make: command not found |
| ncurses-devel | 提供mysql命令行客户端 | 5.x | checking for termcap functions... no |
| zlib-devel | 压缩协议支持 | 1.2.x | cannot find -lz |
| openssl-devel | SSL 连接(可选) | 0.9.7 系 | --with-vio相关链接失败 |
| bison | 部分语法生成 | 1.875 以上 | yacc: not found |
提示:老版本对高版本 GCC 不友好,GCC 4.4 以上编译 4.1.11 常出现
dtoa.c相关报错,能降就降到 4.1 附近,降不了就在编译参数里加兼容开关,后面 2.4 会讲。
2.3 用户、目录与内核参数的准备
MySQL 不建议用 root 跑,先建独立账号和目录。数据目录我习惯放/usr/local/mysql/data,和安装前缀保持一致,迁移时整目录打包就行:
# 建 mysql 用户组与账号,禁止登录 shell groupadd mysql useradd -g mysql -s /sbin/nologin mysql # 安装前缀与数据目录 mkdir -p /usr/local/mysql mkdir -p /usr/local/mysql/data chown -R mysql:mysql /usr/local/mysql这段的作用是把运行身份和文件归属先定死。-s /sbin/nologin是防止这个账号被拿来登录系统,属于最小权限习惯。目录权限必须给到 mysql 用户,否则后面mysql_install_db初始化时会报Can't create/write to file,这个错很多人第一次装都会撞上。
内核参数方面,4.1 时代默认的打开文件数往往不够,尤其做采集写入频繁的场景。临时调一下当前会话的限制就够验证用:
# 查看当前限制 ulimit -n # 临时提到 4096,仅当前 shell 生效 ulimit -n 4096ulimit -n是单进程可打开文件描述符上限,MySQL 每个连接、每个表文件都占 fd,老机器默认 1024 在高并发下会报Too many open files。要持久化就写进/etc/security/limits.conf,但老系统改完要重新登录才生效,验证阶段先用临时值省事。
2.4 编译参数的取舍:三个真正影响运行的开关
./configure的参数很多,但 4.1.11 上真正影响后续运行的就那么几个。我一般这么给:
./configure \ --prefix=/usr/local/mysql \ --localstatedir=/usr/local/mysql/data \ --with-charset=utf8 \ --with-extra-charsets=all \ --with-named-curses-libs=/usr/lib/libncurses.so \ --without-debug \ --enable-thread-safe-client逐项说清楚:--prefix决定安装根目录,后面所有路径都基于它;--localstatedir指定数据目录,和前面建的目录对齐,避免默认落到/var/lib/mysql造成两处数据;--with-charset=utf8把默认字符集定成 utf8,老业务里中文乱码十有八九是这里没定;--with-extra-charsets=all把其他字符集一起编进去,省得后面ALTER TABLE转字符集时缺集报错;--with-named-curses-libs是给 ncurses 路径兜底,老系统上探测经常找错库;--without-debug去掉调试符号,产物小、运行也稳一点;--enable-thread-safe-client让客户端库线程安全,业务侧多线程连库时不会出玄学崩溃。
如果 GCC 版本偏高导致dtoa.c报错,常见做法是在CFLAGS里加-fno-strict-aliasing再 configure,这个开关能绕开老代码对新优化规则的假设问题,属于血泪经验里最省事的一招。
3. 编译安装全流程:从 configure 到 mysql_install_db
3.1 解压与目录约定
源码包解压后目录名带版本号,我习惯在/usr/local/src下操作,编完再决定留不留:
tar -zxvf mysql-4.1.11.tar.gz -C /usr/local/src cd /usr/local/src/mysql-4.1.11-C指定解压目标,避免在当前目录炸出一堆文件。进目录后先ls看一眼有没有configure,4.1.11 是自带预生成脚本的,不需要先跑autoconf,这点和某些更老的开发快照不同。
3.2 configure 与 make 的执行顺序
按 2.4 的参数跑完 configure,输出末尾会打印一份配置摘要,重点看charset、localstatedir、curses三项是否和预期一致,不一致就回去改参数重跑,别急着 make。确认后:
# 并行编译,核数按机器来,老机器 2 就够 make -j2 # 安装到 prefix 指定目录 make install-j2是并行任务数,老工控机内存小,开太高容易 OOM 把编译进程杀掉,表现为make: *** [xxx.o] Killed,看到这个就把-j降下来。make install只往/usr/local/mysql写,不动系统目录,卸载时删这个目录基本就干净了。
3.3 初始化数据目录与配置文件
安装完先初始化系统库。4.1 用的是mysql_install_db,不是 5.7 之后的mysqld --initialize,命令别搞混:
cd /usr/local/mysql ./bin/mysql_install_db \ --user=mysql \ --basedir=/usr/local/mysql \ --datadir=/usr/local/mysql/data--user指定运行身份,--basedir和--datadir显式给全,避免脚本靠推断找错路径。执行成功会看到Installing MySQL system tables...和Filling help tables...两段输出,最后提示OK。如果卡在Installing MySQL system tables后报错,九成是数据目录权限或残留文件问题,清空 data 目录重来。
配置文件我放在/etc/my.cnf,最小可用版本如下:
[mysqld] basedir=/usr/local/mysql datadir=/usr/local/mysql/data port=3306 socket=/tmp/mysql.sock user=mysql default-character-set=utf8 max_connections=200 key_buffer_size=64Mbasedir/datadir和初始化时保持一致;socket放/tmp是老系统惯例,客户端默认也找这里;default-character-set在 4.1 里是服务端参数名,到 5.x 才改成character-set-server,这是版本差异里最容易抄错的一处;key_buffer_size是 MyISAM 索引缓存,4.1 默认引擎还是 MyISAM,这个值给太小查询会明显变慢。
3.4 启动、停止与开机自启
启动用mysqld_safe包一层,它会在 mysqld 异常退出时拉起并记日志:
/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &--defaults-file必须放第一个参数位置,放后面会被忽略,这是老版本参数解析的固定行为。停止用mysqladmin:
/usr/local/mysql/bin/mysqladmin -u root -p shutdown刚初始化完 root 是空密码,第一次-p直接回车即可,进去后立刻改密码。开机自启在 SysV 系统上把启动脚本拷到/etc/init.d/再chkconfig挂上,脚本模板在源码目录support-files/mysql.server,拷过去改一下basedir/datadir两个变量就能用。
4. 避坑与排查:mysql-4.1.11 安装最常见的五处翻车
4.1 现象:configure 报 termcap 找不到
原因:ncurses 开发包没装,或者装了但库路径不在默认搜索范围。解决:先确认ncurses-devel已装,仍报错就在 configure 里显式加--with-named-curses-libs=/usr/lib/libncurses.so,路径按ldconfig -p | grep ncurses的实际结果填。
4.2 现象:make 阶段 dtoa.c 编译失败
原因:高版本 GCC 对老代码的严格别名优化假设不兼容。解决:make clean后带CFLAGS="-fno-strict-aliasing -O2"重新 configure,再 make。这个组合我在多台老系统上验证过,比换编译器省事。
4.3 现象:mysql_install_db 报 Can't create/write to file
原因:data 目录归属不是 mysql 用户,或目录里有上次失败的残留。解决:chown -R mysql:mysql /usr/local/mysql/data,必要时清空 data 目录重跑初始化,别在残留上硬初始化。
4.4 现象:客户端连不上,报 Can't connect to local MySQL server through socket
原因:客户端和服务端 socket 路径不一致,常见于 my.cnf 里改了 socket 但客户端没读到同一份配置。解决:客户端显式带-S /tmp/mysql.sock,或把[client]段也写进 my.cnf 统一路径。用ps aux | grep mysqld看实际启动参数最直接。
4.5 现象:中文写入变问号
原因:默认字符集没定成 utf8,或建库建表时没继承。解决:确认 my.cnf 里default-character-set=utf8生效,建库时显式CREATE DATABASE db DEFAULT CHARSET utf8,已有表用ALTER TABLE ... CONVERT TO CHARACTER SET utf8转。4.1 的字符集参数名和 5.x 不同,抄配置时特别容易在这里翻车。
5. 装完怎么验证跑通:三条命令加一张对照表
装完别急着交付,我固定走三步验证。第一步看进程和端口是否真的起来:
ps aux | grep mysqld | grep -v grep netstat -tlnp | grep 3306第一条确认mysqld_safe和mysqld都在,第二条确认 3306 处于 LISTEN。只有进程没有监听,多半是 my.cnf 里skip-networking被误开或端口被占。
第二步进客户端做一次读写闭环,顺带验证字符集:
-- 登录后先看版本和字符集 SELECT VERSION(); SHOW VARIABLES LIKE 'character_set%'; -- 建库建表写入中文,验证不乱码 CREATE DATABASE verify_db DEFAULT CHARSET utf8; USE verify_db; CREATE TABLE t_check (id INT PRIMARY KEY, note VARCHAR(64)); INSERT INTO t_check VALUES (1, '中文写入验证'); SELECT * FROM t_check;SELECT VERSION()应返回4.1.11,字符集变量里character_set_server和character_set_database都应是utf8。写入后查出来是正常中文,说明从连接层到存储层字符集链路是通的;查出问号就回到 4.5 排查。
第三步做一次重启存活验证,这是最容易被跳过、也最能暴露配置问题的一步:
/usr/local/mysql/bin/mysqladmin -u root -p shutdown /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf & sleep 3 /usr/local/mysql/bin/mysql -u root -p -e "SELECT COUNT(*) FROM verify_db.t_check;"重启后还能查到那条记录,说明数据目录、配置路径、权限三者一致,这套环境才算真跑通。下面这张对照表是我交付前会核对的检查项:
| 检查项 | 期望结果 | 不符时的排查方向 |
|---|---|---|
| 版本号 | 4.1.11 | 装错包或 prefix 指向旧安装 |
| 端口监听 | 3306 LISTEN | my.cnf 端口/skip-networking |
| 字符集 | utf8 | my.cnf 参数名是否写对 |
| 数据目录 | /usr/local/mysql/data | localstatedir 与 my.cnf 是否一致 |
| 重启后数据 | 记录仍在 | 权限、datadir 残留、日志报错 |
从那以后我每次装这类老版本 MySQL,都强制把「重启后查一次数据」当成最后一道关,因为 configure 和 make 全绿不代表运行期配置自洽,只有重启还能读到数据,才说明这套 mysql-4.1.11 是真装住了。希望帮到你。
本文还有配套的精品资源,点击获取