重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
查询死锁进程
我们提供的服务有:成都网站设计、成都做网站、微信公众号开发、网站优化、网站认证、厦门ssl等。为上千多家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的厦门网站制作公司
采用如下存储过程来查询数据中当前造成死锁的进程。
drop procedure sp_who_lock
go
CREATE procedure sp_who_lock
as
begin
declare @spid int
declare @blk int
declare @count int
declare @index int
declare @lock tinyint
set @lock=0
create table #temp_who_lock
(
id int identity(1,1),
spid int,
blk int
)
if @@error0 return @@error
insert into #temp_who_lock(spid,blk)
select 0 ,blocked
from (select * from master..sysprocesses where blocked0)a
where not exists(select * from master..sysprocesses where a.blocked =spid and blocked0)
union select spid,blocked from master..sysprocesses where blocked0
if @@error0 return @@error
select @count=count(*),@index=1 from #temp_who_lock
if @@error0 return @@error
if @count=0
begin
select '没有阻塞和死锁信息'
return 0
end
while @indexA href="mailto:=@count"=@count
begin
if exists(select 1 from #temp_who_lock a where id@index and exists(select 1 from #temp_who_lock where idA href="mailto:=@index"=@index and a.blk=spid))
begin
set @lock=1
select @spid=spid,@blk=blk from #temp_who_lock where id=@index
select '引起数据库死锁的是: '+ CAST(@spid AS VARCHAR(10)) + '进程号,其执行的SQL语法如下'
select @spid, @blk
dbcc inputbuffer(@spid)
dbcc inputbuffer(@blk)
end
set @index=@index+1
end
if @lock=0
begin
set @index=1
while @indexA href="mailto:=@count"=@count
begin
select @spid=spid,@blk=blk from #temp_who_lock where id=@index
if @spid=0
select '引起阻塞的是:'+cast(@blk as varchar(10))+ '进程号,其执行的SQL语法如下'
else
select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '进程号SPID:'+ CAST(@blk AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
dbcc inputbuffer(@spid)
dbcc inputbuffer(@blk)
set @index=@index+1
end
end
drop table #temp_who_lock
return 0
end
GO
--执行该存储过程
exec sp_who_lock
补充:
一、产生死锁的原因
在SQL Server中,阻塞更多的是产生于实现并发之间的隔离性。为了使得并发连接所做的操作之间的影响到达某一期望值而对资源人为的进行加锁(锁本质其实可以看作是一个标志位)。当一个连接对特定的资源进行操作时,另一个连接同时对同样的资源进行操作就会被阻塞,阻塞是死锁产生的必要条件。
二、如何避免死锁
1.使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务;
2.设置死锁超时参数为合理范围,如:3分钟-10分种;超过时间,自动放弃本次操作,避免进程悬挂;
3.优化程序,检查并避免死锁现象出现;
4.对所有的脚本和SP都要仔细测试,在正是版本之前;
5.所有的SP都要有错误处理(通过@error);
6.一般不要修改SQL SERVER事务的默认级别。不推荐强行加锁。
三、处理死锁
1、最简单的处理死锁的方法就是重启服务。
2、根据指定的死锁进程ID进行处理
根据第二步查询到的死锁进行,大致分析造成死锁的原因,并通过如下语句释放该死锁进程
kill pid --pid为查询出来的死锁进程号
3、通过存储过程杀掉某个库下面的所有死锁进程和锁
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_killspid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_killspid]
GO
create proc sp_killspid
@dbname varchar(200) --要关闭进程的数据库名
as
declare @sql nvarchar(500)
declare @spid nvarchar(20)
declare #tb cursor for
select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
open #tb
fetch next from #tb into @spid
while @@fetch_status=0
begin
exec('kill '+@spid)
fetch next from #tb into @spid
end
close #tb
deallocate #tb
go
--使用方法,“db_name”为处理的数据库名称
exec sp_killspid 'db_name'
1.查看表是否被锁:
(1)直接在mysql命令行执行:showengineinnodbstatus\G。
(2)查看造成死锁的sql语句,分析索引情况,然后优化sql。
(3)然后showprocesslist,查看造成死锁占用时间长的sql语句。
(4)showstatuslike‘%lock%。
2.查看表被锁状态和结束死锁步骤:
(1)查看表被锁状态:showOPENTABLESwhereIn_use0;这个语句记录当前锁表状态。
(2)查询进程:showprocesslist查询表被锁进程;查询到相应进程killid。
(3)分析锁表的SQL:分析相应SQL,给表加索引,常用字段加索引,表关联字段加索引。
(4)查看正在锁的事物:SELECT*FROMINFORMATION_SCHEMA.INNODB_LOCKS。
(5)查看等待锁的事物:SELECT*FROMINFORMATION_SCHEMA.INNODB_LOCK_WAITS。
扩展资料
MySQL锁定状态查看命令:
Checkingtable:正在检查数据表(这是自动的)。
Closingtables:正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是这样的话,就应该确认磁盘空间是否已经满了或者磁盘是否正处于重负中。
ConnectOut:复制从服务器正在连接主服务器。
Copyingtotmptableondisk:由于临时结果集大于tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。
Creatingtmptable:正在创建临时表以存放部分查询结果。
deletingfrommaintable:服务器正在执行多表删除中的第一部分,刚删除第一个表。
deletingfromreferencetables:服务器正在执行多表删除中的第二部分,正在删除其他表的记录。
Flushingtables:正在执行FLUSHTABLES,等待其他线程关闭数据表。
Killed:发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在锁释放时马上生效。
Locked:被其他查询锁住了。
Sendingdata:正在处理SELECT查询的记录,同时正在把结果发送给客户端。
Sortingforgroup:正在为GROUPBY做排序。
Sortingfororder:正在为ORDERBY做排序。
Openingtables:这个过程应该会很快,除非受到其他因素的干扰。例如,在执ALTERTABLE或LOCKTABLE语句行完以前,数据表无法被其他线程打开。正尝试打开一个表。
Removingduplicates:正在执行一个SELECTDISTINCT方式的查询,但是MySQL无法在前一个阶段优化掉那些重复的记录。因此,MySQL需要再次去掉重复的记录,然后再把结果发送给客户端。
Reopentable:获得了对一个表的锁,但是必须在表结构修改之后才能获得这个锁。已经释放锁,关闭数据表,正尝试重新打开数据表。
Repairbysorting:修复指令正在排序以创建索引。
Repairwithkeycache:修复指令正在利用索引缓存一个一个地创建新索引。它会比Repairbysorting慢些。
Searchingrowsforupdate:正在讲符合条件的记录找出来以备更新。它必须在UPDATE要修改相关的记录之前就完成了。
Sleeping:正在等待客户端发送新请求。
Systemlock:正在等待取得一个外部的系统锁。如果当前没有运行多个mysqld服务器同时请求同一个表,那么可以通过增加--skip-external-locking参数来禁止外部系统锁。
Upgradinglock:INSERTDELAYED正在尝试取得一个锁表以插入新记录。
Updating:正在搜索匹配的记录,并且修改它们。
UserLock:正在等待GET_LOCK()。
Waitingfortables:该线程得到通知,数据表结构已经被修改了,需要重新打开数据表以取得新的结构。然后,为了能的重新打开数据表,必须等到所有其他线程关闭这个表。
waitingforhandlerinsert:INSERTDELAYED已经处理完了所有待处理的插入操作,正在等待新的请求。
如果要查询服务器上正在跑哪些查询进程,使用show processlist;
如果要查询当地哪些进程正在和mysql交互,可以使用操作系统自带的netstat等工具查看mysql所在的IP和3306端口
ps
-ef|grep
mysql
可以看到是否有mysql进程,如果有mysqld这行(一般会有2行以上)则表示正常运行
也可以mysql
-u
root
-p登陆试试看能不能登陆
如果没有启动,service
mysqld
start启动下
可以先使用 uptime 命令查看 CPU 平均负载
那个 2 users 表示用户连接数,指的是总连接数。
那个 load average 就是系统平均负载,1 分钟、5 分钟、15 分钟系统负载的平均值。
指的是一段时间内 CPU 正在处理以及等待 CPU 处理的进程数之和的统计信息,也就是 CPU 使用队列的长度的统计信息。这个数字越小越好。
然后再用 vmstat 命令看下 CPU 是否饱和
这里面的 r 就是等待 CPU 的进程数,可以用来判定 CPU 是否饱和,当 r 值高于 CPU 数时,就意味着饱和了。
一、用phpMyAdmin进行查看
二、用命令行的SHOW 语句
直接在命令行下登陆MySQL运行SHOW STATUS;查询语句
同样的语句还有SHOW VARIABLES;,SHOW STATUS是查看MySQL运行情况,和上面那种通过pma查看到的信息基本类似。
SHOW VARIABLES
SHOW VARIABLES是查看MySQL的配置参数,还可以使用类似SHOW VARIABLES LIKE ‘Key%’
SHOW PROCESSLIST
SHOW PROCESSLIST是查看当前正在进行的进程,对于有锁表等情况的排查很有用处。一般情况下,打开MySQL的慢查询记录同样有利于排查。
SHOW OPEN TABLES
SHOW OPEN TABLES是显示当前已经被打开的表列表。
三、用MySQL自带工具mysqladmin 查看
使用MySQL自带的mysqladmin 工具查看status,使用以下命令
mysqladmin -uroot -p密码 status
显示的结果如下:
Uptime: 502963 Threads: 2 Questions: 8561820 Slow queries: 734681 Opens: 553
45 Flush tables: 1 Open tables: 85 Queries per second avg: 17.023
另外可以添加 -i 5 参数,让其每五秒自动刷新之。
mysqladmin -uroot -p密码 status -i 5
mysqladmin extended-status
同样的可以使用mysqladmin -uroot -p密码 extended-status来查看更多的MySQL运行信息,这种方式和第一种查看的信息基本一样。