WordPress 数据库报错处理
先分清是连不上、表坏了,还是查询被打断了
数据库报错在浏览器里往往只显示一句话,但背后的原因可能差得很远:凭据写错、服务没起、磁盘写满、表结构损坏、单条 SQL 超出包大小、或者某个插件把连接数占满。「Error establishing a database connection」和「Table is marked as crashed」看起来都是打不开,处理方式完全不同。这一页按报错原文分类,给出判断依据、命令与恢复动作。
六种报错,六个方向
原文决定了该查哪一层
同样表现为「网站打不开」,报错文字已经把排查范围缩小了一半。先把屏幕上那句话原样抄下来,再对照下面五类。
连不上数据库
Error establishing a database connection。这句话由 WordPress 自己输出,意味着 PHP 已经跑起来了,但 mysqli 握手失败。方向在凭据、服务状态、网络与权限四者之间。
表损坏
Table './db/wp_options' is marked as crashed and should be repaired。表文件本身坏了,通常是异常断电、强制杀进程或磁盘故障留下的。数据可能还在,但索引需要重建。
连接中途断开
MySQL server has gone away,或 Lost connection to MySQL server during query。查询跑到一半连接被掐断,多见于大导入、大导出、长事务。
锁等待与死锁
Deadlock found when trying to get lock; try restarting transaction,或 Lock wait timeout exceeded。两个请求互等对方的行锁,InnoDB 会主动杀掉其中一个。
致命错误兜底页
There has been a critical error on this website。这是 WordPress 5.2 之后加的兜底提示,真实错误被藏起来了,必须去看 wp-content/debug.log 或 PHP 错误日志才能知道详情。
写入失败但前台正常
页面能打开,发布文章时报 Could not insert post into the database。说明读没问题、写被拒,多半是数据库用户缺少 INSERT 权限,或磁盘已满导致表只读。
连不上的六种原因
按出现频率排序
这一类的排查成本最低,多数问题在十分钟内能定位。关键是不改任何东西就先做一次手工连接测试,让 MySQL 自己把原因说出来。
凭据写错或迁移后未更新
打开 wp-config.php,核对 DB_NAME、DB_USER、DB_PASSWORD、DB_HOST 四项。迁移后最常见的是库名带了主机商的前缀,比如从 wordpress 变成 user_wp123。密码里有单引号或反斜杠时,转义也会让连接失败。
DB_HOST 不是 localhost
云数据库、容器化环境里,主机地址通常是内网域名或 127.0.0.1:3306 这种带端口的写法。写 localhost 时 MySQL 走 Unix socket,写 127.0.0.1 时走 TCP,两者在部分环境下行为不同,socket 路径不对就会连不上。
- 先试 localhost,不行换 127.0.0.1
- 再不行问主机商要内网地址
数据库服务没起来
服务器重启后 MySQL 没设开机自启,或者因内存不足被系统 OOM killer 杀掉。表现是所有站点同时打不开,而不只是某一个。查服务状态 systemctl status mysqld,再看 /var/log/mysql/error.log 的末尾。
磁盘写满
MySQL 无法写 binlog 或临时表时,连接会被拒绝。用 df -h 看根分区,用 du -sh /var/lib/mysql 看库体积。常见元凶是 binlog 未清理、慢日志涨到几十 GB、或者备份文件放在了同分区。
连接数被占满
报错原文是 Too many connections。先 SHOW PROCESSLIST 看有多少 Sleep 状态的连接,再 SHOW VARIABLES LIKE 'max_connections'。默认 151,小内存机器上被几个爬虫同时抓就会打满。
用户没有该库的权限
能连上服务器但选不了库,报 Access denied for user 'xx'@'localhost' to database 'yy'。用 SHOW GRANTS FOR 'xx'@'localhost'; 确认授权范围,缺的话让主机商或 DBA 补一条 GRANT。
最快的验证方式是绕开 WordPress 直接连:mysql -u 用户名 -p -h 主机地址 库名。能进说明凭据和服务都正常,问题在 WordPress 这一侧(多半是缓存了旧的连接信息);进不去,错误提示会直接告诉你是密码错、主机不通还是权限不足。
表损坏的修复路径
先备份,再修,修不好就重建
看到 crashed 字样不要慌,多数情况下表能修回来。但要先明确一件事:修复动作本身有可能让数据进一步丢失,所以在执行任何 REPAIR 之前,先把整个库导一份出来。
先导出,哪怕库是坏的
mysqldump -u root -p --single-transaction --quick 库名 > before-repair.sql。损坏的表可能导不出来,加上 --force 让它跳过继续导其余的,至少把能救的先救出来。
用 mysqlcheck 批量检查
mysqlcheck -u root -p --auto-repair --all-databases 会先检查再自动修。只想看不想修,把 --auto-repair 换成 --check。装了 WP-CLI 的话,wp db check 与 wp db repair 更贴合 WordPress 的表前缀。
单表修复与引擎判断
针对具体表执行 REPAIR TABLE wp_options;。MyISAM 表多数能修好,InnoDB 表在 MySQL 8 里对 REPAIR 支持有限,往往需要 ALTER TABLE wp_options ENGINE=InnoDB; 触发重建,或从备份单独恢复这张表。
修不好就换表重建
把坏表改名留档,从备份导入同名表,再补上备份之后产生的差异。wp_options 这类配置表体积小,重建代价低;wp_posts 体积大,重建前务必确认备份时间点,否则会丢掉最近的发文。
修完不要立刻收工。跑一次 wp db check 确认全部 OK,再看 /var/log/mysql/error.log 里有没有 InnoDB: Database page corruption 之类的记录。有的话说明是磁盘层面的问题,表会反复损坏,该换机器了。数据库优化与冗余清理的日常做法,见数据库优化与冗余清理。
导入导出时断连
三个参数决定成败
迁移、还原、换主机时最容易撞上的就是这一类。表现是导入跑到一半停住,或者 SQL 文件导进去只成功了一部分,前台看起来正常,实际上少了几百篇文章。
max_allowed_packet
单条 SQL 超过这个值就会被截断,报 MySQL server has gone away。默认常见 4M 或 16M,导入含长文本的库时明显不够。临时调:SET GLOBAL max_allowed_packet=67108864;,持久化要写进 my.cnf 的 [mysqld] 段。
wait_timeout
连接空闲超过这个秒数会被服务端断开,默认 28800 秒通常在网页侧够用,但命令行跑长脚本时就容易断。导入期间临时设为 600 以上,导完改回来。
PHP 侧的执行时间
用 phpMyAdmin 导入时,真正的瓶颈常是 max_execution_time 与 upload_max_filesize。50MB 以上的 SQL 建议走命令行,不要用网页工具,超时和上传限制两道坎都绕不开。
导入完成后一定要核对行数:SELECT COUNT(*) FROM wp_posts; 与源库对比,差几十条就是中断了。另外,导入前把目标库字符集设为 utf8mb4,排序规则与原库一致,否则中文会变成问号,这类问题在恢复之后才发现就晚了,相关流程见备份与恢复。
报错速查表
原文、含义、动作、风险
动手前先对号入座。风险一列写的是「做错会怎样」,不是「可能有问题」。
| 报错原文片段 | 含义 | 处理动作 | 操作风险 |
|---|---|---|---|
| Error establishing a database connection | 凭据或服务异常 | 核对 wp-config 四项,手工 mysql 连接测试 | 改错库名会连到空库,前台看似重置 |
| Access denied for user | 账号或授权不对 | SHOW GRANTS 确认,补授权 | 误删授权会导致其他站一起挂 |
| Unknown database | 库不存在或名字错 | 确认库名,必要时新建后导入 | 新建空库再访问会触发重装流程 |
| Table is marked as crashed | 表文件损坏 | 先 dump,再 REPAIR 或重建表 | 直接 REPAIR 可能丢掉最后几条记录 |
| MySQL server has gone away | 包超限或连接被断 | 调大 max_allowed_packet,减少单条体积 | 全局改参数需重启,影响同机其他应用 |
| Too many connections | 连接数打满 | 清 Sleep 连接,调 max_connections | 调太高会耗尽内存导致服务崩溃 |
| Deadlock found | 行锁互等 | 重试事务,优化批量写入顺序 | 忽略会周期性复发,拖慢结账流程 |
| Disk full / No space left | 磁盘写满 | 清 binlog、慢日志与临时文件 | 误删数据目录文件会造成不可逆损坏 |
数据库故障常见五问
多半是某个后台模块在写库时失败,或者对象缓存里还留着旧数据,前台走缓存所以正常。这类情况更要处理,因为下一次缓存失效就会全线崩。先看 debug.log 里最后一条错误,再确认磁盘是否已满、数据库用户是否还有写权限。
会。主题设置、插件开关、站点地址都存在这张表里。修复后要立刻核对站点地址与首页地址两项,配错会导致整站跳转到错误域名。稳妥做法是从备份单独恢复这张表,再补上修复前最后一段时间的变更。
可以,但要选在低峰期并先导出。全库修复会占用大量 IO,表多的时候可能跑十几分钟,期间站点响应明显变慢。InnoDB 表在这类操作里收益有限,真正需要修的多是遗留的 MyISAM 表。
有间接关系。wp_postmeta 与 wp_options 膨胀会拖慢查询,长查询占住连接,进而引发连接数打满与锁等待。定期清理文章修订版本、过期 transient、废弃插件的残留选项,是成本最低的预防手段,具体做法见数据库优化与冗余清理。
看报错出现在哪一层。页面完全无输出且状态码 500,先查 PHP 错误日志;页面出现 WordPress 样式的数据库提示,说明 PHP 正常、数据库异常;页面白屏但服务器返回 200,多半是主题或插件里的致命错误。白屏与打不开的分支判断,见WordPress 白屏排查和WordPress 网站打不开排查。
数据库报错反复出现
先做一次完整体检,别只重启服务
提供数据库入口或主机面板,我们先查表完整性、慢查询、连接数与磁盘水位,再判断是修复、重建还是迁移。动手前统一做全量导出,恢复路径提前写清楚。相关阅读:WordPress 内存超限与 500 错误。
电话/微信 13280692153 邮箱 web@wordpressx.com 地址 山东省淄博市张店区电子产业创新园 B 座