针对 Oracle 数据库损坏的应对措施
Biot Wang 8 年 Oracle 相关开发及数据库运维经验 (Oracle DB, MySQL, Oracle Apps) 11g OCM MySQL OCP 上海 Oracle 用户组核心成员 E-Mail: biot.wang@parnassusdata.com
诗檀公司介绍国内服务电话 :13764045638 诗檀软件专注于数据服务 提供 Oracle, MySQL,MongoDB,Hadoop 管理和咨询服务 提供解决方案并进行安装 升级 迁移及运维 Oracle 数据库救援 ( 基于自主研发的 PRM-DUL) 专业团队 全天候的 DBA 专家服务 24/7/365 DBA 远程支持咨询, 系统管理及特定项目紧急回复 服务客户 现服务客户主要有在线大型电商, 金融机构, 政府部门及企事业单位
数据损坏造成的影响 数据丢失的影响 长时间数据恢复 人为失误 二次灾害的恢复操作 长时间调查原因 直接损害企业
Oracle Maximum Availability MAA 架构 Oracle Maximum Availability Architecture(MAA) Oracle 的最高可用性架构 (MAA) 是基于很多成功案例上的高可用性最佳实践蓝图 MAA 的目的 避免所有的宕机和提供检测与修复的最佳实践 简化配置最优的高可用性架构 不受硬件与操作系统的影响 提供立竿见影的高可用性体验
One of Five Steps for Maximum Availability 解决计划与非计划的 Downtime
高可用性的五个步骤 解决计划与非计划的Downtime Automatic Storage Management, Recovery Manager (RMAN), Oracle Secure Backup 存储故障 数据恢复 备份 Oracle RAC 实例故障 服务器故障 Rolling maintenance 双活: 性能拓展 Active-Passive: 数据库实例在线转 移 合并 Active Data Guard / Data Guard 数据库故障 系统故障 站点故障 数据零丢失 自动故障切换 最佳数据保护 数据库滚动升级 分担只读负载和备份 Flashback GoldenGate 快速时间点恢复 灵活的维护 异构迁移 Schema 迁移 双向和多主机复制 零停机维护 逻辑损坏的细粒度 修复 事务 表 数据库
Oracle 的最高可用性架构 Oracle Maximum Availability Architecture(MAA)
与传统的保护措施对比 导入 Scheme 的通常方式
传统架构中潜伏着数据库损坏的危险 复杂的碎片层结构构成潜在的风险 数据库 Clusterware Volume Manager OS Driver / MultiPath SW I/O-Interface(DsikNW) Storage Utilities 存储管理器 Controller/Cache/DiskShelf 磁盘 检测不到在下层中发生的损坏 通过多层磁盘的写 每层都是由多个厂商提供导致复杂性 每层都有损坏的风险 由于软件中存在 bug 导致的损坏 由于硬件中存在 bug 导致的损坏 磁盘在不匹配时闪存 物理组件故障, 与老化有关的损坏
最新的保护数据的体系结构的概念 考虑对企业的影响 结合数据的重要性 以事务为基础的保护机制体系 基于 Oracle 考虑的数据保护三原则 单个系统 ( 部分双重化 ) 存在无法防止单点故障的危险单纯的复制无法确保数据一致性和准确性无法快速切换和可靠的恢复与重建机制 ( 持续服务 ) 不同模式 ( 同步 / 异步等 ) 创建数据的多个备份当备份数据有所改动时, 将需要通过一个严格控制的接口发生数据损坏时能提供一个机制迅速恢复
防止块损坏
Oracle 数据库的数据损坏应对措施 块的状态 块损坏 数据损坏 ( 比特错误 部分缺失 地址错误 ) 块处于未能正确识别的状态 Lost Write 在数据库端, 它检测到已经写成功并且没有任何 IO 错误, 但是实际上并没有写到磁盘, 依然是原来的块 故障原因示例 系统 bug 另一个应用程序忽然在磁盘上的数据库领域写入信息 存储异常 在高负荷时从 I / O 控制器写入磁盘出现丢失 检测方法 存储网络故障 损坏的数据写入磁盘 读取块时进行校验和验证 由块检查检测出 (ORA-1578) ( 相应的存储的硬盘, 也可以在写入时检测 ) Data Guard 传输的 REDO 数据和备库的数据块的块版本 (SCN) 检测出不匹配 (ORA-752) ( 不能在非 Data Guard 的场合检测到 ) 恢复方法 由块介质恢复修复块 从 ASM 镜像自动修复 从 Active Data Guard 备库自动修复 从 RMAN 备份手动修复 故障切换到备库 重新执行检测到 Lost Write 时或者更早的 SCN 点的事务 ( 由于主库的数据被旧块更新污染 )
预防数据损坏的扩散 为了实现最全面的数据损坏预防和检测 使用 Oracle Data Guard 物理备库 Oracle Data Guard 是在 Write lost 中保护数据防止数据损坏最好的解决方案 在 Data Guard 中的主备库初始化参数设置数据损坏的相关参数
Oracle Database 的最优化损坏检测 数据库块格式
初始化参数 :DB_ULTRA_SAFE 加强块损坏的检测功能 DB_ULTRA_SAFE 参数 指定 OFF,DATA_ONLY,DATA_AND_INDEX 设置以下是每个初始化参数 DB_ULTRA_SAFE = OFF * 默认值 DB_BLOCK_CHECKING = OFF DB_BLOCK_CHECKSUM = TYPICAL DB_LOST_WRITE_PROTECT = NONE DB_ULTRA_SAFE = DATA_ONLY DB_BLOCK_CHECKING = MEDIUM DB_BLOCK_CHECKSUM = FULL DB_LOST_WRITE_PROTECT = TYPICAL DB_ULTRA_SAFE = DATA_AND_INDEX DB_BLOCK_CHECKING = FULL DB_BLOCK_CHECKSUM = FULL DB_LOST_WRITE_PROTECT = TYPICAL DB_BLOCK_CHECKING, 覆盖明确设置 DB_BLOCK_CHECKSUM 或 DB_LOST_WRITE_PROTECT 的情况下所设置的值 DB_BLOCK_CHECKING 参数, 指定是否在数据库更新时执行检查 DB_BLOCK_CHECKING = OFF * 默认值 仅检查 SYSTEM 表空间 DB_BLOCK_CHECKING = LOW 除了检查 SYSTEM 表空间, 它还会检查用户表空间 块在缓冲区被 DML 语句更新时, 检测缓存区的块头 DB_BLOCK_CHECKING = MEDIUM 当设置为 LOW 时, 对除索引组织表外的所有表进行块校验 DB_BLOCK_CHECKING = FULL 设置为 MEDIUM 时, 除了 LOW 级别的检测外, 还包括除了索引之外的所有对象
补充 DB_BLOCK_CHECKSUM 初始化参数, 指定是否计算校验码 Checksum ( 由数据库中存储的所有字节算出来一个数 ) 并写入数据块头和 redo 块 DB_BLOCK_CHECKSUM = OFF(FALSE) 只为 SYSTEM 表空间计算校验码 Check Sum 不对用户表空间计算 DB_BLOCK_CHECKSUM = TYPICAL(TRUE) * 默认值 在写入数据文件前计算 初始化参数 :DB_ULTRA_SAFE 读取数据时, 读取已有块校验码和基于块数据重新计算的校验码进行比较 当计算出的校验码与已有的不匹配时, 将会输出校验码错误 DB_BLOCK_CHECKSUM = FULL 除了执行 TYPICAL 级别的检测外, 还会在 DML 语句产生的变更应用到数据库之前检测校验码, 并在应用变更后重新计算校验码 当计算出的校验码与已有的不匹配时, 将会输出校验码错误 DB_LOST_WRITE_PROTECT 参数指定是否启用写丢失检测 当 IO 子系统确认数据库对 OS 的 write() 调度完成, 但底层存储实际上并未把数据写入磁盘, 就可能发生写丢失 DB_LOST_WRITE_PROTECT = NONE * 默认值 检测写丢失功能无效 DB_LOST_WRITE_PROTECT = TYPICAL 对于 read/write 表空间写丢失检测功能有效 DB_LOST_WRITE_PROTECT = FULL 对于读写表空间和只读表空间的写丢失检测功能有效
定期块损坏检查 RMAN 块损坏检查 Data Guard 另外, 也可以在备库端检测 客户端 VALIDATE 命令 也可以检查没有备份的块损坏 RMAN 服务进程 目标数据库 控制文件 数据文件 归档日志文 件 RMAN 备库 服务进程 控制文件 数据文件 归档日志文 件 RMAN> VALIDATE DATABASE; RMAN> VALIDATE TABLESPACE < 表空间名 >; RMAN> VALIDATE DATAFILE < 文件路径 >; 整个数据库 表空间单位 数据文件单位
RMAN 块损坏检查 默认设置是停止一个检测块损坏 RMAN> -- 执行增量备份 backup incremental level 1 tablespace RTEST1; 启动 backup( 开始时间 : 12-07-23) 分配的通道 ORA_DISK_1 分配的通道 ORA_DISK_2 通道 ORA_DISK_1: 必须在增量备份 level1 启动数据文件备份通道 ORA_DISK_1: 没有再备份设置中指定数据文件输入数据文件编号 =00010 名前 =+DATA/o11g/datafile/rtest1.282.789398885 通道 ORA_DISK_1: start piece 1 at(12-07-23) RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03009: backup 命令 (ORA_DISK_1 on the channel) failed at 07/23/2012 16:22:00 ORA-19566: exceeded limit of 0 corrupt blocks for file (+DATA/o11g/datafile/rtest1.282.789398885) SQL> select * from V$DATABASE_BLOCK_CORRUPTION; FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTION_TYPE ---------- ---------- ---------- ------------------ --------------------------- 10 14980 1 6681461 FRACTURED KROWN#127924:how to deal with if corruption block is detected when you get a backup using RMAN KROWN#68810:The main cause of ORA-1578 and their workarounds
粒度更小的恢复 数据文件恢复表空间 ( 在线 ) 块介质恢复 检测 数据块 单位的损坏 基于逐块恢复 正常块可以连续访问备份区 例子块介质恢复的流程 ASM 镜像? N Active Data Guard? Y Y 自动恢复读取 ASM 镜像正常块从 Active Data Guard 备用站点自动恢复传输正常块 N RMAN? Y 手动恢复读取 RMAN 备份正常块 N 通过备份中体积单位恢复 手动修复介质进行恢复
块介质恢复 ASM 自动修复 (11gR1~) ASM 镜像自动修复损坏的地方, 降低故障率 磁盘写 ASM 可以是两重或者三重 检测到损坏时 (1) 检测到损坏 位置信息 Oracle 实例 (3) 修复说明 Oracle 实例 ASM 实例 ASM 实例 (4) 修复 (2) 从镜像读取 ASM 磁盘组 ASM 磁盘组
Oracle ASM 发生磁盘故障时的举动 可以弥补磁盘缺陷 配置镜像的前提 读操作期间检测到 IO 错误时 从二级自动读取修复 写操作期间检测到 IO 错误时 故障磁盘自动离线处理 快速镜像重新同步 从存活的磁盘端同步最低所需数据 如果不是在一个多存储捆绑环境端写 恢复后新的存储端无法被识别,ASM 可以
块自动介质恢复 通过 Active Data Guard 块修复功能 SQL> SELECT max(c1) FROM tab1; 1 执行 SQL alert 2 检测到块损坏 Requesting Auto BMR for (file# 7, block# 261) 3 从备库请求正常的块 alert Active Data Guard 可用的情况下 Waiting Auto BMR response for (file# 7, block# 261) Auto BMR successful MAX(C1) ----------------- 5000 6 返回无错误的结果 5 自动恢复 4 自动传输备库的正常块 自动修复错误, 并且返回没有错误的结果
使用 RMAN 介质恢复坏块 恢复块恢复 发生的原因有 : 块故障 间歇或随机的 I/O 错误 存储器损坏等以后数据被写入磁盘 它需要恢复一个或多个数据文件中的损坏块 由于只恢复指定的必要块, 所以能缩短恢复时间 只要存在相同的文件, 不必要的对象可以保持在线 数据文件 块介质恢复 在执行检查 RMAN 备份时即使存在块损坏, 它也可以从正常备份集恢复 表空间 ( 在线 ) 备份区
查看坏块 执行坏块恢复 RMAN 可行性坏块恢复方法 怎么进行坏块恢复 修复指定的坏块 V$DATABASE_BLOCK_CORRUPTION 执行 修复已经了解到的所有的坏块 SQL> select * from v$database_block_corruption; FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO ------ -------- ------- ------------------ --------- 6 108 1 0 CHECKSUM SQL> select ename from employees; ERROR: ORA-01578: Oracle 数据库损坏发生在 ( 文件号 6 块号 108) ORA-01110: 数据文件 6: '/u01/app/oracle/oradata/test01.dbf' RMAN> RECOVER DATAFILE 6 BLOCK 108; RMAN> RECOVER CORRUPTION LIST;
数据保护三原则 1. 有多个不同方式的数据副本 一个错误的操作不至于丢失两个副本 2. 当改变副本时严格检查 错误发生时取消连接 3. 如果问题发生, 使用回滚快速恢复
Flashback Database 快速回滚 返回更新 迅速回退到过去的时间点 (point-in-time) 恢复改变的数据库 使数据库回到指定的时间点 不需要恢复数据库的所以备份 迅速 - 不需要几个小时, 几分钟内恢复 容易 一个命令完成恢复 FLASHBACK DATABASE TO 2:05 PM 正确时间 = 错误发生时间 + f(db_size)
ASM 功能使用
弥补存储的不足 在镜像配置前提下 读操作时检查 I/O 错误 Oracle ASM 在磁盘损坏时 再次读取时自动修复坏块 写进程时检查 I/O 错误 损坏磁盘自动离线处理 快速镜像同步 并且从磁盘同步最低需求的数据
写 I/O 错误时的操作 写到数据 C 数据库实例 Y A B ASM C D ASM 实例 E 主分区第二分区 故障组 1 故障组 2 ASM 磁盘组 A E 磁盘 1 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 C B B E C
磁盘 8 发生写错误 数据库实例 Y A B 写 I/O 错误时的操作 需要磁盘离线 ASM 文件 Y D E ASM 实例 主分区第二分区 写入成功 ASM 磁盘组 A E 磁盘 1 故障组 1 故障组 2 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 Y B B E C 写入失败
使磁盘 8 离线 成功 数据库实例 Y A B 写 I/O 错误时的操作 需要磁盘离线 ASM 文件 Y D E ASM 实例 主分区 第二分区 故障组 1 故障组 2 离线 ASM 磁盘组 A E 磁盘 1 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 Y B B E C
通过高速镜像同步实现冗余配置 成功 数据库实例 A B 写 I/O 错误时的操作 ASM 文件 Y D E ASM 实例 ン主分区第二分区 ASM 磁盘组 A E 磁盘 1 故障组 1 故障组 2 Y B 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 同步 B E C Y 变更为 online
通过 rebalance 冗余恢复 数据库实例 A B 写 I/O 错误时的操作 ASM 文件 Y D E ASM 实例 主分区第二分区 故障组 1 故障组 2 削除 ASM 故障组 A E Y 磁盘 1 磁盘 2 D B 重新复制数据到另一个磁盘 D 磁盘 5 Y A 磁盘 6 磁盘 3 磁盘 4 磁盘 7 磁盘 8 冗余恢复 B E E C
读到数据 C 读 I/O 错误时的操作 数据库实例 C A B ASM 文件 C D ASM 实例 E 主分区第二分区 主分区的读错误 ASM 故障组 磁盘 1 A E 故障组 1 故障组 2 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 C B B E C 第二分区读成功
读 I/O 错误时的操作 输出到日志 Oracle 检测到 I/O 错误时 自動 I/O 镜像 稍后执行镜像 I/O 对应用程序透明 ( 没有错误 ) DB 的告警日志 ( 节选 ) ORA-27061: 非同步 I/O 等待失败 WARNING: failed to read mirror side 1 of virtual extent 0 logical extent 0 of file 263 in group 3 from disk 2 allocation unit 50908; if possible, will try another mirror side NOTE: successfully read mirror side 2 of virtual extent 0 logical extent 1 of file 263 in group 3 from disk 1 allocation unit 316 自动从镜像读取
数据 C 的坏块修复 成功 DB 实例 C A B 读 I/O 错误时的操作 块修复需求 ASM 文件 C D E ASM 实例 故障组 1 故障组 2 : 主分区 : 第二分区 快修复 ASM 磁盘组 A E 磁盘 1 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 B??? 从正常块重写数据 B E C
数据块 C 的修复 ( 重新执行 ) DB 实例 C A 发生 I//O 错误时的操作 B 块修复要求 ASM 文件 C D E ASM 实例 故障组 1 故障组 2 : 主分区 : 第二分区 块修复 ASM 磁盘组 A E??? 磁盘 1 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 再次重写入相同磁盘上的另一个位置 B 块修复失败 B E C
磁盘 3 在离线状态 ( 快速镜像同步操作 ) 块修复要求 DB 实例 C A B 读 I/O 错误时的操作 ASM 文件 C D E ASM 实例 磁盘自身离线 故障组 1 故障组 2 : 主分区 : 第二分区 ASM 磁盘组 A E 磁盘 1 磁盘 2 磁盘 5 磁盘 6 D D A 磁盘 3 磁盘 4 磁盘 7 磁盘 8 B B??? E C
总结
防止块损坏 使用 Oracle Automatic Storage Management (Oracle ASM) 防止存储故障 使用 Oracle ASM HIGH REDUNDANCY 的最佳损坏修复 Oracle ASM 磁盘组冗余, 如果有扇区损坏, 返回介质检查错误 使用 Oracle Active Data Guard 自动块修复 配置 Data Recovery Advisor, 自动诊断数据损坏 逻辑坏块的快速时间点恢复 ( 多数情况由于人为错误 ), 主库故障切换后的快速修复, 闪回数据库技术 通过 Recovery Manager (RMAN) 实现备份和恢复计划 RMAN 的 BACKUP VALIDATE CHECK LOGICAL... 定期扫描用来检查错误 RMAN 和 Oracle Secure Backup 是另外的块检查在使用在备份和修复操作时
检测并监控块损坏 监控错误和数据库告警 Enterprise Manager 用来监控所有目标的可用性 你能查看所有目标从一个视图 HA Console 查看 V$DATABASE_BLOCK_CORRUPTION 视图, 当块损坏或修复时自动更新 通过 Data Recovery Advisor 自动诊断数据故障, 提供合适的修复选项, 并且在用户请求时修复 使用 Data Guard 检测物理坏块, 检测写丢失 通过利用 Active Data Guard 的自动块介质恢复, 自动修复在主库或备库的坏块 使用 SQL*Plus 检测数据文件损坏和块内损坏 ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE SQL*Plus 语句 识别损坏后, 重建表, 执行其他操作
参阅 Oracle Database 高可用性最好用 11g 版本 2 (11.2) Master Note for Handling Oracle Database Corruption Issues [1088018.1] Best Practices for Corruption Detection, Prevention, and Automatic Repair - in a Data Guard Configuration [1302539.1]
附录
块损坏类型 从磁盘读时检测到块损坏 ( 例如前后不搭配等 ) 内部重复读时, 如果错误信息不能被读, 知道正确信息被标记从磁盘读没有问题 随后检查出一个错误 它是内部块恢复 ( 从磁盘读取 redo) 两次, 我们仍然标记两次以防不能被转储 何时检查错误 通过 db_block_checking 和 _check_block_after_checksum 设置 导出数据块 通过损坏标记, 这个块有 DBWR 导出 介质损坏同时从磁盘标记, 因为没有任何更新, 没有脏缓冲区 Media Corrupt 同时被标记到磁盘 Soft Corrupt 可能在脏缓冲后被标记 损坏标记写入到磁盘
损坏情况 没有 OS 错误的 ORA-1578 错误发生 1. 不是 Oracle 导致的损坏情况 1-1. 如果 Oracle 数据库无法识别一个大小不正常的数据块, 物理块没有问题, 当你执行 select 语句时会报 ora-1587 的错误 [ 损坏情况 ] 内存中的错误信息 最后 512 位的块 ffff ffff aaaa aaaa 5555 5555 0000 0000 重复 异常值 1-2. 许多块错误 个别的 相同物理位置但逻辑位置不同的块损坏转储数据块的备份, 如果你操作了多个数据块,ora-1578 c 错误发生 [ 损坏情况 ] 所有块头的 1187 位损坏 1 bit 异常值 oracle 管理的数据 行头区或列头区发现异常的值 2. Oracle 可能损坏情况 2-1. 多个不同物理位置的损坏 逻辑损坏 例如 ( 不同的物理位置损坏, 损坏点是行头 3. Oracle 问题未知的情况 3-1. 多个块被破坏 个别的 物理位置相同的块错误 逻辑块错误 应用程序停止 [ 损坏状况 ] 所有破坏的数据块头已经是一个异常的值
专注于数据诗檀软件软件, 方案, 服务供应商