OB锁机制分析和测试

OB锁机制分析

OB锁机制:https://www.oceanbase.com/docs/community/observer-cn/V3.1.3/0000000000161645

ob的锁是行级锁,没有表锁的概念,行级锁只有互斥行锁。

OceanBase 数据库使用了多版本两阶段锁来维护其并发控制模型的正确性,锁机制是保证正确的数据并发性和一致性很重要的一点。

image-20220523111634757

session 1:
begin;
select * from t1 where a = 1566 for update;

session 2:
begin; select * from t1 where a = 1566 for update;

此时查看锁的信息:

SELECT * FROM v$lock;

img

可以看到addr直接定位到锁住的行

SELECT * FROM gv$lock_wait_stat;

image-20220523110348851

image-20220523110508488

1. 锁与DDL测试

session 1 :

MySQL [test]> select now(6); begin;select * from t3 for update;
+----------------------------+
| now(6)                     |
+----------------------------+
| 2022-05-23 11:23:42.763281 |
+----------------------------+
1 row in set (0.027 sec)

Query OK, 0 rows affected (0.012 sec)

+----+-------+----------------------+----------------------+-------+
| a  | b     | c                    | d                    | e     |
+----+-------+----------------------+----------------------+-------+
|  1 |  6908 | w)/gf.}              | =                    | 18937 |
|  2 | 71417 | dj>;tu               | 1[b=/.               | 15170 |
|  3 |  3759 | zpaugx8)irf2>5       | ]e`m;$+d             | 63122 |
|  4 | 36326 | {%qb53:c/b(:y]qd((.  | k                    | 22437 |
|  5 | 57946 | 41xauq9;xv<q#v[3?`[t | -%!}rh{;.({wpcf      | 52579 |
|  6 | 55555 | sb^u/zuu}kwbg8;j     | r5a#"?h0]&           | 53704 |
|  7 | 79089 | u"#d                 | +e0vn?}t             |  4398 |
|  8 | 55156 | *cgw9}*@,lgn*jqir+8o | -mla(k`l             |  2222 |
|  9 | 81002 | .:9e43!qsf7qdg6/a;zg | p>:3)jrd##,hm|ea09si | 47558 |
| 10 | 17303 | |:f()m               | rd29-                | 22337 |
+----+-------+----------------------+----------------------+-------+
10 rows in set (0.027 sec)

MySQL [test]> desc t3;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| a     | int(11)     | NO   | PRI | NULL    | auto_increment |
| b     | int(11)     | YES  |     | NULL    |                |
| c     | varchar(20) | YES  |     | NULL    |                |
| d     | varchar(20) | YES  |     | NULL    |                |
| e     | int(11)     | YES  |     | NULL    |                |
| f     | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
6 rows in set (0.045 sec)

MySQL [test]> update t3 set f=b+e;
ERROR 6002 (25000): transaction needs rollback


session 2 :

MySQL [test]> select now(6); begin; alter table t3 add column (f int);
+----------------------------+
| now(6)                     |
+----------------------------+
| 2022-05-23 11:24:53.949363 |
+----------------------------+
1 row in set (0.017 sec)

Query OK, 0 rows affected (0.094 sec)

可以看到行锁住的时候是可以执行DDL的,当执行更新的时候,事务会失败,提示需要rollback

2. 同一行不同字段之间的测试

在更新同一行的不同列时,事务依旧会互相阻塞,如此选择的原因是为了减小锁数据结构在行上的存储开销。而更新不同行时,事务之间不会有任何影响。

session 1select now(6); begin;select e from t3 where a = 2 for update;

session 2select now(6); begin;select f from t3 where a = 2 for update;

image-20220523114238124

一段时间之后锁等待超时

image-20220523114309581

OceanBase 数据库使用了多版本两阶段锁,事务的修改每次并不是原地修改,而是产生新的版本。因此读取可以通过一致性快照获取旧版本的数据,因而不需要行锁依旧可以维护对应的并发控制能力,因此能做到执行中的读写不互斥,这极大提升了 OceanBase 数据库的并发能力。

3. 数据库锁机制的存储

锁存储在行上,从而减少内存中所需要维护的锁数据结构带来的开销。在内存中,当事务获取到行锁时,会在对应的行上设置对应的事务标记,即行锁持有者。当事务尝试获取行锁时,会通过对应的事务标记发现自己不是行锁持有者而放弃并等待或发现自己是行锁持有者后获得行的使用能力。当事务释放行锁后,就会在所有事务涉及的行上解除对应的事务标记,从而允许之后的事务继续尝试获取。

4. 死锁的机制

ob对于死锁的解决是通过几个超时机制。

基于超时的死锁解决

OceanBase 数据库当前主要依赖超时回滚机制来解决业务逻辑上的死锁。

存在三种超时机制用来解决对应的问题:

  • 锁超时机制:配置项名称为 ob_trx_lock_timeout,默认为语句超时时间,若加锁等待超过锁超时时间,则会回滚对应的语句,并返回锁超时对应的错误码。此时,由于某一个循环依赖中的资源依赖已经消失,因此就不再存在死锁。以事务 B 获取资源 C 超时为例,只要事务 B 结束,则事务 A 就可以获取到对应的资源 D。
  • 语句超时机制:配置项名称为 ob_query_timeout,默认为 10s,若加锁等待超过语句超时时间,则会回滚对应的语句,并返回语句超时对应的错误码。此时,由于某一个循环依赖中的资源依赖已经消失,因此就不再存在死锁。以事务 B 获取资源 C 超时为例,只要事务 B 结束,则事务 A 就可以获取到对应的资源 D。
  • 事务超时机制:配置项名称为 ob_trx_timeout,默认为 100s,若加锁等待超过事务超时时间,则会回滚对应的事务,并返回语句事务对应的错误码。由于某一个循环依赖中的资源依赖已经消失,因此就不再存在死锁。以事务 B 超时为例,由于事务 B 结束,事务 A 就可以获取到对应的资源 D。
    ob_trx_timeout,默认为 100s,若加锁等待超过事务超时时间,则会回滚对应的事务,并返回语句事务对应的错误码。由于某一个循环依赖中的资源依赖已经消失,因此就不再存在死锁。以事务 B 超时为例,由于事务 B 结束,事务 A 就可以获取到对应的资源 D。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值