[kingbase锁等待问题分析]

参考文章:https://www.modb.pro/db/70021

概述

为了确保复杂的事务可以安全地同时运行,kingbase(PostgreSQL)提供了各种级别的锁来控制对各种数据对象的并发访问,使得对数据库关键部分的更改序列化。事务并发运行,直到它们尝试获取互相冲突的锁为止(比如两个事务更新同一行时)。当多个事务同时在数据库中运行时,并发控制是一种用于维持一致性和隔离性的技术,在kingbase(PostgreSQL)中,使用快照隔离Sanpshot Isolation (简称SI) 来实现多版本并发控制,同时以两阶段锁定 (2PL) 机制为辅。在执行DDL时使用2PL,在执行DML时使用SI。
在数据库中,同样也存在着各式各样的锁,表级锁、行级锁、页锁等等,数据库的并发能力除了和它的并发控制机制有关, 还和数据库的锁粒度控制息息相关,粒度越细冲突范围就越小,并发能力就越强。锁的最终目的无外乎是为了保证数据的一致性和完整性

kingbase锁矩阵

锁矩阵

场景

Z银行客户A系统 性能压测,压测时监控数据库服务器,发现数据库存在长连接情况,对长链接的会话进行锁分析。
经典获取锁信息的SQL:

SELECT blocked_locks.pid  AS blocked_pid,blocked_activity.usename  AS blocked_user,blocked_activity.client_addr as blocked_client_addr,blocked_activity.client_hostname as blocked_client_hostname,blocked_activity.application_name as blocked_application_name,blocked_activity.wait_event_type as blocked_wait_event_type,blocked_activity.wait_event as blocked_wait_event,blocked_activity.query   AS blocked_statement,blocked_activity.xact_start AS blocked_xact_start,blocking_locks.pid  AS blocking_pid,blocking_activity.usename AS blocking_user,blocking_activity.client_addr as blocking_client_addr,blocking_activity.client_hostname as blocking_client_hostname,blocking_activity.application_name as blocking_application_name,blocking_activity.wait_event_type as blocking_wait_event_type,blocking_activity.wait_event as blocking_wait_event,blocking_activity.query AS current_statement_in_blocking_process,blocking_activity.xact_start AS blocking_xact_start
FROM  pg_catalog.pg_locks   blocked_locksJOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pidJOIN pg_catalog.pg_locks  blocking_locks ON blocking_locks.locktype = blocked_locks.locktypeAND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASEAND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relationAND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.pageAND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tupleAND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxidAND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionidAND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classidAND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objidAND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubidAND blocking_locks.pid != blocked_locks.pidJOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted ORDER BY blocked_activity.pid ;

查询结果:
查询结果1
通过上述的SQL查询找到了相互阻塞的SQL,分析等待事件,pid 4183128 在等待一个事务提交,而pid 4183129 是在等客户端完成操作。
两个事务操作的不是同一张表,不应该相互阻塞才对,再次确认一下各自的阻塞pid。
查询阻塞pid SQL:

SELECT pid,pg_blocking_pid(pid),wait_event_type,wait_event,query from pg_stat_activity where pid =xxxxx;

查询结果2
这里说明一下,pid改变,是使用两次压测的查询结果。
查询结果分析:
通过系统函数pg_blocking_pid可以看到阻塞事务pid和等锁类型,分析阻塞update操作的确实是select操作的事务,锁类型是lock,锁事件是等待事务提交,而select操作的锁类型是客户端操作,等待事件是等待客户端操作提交。
考虑到两个SQL并不是操作的一个表,且select操作不应该阻塞DML操作,因此继续使用第二个经典的SQL来查询一下。
经典SQL2:

