前置排查准备:开启报错提示获取完整信息

DedeCMS默认关闭SQL错误详情展示,报错只会显示通用的“SQL语句错误”提示,需要先开启调试模式才能定位根因,操作步骤如下:
- 找到站点根目录下的
include/common.inc.php文件,将文件中$debug = false;修改为$debug = true;
- 如果你使用的是V5.7及以上版本,还要找到
data/config.cache.inc.php文件,将$cfg_debug = 0;修改为$cfg_debug = 1;
- 完整的SQL错误日志存放在站点根目录
data/logs/路径下,文件名为sql_error_开头的.log文件,可直接下载查看完整报错栈
常见报错场景与对应修复方案
场景1:字段不存在/不匹配报错
报错特征:日志或页面显示Unknown column 'xxx' in 'field list',触发原因多为安装第三方插件未执行数据库更新脚本、自定义字段删除后未同步修改调用代码、跨版本升级遗漏表结构更新。
- 步骤1:从报错信息中复制缺失的字段名、对应的表名,注意DedeCMS默认表前缀为dede_,如果你修改过前缀要对应替换
- 步骤2:登录phpMyAdmin或Navicat连接站点数据库,执行查表结构语句确认字段是否存在:
```
DESC `你的表名`;
```
- 步骤3:如果确认字段缺失,执行对应字段添加SQL即可,示例为dede_archives表添加varchar类型的自定义字段test:
```
ALTER TABLE `dede_archives` ADD COLUMN `test` varchar(255) NOT NULL DEFAULT '' COMMENT '自定义测试字段';
```
- 步骤4:如果是字段类型不匹配,比如字段为int类型传入了字符串,执行修改字段类型语句即可,示例为将test字段修改为int类型:
```
ALTER TABLE `dede_archives` MODIFY COLUMN `test` int(11) NOT NULL DEFAULT 0 COMMENT '测试数字字段';
```
场景2:SQL语法错误报错
报错特征:显示You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxx',触发原因多为自定义arclist标签SQL书写错误、拼接参数时遗漏单引号/多了逗号、用户传入特殊字符未转义。
- 步骤1:根据报错中near后面的内容定位错误位置,near指向的内容的前1-2个字符就是错误点
- 步骤2:检查SQL语句是否存在以下常见错误:字段列表末尾多了逗号、字符串类型的值未加单引号、表名/字段名未加反引号导致和MySQL关键字冲突
- 步骤3:如果是用户传入参数导致的语法错误,必须对传入参数做过滤,优先使用DedeCMS自带的FilterSql函数过滤,示例代码:
```
// 接收参数后先过滤
$keyword = FilterSql($_GET['keyword']);
// 再拼接SQL
$sql = "SELECT FROM `dede_archives` WHERE title LIKE '%$keyword%'";
```
场景3:数据库表损坏报错

报错特征:显示Table './你的数据库名/表名' is marked as crashed and should be repaired,触发原因多为服务器意外断电、磁盘空间占满写入失败、数据库异常重启导致表损坏。
- 步骤1:登录phpMyAdmin,在左侧选中对应站点数据库,勾选损坏的表,底部下拉菜单选择「修复表」即可自动修复
- 步骤2:如果无法登录phpMyAdmin,可执行SQL语句直接修复:
```
REPAIR TABLE `你的表名`;
```
- 步骤3:如果修复失败,直接从最近的数据库备份中恢复对应表,DedeCMS默认备份路径为
data/backupdata/
场景4:数据库权限不足报错
报错特征:显示INSERT/UPDATE/DELETE command denied to user '数据库用户名'@'localhost' for table '表名',触发原因多为数据库用户未开通对应表的写入权限、迁移站点后数据库账号权限未同步配置。
- 步骤1:独立服务器用户可直接登录MySQL控制台,执行授权命令:
```
GRANT ALL PRIVILEGES ON 你的数据库名. TO '你的数据库用户名'@'localhost' IDENTIFIED BY '你的数据库密码';
FLUSH PRIVILEGES;
```
- 步骤2:虚拟主机用户直接进入主机管理面板的数据库管理页面,找到对应数据库用户,勾选全部权限后保存即可
修复后验证与长期避坑方案
修复验证操作
- 步骤1:先将之前开启的调试模式改回默认值:
include/common.inc.php中$debug改回false,data/config.cache.inc.php中$cfg_debug改回0,避免泄露数据库敏感信息
- 步骤2:重新触发之前报错的操作,确认功能正常无报错
- 步骤3:查看
data/logs/下最新的日志文件,确认没有新的SQL错误生成
长期避坑操作
- 1. 进入DedeCMS后台-系统-系统基本参数-核心设置,开启SQL注入防御,可自动拦截大部分恶意拼接的SQL语句
- 2. 所有自定义SQL语句、自定义标签的传参必须经过过滤,禁止直接将用户输入的内容未处理就拼接进SQL
- 3. 每次升级系统、安装第三方插件、修改表结构前,必须先全量备份站点文件和数据库
- 4. 每月执行一次数据库表优化,可在phpMyAdmin选中所有表后下拉选「优化表」,或执行SQL:
```
OPTIMIZE TABLE `表名`;
```
紧急兜底方案
如果排查半小时以上仍无法定位问题,可直接执行以下操作快速恢复站点:
- 1. 先进入后台开启站点维护模式,避免用户访问看到报错
- 2. 恢复最近一次正常运行时的数据库备份,注意不要直接覆盖现有数据库,先导入到临时库测试正常后再切换
- 3. 如果报错是修改文件后触发的,直接将修改过的文件替换为备份的原始文件即可