理解Oracle TM和TX锁

在Oracle中有很多锁,通过v$lock_type视图可以查看Oracle中所有类型的锁,
在本篇文章中我们熟悉一下TM和TX锁的类型

SQL> select * from v$lock_type where type in (‘TM‘,‘TX‘);

TYPE     NAME            ID1_TAG            ID2_TAG             IS_USER DESCRIPTION
-------- --------------- ------------------ ------------------- ------- --------------------------------------------------------------------------------
TM       DML             object #           table/partition     YES     Synchronizes accesses to an object
TX       Transaction     usn<<16 | slot     sequence            YES     Lock held by a transaction to allow other transactions to wait for it

在v$lock_type视图中可以看到对TM和TX锁的描述,TM为DML锁,TX锁是事务锁,我们知道数据库中的数据有元数据和数据,
其中元数据就是表的本身,而数据就是指表里的数据,那么TM锁保护的就是元数据,TX锁保护的就是一般意义上的数据
我们知道当truncate一张大表和truncate一张小表所花费的时间是没有差异的,原因在于Oracle在处理的时候只在删除了元数据,
而没有真正删除表里的数据,所以会很快且和表的大小无关。
通过v$lock_type可以看到
TM锁中ID1_TAG表示的是一个对象号,ID2_TAG表示的是一个对象类型,是一个表还是分区
TX锁中ID1_TAG和ID2_TAG联合起来表示的是一个事务ID(如何根据这两列算出事务ID?待续)

通过例子学习TM/TX锁

--预先创建一张表

SQL> create table test(id int,name varchar2(30));

Table created

SQL> insert into test values(1,‘beijing‘);

1 row inserted

SQL> commit;

Commit complete

--更新一下

SQL> update test set name=‘shanghai‘ where id=1;

1 row updated

这次更新会在TEST表元数据上加上TM锁,在TEST数据上加上TX锁

SQL> select distinct sid from v$mystat;

       SID
----------
       153

SQL> select * from v$lock where sid=153;

ADDR     KADDR           SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
-------- -------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
4335184C 43351864        153 TM        54663          0          3          0        264          0
4339B56C 4339B590        153 TX       458794        341          6          0        264          0

可以看到TM和TX锁,通过以上知道TM锁的ID1表示OBJECT#,

SQL> select object_name,object_type from dba_objects where object_id=54663;

OBJECT_NAME     OBJECT_TYPE
--------------- -------------------
TEST            TABLE

TX锁的ID1和ID2表示了一个事务ID,通过相应的计算能够得到事务ID,我们可以查询v$transaction

SQL> select * from v$transaction;

ADDR         XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC STATUS     ....... XID              PRV_XID          PTX_XID
-------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----------       ---------------- ---------------- ----------------
4339B56C          7         42        341          2       2085        481         12 ACTIVE            07002A0055010000 0000000000000000 0000000000000000

总结:
1.查询不需要锁
2.加在行上锁的一定是排他锁 exclusive (row)
3.加在表上的锁最为复杂,可分为以下几种类型 metadata (table)   --也就是指v$lock表上lmode  2,3,4,5,6
4.要想锁定行首先锁定他的元数据

---开启另一会更改相同的数据观察v$lock

SQL> select distinct sid from v$mystat;

       SID
----------
       142

SQL> update test set name=‘guangzhou‘ where id=1;

会发现142会话被阻塞,

SQL> select * from v$lock where sid in (153,142);

ADDR     KADDR           SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
-------- -------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
43834450 43834464        142 TX       458794        341          0          6         72          0
4335184C 43351864        153 TM        54663          0          3          0       2094          0
433518F8 43351910        142 TM        54663          0          3          0         72          0
4339B56C 4339B590        153 TX       458794        341          6          0       2094          1

