Oracle的一致性读保证了读不阻塞写

再深入一步,为大家测试下,如果手动将buffer Header中Buffer Pin内存位设置为1,这就等同于加上了共享Buffer Pin锁,这时另开一个会话,更新这个块,会有什么情况呢?

1、取T1表的第一行数据做测试:
SQL> select rowid,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,id,name from gyj.t1 where rownum=1;

ROWID                   FILE#     BLOCK#         ID   NAME
------------------ ---------- ---------- ----------   --------------
AAASP9AAGAAAACDAAA          6        131        468   gyj468

这里的DBA(Data Block Address)就是由6号文件和131号块组成

2、根据文件号块号获取CBC Latch的地址
SQL> select hladdr,ba,decode(state,0,'free',1,'xcur',2,'scur',3,'cr', 4,'read',5,'mrec',6,'irec',7,'write',8,'pi',9,'memory',10,'mwrite',11,'donated') status from x$bh where file#=6 and dbablk=131;

HLADDR           BA               STATUS
---------------- ---------------- -------
00000003A43FA468 000000039459C000 xcur    --BA=000000039459C000时这个块的状态是xcur(当前块)从上面可以看出6号文件131号块的状态是当前块

3、查本会话下的会话号,进程号
SQL> select s.sid,spid from v$session s,v$process b where s.paddr=b.addr and s.sid in(select sid from v$mystat where rownum=1);

 SID SPID
---------- ------------------------
  125 1545
从上面看出会话号125,进程号1545

4、用Dtrace跟踪一下找到buffer pin的地址3947e73d0
1  51768        sskgslcas:entry i=23 PID::entry:==pid1545:oracle:sskgslcas:entry 3947e73d0 0 1 0 3947e
 如何查到buffer pin地址查看这个链接:http://www.itpub.net/thread-1764511-2-3.html
     5、另开一个会话利用oradebug工具
SQL> conn / as sysdba
Connected.
SQL> select distinct sid from v$mystat;

  SID
----------
16 
SQL> oradebug peek 0x3947e73d0 4        --查6号文件131号有没有buffer pin
BEFORE: [3947E73D0, 3947E73D4) = 00000000  --从这个值上看在6号文件131号块上没有加buffer pin
SQL> oradebug poke 0x3947e73d0 4 1      --在6号文件131号加buffer pin
BEFORE: [3947E73D0, 3947E73D4) = 00000000
AFTER:  [3947E73D0, 3947E73D4) = 00000001         --由0变成1,说明已加上了buffer pin

6、再回到125号会话下,查6号文件131号块的数据
SQL> select * from gyj.t1 where rowid='AAASP9AAGAAAACDAAA';

ID  NAME

---------- -----------------------------
  468  gyj468

SQL> select hladdr,ba,decode(state,0,'free',1,'xcur',2,'scur',3,'cr', 4,'read',5,'mrec',6,'irec',7,'write',8,'pi',9,'memory',10,'mwrite',11,'donated') status from x$bh where file#=6 and dbablk=131;

HLADDR           BA               STATUS
---------------- ---------------- -------
00000003A43FA468 000000039459C000 xcur    --BA=000000039459C000时这个块的状态是xcur(当前块)

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/database/Oracle/

7、再开一个新会话,对6号文件131号块的rowid='AAASP9AAGAAAACDAAA'的这行数据做update,把name的值由gyj468修改成gyjdba;
SQL> update gyj.t1 set name='gyjdba' where rowid='AAASP9AAGAAAACDAAA';

1 row updated.
--update操作没有发生待等

8、再查6号文件131号块,有两条记录,多产生了一条状态是CR的记录
SQL> select hladdr,ba,decode(state,0,'free',1,'xcur',2,'scur',3,'cr', 4,'read',5,'mrec',6,'irec',7,'write',8,'pi',9,'memory',10,'mwrite',11,'donated') status from x$bh where file#=6 and dbablk=131;
HLADDR           BA               STATUS
---------------- ---------------- -------
00000003A43FA468 000000038F442000 xcur    --从BA这个字段可以看出这是新产生出来的,就是后面的UPDATE操作,xcur当前块
00000003A43FA468 000000039459C000 cr      --BA=000000039459C000可以看出这是原来做SELECT的操作,由状态xcur(当前块)变成cr(一致性读块)

9、查等待事件
SQL> select sid,event from v$session where wait_class<>'Idle';

  SID EVENT
---------- ----------------------------------------------------------------
  140 SQL*Net message to client                                   --没有发生等待

