1. 项目概述:为什么你总在 mysql 报错后“两眼一抹黑”?
你刚改完一段 sql,执行 insert into users ... ,结果弹出 error 1062 (23000): duplicate entry 'admin' for key 'username' ;或者服务突然连不上了, mysql -u root -p 死活报 error 2003 (hy000): can't connect to mysql server on 'localhost' (111) ;又或者 docker 容器里 mysql 启动失败,日志里只有一行 mysql exited with code 1 —— 这时候你第一反应是不是立刻去 google 搜 “mysql 连接失败 怎么办”?
但搜出来的答案千篇一律:“检查端口”、“重启服务”、“修改配置文件”,却没人告诉你: 真正的线索,就藏在那个你从来没打开过的 /var/log/mysql/error.log 文件里 。
这个文件不是可有可无的“系统垃圾”,它是 mysql 的“黑匣子”,记录着从服务启动失败、权限校验异常、磁盘空间不足、innodb 崩溃恢复,到慢查询触发告警、ssl 握手失败等所有底层真相。
我做过上百次 mysql 故障排查,90% 的“疑难杂症”——比如 could not open file '/var/log/mysql/error.log' for error logging: permission denied 或 nginx: [alert] could not open error log file 这类看似无关的报错——根源都指向同一个环节: 你根本没真正看懂、读对、用好 mysql 的错误日志 。
它不像 select * from information_schema.processlist 那样能直接在客户端查,也不像 show variables 那样有现成命令;它是一份纯文本的“案发现场记录”,需要你用 less 、 tail 、 grep 这些 linux 基础命令去翻阅、过滤、定位。而 ubuntu 系统下,默认路径、权限设置、日志轮转机制,又和 centos 完全不同。所以这篇内容不是教你“怎么安装 mysql”,而是直击痛点: 当你被 error: claude code process exited with code 1 或 error 2003卡住时,如何在 3 分钟内精准定位到 /var/log/mysql/error.log里的关键线索,并读懂它说的每一句话 。
适合所有正在 ubuntu 上部署、运维或调试 mysql 的人,无论你是刚装完 mysql-server 的新手,还是在 wsl 或 vmware 虚拟机里跑开发环境的程序员,甚至是在 rk3588 开发板上调试嵌入式数据库的工程师——只要你的 mysql 在 linux 下跑,这个日志就是你最该先打开的“诊断说明书”。
2. 日志机制深度拆解:mysql 错误日志不是“日志文件”,而是一套运行时诊断系统
2.1 错误日志的本质:mysql 的“自检报告”而非“操作流水账”
很多人误以为 mysql 错误日志(error log)和应用层的日志(比如 django 的 django.log )一样,是开发者手动 print() 或 logger.error() 写进去的。
这是个致命误解。mysql 的错误日志是 mysqld 进程自身在运行时,由其内部诊断模块(diagnostic module)主动写入的系统级事件记录 。
它不记录 sql 执行结果(那是 general log 或 slow log 的事),而是记录 mysqld 进程自身的“健康状态”。
举个生活化类比:如果把 mysql 比作一辆汽车,那么 slow log 是行车记录仪拍下的“哪段路开得慢”, general log 是车载语音助手记下的“你说了哪些指令”,而 error log 就是发动机控制单元(ecu)自动生成的故障码报告(dtc) ——比如 p0300 (随机/多缸失火)、 u0100 (与 ecm 通信丢失)。
它不告诉你“为什么失火”,但它会明确告诉你“失火发生了”,并附上时间戳、线程 id、内存地址、调用栈片段等原始证据。因此,当你看到 error.log 里出现 innodb: database page corruption on disk or a failed file read of tablespace ,这不是一句模糊的“数据库坏了”,而是 innodb 存储引擎在读取某个 .ibd 文件的特定页(page)时,校验和(checksum)校验失败,说明物理存储已损坏。这种信息,任何 show 命令或客户端工具都给不出来。
2.2 ubuntu 下默认行为的三大关键特征:路径、权限、开关逻辑
ubuntu(以及所有基于 debian 的发行版)对 mysql 错误日志的处理,和 red hat 系列有本质区别。这直接决定了你 cat /var/log/mysql/error.log 时是看到一堆报错,还是 no such file or directory 。核心三点必须吃透:
第一,路径不是“约定俗成”,而是由包管理器硬编码决定的。
在 ubuntu 上, mysql-server 包(来自官方仓库)安装后, mysqld 的默认错误日志路径被编译进二进制文件,固定为 /var/log/mysql/error.log 。这不是 my.cnf 里配置的,也不是启动脚本生成的——它是 deb 包构建时就写死的。你可以用 strace 验证: sudo strace -e trace=openat -f mysqld --no-defaults --help 2>&1 | grep error.log ,会看到 openat(at_fdcwd, "/var/log/mysql/error.log", o_wronly|o_creat|o_append, 0640) = 3 。这意味着,即使你把 my.cnf 里 log_error 改成 /tmp/mysql.err ,ubuntu 的 systemd 服务也会因为权限问题拒绝启动(稍后详述)。所以, 在 ubuntu 上, /var/log/mysql/error.log 就是事实标准路径,别想着改它,先学会读它 。
第二,权限不是“用户能读就行”,而是 mysql 用户专属的“安全沙箱”。
ubuntu 严格遵循最小权限原则。 /var/log/mysql/ 目录的所有者是 mysql:mysql ,权限是 drwxr-x--- (750),意味着只有 mysql 用户和 mysql 组成员能进入此目录;而 error.log 文件本身的所有者也是 mysql:mysql ,权限是 -rw-r----- (640),即只有 mysql 用户可读写, mysql 组成员可读,其他用户(包括你的普通账户 ubuntu )完全无权访问。这就是为什么你 sudo cat /var/log/mysql/error.log 能成功,但 cat /var/log/mysql/error.log 会报 permission denied 。这不是 bug,是设计。它防止恶意程序或低权限用户通过读取日志获取敏感信息(如密码哈希、连接 ip、表结构)。所以, sudo不是偷懒,而是 ubuntu 下读取 mysql 日志的合规姿势 。
第三,开关逻辑不是“开/关二选一”,而是“启动时强制启用 + 运行时可动态关闭”。
mysql 5.7+ 默认开启错误日志,且 log_error 变量是只读的( read only ),你无法在运行时 set global log_error = '/new/path' 。
但在 ubuntu 上,还有一个更隐蔽的开关: log_error_verbosity 。它控制日志的详细程度,取值 1(仅 error)、2(error + warning)、3(error + warning + note)。默认是 3,所以你会看到大量 note 级别的启动信息(如 server socket created on ip: '127.0.0.1'. )。
如果你只想看严重错误,可以临时设为 1,但这不影响日志文件本身的存在与否。
关键结论:在 ubuntu 上,只要你没手动禁用, error.log 就一定存在且在持续写入;找不到它,99% 是权限或路径问题,而不是它被关掉了 。
2.3 为什么less是 ubuntu 下读日志的黄金搭档?不只是“分页查看”那么简单
网络热词里反复出现 linux less命令详解 ,绝非偶然。在 ubuntu 下读 mysql 错误日志, less 的地位远超 cat 、 more 甚至 vim 。
原因有三:
其一, less是唯一能“安全预览大文件”的命令。
一个运行数月的 mysql 实例, error.log 动辄几百 mb。 cat 会一股脑刷屏,卡死终端; vim 加载时会占用巨量内存,甚至崩溃;而 less 是流式加载,只读取当前屏幕所需的数据块。你用 sudo less /var/log/mysql/error.log ,它瞬间打开,光标停在文件开头,按 g (大写)直接跳到末尾(最新日志),按 g (小写)跳回开头,全程零卡顿。这是底层设计决定的: less 用 mmap() 映射文件,而非全部读入内存。
其二, less内置的搜索功能是故障定位的核心武器。
less 的 / 键支持正则搜索。比如,你想找所有 error 级别日志,按 / 输入 ^20[0-9]{2}-[0-9]{2}-[0-9]{2}t[0-9]{2}:[0-9]{2}:[0-9]{2}.*error (匹配 iso 时间戳 + error 字样),回车后高亮所有匹配行,按 n 下一个, n 上一个。更实用的是,mysql 启动失败时,关键线索往往在最后几行。你按 g 跳到末尾,再按 k (上箭头)逐行往上翻,看到 mysqld: can't create/write to file '/var/lib/mysql/is_writable' (errcode: 13 - permission denied) 这样的行,立刻就知道是 /var/lib/mysql 权限错了。 less 的交互式导航,让你像侦探一样在日志里“现场勘查”。
其三, less的 -n参数能暴露日志的“时间序列真相”。
默认 less 不显示行号,但加 -n ( sudo less -n /var/log/mysql/error.log )后,每行前面显示绝对行号。这在分析日志轮转(log rotation)时至关重要。ubuntu 的 logrotate 默认每天轮转一次,旧日志变成 error.log.1.gz 。如果你发现 error.log 里最新一条是昨天的 2024-05-20t10:30:00z ,而今天服务又挂了,那必须立刻查 error.log.1.gz : zless /var/log/mysql/error.log.1.gz | tail -50 。行号能帮你确认“新日志是否真的在写入”,避免误判。
提示: less 的常用快捷键必须烂熟于心: g (跳末尾)、 g (跳开头)、 / (搜索)、 n/n (下/上一个匹配)、 k/j (上/下一行)、 q (退出)。这些不是“技巧”,而是 ubuntu 下 mysql 运维的肌肉记忆。
3. 实操全流程:从“找不到文件”到“读懂最后一行”的完整闭环
3.1 第一步:确认日志文件是否存在及基础状态(30 秒定乾坤)
很多人的第一步就错了:不是直接 cat ,而是先做三件事,用 ls 和 stat 快速建立认知。
执行命令:
sudo ls -l /var/log/mysql/ sudo stat /var/log/mysql/error.log sudo systemctl status mysql
解读输出:
sudo ls -l /var/log/mysql/ 输出类似:
drwxr-x--- 2 mysql mysql 4096 may 20 10:30 . drwxr-xr-x 12 root root 4096 may 20 09:00 .. -rw-r----- 1 mysql mysql 0 may 20 10:30 error.log -rw-r----- 1 mysql mysql 1234 may 19 23:59 error.log.1.gz
关键看三点:
error.log 文件是否存在(不是 no such file );大小是否为 0 (如果是,说明 mysqld 没写入过,可能根本没启动成功);权限是否为 -rw-r----- (如果不是,比如是 600 或 644 ,说明权限被改过,需修复)。
sudo stat /var/log/mysql/error.log输出包含access:(最后访问时间)、modify:(最后修改时间)、change:(最后状态变更时间)。重点看modify:,如果它的时间戳远早于当前时间(比如是昨天的),而systemctl status mysql显示服务是active (running),那就说明日志写入被阻塞了,常见原因是磁盘满(df -h /var/log查看)或log_error配置被覆盖。sudo systemctl status mysql输出中,active:行最关键。如果是active (running),说明服务在跑,日志应该有内容;如果是failed,则error.log很可能为空或只有启动失败的几行,此时要结合journalctl -u mysql --since "2024-05-20 10:00:00"查 systemd 日志。
注意: sudo ls -l 是必须的。不要用 ls -l ,否则看不到 mysql 用户的权限细节,你会误以为“文件存在就能读”,结果 cat 时 permission denied ,白白浪费时间。
3.2 第二步:用less安全打开并定位最新错误(1 分钟内完成)
确认文件存在且非空后,立即执行:
sudo less -n /var/log/mysql/error.log
操作流程与意图解析:
- 按
g(大写 g)跳到文件末尾 :mysql 日志是追加写入(append-only),最新日志永远在最底部。跳到末尾是“第一现场勘查”,避免在几千行历史中大海捞针。 - 按
k(小写 k)向上翻页,逐行审视 :重点扫描以[error]、[warning]、[note]开头的行。注意[error]是红色警报,[warning]是黄色预警,[note]是蓝色提示。例如:
2024-05-20t10:30:15.123456z 0 [error] could not open file '/var/lib/mysql/ibdata1' for reading: permission denied 2024-05-20t10:30:15.123457z 0 [error] innodb: the system tablespace must be writable!
这两行就是核心线索: permission denied 指向权限问题, ibdata1 是 innodb 共享表空间文件,路径 /var/lib/mysql/ 是数据目录。
解决方案立刻清晰: sudo chown -r mysql:mysql /var/lib/mysql 。
按 / 搜索关键词 :如果末尾没有明显错误,或你想找特定问题,用正则搜索。常用模式:
/error:找所有错误(注意大写,避免匹配error.log字符串)/2003:找error 2003连接失败(mysql 错误码常出现在日志中)/cannot connect:找连接相关描述/disk full:找磁盘空间问题 搜索后按n跳到下一个匹配项,快速定位。
按 q退出 less:不要用 ctrl+c ,那会中断进程。 q 是优雅退出。
实操心得:我见过太多人卡在“日志太大打不开”。记住, less 的 g 键是你的救命稻草。永远先跳末尾,再往上翻。90% 的故障,线索就在最后 20 行内。
如果 g 后看到 mysqld: ready for connections ,说明启动成功,问题在应用层;如果看到 aborting 或 fatal error ,那就是 mysql 自身崩溃。
3.3 第三步:处理“找不到文件”和“权限拒绝”的两大高频陷阱(附真实案例)
网络热词中 could not open file '/var/log/mysql/error.log' for error logging: permission denied 和 no such file or directory 高频出现,它们不是孤立错误,而是系统性配置问题的表象。
陷阱一:“no such file or directory” —— 日志文件根本不存在
现象: sudo ls /var/log/mysql/ 返回 no such file or directory ,或 error.log 文件名不存在。
根因分析: 这通常发生在两种场景:
- 场景 a:mysql 从未成功启动过。 ubuntu 的
mysql-server包安装后,mysqld并不会自动创建/var/log/mysql/目录。它只在第一次成功启动时,由mysqld进程自己创建该目录并写入error.log。如果首次启动因配置错误(如bind-address = 0.0.0.0但防火墙拦截)失败,目录就不会创建。 - 场景 b:
log_error被错误配置。 虽然 ubuntu 默认路径是硬编码的,但如果你手动编辑了/etc/mysql/mysql.conf.d/mysqld.cnf,添加了log_error = /tmp/mysql.err,那么mysqld会尝试写入/tmp/mysql.err,而/var/log/mysql/目录自然不会被创建。
解决方案:
- 先检查
mysqld是否在运行:sudo systemctl status mysql。如果inactive (dead),执行sudo systemctl start mysql。 - 如果启动失败,看
systemctl的active:行后的main pid和status。常见status: "failed with result 'exit-code'"。 - 此时不要猜,直接查
journalctl:sudo journalctl -u mysql -n 50 --no-pager。它会显示mysqld启动时的 stdout/stderr,比如can't read dir of '/etc/mysql/conf.d/'(配置目录权限错)或unknown variable 'log_error=/tmp/mysql.err'(配置语法错)。 - 修复配置后,手动创建目录并赋权:
sudo mkdir -p /var/log/mysql && sudo chown mysql:mysql /var/log/mysql && sudo chmod 750 /var/log/mysql。然后重试sudo systemctl start mysql。
陷阱二:“permission denied” —— 权限链断裂
现象: sudo ls -l /var/log/mysql/ 显示 error.log 权限是 -rw-r----- ,但 sudo cat /var/log/mysql/error.log 却报 permission denied 。
根因分析: 这违反了 linux 权限的基本规则,说明权限链上有环节被破坏。最常见的是:
- 父目录权限错误:
/var/log/mysql/目录的权限不是750,而是700(只有mysql用户能进)或755(其他用户也能进,但不符合 ubuntu 安全策略)。ls -ld /var/log/mysql/查看目录权限。 - selinux/apparmor 干预: ubuntu 默认用 apparmor。如果
aa-status显示apparmor module is loaded,且sudo aa-status | grep mysql显示mysqlprofile 是enforce模式,那么 apparmor 可能阻止了mysqld写入日志。检查/var/log/audit/audit.log或/var/log/syslog里是否有apparmor="denied"记录。
解决方案:
- 修复目录权限:
sudo chmod 750 /var/log/mysql/(确保组可读可执行)。 - 检查 apparmor:
sudo aa-status --enabled确认启用,sudo aa-status | grep -a 5 mysql查看 profile 状态。如果 profile 被禁用(complain模式),用sudo aa-enforce /etc/apparmor.d/usr.sbin.mysqld启用;如果启用但报错,临时禁用测试:sudo aa-disable /etc/apparmor.d/usr.sbin.mysqld,然后sudo systemctl restart mysql。如果问题消失,说明是 apparmor 规则问题,需更新规则(sudo vim /etc/apparmor.d/usr.sbin.mysqld,添加/var/log/mysql/** rw,)。
实操心得:权限问题不是“chmod 777”能解决的。ubuntu 的安全模型是层层递进的: /var/log 目录权限 → /var/log/mysql/ 目录权限 → error.log 文件权限 → apparmor profile。漏掉任何一层,都会导致 permission denied 。我建议新人先 sudo chmod 750 /var/log/mysql/ 和 sudo chown mysql:mysql /var/log/mysql/ ,这是最安全的基线。
3.4 第四步:日志轮转(log rotation)与历史日志挖掘(应对“日志被清空”)
ubuntu 的 logrotate 默认每天轮转 mysql 日志,旧日志压缩为 .gz 文件。这意味着你 less 打开的 error.log 只是“今天的”日志。当故障发生在昨天,而你只看 error.log ,就会一无所获。
轮转机制详解:
/etc/logrotate.d/mysql-server 文件定义了轮转规则。关键参数:
daily:每天轮转一次。rotate 7:保留最近 7 个轮转文件(error.log.1.gz到error.log.7.gz)。compress:用 gzip 压缩旧日志。missingok:如果日志文件不存在,不报错。create 640 mysql mysql:轮转后,新建error.log文件,权限640,所有者mysql:mysql。
挖掘历史日志的实操步骤:
- 列出所有轮转文件:
sudo ls -lt /var/log/mysql/error.log*。-t按修改时间排序,最新的在最上面。 - 查看最新轮转文件(
.1.gz):
zless /var/log/mysql/error.log.1.gz
zless 是 less 的 gzip 版本,用法完全一样( g , / , q )。如果 .1.gz 也空,继续查 .2.gz 。
- 用
zgrep快速搜索压缩日志:
比如找昨天的所有 error :
zgrep -i "error" /var/log/mysql/error.log.1.gz | head -20
-i 忽略大小写, head -20 只看前 20 行,避免刷屏。
- 还原整个轮转周期:
如果你需要分析连续几天的日志,可以解压并合并:
zcat /var/log/mysql/error.log.[1-7].gz /var/log/mysql/error.log > /tmp/all_mysql_errors.log sudo less -n /tmp/all_mysql_errors.log
这样你就有了一个包含一周日志的“全景视图”,便于追踪问题演变。
注意: zcat 和 zless 是 ubuntu 预装的,无需额外安装。不要用 gunzip 解压再 cat ,那会生成巨大的临时文件,浪费磁盘空间。
4. 故障排查实战:从热搜词出发的 5 个典型场景与日志解码
4.1 场景一:error 2003 (hy000): can't connect to mysql server on 'localhost:3306'(连接失败)
这是 mysql 新手最常遇到的报错。 2003错误码表示客户端无法建立 tcp 连接,但原因千差万别。 error.log是唯一能区分“服务没起来”和“服务起来了但拒绝连接”的地方。
日志特征与解码:
特征 a:日志末尾无 ready for connections,只有 mysqld: ready for connections之前的启动日志,最后是 aborting或 fatal error。
例如:
2024-05-20t10:30:15.123456z 0 [error] could not open file '/var/lib/mysql/ibdata1' for reading: permission denied 2024-05-20t10:30:15.123457z 0 [error] innodb: the system tablespace must be writable! 2024-05-20t10:30:15.123458z 0 [error] plugin 'innodb' init function returned error. 2024-05-20t10:30:15.123459z 0 [error] plugin 'innodb' registration as a storage engine failed. 2024-05-20t10:30:15.123460z 0 [error] failed to initialize plugins. 2024-05-20t10:30:15.123461z 0 [error] aborting
解码: aborting 是最终判决。前面的 permission denied 指向 /var/lib/mysql/ 目录权限错误。
解决方案: sudo chown -r mysql:mysql /var/lib/mysql && sudo systemctl restart mysql 。
特征 b:日志末尾有 mysqld: ready for connections ,但客户端仍连不上。
例如:
2024-05-20t10:30:15.123456z 0 [note] mysqld: ready for connections. version: '8.0.33-0ubuntu0.22.04.2' socket: '/var/run/mysqld/mysqld.sock' port: 3306 (ubuntu).
解码: 服务已启动,监听 3306 端口。问题在客户端配置或网络层。检查 netstat -tuln | grep :3306 确认端口监听; sudo ss -tuln | grep :3306 (更现代); mysql -h 127.0.0.1 -p 3306 -u root -p (用 ip 而非 localhost ,绕过 socket)。
避坑技巧: error 2003 的日志位置很关键。如果 aborting 出现在 ready for connections 之前,是服务启动失败;如果 ready for connections 存在,但之后又有 aborting ,则是服务运行中崩溃,需查崩溃前的 error 行。
4.2 场景二:error: claude code process exited with code 1 view output logs(docker/wsl 环境集成失败)
这个热词组合暴露了一个典型场景:你在 wsl 或 docker 中运行 claude code(或其他依赖 mysql 的 ai 工具),它启动时抛出 exited with code 1 ,提示你“view output logs”。这其实是容器或子进程的退出码,根源往往是 mysql 服务不可用。
日志特征与解码:
特征:日志里出现 socket相关错误,且 ready for connections后无 socket路径。
例如:
2024-05-20t10:30:15.123456z 0 [note] mysqld: ready for connections. version: '8.0.33-0ubuntu0.22.04.2' socket: '/var/run/mysqld/mysqld.sock' port: 3306 (ubuntu). 2024-05-20t10:30:20.123456z 0 [warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode. 2024-05-20t10:30:25.123456z 0 [error] can't start server: bind on tcp/ip port. got error: 98: address already in use
解码: address already in use 表明 3306 端口被占用了。在 wsl/docker 中,这通常是因为宿主机(windows)上已运行了一个 mysql 服务,或者另一个容器占用了端口。 socket 路径 /var/run/mysqld/mysqld.sock 是 unix socket,用于本地连接; port: 3306 是 tcp 端口。如果端口被占,tcp 连接失败,但 socket 连接可能还可用(取决于应用配置)。
解决方案:
- 查谁占了
3306:sudo lsof -i :3306或sudo netstat -tulnp | grep :3306。 - 在 docker 中,确保
docker run时指定-p 3307:3306映射到其他端口,避免冲突。 - 在 wsl 中,关闭 windows 的 mysql 服务:
net stop mysql(管理员 powershell)。
实操心得: exited with code 1 是通用退出码,意义不大。关键看 view output logs 提示的“output logs”是什么——如果是 docker,用 docker logs <container_id> ;如果是 wsl 子进程,用 journalctl -u mysql 。 error.log 是 mysql 自身的日志,它告诉你 mysql 是否正常,但不告诉你外部进程为何失败。
4.3 场景三:could not open file '/var/log/mysql/error.log' for error logging: permission denied(日志写入失败)
这个错误不是客户端报的,而是 mysqld 自己在 error.log 里写的!它意味着 mysql 启动时,试图打开自己的日志文件失败,于是它连错误都无法记录,只能在 stderr(即 journalctl )里吐出这句话。
日志特征与解码:
特征: error.log文件本身是空的( size 0),而 journalctl -u mysql里有这行错误。
例如 journalctl 输出:
may 20 10:30:15 ubuntu mysqld[1234]: mysqld: could not open file '/var/log/mysql/error.log' for error logging: permission denied may 20 10:30:15 ubuntu mysqld[1234]: mysqld: aborting
根因与修复:
这一定是 /var/log/mysql/ 目录的权限或所有者错了。 mysqld 进程以 mysql 用户身份运行,它需要对该目录有 w (写)权限才能创建 error.log 。检查:
sudo ls -ld /var/log/mysql/ # 正确应为:drwxr-x--- 2 mysql mysql ... # 如果是 drwx------ 2 root root ...,则修复: sudo chown mysql:mysql /var/log/mysql/ sudo chmod 750 /var/log/mysql/
然后 sudo systemctl restart mysql 。
4.4 场景四:nginx: [alert] could not open error log file: createfile() "logs/error.log"(nginx 与 mysql 日志混淆)
这个热词组合很有意思,它把 nginx 和 mysql 日志混在一起了。虽然 nginx 的错误和 mysql 无关,但它揭示了一个普遍问题: 开发者常把不同服务的日志路径搞混,或在共享环境中(如 docker compose)配置冲突 。
日志特征与解码:
nginx 的错误日志路径是 logs/error.log (相对路径)或 /var/log/nginx/error.log (绝对路径),和 mysql 的 /var/log/mysql/error.log 完全不同。但如果在 docker 中,你把 mysql 的 /var/log/mysql 目录挂载到了 nginx 容器的 /var/log/nginx ,就可能引发路径覆盖。
排查思路:
- 确认
nginx的日志配置:grep "error_log" /etc/nginx/nginx.conf。 - 检查
nginx进程的cwd(当前工作目录):sudo pwdx $(pgrep nginx)。 - 如果
nginx的error_log是相对路径logs/error.log,它会在nginx的cwd下创建logs/目录。如果cwd是/,它就会尝试创建/logs/error.log,而/目录通常不允许普通用户写入,导致permission denied。
解决方案:
- 在
nginx.conf中,用绝对路径:error_log /var/log/nginx/error.log;。 - 确保
/var/log/nginx/目录存在且权限正确:sudo mkdir -p /var/log/nginx && sudo chown www-data:www-data /var/log/nginx。
4.5 场景五:日志爆炸与磁盘占满(df -h显示/var/log100%)
mysql 错误日志本身不会无限增长,但 logrotate 失效或 log_error_verbosity 设为 3 (记录所有 note ),加上频繁的 warning
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论