with      
t_wait as      
(      select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,     a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,      b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name     from pg_locks a,pg_stat_activity b where a.pid=b.pid and not a.granted     
),     
t_run as     
(     select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,     a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,     b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name     from pg_locks a,pg_stat_activity b where a.pid=b.pid and a.granted     
),     
t_overlap as     
(     select r.* from t_wait w join t_run r on     (     r.locktype is not distinct from w.locktype and     r.database is not distinct from w.database and     r.relation is not distinct from w.relation and     r.page is not distinct from w.page and     r.tuple is not distinct from w.tuple and     r.virtualxid is not distinct from w.virtualxid and     r.transactionid is not distinct from w.transactionid and     r.classid is not distinct from w.classid and     r.objid is not distinct from w.objid and     r.objsubid is not distinct from w.objsubid and     r.pid <> w.pid     )      
),      
t_unionall as      
(      select r.* from t_overlap r      union all      select w.* from t_wait w      
)      
select locktype,datname,relation::regclass,page,tuple,virtualxid,transactionid::text,classid::regclass,objid,objsubid,     
string_agg(     
'Pid: '||case when pid is null then 'NULL' else pid::text end||chr(10)||     
'Lock_Granted: '||case when granted is null then 'NULL' else granted::text end||' , Mode: '||case when mode is null then 'NULL' else mode::text end||' , FastPath: '||case when fastpath is null then 'NULL' else fastpath::text end||' , VirtualTransaction: '||case when virtualtransaction is null then 'NULL' else virtualtransaction::text end||' , Session_State: '||case when state is null then 'NULL' else state::text end||chr(10)||     
'Username: '||case when usename is null then 'NULL' else usename::text end||' , Database: '||case when datname is null then 'NULL' else datname::text end||' , Client_Addr: '||case when client_addr is null then 'NULL' else client_addr::text end||' , Client_Port: '||case when client_port is null then 'NULL' else client_port::text end||' , Application_Name: '||case when application_name is null then 'NULL' else application_name::text end||chr(10)||      
'Xact_Start: '||case when xact_start is null then 'NULL' else xact_start::text end||' , Query_Start: '||case when query_start is null then 'NULL' else query_start::text end||' , Xact_Elapse: '||case when (now()-xact_start) is null then 'NULL' else (now()-xact_start)::text end||' , Query_Elapse: '||case when (now()-query_start) is null then 'NULL' else (now()-query_start)::text end||chr(10)||      
'SQL (Current SQL in Transaction): '||chr(10)||    
case when query is null then 'NULL' else query::text end,      
chr(10)||'--------'||chr(10)      
order by      (  case mode      when 'INVALID' then 0     when 'AccessShareLock' then 1     when 'RowShareLock' then 2     when 'RowExclusiveLock' then 3     when 'ShareUpdateExclusiveLock' then 4     when 'ShareLock' then 5     when 'ShareRowExclusiveLock' then 6     when 'ExclusiveLock' then 7     when 'AccessExclusiveLock' then 8     else 0     end  ) desc,     (case when granted then 0 else 1 end)    
) as lock_conflict    
from t_unionall     
group by     
locktype,datname,relation,page,tuple,virtualxid,transactionid::text,classid,objid,objsubid ;    

SQL2查询结果:
查询结果3
查询结果3-2
分析SQL2查询结果,发现update实际被另一个update阻塞。
找到了相互阻塞的事务,现在重点关注的是select操作为什么没有commit,这就需要看一下业务的代码了,先现象和分析结果反馈给了业务侧开发,开发反馈是方法上之前有一个事务的注解,去掉之后select正常提交,未在出现锁等待情况。

问题解决方案:
1 数据库端添加超时参数,idle_in_transaction_session_timeout,单位ms。
2 业务代码侧解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/166051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux安全之AIDE系统入侵检测工具安装和使用

一、AIDE 系统入侵检测工具简介 AIDE&#xff0c;全称为Advanced Intrusion Detection Environment&#xff0c;是一个主要用于检测文件完整性的入侵检测工具。它能够构建一个指定文件的数据库&#xff0c;并使用aide.conf作为其配置文件。AIDE数据库能够保存文件的各种属性&am…

Django(十、中间件)

文章目录 一、中间件的介绍中间件有什么用中间件功能自定义中间中间件的顺序 一、中间件的介绍 中间件顾名思义&#xff0c;是介于request与response处理之间的一道处理过程&#xff0c;相对比较轻量级&#xff0c;并且在全局上改变django的输入与输出。因为改变的是全局&…

U盘启动制作工具Rufus

U盘启动制作工具Rufus 下载U盘启动制作工具Rufus&#xff0c;进入Rufus官网&#xff1a;http://rufus.ie/en/&#xff0c;打开之后往后滑动&#xff0c;找到download即可点击下载。 需要插入U盘 首先需要插入U盘&#xff0c;如果U盘有重要文件一定要备份&#xff0c;然后右键…

Grails 启动

Grails系列 Grails项目启动 文章目录 Grails系列Grails一、项目创建二、可能的问题1.依赖下载2.项目导入到idea失败3.项目导入到idea后运行报错 Grails Grails是一款基于Groovy语言的Web应用程序框架&#xff0c;它使用了许多流行的开源技术&#xff0c;如Spring Framework、…

内衣洗衣机怎么选?性价比高的小型洗衣机推荐

在机器解放了双手的时代中&#xff0c;洗衣机走进了千家万户&#xff0c;虽然在某种程度上缓解了人们手洗衣服的压力&#xff0c;但还是有不少人选择了人工手洗自己的内衣内裤&#xff0c;甚至连袜子都是手工洗的&#xff0c;这让人很是郁闷&#xff0c;倒不是说洗衣机不方便&a…

SpringBoot整合SpringSecurity+jwt+knife4生成api接口(从零开始简单易懂)

一、准备工作 ①&#xff1a;创建一个新项目 1.事先创建好一些包 ②&#xff1a;引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency>&…

linux -系统通用命令查询

有时候内网环境下&#xff0c;系统有些命令没有安装因此掌握一些通用的linux 命令也可以帮助我们解决一些问题查看 1.查看系统内核版本 uname -r2.查看系统版本 cat /etc/os-release3. 查看cpu 配置 lscpu4.查看内存信息 free [参数] 中各个数值的解释如下表 数值解释t…

提高工作效率的宝藏网站和宝藏工具(高级版)

