Oracle 下 unpin 的cursor 才能被移除

2014-11-24 18:10:40 · 作者: · 浏览: 1


测试就为证明以下两句话:


cursor is pined ,can't be age out. only freeable cursor can be flush.


The buffer is now unpinned and is a candidate for immediate aging out




--创建测试表


SQL>create table td as select * from user_tables;



--session A 修改表,注意没有commit


SYS@anqing2(rac2)> update td set tablespace_name='users';


719 rows updated.



--Session B修改表,同样不commit


SYS@anqing2(rac2)> update td set tablespace_name='users';


-- session A 没有commit的情况下,这里是hang住的,验证一下



--查看session ASID


SYS@anqing2(rac2)> select sid from v$mystat where rownum=1;



SID


----------


130


--查看Lock 信息


SYS@anqing2(rac2)> select sid,lmode,request from v$lock where type in ('TX','TM');



SID LMODE REQUEST


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


124 0 6


130 3 0


124 3 0


130 6 0



DML操作一般要加两个锁,一个是对表加模式为3TM锁,一个是对数据行的模式为6TX锁。只要操作的不是同一行数据,是互不阻塞的。



根据查询结果,我们看到,Session B 已经拿到了3级别的TM 锁, 现在在等待6级别的TX锁。 6级的TX 锁在session A130)持有,所以session B124)处于等待状态。



-- Flush shared pool


SYS@anqing2(rac2)> alter system flush shared_pool;


System altered.



-- 查看v$sql 里,对应的cursor 是否存在


SYS@anqing2(rac2)> select sql_text from v$sql where sql_text like 'update%';


SQL_TEXT


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


update td set tablespace_name=:"SYS_B_0"



我们的cursor 还存在v$sql 里。



-- session A 提交


SYS@anqing2(rac2)> commit;


Commit complete.



-- 提交之后,session A 对应的Lock 就释放了。


SYS@anqing2(rac2)> select sid,lmode,request from v$lock where type in ('TX','TM');



SID LMODE REQUEST


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


124 3 0


124 6 0



--session B 结束hang状态后在commit


SYS@anqing2(rac2)> update td set tablespace_name='users';


719 rows updated.


SYS@anqing2(rac2)> commit;


Commit complete.




-- 全部commit 之后,我们不flush,查看


SYS@anqing2(rac2)> select sql_text from v$sql where sql_text like 'update%';



SQL_TEXT


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


update td set tablespace_name=:"SYS_B_0"



对应的cursor 还存在



--我们flush 一下


SYS@anqing2(rac2)> alter system flush shared_pool;


System altered.



--查看cursor


SYS@anqing2(rac2)> select sql_text from v$sql where sql_text like 'update%';



刚才的cursor 已经不存在了。




以上测试只为证明一句话:


正在被pin 住的cursor 不能从shared pool里移除,只有unpincursor 才能被移除。