模拟Oracle中的ACID异常

本文通过实验演示了在Oracle数据库中,当LGWR进程被挂起时,已提交事务在redo记录未写入磁盘前可能会丢失数据的情况。通过设置mdb和oradebug挂起LGWR进程,模拟数据修改并提交,然后查询验证修改成功,最后通过shutdownabort重启数据库观察数据丢失。实验揭示了事务提交过程中redo记录写入磁盘的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Jonathan Lewis的Oracle Core这本书中提到了一种ACID异常的现象,在这种情况下,事务已经提交,但是redo log buffer还没有写到磁盘。
如果断电,已提交的事务会丢失数据。

实验之前,我们首先来复习一下commit这个操作。

通常情况下,commit是一个非常快的操作,commit的主要操作是更新事务表槽的SCN。这个操作本身也会产生redo,一般来说,这是一个很快的操作。具体细节如下:
1.得到一个SCN值,准备更新事务表的事务表槽。并且在redo log buffer中为这次更新操作创建一条redo 记录
2.将生成的redo记录复制到日志缓冲区。
3.对undo事务表槽,应用这条redo。事务表中的槽位的SCN等信息被更新。
4.将这条commit记录产生的redo log buffer刷新到磁盘上的在线日志文件。

在第3步和第4步中间,其他的会话能看到事务已经改变,尽管redo还没有写到磁盘,如果数据库实例在第3步和第4步中间崩溃,那么有可能这个已经提交的事务没有被恢复。演示如下:

1.会话1:使用mdb或者oradebug将lgwr挂起。
2.会话2:修改一条数据然后提交--会话会挂起。
3.会话3:查询数据,并注意到修改后的数据是可见的。
4.会话3:shutdown abort,数据库重启后,第2步产生的更改丢失。

在Solaris10+Oracle 11.2.0.1环境下测试.
1.挂起lgwr进程。
# ps -ef|grep lgwr
  oracle  1063     1   0 13:37:42 ?           0:01 asm_lgwr_+ASM1
  oracle  1637     1   0 13:39:33 ?           0:02 ora_lgwr_mydb1
    root 22754 22544   0 20:53:21 pts/3       0:00 grep lgwr
# mdb -p 1637
Loading modules: [ ld.so.1 libc.so.1 ]


2.修改一条记录并提交。t1表的唯一字段x,初始值为7,将其更新为8.
SQL> select * from t1;


         X
----------
         7
SQL> update t1 set x=8;
1 row updated.
SQL> commit;
由于LGWR被挂起,这里的commit操作会hang.


3.查询修改的记录,我们可以看到,这条记录已经由7变成了8
SQL> select * from t1;


         X
----------
         8

4.shutdown abort数据库,然后重新查询这条记录。SQL> shutdown abort;
ORACLE instance shut down.
SQL> startup

ORACLE instance started.


Total System Global Area 1570009088 bytes
Fixed Size                  2211368 bytes
Variable Size             469762520 bytes
Database Buffers         1090519040 bytes
Redo Buffers                7516160 bytes
Database mounted.
Database opened.
SQL> SQL> select * from t1;


         X
----------
         7


我们可以看到,数据库重启之后,已经commit的操作丢失了。
由于LGWR不会经常崩溃,出现这种问题的时间窗口极短。
Oracle一直在不断的在进行改进和优化,对于commit操作,在11g中又引入了两个新参数:commit_logging和commit_wait.有兴趣的同学可以自己研究。

以上实验完全参考Oracle Core。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值