数据库锁表和解锁

这篇具有很好参考价值的文章主要介绍了数据库锁表和解锁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述

在开发或生产环境中,我们经常会遇到数据库锁表的情况,一旦发生锁表,对业务将会产生很大的影响,本篇主要介绍如何判断数据库锁表和锁表后的处理。

mysql锁表处理

一、导致锁表的原因

1、锁表发生在insert update 、delete 中;

2、锁表的原理是 数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发生commite 或者 回滚 或者退出数据库用户;

3、锁表的原因 :

1)、A程序执行了对 tableA 的 insert ,并还未 commite时,B程序也对tableA 进行insert 则此时会发生资源正忙的异常 就是锁表;

2)、锁表常发生于并发而不是并行(并行时,一个线程操作数据库时,另一个线程是不能操作数据库的,cpu 和i/o 分配原则)

4、减少锁表的概率:
减少insert 、update 、delete 语句执行 到 commite 之间的时间。
具体点批量执行改为单个执行、优化sql自身的非执行速度
如果异常对事物进行回滚。

二、mysql锁表的解决

#查看进程id,然后用kill id杀掉进程

1)processlist展示了对应的数据库有哪些线程在运行,如果有些语句执行速度慢,可以在里面看到

show processlist;

#根据不同的账号权限可以看到所有用户的,当前用户的对应的连接。只有100条

show full processlist:
展示所有的连接数据
SELECT * FROM information_schema.PROCESSLIST;
#查询正在执行的进程
SELECT * FROM information_schema.PROCESSLIST where length(info) >0 ;
字段说明

ID 连接标识符,这个ID和show processlist 中ID是一样的,也和Performance Schema 中threads表的PROCESSLIST_ID 栏位是一样的,也和CONNECTION_ID()函数返回的是一样的
USER 连接的用户,其中system user代表系统用户,非用户连接,unauthenticated user代表是用户连接,但是未完成认证,event_scheduler 用户代表的是监控定时任务的用户
HOST 连接的主机名,如果用户是system user,则HOST为空
DB 连接的数据库,如果未选择数据库,则为NULL
COMMAND 线程执行的命令类型
TIME 线程在当前状态持续的时间,以秒为单位
STATE 线程当前的状态,如果该状态持续很久,说明有问题,如果是SHOW PROCESSLIST 命令,则状态为NULL
INFO 线程执行的具体命令,如果执行的是call procedure,这里可能显示的是内容的语句,如select

#查询是否锁表
show OPEN  TABLES where In_use > 0;
字段说明

Database 含有该表的数据库。
Table 表名称。
In_use 表当前被查询使用的次数。如果该数为零,则表是打开的,但是当前没有被使用。
Name_locked 表名称是否被锁定。名称锁定用于取消表或对表进行重命名等操作

#查看被锁住的
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

innodb_locks提供有关InnoDB 事务已请求但尚未获取的每个锁的信息,以及事务持有的阻止另一个事务的每个锁。

字段说明

lock_id:锁 ID。
lock_trx_id:拥有锁的事务 ID。可以和 INNODB_TRX 表 JOIN 得到事务的详细信息。
lock_mode:锁的模式。有如下锁类型:行级锁包括:S、X、IS、IX,分别代表:共享锁、排它锁、意向共享锁、意向排它锁。表级锁包括:S_GAP、X_GAP、IS_GAP、IX_GAP 和 AUTO_INC,分别代表共享间隙锁、排它间隙锁、意向共享间隙锁、意向排它间隙锁和自动递增锁。
lock_type:锁的类型。RECORD 代表行级锁,TABLE 代表表级锁。
lock_table:被锁定的或者包含锁定记录的表的名称。
lock_index:当 LOCK_TYPE=’RECORD’ 时,表示索引的名称;否则为 NULL。
lock_space:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的表空间 ID;否则为 NULL。
lock_page:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的页号;否则为 NULL。
lock_rec:当 LOCK_TYPE=’RECORD’ 时,表示一堆页面中锁定行的数量,亦即被锁定的记录号;否则为 NULL。
lock_data:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的主键;否则为NULL。

#等待锁定
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

innodb_lock_waits包含每个被阻止InnoDB 事务的一个或多个行,指示它已请求的锁以及阻止该请求的任何锁。

