How to Analyse Row Lock Contention in Oracle 10gR2 and later

我们有一道面试题,原以为很简单,但是却发现面试者能够完美解出的几乎没有,一部分人有思路,但是可能是因为面试紧张,很难在指定时间内完成解题,而更大一部分人连思路也不清晰。 题目是:请将emp.empno=7369的记录ename字段修改为“ENMOTECH”并提交,你可能会遇到各种故障,请尝试解决。 其实题目的设计非常简单,一个RAC双节点的实例环境,面试人员使用的是实例2,而我们在实例1中使用select for update将EMP表加锁。 SQL> select * from emp for update; 此时在实例2中,如果执行以下SQL语句尝试更新ename字段,必然会被行锁堵塞。 SQL> update emp set ename=’ENMOTECH’ where empno=7369; 这道面试题中包含的知识点有: 1. 如何在另外一个session中查找被堵塞的session信息; 2. 如何找到产生行锁的blocker; 3. 在杀掉blocker进程之前会不会向面试监考人员询问,我已经找到了产生堵塞的会话,是不是可以kill掉; 4. 在获得可以kill掉进程的确认回复后,正确杀掉另一个实例上的进程。 这道题我们期待可以在5分钟之内获得解决,实际上大部分应试者在15分钟以后都完全没有头绪。 正确的思路和解法应该如下: 检查被阻塞会话的等待事件 更新语句回车以后没有回显,明显是被锁住了,那么现在这个会话经历的是什么等待事件呢? SQL> select sid,event,username,sql.sql_text 2 from vsession s,vsql sql 3 where s.sql_id=sql.sql_id 4 and sql.sql_text like ‘update emp set ename%’; SID EVENT USERNAME…

Oracle ASM Filter Driver (ASMFD) – New Features for Oracle ASM 12.1.0.2

什么是Oracle ASM Filter Driver(ASMFD)? 简单地说,这是一个可以取代ASMLIB和udev设置的新功能,并且还增加了I/O Filter功能,这也体现在该功能的命名中。ASMFD目前只在Linux操作系统中有效,并且必须要使用最新版的Oracle ASM 12.1.0.2。在之前,由于Linux操作系统对于块设备的发现顺序不定,所以在系统重启以后,无法保证原来的/dev/sda还是sda,所以不能直接使用这样原始的设备名来做ASM Disk的Path,因此出现了ASMLIB,以Label的方式给予设备一个固定的名字,而ASM则直接使用这个固定的名字来创建ASM磁盘,后来ASMLIB必须要ULN帐号才可以下载了,于是大家全部转到了udev方式,我还因此写了几篇文章来阐述在Linux中如何设置udev rule。比如: How to use udev for Oracle ASM in Oracle Linux 6 Oracle Datafiles & Block Device & Parted & Udev 现在Oracle推出了ASMFD,可以一举取代ASMLIB和手动设置udev rules文件的繁琐,并且最重要的是I/O Filter功能。 什么是I/O Filter功能? 文档原文如下: The Oracle ASM Filter Driver rejects any I/O requests that are invalid. This action eliminates accidental overwrites of Oracle…

【Oracle Database 12c New Feature】Aggregate Data Across Many PDBs by CONTAINERS Clause

在最新版本的Oracle Database 12.1.0.2中,新特性提供了PDB Containers子句,用以从CDB$ROOT层面直接聚合查询多个PDB中同一张表的数据。在新特性文档中该段如下描述: 但是实现起来并非看上去如此简单。 现有测试环境如下: 当前CDB中有2个PDB,分别是PDB1和PDB2;每个PDB中都有一个相同名字的Local User,为KAMUS;每个KAMUS用户下都有一个TT表,表结构相同,数据不同。 首先按照想象,在CDB$ROOT中直接使用SYS用户查询,会报ORA-00942错误。 SQL> show user USER is “SYS” SQL> show con_name CON_NAME —————————— CDB$ROOT SQL> select count(*) FROM CONTAINERS(KAMUS.TT) WHERE CON_ID IN (3); select count(*) FROM CONTAINERS(KAMUS.TT) WHERE CON_ID IN (3) * ERROR at line 1: ORA-00942: table or view does not exist 这要求我们首先创建一个Common User。并赋予其足够的权限。赋予select any table权限是为了方便测试,在真实环境中你可能需要更精细地规划权限。 SQL>…