关于Oracle数据恢复的两个临界点

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 有的网友对我之前写的一篇技术博文中的描述提出了疑问,http://blog.itpub.net/23718752/viewspace-1436965/ 其中的主要意思是:oracle中采用了undo+redo机制来作为数据恢复的基石,数据的恢复是通过前后台结合...
有的网友对我之前写的一篇技术博文中的描述提出了疑问,http://blog.itpub.net/23718752/viewspace-1436965/
其中的主要意思是: oracle中采用了undo+redo机制来作为数据恢复的基石,数据的恢复是通过前后台结合来实现的,在缓存级别,通过dbwr,能够把修改后的数据块刷入数据文件,这是一个异步的过程,不会因为发生数据变更就马上写入数据文件,同时存在log buffer,能够通过log buffer生成redo日志,最后通过lgwr把这部分变更刷到redo 日志,在这个过程中lgwr负责了保持数据完整性的任务,保证了数据不会丢失。
这句话再浓缩一下就是Oracle能够保证对于commit操作的数据都能够成功恢复。
今天可以通过两个特殊的场景来解释一下。
场景1: 模拟Oracle ACID的异常情况,事务已经提交,但是redo log buffer还没有写到磁盘
第一个场景就是把lgwr写入redo的操作影响放大,操作时间延长。这个可以参考 Jonathan Lewis的博客。https://jonathanlewis.wordpress.com/2011/08/19/redo-2/
这个场景被称为模拟Oracle ACID的异常情况,事务已经提交,但是redo log buffer还没有写到磁盘.我们来看看再下结论。
window #1: --打开一个窗口1,然后创建一个临时表t1
create table t1(n1 number);
insert into t1 values(1);
commit;

然后通过v$process查到对应的LGWR pid
n1@TEST11G>  select v$process.pid  from v$process  where pname='LGWR';
       PID
----------
        11

window #2 --打开窗口2,开启oradebug,绑定到lgwr上
sys@TEST11G> oradebug setorapid 11
Oracle pid: 11, Unix process pid: 11767, image: oracle@oel1 (LGWR)
sys@TEST11G> oradebug suspend 
Statement processed.

window #1--然后回到窗口1,做一个dml操作,commit
n1@TEST11G> update t1 set n1 = 2;
1 row updated.
n1@TEST11G> commit;

这个时候commit操作会一直hang在那儿


window #3  --开启第3个窗口,然后查看是否更新后的值已经可以成功查看。
sys@TEST11G> select count(*)from n1.t1;
  COUNT(*)
----------
          2
1 row selected. 

这个时候我们马上做类似断电的场景,shutdown abort
sys@TEST11G> shutdown abort
ORACLE instance shut down.

这个时候如果观察第一个窗口,会发现下面的错误,可以得知对应的session已经被强制释放了。
n1@TEST11G> commit;
ERROR:
ORA-03114: not connected to ORACLE
commit
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 15180
Session ID: 125 Serial number: 84

然后我们重启数据库
idle> startup
ORACLE instance started.
Total System Global Area  435224576 bytes
Fixed Size                  1337044 bytes
Variable Size             272632108 bytes
Database Buffers          155189248 bytes
Redo Buffers                6066176 bytes
Database mounted.
Database opened.

这个时候再查看数据,就会发现更新后的值已经丢失了。
idle> select *from n1.t1;
        N1
----------
         1
1 row selected.
对于这个问题,网上大家也是各有所见,有的说commit没有成功返回,就不算是一个完整的事务,没有恢复是可以理解的。有的说,这个是Oracle对于数据恢复的一个灰色地带。
我的意见是首先这是一个测试,把整个过程放慢,影响放大了,整个过程处于一个快要提交但是还没有提交的边界。这部分内容还是没有写入redo中的。只是从缓存中完成了整个数据变更的过程。
commit在这个放慢的临界点没有完成,严格意义上应该不属于一个完整的事务。

上面这个案例是通过debug的方式来做的,我们来用另外一个场景来模拟一下,看看实际中可能碰到的场景如果出现类似问题,redo是否依旧可靠。

场景2: 模拟Oracle 归档满的临界点,事务是否依然能够成功提交,成功恢复
我们来模拟在归档日志满的时候,无法再写入redo,依旧可以成功commit,但是数据是否能够成功恢复的案例。
我们在测试环境简单模拟一下归档满的临界点,查看磁盘空间,归档所在的挂载点还有6G的可用空间。
[ora11g@oel1 archivelog]$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3              30G   23G   6.0G  79% /u02
none                  690M  104K  690M   1% /var/lib/xenstored

