分析ROLLBACK是否产生日志信息

本文介绍了如何使用Oracle的LOGMNR工具进行数据库日志分析,包括配置归档模式、创建日志字典、启动和结束日志分析等步骤,并通过实例展示了不同事务提交状态下的日志变化。

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

首先介绍分析日志的方法,采用LOGMNR

流程如下:

SQL> @F:\app\Administrator\product\11.2.0\dbhome_1\RDBMS\ADMIN\dbmslm.sql

程序包已创建。


授权成功。


同义词已创建。

SQL> @F:\app\Administrator\product\11.2.0\dbhome_1\RDBMS\ADMIN\dbmslmd.sql

程序包已创建。


同义词已创建。


SQL> select log_mode from v$database;

LOG_MODE                                                                        
------------                                                                    
NOARCHIVELOG                                                                    

SQL> @F:\app\Administrator\product\11.2.0\dbhome_1\RDBMS\ADMIN\dbmslms.sql

程序包已创建。

没有错误。

授权成功。

SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup mount;
ORACLE 例程已经启动。

Total System Global Area  778387456 bytes                                       
Fixed Size                  1374808 bytes                                       
Variable Size             301991336 bytes                                       
Database Buffers          469762048 bytes                                       
Redo Buffers                5259264 bytes                                       
数据库装载完毕。
--开启归档
SQL> alter database archivelog;

数据库已更改。

SQL> alter database open;

数据库已更改。
--创建日志字典路径
SQL> alter system set utl_file_dir='d:\logmin' scope=spfile;

系统已更改。

SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area  778387456 bytes                                       
Fixed Size                  1374808 bytes                                       
Variable Size             301991336 bytes                                       
Database Buffers          469762048 bytes                                       
Redo Buffers                5259264 bytes                                       
数据库装载完毕。
数据库已经打开。
SQL> begin
  2  dbms_logmnr_d.build(
  3  dictionary_filename=>'logmin_dict.dat',
  4  dictionary_location=>'d:\logmin');
  5  end;
  6  /

PL/SQL 过程已成功完成。

SQL> execute dbms_logmnr.add_logfile(options=>dbms_logmnr.new,logfilename=>'F:\app\Administrator\oradata\orcl\REDO01.LOG');

PL/SQL 过程已成功完成。
                                                             

SQL> begin
  2  dbms_logmnr.start_logmnr(
  3   dictfilename=>'d:\logmin\logmin_dict.dat'
  4  );
  5  end;
  6  /

PL/SQL 过程已成功完成。

SQL> select count(*) from v$logmnr_contents;

  COUNT(*)                                                                      
----------                                                                      
     50496                                                                      

SQL> create table log_back as select * from v$logmnr_contents;

表已创建。

SQL>execute dbms_logmnr.end_logmnr();
PL/SQL 过程已成功完成。

SQL> spool off


直接使用包来分析日志(11g r2的版本)

--使用包分析日志的方法
exec dbms_logmnr.add_logfile('/data/archive/redo001.log',dbms_logmnr.new);
exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
--查询日志信息
select timestamp,scn,sql_redo
from v$logmnr_contents
where lower(sql_redo) like '%insert%'
and seg_name='TEST'
and seg_owner='TEST';

dbms_logmnr.end_logmnr(); --停止日志分析

注意:
如果所有操作只回滚不提交的话,最后生成的归档日志是不会有任何人工操作数据的(可能会有一些系统操作的数据信息).
SQL> select group#,archived,status,first_time from v$log;

GROUP# ARC STATUS FIRST_TIME
---------- --- ---------------- -------------------
1 YES INACTIVE 2012-10-25 11:17:50
2 NO CURRENT 2012-10-25 11:17:57
3 YES INACTIVE 2012-10-25 11:17:39
也就是现在分析1和3,v$logmnr_contents表里没有任何信息(之前我只有做rollback,未做任何commit事务).只有分析2、CURRENT状态的才有数据.

还要注意的是如果分析活动的日志(如现在分析GROUP 2),有时候不能使用INSERT INTO TT select * from v$logmnr_contents,来保存日志数据,它会提示如下错误:

第 1 行出现错误:
ORA-00310: 归档日志包含序列 290; 要求序列 287
ORA-00334: 归档日志: 'F:\APP\ADMINISTRATOR\ORADATA\ORCL\REDO02.LOG'

这个不是很清楚原因,个人猜想可能是ARC进程正在归档造成的,此时查询V$LOG发现如下:

SQL> select group#,archived,status,first_time from v$log

GROUP# ARC STATUS FIRST_TIME
---------- --- ---------------- -------------------
1 YES ACTIVE 2012-10-25 12:08:45
2 YES ACTIVE 2012-10-25 12:09:41
3 NO CURRENT 2012-10-25 12:09:45


在分析日志组2(状态为:CURRENT)的数据时发现,如果insert操作后(
语句为:
begin
for i in 1..1000 loop
INSERT into tt002 values(i,'aa');
end loop;
end;)
不rollback,也不commit.分析后的日志信息如下:
TIMESTAMP SCN
------------------- ----------
SQL_REDO
--------------------------------------------------------------------------------
2012-10-25 11:34:38 3813555
insert into "TEST"."TT002"("I","J") values ('1','aa');

