共计 8461 个字符,预计需要花费 22 分钟才能阅读完成。
本篇内容介绍了“oracle 根据操作资源的类型把锁分哪几类”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
数据库锁概述
oracle 在事务执行会自动对操作资源进行锁定,防止其它事务对同一个资源做破坏性存取。数据库自动根据操作资源类型不同,对资源加上各种类型的锁。
oracle 根据操作资源的类型,把锁分为如下分类
DML 锁:保护数据,例如表锁锁定这个表,行级锁锁定选择的行
DDL 锁:保护对象的定义,例如表和视图的数据字典
系统锁:保护内部数据库的结构,例如数据文件,latch,mutexes 和内部锁定,这些都是自动实现的
dml 锁
一个 DML 锁,又叫做数据锁,用来保证多个用户并发事务执行时的数据完整性。
例如: 一个 DML 锁可以防止两个用户在在线商店购买最后一本书。DML 语句自动获取如下类型的锁:行级锁 TX 和表锁 TM
示例
SQL update t_test set a=1;
2 rows updated.
可见 产生事务会 在原有基础上添加 2 种锁,一为表锁 tm, 其锁模式为行级排它锁, 二为行锁 tx,其锁模式为排它锁
SQL /
SID TY
ID1
LMODE
REQUEST
———- — ———- ———- ———- ———-
25 AE
133
0
4
0
25 TX
65566 1359
0 dml 锁
25 TM
76989
0
3
0 dml 锁
SQL desc dba_dml_locks;
Name
Null? Type
—————————————– ——– —————————-
SESSION_ID
NUMBER
OWNER
NOT NULL VARCHAR2(128)
NAME
NOT NULL VARCHAR2(128)
MODE_HELD
VARCHAR2(13)
MODE_REQUESTED
VARCHAR2(13)
LAST_CONVERT
NUMBER
BLOCKING_OTHERS
VARCHAR2(40)
SQL select session_id,owner,name,mode_held,mode_requested,last_convert,blocking_others from dba_dml_locks
SESSION_ID OWNER
MODE_HELD
MODE_REQUESTE LAST_CONVERT BLOCKING_OTHERS
———- ——————– ——————– ————- ————- ———— —————————————-
25 USER_DDL
T_TEST
Row-X (SX) None
1052 Not Blocking
oracle 在锁定行所在的数据块(事务需要修改的数据块)中存储锁的相关信息。数据库使用队列机制获取行级锁,如果事务需要一个未锁定行的锁,那么事务在数据块中在放一个锁, 事务修改的每一行都会指向数据块头部(ITL)中的事务 ID。当事务结束时,事务 ID 仍然留在数据块头部的 ITL 中。如果不同的事务想要修改一行数据,数据库会使用 ITL 中原来事务的 ID,通过查询相关动态视图判断事务是否还存在,及锁是否存在,如果锁仍然是活动的,那么会话排队等待事务结束后的通知,如果锁不活动了,那么,事务得到锁,并更新 ITL 表
小结
oracle 会在数据块中记录锁的信息及事务的信息
oracle 会话如需要获取表记录的锁,先查找表记录所属数据块是否已存在锁,在数据块中存储事务及锁的数据结构叫 itl
itl 在数据块的头块
oracle 会话发现修改数据块有活动事务,即持锁,它会等待
oracle dml 锁是采用排队机制实现即先到先到,后到后等算法
oracle 的在获取到数据块进行修改时,需要在数据块头部的 itl 修改数据块的事务状态, 表明数据块正被修改
tm 锁即表锁,会有 5 种不同的锁模式,之前文章讲过,不再复述
ddl 锁
当 DDL 操作或者关联操作某对象时,DDL 锁保护对象的定义。只有在 DDL 语句中修改或者引用的对象才被锁定,数据库不会锁定整个数据字典。oracle 数据库代表 DDL 事务自动实现 DDL 锁。
用户不能显式获得 DDL 锁。例如,一个用户创建一个存储过程,数据库自动获得存储过程中引入的对象的 DDL 锁。DDL 锁阻止存储过程编译过程中这些对象的修改和删除
小结
ddl 锁保存数据定义的数据结构
ddl 锁只有在修改数据定义的数据结构或引用数据定义的数据结构,才会持有 ddl 锁
修改数据定义的数据结构操作,比如:create table,alter table 类似的语句
引用数据定义的数据结构操作,比如:基于源表创建存储过程或调用执行存储过程(因为必须保证在执行存储过程期间依赖基表的完整性)
ddl 锁由 oracle 自身控制,人为无法控制,无法显式获取 ddl 锁
ddl 锁一般看不到,因为 ddl 操作极快
ddl 锁底层是通过锁定数据字典实现
SQL desc dba_ddl_locks;
Name
Null? Type
—————————————– ——– —————————-
SESSION_ID
NUMBER
OWNER
VARCHAR2(128)
NAME
VARCHAR2(1000)
TYPE
VARCHAR2(40)
MODE_HELD
VARCHAR2(9)
MODE_REQUESTED
VARCHAR2(9)
即使没有执行数据库事务,仍存在 ddl 锁,下述 ddl 锁就是保护各种对象类型的定义结构不被破坏
SQL select session_id,owner,name,type,mode_held,mode_requested from dba_ddl_locks;
SESSION_ID OWNER
TYPE
MODE_HELD MODE_REQU
———- ——————– ——————– —————————————- ——— ———
32 SYS
KUPU$UTILITIES
Table/Procedure/Type
Null
None
32 SYS
STANDARD
Table/Procedure/Type
Null
None
32 SYS
STANDARD
Table/Procedure/Type
Null
None
32 SYS
DBMS_PRVT_TRACE Table/Procedure/Type
Null
None
74 SYSTEM
SYSTEM
18
Null
None
76 SYSTEM
SYSTEM
18
Null
None
75 SYSTEM
SYSTEM
18
Null
None
74 SYS
DBMS_OUTPUT
Body
Null
No
SQL grant execute on dbms_lock to system;
Grant succeeded.
create or replace procedure proc_t_test
as
v_cnt int;
begin
dbms_lock.sleep(300);
select count(a) into v_cnt from t_test;
end;
/
– 未执行相关与 DDL 前 2 个测试会话各为 25 及 74 的运行信息
SQL select session_id,owner,name,type,mode_held,mode_requested from dba_ddl_locks where session_id in (25,74)
SESSION_ID OWNER
NAME
TYPE
MODE_HELD MODE_REQU
———- ————— ————————————————– —————————————- ——— ———
25 SYSTEM
SYSTEM
18
Null
None
74 SYSTEM
SYSTEM
18
Null
None
74 SYS
DBMS_OUTPUT
Body
Null
None
25 SYS
DBMS_LOCK
Body
Null
None
74 SYS
DBMS_OUTPUT
Table/Procedure/Type
Null
None
25 LBACSYS
LBAC_EVENTS
Body
Null
None
25 LBACSYS
LBAC_EVENTS
Table/Procedure/Type
Null
None
25 SYS
DBMS_APPLICATION_INFO
Body
Null
None
74 SYS
DBMS_APPLICATION_INFO
Body
Null
None
25 SYS
DBMS_STANDARD
Table/Procedure/Type
Null
None
74 SYS
PLITBLM
Table/Procedure/Type
Null
None
SESSION_ID OWNER
NAME
TYPE
MODE_HELD MODE_REQU
———- ————— ————————————————– —————————————- ——— ———
74
SYSTEM
73
Share
None
25
SYSTEM
73
Share
None
25 SYS
DBMS_APPLICATION_INFO
Table/Procedure/Type
Null
None
74 SYS
DBMS_APPLICATION_INFO
Table/Procedure/Type
Null
None
25 MDSYS
GETMDSYSEVENT
Table/Procedure/Type
Null
None
25 SYS
DBMS_LOCK
Table/Procedure/Type
Null
None
25 SYS
DATABASE
18
Null
None
74 SYS
DATABASE
18
Null
None
19 rows selected.
— 会话 25
执行存储过程
SQL exec proc_t_test;
— 会话 74
正在执行存储过程期间删除存储过程
卡住
SQL drop procedure proc_t_test;
SQL select session_id,owner,name,type,mode_held,mode_requested from dba_ddl_locks where session_id in (25,74) and mode_held= Exclusive or mode_requested= Exclusive
SESSION_ID OWNER
NAME
TYPE
MODE_HELD MODE_REQU
———- —————————— ————————————————– ——————– ——— ———
74 SYSTEM
PROC_T_TEST
Table/Procedure/Type Exclusive None
SQL /
SESSION_ID OWNER
NAME
TYPE
MODE_HELD MODE_REQU
———- —————————— ————————————————– ——————–
25 SYSTEM
PROC_T_TEST
Table/Procedure/Type Null
None 持锁会话(持锁模式为 null)
74 SYSTEM
PROC_T_TEST
Table/Procedure/Type Exclusive None 等待会话 (请求持锁模式为排它模式)
SQL select distinct type from dba_ddl_locks;
TYPE
——————–
73
Table/Procedure/Type
18
10
Body
23
6 rows selected.
— 可见产生 ddl 锁,不会体现在 v$lock 中
SQL select sid,type,id1,id2,lmode,request from v$lock where sid in (25,74);
SID TY
ID1
LMODE
REQUEST
———- — ———- ———- ———- ———-
74 AE
133
0
4
0
25 AE
133
0
4
0
– 可见产生 ddl 锁,持 ddl 锁的会话等待事件为 library cache pin
SID STATUS BLOCKING_SESSION EVENT
———- ——– —————- —————————————————————-
25 ACTIVE
PL/SQL lock timer
74 ACTIVE
25 library cache pin
– 等待事件对应如下的 library cache pin,library cache pin 对 sga 的 library cache 内存数据结构的一种保存机制
SQL col type for a50
SQL col name for a35
SQL col id1_tag for a30
SQL col id2_tag for a30
SQL col description for a50
SQL select type,name,id1_tag,id2_tag,is_user,description from v$lock_type where lower(description) like %library%
TYPE
NAME
ID1_TAG
ID2_TAG
IS_ DESCRIPTION
———- ———————————– ——————– ————————- — —————————————————————————————————-
V
Library Cache Lock 3
hash value
hash value
NO Synchronizes accesses to library cache objects
E
Library Cache Lock 2
hash value
hash value
NO Synchronizes accesses to library cache objects
L
Library Cache Lock 1
hash value
hash value
NO Synchronizes accesses to library cache objects
Y
Library Cache Pin 3
hash value
hash value
NO Synchronizes accesses to the contents of library cache objects
G
Library Cache Pin 2
hash value
hash value
NO Synchronizes accesses to the contents of library cache objects
N
Library Cache Pin 1
hash value
hash value
NO Synchronizes accesses to the contents of library cache objects
IV
Library Cache Invalidation
object #
time stamp
NO Synchronizes library cache object invalidations across instances
7 rows selected.
ddl 锁又分为几种类型:
排它 ddl 锁
排它 DDL 锁阻止其他会话获得 DDL 和 DML 锁。例如删除一个表的操作会阻止同时在表中添加一列的 DDL 操作,反之亦然。排它的 DDL 锁在整个 DDL 操作时有效,执行结束会自动提交
共享 ddl 锁
共享 DDL 锁防止其它冲突的 DDL 操作,但是允许类似的 DDL 操作并发执行。例如当执行 DDL 操作时,会对引用的所有表加 DDL 共享锁,其它事务可以建存储过程时加共享 DDL 锁,但
是不允许加排它 DDL 锁
易碎解析锁
sql 或者 pl/sql 会持有应用对象的解析锁。解析锁被用来实现当引用的对象被修改或者删除时,共享 sql 区域会失效。解析锁之所以易碎,是因为它不允许 DDL 操作,当 DDL 冲突
时,会被打碎
小结
上述的 ddl 锁和 dml 锁不太一样,不好理解。后续会有专门文章分享。
系统锁
oracle 使用系统锁保护内部的数据库和内存结构,用户不能操作这些内部锁, 它由数据库自己控制。
系统锁分为 latch,mutexes, 内部锁 internal lock
闩 latch
latch 是为了保护 sga 内存数据结构的一致,实现的一种底级锁机制
SQL select count(*) from v$latchname;
COUNT(*)
———-
902
SQL select distinct type from v$latchname;
TYPE
—-
SGA
OSP
SQL
SQL select name,hash,type from v$latchname where lower(name) like %library%
NAME
HASH TYPE
—————————————————————- ———- —-
library cache load lock
2952162927 SGA
mutex
mutex 不同上于上述的 latch,latch 保护一组对象,而 mutex 更低级,它仅保护一个对象,它是代码层面的,相当底层
SQL select mutex_type from v$mutex_sleep;
MUTEX_TYPE
——————————–
Row Cache
Library Cache
Cursor Pin
内部锁
它是高级别,比 latch 和 mutex 更复制,用于其它用途。数据库具有一些类型的内部锁:
数据字典缓存锁
这种锁时间短,当数据字典实体被修改时,用来保护相关内容。这种锁确保语句解析期间,能够看到对象的一致性视图。数据
字典锁是共享和排它的。解析结束时,共享锁被释放,DDL 操作结束时,排它锁被释放
文件和日志管理锁
这种锁保护各种文件,例如,内部锁保护控制文件,确保一个时间点只有一个进程能够修改。另外的锁能协调归档和在线日志。当
多实例共享模式挂载数据库或者单实例排它挂载时会对数据文件加锁。由于文件锁标识着文件的状态,这些锁持续的时间一般都比较长
表空间和 undo 段锁
用来保护表空间和 undo 段,例如所有实例必须对表空间是否在线达成一致
“oracle 根据操作资源的类型把锁分哪几类”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!