发现v$lock视图153会话BLOCK为1,这就表示153会话阻塞了别的会话,可以看到142会话在请求一个REQUEST 6 的锁,
因为我们这是模拟的阻塞,我们知道153的会话阻塞了142的会话,可以看到153和142的ID1/ID2所请求或持有的资源
是一样的,从这也可判断153阻塞了142的会话

--查询session

SQL> select * from v$session where sid in (153,142);

SADDR           SID    SERIAL#     AUDSID PADDR         USER# USERNAME                          COMMAND    OWNERID TADDR    LOCKWAIT STATUS   SERVER       SCHEMA# SCHEMANAME                     OSUSER                         PROCESS      MACHINE                                                          TERMINAL                       PROGRAM                                          TYPE       SQL_ADDRESS SQL_HASH_VALUE SQL_ID        SQL_CHILD_NUMBER PREV_SQL_ADDR PREV_HASH_VALUE PREV_SQL_ID   PREV_CHILD_NUMBER PLSQL_ENTRY_OBJECT_ID PLSQL_ENTRY_SUBPROGRAM_ID PLSQL_OBJECT_ID PLSQL_SUBPROGRAM_ID MODULE                                           MODULE_HASH ACTION                           ACTION_HASH CLIENT_INFO                                                      FIXED_TABLE_SEQUENCE ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# LOGON_TIME  LAST_CALL_ET PDML_ENABLED FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER RESOURCE_CONSUMER_GROUP          PDML_STATUS PDDL_STATUS PQ_STATUS CURRENT_QUEUE_DURATION CLIENT_IDENTIFIER                                                BLOCKING_SESSION_STATUS BLOCKING_INSTANCE BLOCKING_SESSION       SEQ#     EVENT# EVENT                                                            P1TEXT                                                                   P1 P1RAW    P2TEXT                                                                   P2 P2RAW    P3TEXT                                                                   P3 P3RAW    WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS                                                        WAIT_TIME SECONDS_IN_WAIT STATE               SERVICE_NAME                                                     SQL_TRACE SQL_TRACE_WAITS SQL_TRACE_BINDS
-------- ---------- ---------- ---------- -------- ---------- ------------------------------ ---------- ---------- -------- -------- -------- --------- ---------- ------------------------------ ------------------------------ ------------ ---------------------------------------------------------------- ------------------------------ ------------------------------------------------ ---------- ----------- -------------- ------------- ---------------- ------------- --------------- ------------- ----------------- --------------------- ------------------------- --------------- ------------------- ------------------------------------------------ ----------- -------------------------------- ----------- ---------------------------------------------------------------- -------------------- ------------- -------------- --------------- ------------- ----------- ------------ ------------ ------------- --------------- ----------- -------------------------------- ----------- ----------- --------- ---------------------- ---------------------------------------------------------------- ----------------------- ----------------- ---------------- ---------- ---------- ---------------------------------------------------------------- ---------------------------------------------------------------- ---------- -------- ---------------------------------------------------------------- ---------- -------- ---------------------------------------------------------------- ---------- -------- ------------- ----------- ---------------------------------------------------------------- ---------- --------------- ------------------- ---------------------------------------------------------------- --------- --------------- ---------------
44309734        142         56 4294967295 44226F64          0 SYS                                     6 2147483644 43395CA0 43834464 ACTIVE   DEDICATED          0 SYS                            livan                          12940:6372   WORKGROUP\LENOVO-PC                                              LENOVO-PC                      plsqldev.exe                                     USER       401CE71C        1521039957 28tf955dakfkp                0 403E63FC            356401299 9m7787camwh4m                 0                                                                                     PL/SQL Developer                                  1190136663 命令窗口 - 新建                   1316471608                                                                                  6083         54663              1           59602             0 2015/1/22 1         1884 NO           NONE          NONE            NO                                           DISABLED    ENABLED     ENABLED                        0                                                                  VALID                                   1              153         51        186 enq: TX - row lock contention                                    name|mode                                                        1415053318 54580006 usn<<16 | slot                                                       458794 0007002A sequence                                                                341 00000155    4217450380           1 Application                                                               0            1884 WAITING             ZDJS                                                             DISABLED  FALSE           FALSE
4431717C        153         21 4294967295 442263EC          0 SYS                                     0 2147483644 4339B56C          INACTIVE DEDICATED          0 SYS                            livan                          12940:6372   WORKGROUP\LENOVO-PC                                              LENOVO-PC                      plsqldev.exe                                     USER       00                       0                                403E63FC            356401299 9m7787camwh4m                 0                                                                                     PL/SQL Developer                                  1190136663 命令窗口 - 新建                   1316471608                                                                                  5729         49440              3           21372             0 2015/1/22 1         3755 NO           NONE          NONE            NO                                           DISABLED    ENABLED     ENABLED                        0                                                                  NO HOLDER                                                         351        259 SQL*Net message from client                                      driver id                                                        1952673792 74637000 #bytes                                                                    1 00000001                                                                           0 00          2723168908           6 Idle                                                                      0            3755 WAITING             ZDJS                                                             DISABLED  FALSE           FALSE
 