一、参考资料 亲测&#xff1a;你这些网站都不知道&#xff0c;哪来时间去摸鱼&#xff1f; 提高工作效率的宝藏网站和宝藏工具&#xff08;基础版&#xff09; 二、好用的网站 HelloGitHub - 开源项目平台 HelloGitHub 是一个分享有趣、 入门级开源项目的平台。 希望大家能…

MySQL-02-InnoDB存储引擎

实际的业务系统开发中&#xff0c;使用MySQL数据库&#xff0c;我们使用最多的当然是支持事务并发的InnoDB存储引擎的这种表结构&#xff0c;下面我们介绍下InnoDB存储引擎相关的知识点。 1-Innodb体系架构 InnoDB存储引擎有多个内存块&#xff0c;可以认为这些内存块组成了一…

qgis添加arcgis的mapserver

左侧浏览器-ArcGIS地图服务器-右键-新建连接 Folder: / 展开-双击图层即可

物联网AI MicroPython学习之语法 I2S音频总线接口

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; I2S 介绍 模块功能: I2S音频总线驱动模块 接口说明 I2S - 构建I2S对象 函数原型&#xff1a;I2S(id, sck, ws, sd, mode, bits, format, rate, ibuf)参数说明&#xff1a; 参数类型必选参数&#xff1f…

关于接口测试自动化的总结与思考!

序 近期看到阿里云性能测试 PTS 接口测试开启免费公测&#xff0c;本着以和大家交流如何实现高效的接口测试为出发点&#xff0c;本文包含了我在接口测试领域的一些方法和心得&#xff0c;希望大家一起讨论和分享&#xff0c;内容包括但不仅限于&#xff1a; 服务端接口测试介…

Vatee万腾的科技冒险:vatee创新力量的前沿发现

在当今飞速发展的科技潮流中&#xff0c;Vatee万腾以其独特的创新力量成为前沿的引领者。这场科技冒险不仅仅是技术的迭代&#xff0c;更是一次前所未有的前沿发现之旅&#xff0c;让我们一同深入探索Vatee万腾的科技冒险&#xff0c;感受vatee创新力量的前沿奇迹。 Vatee万腾将…

机器学习---最大似然估计和贝叶斯参数估计

1. 估计 贝叶斯框架下的数据收集&#xff0c;在以下条件下我们可以设计一个可选择的分类器 : P(wi) (先验)&#xff1b;P(x | wi) (类条件密度) 但是。我们很少能够完整的得到这些信息! 从一个传统的样本中设计一个分类器&#xff1a; ①先验估计不成问题 ②对类条件密度…

git本地账户如何从一台电脑迁移到另外一台

为了表述方便&#xff0c;我们此处用旧电脑、新电脑指代。 在新电脑上安装git 例如&#xff0c;我旧电脑上安装的git版本是2.33.1版本&#xff0c;新电脑安装git的版本是2.43.0&#xff0c;这不妨碍迁移。 将git的全局配置文件从旧电脑拷贝到新电脑 Git的全局配置文件&…

“关爱零距离.情暖老人心”主题活动

为提高社区老年人的生活质量&#xff0c;促进邻里间的互动与友谊&#xff0c;以及弘扬尊老爱幼的社区精神&#xff0c;11月21日山东省潍坊市金阳公益服务中心、重庆市潼南区同悦社会工作服务中心在潼南区桂林街道东风社区共同在潼南区桂林街道东风社区举办了“关爱零距离.情暖老…

22款奔驰S400L升级原厂360全景影像 高清环绕 无死角

360全景影像影像系统提升行车时的便利&#xff0c;不管是新手或是老司机都将是一个不错的配置&#xff0c;无论是在倒车&#xff0c;挪车以及拐弯转角的时候都能及时关注车辆所处的环境状况&#xff0c;避免盲区事故发生&#xff0c;提升行车出入安全性。 360全景影像包含&…

自学编程,用好这几个网站就够了!

如果你要自学编程&#xff0c;一定要收藏好这7个网站&#xff0c;上面免费的优质教程很多&#xff0c;完全可以省去你上万块钱的学费&#xff01; 话不多说&#xff0c;直接上干货&#xff01; 第一个&#xff0c;W3school 一个主打图文教程的网站&#xff0c;不管是前端开发…

怎样将带表格的图片批量合并转换成word表格?

注&#xff1a;本功能适用于V3.66以上版本的金鸣表格文字识别大师 在日常的办公场景中&#xff0c;我们常常会遇到需要将带有表格类的图片识别成excel的需求。我们知道&#xff0c;普通的OCR软件并不具备识别中文表格的功能&#xff0c;即使有&#xff0c;效果也强差人意&…

JSP:MVC

Web应用 一个好的Web应用&#xff1a; 功能完善 易于实现和维护 易于扩展等 的体系结构 一个Web应用通常分为两个部分&#xff1a; m 1. 由界面设计人员完成的 表示层 &#xff08;主要做网页界面设计&#xff09; m 2. 由程序设计人员实现的 行为层 &#xff08;主要完成本…