Oracle锁机制之分类和死锁

csdn推荐

文章目录

1 Oracle锁 1.1 简介

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

Oracle的锁机制是一种轻量级的锁定机制,不是通过构建锁列表来进行数据的锁定管理,而是直接将锁作为数据块的属性,存储在数据块首部。

在 Oracle 数据库中,它并不是对某个表加上锁或者某几行加上锁, 锁是以数据块的一个属性存在的。 也就是说, 每个数据块本身就存储着自己数据块中数据的信息,这个地方叫 ITL( Interested Transaction List), 凡是在这个数据块上有活动的事务,它的信息就会记录在这里面供后续的操作查询,一保证事务的一致性。

点击了解Oracle中 逻辑存储结构

在oracle数据库中,不存在真正意义上属于某个对象或数据的锁。oracle锁的信息是数据块的一个物理属性,而不是逻辑上属于某个表或某个行。

1.2 分类 1.2.1 用户和系统分

按用户和系统分可以分为自动锁和显示锁

显示锁( Manual Data Locks)

某些情况下,需要用户显示的锁定数据库操作要用到的数据,才能使数据库操作执行得更好,显示锁是用户为数据库对象设定的 1.2.2 锁级别分

按锁级别分可以分为排它锁和共享锁

排他锁(exclusive lock,即X锁)和共享锁(share lock,即S锁)

点击了解 oracle锁机制之悲观锁与乐观锁以及for update用法

1.2.3 锁类型分 1.2.3.1 内部闩锁

Oracle的内部闩锁(Latch)是一种特殊的低级别同步机制,用于保护共享数据结构,以避免并发访问时发生冲突。在Oracle数据库中,Latch作为一种轻量级的锁资源,主要工作在内存中,它允许多个进程不会同时修改某个特定的共享资源。

Latch特点:

在Oracle数据库中,Share Pool Latch和 Library Cache Latch都是用于保护共享内存区域访问的同步机制。

share pool latch和library cache latch 区别:

争用情况 性能影响 调优方向 数量关系 1.2.3.2 DDL锁

DDL锁作用:可以保护模式中对象的结构。

DDL锁细分:

会话执行DDL操作时,Oracle会自动的提交一次事务,然后自动给处理对象加锁,当DDL结束时,Oracle会隐式提交事务并释放DDL锁。与 DML不同,用户不能显示的使用DDL锁。

1.2.4 DML锁

也属于按类型分得锁,主要用于保护数据,主要保证访问时数据的完整性

DML 锁用于控制并发事务中的数据操纵,保证数据的一致性和完整性。主要用于保护并发情况下的数据完整性。

DML 语句能够自动地获得所需的 表级锁(TM)与 行级(事务)锁(TX)

1.2.4.1 TM锁

TM(表级锁):主要作用是防止在修改表的数据时,表的结构发生变化。例如会话S在修改表A的数据时它会得到表A的TM锁,而此时不允许其他会话对该表进行变更或者删除。

当一个事务通过INSERT、UPDATE、DELETE、MERGE或SELECT...FOR UPDATE等语句修改表时,就会获得一个表锁,也称为TM锁。这种锁的主要作用是为事务保留对表的DML访问权限,并防止与事务冲突的DDL操作

当事务获得行锁后,此事务也将自动获得该行的表锁(共享锁),以防止其它事务进行 DDL 语句影响记录行的更新。

事务也可以在进行过程中获得共享锁或排它锁,只有当事务显示使用 LOCK TABLE 语句显示的定义一个排它锁时,事务才会获得表上的排它锁,也可使用 LOCK TABLE 显示的定义一个表级的共享锁。

TM 锁包括了 SS、 SX、 S、 X 等多种模式,在数据库中用 0-6 来表示。不同的 SQL 操作产生不同类型的 TM 锁.

详解各种锁模式:

