热衷于分享各种干货知识,大家有想看或者想学的可以评论区留言,秉承着“开源知识来源于互联网,回归于互联网”的理念,分享一些日常工作中能用到或者比较重要的内容,希望大家能够喜欢,不足之处请大家多提宝贵地意见,我们一起提升,守住自己的饭碗。
Oracle数据库坏块问题犹如一颗隐藏的定时炸弹,随时可能引发数据访问异常与系统故障。接下来主要分享一些常见的 Oracle 坏块的故障现象、原因、定位思路以及通用应急维护方法。
一、故障现象
Oracle 数据文件中的坏块分为物理坏块和逻辑坏块。
“物理坏块(介质坏块),其块格式本身损坏,内部数据毫无意义;
逻辑坏块则是数据在逻辑层面存在问题,比如索引块的索引值未按从小到大排列。
当 Oracle 尝试访问坏块时,常出现 ORA - 1578 类型错误或 ORA - 600[17xxx]错误。
二、故障原因
(一)物理坏块
多由内存、OS、IO 子系统以及硬件问题所致,像硬件或防火墙 I/O 问题。其中,大部分硬件问题源于物理磁盘损坏或磁盘控制器故障,此类问题通常会在操作系统日志中有所体现。
(二)逻辑坏块
主要由 Oracle Bug 等软件问题引发,如操作系统或 Oracle 软件自身的问题。在读写坏块时,虽操作系统读写文件看似正常,但会伴随内部错误与存储器内容清除。产生软件问题的根源包括:数据库或操作系统性能低下、频繁宕机、数据库运行时误操作终止 Oracle 后台进程、内核级别问题以及在不可恢复或未记录重做日志的数据库中执行恢复操作(常导致 ORA - 1578 错误)。
三、定位思路
(一)硬件与软件问题判别
仔细检查操作系统日志文件,以确定是否为硬件问题,同时可请求存储厂商对存储设备进行检查确认。
(二)受影响数据库对象查找
通过执行特定 SQL 语句获取表空间、段类型、段拥有者、坏块对象名等信息。
SQL>SELECT tablespace_name, segment_type, owner, segment_name FROM dba_extents WHERE file_id = &AFN and &BL between block_id AND block_id + blocks - 1;
说明:其中 &AFN 需替换为报错的 file 号,&BL 需替换为报错的 block 号。
例如,对于错误“ORA - 01578: ORACLE data block corrupted (file # 2, block # 3332) ORA - 01110: data file 2: '/dev/vg_data/rring_data20'”,&AFN 应设为 2,&BL 应设为 3332。此案例来源于网络。
(三)损坏数据块确定
采用多种方式检查数据块,如 DBVERIFY、RMAN、EXP、全表扫描、analyze table 等。
四、通用应急维护方法
(一)判断坏块盘区及问题性质
首先判定出现坏块的盘区,并确定是永久性问题还是临时性问题。
(二)硬件问题排查与修复
排查硬件故障,一旦发现有故障的硬件,及时进行更换。
(三)依据坏块段类型处理
根据坏块段类型,运用不同方法查找受影响的数据库对象,并确定适宜的恢复方法。
CACHE 类坏块:受影响对象需重新检查 SQL 语句与参数正确性。恢复方法为恢复数据库。 CLUSTER 类坏块:
SQL> SELECT owner, table_name FROM dba_tables WHERE owner = '&OWNER' AND cluster_name = '&SEGMENT_NAME';
查询集群包含的表数。若 &OWNER 为 SYS,则可能需恢复数据库;若为非数据字典的集群,则需重建集群。
3. INDEX PARTITION 类坏块:
SQL> SELECT partition_name FROM dba_extents WHERE file_id = &AFN AND &BL BETWEEN block_id AND block_id + blocks – 1;
查询索引分区,然后执行SQL:
SQL> ALTER INDEX index_name REBUILD PARTITION partition_name;
索引类坏块:查询索引对应的表信息:
SQL> SELECT table_owner, table_name FROM dba_indexes WHERE owner = '&OWNER' AND index_name = '&SEGMENT_NAME';
查询主键或唯一性约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE owner = '&TABLE_OWNER' AND constraint_name = '&INDEX_NAME';
查询外键约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE r_owner = '&TABLE_OWNER' AND r_constraint_name = '&INDEX_NAME';
若 &OWNER 为 SYS,则可能需恢复数据库;若为非数据字典索引,则先删除索引,再重建。
表分区类坏块:
SQL> SELECT partition_name FROM dba_extents WHERE file_id = &AFN AND &BL BETWEEN block_id AND block_id + blocks – 1;
查询分区表。若所有坏块在同一分区,可通过与空表交换恢复,具体参考表的恢复方法。
7. 数据表类坏块:查询表对应的索引信息:
SQL> SELECT owner, index_name, index_type FROM dba_indexes WHERE table_owner = '&OWNER' AND table_name = '&SEGMENT_NAME';
查询主键约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE owner = '&TABLE_OWNER' AND constraint_name = '&INDEX_NAME' AND constraint_type = 'P';
查询外键约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE r_owner = '&TABLE_OWNER' AND r_constraint_name = '&INDEX_NAME';
若 &OWNER 为 SYS,则可能需恢复数据库;若为非数据字典表,则可恢复或抢救数据后重建表,或者使用 DBMS_REPAIR 工具标记坏块使程序跳过。
LOB 索引类坏块:查询出LOB对应的表:
SQL> SELECT table_name, column_name FROM dba_lobs WHERE owner = '&OWNER' AND index_name = '&SEGMENT_NAME';
查询表对应的索引信息:
SQL> SELECT owner, index_name, index_type FROM dba_indexes WHERE table_owner = '&OWNER' AND table_name = '&SEGMENT_NAME';
查询主键约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE owner = '&TABLE_OWNER' AND constraint_name = '&INDEX_NAME' AND constraint_type = 'P';
查询外键约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE r_owner = '&TABLE_OWNER' AND r_constraint_name = '&INDEX_NAME';
若 &OWNER 为 SYS,则可能需恢复数据库;若为非数据字典表,则恢复或抢救数据后重建表,一般不采用标记坏块方法,除非该表后续无 DML 操作。
LOB 区段类坏块:查询表对应的索引信息:
SQL> SELECT owner, index_name, index_type FROM dba_indexes WHERE table_owner = '&OWNER' AND table_name = '&SEGMENT_NAME';
查询主键约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE owner = '&TABLE_OWNER' AND constraint_name = '&INDEX_NAME' AND constraint_type = 'P';
查询外键约束条件:
SQL> SELECT owner, constraint_name, constraint_type, table_name FROM dba_constraints WHERE r_owner = '&TABLE_OWNER' AND r_constraint_name = '&INDEX_NAME';
若 &OWNER 为 SYS,则可能需恢复数据库;若为非数据字典表,则恢复或抢救数据后重建表,或者标记坏块(无法使用 DBMS_REPAIR 工具)使程序跳过。
临时表空间类坏块:
SQL> SELECT count(*) FROM dba_users WHERE temporary_tablespace = '&TABLESPACE_NAME';
确认是否临时表空间出现问题。若是,则只需重建一个临时表空间,替换原有临时表空间后删除原来的临时表空间。
(四)恢复机制选择
依据确定的恢复方法,挑选合适的恢复机制,如完整恢复(可针对块、数据文件、数据库)、重建索引、恢复表中数据(可使用 10231 事件绕过坏块表提取数据、使用 EXP 导出 10231 事件跟踪的表中数据、使用 DBMS_REPAIR 标记坏块表提取数据、使用 EXP 导出 DBMS_REPAIR 标记的表中数据)等,每种恢复机制均有其特定的操作步骤,需参照对应步骤详细执行。
综上所述,Oracle 坏块问题的处理需要数据库管理员具备敏锐的洞察力、严谨的分析能力以及熟练的操作技能。通过对故障现象、原因的精准把握,高效的定位思路以及完善的应急维护方法的运用,能够最大程度降低坏块问题对数据库系统的影响,保障数据的完整性与系统的稳定性,为企业的业务连续性提供坚实的支撑。
更深入的大家可以看这篇文章,转自陈举超大佬。
文中的概念来源于互联网,如有侵权,请联系我删除。
欢迎关注公众号:小周的数据库进阶之路,一起交流数据库、中间件和云计算等技术。如果觉得读完本文有收获,可以转发给其他朋友,大家一起学习进步!感兴趣的朋友可以加我微信,拉您进群与业界的大佬们一起交流学习。