2026年5月29日收到数据库系统报警,报警信息
The result is ORA-00600: internal error code, arguments: [qosdExpStatRead: expcnt mismatch], [65539], [3], [481407], [1], [], [], [], [], [], [], [].

报警现象:
从数据库报警信息上分析ORA-600 qosdExpStatRead,那么qosdExpStatRead是什么意思,首先给大家解释一下,方便分析错误产生的原因。
QOSD 是什么?
数据库 自动统计信息收集(Auto Stats)
对比性能变化
回滚统计信息
AWR / 调优工具分析历史负载
“QOSD 统计导出” 指的是什么?
QOSD 负责把 统计信息快照导出、写入数据字典表:
- sys.exp_obj$:每个对象 + 快照的 元数据 + 计数器(EXP_CNT)
- sys.exp_stat$: 明细数据,一条一条的统计项
为什么会触发你那个 ORA-600?
核心是因为是oracle的一个小 Bug 28681153 :
自动统计收集
手动 DBMS_STATS.GATHER_*
expdp 导出统计
QOSD 先写明细 exp_stat \(,后更新 exp_obj\).EXP_CNT
没有锁保护,并发时:
会话 A:插入明细 → 还没来得及更新 EXP_CNT
会话 B:又插入明细 → 更新 EXP_CNT
结果: EXP_CNT ≠ 实际明细行数
下次 QOSD 读取校验 → expcnt mismatch → ORA-600
自动统计更激进、默认开启
RAC 节点间同步更频繁
校验更严格(11g/12c 可能不报错)所以这个问题在 19c 特别常见。
sys.exp_obj$ 的计数器字段
EXP_CNT,和明细表
sys.exp_stat$ 的实际记录行数不一致,Oracle 内部校验不通过,直接抛 ORA-600。sys.exp_obj$:
统计信息快照的 “元数据表”,每条记录记一个对象 + 快照的统计条目总数(
EXP_CNT)sys.exp_stat$:
统计信息快照的 “明细数据表”,存每一条统计数据
解决方案:
1、紧急修复步骤
1)定位不一致记录(SYS 执行)
With b as ( select count(*) cnt,objn,snapshot_id from sys.exp_stat$ es group by objn,snapshot_id) select * from sys.exp_obj$ a, b where a.objn=b.objn and a.snapshot_id=b.snapshot_id and a.EXP_CNT<>b.CNT; OBJN SNAPSHOT_ID EXP_CNT CNT OBJN SNAPSHOT_ID ---------- ----------- ---------- ---------- ---------- ----------- 6760972 1 0 65536 6760972 1
返回结果即为 有问题的对象号 + 快照 ID
2)修复字典不一致(替换 &SNAP_ID / &OBJN)
先备份(安全第一) -- 备份异常数据,防止意外 CREATE TABLE sys.exp_obj_bak AS SELECT * FROM sys.exp_obj$; CREATE TABLE sys.exp_stat_bak AS SELECT * FROM sys.exp_stat$; delete from sys.exp_stat$ b where b.snapshot_id = <snapshot_id> and b.objn = <objn> ; update sys.exp_obj$ a set a.EXP_CNT=0 where a.SNAPSHOT_ID= <snapshot_id> and a.objn = <objn>; commit;
注意:这是修改系统字典, 操作前务必备份数据库
3)临时关闭自动统计(防止复发)
-- 关闭自动SQL调优任务
EXEC DBMS_AUTO_TASK_ADMIN.DISABLE(client_name=>'SYS_AUTO_SQL_TUNING_TASK',operation=>NULL,window_name=>NULL);
-- 或仅关闭统计收集(按需)
EXEC DBMS_STATS.SET_PARAM('AUTO_STATS_TASK','FALSE');
ALTER SYSTEM SET "_fix_control"='31143146:on' SCOPE=BOTH;
2、执行后验证(确认修复干净)
-- 检查是否还有不一致 WITH stat_cnt AS (SELECT objn, snapshot_id, COUNT(*) real_cnt FROM sys.exp_stat$ GROUP BY objn, snapshot_id) SELECT '仍有异常' AS result FROM sys.exp_obj$ o JOIN stat_cnt s ON o.objn = s.objn AND o.snapshot_id = s.snapshot_id WHERE o.exp_cnt <> s.real_cnt AND ROWNUM = 1;
输出 无数据行表示已经修复成功了。
3、彻底解决方法
-- 关闭有问题的 QOSD 统计导出(官方推荐规避方案) ALTER SYSTEM SET "_exadata_feature_on"=FALSE SCOPE=SPFILE; -- 19c 推荐开启修复控制 ALTER SYSTEM SET "_fix_control"='31143146:ON' SCOPE=BOTH;
上面的文档是官方提供的bug修复方案
该问题主要是oracle官方的一个bug引起的。我们虽然修复了bug。但是没有激活Bug31143146 。
因此第二种修复方案如下:
1. Check the existing "_fix_control" settings:
For example:
--Check SPFILE setting
SQL> select name, value from V$SYSTEM_PARAMETER2 where name like '_fix_control';
NAME VALUE
------------------ ------------------
_fix_control 32005394:on
SQL>
--Check memory setting
SQL> select a.ksppinm "Parameter",
c.ksppstvl "Instance Value"
from x$ksppi a, x$ksppcv b, x$ksppsv c
where a.indx = b.indx
and a.indx = c.indx
and a.ksppinm in ('_fix_control')
order by 1; 2 3 4 5 6 7
Parameter Instance Value
------------------------------ --------------------
_fix_control 32005394:on
SQL>
2. set "_fix_control"='31143146:on' without removing existing settings:
For example:
System altered.
SQL>
3.Check the latest settings:
For example:
SQL> select name, value from V$SYSTEM_PARAMETER2 where name like '_fix_control';
NAME VALUE
------------------ --------------------------
_fix_control 31143146:on
_fix_control 32005394:on
SQL> select a.ksppinm "Parameter",
c.ksppstvl "Instance Value"
from x$ksppi a, x$ksppcv b, x$ksppsv c
where a.indx = b.indx
and a.indx = c.indx
and a.ksppinm in ('_fix_control')
order by 1; 2 3 4 5 6 7
Parameter Instance Value
------------------------------ --------------------------
_fix_control 31143146:on, 32005394:on
SQL>
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12798004/viewspace-3172634/ ,如需转载,请注明出处,否则将追究法律责任。