我们来使用dd来创建一些dummy文件。
[ora11g@oel1 archivelog]$ time dd if=/dev/zero bs=1M count=5000 of=direct_5000M
5000+0 records in
5000+0 records out
5242880000 bytes (5.2 GB) copied, 224.21 seconds, 23.4 MB/s
real    3m44.222s
user    0m0.024s
sys     0m20.317s
创建后再逐步缩小范围。
[ora11g@oel1 archivelog]$ time dd if=/dev/zero bs=1M count=1000 of=direct_1000M
[ora11g@oel1 archivelog]$ time dd if=/dev/zero bs=1M count=100 of=direct_100M
最后发现空间都被占用完了。
[ora11g@oel1 archivelog]$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3              30G   29G     0 100% /u02
直到没有空间可用我们才收手。
[ora11g@oel1 archivelog]$ time dd if=/dev/zero bs=1M count=10 of=direct_10M
dd: writing `direct_10M': No space left on device
1+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000909 seconds, 0.0 kB/s
最后生成的dd文件如下:
-rw-r----- 1 ora11g dba   33485824 May 20 15:30 1_4_879784710.dbf
-rw-r--r-- 1 ora11g dba 5242880000 May 20 15:36 direct_5000M
-rw-r--r-- 1 ora11g dba 1048576000 May 20 15:37 direct_1000M
-rw-r--r-- 1 ora11g dba  104603648 May 20 15:38 direct_100M
-rw-r--r-- 1 ora11g dba           0 May 20 15:39 direct_10M

使用sqlplus报出下面的错误,这样我们就可以开始这个临界点的测试了。
sys@TEST11G> conn n1/n1
ERROR:
ORA-00257: archiver error. Connect internal only, until freed.
sys@TEST11G> create table aa as select *from cat;
Table created.
sys@TEST11G> insert into aa select *from aa;
4856 rows created.
sys@TEST11G> commit;
Commit complete.
sys@TEST11G> insert into aa select *from aa;
9712 rows created.
sys@TEST11G> commit;
Commit complete.
sys@TEST11G> select count(*)from aa;
  COUNT(*)
----------
     19424

可以看到这个过程中还是能够成功commit数据的。查取更新都可以使用顺利完成。
可以再开一个窗口运行alter system switch logfile做几个日志刷新。发现这个时候日志刷新也hang住了。

看看alert日志,发现已经提示空间不够,无法生成归档日志了。
Wed May 20 15:43:59 2015
Errors in file /u02/ora11g/diag/rdbms/test11g/TEST11G/trace/TEST11G_arc1_13247.trc:
ORA-19504: failed to create file "/u02/ora11g/flash_recovery_area/TEST11G/archivelog/1_5_879784710.dbf"
ORA-27044: unable to write the header block of file
Linux Error: 28: No space left on device
Additional information: 3
ARC1: Error 19504 Creating archive log file to '/u02/ora11g/flash_recovery_area/TEST11G/archivelog/1_5_879784710.dbf'
ARCH: Archival stopped, error occurred. Will continue retrying
Non critical error ORA-00001 caught while writing to trace file "/u02/ora11g/diag/rdbms/test11g/TEST11G/trace/TEST11G_arc1_13247.trc"
Error message: 
Writing to the above trace file is disabled for now on...
ORACLE Instance TEST11G - 

这个时候我们继续模拟一个断电场景shutdown abort.
原有的日志刷新也会自动终止。
ERROR:
ORA-03114: not connected to ORACLE
alter system switch logfile
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 9686
Session ID: 125 Serial number: 480

如果这个时候启动到open阶段就会自动停止,原因就是归档空间的问题。
我们做一个小改动。腾出一小部分空间来。
[ora11g@oel1 archivelog]$ rm direct_100M
然后再次尝试启动数据库就没有问题了
idle> alter database open;
Database altered.
这个时候查看归档路径下,会发现已经生成了3个归档文档
-rw-r--r-- 1 ora11g dba 5242880000 May 20 15:36 direct_5000M
-rw-r--r-- 1 ora11g dba 1048576000 May 20 15:37 direct_1000M
-rw-r--r-- 1 ora11g dba          0 May 20 15:39 direct_10M
-rw-r----- 1 ora11g dba       2048 May 20 15:55 1_6_879784710.dbf
-rw-r----- 1 ora11g dba     204800 May 20 15:55 1_5_879784710.dbf
-rw-r----- 1 ora11g dba    1808384 May 20 15:55 1_7_879784710.dbf
这个时候发现对于这些信息变更已经成功刷新到了归档中。这样就为数据恢复提供了强有力的基石,保证了数据在commit成功的情况下能够成功恢复。



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
存储 Oracle 关系型数据库
数据库数据恢复—ORACLE常见故障的数据恢复方案
Oracle数据库常见故障表现: 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE ASM存储破坏。 3、ORACLE数据文件丢失。 4、ORACLE数据文件部分损坏。 5、ORACLE DUMP文件损坏。
116 11
|
2月前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—Oracle数据库文件有坏快损坏的数据恢复案例
一台Oracle数据库打开报错,报错信息: “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。管理员联系我们数据恢复中心寻求帮助,并提供了Oracle_Home目录的所有文件。用户方要求恢复zxfg用户下的数据。 由于数据库没有备份,无法通过备份去恢复数据库。
|
2月前
|
存储 Oracle 关系型数据库
oracle数据恢复—Oracle数据库文件大小变为0kb的数据恢复案例
存储掉盘超过上限,lun无法识别。管理员重组存储的位图信息并导出lun,发现linux操作系统上部署的oracle数据库中有上百个数据文件的大小变为0kb。数据库的大小缩水了80%以上。 取出&并分析oracle数据库的控制文件。重组存储位图信息,重新导出控制文件中记录的数据文件,发现这些文件的大小依然为0kb。
|
1月前
|
存储 Oracle 关系型数据库
服务器数据恢复—华为S5300存储Oracle数据库恢复案例
服务器存储数据恢复环境: 华为S5300存储中有12块FC硬盘,其中11块硬盘作为数据盘组建了一组RAID5阵列,剩下的1块硬盘作为热备盘使用。基于RAID的LUN分配给linux操作系统使用,存放的数据主要是Oracle数据库。 服务器存储故障: RAID5阵列中1块硬盘出现故障离线,热备盘自动激活开始同步数据,在同步数据的过程中又一块硬盘离线,RAID5阵列瘫痪,上层LUN无法使用。
|
3月前
|
存储 Oracle 关系型数据库
数据库数据恢复—Oracle ASM磁盘组故障数据恢复案例
Oracle数据库数据恢复环境&故障: Oracle ASM磁盘组由4块磁盘组成。Oracle ASM磁盘组掉线 ,ASM实例不能mount。 Oracle数据库故障分析&恢复方案: 数据库数据恢复工程师对组成ASM磁盘组的磁盘进行分析。对ASM元数据进行分析发现ASM存储元数据损坏,导致磁盘组无法挂载。
|
4月前
|
Oracle 关系型数据库 数据库
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
打开oracle数据库报错“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。 数据库没有备份,无法通过备份去恢复数据库。用户方联系北亚企安数据恢复中心并提供Oracle_Home目录中的所有文件,急需恢复zxfg用户下的数据。 出现“system01.dbf需要更多的恢复来保持一致性”这个报错的原因可能是控制文件损坏、数据文件损坏,数据文件与控制文件的SCN不一致等。数据库恢复工程师对数据库文件进一步检测、分析后,发现sysaux01.dbf文件损坏,有坏块。 修复并启动数据库后仍然有许多查询报错,export和data pump工具使用报错。从数据库层面无法修复数据库。
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
|
4月前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—异常断电导致Oracle数据库数据丢失的数据恢复案例
Oracle数据库故障: 机房异常断电后,Oracle数据库启库报错:“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。数据库没有备份,归档日志不连续。用户方提供了Oracle数据库的在线文件,需要恢复zxfg用户的数据。 Oracle数据库恢复方案: 检测数据库故障;尝试挂起并修复数据库;解析数据文件。
|
3月前
|
Oracle 关系型数据库 数据库
oracle数据恢复—Oracle数据库文件损坏导致数据库打不开的数据恢复案例
打开oracle数据库时报错,报错信息:“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。急需恢复zxfg用户下的数据。 出现上述报错的原因有:控制文件损坏、数据文件损坏、数据文件与控制文件的SCN不一致等。数据恢复工程师对数据库文件做进一步检测分析后发现sysaux01.dbf文件有坏块。修复sysaux01.dbf文件,启动数据库依然有许多查询报错。export和data pump工具无法使用,查询告警日志并分析报错,确认发生上述错误的原因就是sysaux01.dbf文件损坏。由于该文件损坏,从数据库层面无法修复数据库。由于system和用户表空间的数据文件是正常的,
|
4月前
|
Oracle 安全 关系型数据库
Oracle数据恢复—Oracle数据库误删除的数据恢复方法探讨
删除Oracle数据库数据一般有以下2种方式:delete、drop或truncate。下面针对这2种删除oracle数据库数据的方式探讨一下oracle数据库数据恢复方法(不考虑全库备份和利用归档日志)。
|
6月前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—Oracle数据库误删除的数据恢复方法
相信有很多oracle数据库用户都遇到过在操作Oracle数据库时误删除某些重要数据的情况,这个时候如果数据库没有备份且数据十分重要的,怎么才能恢复误删除的数据呢?北亚企安数据恢复工程师下面简单介绍几个误删除Oracle数据库数据的恢复方法。