当前位置: 首页 > article >正文

达梦数据库阻塞死锁及解锁

达梦数据库阻塞死锁及解锁

  • 达梦数据库
  • 业务背景
  • 模拟阻塞产生
  • 查询阻塞语句
  • 解决阻塞
  • 避免死锁

达梦数据库

达梦数据库管理系统是由达梦公司推出的具有完全自主知识产权的高性能数据库管理系统,简称DM,其最新版本为8.0版本(DM8)。达梦数据库在性能方面表现极为出色,这主要体现在多个关键方面。

在高并发处理能力上,达梦数据库采用了多种先进技术手段。例如多版本并发控制(MVCC)技术,它允许多个事务同时对数据库进行读写操作而不会产生冲突,通过为每个事务维护一个独立的快照,确保数据一致性。同时,优化的锁机制通过细粒度锁管理来减少锁的持有时间和范围,在高并发场景下,传统的锁机制往往会导致大量的锁等待和死锁问题,而达梦数据库通过引入行级锁、表级锁等多种锁类型,有效地解决了这些问题。再加上高效的查询执行计划,能够在最短时间内找到最佳的查询路径,从而大幅度提高查询效率。所以,当面对大量用户同时访问时,达梦数据库系统能够保持稳定运行,像在大型企业级应用中,它能够轻松处理成千上万的并发请求,同时保证数据的一致性和完整性。

在数据存储和检索速度方面,达梦数据库也有卓越的表现。它采用高效的数据存储结构、智能的索引机制以及缓存优化技术。其数据存储结构经过精心设计,能快速将数据写入磁盘并进行高效读取操作,如采用行存储和列存储结合的方式,在写入数据时按照行存储方式快速写入,在进行复杂查询时,通过列存储方式提升查询效率。智能的索引机制支持B树索引、哈希索引、全文索引等多种类型索引,可根据不同查询场景选择最合适的索引类型,大幅提升查询速度。缓存优化技术通过将频繁访问的数据缓存到内存中,使后续查询操作能直接从内存读取数据,减少磁盘I/O操作,从而提升检索速度。

在事务处理性能方面,达梦数据库的事务管理机制经过精心设计,能够高效处理大量并发事务以确保数据的一致性和完整性。例如采用两阶段提交协议(2PC),在分布式事务场景下保证所有参与节点的一致性提交。其并发控制能力强大,通过采用多版本并发控制(MVCC)和行级锁等技术手段,在高并发场景下保持稳定运行,避免事务冲突和死锁问题,并且提供丰富的事务隔离级别,用户可根据实际需求选择最合适的隔离级别,在保证数据一致性的前提下提升事务处理性能。

在扩展性方面,达梦数据库支持分布式架构,可进行横向和纵向扩展以应对不断增长的数据处理需求。它支持水平扩展,通过增加数据库节点提升系统处理能力;支持垂直扩展,通过增加硬件资源(如CPU、内存等)提升单个节点的处理能力。在分布式架构下,达梦数据库还支持分区表、分布式事务等技术,有效管理和处理大规模数据。

业务背景

近期我正在参与一个银行相关的项目。在当下的银行项目中,数据库国产化已成为一种普遍的要求。而在众多国产数据库里,达梦数据库往往被视为首选。然而,在使用达梦数据库的过程中,死锁问题时有发生。那么,当遭遇这种死锁情况时,怎样才能迅速进行处理呢?今天呢,我们主要先对死锁情况进行模拟,之后再着手解决死锁问题。通过这样的方式,能让大家更为直观地感受到死锁处理后的效果。

模拟阻塞产生

这里我在本地达梦数据库首先创建一个表,然后插入一条数据,但是不关闭查询框,不提交 COMMIT 事务。新建SQL查询语句窗口 A

CREATE TABLE TEST.TBL_TEST(ID INT PRIMARY KEY, NAME VARCHAR(50));
INSERT INTO TEST.TBL_TEST VALUES(1, '中文');

执行当前语句可以看到执行效果
在这里插入图片描述
再新建SQL查询语句窗口B,同时输入查询语句

INSERT INTO TEST.TBL_TEST VALUES(1, '中文');

执行语句可以看到如下的执行效果
在这里插入图片描述
这里显示【语句依次执行…】但是一直没有执行成功,其实就是对于主键约束字段,窗口A插入sql一直没有提交,窗口B再次插入相同主键数据时就会阻塞。

查询阻塞语句

这里通过 V T R X W A I T 视图查看进程,找到 I D , I D 对应着 V TRXWAIT 视图查看进程,找到ID,ID对应着V TRXWAIT视图查看进程,找到IDID对应着VSESSIONS视图的SESS_ID