字段说明

requesting_trx_id:请求事务的 ID。
requested_lock_id:事务所等待的锁定的 ID。可以和 INNODB_LOCKS 表 JOIN。
blocking_trx_id:阻塞事务的 ID。
blocking_lock_id:某一事务的锁的 ID,该事务阻塞了另一事务的运行。可以和 INNODB_LOCKS 表 JOIN

#杀掉锁表进程

kill 5601

达梦数据库锁表处理

1. 定义

阻塞:多个线程之间的相互影响,等待临界资源;
死锁:多个线程之间互相等待,形成等待环;

对于死锁,达梦数据库会自动检测,并选择牺牲掉其中的一个事务,保证其它事务正常运行。死锁一般是由于应用程序bug导致的,当有修改多表的事务时,应尽量保证每个事务以相同的顺序锁定表。可以通过V$DEADLOCK_HISTORY查询死锁历史,其中记录了产生死锁后被牺牲掉的事务的事务ID、会话ID、执行的SQL语句以及死锁发生时间(没有记录造成死锁的其它事务)。对于阻塞,达梦数据库不会自动处理,被阻塞的事务会一直挂起,直到获取到所需的资源。阻塞一般是由应用程序bug造成的,在应用编写中,应尽量形成短事务,快速提交。

2. 什么情况下会形成阻塞?

在达梦数据库中,默认采用读提交的机制,查询永远不会被阻塞。查询一般情况下也不会阻塞增删改操作,SELECT FOR UPDATE的情况除外。
INSERT语句被阻塞的情况:多个事务同时向有主键或唯一约束的表中插入相同的数据;
删、改语句被阻塞的情况:所需要操作的数据被其它事务修改过,且一直没有提交或回滚;

3.阻塞的排查

当阻塞发生时,我们可以通过 v$lock 视图查到当前数据库中锁的状态

select * from v$lock;

数据库锁表和解锁

结果中我们可以看到,事务 1459 被阻塞了,阻塞他的事务为 1450,同样我们也可以通过 V$TRXWAIT 视图排查阻塞,

select * from v$trxwait;

数据库锁表和解锁

得出同样的结果,等待时间是1814645 毫秒。
接下来,通过 V$SESSIONS 视图查找两个事务对应的会话,可以知道是哪些 SQL 语句产生的阻塞。

select sess_id,sql_text,state,trx_id from v$sessions where trx_id in('1459','1450');

数据库锁表和解锁

4.阻塞的解决方法

根据需求,可以有两种解决方案。

4.1 提交或回滚产生阻塞的事务。

根据上文,我们可知产生阻塞的事务会话 ID 为 140702994469648。此时,我们只需要在该会话下提交或回滚事务,锁自然会被释放,阻塞解决。

4.2 关闭产生阻塞的会话

同样,我们也可以使用系统过程 SP_CLOSE_SESSION(SESS_ID)来关闭对应的会话
数据库锁表和解锁

此时,锁被释放,delete 操作也可以顺利进行下去。

数据库锁表和解锁
也可以用一条语句查看出被阻塞的操作和事务会话 ID(SESS_ID)

select a.*, b.NAME, c.SESS_ID from v$lock a
left join sysobjects b on b.ID=a.TABLE_ID
left join v$sessions c on a.TRX_ID=c.TRX_ID;

然后直接执行SP_CLOSE_SESSION(SESS_ID) 来关闭对应的会话

SQL Server数据库锁表处理

第一步:查询死锁语句

1: 条件是 blocked <> 0

select dbid,* from sys.sysprocesses
where 1=1
and spid >50
and blocked <> 0
--and spid= 62

查询结果如下图所示:
数据库锁表和解锁

以上查询得出:

受影响的数据库ID 是 5;
受到阻塞的会话有1301、1306、869、109;
阻塞会话是961;

第二步:查询发生阻塞或死锁的当前数据库

1:通过第一步查询,知道数据库ID 为 DBID=5。

2:sp_helpdb 或 Select name,dbid from master.sys.sysdatabases 查询数据库名称

数据库锁表和解锁

第三步:查询发生阻塞或死锁的SQL语句

