本节摘要:安装 MySQL 8.0、完成基础配置、掌握服务的启动停止与连接验证。诊断环境的目标是"敢删敢重启",一切病例都能在这里复现。
以 Linux 为例(Windows 用安装器同理):
# 安装后初始化并启动 systemctl start mysqld # 拿到临时 root 密码 grep 'temporary password' /var/log/mysqld.log # 首次登录后立刻改密码 mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Diag#2026Lab';
诊断环境建议单独建一个练习账号,别天天用 root——这也是给自己养成最小权限的习惯:
CREATE USER 'trainee'@'localhost' IDENTIFIED BY 'Train#2026Pwd'; GRANT SELECT, INSERT, UPDATE, DELETE ON clinic.* TO 'trainee'@'localhost';
systemctl stop mysqld # 停止 systemctl restart mysqld # 重启(改配置后必做) systemctl status mysqld # 看心跳
连接验证用一条 SQL 就够:
SELECT VERSION(), NOW();
两个参数在后面所有章节都会反复用到,装完先打开:
[mysqld] slow_query_log = ON long_query_time = 0.5
long_query_time 设成 0.5 秒而不是默认 10 秒,是因为多数线上问题的病灶查询都在几百毫秒量级,等它跑满 10 秒早就被用户投诉了。
⚠️ 常见坑:改完配置文件不重启,然后纳闷为什么不生效。mysqld 只在启动时读一遍配置文件。
单靠两个诊断开关还不够,装完机建议一次性把这份起步配置放进去,后面章节的实验都默认它生效:
[mysqld] # 字符集一步到位,避免以后迁移时的字符集手术 character-set-server = utf8mb4 collation-server = utf8mb4_0900_ai_ci # 慢查询诊断三件套 slow_query_log = ON long_query_time = 0.5 log_queries_not_using_indexes = ON # 错误日志:排启动故障的第一现场 log_error = /var/log/mysql/error.log # 练习环境内存不用大,256M 够跑全书示例 innodb_buffer_pool_size = 256M # 8.0 默认开启,确认一下即可 log_bin = ON binlog_format = ROW
log_queries_not_using_indexes 会把没走索引的查询也记进慢日志,练习环境开着它,很多索引失效的病例会自己送上门。生产环境要慎开,低频没索引但代价很小的查询会刷屏。
改完配置的重启也有讲究:
# 重启前先验证配置文件语法,低版本可跳过 mysqld --validate-config --console systemctl restart mysqld # 重启后确认参数真的生效了 mysql -uroot -p -e "SHOW VARIABLES LIKE 'slow_query%';"
装机阶段的病最打击新手信心,好在翻来覆去就那几种。密码忘了:停服务、加 skip-grant-tables 启动、免密进去改密码、去掉参数正常重启,五分钟能走完。端口被占:报错 Address already in use,用端口占用查询找到占用进程,或者换一个 port。字符集乱码:多半是客户端连接字符集与服务端不一致,连接串里显式指定 charset 即可。root 远程连不上:默认只允许本机登录,给练习账号授权对应网段就好,别直接放开 root 到任意主机。
每个故障处理完,值得花一分钟想一下报错信息里其实已经写了什么。数据库的报错比多数软件诚实,读懂报错这个习惯,在后面诊断慢查询时同样值钱。
空库复现不了性能病例,建表后先灌几万行数据让表有点体重。存储过程是最省事的灌数工具:
DELIMITER // CREATE PROCEDURE seed_orders(IN n INT) BEGIN DECLARE i INT DEFAULT 0; START TRANSACTION; REPEAT SET i = i + 1; INSERT INTO clinic_order (user_id, amount, status, created_at) VALUES (ELT(1+(i MOD 500), FLOOR(1+RAND()*500)), ROUND(RAND()*999,2), i MOD 5, NOW() - INTERVAL (i MOD 720) HOUR); UNTIL i >= n END REPEAT; COMMIT; END // DELIMITER ; CALL seed_orders(200000);
二十万行的表足够让全表扫描与索引查找的差距肉眼可见,又不会让练习机卡顿。灌完顺手跑一次统计更新,后面拍执行计划时数字更可信。
排障时经常要对照两个版本的行为差异,Windows 上 zip 包解压两份、Linux 上把第二个实例的数据目录与端口分开即可:
# 第二实例用独立数据目录与端口启动(Linux 示例) mysqld --initialize-insecure --datadir=/data/mysql8037 mysqld --datadir=/data/mysql8037 --port=3307 --socket=/tmp/mysql8037.sock & mysql -uroot -S /tmp/mysql8037.sock # 连第二实例
initialize-insecure 生成空 root 密码,只可用于练习环境。生产初始化永远用 --initialize 拿随机密码再改。数据目录、端口、socket 三件套分开,两个实例就互不干扰,升级演练、版本对比实验都在一台机器上完成。
mysqld 起不来是新手最常见的急症,按流程走五分钟能定位九成。第一步看错误日志最后一屏,权限不足、端口占用、配置项拼写错误都会直接写在那里。第二步核对数据目录属主,mysqld 用户没有数据目录写权限是最经典的翻车。第三步用启动参数绕过配置文件试一次,起来了就说明配置文件有雷,二分注释定位。第四步磁盘满与 inode 耗尽也要列入怀疑名单,日志把盘写满导致实例反复重启的病例并不罕见:
# 最小化启动:跳过授权表,只做急救诊断用 mysqld_safe --skip-grant-tables --skip-networking & # 能起来说明 mysqld 本体没病,问题在权限或配置
急救完记得正常重启一次,别带着 skip-grant-tables 过夜——它等于把诊断室大门整夜敞开。