你的Oracle生产数据库遭受过哪些迫害?

背景

在我十多年的数据库运维经历中,遇到了各种各样的生产数据库数据丢失事件。我相信同行们也听说过许多类似的案例。数据丢失不仅发生在核心生产系统中,外围系统也同样面临这样的风险。通常我们可能认为某些数据库不那么重要,但一旦数据丢失,它们的重要性就会突然凸显。在这种情况下,恢复数据往往需要耗费大量资金。

谈谈我经历过的数据库被破坏的案例

在深入讨论之前,我先总结一些工作中遇到的数据丢失情况,这里不包括由于硬件损坏导致的情况。

Oracle数据库案例:

  1. 核心表被truncate

  2. 数据表被drop

  3. 某个数据文件被删除

  4. redo文件被误删除

  5. undo文件损坏

  6. 数据文件存在坏块

  7. 恢复虚拟机快照导致数据文件不一致

  8. 数据库被勒索病毒加密

Sqlserver数据库案例:

  1. 维护镜像的时候误把生产数据库drop

  2. 数据表被drop

  3. 数据表被truncate

  4. 备库数据少,强制切换成主库,反向同步的时候将生产数据覆盖造成数据丢失

  5. 数据库被勒索病毒加密

DB2数据库案例:

1.活动日志被删除

以上是我在数据库运维领域多年工作经验中遇到的一些数据库受损案例。实际上,数据库遭受破坏的情况要比我所经历的多得多。这里只是分享了我个人遭遇的一些故障实例。

鉴于篇幅长度,本文将专注于探讨Oracle数据库损坏后的恢复策略。

针对oracle数据库破坏的案例如何进行恢复呢?

本次我们只讨论数据库没有正常备份的情况下的恢复。

01 、数据表被truncate

TRUNCATE 命令的工作原理是通过修改表的元数据来迅速清空表内容,这种方式比delete删除数据的效率要高得多。此外,TRUNCATE 不会产生 REDO 日志,这意味着一旦执行了 TRUNCATE 操作,就无法通过回滚来撤销。在数据库内部,TRUNCATE 仅仅是将表标记为"空",实际上并没有从数据文件中删除数据,因此数据在物理层面上仍然保留。

恢复方法:

language 复制代码
当核心表被 TRUNCATE 操作后,应立即关闭数据库以避免数据覆盖。并及时备份受影响数据文件,以下是应对策略:
1. 数据库闪回(不推荐):如果启用了数据库闪回功能,理论上可以将整个数据库回滚到 TRUNCATE 发生之前的状态。但这不是个好方法,因为这会导致其他表的数据丢失。此外,出于性能考虑,生产环境的数据库很少开启闪回功能。
2. 第三方恢复工具:可以考虑使用如 DUL、ODU 等第三方恢复工具。这些工具的基本原理是直接从 Oracle 数据文件中提取数据,并将其转换为 DMP 或文本格式。然而,需要注意的是,这些工具通常是收费的。

02、数据表被drop

drop表分为普通drop和指定purge子句。

  1. 当您在执行 DROP TABLE 语句时未包含 PURGE 子句,该表及其相关依赖对象将被转移到回收站,而不是立刻被永久从数据库中移除。这表示尽管表在逻辑层面上被删除,它的数据实际上仍旧保存在数据库的物理存储设备上,并且被标记为删除状态。如果需要,你可以通过特定的语句来恢复这些表。

    FLASHBACK TABLE my_table TO BEFORE DROP;

2.如果使用 DROP TABLE 命令并附加了 PURGE 子句来删除表,该表将不会进入回收站,而是会被直接从数据库中移除。在这种情况下,应立即备份该表所在的表空间的所有数据文件。之后,可以尝试使用 DUL、ODU等第三方工具来恢复数据。

03、某个数据文件被删除(linux)

