MySQL 4.1.11源码包编译安装与数据迁移指南
发布时间:2026/9/26 22:22:20 锦皓数字建站

简介MySQL 4.1.11 是面向 Linux/Unix 环境的开源关系型数据库管理系统完整源码包适合需要追溯学习早期数据库底层实现、研究 MySQL 历史版本架构或在特殊业务环境中恢复旧版数据库的运维与研发人员。包内共 4541 个文件压缩后约 21.82MB以 C/C 源码为主涵盖 829 个 .c、351 个 .cpp、441 个 .h 与 363 个 .hpp 头文件同时包含 326 个 .test 测试集、236 个 .tcl 脚本、191 个 .cc 编译单元以及 .am/.ac/.in/.sh 等 autoconf 构建配置脚本可帮助读者从源码层面理解 MySQL 存储引擎、客户端工具与 binlog 日志系统的设计脉络。资源中还保留了大量编译辅助文件、测试用例和文档通过目录可快速定位核心模块对研究数据库内核或维护遗留系统均有参考价值。目前已有 196 人浏览学习该资源。1. mysql-4.1.11.tar.gz 是什么一个二十年前的源码包为什么今天还会出现mysql-4.1.11.tar.gz 这个名字要是放在今天的生产环境第一眼会让人觉得走错了片场。它大约是 2005 年前后的 MySQL 官方源码包MySQL 4.1 系列在历史上第一次把 UTF-8、预处理语句和子查询带进了主流版本而 4.1.11 又是这个系列里修问题修得比较勤的版本之一。现在还会拿到这个包的人多半不是在选型而是在接手一台老机器的恢复任务文档只写着“数据库是 MySQL 4.1”磁盘上只剩这一个 tar.gz而应用层早就没人记得当年是怎么编译的了。这个包能解决的实际问题很具体在今天的 Linux 发行版上把它重新编译起来让老的业务代码能继续连库或者把库里的数据完整导出到新版本。它和现在的 MySQL 8.0 安装流程完全不同既不支持 cmake也没有 docker 镜像替你处理依赖。你需要面对的是 autotools 时代的一整套构建逻辑以及新编译器和老 C 代码之间的各种摩擦。整篇笔记按“识别归档 → 准备依赖 → configure → 初始化 → 排障 → 迁移”的顺序展开。如果你手里正好躺着这个包下面的命令直接照着改路径就能用如果你只是好奇老版 MySQL 怎么在 Linux 上落地也能从这里看到源码包时代的完整套路。2. 先从归档里认出它mysql-4.1.11.tar.gz 的校验、解压与依赖清单2.1 拿到包先别急着解压这个文件名看起来明确但 MySQL 官方在 4.1 时代同时发布过源码包和二进制包二进制包通常叫 mysql-4.1.11-linux-i686.tar.gz 或者 mysql-4.1.11-solaris10-sparc.tar.gz 之类文件名里会带操作系统平台。单纯叫 mysql-4.1.11.tar.gz 的基本可以认定是源码包但也存在“打包者把 CVS 工作目录直接打成 tar.gz”的情况目录里没有现成的 configure 脚本。所以第一步不是 tar -xzf而是先看清楚这个包内部长什么样。# 先判断压缩格式避免解压后才发现拿错文件 file mysql-4.1.11.tar.gz # 与官方渠道给出的 MD5 / SHA1 校验值比对 md5sum mysql-4.1.11.tar.gz sha1sum mysql-4.1.11.tar.gz # 只列归档内容不解压。看顶层目录是不是源码树 tar -tzf mysql-4.1.11.tar.gz | head -30file 命令会告诉你这是不是 gzip 压缩的数据某些从 Windows 网盘拷下来的文件可能被二次打包成 .tar.gz.tar.gz这一步能提前发现。md5sum 和 sha1sum 是核对文件完整性用的老版本源码包通常会在发布说明里给出 MD5比对不一致就不要继续用了解压一个损坏的压缩包后面编译会翻车翻到没法查。tar -tzf 只列出归档内部的文件名不会真正解压看前 30 行足够判断结构。如果顶层目录名是 mysql-4.1.11里面有 configure、README、INSTALL-SOURCE、Makefile.am 这些文件那就是标准源码树。如果顶层直接是 bin、lib、share说明这其实是二进制发行包那就不需要编译直接看后面的初始化章节把路径替换成解压出来的目录即可。2.2 校验通过后的解压步骤确认无误后解压这个操作没有太多技术含量但有一个细节值得注意解压出来的文件属主是当前用户如果后面要让 mysql 系统用户运行编译产物最好先把整个源码目录的属主切换好。# 解压到当前目录建议放在 /opt/src 这类专门目录下 tar -xzf mysql-4.1.11.tar.gz cd mysql-4.1.11 # 确认关键文件都在 ls -la | head -40 file configure ls scripts bin 2/dev/nullfile configure 这一句很关键。正常发行包里的 configure 是一个 shell 脚本file 会输出 POSIX shell script text executable。如果 file 提示 configure 是 M4 macro 或者干脆不存在说明这个包是直接从 CVS 导出的快照后面需要 autoreconf 生成构建脚本这个坑放在第 5 章细说。解压目录空间也要留够源码包本身不到十几 MB但编译中间文件和安装后的完整目录会占几百 MB/opt 或 /usr/local 分区至少留 1GB 比较稳。老服务器上经常遇到 /usr 分区只有几百 MB 的情况编译一半才发现磁盘满make clean 都未必能完全恢复空间。2.3 依赖清单给老 autotools 项目备齐工具MySQL 4.1.11 的构建系统是 autoconf automake libtool它跟现在用 cmake 的 MySQL 5.7 之后版本完全是两套逻辑。你在 CentOS 7 上装过 mysql-community-server RPM 的经验在这里基本用不上这里需要的是传统 Linux 编译工具链。Debian / Ubuntu 系sudo apt-get update sudo apt-get install -y build-essential libncurses-dev zlib1g-dev bisonRHEL / Rocky / AlmaLinux 系sudo dnf groupinstall Development Tools sudo dnf install -y ncurses-devel zlib-devel bison gcc-c依赖里最容易被忽略的是 libncurses。MySQL 的老版本终端工具需要 ncurses 库configure 会检测 /usr/include/ncurses.h找不到就直接报 No curses/termcap library found整个配置过程中止。zlib 用于压缩相关功能bison 用于解析器生成。注意这个版本的源码不强制要求 openssl 开发头文件如果你不需要 SSL 连接可以在 configure 时不加 --with-ssl避开新版 OpenSSL API 不兼容的问题。gcc 版本方面不需要刻意安装老版本现代发行版默认的 gcc 11、12 都能编译只是要给 CXXFLAGS 加一个兼容参数第 3 章会详细说明。唯一不建议做的是拿 clang 去编译老代码对 GCC 专属扩展的依赖比较重clang 会误判很多属性反而难排。3. configure 阶段最容易翻车mysql-4.1.11 编译前的几个必调参数3.1 为什么老版本用 configure 而不是 cmakeMySQL 源码包从 5.7 开始全面转向 cmakeconfigure 脚本从此消失。而在 4.1.11 的年代configure 是唯一入口它负责检测当前系统的编译器、头文件、库函数、线程模型、socket 支持等内容然后生成 Makefile 和 config.h。跳过 configure 直接 make 是行不通的因为根目录下根本没有 Makefilemake 只会提示找不到目标。configure 生成的 config.h 里记录了大量编译期选项例如是否支持 pthread、是否有 getpwuid、用哪个字符集作为默认。这些内容在今天的 Linux 上有很大一部分仍然适用但也会踩到老检测逻辑的坑。所以 configure 这一步值得多花时间看输出不要一路管道到 /dev/null。3.2 一组能少踩坑的 configure 参数我一般这样跑 configure# 提升 C 兼容性解决老代码在新编译器下的报错 export CXXFLAGS-fpermissive -Wno-deprecated ./configure \ --prefix/usr/local/mysql-4.1.11 \ --with-mysqld-usermysql \ --with-unix-socket-path/tmp/mysql.sock \ --with-extra-charsetsall \ --with-charsetlatin1 \ --enable-thread-safe-client \ --without-debug参数含义如下表实际使用时可删减但前三个建议保留。参数作用备注--prefix安装根目录建议带版本号后续多版本共存方便--with-mysqld-usermysqld 以哪个系统用户运行需要预先创建 mysql 用户--with-unix-socket-path本地连接的 socket 路径指定为 /tmp/mysql.sock避免权限问题--with-extra-charsets额外支持的字符集选 all 最稳代价是编译时间增加--with-charset默认字符集老库多为 latin1选 latin1 更贴近原环境--enable-thread-safe-client客户端库线程安全多线程应用连库时必备--without-debug去掉调试代码减小体积提高运行效率CXXFLAGS 里的 -fpermissive 是专门用来对付老代码的。MySQL 4.1.11 的 C 代码用了大量旧的 register 关键字新版本 GCC 从 C17 开始把它移除编译时直接报错。加上 -fpermissive 后gcc 会把这类错误降级为警告编译能继续。-Wno-deprecated 避免一堆废弃声明的警告刷屏。3.3 两个必查的 configure 中止信号configure 失败时第一件事是看 config.log 的末尾。这个文件记录了所有检测项的详细输出最后的 error 提示往往比终端上的红色字更准确。常见的第一个中止是 configure: error: No curses/termcap library found。这是缺 ncurses 开发包回到第 2 章装上 libncurses-dev 或 ncurses-devel 后重新 configure。偶尔装好包还报错说明系统可能只提供了 ncursesw可以检查 /usr/include/ncurses.h 是否存在没有就再装 libncursesw5-dev。常见的第二个中止是 configure: error: C compiler cannot create executables。这种情况先确认 g 是否安装Debian 系只装 build-essential 一般没这问题但精简容器镜像可能漏了 g。如果 g 存在再用下面命令确认基础编译流程echo int main(){return 0;} | g -x c - -o /tmp/test_gpp /tmp/test_gpp这条命令能帮你快速区分是编译器坏了还是 configure 脚本本身检测出错。如果最简单的一段代码都编译不过先修工具链如果编译过了那问题在 configure 的某个检测项上去 config.log 里搜 last error 附近的内容通常能看到具体缺哪个头文件。3.4 编译与安装的节奏configure 通过后直接跑 make。老项目的 Makefile 依赖关系不如现代 CMake 严谨建议先单线程编译make make installmake 不加 -j 参数是求稳的做法。4.1.11 在并行编译时可能因为头文件依赖没生成完整而报 undefined reference这类错误不一定是代码坏了make clean 后单线程重跑通常能过。如果机器性能差单线程编译可能要十几分钟耐心等。安装完成后检查一下 bin 目录ls -l /usr/local/mysql-4.1.11/bin应该能看到 mysql、mysqld、mysqld_safe、mysqladmin、mysqldump、mysql_install_db 这几个主要工具。mysql_install_db 在第 4 章初始化时会用到确认它存在避免后面手忙脚乱。4. 初始化数据库并启动把 mysql-4.1.11 变成一个能连的实例4.1 为什么必须跑 mysql_install_dbMySQL 5.7 之后初始化用 mysqld --initialize而 4.1.11 的时代用的是 mysql_install_db 脚本。它的作用是在数据目录里创建 mysql 系统库和授权表也就是 mysql.user、mysql.db 这些表。不跑这一步直接启动 mysqld会在错误日志里看到一个经典报错Cant open and lock privilege tables然后进程退出。电源数据的保存目录如果已经存在千万不要再次执行 mysql_install_db它不会智能跳过已有数据重复执行会把原来的授权表覆盖掉。老库恢复时正确做法是直接使用原 datadir 启动只有全新搭建实例才需要初始化。4.2 建用户、建目录、授权mysqld 不推荐以 root 身份运行configure 时已经指定了 --with-mysqld-usermysql所以系统里需要有一个 mysql 用户。# 创建系统用户如果已存在会提示冲突加 || true 不中断脚本 sudo useradd -r -s /bin/false mysql || true # 数据目录独立出来不建议放在安装目录下 sudo mkdir -p /var/lib/mysql-4.1.11 sudo chown mysql:mysql /var/lib/mysql-4.1.11 sudo chmod 700 /var/lib/mysql-4.1.11数据目录放在安装目录之外是个好习惯以后升级或重编译时不会误删数据。chmod 700 是 MySQL 数据目录的惯例防止其他系统用户直接读文件。很多新手在这里只 mkdir 没 chown导致后面 mysqld 启动时无法写入文件错误日志里反复出现 Permission denied。4.3 初始化的两个前置检查执行 mysql_install_db 之前先确认两件事3306 端口没被占用/etc/hosts 里有没有本机主机名。# 检查端口占用避免启动时 Address already in use ss -lntp | grep 3306 || echo port 3306 free # 检查 hosts 映射MySQL 初始化要做主机名反解 cat /etc/hosts | grep $(hostname) || echo no hostname mappingMySQL 4.1 在初始化时会对当前主机名做反向解析如果 /etc/hosts 里没有本机记录会报 Neither host xxx nor localhost could be looked up with resolveip。解决办法是把本机名加进 hostsecho 127.0.0.1 $(hostname) localhost | sudo tee -a /etc/hosts注意先检查是否已有类似行重复添加反而可能引起新的解析混乱。4.4 执行初始化并启动cd /usr/local/mysql-4.1.11 # 建立 mysql 库和授权表 sudo ./bin/mysql_install_db \ --basedir/usr/local/mysql-4.1.11 \ --datadir/var/lib/mysql-4.1.11 \ --usermysql这段脚本会在数据目录生成 mysql 子目录和一系列 .frm 表结构文件。输出末尾出现 “To start mysqld at boot time you have to copy support-files/mysql.server” 之类的提示是正常的它是在提示你把启动脚本放到系统服务目录。接下来用一个最简单的 my.cnf 把参数固定下来[mysqld] basedir/usr/local/mysql-4.1.11 datadir/var/lib/mysql-4.1.11 socket/tmp/mysql.sock port3306 usermysql然后启动sudo nohup /usr/local/mysql-4.1.11/bin/mysqld_safe \ --defaults-file/etc/my.cnf \ --usermysql \ /tmp/mysqld_safe.log 21 mysqld_safe 是一个守护外壳mysqld 异常退出时它会尝试拉起同时把日志写到数据目录的 .err 文件。启动后不要立刻连库等两三秒再验证# 检查 socket 文件是否已生成 ls -l /tmp/mysql.sock # 用 mysqladmin 做连通性测试 /usr/local/mysql-4.1.11/bin/mysqladmin \ --socket/tmp/mysql.sock \ -u root ping新初始化的实例 root 默认没有密码mysqladmin ping 返回 mysqld is alive 就说明服务正常。注意 MySQL 官方从 5.7 开始默认生成随机 root 密码但在 4.1.11 上不会这反而是老版本踩坑点之一。5. 避坑我见过 mysql-4.1.11 把新手卡死的是这些地方5.1 error 2002 (HY000)socket 连不上的三种起因客户端报这个错大概率不是 MySQL 本身坏了而是连接时用的 socket 路径和服务端不一致。最常见的三种情况现象mysql -u root 报 ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock。原因一mysqld 根本没起来。ps aux | grep mysqld 看不到进程。原因二mysqld 起来了但 socket 路径不是 /tmp/mysql.sock。比如 my.cnf 里写成了 /var/lib/mysql/mysql.sock客户端默认找 /tmp。原因三socket 文件存在但当前用户没有访问权限。/tmp 下的 socket 权限通常是 777 或 755但如果被限制成 700普通用户连不上。排查顺序很固定先看进程再看文件最后做一次显式 socket 连接ps aux | grep mysqld ls -l /tmp/mysql.sock # 显式指定 socket 连接排除默认路径差异 /usr/local/mysql-4.1.11/bin/mysql \ -u root --socket/tmp/mysql.sock如果显式指定 socket 能连上说明是默认路径不一致把客户端命令都加上 --socket 参数或者统一 my.cnf 里的 socket 配置。如果文件不存在问题回到原因一去数据目录下的 .err 日志看 mysqld 为什么没起来。5.2 进程反复“起来了又退掉”日志指向权限表现象ps 能看到 mysqld 短暂出现但 mysqladmin ping 永远失败数据目录的 .err 文件里反复出现 Cant open and lock privilege tables。原因数据目录属主不是 mysql或者 mysql_install_db 初始化的 datadir 与启动时 --datadir 指定的不是同一个目录。我见过有人初始化时用 /var/lib/mysql-4.1.11启动时却在 /etc/my.cnf 里写成 /var/lib/mysql结果 mysqld 找不到 mysql 库。解决先用 ls -ld 确认两个路径一致且属主正确再以前台模式启动 mysqld 看实时输出sudo -u mysql /usr/local/mysql-4.1.11/bin/mysqld \ --datadir/var/lib/mysql-4.1.11 \ --usermysql \ --console前台启动能直接看到 Fatal error 的第一行内容比翻日志更直观。确认原因后把 my.cnf 改对重新跑 mysql_install_db 只针对全新环境不要在已有数据上重复执行。5.3 Client does not support authentication protocol老协议和新 hash 的恩怨现象版本较老的客户端程序连接 4.1.11 时报错 Client does not support authentication protocol requested by server反过来老版本 MySQL 客户端连新实例也会报类似内容。原因MySQL 4.1 把密码 hash 从 16 字节升级成了 41 字节的 SHA 加密格式4.0 及更早版本的客户端不认识新格式。4.1.11 为了兼容留了一个 OLD_PASSWORD() 函数但默认情况下老客户端依然无法认证。解决如果必须让老客户端连上来在服务端把该账号的密码改成老 hash 格式SET PASSWORD FOR userhost OLD_PASSWORD(your_password);或者全局开启[mysqld] old_passwords1然后重新设置账号密码。重启后新协议客户端反而可能连不上所以这只是一个短期过渡手段。实际迁移时更推荐先把账号密码改成普通格式集中精力把数据导出。MySQL 8.0 已经彻底移除 OLD_PASSWORD 函数这条知识只对 4.x 到 5.0 之间的过渡环境有效。5.4 解压后没有 configureCVS 快照包的救法现象tar -xzf 后目录里只有 configure.in、Makefile.am、aclocal.m4没有 configure 文件直接 ./configure 报 No such file or directory。原因这个 tar.gz 不是发布版源码包而是直接从 CVS 仓库导出后打包的没执行过 autoconf 生成 configure。解决安装 autoconf、automake、libtool 后执行 autoreconfsudo apt-get install -y autoconf automake libtool autoreconf -ivf-autoreconf -ivf 会依次调用 aclocal、autoconf、automake生成完整的 configure 脚本。执行过程如果报缺少某个宏检查 libtool 是否安装。这个步骤跑完之后再回到第 3 章的 configure 命令继续。顺便说一句CVS 快照包里残留的 .cvsignore 文件可以忽略不影响编译。5.5 make -j 并行编译的玄学undefined reference 与 make clean现象make -j8 编译到中途报 undefined reference或者崩溃在某个 .depend 文件缺失但单独 make 又能过。原因老版 MySQL 的 Makefile 里头文件和目标文件的依赖关系写得比现代项目粗糙并行编译时可能出现目标文件在头文件生成之前就被编译导致链接阶段符号缺失。这不是环境坏了是并行度太高触发了构建顺序问题。解决先 make clean 清掉半成品然后单线程 make。两次编译之间如果只改少数文件可以用 make -j2 试探超过 4 的并行度在 4.1.11 上基本都会出问题。编译完成后如果 binary 已经生成可以考虑 make install 不变的部分但保险起见还是 clean 后完整重来。这一步没有太多优雅手段老项目就得顺着它的脾气来。6. 迁移验证技巧把 mysql-4.1.11 的数据安全送进 MySQL 8.06.1 先想清楚老库不是拿来长期跑的在今天的 Linux 上装好 mysql-4.1.11核心价值不是让它重新支撑业务而是作为数据出口。老版本早已停止维护4.1.11 的 InnoDB 和 MyISAM 引擎都缺少后来累积的大量修复长期运行风险太大。正确的收尾动作是把业务库完整迁到 MySQL 8.0 或 MariaDB这台老实例只负责“把数据吐出来”。6.2 导出时两个参数一定不能错mysqldump 最好用老实例自带的版本因为它对老表结构的兼容性最好。导出时默认字符集大概率是 latin1如果数据库里存的确实是 latin1 编码导出命令带上 --default-character-setlatin1 可以避免转成 UTF-8 时出现乱码。/usr/local/mysql-4.1.11/bin/mysqldump \ --socket/tmp/mysql.sock \ -u root \ --passwordyour_password \ --default-character-setlatin1 \ --single-transaction \ dbname dbname.sql--single-transaction 只对 InnoDB 表有意义能在不锁表的情况下拿到一致性快照如果业务表是 MyISAM这个参数不生效要换成 --lock-tables代价是会短暂锁写。老版本的 mysqldump 对 view、trigger、routine 的支持比新版弱导出后务必查看 dump 文件里有没有包含 CREATE VIEW没有的话要单独处理。6.3 导入到新实例后的最小验证清单# 新建业务库字符集明确指定为 utf8mb4 mysql -u root -p -e CREATE DATABASE dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 导入 mysql -u root -p dbname dbname.sql导入成功后先不要急着切流量用三个查询做验证SELECT COUNT(*) FROM dbname.tablename; SHOW CREATE TABLE dbname.tablename; SHOW WARNINGS;数量和表结构只能说明导入没丢大件外键和自增值要再抽查几条业务 SQL。如果原库存在不规范的时间字段比如字符串日期MySQL 8.0 的严格模式可能会拒绝写入此时用 SET SESSION sql_mode 只适合临时排查长期运行还是要修数据。我现在的习惯是拿到这类老包后先做三件事把 datadir 整体打包备份、检查是否还有第二份原始文件、再做一次只读导出。每次迁移都留好后路确认新库数据可用之前老实例不关机、不删目录。这套流程帮我避过好几次“导出成功但导入乱码”的尴尬也让我越来越信任那些看似古老的文件名背后其实还有完整的恢复路径。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。