大家好,这里是 Lucifer三思而后行,专注于提升数据库运维效率。
目录
- 前言
- 问题分析
- 日志分析
- ORA-600 解析
- DBLINK 问题?
- 解决方案
- 后记
- 往期精彩文章推荐
前言
一大早还没上班,客户紧急告知应用频繁报错:ORA-00600 [25027]
,且产线大面积无法使用,需要帮忙分析问题原因以及如何解决。
参考 MOS 文档:
- ORA-600 [25027] (Doc ID 284433.1)
- ORA-00600 [25027] [x] [0] Raised by Insert into LOB (Doc ID 1608861.1)
以下仅为个人分析记录,仅供参考。
问题分析
已知当前报错的库为一套 3 节点 19.21 RAC 数据库。
日志分析
通过 adrci 查看最近是否有 ORA 报错:
## 发现 ORA-600 报错
PROBLEM_ID PROBLEM_KEY LAST_INCIDENT LASTINC_TIME
-------------------- ----------------------------------------------------------- -------------------- -----------------------------
2 ORA 600 [ORA-00600: 內部錯誤代碼, 引數: [25027], [8 314306 2024-09-09 07:56:38.018000 +08:00
经检查 alert 日志报错内容为 ORA-600 [25027], [8], [0]
,并且问题指向 TESTDB:
ORA-00600: 內部錯誤代碼, 引數: [ORA-00600: 內部錯誤代碼, 引數: [25027], [8], [0], [], [], [], [], [], [], [], [], []
], [], [], [], [], [], [], [], [], [], [], []
ORA-02063: 在 line 之前, 自 TESTDB
查看 trace 详细日志内容发现对应 SQL 为一条 INSERT 语句,并且是通过 DBLINK 连接到 TESTDB 执行数据插入:
INSERT INTO CUS_LUCIFER_UPLOAD_BASE@TESTDB (xxxxxxxxxxx) VALUES (xxxxxxxxxxxxx)
查看 TESTDB 库的 alert 日志内容,同样报错 ORA-600 [25027], [8], [0]
:
ORA-00600: 內部錯誤代碼, 引數: [25027], [8], [0], [], [], [], [], [], [], [], [], []
看来问题应该是出在 TESTDB 上,这是一套 11GR2(201020)补丁的单机数据库。
ORA-600 解析
ORA-600 是 Oracle 中非常常见的一种错误,大概率是由于 BUG 导致,所以需要查看一下 MOS 中对 ORA-600 [25027] (Doc ID 284433.1)
ERROR:
Format: ORA-600 [25027] [a] [b]
VERSIONS:
versions 9.2 and above
ARGUMENTS:
Arg [a] Tablespace Number (TSN)
Arg [b] Decimal Relative Data Block Address (RDBA)
In 12c it includes Multitenant information:
Arg [a] 0 if Multitenant is not enabled or 0 if there is not Root CDB session, 1 ROOT PDBID, otherwise PDBID top session
Arg [b] PDBID
Arg [c] Tablespace Number (TSN)
Arg [d] Decimal Relative Data Block Address (RDBA)
因为 TESTDB 是一套 11GR2 的库,所以只需要看对应版本的 ARGUMENTS 即可:
ARGUMENTS:
Arg [a] Tablespace Number (TSN)
Arg [b] Decimal Relative Data Block Address (RDBA)
通过 alert 报错信息可以发现 [a] [b] 对应的值为 [8] [0],a 代表的是表空间的号,b 代表的是 RDBA(数据块的十进制地址)。
MOS 针对报错给出的分析建议如下:
SUGGESTIONS:
1. If the Arg [b] or [d] in 12c (the RDBA) is 0 (zero), then this could be caused by fake indexes. The following query will list fake indexes:
select do.owner,do.object_name, do.object_type,sysind.flags
from dba_objects do, sys.ind$ sysind
where do.object_id = sysind.obj#
and bitand(sysind.flags,4096)=4096;
If the above query returns any rows, check the objects involved and consider dropping them as they can cause this error.
or it could be the case described in the next article when allocating a block for a LOB segment in a DML:
Note 1608861.1 ORA-00600 [25027] [x] [0]
2. Run analyze table validate structure on the table referenced in the Current SQL statement in
the related trace file.
If the Known Issues section below does not help in terms of identifying
a solution, please submit the trace files and alert.log to Oracle
Support Services for further analysis.
这里第一条的 b 值为 0,看起来与我们的情况有些相符,大概意思有可能是由虚假索引导致的,建议检查是否存在虚假索引:
SQL> select do.owner,do.object_name, do.object_type,sysind.flags
from dba_objects do, sys.ind$ sysind
where do.object_id = sysind.obj#
and bitand(sysind.flags,4096)=4096;
no rows selected
很不幸,没有查到任何内容,看来不符合这个建议。下面说有可能是对 LOB 对象做 DML 操作时导致,初看也与我们的情况比较相似,因为报错 SQL 确实是一个 INSERT 操作,所以需要确认以下表是否有 LOB 字段:
SQL> desc LUCIFER.CUS_LUCIFER_UPLOAD_BASE
Name Null? Type
----------------------------------------- -------- ----------------------------
UPDATE_TIME DATE
TERMINAL_ID NUMBER
PART_ID NUMBER
RESULT VARCHAR2(32)
SUM_COUNT NUMBER
SUCC_COUNT NUMBER
FAIL_COUNT NUMBER
WORK_ORDER VARCHAR2(32)
UPLOAD_TIME DATE
KEYID VARCHAR2(64)
FTP_PATH VARCHAR2(1024)
FTP_TYPE NUMBER
UPDATE_EMPNO VARCHAR2(64)
MACHINE_ID NUMBER
RECID VARCHAR2(256)
CREATE_TIME DATE
CREATE_DATE NUMBER
检查后发现没有 LOB 字段,还是不符合。那就只能看第二种建议了,建议对表进行 analyze validate structure
操作,看来是怀疑有坏块,也有一定的可能性:
-- 首先确保当前数据库中没有坏块
SQL> select * from V$DATABASE_BLOCK_CORRUPTION;
no rows selected
-- analyze 表
SQL> set timing on
SQL> analyze table CUS_LUCIFER_UPLOAD_BASE validate structure;
Table analyzed.
Elapsed: 00:01:22.63
-- analyze 表和索引
SQL> analyze table CUS_LUCIFER_UPLOAD_BASE validate structure cascade;
Table analyzed.
Elapsed: 01:14:04.09
看来表和索引都没有任何问题,不存在逻辑坏块。那么有没有可能存在物理坏块,查看表和索引所在的数据文件:
-- 查看 a 值 8 对应的表空间数据文件,对应的都是索引表空间
SQL> select t.ts#, t.name tablespace_name, f.file#, f.name file_name
from v$tablespace t, v$datafile f
where t.ts#=f.ts# and t.ts#=8;
TS# TABLESPACE_NAME FILE# FILE_NAME
---------- ------------------------------ ---------- ----------------------------------------------------------------------------------------------------
8 luciferidx 6 /oradata/testdb/luciferidx01.dbf
8 luciferidx 7 /oradata/testdb/luciferidx02.dbf
8 luciferidx 8 /oradata/testdb/luciferidx03.dbf
8 luciferidx 333 /oradata2/testdb/dataidx231120.dbf
8 luciferidx 365 /oradata2/testdb/dataidx240412.dbf
-- 查看表所在的数据文件
select file_name from dba_tables t1, dba_data_files t2
where t1.tablespace_name=t2.tablespace_name
and t1.owner='LUCIFER' and t1.table_name='CUS_LUCIFER_UPLOAD_BASE';
FILE_NAME
----------------------------------------------------------------------------------------------------
/oradata2/testdb/lucifer04.dbf
/oradata/testdb/lucifer03.dbf
/oradata/testdb/lucifer02.dbf
/oradata/testdb/lucifer01.dbf
对表和索引所在的数据文件进行 dbv 分析:
dbv file=/oradata/testdb/luciferidx01.dbf blocksize=8192
dbv file=/oradata/testdb/luciferidx02.dbf blocksize=8192
dbv file=/oradata/testdb/luciferidx03.dbf blocksize=8192
dbv file=/oradata2/testdb/dataidx231120.dbf blocksize=8192
dbv file=/oradata2/testdb/dataidx240412.dbf blocksize=8192
rman check 分析:
RMAN> backup check logical validate datafile '/oradata/testdb/lucifer01.dbf';
RMAN> backup check logical validate datafile '/oradata/testdb/lucifer02.dbf';
RMAN> backup check logical validate datafile '/oradata/testdb/lucifer03.dbf';
RMAN> backup check logical validate datafile '/oradata2/testdb/lucifer04.dbf';
查看坏块:
SQL> select * from V$DATABASE_BLOCK_CORRUPTION;
no rows selected
没有发现任何坏块,看来坏块的怀疑也排除了。
这里抱着重启试试的心态,把 TESTDB 数据库重启了一下,发现依然频繁报错,没有任何改善。
DBLINK 问题?
开发怀疑有可能是 DBLINK 导致的问题,所以重建了 DBLINK,不幸的是,重建后依然报错。后面索性直接不使用 DBLINK,改为在本地建一张表,然后直接在本地插入数据,确实可行,数据库没有再报错,产线也恢复正常。
到这里,看起来可能是使用 DBLINK 导致的问题,所以查了 2pc 分布式事务的相关情况,没有发现异常,所以还是怀疑是 TESTDB 的这张表有问题,那就重建这张表试试。
解决方案
经过跟开发沟通之后,在 TESTDB 重建表,把原表 RENAME 重建之后,恢复 DBLINK,持续观察了一段时间,发现产线恢复正常,ORA-600 报错消失:
alter table LUCIFER.CUS_LUCIFER_UPLOAD_BASE rename to CUS_LUCIFER_UPLOAD_BASE_BAK;
create table LUCIFER.CUS_LUCIFER_UPLOAD_BASE tablespace lucifer as select * from LUCIFER.CUS_LUCIFER_UPLOAD_BASE_BAK;
create index LUCIFER.IDX_LUCIFER_ATEUPLOAD_BASE_SN on CUS_LUCIFER_UPLOAD_BASE (TERMINAL_ID) tablespace LUCIFERIDX parallel 32;
alter index LUCIFER.IDX_LUCIFER_ATEUPLOAD_BASE_SN noparallel;
问题虽然解决了,但是我一脸懵逼,看起来就是这张表出问题了,但是问题到底出在哪里了?
后记
开了 Oracle Case,得到回复如下:
这次的现象属于 Logical Block Corruptions(逻辑破损)的范畴。
Ref:
Physical and Logical Block Corruptions. All you wanted to know about it. ( Doc ID 840978.1 )
Logical Block Corruptions
This is when block contains a valid checksum and the structure below the beginning of the block is corrupt (Block content is corrupt). It may cause different ORA-600 errors.
The detailed corruption description for Logical Corruptions are not normally printed in the alert.log. DBVerify will report what is logically corrupted in the block.
事后想追溯其根本原因说实话其实是非常困难的。因为涉及到的层面比较多,比如存储,OS I/O 写,应用(Oracle)等层面都有可能引起 逻辑破损 的可能性。
Ref:
Handling Oracle Block Corruptions ( Doc ID 28814.1 )
Overview of Steps to handle a Corruption
There are many possible causes of a block corruption including:
・Bad IO hardware / firmware
・OS problems
・Oracle problems
・Recovering through "UNRECOVERABLE" or "NOLOGGING" database actions
(in which case ORA-1578 is expected behaviour - see below)
比如,已知的和存储相关的现象,烦请参考下面的技术文档。
Ref:
Database Corruption due to stale/old blocks after EMC SRDF/A DR switchover - ORA-600 [25027] ORA-600 [kdsgrp1] ORA-8103 ORA-1410 ( Doc ID 1675764.1 )
以上仅供参考。
往期精彩文章推荐
Oracle 数据库启动过程之 nomount 详解Oracle RAC 修改系统时区避坑指南(深挖篇)Ubuntu 22.04 一键安装 Oracle 11G RAC使用 dbops 快速部署 MySQL 数据库Oracle RAC 启动顺序,你真的了解吗?达梦数据库一键安装脚本(免费)一篇文章让你彻底掌握 Python 🔥
一篇文章让你彻底掌握 Python一篇文章让你彻底掌握 Shell 🔥
Oracle 监控 EMCC 13.5 安装部署超详细教程 🔥
Oracle 一键巡检自动生成 Word 报告 🔥
Oracle一键安装脚本的 21 个疑问与解答 🔥
Oracle一键巡检脚本的 21 个疑问与解答 🔥
全网首发:Oracle 23ai 一键安装脚本 🔥
Oracle 19C 最新 RU 补丁 19.24 ,一键安装! 🔥
Oracle Linux 6 一键安装 Oracle 11GR2 RACOracle Linux 7.9 一键安装 Oracle 19COracle Linux 8.9 一键安装 Oracle 19C RACOracle Linux 9.4(aarch64) 一键安装 Oracle 19C 🔥
openEuler 20.03 LTS SP4 一键安装 Oracle 19C 🔥
openEuler 22.03 LTS SP4 一键安装 Oracle 19C RACRHEL 7.9 一键安装 Oracle 19C 19.23 RACRedhat 8.4 一键安装 Oracle 11GR2RedHat 9.4(aarch64) 一键安装 Oracle 19C龙蜥 Anolis 7.9 一键安装 Oracle 19C 19.23龙蜥 Anolis OS 8.8 一键安装 Oracle 19CSUSE 15 SP5 一键安装 Oracle 19C统信 UOS V20 1070(a) 一键安装 Oracle 11GR2Ubuntu 22.04 一键安装 Oracle 19CUbuntu 14.04 一键安装 Oracle 19C银河麒麟 Kylin V10 SP3 一键安装 Oracle 19C 🔥
银河麒麟 Kylin V10 SP3 一键安装 Oracle 11GR2 RACOracle DataGuard GAP 修复手册 🔥
优化 Oracle:最佳实践与开发规范DBA 必备:Linux 软件源配置全攻略 🔥
Linux 一键配置时钟同步全攻略 🔥
Starwind 配置 ISCSI 共享存储SUSE 15 SP3 安装 Oracle 19C RAC 数据库达梦 8 数据库安装手册 🔥
Oracle 12CR2 RAC 安装避坑宝典Linux7 安装 Oracle 19C RAC 详细图文教程 🔥
Oracle ADG 搭建 RAC to Single 详细教程Oracle DataGuard GAP 修复手册 🔥
Oracle 分区表之在线重定义AutoUpgrade 快速升级 Oracle 数据库Oracle 数据库巡检命令手册 🔥
Oracle 数据坏块的 N 种修复方式 🔥
数据库 SQL 开发入门教程超全 Linux 基础命令总结 🔥
VMware 虚拟机安装 Linux 系统Linux 安装 MySQL 详细教程教你玩转 SQLPLUS,工作效率提升 200%
感谢您的阅读,这里是 Lucifer三思而后行,欢迎 点赞+关注,我会持续分享数据库知识、运维技巧。