可以看到v$session中有一个LOCKWAIT列,改列就对应到了v$lock视图的KADDR  ,其中V$LOCK中的ADDR对应到v$transaction中的ADDR找到对应的session信息,可以通过v$session中的SQL_ID找到对应的SQL

 SQL> select sql_text from v$sql where sql_id=‘28tf955dakfkp‘;

SQL_TEXT
--------------------------------------------------------------------------------
 update test set name=‘guangzhou‘ where id=1

可以看到哪个到底哪个语句被阻塞了

在v$session中可以142会话BLOCKING_SESSION_STATUS列为VALID,这也说明该会话被阻塞了,BLOCKING_SESSION列说名阻塞他的到底是哪个会话,BLOCKING_INSTANCE表示阻塞发生哪个实例
通过v$session的ROW_WAIT_OBJ#,ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW#就可以求出一个ROWID,有了ROWID就知道了修改哪条数据了

SQL> select dbms_rowid.rowid_create(1,ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#)
  2  from v$session where sid=142;

DBMS_ROWID.ROWID_CREATE(1,ROW_
------------------------------
AAANWHAABAAAOjSAAA

根据这个rowid可以求出是哪条数据:

SQL> select * from test where rowid=‘AAANWHAABAAAOjSAAA‘;

                                     ID NAME
--------------------------------------- ------------------------------
                                      1 beijing
                                    

lock 保护数据库对象
latch 闩  :保护的内存结构,凡是有共享的地方都有lock或latch 在同一时刻绝对是串行修改

时间: 2024-10-12 18:04:16

理解Oracle TM和TX锁的相关文章

ORACLE的TM锁和TX锁

根据保护的数据不同,ORACLE的数据库锁分为以下几大类: 1.DML锁(data locks数据锁),用于保护数据的完整性: 2.DDL锁(dictionary locks字典锁),用于保护数据库对象的结构,例如表.索引的结构定义: 3.内部锁或闩(internal locks or latches),用于保护内部结构 在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁. 当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的

Oracle TM锁和TX锁

本文主要介绍Oracle中的TM锁,了解当我们通过sql语句访问数据库中的同一表对象时,此时如果多个用户对同一表对象进行操作的话,可能会产生数据不一致,关于数据不一致,请参考数据库事务的一致性和原子性浅析,oracle解决事务在多线程情况下的数据不一致问题,主要是通过两种锁,一种是悲观锁,也就是我接下来要说的,另一种是乐观锁,关于这两种锁的介绍同样也请参考数据库事务的一致性和原子性浅析. TM锁和TX锁就是悲观锁的一部分,那么oracle是怎么通过TM锁TX锁来解决多用户访问同一对象,保证数据一

深入理解Oracle RAC 12c

深入理解Oracle RAC 12c(顶尖专家权威指南唯一最新版数据库著作 Oracle第一社区技术大牛翻译 Amazon五星推荐) [美]Syed Jaffar Hussain(赛义德 贾法尔 侯赛因),Tariq Farooq(塔里克 法鲁克),Riyaj Shamsudeen(瑞亚吉沙姆斯丁),Kai Yu(于凯) 著   赵燚 梁涛 程飞 李真旭 译 ISBN 978-7-121-24066-9 2014年10月出版 定价:99.00元 488页 16开 编辑推荐 <深入理解 Oracl

深入理解Oracle RAC 12c 笔记

深入理解Oracle RAC 12c 跳转至: 导航. 搜索 目录 1 概述 2 集群件管理和故障诊断 3 运行实践 4 新特性 5 存储和ASM 6 应用设计上的问题 7 管理和调优一个复杂的RAC环境 8 备份与恢复 9 网络实践 10 优化RAC数据库 11 锁与死锁 12 并行查询 13 集群件和数据库升级 14 RAC One Node 概述 p5 RAC使用缓存融合技术来管理所有节点的数据缓存并保持一致... 为什么不从高速IO网络读取,而是从其他节点的缓存? p15 GCS GES

Oracle事务之一:锁和隔离

Oracle事务之一:锁和隔离 一. 事务概述 事务管理是数据库处理的核心.数据库既要保证用户能并发地执行事务,还要保证数据库的一致性. 当第一条可执行的SQL开始执行,就隐形地开始了一个事务,直到遇到下面的几种情况: 1.Commit:提交事务. 2.RollBack:回滚. 3.DDL语句:执行和提交DDL语句结果前首先提交当前所有DML语句,成为隐式提交. 4.程序正常退出:自动提交. 5.不正常的程序失败:隐式回滚. 二.事务特性 事务的四个特性:A(原子性).C(一致性).I(隔离性)

数据库隔离级别深入理解(ORACLE)

TRANSACTION_READ_UNCOMMITTED 1 这种隔离级别最低,脏读,不可重复读,幻读都会发生,我用的oracle,并没有支持这个级别,不作研究. TRANSACTION_READ_COMMITTED  2  This is the default transaction isolation level. Each query executed by a transaction sees only data that was committed before the query

深入理解Oracle中的latch

深入理解Oracle中的latch 串行化 概述 串行化 - 数据库系统本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库, 多个用户同时在相同的物理位置上写数据时,不能发生互相覆盖的情况,这叫做串行化,串行化会降低系统的并发性,但这对于保护数据结构不被破坏来说则是必需的.在Oracle数据库中,通过闩锁(latch)和锁定(lock)来解决这两个问题.闩锁和锁定既有相同点又有不同点.相同点在于它们都是用于实现串行化的资源.而不同点则在于闩锁(Latch)是一个低级别

【问底】陈焕生:深入理解Oracle 的并行执行

摘要:Oracle并行执行是一种分而治之的方法.执行一个sql 时,分配多个并行进程同时执行数据扫描,连接以及聚合等操作,使用更多的资源,得到更快的sql 响应时间.并行执行是充分利用硬件资源,处理大量数据时的核心技术. Oracle并行执行是一种分而治之的方法.执行一个sql 时,分配多个并行进程同时执行数据扫描,连接以及聚合等操作,使用更多的资源,得到更快的sql 响应时间.并行执行是充分利用硬件资源,处理大量数据时的核心技术. 在本文中,在一个简单的星型模型上,我会使用大量例子和sql m

ORACLE查询数据库的锁表情况

  查询数据库的锁表情况语句如下: SELECT p.spid,a.serial#, c.object_name,b.session_id,b.oracle_username,b.os_user_name FROM v$process p,v$session a, v$locked_object b,all_objects c WHERE p.addr=a.paddr AND a.process=b.process AND c.object_id=b.object_id 如果表因为某些情况出现死