‘壹’ 怎么查看和处理sql死锁
找到事务号,可以从 events_statements_current 找到对应的 SQL 语句:
SQL_TEXT: delete from action1 where id = 3 //具体的sql语句
DIGEST:
DIGEST_TEXT: DELETE FROM `action1` WHERE `id` = ?
CURRENT_SCHEMA: test1
OBJECT_TYPE: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL
OBJECT_INSTANCE_BEGIN: NULL
MYSQL_ERRNO: 0
RETURNED_SQLSTATE: 00000
MESSAGE_TEXT: NULL
ERRORS: 0
WARNINGS: 0
ROWS_AFFECTED: 1
ROWS_SENT: 0
ROWS_EXAMINED: 3
CREATED_TMP_DISK_TABLES: 0
CREATED_TMP_TABLES: 0
SELECT_FULL_JOIN: 0
SELECT_FULL_RANGE_JOIN: 0
SELECT_RANGE: 0
SELECT_RANGE_CHECK: 0
SELECT_SCAN: 0
SORT_MERGE_PASSES: 0
SORT_RANGE: 0
SORT_ROWS: 0
SORT_SCAN: 0
NO_INDEX_USED: 0
NO_GOOD_INDEX_USED: 0
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
NESTING_EVENT_LEVEL: 0
1 row in set (0.00 sec)
可以看到是一条 delete 阻塞了后续的 update,生产环境中可以拿着这条 SQL 语句询问开发,是不是有 kill 的必要。
‘贰’ 如何查看SQL死锁
其实所有的死锁最深层的原因就是一个:资源竞争
表现一:
一个用户A
访问表A(锁住了表A),然后又访问表B
另一个用户B
访问表B(锁住了表B),然后企图访问表A
这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B,才能继续,好了他老人家就只好老老实实在这等了
同样用户B要等用户A释放表A才能继续这就死锁了
解决方法:
这种死锁是由于你的程序的BUG产生的,除了调整你的程序的逻辑别无他法
仔细分析你程序的逻辑,
1:尽量避免同时锁定两个资源
2:
必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源.
表现二:
用户A读一条纪录,然后修改该条纪录
这是用户B修改该条纪录
这里用户A的事务里锁的性质由共享锁企图上升到独占锁(for
update),而用户B里的独占锁由于A有共享锁存在所以必须等A释
放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。
这种死锁比较隐蔽,但其实在稍大点的项目中经常发生。
解决方法:
让用户A的事务(即先读后写类型的操作),在select
时就是用Update
lock
语法如下:
select
*
from
table1
with(updlock)
where
....
‘叁’ 怎么查看mysql表是否被锁定
可直接在mysql命令行执行:show engine innodb status\G;
查看造成死锁的sql语句,分析索引情况,然后优化sql然后show processlist;
另外可以打开慢查询日志,linux下打开需在my.cnf的[mysqld]里面加上以下内容:
‘肆’ 查看Oracle中是否有锁表的sql
1、查看是否有锁表的sql
代码如下:
select 'blocker('||lb.sid||':'||sb.username||')-sql:'|| qb.sql_text blockers,
'waiter ('||lw.sid||':'||sw.username||')-sql:'|| qw.sql_text waiters
from v$lock lb,
v$lock lw,
v$session sb,
v$session sw,
v$sql qb,
v$sql qw
where lb.sid=sb.sid
and lw.sid=sw.sid
and sb.prev_sql_addr=qb.address
and sw.sql_address=qw.address
and lb.id1=lw.id1
and sw.lockwait is not null
and sb.lockwait is null
and lb.block=1 ;
2、查看被锁的表
代码如下:
select p.spid,a.serial#,c.object_name,b.session_id,b.oracle_username,b.os_user_name
from v$process p,v$session a, v$locked_object b,all_objects c
where p.addr=a.paddr and a.process=b.process and c.object_id=b.object_id ;
3、查看那个用户那个进程造成死锁,锁的级别
代码如下:
select b.owner,b.object_name,l.session_id,l.locked_mode fromv$locked_object l, dba_objects
4、查看连接的进程
代码如下:
SELECT sid, serial#, username, osuser FROMv$session;
5、查看是哪个session引起的
代码如下:
select b.username,b.sid,b.serial#,logon_time
from v$locked_object a,v$session b
where a.session_id = b.sid order by b.logon_time;
6、杀掉进程
代码如下:
alter system kill session 'sid,serial#';
‘伍’ 怎么查看 sql server 数据库有没有锁表
查看sql server数据库被锁表可以用用如下语句:
拓展资料:
SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点,可跨越从运行Microsoft Windows 98 的膝上型电脑到运行Microsoft Windows 2012 的大型多处理器的服务器等多种平台使用。
Microsoft SQL Server 是一个全面的数据库平台,使用集成的商业智能 (BI)工具提供了企业级的数据管理。Microsoft SQL Server 数据库引擎为关系型数据和结构化数据提供了更安全可靠的存储功能,使您可以构建和管理用于业务的高可用和高性能的数据应用程序。
‘陆’ 怎么知道数据库表已经锁表了
可直接在mysql命令行执行:show engine innodb statusG;
查看造成死锁的sql语句,分析索引情况,然后优化sql然后show processlist;
show status like ‘%lock%’
show OPEN TABLES where In_use > 0; 这个语句记录当前锁表状态
另外可以打开慢查询日志,linux下打开需在my.cnf的[mysqld]里面加上以下内容:
slow_query_log=TRUE(有些mysql版本是ON)
slow_query_log_file=/usr/local/mysql/slow_query_log.txt
long_query_time=3
select *from v$locked_object:可以获得被锁的对象的object_id及产生锁的会话sid。通过查询结果中的object_id,可以查询到具体被锁的对象。
(6)如何判断sql是否有锁扩展阅读:
注意事项
也可以直接把这几个视图和表关联起来,在查询结果中直接得到“alter system kill session 'sid, serial#'”这样的方便的kill sessoin命令。
如果执行kill session命令后,锁并没有除掉,session依然存在。这种情况,通过select spid from v$process where addr in(select paddr from v$session where sid = &sid)查询到oracle会话在服务器上的pid,然后登陆到服务器上,执行kill -9 pid这样就能杀掉进程解锁了。
‘柒’ 如何查看SQL数据有没有锁表
后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。若要获取有关 SQL Server 数据库引擎中的锁的信息,请使用 sys.dm_tran_locks 动态管理视图。
USE master;
GO
EXEC sp_lock 53;
GO
‘捌’ sql server 查询有没有锁
--查看被锁表:
select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName
from sys.dm_tran_locks where resource_type='OBJECT'
--spid 锁表进程
--tableName 被锁表名
-- 解锁:
declare @spid int
Set @spid = 57 --锁表进程
declare @sql varchar(1000)
set @sql='kill '+cast(@spid as varchar)
exec(@sql)