会话在做DML操作的时候,数据库会先申请数据对象上的共享锁,防止其他会话对此对象做DDL操作。一旦申请成功。 则会对要修改的记录申请排它锁。(如果此时其他会话正在修改数据,则等待其他事务结束后再增加排它锁)

1.2.4.2 TX锁

TX(事务锁或行级锁):也叫事务锁。当修改表中某行记录时。需要对将要修改的记录加行级锁。该锁属于排他锁,是在事务首次发起 DML 语句时获得的,保持到事务被提交或回滚。

TX 锁主要用于保护数据行的完整性,确保在多会话环境下对同一数据行的访问不会导致数据不一致的问题。

当TM锁获得后(即表级锁已经被锁定),系统再自动申请TX锁。

1.2.4.3 加锁过程和原理

当 Oracle 执行 DML 语句时,系统自动在所要操作的表上申请 TM 类型的锁。当 TM 锁获得后,系统再自动申请 TX 类型的锁,并将实际锁定的数据行的锁标志位进行置位。

这样在事务加锁前检查 TX 锁相容性时就不用再逐行检查锁标志,而只需检查 TM 锁模式的相容性即可,大大提高了系统的效率。

在数据行上只有 X 锁(排他锁)

在 Oracle 数据库中,当一个事务首次发起一个 DML 语句时就获得一个 TX 锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行 DML 语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后, TX 锁被释放,其他会话才可以加锁。

当 Oracle 数据库发生 TX 锁等待时,如果不及时处理常常会引起 Oracle 数据库挂起,或导致死锁的发生,产生ORA-600 的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。

加行锁原理:

一个事务要修改块中的数据,必须获得该块中的一个itl,通过itl和undo segment header中的transaction table,可以知道事务是否处于活动阶段。事务在修改块时(其实就是在修改行)会检查行中row header中的标志位,如果该标志位为0(该行没有被活动的事务锁住),就把该标志位修改为事务在该块获得的itl的序号,这样当前事务就获得了对记录的锁定,然后就可以修改行数据了,这也就是oracle行锁实现的原理。

1.2.4.4 共享方式的表级锁

共享方式的表级锁(Share)是对表中的所有数据进行加锁,该锁用于保护查询数据的一致性,防止其它用户对已加锁的表进行更新。

其它用户只能对该表再施加共享方式的锁,而不能再对该表施加独占方式的锁,共享更新锁可以再施加,但不允许持有共享更新封锁的进程做更新。

共享该表的所有用户只能查询表中的数据,但不能更新。

共享方式的表级锁只能用户用 SQL 语句来设置.

语句格式如下:

LOCK TABLE <表名>[,<表名>]... IN SHARE MODE [NOWAIT]

执行该语句,对一个或多个表施加共享方式的表封锁。

当指定了选择项 NOWAIT,若该锁暂时不能施加成功,则返回并由用户决定是进行等待,还是先去执行别的语句。

持有共享锁的事务,在出现如下之一的条件时,便释放其共享锁:

共享方式表级锁常用于一致性查询过程,即在查询数据期间表中的数据不发生改变

1.3 锁等待和死锁 1.3.1 定义

由于占用资源不能及时释放,会造成锁的等待。例如,当一个会话S1修改记录A,A被加锁,如果另一个会话S2也来修改记录A,那么第二个会话将得不到排它锁会一直等待,知道会话S1事务提交释放锁,会话S2才能对数据进行操作。

死锁是锁等待的一个特征,加入,当会话S1需要修改2个资源,这2个资源在同一个事务里,修改第一个对象A时对其加锁,修改第2个对象B时另一个会话S2获取了锁并锁定了B,等待A释放锁,那么就出现了死锁。

当出现死锁的时候可以使用下面的SQL尝试处理,例如下面是之前遇到的一个问题,SID869修改DICTEN表,且锁住了表。 SID1393尝试修改DICTEN表时死锁一直等待

1.3.2 死锁分析

