是否有想过如何在Oracle中实现脏读(dirty read),在Oracle官方文档或者Asktom的时候显然会提到Oracle是不实现脏读的, 总是有undo来提供数据块的前镜像(before image)以维护一致性Consistent, 通过正常途径我们几乎不可能破坏Oracle中查询的一致性来实现脏读。   是否真的无计可施? 非也,非也,Oracle作为一个高度复杂而又可控的RDBMS,仍是有很多空子可以钻的。   我们先来介绍以下的2个隐藏参数: _offline_rollback_segments or _corrupted_rollback_segments 这2个隐藏参数对于熟悉Oracle数据库异常恢复或者解决ORA-600[4XXX]问题有经验的同学来说肯定不陌生,因为这2个参数是针对Undo存在Corruption讹误时忽略问题的有力工具,而大家对这2个参数实际起到的作用有多少认识呢?   我们可能在以下几种场景中用到_offline_rollback_segments 和 _corrupted_rollback_segments 这2个隐藏参数:

  • 强制打开数据库(FORCE OPEN DATABASE)
  • 控制一致性读和延迟块清除(consistent read & delayed block cleanout)
  • 强制删除某个rollback segment回滚段

但是请注意:千万不要在没有Oracle专家建议的情况下,在产品环境设置以上这2个隐藏参数,可能造成数据逻辑讹误等影响!!   _offline_rollback_segments 和 _corrupted_rollback_segments 均会造成的实例行为变化:

  • 以上2个参数所列出的Undo Segments(撤销段/回滚段)将不会被在线使用online
  • 在UNDO$数据字典基表中将体现为OFFLINE的记录
  • 在实例instance的生命周期中将不会再给新的事务分配使用
  • 参数所列出的Undo Segments列表上的活跃事务active transaction将即不被回滚亦不被标记为dead以便SMON去回滚(了解你所不知道的SMON功能(五):Recover Dead transaction)

_OFFLINE_ROLLBACK_SEGMENTS(offline undo segment list)隐藏参数(hidden parameter)的独有作用:

  • 在实例startup启动并open database的阶段仍将读取_OFFLINE_ROLLBACK_SEGMENTS所列出的Undo segments(撤销段/回滚段),若访问这些undo segments出现了问题则将在alert.log和其他TRACE中体现出来,但不影响实际的startup进程

    • 若查询数据块发现活跃的事务,并ITL指向对应的undo segments则:
    • 若读取undo segments的transaction table事务表发现事务已提交则做数据块的清除
    • 若读取发现事务仍活动未commit,则生成一个CR块拷贝
    • 若读取该undo segments存在问题(可能是corrupted讹误,可能是missed丢失)则产生一个错误并写出到alert.log,查询将异常终止
  • 若DML更新相关的数据块会导致服务进程为了恢复活跃事务而进入死循环消耗大量CPU,解决方法是通过可以进行的查询工作重建相关表

_CORRUPTED_ROLLBACK_SEGMENTS(corrupted undo segment list)隐藏参数所独有的功能:

  • 在实例启动startup并open database的阶段_CORRUPTED_ROLLBACK_SEGMENTS所列出的undo segments(撤销段/回滚段)将不会被访问读取
  • 所有指向这些被_CORRUPTED_ROLLBACK_SEGMENTS列出的undo segments的事务都被认为已经提交了commit,和这个undo segments已经被drop时类似
    • 这将导致严重的逻辑讹误
    • 如果数据字典上有活跃事务那么将更糟糕,数据字典逻辑讹误会造成数据库管理问题
    • 如果bootstrap自举核心对象有活跃事务,那么将无法忽略错误ORA-00704: bootstrap process failure错误,导致无法强制打开数据库(见拙作Oracle数据恢复:解决ORA-00600:[4000] ORA-00704: bootstrap process failure错误一例)
  • 衷心地建议用_CORRUPTED_ROLLBACK_SEGMENTS这个参数打开数据库后导出数据并重建数据库,这个参数使用的后遗症可能很顽固
  • Oracle公司内部有叫做TXChecker的工具可以检查问题事务

好了了解了以上2个参数之后,你将不难明白下面演示如何通过_CORRUPTED_ROLLBACK_SEGMENTS隐藏参数让SELECT查询绕过UNDO实现脏读的过程:

