DM8的锁

一、达梦是如何实现其他数据库行锁的


官方手册有这么一段话:
“执行 INSERT、DELETE、UPDATE 操作时,设置事务号到 TID 字段。
这相当于隐式地对记录上了一把 TID 锁,INSERT、DELETE、UPDATE 操作不再需要额外的行锁,避免了大量行锁对系统资源的消耗。
达梦数据有写不阻塞读的特性,SELECT 操作已经消除了行锁,因此 DM 中不再有行锁的概念”
达梦数据库真的没有行锁?下面用实验证明下。

实验目的:验证官方文档这段话。
---本次使用 DML 操作导致会话阻塞的场景
--会话1:更新一行记录不提交
SQL> select * from yangkai1.tb1 where id=1;

LINEID     ID          NAME   AGE        
---------- ----------- ------ -----------
1          1           张三 23

used time: 32.907(ms). Execute id is 2500.
SQL>  update yangkai1.tb1 set name='张三' where id=1;
affect rows 1
used time: 3.372(ms). Execute id is 2501.
SQL> SELECT TRX_ID FROM V$SESSIONS WHERE SESS_ID = SESSID();

LINEID     TRX_ID              
---------- --------------------
1          7539471

used time: 1.009(ms). Execute id is 2502.    

会话2:更新同一行数据,会发生什么?
SQL>  update yangkai1.tb1 set name='李四' where id=1;
---会发现hang住    

查询会话1对应有哪些锁

查询会话2对应的有哪些锁

当事务 T2(事务号为 7539472)试图修改id=1这行数据,而该行数据正在被另一个事务 T1(事务号为 7539471)修改,此时事务 T2 会生成一个新的 TID 锁,其锁对象为事务号 7539471

可以发现两个会话都持有意向排它表锁(IX),防止其他会话对 tb1 表级变动,DM 中使用 TID 事务锁来控制行级并发,DM 会话 1使用独占排它事务锁(TID)来标记更新某行记录,并申请开启另外一个事务锁(TID)且 BLOCK=1 来阻止 DM会话 2 更新相同的行,DM 事务锁(TID)和多版本控制(MVCC)实现并发事务处理。


达梦数据库锁类型可以分为2类:
object锁:(类似oracle数据库的TM锁),用来保护对象的
(1)防止向正在使用 FAST LOADER 工具装载数据的表中插入数据、防止对存在未提交修改的表执行 ALTER TABLE、TRUNCATE TABLE 操作。
(2)防止多个事务同时修改同一个对象的字典定义(SCH,DSYNOM,table,VIEW)

TID锁:(类似于oracle的TX锁)防止多个事务同时修改同一行记录

二、达梦日常过程中锁运维实战

    • DDL引起的锁超时如何处理

在我们日常运维中,经常执行DDL操作,对于DDL操作引起的锁超时,我们如何解决?首先看其他数据库是如何解决的?在Oracle 11g以前,DDL语句是不会等待DML语句的。当DDL语句访问的对象正在执行DML语句,会立即报错“ORA-00054:resource busy and acquire with nowait specified”,而在Oracle 11g以后,DDL_LOCK_TIMEOUT参数可以修改这一状态。达梦数据库也是可以用oracle的办法解决,而且达梦数据对于锁超时非常人性化,DDL_LOCK_TIMEOUT默认给了10秒,最大可以设置604800秒生产环境我们可以用下面二个参数来延长锁超时时间,以及开启快速加列、修改列、删除列提高DDL操作的成功率。

SQL> SP_SET_PARA_VALUE (1, 'DDL_WAIT_TIME', 60);
DMSQL executed successfully
used time: 16.952(ms). Execute id is 1400.
SQL>  SP_SET_PARA_VALUE (1, 'ALTER_TABLE_OPT', 2);
DMSQL executed successfully
used time: 16.925(ms). Execute id is 1401.
    • DML引起的锁等待如何处理

---会话1:更新一行记录不提交
SQL>  update yangkai1.tb1 set name='张三' where id=1;
affect rows 1
--会话2:更新同一行
SQL>  update yangkai1.tb1 set name='李四' where id=1;
---会发现hang住    
立即通知相关联系人
一般情况下锁阻塞是导致应用服务不正常最常见的故障,当出现锁阻塞时,所有需要用到这个事务的业务都会无法正常服务。
处理流程如下:
a)用下面语句检查数据库中产生锁资源阻塞的线程的SESSION信息及正在执行的SQL
b)找出产生锁阻塞的线程信息及SQL后,并记录下来.然后通知相关人员,并协商锁释放方式.
c)如果无法中止客户程序,可以用下面的语句杀掉相关会话:
SQL> sp_close_session(134743448);
THE END
< <上一篇
下一篇>>