上周五組長對我說了一句要殺死數據庫的死鎖進程,有時候同一時刻不停寫入數據庫會造成這種情況的發生,因為自己對數據庫不是很熟悉,突然組長說了我也就決定一定要倒騰一下,不然自己怎么提高呢?現在不研究,說不定下次還是要研究呢,倒騰出來了就可以在下次用到了,后來組長又補了一句:"還有定時備份數據庫的問題要解決",說干就干。
PS:Sqlserver 2008 R2,windows 8 64位
1.備份數據庫
因為要備份,我們就要用到Sqlserver的代理,默認數據庫的代理是不開啟的。需要我們手動開啟的。
執行備份數據庫腳本,現在將腳本公布,其實將這一段代碼中需要保存的文件路徑和數據庫名稱替換一下就可以實現備份了。但是還沒有達到定時備份的目的
--自動備份並保存最近5天的SQL數據庫作業腳本 DECLARE @filename VARCHAR(255) DECLARE @date DATETIME SELECT @date=GETDATE() SELECT @filename = 'G:\存放位置\數據庫名稱-'+CAST(DATEPART(yyyy,@date) as varchar)+'-'+CAST(DATEPART(mm,@date) as varchar)+'-'+CAST(DATEPART(dd,@date) as varchar)+'.bak' BACKUP DATABASE [數據庫名稱] TO DISK = @filename WITH INIT GO DECLARE @OLDDATE DATETIME SELECT @OLDDATE=GETDATE()-5 EXECUTE master.dbo.xp_delete_file 0,N'G:\存放位置',N'bak',@olddate,1
2.定時備份指定數據庫
剛剛開啟了Sqlserver代理服務,其實我自己的理解就是一個定時器,不停的執行一些操作者分配給他的任務,有點像鬧鍾的感覺,看我的演示步驟
第一步
第二步
第三步
第四步
第五步
上面的步驟就是完成了定時備份指定數據庫的功能!
**************************************************************************
1.殺死數據庫死鎖進程
接下來介紹一些殺死數據庫死鎖進程的方法
下午折騰了半天找了很多的文章看了一下,發現很多都是使用到了master中的sys.sysprocesses表(http://msdn.microsoft.com/zh-cn/library/ms179881(SQL.90).aspx)這里附上msdn對這個表的解釋,不懂的可以參考看看這里面的每個表字段的含義。
參考了網上的意見,大部分都是寫一個存儲過程在master數據庫中,然后使用作業的方式定時殺死死鎖進程的,覺得這個方法可行!
下面是存儲過程SQL語句
--數據庫死鎖解決,結合作業(百度)實現定時清除數據庫死鎖進程,存儲過程放在master數據庫中 USE master GO SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO CREATE PROCEDURE sp_who_lock AS BEGIN DECLARE @spid INT , @bl INT , @intTransactionCountOnEntry INT , @intRowcount INT , @intCountProperties INT , @intCounter INT CREATE TABLE #tmp_lock_who ( id INT IDENTITY(1, 1) , spid SMALLINT , bl SMALLINT ) IF @@ERROR <> 0 RETURN @@ERROR INSERT INTO #tmp_lock_who ( spid, bl ) SELECT 0, blocked FROM ( SELECT * FROM sys.sysprocesses WHERE blocked > 0 ) a WHERE NOT EXISTS ( SELECT * FROM ( SELECT * FROM sys.sysprocesses WHERE blocked > 0 ) b WHERE a.blocked = spid ) UNION SELECT spid, blocked FROM sys.sysprocesses WHERE blocked > 0 IF @@ERROR <> 0 RETURN @@ERROR -- 找到臨時表的記錄數 SELECT @intCountProperties = COUNT(*), @intCounter = 1 FROM #tmp_lock_who IF @@ERROR <> 0 RETURN @@ERROR IF @intCountProperties = 0 SELECT N'現在沒有阻塞和死鎖信息' AS message -- 循環開始 WHILE @intCounter <= @intCountProperties BEGIN -- 取第一條記錄 SELECT @spid = spid, @bl = bl FROM #tmp_lock_who WHERE Id = @intCounter BEGIN IF @spid = 0 SELECT N'引起數據庫死鎖的是: ' + CAST(@bl AS VARCHAR(10)) + N'進程號,其執行的SQL語法如下' ELSE SELECT N'進程號SPID:' + CAST(@spid AS VARCHAR(10)) + N'被進程號SPID:' + CAST(@bl AS VARCHAR(10)) N'阻塞,其當前進程執行的SQL語法如下' DBCC INPUTBUFFER (@bl ) END -- 循環指針下移 SET @intCounter = @intCounter + 1 END DROP TABLE #tmp_lock_who RETURN 0 END go
上面sql語句執行完成也就在master數據庫生成了存儲過程,調用的代碼很簡單
--執行 EXEC sp_who_lock GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
調用完成之后就可以殺死數據庫當中的所有死鎖進程
題外話:如何判斷那些進程是否是死鎖進程,這個是關鍵點,在msdn中對sys.sysprocesses表的有一個字段blocked這個字段,取出所有大於0的就是數據庫的死鎖進程數據,然后使用KILL+SPID(進程ID)執行就可以殺死死鎖進程,主要思想就是這些。
2.定時殺死數據庫死鎖進程
對於定時殺死數據庫死鎖進程,這里有兩點需要注意
1.執行的順序,現在master數據庫創建存儲過程,然后創建作業
2.作業的執行代碼,執行代碼是調用殺死死鎖進程的存儲過程(調用存儲過程的sql語句,不能包含刪除存儲過程(DROP xxx)這樣的語句是不行,到時候作業第一次執行后,第二次就要報錯了,就永遠執行不成功
第一步
需要執行上面的殺死死鎖進程的存儲過程,只有master數據庫中存在這個存儲過程,才可以以作業的方式調用這個存儲過程,否則就是調用失敗★
第二步
創建一個新的作業,將剛剛的調用存儲過程的SQL語句放入到新建作業=>步驟選項=>命令,中就可以了。最后一步執行計划自己根據實際情況進行設置
關於Sqlserver數據庫的兩個難點也在這個下午被我自己吸收了。將來碰到類似的問題也可以輕松應對了,如果大家覺得有幫助可以幫小弟推薦一下哦!
如果文章中有錯誤的地方,大家可以聯系我的qq:707055073
我的群:152652959
版權所有,違法必究。
轉載請說明原文鏈接