Mysql數(shù)據(jù)庫的一個表任何操作都阻塞,

成都創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站設(shè)計制作、做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元金山做網(wǎng)站,已為上家服務(wù),為金山各地企業(yè)和個人服務(wù),聯(lián)系電話:18982081108
看會不會有一些語句卡住了,鎖表,新語句執(zhí)行不了 show full processlist,看看是否有運行太久的語句
當磁盤空間寫滿了之后,MySQL是無法再寫入任何數(shù)據(jù)的,包括對表數(shù)據(jù)的寫入,以及binlog、binlog-index等文件。
當然了,因為InnoDB是可以把臟數(shù)據(jù)先放在內(nèi)存里,所以不會立刻表現(xiàn)出來無法寫入,除非開啟了binlog,寫入請求才會被阻塞。
當MySQL檢測到磁盤空間滿了,它會:
每分鐘:檢查空間是否得到釋放,以便寫入新數(shù)據(jù)。當發(fā)現(xiàn)有剩余空間了,就會繼續(xù)寫入數(shù)據(jù),一切照舊。
每十分鐘:如果還是發(fā)現(xiàn)沒剩余空間,則會在日志中寫入一條記錄,報告磁盤空間滿(這時候只寫入幾個字節(jié)還是夠的)。
應(yīng)該怎么辦
那么,當發(fā)現(xiàn)磁盤空間滿了之后,我們應(yīng)該怎么處理呢,建議:
提高監(jiān)控系統(tǒng)檢測頻率,預(yù)防再次發(fā)生;
及時刪除不用的文件,釋放空間;
若有線程因磁盤滿的問題被阻塞了,可先殺掉,等到下一分鐘重新檢測時它可能又可以正常工作了;
可能因磁盤滿導(dǎo)致某些線程被阻塞,引發(fā)其他線程也被阻塞,可把導(dǎo)致阻塞的線程殺掉,其他被阻塞的線程也就能繼續(xù)工作了。
例外
有個例外的情況是:
當執(zhí)行 REPAIR TABLE 或者 OPTIMIZE TABLE 操作時,或者執(zhí)行完 LOAD DATA INFILE 或 ALTER TABLE 之后批量更新索引時,這些操作會創(chuàng)建臨時文件,當執(zhí)行這些操作過程中mysqld發(fā)現(xiàn)磁盤空間滿了,就會把這個涉及到的表標記為crashed,刪掉臨時文件(除了 ALTER TABLE 操作,MySQL會放棄正在執(zhí)行的操作,刪除臨時文件,釋放磁盤空間)。
備注:當執(zhí)行這些命令過程中mysqld進程被意外被殺掉的話,其所生成臨時文件不會自動刪除,需要手工刪掉才能釋放磁盤空間。
線程A等待線程B的數(shù)據(jù),線程B等待線程A的數(shù)據(jù),互相等待,就會陷入阻塞,這也是一種線程阻塞。阻塞狀態(tài)是正在運行的線程遇到某個特殊情況。例如,延遲、掛起、等待I/O操作完成等。進入阻塞狀態(tài)的線程讓出CPU,并暫時停止自己的執(zhí)行。線程進入阻塞狀態(tài)后,就一直等待,直到引起阻塞的原因被消除,線程又轉(zhuǎn)入就緒狀態(tài),重新進入就緒隊列排隊。
通過下面的查詢,?來查詢當前數(shù)據(jù)庫,?有哪些事務(wù),都鎖定哪些資源。
SELECT
trx_id?AS??`事務(wù)ID`,
trx_state?AS?`事務(wù)狀態(tài)`,
trx_requested_lock_id??AS??`事務(wù)需要等待的資源`,
trx_wait_started AS??`事務(wù)開始等待時間`,
trx_tables_in_use?AS?`事務(wù)使用表`,
trx_tables_locked?AS?`事務(wù)擁有鎖`,
trx_rows_locked??AS?`事務(wù)鎖定行`,
trx_rows_modified??AS?`事務(wù)更改行`
FROM
information_schema.innodb_trx?;
SELECT
lock_id AS `鎖ID`,
lock_trx_id? AS `擁有鎖的事務(wù)ID`,
lock_mode? AS `鎖模式 `,
lock_type? AS `鎖類型`,
lock_table? AS `被鎖的表`,
lock_index? AS `被鎖的索引`,
lock_space? AS `被鎖的表空間號`,
lock_page? AS `被鎖的頁號`,
lock_rec? AS `被鎖的記錄號`,
lock_data? AS `被鎖的數(shù)據(jù)`
FROM
information_schema.innodb_locks;
SELECT
requesting_trx_id???AS??`請求鎖的事務(wù)ID`,
requested_lock_id???AS??`請求鎖的鎖ID`,
blocking_trx_id?????AS??`當前擁有鎖的事務(wù)ID`,
blocking_lock_id????AS??`當前擁有鎖的鎖ID`
FROM
innodb_lock_waits;
查詢死鎖進程
采用如下存儲過程來查詢數(shù)據(jù)中當前造成死鎖的進程。
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 '引起數(shù)據(jù)庫死鎖的是: '+ CAST(@spid AS VARCHAR(10)) + '進程號,其執(zhí)行的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))+ '進程號,其執(zhí)行的SQL語法如下'
else
select '進程號SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '進程號SPID:'+ CAST(@blk AS VARCHAR(10)) +'阻塞,其當前進程執(zhí)行的SQL語法如下'
dbcc inputbuffer(@spid)
dbcc inputbuffer(@blk)
set @index=@index+1
end
end
drop table #temp_who_lock
return 0
end
GO
--執(zhí)行該存儲過程
exec sp_who_lock
補充:
一、產(chǎn)生死鎖的原因
在SQL Server中,阻塞更多的是產(chǎn)生于實現(xiàn)并發(fā)之間的隔離性。為了使得并發(fā)連接所做的操作之間的影響到達某一期望值而對資源人為的進行加鎖(鎖本質(zhì)其實可以看作是一個標志位)。當一個連接對特定的資源進行操作時,另一個連接同時對同樣的資源進行操作就會被阻塞,阻塞是死鎖產(chǎn)生的必要條件。
二、如何避免死鎖
1.使用事務(wù)時,盡量縮短事務(wù)的邏輯處理過程,及早提交或回滾事務(wù);
2.設(shè)置死鎖超時參數(shù)為合理范圍,如:3分鐘-10分種;超過時間,自動放棄本次操作,避免進程懸掛;
3.優(yōu)化程序,檢查并避免死鎖現(xiàn)象出現(xiàn);
4.對所有的腳本和SP都要仔細測試,在正是版本之前;
5.所有的SP都要有錯誤處理(通過@error);
6.一般不要修改SQL SERVER事務(wù)的默認級別。不推薦強行加鎖。
三、處理死鎖
1、最簡單的處理死鎖的方法就是重啟服務(wù)。
2、根據(jù)指定的死鎖進程ID進行處理
根據(jù)第二步查詢到的死鎖進行,大致分析造成死鎖的原因,并通過如下語句釋放該死鎖進程
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) --要關(guān)閉進程的數(shù)據(jù)庫名
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”為處理的數(shù)據(jù)庫名稱
exec sp_killspid 'db_name'
1、在mysql數(shù)據(jù)庫中如何鎖定一行數(shù)據(jù),保證不被其他的操作影響。
2、從對數(shù)據(jù)的操作類型分為讀鎖和寫鎖。從對數(shù)據(jù)操作的粒度來分:表鎖和行鎖。
3、現(xiàn)在我們建立一個表來演示數(shù)據(jù)庫的行鎖講解。
4、行鎖基本演示如下圖所示。
5、如果兩個會話操作的是不同的行,就不會互相阻塞了。
文章標題:mysql怎么抓阻塞 mysql查詢阻塞
轉(zhuǎn)載來源:http://www.chinadenli.net/article34/hipgse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計、用戶體驗、網(wǎng)站設(shè)計、ChatGPT、網(wǎng)站內(nèi)鏈、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)