SQL> alter system set event= '10513 trace name context forever, level 2' scope=spfile;System altered.SQL> alter system set "_in_memory_undo"=false scope=spfile;System altered.10513 level 2 event可以禁止SMON 回滚rollback 死事务 dead transaction
_in_memory_undo 禁用 in memory undo 特性SQL> startup force;
ORACLE instance started.Total System Global Area 3140026368 bytes
Fixed Size                  2232472 bytes
Variable Size            1795166056 bytes
Database Buffers         1325400064 bytes
Redo Buffers               17227776 bytes
Database mounted.
Database opened.session A:SQL> conn maclean/maclean
Connected.SQL> create table maclean tablespace users as select 1 t1 from dual connect by level exec dbms_stats.gather_table_stats('','MACLEAN');PL/SQL procedure successfully completed.SQL> set autotrace on;   SQL> select sum(t1) from maclean;SUM(T1)
----------501Execution Plan
----------------------------------------------------------
Plan hash value: 1679547536------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     1 |     3 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |         |     1 |     3 |            |          |
|   2 |   TABLE ACCESS FULL| MACLEAN |   501 |  1503 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------Statistics
----------------------------------------------------------1  recursive calls0  db block gets3  consistent gets0  physical reads0  redo size515  bytes sent via SQL*Net to client492  bytes received via SQL*Net from client2  SQL*Net roundtrips to/from client0  sorts (memory)0  sorts (disk)1  rows processe在没有活跃事务的情况下,直接读取current block,
全表扫描一致性读,consistent gets只要3次                  SQL> update maclean set t1=0;501 rows updated.SQL> alter system checkpoint;System altered.这里session A不commit;另开一个 session:SQL> conn maclean/maclean
Connected.
SQL>
SQL> set autotrace on;
SQL>  select sum(t1) from maclean;SUM(T1)
----------501Execution Plan
----------------------------------------------------------
Plan hash value: 1679547536------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     1 |     3 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |         |     1 |     3 |            |          |
|   2 |   TABLE ACCESS FULL| MACLEAN |   501 |  1503 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------Statistics
----------------------------------------------------------0  recursive calls0  db block gets505  consistent gets0  physical reads108  redo size515  bytes sent via SQL*Net to client492  bytes received via SQL*Net from client2  SQL*Net roundtrips to/from client0  sorts (memory)0  sorts (disk)1  rows processed为了一致性读 上面的查询需要通过undo构造CR块,这导致consistent gets上升到 505[oracle@vrh8 ~]$ ps -ef|grep LOCAL=YES |grep -v grep
oracle    5841  5839  0 09:17 ?        00:00:00 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))[oracle@vrh8 ~]$ kill -9 5841杀掉session A对应的Server Process服务进程,这导致dead transaction 但是不被smon回滚select ktuxeusn,to_char(sysdate, 'DD-MON-YYYY HH24:MI:SS') "Time",ktuxesiz,ktuxestafrom x$ktuxewhere ktuxecfl = 'DEAD';KTUXEUSN Time                   KTUXESIZ KTUXESTA
---------- -------------------- ---------- ----------------2 06-AUG-2012 09:20:45          7 ACTIVE此时有1个active rollback segment SQL> conn maclean/maclean
Connected.SQL> set autotrace on;SQL> select sum(t1) from maclean;SUM(T1)
----------501Execution Plan
----------------------------------------------------------
Plan hash value: 1679547536------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     1 |     3 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |         |     1 |     3 |            |          |
|   2 |   TABLE ACCESS FULL| MACLEAN |   501 |  1503 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------Statistics
----------------------------------------------------------0  recursive calls0  db block gets411  consistent gets0  physical reads108  redo size515  bytes sent via SQL*Net to client492  bytes received via SQL*Net from client2  SQL*Net roundtrips to/from client0  sorts (memory)0  sorts (disk)1  rows processed到上面为止 虽然通过kill进程 和禁止smon 回滚dead transaction ,
形成了一个不回滚的死事务 但是仍通过undo实现了一致性读找出当前active的rollback segment的名字SQL> select segment_name from dba_rollback_segs where segment_id=2;SEGMENT_NAME
------------------------------
_SYSSMU2$SQL> alter system set "_corrupted_rollback_segments"='_SYSSMU2$'  scope=spfile;System altered.用 _corrupted_rollback_segments 废掉 上面的2个rollback segment, 这将导致无法提供undo SQL> startup force;
ORACLE instance started.Total System Global Area 3140026368 bytes
Fixed Size                  2232472 bytes
Variable Size            1795166056 bytes
Database Buffers         1325400064 bytes
Redo Buffers               17227776 bytes
Database mounted.
Database opened.SQL> conn maclean/maclean
Connected.SQL> set autotrace on;SQL> select sum(t1) from maclean;SUM(T1)
----------94Execution Plan
----------------------------------------------------------
Plan hash value: 1679547536------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     1 |     3 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |         |     1 |     3 |            |          |
|   2 |   TABLE ACCESS FULL| MACLEAN |   501 |  1503 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------Statistics
----------------------------------------------------------228  recursive calls0  db block gets29  consistent gets5  physical reads116  redo size514  bytes sent via SQL*Net to client492  bytes received via SQL*Net from client2  SQL*Net roundtrips to/from client4  sorts (memory)0  sorts (disk)1  rows processedSQL> /SUM(T1)
----------94Execution Plan
----------------------------------------------------------
Plan hash value: 1679547536------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     1 |     3 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |         |     1 |     3 |            |          |
|   2 |   TABLE ACCESS FULL| MACLEAN |   501 |  1503 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------Statistics
----------------------------------------------------------0  recursive calls0  db block gets3  consistent gets0  physical reads0  redo size514  bytes sent via SQL*Net to client492  bytes received via SQL*Net from client2  SQL*Net roundtrips to/from client0  sorts (memory)0  sorts (disk)1  rows processed

