oracle根据操作资源的类型把锁分哪几类

62次阅读
没有评论

共计 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 小编将为大家输出更多高质量的实用文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-26发表,共计8461字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)