Linux数据库环境搭建:七步实战到稳定
|
去年冬天,凌晨三点零七分,我蹲在测试机前,盯着那台老掉牙的 Dell OptiPlex 3020——显示器竖着,键盘上 Delete 键早掉了,只剩个灰印。后端甩过来一个「环境已配好」的 commit 记录:7a2f8d1 —— 改了 Dockerfile 的 ENTRYPOINT,没改 init.sql 里 TIMESTAMP 默认值写法。我就信了。 亲历现场。不是看文档,是直接连进那台跑 CentOS 7.9 的测试服务器,ssh 进去第一眼就看到 /var/log/mysqld.log 里塞着两行报错:「Unknown or incorrect time zone: 'Asia/Shanghai'」和底下紧跟着的「Can't start server: Bind on TCP/IP port. Got error: 98: Address already in use」。没人告诉我 port 3306 被另一个 mysqld 实例占着,也没人说系统时区还没配,更没人说那个「已配好」的镜像压根没跑过 init.sql——它连目录都不存在,init.sql 是挂在 -v 里的,但路径写错了,少了个 ./。
文章配图,仅供参考 会议室的白板没擦干净,上面还留着三天前产品讲「双十二大促数据看板实时刷新」时画的三张表关联草图,MySQL 没启起来,ER 图就是一坨装饰画。有人端着杯子站了很久,在门口反复刷门禁卡,因为工位网段被运维临时封了,他说他刚改完前端 WebSocket 的重连逻辑,现在连不上自己的本地 mock 接口——他不知道,他连的 mock 服务其实在调我的数据库连接池。第一步,杀进程。ps aux | grep mysql,kill -9 七个 PID,其中三个属于上个月遗留的 systemd 启动失败残留;第二步,删 data 目录——/var/lib/mysql 下面有个 ib_logfile0 明明在用,rm -rf 却不报错,等启动才吐出「InnoDB: Unable to lock ./ibdata1 error 11」;第三步,重装 MySQL 5.7.38,rpm -ivh 强制覆盖,结果 rpmdb 损坏,yum update 报错「cannot open Packages index using db5」;第四步,切回 tar.gz 手动部署,解压完 chmod -R 755 mysql,漏了 chown -R mysql:mysql ./data,mysqld --initialize --user=mysql 之后报「File ./auto.cnf can't be created」;第五步,翻出去年中台项目留下的 my.cnf 备份,拷进去,发现 innodb_buffer_pool_size 写成 4G——服务器总共才 2G 内存,一启就 OOM killer 杀掉 mysqld;第六步,把 buffer_pool 调到 512M,重启,建库时报「ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'promotion'」——root 密码根本没设,初始化时跳过了 --initialize-insecure;第七步,重来,--initialize-insecure,再进 mysql_secure_installation,中途卡在「Remove anonymous users? [Y/n]」——控制台光标狂闪,SSH 会话其实已经断了,但你没注意,还在敲 y。 谁在背后走过碰了椅子,我手一抖,回车按早了。Secure Installation 自动选了 Y,删了匿名用户,顺手关了 root 远程登录——但活动页后端配的是 root@%。后端同学微信弹出来:“连不上啊”,我截图发过去,他回复:“你给的账号密码不对”。我说没给你新密码,他说“那你给的肯定是旧的”。我们吵了十七分钟,不是因为技术,是因为他拉的 branch 名字叫 feature/dbswitch-final-v2-fix2-again,而我改的 my.cnf 在 master 分支的 config/ 目录下,他 pull 的是另一个私有 repo——连同步都没做,我们各自对着两个世界修 bug。 外卖到了没人去拿,塑料袋在工位隔板边堆成小山。我盯着性能面板里 Network 标签页:/api/promotion/list 返回状态码一直是 pending,Request Headers 里 Connection 显示 keep-alive,但 Response 里啥都没有——因为连接池全在 wait 状态,show processlist 一眼扫过去,14 个 Sleep 进程卡在 init,timeout 设置是 28800,而 MySQL 连接超时默认 8 小时。时间线崩得比 CSS flex 布局还松散:凌晨三点部署,五点上线倒计时,六点运营催埋点 ID,七点产品经理在群里问“数据能实时刷吗”,八点我才发现主从同步的 relay-log-index 文件权限是 600,chown mysql:mysql 都没用,得 chmod 644,因为从库 io_thread 启动需要读索引文件。 这七步,不是教程,是刮骨。所谓“实战到稳定”,本质是把所有你以为「肯定不会出问题」的地方,亲手捅一遍——比如以为 init.sql 是自动执行的,其实是 shell 脚本里一句 mysql -u root -p < init.sql,而那个 -p 后面没填密码,脚本就卡住不动;比如以为 systemctl daemon-reload 之后 service 就会认新配置,结果 mysqld.service 里 User= 不是 mysql 而是 root,一跑就报「Failed at step USER spawning /usr/sbin/mysqld: No such process」;比如以为 docker-compose up -d 启动完就算数,实际上 healthcheck 健康检查写的是一行 curl http://localhost:3306,而 MySQL 根本不走 HTTP,curl 一直 7(Failed to connect),容器永远 restart: on-failure。 我不觉得这是「搭建」,这是拆弹。你得先确认爆炸物在哪:是 ulimit -n 开太低导致 too many open files;是 selinux enforcing 状态让 socket 绑定失败;是 firewalld 里开了 3306 却忘了 internal zone 没配 masquerade;还是 just that one line in /etc/my.cnf where skip-networking 被注释掉了,但 bind-address=127.0.0.1 没改,结果外网请求全进不来——可前端接口又硬编码写了内网 IP。 冷眼。我没力气总结什么“标准化流程”或“沉淀最佳实践”。我现在要做的,是立刻 ssh 到那台测试服务器,cd /tmp,wget 我本地最新版的 deploy-check.sh——它只做四件事:检测 3306 端口、查 /var/lib/mysql/ 是否有 ibdata1、跑一次 mysqladmin ping、cat /proc/$(pgrep mysqld)/status | grep Uid,确认是不是 mysql 用户启的。如果这四个都过,我就把这台机器打个快照,名字叫「20231208-before-product-thinks-it’s-live」,然后 push 到公司内部的 Ansible Vault,加一条 note:别信 commit message,别信微信群记录,别信“已配好”三个字。 下次再遇到这种事,我打算先把 keyboard 上那个掉的 Delete 键粘回去。至少按 Ctrl+C 的时候,手指能落到实处。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


Linux安全环境搭建:13年运维实战指南
新规首周,中小带货主播话术速调——数据库视角看流量策略实时演化
SQL Server数据库设计避坑指南:12个实战关键点
Linux新手避坑指南:14年接口测试工程师亲授安装配置
Linux下H5开发环境与数据库一键配置实战
Windows数据科学环境搭建:15年网安工程师避坑指南
Go赋能数据库优化:技术跨界启迪站长新视野