2012-10-25 11:34:38 3813555
insert into "TEST"."TT002"("I","J") values ('2','aa');

2012-10-25 11:34:38 3813555
insert into "TEST"."TT002"("I","J") values ('3','aa');

......

如果ROLLBACK之后,产生的日志信息如下:
SQL> select timestamp,scn,sql_redo
2 from v$logmnr_contents
3 where lower(sql_redo) like '%tt002%' and lower(sql_redo) like '%delete%';

TIMESTAMP SCN
------------------- ----------
SQL_REDO
--------------------------------------------------------------------------------
2012-10-25 11:36:26 3813606
delete from "TEST"."TT002" where ROWID = 'AAAS0lAAEAAAAFbAGB';

2012-10-25 11:36:26 3813606
delete from "TEST"."TT002" where ROWID = 'AAAS0lAAEAAAAFbAGA';

2012-10-25 11:36:26 3813606
delete from "TEST"."TT002" where ROWID = 'AAAS0lAAEAAAAFbAF/';

.....

也就是说回滚INSERT对应产生了DELETE的日志信息.


-----------------------------------------------------------------

如此文有错误,欢迎指正,顺便告诫自己一定要多动手,实践才能出真理,切勿想当然.

### 数据库事务日志的作用及其实现 #### 一、事务日志的核心概念 事务日志是一种用于支持数据库事务管理的重要机制,其主要功能是对事务的操作过程进行记录,以便在发生异常情况时能够恢复到一致状态。具体来说,事务日志分为两种类型:重做日志(Redo Log)和撤销日志(Undo Log),它们共同保障了事务的ACID特性。 - **Undo Log 的作用** Undo Log 是一种逻辑日志,主要用于提供事务回滚的能力以及实现多版本并发控制(MVCC)。当事务对数据进行修改时,除了生成 Redo Log 外还会生成相应的 Undo Log 条目。这些条目包含了如何撤消当前操作的信息,例如删除一条记录时会在 Undo Log 中记录一条插入该记录的日志[^4]。通过这种方式,在事务失败或被显式回滚的情况下,可以通过应用 Undo Log 将数据还原至原始状态。 - **Redo Log 的作用** Redo Log 则侧重于持久化保护,即确保即使系统崩溃也能恢复未完成的数据写入操作。它是基于物理层面的日志形式,记录了每次磁盘页变更的具体细节。尽管不同事务可能交错执行并产生无序的 Redo Log 条目,但这种设计有助于提高性能效率[^3]。一旦检测到实例故障,则可通过分析 Redo Logs 完成必要的前滚处理来同步内存缓冲区与实际存储之间的差异。 #### 二、MySQL 中事务日志的具体实现方式 ##### (1)Undo Log 实现原理 在 MySQL 的 InnoDB 存储引擎里,Undo Log 被用来保存旧版本的数据副本,从而允许其他查询看到过去某个时间点的状态而不是最新的更改结果——这就是所谓的 MVCC 技术的基础之一[^2]。每当有新的 DML 操作被执行时: ```sql -- 假设有一张表 t(id INT PRIMARY KEY, name VARCHAR(50)) INSERT INTO t VALUES (1,'Alice'); UPDATE t SET name='Bob' WHERE id=1; DELETE FROM t WHERE id=1; ``` 对于上述 SQL 序列而言, - `INSERT` 操作会产生一个指向新增行位置的新指针; - 随后的 `UPDATE` 动作则创建另一份包含原值 `'Alice'` 的隐藏拷贝存放在 Rollback Segment 区域内作为历史快照; - 最终的 `DELETE` 行动同样不会立即移除目标对象而是标记为已删并将关联信息追加进 Undo Chain 结构之中直到满足清理条件为止。 ##### (2)Redo Log 工作流程 相比之下,Redo Logging 更关注于提升系统的可靠性而非功能性扩展。以下是典型的工作流描述: 1. 当应用程序提交了一个涉及多个页面更新的大规模批量导入作业之后,所有相关的改动都会先暂存在 Buffer Pool 缓冲池当中暂时停留一段时间而不直接刷回到硬盘上。 2. 后台线程定期扫描活跃队列寻找符合条件待刷新的目标项,并按照一定策略将其序列化的镜像复制一份出来形成最终版的 Redo Entry 内容准备入库。 3. 如果此时遭遇意外断电等情况造成部分已完成却尚未落地的部分丢失的话,重启期间就可以依靠解析残留下来的这部分线索重新构建缺失片段进而达成完整的业务连续性需求. #### 三、总结说明 综上所述,无论是从理论角度还是实践角度来看,合理运用好这两种类型的事务日记都能够极大地增强现代关系型数据库管理系统应对复杂场景下的挑战能力。一方面依赖 Undo Log 可以轻松解决长时间运行过程中可能出现的各种不确定因素干扰;另一方面凭借高效可靠的 Redo Mechanism 则能有效降低因硬件资源耗尽而导致的服务中断风险。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值