select * from V$TRXWAIT ;

执行查询死锁语句后可以看到
在这里插入图片描述
其中:WAIT_FOR_ID 表示正在执行的事务ID,也就是说事务ID 12155 在等待 12154执行完成。

再通过V$SESSIONS视图,查找对应的ID号确定阻塞语句

SELECT SESS_ID,SQL_TEXT,TRX_ID from V$SESSIONS;

执行查询语句之后就可以看到具体的sql 阻塞内容
在这里插入图片描述

解决阻塞

解决阻塞其实也简单,当你找到需要解决的阻塞产生的SESS_ID了,你就可以调用 SP_CLOSE_SESSION(SESS_ID);系统函数来关闭会话

SP_CLOSE_SESSION(1866105112);
SP_CLOSE_SESSION(1859760408);

执行关闭回话系统函数之后,查看执行效果
在这里插入图片描述
再次查询产生阻塞产生的sql 内容查询语句

SELECT SESS_ID,SQL_TEXT,TRX_ID from V$SESSIONS;

可以看到刚才产生阻塞的两条语句已经没有了
在这里插入图片描述
那么到这里在遇到阻塞问题时的解决办法也就说完了,比较简单。当dm.ini中的参数ENABLE_MONITOR=1时,使用死锁历史动态试图V$DEADLOCK_HISTORY,可以查询到发生过的死锁信息。

SELECT * FROM V$DEADLOCK_HISTORY;

避免死锁

那么如何避免死锁呢,通常业务情况下,可能会出现这样的场景,比如数据库有两条数据,两个进程或者线程来操作这两条数据。首先查询数据表

SELECT * FROM TEST.TBL_TEST;

查询结果如图所示
在这里插入图片描述
这时候你打开两个SQL查询窗口,在窗口A执行语句

UPDATE TEST.TBL_TEST SET NAME='1111' WHERE ID = 1;

在窗口B执行语句

UPDATE TEST.TBL_TEST SET NAME='2222' WHERE ID = 2;

在窗口A继续执行语句

UPDATE TEST.TBL_TEST SET NAME='2222' WHERE ID = 2;

在窗口B继续执行语句

UPDATE TEST.TBL_TEST SET NAME='1111' WHERE ID = 1;

此时可以看到窗口A的第二条更新语句一直显示 【语句正依次执行…】
在这里插入图片描述
而窗口B的第二条语句已经显示【死锁】了
在这里插入图片描述
死锁与阻塞的不同之处在于死锁包括两个或者多个已阻塞事务,它们之间形成了等待环,每个都等待其他事务释放锁。例如事务1给表T1上了排他锁,第二个事务给表T2上了排他锁,此时事务1请求T2的排他锁,就会处于等待状态,被阻塞。若此时T2再请求表T1的排他锁,则T2也处于阻塞状态。此时这两个事务发生死锁,DM数据库会选择牺牲掉其中一个事务。

死锁的本质也是锁等待,所以解决锁等待的问题,就解决了死锁的问题。


http://www.kler.cn/a/568203.html

相关文章:

  • Excel工作圈小工具一个集合了大量Excel功能的绿色工具软件
  • C#中使用Newtonsoft.Json多态正反序列化
  • 基于 MetaGPT 自部署一个类似 MGX 的多智能体协作框架
  • 内容中台的企业CMS架构是什么?
  • 对话式AI引擎:DeepSeek技术引领多模态交互新篇章
  • RabbitMq延时队列的实现
  • 【漫话机器学习系列】107.线性组合(Linear Combination)
  • 【论文阅读笔记】SL-YOLO(2025/1/13) | 小目标检测 | HEPAN、C2fDCB轻量化模块
  • 检索增强生成(RAG)技术解析:大模型时代的“知识导航系统”
  • 基于Selenium的Python淘宝评论爬取教程
  • 【AI+智造】基于SKF IMAX-16+PT1000与Odoo18工业物联网架构智慧生产诊断系统集成方案
  • ubuntu 20.04 安装labelmg
  • C# Unity 唐老狮 No.1 模拟面试题
  • 【论文阅读笔记】FcaNet: Frequency Channel Attention Networks(2021/7/23)
  • Deepseek开源周第四天:从 DualPipe 到 EPLB
  • 查找Excel包含关键字的行(の几种简单快速方法)
  • 北京中烟创新科技有限公司:荣誉与创新并行
  • 考研复试问题总结-数据结构(1)
  • 【一条龙教程】用AI DS+创作原创音乐 (配合Midjourney漫画)制作原创MTV
  • 构建神经网络之Matplotlib(持续完善)