10、总结一下:在这种情况下读是不会阻塞写的,那我们在AWR中看到的buffer busy waits等待事件是由什么产生的,它是由写(DML/DDL)阻塞读(SELECT)和写阻塞写产生的。

11、思考个问题:
那读会阻塞写吗?
如果有那么在哪几种情况发生?
在AWR中看到的dirty buffers inspected等待事件跟读阻塞写有关吗?

12、读阻塞读的测试,链接地址:
http://blog.csdn.net/guoyjoe/article/details/8585391

http://www.itpub.net/thread-1764511-1-1.html

时间: 2024-09-20 20:22:20

Oracle的一致性读保证了读不阻塞写的相关文章

ORACLE 物理读 逻辑读 一致性读 当前模式读总结浅析

     在ORACLE数据库中有物理读(Physical Reads).逻辑读(Logical Reads).一致性读(Consistant Get).当前模式读(DB Block Gets)等诸多概念,如果不理解或混淆这些概念的话,对你深入理解一些知识无疑是一个障碍,但是这些概念确实挺让让人犯晕的.下面我们总结.学习一下这方面的知识点.捋一捋他们的关系和特点,希望对你有所帮助.   物理读(Physical Reads)   从磁盘读取数据块到内存的操作叫物理读,当SGA里的高速缓存(Cac

非一致性内存访问的读写锁

原文地址,译文地址,译者: 李杰聪,校对:郑旭东 原文作者: Irina Calciu         Brown University        irina@cs.brown.edu Dave Dice          Oracle Labs             dave.dice@oracle.com Yossi Lev           Oracle Labs             yossi.lev@oracle.com Victor Luchangco    Oracle

buffer cache实验9:从buffer caceh中读取数据块解析-从逻辑读到物理读

先来张大图: 所用SQL语句: BYS@ ocm1>select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,deptno from bys.test;     FILE#     BLOCK#     DEPTNO ---------- ---------- ----------         4        391         10 就以上图为例,文字描述

java nio 如何实现 阻塞读 不阻塞写

问题描述 java nio 如何实现 阻塞读 不阻塞写 java nio 如何实现 阻塞读 不阻塞写java nio 如何实现 阻塞读 不阻塞写 解决方案 java NIO 及 阻塞和非阻塞IO 解决方案二: 用selector可以实现不

Lotus在C#中如何将邮件由未读变为已读

问题描述 在.net环境用Domino,现在已经做到收取.发送邮件的功能了,但是有一个需求,需要把收到的邮件由未读变为已读,请问如何用C#来写?谢谢...

java读文件后的数据怎么写到一个数组中 数据格式如下

问题描述 java读文件后的数据怎么写到一个数组中 数据格式如下 解决方案 简单的写了一下,希望对你有帮助: public class Test { // 数组列数 private static final int COLUMN_COUNT = 3; public static void main(String[] args) { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(new F

前端开发-怎么让已读和未读的邮件的字体格式上有区别(未读加粗)

问题描述 怎么让已读和未读的邮件的字体格式上有区别(未读加粗) 已读和未读的代码如下,请问是在哪里进行设置 <c:if test="${(type == 'seeUnread') ||(type == 'seeRead')}"> <span class="unable"><a href="<%=basePath%>user/receive!seeMail.action?folderType=${ft}&pa

Android 高仿QQ滑动弹出菜单标记已读、未读消息

  在上一篇博客<Android 高仿微信(QQ)滑动弹出编辑.删除菜单效果,增加下拉刷新功能>里,已经带着大家学习如何使用SwipeMenuListView这一开源库实现滑动列表弹出菜单,接下来,将进一步学习,如何为不同的list item呈现不同的菜单,此处我们做一个实例:Android 高仿QQ滑动弹出菜单标记已读.未读消息,看下效果图: 1. 创建项目,并导入SwipeMenuListView类库 2. 创建消息实体bean: public class Msg { public int

理解SQL SERVER中的逻辑读,预读和物理读

SQL SERVER数据存储的形式 在谈到几种不同的读取方式之前,首先要理解SQL SERVER数据存储的方式.SQL SERVER存储的最小单位为页(Page).每一页大小为8k,SQL SERVER对于页的读取是原子性,要么读完一页,要么完全不读,不会有中间状态.而页之间的数据组织结构为B树.所以SQL SERVER对于逻辑读,预读,和物理读的单位是页. SQL SERVER一页的总大小为:8K 但是这一页存储的数据会是:8K=8192字节-96字节(页头)-36字节(行偏移)=8060字节