简介:MySQL 4.1.11 源码包以 .tar.gz 形式打包,适合需要在 Linux/Unix 老版本环境中安装、编译或研究早期 MySQL 源码的运维与开发人员。该源码包共包含 4541 个文件,压缩后约 21.82MB;源码类文件以 829 个 C、191 个 C++、441 个头文件为主,另有 configure、Makefile 等构建相关文件,以及大量 tcl/test/result 测试用例,可用于核对功能行为和验证编译结果。已有 196 人学习下载,属于较典型的旧版数据库源码学习素材。通过该包可以了解 MySQL 4.1 时代的目录结构、编译方式和基础模块划分,包括存储引擎、客户端工具、mysqld 服务端以及回归测试组织方式;对排查旧系统兼容性问题、移植到特定平台或理解数据库源码演进都有参考价值。对于新项目不建议直接使用这一版本,但作为历史版本研究、认证实验或老环境维护的辅助材料,仍具实用性。
1. mysql-4.1.11.tar.gz:一个 20 年前的安装包,为什么现在还有人折腾
mysql-4.1.11.tar.gz 这个包,放到今天,比不少读者的工龄还要长。它并不是考古爱好者的猎奇物:我这两年接手过的存量服务器里,就有内网单机报表库、边缘业务库,至今还跑在 4.1.x 上。这类环境最尴尬的是往往拿不到现成的 RPM 包,只能去官网归档区找回 tar.gz 源码包,在一台普通 Linux 上现场编译,再初始化成能用的数据库。这篇文章就按离线安装的完整路径,从解压、configure 到 my.cnf 配置,把 4.1.11 的落地过程、参数取舍和几个经典坑交代清楚。适合需要维护老内网存量库、做版本兼容验证,或者想在实验环境里研究早期 MySQL 实现的读者。
2. 先分清包形态:4.1.11 源码包与二进制包,解压前需要做的三件事
拿到 mysql-4.1.11.tar.gz 之后,我一般不会直接解压,而是先判断它是源码包还是二进制包。两个形态的差别会影响后面所有操作。源码包解压后根目录有 configure、Makefile.in 这类文件,需要完整的编译链;二进制包解压后直接是 bin/mysql、libexec/mysqld,多用于没有编译环境的机器。4.1 时代官网发布过的 tar.gz,绝大多数是源码包,但也有少量针对特定 glibc 预编译的二进制发布,老文档里写的 “linux-i686.tar.gz” 就是后一种。
| 包形态 | 判别方法 | 适合场景 |
|---|---|---|
| 源码包 | 解压后根目录存在 configure、Makefile.in | 内网离线编译、需要定制编译参数 |
| 二进制包 | 根目录存在 bin/mysql、share/mysql,没有 configure | 快速搭实验环境,且操作系统 glibc 与编译环境一致 |
如果你只是要在内网装一个能用的 mysql,我默认推荐源码包:它能让你在 configure 阶段就把字符集、运行用户、socket 路径定死,后期少踩一半的配置坑。二进制包看着省事,可一旦操作系统里的 glibc 和编译环境不匹配,mysqld 启动时直接报 version GLIBC_xxx not found,连修改余地都没有。当然,前提是你机器上有 gcc 和 make;完全离线的生产环境,常见做法是先把编译依赖的 rpm 或 tar.gz 拷进去,这本身就是离线安装 mysql 的标准流程。
2.1 解压前第一件事:校验 md5,不要信随包附带的 Hash
老 tar.gz 在网络传输或 U 盘拷贝过程中损坏的概率比新版本高不少,我遇到过一次:解压不报错,configure 也能走,链接阶段却不断报内部错误。后来查出是源码文件在传输中掉了字节。你现在很难在官网上直接找到 4.1.11 的校验值,但常见做法是:在下载时留意归档页面或随包 README 里给出的 md5,拿到 tar.gz 后顺手算一遍。
校验命令很简单:
md5sum mysql-4.1.11.tar.gz # 输出的 32 位十六进制串要和下载处公布的一致 # 不一致就重新下载,别继续往下走这步的操作成本不到一分钟,却是我栽过跟头之后的保留项目。如果你是从内网 FTP 或离线包仓库拿的文件,也建议做一遍。文件校验通过后,再去看包里的内容。
2.2 用 tar -tzvf 预览归档内容,再决定解压目录
解压前先用列表模式看一眼包内结构,能提前发现很多问题。比如有的包是被二次打包过的,根目录不是想象中的 mysql-4.1.11,而是一堆散文件,直接解压会把你的源码目录弄乱。预览命令:
tar -tzvf mysql-4.1.11.tar.gz | head -30 # -t 只列出内容,不解压;-z 表示 gzip 压缩;-v 显示权限与所有者;-f 指定归档文件重点看前几项:第一层目录是否统一、有没有 configure、有没有 docs 目录和 INSTALL-SOURCE 文件。确认没问题后,再解压到标准源码目录:
tar -xzvf mysql-4.1.11.tar.gz -C /usr/local/src # -x 执行解压;-C 指定目标目录,目标目录要先创建好 cd /usr/local/src/mysql-4.1.11注意 -C 后面的目录如果不存在,tar 版本老的会直接报错,不会帮你建目录,所以先 mkdir -p /usr/local/src。为什么放到 /usr/local/src 而不是 /tmp?因为编译中间文件可能有好几百兆,/tmp 常被定时清理,编译到一半文件没了很麻烦。
2.3 解压之后的文件布局,先认识这几样
进入源码目录后,我建议先看一眼几个关键文件再动手:
ls -l configure INSTALL-SOURCE file configureINSTALL-SOURCE 是 4.1 时代官方随源码包发布的编译说明,里面写了从 configure 到 make install 的完整顺序,还包括它支持的编译器和已知限制。这份文件比你在网上搜到的很多二手中文教程都准确,尤其是参数默认值部分。file configure 能确认脚本格式,如果它是 CRLF 换行或者被改动过,sh ./configure 执行时会报奇怪错误。
老源码的目录结构也很直观:sql 目录放服务端核心代码,client 目录放 mysql、mysqladmin 等客户端程序,mysqld 目录是 daemon 的入口,myisam 和 innodb 是两个存储引擎的实现目录。你不用读代码,但知道这些目录的存在,编译出错时看报错路径就能快速判断是哪一部分的问题,不用对着整屏日志发呆。
2.4 为什么这个老版本不直接用 RPM,而要走源码路径
在 Red Hat 系或 Rocky Linux 上,新用户第一反应是 rpm -qa | grep mysql,然后尝试用包管理直接装。但 4.1.11 太老,多数发行版的源里早就没有它了;RPM 包即使找到,也未必匹配当时的内核和动态库。另一个更现实的原因是,老 MySQL 的默认编译选项不一定符合你的内网要求,比如默认字符集 latin1、默认数据目录写在编译前缀下,这些在 RPM 里几乎改不了。源码包则可以在 configure 时一次定好。这在“linux 安装 mysql”的老教程里是主流做法,放到现在,只要编译依赖齐全,可行性依旧很高。离线环境里最怕的不是编译耗时间,而是装完以后字符集对不上、socket 路径对不上,那才是返工的大头。
还有一种很常见的偷懒做法:直接从同版本的另一台机器上把整个 /usr/local/mysql 目录 tar 过去拷贝。这个办法在 glibc 版本完全一致的内网机器之间是可行的,但如果两台系统小版本差太多,动态库依赖会立刻暴露。我的原则是:目标机器能编译就编译,不能编译才考虑拷贝二进制包,并且拷贝后一定要跑一次 mysqladmin version 验证动态库链接正常。毕竟老版本已经停止维护,出了问题没有官方补丁可打,只能靠环境一致性和配置谨慎来兜底。
3. 编译安装:configure 参数、make 进度与三个必调开关
这一章开始动手。编译老版本最怕的是环境太新,所以我会按“依赖检查 → configure → make → make install”的顺序来。每一步的失败信号不一样,能提前确认的就不拖到后面。
3.1 编译前依赖检查:gcc、make、ncurses 与主机名解析
先确认机器上具备哪些编译基础件,红帽系用 rpm 查,Debian 系用 dpkg:
rpm -q gcc make ncurses-devel autoconf automake # 正常会输出一列带版本号的包名;缺哪个就装哪个 yum install -y gcc make ncurses-devel autoconf automake # 完全离线时,需要把对应 rpm 拷进内网,再 rpm -ivh 安装这里的 ncurses-devel 很容易漏。4.1.11 的 configure 和后续的客户端工具编译都会用到 curses 头文件;缺了它,configure 不一定立刻报错,但 make 到一半会冒出找不到 curses.h 的错误,那时候再回头装就浪费一轮编译时间。autoconf 和 automake 按需,老源码有时会触发 configure 重新生成,装上有备无患。
还有一个经常被忽略的检查是主机名解析。4.1.11 在 configure 时会调用 gethostbyname 之类的能力检测,如果机器 hostname 无法解析,configure 会卡在奇怪的检查项上。我一般先跑:
hostname grep "$(hostname)" /etc/hosts如果没有对应条目,就在 /etc/hosts 里补一行 “127.0.0.1 你的主机名”。这个操作在大多数 Linux 安装 mysql 的教程里都不会写,但老源码对它的依赖比新版本强得多。新版本默认关闭主机名反解,老版本还在积极使用,不补这一行,后面 mysqld 启动时也可能因为解析失败而表现得很奇怪,这是典型的“黑匣子”排错点。
3.2 configure 的三个必调参数:prefix、charset 与运行用户
进入源码目录之后,我一般会先看一眼 configure 的帮助里的默认值,再按下述模板执行。对 4.1.11 来说,有三个参数是必须调的:prefix、charset、mysqld-user,其余按需。完整示例:
cd /usr/local/src/mysql-4.1.11 ./configure \ --prefix=/usr/local/mysql \ --with-mysqld-user=mysql \ --with-charset=utf8 \ --with-extra-charsets=all \ --localstatedir=/usr/local/mysql/data \ --with-unix-socket-path=/tmp/mysql.sock \ --with-client-ldflags=-static逐个说明。--prefix 决定程序安装根目录,老版本默认是 /usr/local 或 /usr/local/mysql 不一定,显式写清楚可以避免后续 PATH 混乱。--with-mysqld-user=mysql 是把 mysqld 默认运行用户设为 mysql,注意这是 configure 时写进源码的默认值,和启动命令里 mysqld_safe --user=mysql 是一个意思但不在同一层。--with-charset=utf8 是我必开的,4.1.11 开始支持 utf8,但默认字符集还是 latin1,如果不在这里改,建库时不显式声明字符集就会出现中文乱码。--with-extra-charsets=all 把所有字符集都编进去,虽然不是最省空间的做法,但对老版本来说,后面对比数据、迁移数据时能少很多麻烦。
--localstatedir 指定数据目录,和后面的 --prefix 组合后,MyISAM 表文件会落在 /usr/local/mysql/data 下。--with-unix-socket-path 指定 socket 文件位置,4.1 默认是 /tmp/mysql.sock,这里写死它,后面 my.cnf 也写它,client 端连起来就不会出现 socket 路径不一致的毛病。最后的 --with-client-ldflags=-static 是我个人的补充:老客户端在系统库较新时容易发生符号冲突,静态链接客户端程序可以减少这类“玄学”运行期问题;不需要的话可以去掉。
如果你想确认某个参数到底存不存在,直接查帮助:
./configure --help | grep with-mysqld-user ./configure --help | grep with-charset老版本 configure 的参数名和现代 MySQL 8 差异不小,不要拿新文档里的 --initialize 或 --default-authentication-plugin 来套,套不上的。
3.3 make 阶段:并行度不要贪多,失败时先看 config.log 尾部
configure 顺利通过后,进入编译。老版本源码对并行编译的支持是有限的,很多人在这一步翻车:
make -j2 # -j2 表示两个编译任务并行;内存 2GB 以下用 -j1 更保险 echo $? # 期望输出 0;非 0 说明编译中断不要因为机器是 16 核就直接 -j16。4.1.11 时代 Makefile 的依赖关系没有现代项目那么严谨,并行度一高,会出现文件还没生成完就被另一个任务拿去编译的竞态问题,报错形式是 “No rule to make target” 或者 c++ 内部错误,非常容易误导排查方向。内存小于 2GB 的虚拟机,我建议老实 -j1,虽然慢,但每一条报错都是真实可追踪的。
make 中断后,常见做法是重定向日志:
make -j1 > /tmp/make_mysql.log 2>&1 tail -30 /tmp/make_mysql.log只盯尾部就够定位问题了。我看到最多的是 undefined reference to 'crypt'、找不到 curses.h、以及 configure 阶段生成的 config.h 与实际环境不匹配。处理顺序是先 make distclean 清掉上次的产物,再检查 config.log 最后二三十行,确认是哪一步检查失败,再决定是装缺失依赖还是加编译环境变量。不要在它报错时盲目重跑 make,那只会把同一个错误再看一遍。
3.4 make install 与安装后的快速自查
编译安装本身不复杂,但装完之后的目录状态直接影响初始化:
make install ls -l /usr/local/mysql/bin/mysqld ls -l /usr/local/mysql/bin/mysql看到两个可执行文件的 mtime 是当前时间,基本就说明安装成功。此时先不要急着初始化,把安装目录的所有权预留给 mysql 用户,这一步很多教程跳过了,直接导致后面 mysql_install_db 报错:
groupadd mysql 2>/dev/null || true useradd -g mysql -s /sbin/nologin mysql 2>/dev/null || true chown -R mysql:mysql /usr/local/mysql这里把整个安装目录交给 mysql 用户,是为了编译好的 mysqld 在运行态能读取数据目录、写错误日志和 pid 文件。mysqld_safe 会以 mysql 用户身份启动 mysqld,如果目录还是 root 所有,后面初始化阶段会立刻报“权限不足”或者启动后秒退。到这里编译安装阶段就收口了。
4. 初始化与启动:mysql_install_db、my.cnf 与 socket 路径的先后顺序
装好二进制之后,老版本不能像 MySQL 8 那样用 mysqld --initialize 直接初始化。4.1.11 有自己的一套初始化脚本,路径和参数都比较老旧,按顺序来做能省掉大半截启动故障。这一章我说清楚从空目录到能连上 mysql 的过程。
4.1 数据目录、运行用户与权限:初始化前必须准备好的三件事
在跑 mysql_install_db 前,先确认 mysql 用户和空数据目录就位:
groupadd mysql useradd -g mysql -s /sbin/nologin mysql mkdir -p /usr/local/mysql/data chown -R mysql:mysql /usr/local/mysql/data chmod 755 /usr/local/mysql/data这段命令里 useradd 用了 -s /sbin/nologin,是因为 mysqld 只需要一个不能登录系统的运行账号,不需要给它 shell。chmod 用 755 而不是 777,老版本 mysqld 对数据目录权限有检查,目录权限过宽会在错误日志里出现警告,虽然不影响启动,但排查问题时容易让人误判。如果你之前用 root 跑过测试,数据目录里有残留的 .err 文件,最好清空整个 data 目录再初始化。注意 /usr/local/mysql 整个目录的所有权,也一起给 mysql;否则 mysqld_safe 在切换用户之后连 basedir 都读不了。
4.2 用 mysql_install_db 初始化:4.1.11 的专属步骤
4.1.11 的初始化脚本是 bin/mysql_install_db,它是个 shell 脚本,内部还会调用编译时生成的 my_print_defaults 等辅助程序。初始化命令如下:
/usr/local/mysql/bin/mysql_install_db \ --basedir=/usr/local/mysql \ --datadir=/usr/local/mysql/data \ --user=mysql执行时要注意:这条命令必须由 root 运行,脚本内部会先读 my.cnf,再用 su 或者 setuid 切换成 --user 指定的 mysql 用户去建库。如果你已经用 mysql 用户去执行它,脚本反而会提示你以 root 身份重跑。成功的标志通常是输出一段 “To start mysqld at boot time you have to copy support-files/mysql.server……” 的提示,并且 data 目录下出现 mysql、test 两个子目录。看到这个再往下走。
初始化失败时,第一反应不要去看终端最后一屏,而是看 data 目录下有没有生成错误日志。老版本初始化失败大多落在两类:一类是 my.cnf 里的 socket 路径或 pid 路径指向了不存在的目录,另一类是 perl 环境缺失或者 my_print_defaults 找不到。确认方式很简单:ls /usr/local/mysql/data/mysql,如果目录为空或不完整,说明初始化没有真正完成,需要清掉重建。
4.3 my.cnf 两段式配置:client 与 mysqld 的 socket 必须指向同一路径
很多老资料教你装完直接 bin/mysqld_safe & 启动,我不建议这样。4.1.11 的默认行为在没有 my.cnf 时也能起,但 socket 路径、pid 文件、数据目录都可能和你编译参数不一致,排错成本很高。我习惯把所有关键路径写进 /etc/my.cnf:
[client] port=3306 socket=/tmp/mysql.sock [mysqld] basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/tmp/mysql.sock pid-file=/usr/local/mysql/data/mysql.pid log-error=/usr/local/mysql/data/mysql.err user=mysql port=3306 skip-name-resolve这里最重要的是 [client] 和 [mysqld] 两段里的 socket 完全一致。mysql 命令行客户端在读配置时只认 [client] 段,mysqld 启动时只认 [mysqld] 段;两边不一致时,客户端会去连一个服务端根本不监听的 socket 路径,报的正是 ERROR 2002 (HY000) Can't connect to local MySQL server through socket '...'。这种问题不是服务没起,而是路径错位,先改配置再谈其他排错。
log-error 显式写到 data 目录,是为了让错误日志的位置固定。老版本默认日志名是 主机名.err,藏在 datadir 下,等你需要看它时再去找就慢了。skip-name-resolve 是我在纯 IP 内网里喜欢加的一项,老版本默认会对来访客户端做反向解析,DNS 不通时会拖慢连接;加这一项之后,连接速度快很多。
提示:加了 skip-name-resolve 之后,GRANT 授权语句里的主机部分要写 IP,不能再写 hostname。例如建应用账号用 'app'@'192.168.1.%',而不是 'app'@'dbhost'。
4.4 启动与验证:mysqld_safe 只是壳,真正的状态在 .err 日志里
配置就绪后,启动命令很多人知道是 mysqld_safe,但不知道它只是个守护壳,真正干活的 mysqld 是它派生出来的子进程。启动后立刻验证:
/usr/local/mysql/bin/mysqld_safe --user=mysql & sleep 3 /usr/local/mysql/bin/mysqladmin --socket=/tmp/mysql.sock -u root ping # 正常会输出 mysqld is alive如果 ping 输出的是别的,立刻去看 4.3 里配置的 mysql.err:
tail -30 /usr/local/mysql/data/mysql.err错误日志里能看到启动到了哪一步。老版本最常见的启动失败是 data 目录所有权不对、pid 文件路径不可写、以及 my.cnf 里 basedir/datadir 写错导致找不到系统表。如果你在错误日志里看到 “Can't open the mysql.plugin table” 之类的信息,多半是初始化阶段没生成好系统库,直接删掉 data 目录重建一次,不要尝试手工补表。
4.5 确认进程与监听端口,并设置开机自启
启动并 ping 通之后,再从进程和端口两面确认一次:
ps -ef | grep mysqld | grep -v grep ss -ltn | grep 3306 /usr/local/mysql/bin/mysql -uroot -e "show full processlist;"processlist 能看到当前连接里有没有异常会话;刚装好的库应该只有 mysql 自己的一条连接。如果有大量 Sleep 连接来自你的应用,就说明连接池已经在连了,此时可以进入下一章的避坑环节。这一步还有一个作用:留个干净的基线,后面如果出现锁、连接堆积、慢查询,可以和这个状态对比。
老版本源码包里自带 sysv 风格的启动脚本,在 support-files 目录下。内网老机器上我一般直接装成系统服务:
cp /usr/local/src/mysql-4.1.11/support-files/mysql.server /etc/init.d/mysqld chmod +x /etc/init.d/mysqld chkconfig --add mysqld chkconfig mysqld on之后就能用 service mysqld start 和 service mysqld stop 管理了。注意这个脚本会去 /etc/my.cnf 读配置,也会尝试用 mysql 用户启动,所以前面章节的授权步骤不能省。在这个版本上,systemd 的 LSB 包装是后来发行版自动兼容出来的,手动装 init.d 脚本反而最省事。
5. 老版本避坑清单:ERROR 2002 与五个高频翻车现场
老版本 MySQL 的坑多数不是逻辑多深,而是行为习惯和现代版本差异太大。这里按我经历过的频率排了五条,每一条都是现象、原因、解决三步到位。
5.1 ERROR 2002 (HY000):socket 连不上,先按三层顺序查
现象:mysql -uroot 报错 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2),让人以为服务挂了,其实服务可能好端端跑着。
原因分三层,排查顺序不能乱。第一层:socket 文件根本不存在,说明 mysqld 没起来,优先看 error log;第二层:socket 文件存在,但路径和客户端读到的路径不一致,多数是 [client] 与 [mysqld] 两段配置错位;第三层:socket 文件存在、路径一致,但目标目录权限或 SELinux 策略挡了连接。
解决:先 ls -l /tmp/mysql.sock 确认文件,再核对 /etc/my.cnf 中两个 socket 段,然后 mysqladmin ping 看服务端是否真的活着。SELinux 场景比较少见,但内网机器上遇到时可以临时 getenforce 看一下状态,不要直接关。最土的办法往往最有效:直接用 --socket 参数强制指定路径再连一次,能连上就说明配置错位,不能连上才去查 mysqld 进程。
5.2 configure 或 make 阶段的链接错误:undefined reference to 'crypt'
现象:编译到最后链接时报一堆 undefined reference,常见对象是 crypt、gethostbyname,日志看起来很长,错误五花八门。
原因:老 MySQL 的 configure 对部分库的探测不全,某些系统上不会自动把 -lcrypt 加到链接参数里;另外高版本 gcc 对老代码的警告更容易升级成“致命错误”,导致看哪都是错的。
解决:先 make distclean 清干净,再用 LDFLAGS="-lcrypt" ./configure ... 重配一次,继续 make。gcc 太新时,我一般加 CFLAGS="-O2 -pipe -fno-strict-aliasing" 降低编译器优化带来的误判。如果机器上同时装了多版本 gcc,优先用旧一点的版本(能找到的话),比加编译参数省事得多。这属于老源码移植到新系统的经典痛点。
5.3 中文乱码与排序不符合预期:默认 latin1 的锅
现象:插入中文后通过 mysql 客户端看是乱码,或者 order by 排序结果与拼音、编码预期不符,但表结构看起来一切正常。
原因:4.1.11 虽然支持 utf8,但默认字符集是 latin1。configure 时如果没有带 --with-charset=utf8,建库语句也没显式声明,所有表都以 latin1 存储,中文自然乱;排序也按单字节序号排,和 utf8 字典序完全不一样。
解决:数据库这一侧统一指定。推荐做法是建库时显式写 CREATE DATABASE xxx DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;,表和连接层都不要依赖全局默认。注意 4.1 的 utf8 是 3 字节实现,不支持 emoji 和部分生僻字;如果业务必须存这类字符,建议直接放弃这个版本,上 5.7 或 8.0。这里不要指望升级 collation 能解决,方向错了。
5.4 mysqladmin shutdown 后进程还在:信号与 pid 文件的处理顺序
现象:mysqladmin -uroot shutdown 执行后命令返回,但 ps 里 mysqld 还在,socket 文件也没消失,过一会儿又自动恢复运行。
原因:老版本在处理某些特定表或锁时,shutdown 流程会等待内部资源释放;如果客户端断开异常,连接清理没完成,主进程就会一直处于半退出状态。另一个可能是 mysqld_safe 检测到 mysqld 意外退出,自动把它拉起来了;这种“守护壳”行为会让 shutdown 看起来像没生效。
解决:先用 mysqladmin ping 确认还在,再看 mysql.err 尾部有没有 “Shutdown complete” 字样。没有的话,先 kill $(cat /usr/local/mysql/data/mysql.pid),等 5 秒,还在就再 kill -9;同时把 mysqld_safe 进程也一并停掉,否则它会再拉起一个 mysqld。我的习惯是:停老实例先 mysqladmin shutdown,10 秒后仍失败才上 kill;不要上来就 kill -9,那会让 InnoDB 或 MyISAM 的损坏概率变大,这个版本可没有现代的崩溃恢复兜底。
5.5 远程连接慢、握手超时:主机名反解是隐形杀手
现象:同网段客户端连接 mysql 要卡几秒甚至十几秒,偶尔提示 “Host xxx is not allowed to connect”,本地连却很快。
原因:4.1.x 默认对每个客户端连接做反向 DNS 解析。内网 DNS 没有配置 PTR 记录时,解析超时、失败,mysqld 会等一轮才放行或拒绝。这和用户授权没关系,是握手阶段的前置检查。
解决:确认只用 IP 访问后,在 my.cnf 的 [mysqld] 段加上 skip-name-resolve,重启 mysqld。同时注意,开启这一项后授权写法的变化:grant all on.to 'app'@'192.168.1.%'; 要按 IP 段写,不能再写 'app'@'dbhost'。反过来,如果你的内网 DNS 管理规范,也可以不加这个参数,一切以能不能正常解析为准。遇到这类问题,先看 mysql.err 里有没有解析超时记录,再决定配不配。
6. 装完不白装:用自带工具给 4.1.11 做一次功能验证
系统跑起来只是第一步,作为交付前的最后一道关卡,我会用自带工具把字符集、排序、连接状态各验证一遍,避免出现“能启动但业务一接入就乱码”的尴尬。
6.1 mysqlshow 与 mysqladmin status:先确认系统库与服务状态
/usr/local/mysql/bin/mysqlshow -u root /usr/local/mysql/bin/mysqladmin statusmysqlshow 输出应该包含 mysql 库和 test 库;mysqladmin status 会返回 Uptime、Threads、Queries 等一组数值。如果你的应用连上来之后发现性能不对,这里的 Threads 和 Queries 是后续分析的基线。这个版本的客户端自带的帮助信息也很全,mysql --help 里能直接看到默认配置文件的搜索顺序,排查配置不生效时先看这里。
6.2 用一张临时表验证字符集、排序规则与连接行为
我习惯装完顺手测一下,而不是直接交给业务。
/usr/local/mysql/bin/mysql -uroot <<'SQL' CREATE DATABASE IF NOT EXISTS testbed DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE testbed; CREATE TABLE t (name varchar(50)) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO t VALUES ('mysql'),('MySQL'),('MYSQL'),('排序'); SELECT name FROM t ORDER BY name; SQL如果输出的四条记录按 utf8 字典序排列,而且中文没有变成问号,说明字符集链路是通的。这里 ENGINE=MyISAM 是因为 4.1.11 默认存储引擎是 MyISAM,InnoDB 在这个版本里虽然是可选项但默认不会给普通表启用;你不需要刻意改成 InnoDB,除非业务明确要用事务。
6.3 一个值得保留的习惯:把错误日志路径和 config.log 留在手边
我自己的习惯是装完不删 /usr/local/src/mysql-4.1.11/config.log,并且在 mysql.err 里定位到启动成功后,把日志路径抄在 my.cnf 注释里。老版本排错特别依赖现场信息,日志被清掉等于自断后路。另外,如果这台机器未来要交付给别人,我会把数据目录的完整权限列表打一份留存,避免后来者一上来就 chmod -R 777 把权限基线打乱。这算不上技巧,但对老版本维护来说,是最划算的一句话。希望帮到你。
本文还有配套的精品资源,点击获取