在 Oracle 数据库中,当出现死锁时,Oracle 会自动检测到并记录相关信息。我们可以通过以下步骤查看和分析死锁日志:

使用 Oracle Enterprise Manager (OEM)

如果你有使用 OEM,可以通过其图形化界面查看和搜索死锁相关的信息。分析死锁日志

在 Alert 日志文件中,死锁会以 “ORA-00060: deadlock detected” 错误开始。以下是一个死锁日志示例及其分析方法:

示例死锁日志

*** 2024-06-05 14:23:45.123
DEADLOCK DETECTED (ID 0x70007b3c8)
[Transaction Deadlock]
  Current SQL Statement for this session:
  UPDATE employees SET salary = salary + 1000 WHERE employee_id = 101
  *** Deadlock graph:
        ---------Blocker(s)--------
        Resource Name: TX-00070007b3c8-00000000
        Lock Mode:     Exclusive
        Hold Mode:     Exclusive
        Wait Mode:     None
        Session ID:    34
        Session Serial #:  15
        Session Owner: HR
        ----------------------------
        ---------Waiter(s)--------
        Resource Name: TX-00070007b3c8-00000000
        Lock Mode:     Exclusive
        Hold Mode:     None
        Wait Mode:     Exclusive
        Session ID:    47
        Session Serial #:  8
        Session Owner: HR
        ----------------------------
  *** Final Blocker:
        Resource Name: TX-00070007b3c8-00000000
        Lock Mode:     Exclusive
        Hold Mode:     Exclusive
        Wait Mode:     None
        Session ID:    47
        Session Serial #:  8
        Session Owner: HR
*** 2024-06-05 14:23:45.123

Oracle V$ 视图

使用以下查询查看当前锁和等待的详细信息:

-- 查看当前锁信息
SELECT * FROM v$lock;
-- 查看等待事件
SELECT * FROM v$session_wait;
-- 查看死锁检测器信息
SELECT * FROM v$system_event WHERE event = 'enqueue';
-- 查看死锁是否存在
SELECT username, lockwait, status, machine, program   
FROM v$session WHERE sid IN (SELECT session_id FROM v$locked_object);
-- 查看死锁的详细信息
SELECT   
    l.xidusn, l.object_id, o.owner, o.object_name,   
    l.session_id, l.oracle_username, l.os_user_name, l.process,   
    DECODE(l.locked_mode, 0, '', 1, 'NULL', 2, '(SS)', 3, '(SX)', 4, '(S)', 5, '(SSX)', 6, '(X)', '??') locked_mode   
FROM   
    v$locked_object l, dba_objects o   
WHERE   
    l.object_id = o.object_id;
--分析死锁日志
SELECT   
    username, osuser, machine, terminal, program, sid, serial#, status, sql_address, sql_text   
FROM   
    v$session ss, v$sqltext sq   
WHERE   
    type='USER' AND ss.sql_address=sq.address   
ORDER BY   
    ss.sid, ss.serial#, sq.piece;

1.3.3 死锁解决

在Oracle中,当发生死锁时,用户或应用程序需要手动介入以解决问题。这可能包括终止导致死锁的事务、调整事务的隔离级别或锁策略、优化查询语句等

一旦确定了死锁的原因,可以采取相应的措施来解决它。这通常包括结束导致死锁的会话、优化数据库操作、修改Java代码等。

结束会话:使用 ALTER SYSTEM KILL SESSION 'sid,serial#'语句, 锁表进程中的 SID和SERIAL 字段的值,把所有的值全部杀掉即可,该命令可以结束导致死锁的会话。注意,这可能会导致数据丢失或不一致,因此应谨慎使用。

优化数据库操作:通过减少长时间的事务、优化查询语句、调整锁策略等方式来减少死锁的发生。

文章来源:https://blog.csdn.net/u012060033/article/details/139629948



微信扫描下方的二维码阅读本文

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容