Oracle中的锁和10704对高级队列锁

锁是数据库用来控制共享资源并发访问的机制,是用来保护和用户相关的资源,如:表、用户、会话等。

一、Oracle锁的种类

Oracle里锁分为三大类:

高级队列锁:TM,TX锁等等 视图V$LOCK

中级内存锁:Library cache lock

Library cache pin(堆)

Row cache lock;

Buffer pin lock;

低级内存锁:Latch

Mutex

高级队列锁Lock与低级内存锁的区别:

1.Lock的种类多,如TM,TX,TT等等;

2.Lock作用于数据库Object,Lacth只作用于SGA内存中;

3.Lock的释放需要等到事务结束,Latch是瞬间的占用和释放;

4.Lock存在死锁,Latch不存在死锁(因free lock机制)

低级内存锁与中级内存锁的区别,主要在于低级内存锁有lock free机制(无锁式编程):即请求latch时,如果该latch不可用,进程会在CPU中等待小段时间(spin)然后重新请求latch。如果依然不可用,该进程会重复以上步骤去请求latch。重复的次数默认值为2000(mutex为500)。如果在重复次数内还是请求不到latch,进程会在v$session_wait中记录latch free等待事件,然后释放cpu,转入睡眠状态。当睡眠一定时间后,进程被唤醒并重复上面的过程,一直到成功获取latch。因此低级内存锁避免了死锁的存在。此外,中级内存锁往往执行多条记录才会释放,而低级内存锁执行几条就可能会释放。

二、Oracle锁的模式

锁模式可粗略的分为空锁,共享和独占:

空 锁:1号锁,空锁,通常只起标志性作用,保证内存不会被释放。

共享锁:2-5号锁,包括RS(行共享)、RX(行专用)、S(共享锁)、SRX(共享行专用),允许部分DML操作,数字越大影响的操作越大。

独占锁:6号锁,exclusive独立访问使用,是限制最高级别的锁,禁止所有DML操作。

说明:Oracle中多数锁都是有着多种模式的,除高级队列锁TM外,中级内存锁Library Cache Lock/pin、buffer pin也是有多种模式的。

本文主要以跟踪高级队列锁为主:

TM锁定的是对象,所以叫对象锁,或者表锁,用来阻塞DML(或DDL)的运行,通常是持有2-6号锁,1号较少。

TX即事务独占锁,是所有加在行上的锁的总称。模式只有两种,要么无锁,要么独占锁(6号);

三、跟踪高级队列锁Lock示例

10704事件可以帮助我们跟踪锁和队列的使用情况,下面先以update为例,用10704事件来观察锁的状态:

sqlplus cheng/oracle

SQL> select * from v$version;

BANNER


Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

PL/SQL Release 11.2.0.4.0 - Production

CORE 11.2.0.4.0 Production

TNS for Linux: Version 11.2.0.4.0 - Production

NLSRTL Version 11.2.0.4.0 - Production

SQL> select * from test_t1;

ID NAME


1 aaaaaa

2 aaaaaa

3 aaaaaa

4 aaaaaa

5 aaaaaa

6 aaaaaa

7 aaaaaa

8 aaaaaa

9 aaaaaa

10 aaaaaa

10 rows selected.

SQL> alter session set events '10704 trace name context forever, level 12'; --开启10704跟踪

Session altered.

SQL> update test_t1 set NAME='bbbbbb' where id<5; --更新几条数据

4 rows updated.

SQL> commit; --提交数据

Commit complete.

SQL> alter session set events '10704 trace name context off'; --关闭10704跟踪

Session altered.

oracle@localhost \~ cd ORACLE_BASE/diag/rdbms/orcl/orcl/trace/

oracle@localhost trace$ more orcl_ora_4992.trc --提取日志分析

*** 2026-07-05 15:58:46.636

ksqgtl *** CU-bd59a970-00000000 mode=6 flags=0x10000 timeout=300 *** --申请持有游标锁

ksqgtl: no transaction

ksqgtl: use existing ksusetxn DID

ksqgtl:

ksqlkdid: 0001-0015-00000017

*** 2026-07-05 15:58:46.636

*** ksudidTrace: ksqgtl

ksusesdi: 0000-0000-00000000

