IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 达梦数据库_死锁与阻塞(分析&&处理) -> 正文阅读

[大数据]达梦数据库_死锁与阻塞(分析&&处理)

一、什么是阻塞?

阻塞是指障碍而不能通过,无法畅通

阻塞通常形容多线程间的相互影响,比如一个线程占用了临界区资源,那么其他所有需要这个资源的线程就必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞。如果这个线程不释放资源,那么其他所在阻塞在这个临界区上的线程都不能工作。

阻塞:是第一个事务占用资源没有释放,而第二个事务需要获取这个资源。如果第一个事务没有提交或者回滚,第二个事务会一直等待下去,直到第一个事务释放该资源为止。

遇到阻塞怎么办?

  1. 被阻塞的事务会一直挂起,直到持有锁的事务放弃锁定的资源为止(提交/回滚)
  2. 这种情况是应用程序BUG产生的,需要调整程序的逻辑结构,尽量形成短事务,快速提交,避免阻塞时间过长。不要将其他无关操作放到容易引起阻塞的模块

二、什么是死锁?

死锁是两个事务都在等待对方持有的资源锁,要等对方释放持有的资源之后才能继续工作,他们互不相让,坚持到底,双方都要等到对方完成之后才能继续工作,而以目前的这种状态,双方都完成不了,陷入死循环

遇到死锁怎么办?

  1. 数据库的机制是当发生有死锁时牺牲掉其中的一个进程来让其他进程继续执行下去
  2. 应用程序BUG产生的,需要调整程序的逻辑结构,在对多表进行操作的时候,尽量按照形同的顺序进行处理,避免同时锁定两个资源,必须同时锁定两个资源的时候,要保证在任何时候都应该按照相同的顺序来锁定资源。

三、数据库相关定义

在这里插入图片描述

阻塞

模拟阻塞场景

建表sql

create table lock_test01(id int primary key, name varchar(20));
create table lock_test02(id int primary key, name varchar(20));

insert into lock_test01(id, name) values(1, '1cheng');
insert into lock_test01(id, name) values(2, '1gao');

insert into lock_test02(id, name) values(1, '2cheng');
insert into lock_test02(id, name) values(2, '2gao');

阻塞场景

-- Session A 执行insert 不提交
insert into "SYSDBA"."LOCK_TEST01"("ID", "NAME")  VALUES(3, '3zzzz');
-- Session B 执行insert  会发生阻塞
insert into "SYSDBA"."LOCK_TEST01"("ID", "NAME")  VALUES(3, '4zzzz');

解决阻塞方法

解决阻塞(一)

/*定位锁等待问题 */
--1. 查看被挂起的事务(TRX_ID)
SELECT VTW.ID AS TRX_ID, VS.SESS_ID,VS.SQL_TEXT,VS.APPNAME,VS.CLNT_IP FROM V$TRXWAIT VTW LEFT JOIN V$TRX VT ON
(VTW.ID=VT.ID) LEFT JOIN V$SESSIONS VS ON (VT.SESS_ID=VS.SESS_ID);
--2. 通过挂起事务ID(TRX_ID)找到它等待的事务(WAIT_FOR_ID)。
SELECT WAIT_FOR_ID,WAIT_TIME FROM V$TRXWAIT WHERE ID=321646; 
--3. 通过等待事务ID(WAIT_FOR_ID)定位到连接以及执行的语句
SELECT VT.ID AS TRX_ID,VS.SESS_ID,VS.SQL_TEXT,VS.APPNAME,VS.CLNT_IP FROM
V$TRX VT LEFT JOIN V$SESSIONS VS ON (VT.SESS_ID=VS.SESS_ID) WHERE
VT.ID = 321643;
--4. 杀掉会话
--SP_CLOSE_SESSION关闭等待事务(SESS_ID)
SP_CLOSE_SESSION(142344256);

解决阻塞(二)

--查询被阻塞的信息和引起阻塞的信息
SELECT
        SYSDATE STATTIME,
        DATEDIFF(SS, S1.LAST_SEND_TIME, SYSDATE) SS ,
        '被阻塞的信息' WT , 
        S1.SESS_ID WT_SESS_ID,
        S1.SQL_TEXT WT_SQL_TEXT,
        S1.STATE WT_STATE,
        S1.TRX_ID WT_TRX_ID,
        S1.USER_NAME WT_USER_NAME,
        S1.CLNT_IP WT_CLNT_IP,
        S1.APPNAME WT_APPNAME,
        S1.LAST_SEND_TIME WT_LAST_SEND_TIME,
        '引起阻塞的信息' EM,
        s2.SESS_ID EM_SESS_ID,
        S2.SQL_TEXT EM_SQL_TEXT,
        S2.STATE FM_STATE,
        S2.TRX_ID FM_TRX_ID,
        S2.USER_NAME FM_USER_NAME,
        S2.CLNT_IP FM_CLNT_IP,
        S2.APPNAME FM_APPNAME,
        S2.LAST_SEND_TIME FM_LAST_SEND_TIME
FROM
        V$SESSIONS S1 ,V$SESSIONS S2,V$TRXWAIT W
where S1.TRX_ID=W.ID
AND S2.TRX_ID=W.WAIT_FOR_ID;

--2. 杀掉会话
SP_CLOSE_SESSION(142344256);

阻塞的发生场景

  1. 当多个事务同时试图向有主键或 UNIQUE 约束的表中插入相同的数据时,其中的一个事务将被阻塞,直到另外一个事务提交或回滚。
  2. 当 UPDATE 和 DELETE 修改的记录,已经被另外的事务修改过,将会发生阻塞,直到另一个事务提交或回滚。
  3. 同一个事务中先update语句(发生堵塞),在select查询时也会被堵塞。
  4. 进行update更新时,是范围更新(where id <10),另一个session进行更新时是其中的数据,也会发生阻塞

死锁

模拟死锁场景

-- 按照序号执行
-- 1. session A执行 update id = 1 ,事务不提交
update LOCK_TEST01 set  "NAME" = 'deadlock1' where id =1;
-- 3. session A执行 update id = 2 ,此时会发生阻塞,等待session B 释放
update LOCK_TEST01 set  "NAME" = 'deadlock2' where id =2;

-- 2. session B执行 update id = 2 ,事务不提交
update LOCK_TEST01 set  "NAME" = 'deadlock2' where id =2;
-- 4. session B执行 update id = 1 ,此时发生死锁
update LOCK_TEST01 set  "NAME" = 'deadlock1' where id =1;

在这里插入图片描述

解决死锁方法

查询死锁历史视图

-- 查询死锁历史记录
select * from V$DEADLOCK_HISTORY;

由于死锁会被数据库自动识别并终止,所以从会话视图中是感受不到的,程序会反馈一个死锁错误,通常死锁历史动态试图V$DEADLOCK_HISTORY,可以查询到发生过的死锁信息。

四、相关视图

select * from v$trx ;

-- 查询数据库会话
select * from v$sessions;
-- 查询阻塞锁
select * from v$lock where BLOCKED = 1;
-- 查询锁等待
select * from v$trxwait;
-- 查询死锁历史记录
select * from V$DEADLOCK_HISTORY;

-- 查询等待事件  total_waits 次数
select * from v$system_event
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:04:09  更:2022-10-31 12:05:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 8:27:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码