MySQL 4.1.11源码包离线编译安装指南与避坑实践
简介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 系用 dpkgrpm -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-usermysql \ --with-charsetutf8 \ --with-extra-charsetsall \ --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-usermysql 是把 mysqld 默认运行用户设为 mysql注意这是 configure 时写进源码的默认值和启动命令里 mysqld_safe --usermysql 是一个意思但不在同一层。--with-charsetutf8 是我必开的4.1.11 开始支持 utf8但默认字符集还是 latin1如果不在这里改建库时不显式声明字符集就会出现中文乱码。--with-extra-charsetsall 把所有字符集都编进去虽然不是最省空间的做法但对老版本来说后面对比数据、迁移数据时能少很多麻烦。--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 21 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 \ --usermysql执行时要注意这条命令必须由 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] port3306 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 usermysql port3306 skip-name-resolve这里最重要的是 [client] 和 [mysqld] 两段里的 socket 完全一致。mysql 命令行客户端在读配置时只认 [client] 段mysqld 启动时只认 [mysqld] 段两边不一致时客户端会去连一个服务端根本不监听的 socket 路径报的正是 ERROR 2002 (HY000) Cant connect to local MySQL server through socket ...。这种问题不是服务没起而是路径错位先改配置再谈其他排错。log-error 显式写到 data 目录是为了让错误日志的位置固定。老版本默认日志名是 主机名.err藏在 datadir 下等你需要看它时再去找就慢了。skip-name-resolve 是我在纯 IP 内网里喜欢加的一项老版本默认会对来访客户端做反向解析DNS 不通时会拖慢连接加这一项之后连接速度快很多。提示加了 skip-name-resolve 之后GRANT 授权语句里的主机部分要写 IP不能再写 hostname。例如建应用账号用 app192.168.1.%而不是 appdbhost。4.4 启动与验证mysqld_safe 只是壳真正的状态在 .err 日志里配置就绪后启动命令很多人知道是 mysqld_safe但不知道它只是个守护壳真正干活的 mysqld 是它派生出来的子进程。启动后立刻验证/usr/local/mysql/bin/mysqld_safe --usermysql sleep 3 /usr/local/mysql/bin/mysqladmin --socket/tmp/mysql.sock -u root ping # 正常会输出 mysqld is alive如果 ping 输出的是别的立刻去看 4.3 里配置的 mysql.errtail -30 /usr/local/mysql/data/mysql.err错误日志里能看到启动到了哪一步。老版本最常见的启动失败是 data 目录所有权不对、pid 文件路径不可写、以及 my.cnf 里 basedir/datadir 写错导致找不到系统表。如果你在错误日志里看到 “Cant 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): Cant 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-charsetutf8建库语句也没显式声明所有表都以 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 shutdown10 秒后仍失败才上 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 app192.168.1.%; 要按 IP 段写不能再写 appdbhost。反过来如果你的内网 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)) ENGINEMyISAM DEFAULT CHARSETutf8; INSERT INTO t VALUES (mysql),(MySQL),(MYSQL),(排序); SELECT name FROM t ORDER BY name; SQL如果输出的四条记录按 utf8 字典序排列而且中文没有变成问号说明字符集链路是通的。这里 ENGINEMyISAM 是因为 4.1.11 默认存储引擎是 MyISAMInnoDB 在这个版本里虽然是可选项但默认不会给普通表启用你不需要刻意改成 InnoDB除非业务明确要用事务。6.3 一个值得保留的习惯把错误日志路径和 config.log 留在手边我自己的习惯是装完不删 /usr/local/src/mysql-4.1.11/config.log并且在 mysql.err 里定位到启动成功后把日志路径抄在 my.cnf 注释里。老版本排错特别依赖现场信息日志被清掉等于自断后路。另外如果这台机器未来要交付给别人我会把数据目录的完整权限列表打一份留存避免后来者一上来就 chmod -R 777 把权限基线打乱。这算不上技巧但对老版本维护来说是最划算的一句话。希望帮到你。本文还有配套的精品资源点击获取