输出死锁的执行的语句:

dbcc inputbuffer(961)

语句如下:

select o.tp_Login,o.tp_Title, CONVERT(varchar(10),a.TimeCreated,120)  as accessingdate,count(*) as docnum, 'sps' as type  from UserData u,AllDocs a, userinfo o ,webs w where a.ListId = u.tp_ListId and a.Id = u.tp_docID  and w.Id = a.WebId and w.SiteId = a.SiteId and w.SiteId = o.tp_SiteID and

第四步:杀死锁

kill  961

之后再从第一步进行查询,看是否还存在死锁;

从第二步、第三步,查询出了出问题的锁死数据库及SQL语句,便于分析彻底解决死锁问题。

ORACEL数据库锁表处理

oracle表在什么情况下会被锁住

DML锁又可以分为,行锁、表锁、死锁

行锁: 当事务执行数据库插入、更新、删除操作时,该事务自动获得操作表中操作行的排它锁。

表级锁: 当事务获得行锁后,此事务也将自动获得该行的表锁(共享锁),以防止其它事务进行DDL语句影响记录行的更新。事务也可以在进行过程中获得共享锁或排它锁,只有当事务显示使用LOCK TABLE语句显示的定义一个排它锁时,事务才会获得表上的排它锁,也可使用LOCK TABLE显示的定义一个表级的共享锁(LOCK TABLE具体用法请参考相关文档)。

死锁: 当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就出现死锁。
如事务1在表A行记录#3中有一排它锁,并等待事务2在表A中记录#4中排它锁的释放,而事务2在表A记录行#4中有一排它锁,并等待事务1在表A中记录#3中排它锁的释放,事务1与事务2彼此等待,因此就造成了死锁。死锁一般是因拙劣的事务设计而产生。
死锁只能使用SQL下:alter system kill session “sid,serial#”;或者使用相关操作系统kill进程的命令,如UNIX下kill -9 sid,或者使用其它工具杀掉死锁进程。

DDL锁又可以分为:排它DDL锁、共享DDL锁、分析锁

排它DDL锁:创建、修改、删除一个数据库对象的DDL语句获得操作对象的 排它锁。如使用alter table语句时,为了维护数据的完成性、一致性、合法性,该事务获得一排它DDL锁。

共享DDL锁:需在数据库对象之间建立相互依赖关系的DDL语句通常需共享获得DDL锁。
如创建一个包,该包中的过程与函数引用了不同的数据库表,当编译此包时,该事务就获得了引用表的共享DDL锁。

分析锁:ORACLE使用共享池存储分析与优化过的SQL语句及PL/SQL程序,使运行相同语句的应用速度更快。一个在共享池中缓存的对象获得它所引用数据库对象的分析锁。分析锁是一种独特的DDL锁类型,ORACLE使用它追踪共享池对象及它所引用数据库对象之间的依赖关系。当一个事务修改或删除了共享池持有分析锁的数据库对象时,ORACLE使共享池中的对象作废,下次在引用这条SQL/PLSQL语句时,ORACLE重新分析编译此语句。

Oracle锁表查询和解锁

第一步:通过管理员权限用户查询被锁表信息

如果怀疑表被锁了,或者事务未被正常关闭,在Oracle数据库中我们可以通过以下语句进行查询获取相关信息:

 select t2.username,    t2.sid,    t2.serial#,    t3.object_name,  t2.OSUSER,  t2.MACHINE,
        t2.PROGRAM,  t2.LOGON_TIME,  t2.COMMAND,   t2.LOCKWAIT,
        t2.SADDR,   t2.PADDR, t2.TADDR,   t2.SQL_ADDRESS,   t1.LOCKED_MODE
   from v$locked_object t1, v$session t2, dba_objects t3
  where t1.session_id = t2.sid
    and t1.object_id = t3.object_id
  order by t2.logon_time;

大家发现,上面这条SQL语句用到了Oracle的两个视图和一个表,分别是v l o c k e d o b j e c t 、 v locked_object、v lockedobjectvsession、dba_objects:
v l o c k e d o b j e c t 视图中记录了所有 s e s s i o n 中的所有被锁定的对象信息。 v locked_object 视图中记录了所有session中的所有被锁定的对象信息。 v lockedobject视图中记录了所有session中的所有被锁定的对象信息。vsession 视图记录了所有session的相关信息。
dba_objects 为oracle用户对象及系统对象的集合,通过关联这张表能够获取被锁定对象的详细信息。