以上可以看到 consistent gets下降到3,服务进程读取数据块发现存在活跃事务,但是ITL指向的UNDO SEGMENTS在_corrupted_rollback_segments的列表中,所以直接认为该事务已经COMMIT提交,以便绕过UNDO。 这里实现了脏读,虽然通过上述方法去实现脏读在产品环境中没有实际收益(有部分数据库软件允许脏读来做统计信息收集),破坏了一致性且需要设置需重启实例的 隐藏参数 , 仅供参考。

在Oracle中如何让SELECT查询绕过UNDO相关推荐

  1. 查询oracle中用户的角色,oracle中用户角色的查询和授权

    用户拥有的系统权限 select  privilege  from dba_sys_privs  where grantee='&USERNAME' union select  privile ...

  2. ORACLE中使用SQL语句查询所有员工的职位信息,并用DISTINCT消除重复信息。

    ORACLE中使用SQL语句查询所有员工的职位信息,并用DISTINCT消除重复信息. 在sqlplus中执行下面语句: select job from emp: 显示结果如下: SQL> se ...

  3. oracle中的select into,Oracle中insert into select和select into的用法

    Oracle中insert into select和select into的用法 两张表进行数据的拷贝,最常用的拷贝语句是: insert into select 和select into from ...

  4. day02: SQL_DML, oracle中sql的各种查询

    1.oraclesql的特性 pLsql显示: 修改显示的格式 SQL> set pagesize 300; SQL> set linesize 300; SQL> select e ...

  5. oracle怎么获取行,在oracle中如何实现SELECT TOP N取得前几行记录

    在sql server中可以通过SELECT TOP N来取得想要结果的前几行的信息. 但是在oracle中必须借助伪列rownum来完成 一个查询语句在取得结果集后,伪列rownum就会从1开始,从 ...

  6. ArcGIS——数据库空间SQL(一、oracle中使用sql空间查询及st_astext等函数出错问题)

    一.引言 将shp文件导入oracle中就想着直接用sql进行普通查询和空间查询,这样直接通过webserver发布就可以不用arcgis server直接进行接口调用了,感觉这样比较接触底层些,所以 ...

  7. Oracle中insert into select和select into的区别

    文章转自:http://www.linuxidc.com/Linux/2012-09/70984.htm 在Oracle中,将一张表的数据复制到另外一个对象中.通常会有这两种方法:insert int ...

  8. Oracle中Timestamp类型字段查询结果格式化处理

    在使用Oracle数据库时,把Timestamp类型的字段查出来显示到界面上居然是一串数字,不符合我们常见的要求,我就查了一下,发现中间还有很多道道,Oracle查出来的Timestamp类型和jav ...

  9. 查询oracle历史scn,ORACLE中的各种SCN查询

    1.查询系统当前SCN两条命令 SQL> select current_scn from v$database; SQL> select dbms_flashback.get_system ...

最新文章

  1. Provisioning Services 7.8 入门系列教程之十三 使用 Boot Device Management(BDM)
  2. 面试--js实现继承的几种方式
  3. mysql服务实例配置_MySQL多实例配置(一)
  4. 中文数据集有奖公开征集
  5. amd建议超频吗_Amd 超频简单说明书——CPU篇
  6. 12036火车票小工具,希望大家都能顺利回家
  7. unity3d 自动变化大小_一种可扩展的Unity3d资源检查方式
  8. python查找输出文字_Python基础练习,查询文本内容并输出;
  9. iOS开发总结(A0)- Localization
  10. 30 网站项目建设流程概述
  11. 产品经理该如何做竞品分析
  12. 【ArcGIS 10.2新特性】地理数据(Geodatabase 和database)10.2 新特性
  13. 消息队列与RabbitMQ
  14. 系统集成资质-2009年5月系统集成项目管理工程师真题-1
  15. 用pdf转cad转换器进行操作的简单步骤
  16. 天龙八部荣耀版体验服服务器未响应,《天龙八部荣耀版》体验服评测:用竖版画面重新诠释天龙江湖...
  17. 决定局域网特性的三要素
  18. 【peoplesoft】Integration Gateway - General Error (158,10201)错误
  19. Java程序员必读精选书籍分享,强烈推荐
  20. SIM800C通讯模块调试

热门文章

  1. 用表格布局2个链接6个图片
  2. win10+anaconda+cuda配置dlib,使用GPU对dlib的深度学习算法进行加速(以人脸检测为例)...
  3. [jquery]if条件句
  4. (转)xshell无法在vim中复制黏贴
  5. CSS中position的几个属性值
  6. MATLAB加入螺旋相位板调制,连续型螺旋相位板设计方法与流程
  7. acs880变频器选型手册_据说这是变频器知识里讲的最全的了,小编拿来分享给大家!...
  8. jetty java 实例_Maven+Jetty+Servlet 简单示例
  9. LTE MAC PDU
  10. Linux数据报文接收发送总结3