ksusetxn: 0001-0015-00000017

ksqgtl: RETURNS 0 --获得游标锁

*** 2026-07-05 15:58:46.639

ksqrcl: CU,bd59a970,0

ksqrcl: returns 0 --释放游标锁

*** 2026-07-05 15:58:46.639

ksqgtl *** TM-00015b7d-00000000 mode=3 flags=0x401 timeout=21474836 *** --申请持有TM锁(3号)

ksqgtl: xcb=0xbbeb52b8, ktcdix=2147483647, topxcb=0xbbeb52b8

ktcipt(topxcb)=0x0

*** 2026-07-05 15:58:46.639

ksucti: init txn DID from session DID

ksqgtl:

ksqlkdid: 0001-0015-00000017

*** 2026-07-05 15:58:46.639

*** ksudidTrace: ksqgtl

ktcmydid(): 0001-0015-00000017

ksusesdi: 0000-0000-00000000

ksusetxn: 0001-0015-00000017

ksqgtl: RETURNS 0 --获得TM锁

*** 2026-07-05 15:58:46.639

ksqgtl *** TX-00090011-0000058b mode=6 flags=0x401 timeout=0 *** --申请持有TX锁(6号独占)

ksqgtl: xcb=0xbbeb52b8, ktcdix=2147483647, topxcb=0xbbeb52b8

ktcipt(topxcb)=0x0

*** 2026-07-05 15:58:46.639

ksucti: init session DID from txn DID:

ksqgtl:

ksqlkdid: 0001-0015-00000017

*** 2026-07-05 15:58:46.639

*** ksudidTrace: ksqgtl

ktcmydid(): 0001-0015-00000017

ksusesdi: 0000-0000-00000000

ksusetxn: 0001-0015-00000017

ksqgtl: RETURNS 0 --获得TX锁

--此时COMMIT提交

*** 2026-07-05 15:58:57.519

ksqrcl: TX,90011,58b

ksqrcl: returns 0 --释放TX锁

*** 2026-07-05 15:58:57.519

ksqrcl: TM,15b7d,0

ksqrcl: returns 0 --释放TM锁

以上即是update test_t1 set NAME='bbbbbb' where id<5语句的锁的状态过程

分析:

TM-00015b7d-00000000 mode=3

TM锁ID1对应的是Object_ID,00015b7d(十六进制)>88957(十进制)

SQL> select object_id,object_name from dba_objects where object_id=88957;

OBJECT_ID OBJECT_NAME


88957 TEST_T1

可知在update执行过程中,TEST_T1持有的是3号锁,不会堵塞DML操作。

TX-00090011-0000058b mode=6

即对应update test_t1 set NAME='bbbbbb' where id<5语句,可见Update四行,只产生一个TX锁。

相关推荐
imDwAaY18 分钟前
Redis 也能做消息队列?从 Stream 的存储讲到消费确认
数据库·redis·缓存
@Mike@28 分钟前
13-数据库学习笔记(查询执行处理模型)
数据库·笔记·学习
弈栈录1 小时前
MySQL 事务、索引与锁:后端开发必须掌握的数据库基础
数据库·后端
9624561 小时前
餐饮 SaaS 优惠券系统架构演进(三):优惠计算引擎——商品级计价、冲突策略与优惠分摊
java·数据库·spring boot
染指11101 小时前
135.Agent-多Agent框架-LangChain多智能体(SubAgents子代理)
数据库·人工智能·设计模式·langchain·agent·agents
Elastic 中国社区官方博客1 小时前
错误最多的服务运行正常:使用 ES|QL 从日志进行根因分析
大数据·运维·数据库·sql·elasticsearch·搜索引擎·全文检索
做运维的阿瑞2 小时前
mysql数据库视图笔记:创建、修改、删除与适用场景
数据库·笔记·mysql
Seraphina362 小时前
DVWA(SQL Injection-High,XSS Reflected-Medium,XSS Stored-Medium)
数据库·经验分享·sql·网络安全·xss
@Mike@2 小时前
12-数据库学习笔记(五种连接算法)
数据库·笔记·学习
Omics Pro2 小时前
之江实验室NAR|虚拟细胞3阶段训练范式
数据库·人工智能·算法·机器学习·自然语言处理