eg:现在我通过scott用户执行DML语句(eg:select * from emp for update;或者update scott.emp set sal = ‘2000’ where empno=‘7788’; )之后一直不进行提交,然后通过system用户执行上面的查询oracle中被锁表的sql语句,就会找到如下记录:

说明:

username:oracle用户名
sid:进程号
serial#:序列号
object_name:表名
osuser:操作系统用户名
machine:机器名
program:操作工具
logon_time:登陆时间
lockwait:表示当前这张表是否正在等待其他用户解锁这张表
locked_mode:锁表模式(下面详细说明)

注意:这时候如果通过system用户执行select * from scott.emp for update;语句就无法成功执行。

第二步:通过拥有管理员权限的用户解除数据库中被锁住的表(SID,SERIAL)

通过第一步查出来的信息找到被锁的表之后执行如下语句解锁该表:

alter system kill session ‘sid,seial#’;
注意:sid和seial#就是第一步中查询出来的进程号和序列号。

eg:解除第一步中表的锁

alter system kill session ‘10,15’;
现在通过system再次执行DML语句(eg:select * from scott.emp for update;或update scott.emp set sal = ‘2000’ where empno=‘7788’;)就可以了。

锁的模式
v$locked_object中的LOCKED_MODE字段表示锁的模式,oracle中锁的模式有如下几种:
0:none
1:null 空
2:Row-S 行共享(RS):共享表锁,sub share
3:Row-X 行独占(RX):用于行的修改,sub exclusive
4:Share 共享锁(S):阻止其他DML操作,share
5:S/Row-X 共享行独占(SRX):阻止其他事务操作,share/sub exclusive
6:exclusive 独占(X):独立访问使用,exclusive

数字越大锁级别越高, 影响的操作越多。

1级锁有: Select,有时会在v$locked_object出现。
2级锁有: Select for update,Lock For Update,Lock Row Share
select for update当对话使用for update子串打开一个游标时,所有返回集中的数据行都将处于行级(Row-X)独占式锁定,其他对象只能查询这些数据行,不能进行update、delete或select for update操作。
3级锁有: Insert, Update, Delete, Lock Row Exclusive
没有commit之前插入同样的一条记录会没有反应, 因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作。
4级锁有: Create Index, Lock Share
locked_mode为2,3,4不影响DML(insert,delete,update,select)操作, 但DDL(alter,drop等)操作会提示ora-00054错误。
00054, 00000, “resource busy and acquire with NOWAIT specified”
// *Cause: Resource interested is busy.
// *Action: Retry if necessary.
5级锁有: Lock Share Row Exclusive
具体来讲有主外键约束时update / delete … ; 可能会产生4,5的锁。
6级锁有: Alter table, Drop table, Drop Index, Truncate table, Lock Exclusive

还有一条比较实用的sql:

–查某session 正在执行的sql语句,从而可以快速定位到哪些操作或者代码导致事务一直进行没有结束等.

 SELECT /*+ ORDERED */ 
  sql_text
   FROM v$sqltext a
  WHERE (a.hash_value, a.address) IN
        (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
                DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
           FROM v$session b
          WHERE b.sid = '67')  /* 此处67 为SID*/
  ORDER BY piece ASC;

参考链接:
https://blog.csdn.net/snowfoxmonitor/article/details/7182948
https://www.cnblogs.com/pugang/p/16531352.html
https://blog.csdn.net/qq_26987043/article/details/127640853
http://t.zoukankan.com/smellpawn-p-10799174.html文章来源地址https://www.toymoban.com/news/detail-403943.html