在处理删除数据文件的情况时,可以区分为以下两种场景:

  1. 未重启数据库:如果数据文件被删除后数据库没有重启,那么文件仍有可能被恢复。因为在 Linux 系统中,即使文件被删除,只要有进程持有该文件的句柄,文件内容仍然存在。可以利用 Linux 文件句柄来恢复数据文件。方法如下:
language 复制代码
[oracle@host01 PROD4]$ ps -ef |grep dbw
oracle   13286     1  0 10:42 ?        00:00:01 ora_dbw0_PRODCDB
oracle   13678     1  0 10:43 ?        00:00:00 ora_dbw0_PROD4
oracle   13913     1  0 10:43 ?        00:00:00 ora_dbw0_PROD5
oracle   14168     1  0 10:43 ?        00:00:00 ora_dbw0_DB11G
oracle   20727 13136  0 14:54 pts/0    00:00:00 grep dbw
[oracle@host01 PROD4]$ ll /proc/13678/fd
total 0
lr-x------ 1 oracle oinstall 64 Aug 17 18:09 0 -> /dev/null
l-wx------ 1 oracle oinstall 64 Aug 17 18:09 1 -> /dev/null
lr-x------ 1 oracle oinstall 64 Aug 17 18:09 10 -> /u01/app/oracle/product/12.1.0/dbhome_1/rdbms/mesg/oraus.msb
l-wx------ 1 oracle oinstall 64 Aug 17 18:09 2 -> /dev/null
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 256 -> /u01/app/oracle/oradata/PROD4/control01.ctl
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 257 -> /u01/app/oracle/fast_recovery_area/PROD4/control02.ctl
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 258 -> /u01/app/oracle/oradata/PROD4/system01.dbf (deleted)
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 259 -> /u01/app/oracle/oradata/PROD4/sysaux01.dbf
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 260 -> /u01/app/oracle/oradata/PROD4/undotbs01.dbf
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 261 -> /u01/app/oracle/oradata/PROD4/example01.dbf
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 262 -> /u01/app/oracle/oradata/PROD4/users01.dbf (deleted)
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 263 -> /u01/app/oracle/oradata/PROD4/temp01.dbf
lr-x------ 1 oracle oinstall 64 Aug 17 18:09 3 -> /dev/null
lr-x------ 1 oracle oinstall 64 Aug 17 18:09 4 -> /u01/app/oracle/product/12.1.0/dbhome_1/rdbms/mesg/oraus.msb
lr-x------ 1 oracle oinstall 64 Aug 17 18:09 5 -> /proc/13678/fd
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 6 -> /u01/app/oracle/product/12.1.0/dbhome_1/dbs/hc_PROD4.dat
lrwx------ 1 oracle oinstall 64 Aug 17 18:09 9 -> /u01/app/oracle/product/12.1.0/dbhome_1/dbs/lkPROD4
[oracle@host01 PROD4]$ cp /proc/13678/fd/258 /u01/app/oracle/oradata/PROD4/system01.dbf
[oracle@host01 PROD4]$ cp /proc/13678/fd/262 /u01/app/oracle/oradata/PROD4/users01.dbf
  1. 已重启数据库:如果在删除数据文件后重启了数据库实例,而且没有备份,那么情况会比较复杂。在没有使用磁盘恢复软件的前提下,可能需要依赖其他备份或恢复策略来尝试恢复数据。

04、redo文件损坏或被误删除

Oracle Redo损坏分四种情况:unused, inactive, active, 和 current。恢复思路如下:

  1. 如果损坏的是非current状态的redo log,你可以尝试以下步骤:

注意不需要重启数据库,只需要把日志清除即可。执行命令:

language 复制代码
SQL> alter database clear unarchived logfile group 2;
SQL> alter system switch logfile;  
  1. 对于current状态的redo日志损坏,恢复过程可能更为复杂。这可能涉及到设置隐含参数,并且在处理过程中可能会遇到ORA-00600错误。恢复方法可能包括使用poke、event、gdb等技术来推进SCN。由于不同版本的数据库处理方式不同,且过程相对复杂,这里不展开阐述,建议咨询专业人士。

05、undo文件损坏

出现undo损坏通常会导致数据库回滚操作异常,这可能会引起SMON进程崩溃,从而导致整个数据库实例的崩溃。 这种情况下,数据库通常无法正常启动,需要采取特殊的恢复措施。

处理方式:

  1. 可以通过设置10531 event,禁止smon进程进行回滚

  2. 打开数据库,创建新的undo表空间,并设置为默认表空间

  3. 删除旧的表空间,但是往往原undo表空间仍然存在活跃的undo段

  4. 查询相关视图,获取所有原undo表空间仍活跃的undo段

language 复制代码
select status,segment\_name from dba\_rollback\_segs where status not in ('OFFLINE') and tablespace\_name='UNDOTBS1'; 
  1. 添加隐含参数至pfile参数文件中,跳过以上查出的所有undo段

  2. 关闭数据库,以修改后的pfile文件进行启动数据库

  3. 删除旧的表空间及其的所有数据!

06、数据文件存在坏快

数据文件出现坏块是一种相对常见的问题。处理此问题时,首先需要评估坏块的数量,如果发现大量坏块,则可能表明存在较大的硬件损坏风险。

另外需要确定坏块所属的数据库对象类型。如果坏块属于索引,则可以通过重建索引来解决问题。

如果坏块属于表,则需要采取更为谨慎的恢复步骤:

使用Oracle Data Pump导出表数据。

设置事件10231,以便在导出过程中跳过坏块。

删除并重新创建表,以清除坏块影响。

导入之前导出的数据,恢复表内容。

请注意,这些步骤可能需要根据您的具体数据库版本和环境进行调整。在执行任何操作之前,建议备份受影响的数据。

07、虚拟主机快照恢复

虚拟化服务器数据文件存放在本地盘和外挂盘,快照恢复只还原了本地数据文件,导致数据文件scn不一致,相信这也是比较罕见的案例。

恢复方法:

1.12c以上可以尝试推进scn。

2.可以通过bbed更改数据库文件头使得所有数据文件保持一致,read only打开数据库并exp导出。重建数据库,导入数据。

3.如果前面两种方法都不行可以用第三方恢复工具:比如dul、ODU等第三方软件逻辑导出表。

08、数据库被勒索病毒加密

这个相信很多同行也碰到过,这个没辙,防勒索措施做好。

总结建议

面对生产数据库,我们必须持有敬畏之心,并采取周全的数据保护措施。 基于此,我提出以下建议:

1、定期进行数据库备份:确保定期执行逻辑备份和物理备份,并将备份文件传输至远程服务器以确保数据安全。

2、部署有效的数据库容灾系统:建立并维护一个完善的数据库容灾系统,并定期监控其运行状态。这样,在生产系统受损时,容灾系统能够迅速接管,保障业务连续性。

3、安装防勒索软件:为了进一步保护数据库免受恶意软件的威胁,建议部署专业的防勒索软件,以防止数据被加密和勒索。

Q(延伸问题):

可能有朋友会问用RMAN不就好了吗?

A: 虽然定期的物理备份(RMAN)对于数据保护至关重要,但逻辑备份也不可或缺。 逻辑备份的优势在于,当单个表遭受损坏时,可以利用逻辑备份快速恢复该表,而无需恢复整个数据库。这样做可以显著减少业务中断的时间,提高恢复效率。因此,逻辑备份是一个补充物理备份的有效策略,它为特定情况下的快速数据恢复提供了更多的灵活性和便利。

相关推荐
月光水岸New1 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6751 小时前
数据库基础1
数据库
我爱松子鱼1 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo2 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
Rverdoser3 小时前
【SQL】多表查询案例
数据库·sql
Galeoto3 小时前
how to export a table in sqlite, and import into another
数据库·sqlite
人间打气筒(Ada)3 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231113 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql
喝醉酒的小白3 小时前
PostgreSQL:更新字段慢
数据库·postgresql
敲敲敲-敲代码3 小时前
【SQL实验】触发器
数据库·笔记·sql