到了这里,关于数据库锁表和解锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【开发问题】flink-cdc不用数据库之间的,不同类型的转化

    我一开始是flink-cdc,oracle2Mysql,sql 我一开始直接用的oracle【date】类型,mysql【date】类型,sql的校验通过了,但是真正操作数据的时候报错,告诉我oracle的数据格式的日期数据,不可以直接插入到mysql格式的日期数据,说白了就是数据格式不一致导致的 我想的是既然格式不对

    2024年02月12日
    浏览(35)
  • 全网唯一解决Mysql数据库宕机生产事故的通用方法高级DBA真实案例解答

    国内90%的生产数据库用的最多的就是MySql数据库。企业软件生产环境通常情况下,都有一主一从,或者一主多从的HA高可用架构。结合作者本人实际经验结合一个实际的生产数据库宕机的例子,来讲解应该用怎么样的思路去解决问题。在生产事故过程中,有那些注意的关键点

    2024年02月05日
    浏览(48)
  • Redis生产实战-热key、大key解决方案、数据库与缓存最终一致性解决方案

    热 key 问题就是某一瞬间可能某条内容特别火爆,大量的请求去访问这个数据,那么这样的 key 就是热 key,往往这样的 key 也是存储在了一个 redis 节点中,对该节点压力很大 那么对于热 key 的处理就是通过热 key 探测系统对热 key 进行计数,一旦发现了热 key,就将热 key 在 jv

    2024年02月05日
    浏览(40)
  • 有没有一种支持对象建模、数据库建模和低代码能力的工具,用来解放程序员生产力呢?

    1. 简介 作为一个程序员,很多时候在面对项目开发工期短、任务重、功能复杂、压力大,同时还得迎合领导或者甲方的要求提供研发设计文档时,往往很苦恼,因为随着软件项目的迭代,很难保持输出与代码一致的数据模型和架构模式相关设计图,而且还要花费大量时间去绘

    2024年02月06日
    浏览(39)
  • 【手写数据库toadb】01 开发数据库内核准备阶段-开发环境准备

    ​ 专栏内容 : 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学

    2024年01月22日
    浏览(37)
  • [开发|数据库] java程序人大金仓数据库适配笔记

    需要去人大金仓https://www.kingbase.com.cn/qd/index.htm下载linux版iso文件和授权文件(license-企业版-90天)。 iso文件需要挂载在指定目录下。 参考:(https://www.cnblogs.com/bluestorm/p/16941812.html)。 人大金仓数据库安装过程中出现乱码/内容不显示是因为jdk版本不匹配,通过asdf更换java版本为

    2024年02月12日
    浏览(30)
  • 【SQL Server】数据库开发指南(二)MSSQL数据库开发对于库、表、数据类型、约束等相关操作

    本系列博文还在更新中,收录在专栏:#MS-SQL Server 专栏中。 本系列文章列表如下: 【SQL Server】 Linux 运维下对 SQL Server 进行安装、升级、回滚、卸载操作 【SQL Server】数据库开发指南(一)数据库设计的核心概念和基本步骤 【SQL Server】数据库开发指南(二)MSSQL数据库开发对

    2023年04月09日
    浏览(46)
  • 【SQL Server】数据库开发指南(一)数据库设计

    本系列博文还在更新中,收录在专栏:#MS-SQL Server 专栏中。 本系列文章列表如下: 【SQL Server】 Linux 运维下对 SQL Server 进行安装、升级、回滚、卸载操作 【SQL Server】数据库开发指南(一)数据库设计的核心概念和基本步骤 【SQL Server】数据库开发指南(二)MSSQL数据库开发对

    2023年04月08日
    浏览(55)
  • 数据库问题记录(粗略版)oracle、mysql等主流数据库通用

    1. ORA-00918:未明确定义列 该问题情况大致为:select 所取列名错误、重复等问题。 2. “select * from temp where 1=0; ”的含义 布尔值为FALSE,只返回表结构,不返回数据。 举一反三: select * from temp where 10 , 布尔值为TRUE,返回所有数据记录; select * from temp where 1=0, 暂不清楚是何

    2024年02月07日
    浏览(38)
  • 微信小程序开发14 复杂数据库设计:如何用好云开发提供的文档型数据库?

    我们知道,大多数互联网应用产品都会不断产生各种数据(可能是用户产生的,也可能是系统自动生成的)。要想高效保存这些数据,并维持应用产品的有效运转,就要用到数据库。 数据库是高效存储数据、读取数据的存储器。我们日常用到的绝大部分应用,都是把数据库放

    2024年02月09日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包