【1】 錯誤日志簡介
【1.1】. Windows事件日志與SQL Server 錯誤日志
【1.2】. 如何理解SQL Server的Error message?
【1.3】. SQL Server 錯誤日志包含哪些信息
【1.4】. SQL Server 錯誤日志存放在哪里
【1.5】. SQL Server 錯誤日志目錄下的其他文件
【1.6】錯誤號具體對應信息
0-9 :返回不太嚴重的狀態信息或報表錯誤的信息性消息。 數據庫引擎 不會引起嚴重級別為 0 到 9 的系統錯誤。
10 :返回不太嚴重的狀態信息或報表錯誤的信息性消息。 由於兼容性原因, 數據庫引擎 在將錯誤信息返回到調用應用程序前將嚴重性級別從 10 轉換為 0。
11-16 :指示可由用戶糾正的錯誤。
17-19 :指示無法由用戶糾正的軟件錯誤。 請將問題通知系統管理員。
20-24 :指示系統問題並且是致命錯誤,這意味着正在執行某語句或批處理的 數據庫引擎 任務已停止運行。此任務記錄了所發生事件的有關信息,然后終止。
在大多數情況下,應用程序與 數據庫引擎 實例的連接也可能終止。 如果發生這種情況,該問題可能使應用程序無法重新連接。
【2】錯誤日志維護
【2.0】維護SQL匯總
-- 查看錯誤日志URL路徑 SELECT SERVERPROPERTY('ErrorLogFileName') -- 查看所有錯誤日志文件名即文件大小 EXEC master..xp_enumerrorlogs -- 查看錯誤日志文件具體內容 exec dbo.xp_readerrorlog 文件編號,文件類型,N'檢索string1',N'and檢索string2',開始時間,結束時間,N'結果排序desc' -- 輪轉錯誤日志 與 代理Agent日志 EXEC master..sp_cycle_errorlog; --DBCC ERRORLOG 亦可 EXEC msdb.dbo.sp_cycle_agent_errorlog;--SQL Agent 服務需在啟動狀態下才有效
【2.1】錯誤日志文件個數
-- 查看所有錯誤日志文件名即文件大小 EXEC master..xp_enumerrorlogs
查看最大錯誤日志個數
通過T-SQL查看最大錯誤日志個數
USE [master] GO EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', REG_DWORD, 50 GO --Check current errorlog amout USE [master] GO DECLARE @i int EXEC xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', @i OUTPUT SELECT @i
【2.2】SQL Server Agent錯誤日志
如何查看?Agent錯誤日志位置?
【2.3】錯誤日志歸檔
(1) 為什么要歸檔錯誤日志?
假設SQL Server實例從來沒被重啟過,也沒有手動歸檔過錯誤日志,那么錯誤日志文件可能會變得很大,尤其是有內部錯誤時會DUMP很多信息,一來占空間,更重要的是:想要查看分析也會不太方便。
SQL Server/SQL Server Agent 錯誤日志有2種歸檔方式,即:創建一個新的日志文件,並將最老的日志刪除。
(1) 自動歸檔:在SQL Server/ SQL Server Agent服務重啟時;
(2) 手動歸檔:定期運行如下系統存儲過程
EXEC master..sp_cycle_errorlog; --DBCC ERRORLOG 亦可 EXEC msdb.dbo.sp_cycle_agent_errorlog;--SQL Agent 服務需在啟動狀態下才有效
【2.4】錯誤日志的查看 與告警
錯誤日志以文本方式記錄,記事本就可以查看,如果錯誤日志很大,可以選擇Gvim/UltraEdit /DOS窗口type errorlog等,這些方式都會“分頁”加載,不會卡住。
(1)錯誤日志查看
SQL Server提供了以下2種方式查看:
(1) 日志查看器 (log viewer),除了可以查看SQL Server 與SQL Server Agent的錯誤日志,還可以查看操作系統日志、數據庫郵件日志。不過當日志文件太大時,圖形界面非常慢;
(2) 未記載的擴展存儲過程xp_readerrorlog,另外還有一個名為sp_readerrorlog的存儲過程,它是對xp_readerrorlog的簡單封裝,並且只提供了4個參數,直接使用xp_readerrorlog即可:
在SQL Server 2005及以后版本里,支持多達7個參數,說明如下:
exec dbo.xp_readerrorlog 1,1,N'string1',N'string2',null,null,N'desc'
參數1.日志文件號: 0 = 當前, 1 = Archive #1, 2 = Archive #2, etc...
參數2.日志文件類型: 1 or NULL = SQL Server 錯誤日志, 2 = SQL Agent 錯誤日志
參數3.檢索字符串1: 用來檢索的字符串
參數4.檢索字符串2: 在檢索字符串1的返回結果之上再做過濾
參數5.日志開始時間
參數6.日志結束時間
參數7.結果排序: N'asc' = 升序, N'desc' = 降序
--sql server 2005 read error log 包含某內容的信息 if OBJECT_ID('tempdb..#tmp_error_log') is not null drop table #tmp_error_log create table #tmp_error_log ( logdate datetime, processinfo varchar(100), info varchar(8000) ) insert into #tmp_error_log exec dbo.xp_readerrorlog select * from #tmp_error_log where info like '%18456%'
(2)獲取錯誤日志告警信息
可以通過對某些關鍵字做檢索:錯誤(Error),警告(Warn),失敗(Fail),停止(Stop),而進行告警 (database mail),以下腳本檢索24小時內的錯誤日志:
--檢索24小時內出現的錯誤日志
declare@start_time datetime,@end_time datetime set @start_time = CONVERT(char(10),GETDATE() - 1,120) set @end_time = GETDATE() if OBJECT_ID('tempdb..#tmp_error_log') is not null drop table #tmp_error_log create table #tmp_error_log ( logdate datetime, processinfo varchar(100), info varchar(8000) ) insert into #tmp_error_log exec dbo.xp_readerrorlog 0,1,NULL,NULL,@start_time,@end_time,N'desc' select COUNT(1) as num, MAX(logdate) as logdate,info from #tmp_error_log where (info like '%ERROR%' or info like '%WARN%' or info like '%FAIL%' or info like '%STOP%') and info not like '%CHECKDB%' and info not like '%Registry startup parameters%' and info not like '%Logging SQL Server messages in file%' and info not like '%previous log for older entries%' group by info
當然,還可以添加更多關鍵字:kill, dead, victim, cannot, could, not, terminate, bypass, roll, truncate, upgrade, recover, IO requests taking longer than,但當中有個例外,就是DBCC CHECKDB,它的運行結果中必然包括Error字樣,如下:
DBCC CHECKDB (xxxx) executed by sqladmin found 0 errors and repaired 0 errors.
所以對0 errors要跳過,只有在發現非0 errors時才作告警。
(3)小結
如果沒有監控工具,那么可選擇擴展存儲過程,結合數據庫郵件的方式,作自動檢查及告警,並定期歸檔錯誤日志文件以避免文件太大。大致步驟如下 :
(1) 部署數據庫郵件;
(2) 部署作業:定時檢查日志文件,如檢索到關鍵字,發郵件告警;
(3) 部署作業:定期歸檔錯誤日志,可與步驟(2) 合並作為兩個step放在一個作業里。
【3】根據警報監控錯誤日志
該部分轉自:https://www.cnblogs.com/kerrycode/p/4056491.html
SQL Server的錯誤消息(Error Message)按照消息的嚴重級別一共划分25個等級,級別越高,表示嚴重性也越高。但是如果你統計sys.messages,你會發現,實際上只有16(SQL SERVER 2008/2012)或17個(SQL SERVER 2005)個級別。猜測應該是一些留作擴展用,一些留作用戶自定義錯誤消息的級別。
sys.messages中有個字段is_event_logged,取值為1時表示出現錯誤時將消息記入事件日志。 對於 message_id 中的所有消息語言,此參數都是相同的。所以也就是說有些錯誤信息(Error Message)會寫入事件日志,有些就不會寫入錯誤日志。因此監控錯誤日志時,我們只能監控那些寫入錯誤日志的錯誤信息。一般而言,我們應該監控嚴重級別在16~25之間的錯誤信息,另外嚴重級別14的也應該監控(主要是Error: 18456, Severity: 14)。
監控錯誤日志有很多方式,下面介紹一種非常簡單、有效的監控錯誤日志的方法.我們可以通過sp_add_alert創建一個警報(Alerts),如下所示,我們創建一個名稱為SQL Server Severity Event 14的警報(配置前需要配置郵件、ProfileName,Operators,下面腳本也要根據具體情況調整)。關於創建警報的具體信息,可以參考http://msdn.microsoft.com/zh-cn/library/ms189531.aspx
USE [msdb]
GO
IF NOT EXISTS(SELECT 1 FROM msdb.dbo.syscategories WHERE NAME='DBA_MONITORING' AND category_class=2)
BEGIN
EXEC msdb.dbo.sp_add_category @class=N'ALERT', @type=N'NONE', @name=N'DBA_MONITORING' ; END GO IF EXISTS (SELECT name FROM msdb.dbo.sysalerts WHERE name = N'SQL Severity Event 14') EXEC msdb.dbo.sp_delete_alert @name=N'SQL Server Severity Event 14' GO USE [msdb] GO EXEC msdb.dbo.sp_add_alert @name=N'SQL Server Severity Event 14', @message_id=0, @severity=14, @enabled=1, @delay_between_responses=60, @include_event_description_in=1, @category_name=N'DBA_MONITORING', @job_id=N'00000000-0000-0000-0000-000000000000' GO EXEC msdb.dbo.sp_add_notification @alert_name=N'SQL Server Severity Event 14', @operator_name=N'YourSQLDba_Operator', @notification_method = 1 GO
如下所示,在UAT服務器,我故意用dw賬號錯誤密碼登錄數據庫,一分鍾后,我立馬回收到一封告警郵件
DATE/TIME: ; 2014/10/28 9:21:42
DESCRIPTION: ; Login failed for user 'dw'. Reason: Password did not match that for the login provided. [CLIENT: 192.xxx.xxx.xxx]
COMMENT: ; (None)
JOB ;RUN: (None)
SQL Server 錯誤日志
Windows事件日志
我們依次建立16-25級別的告警來監控數據庫錯誤日志的錯誤信息。如下所示:

執行完上面腳本后,就會建立下面幾個告警。當數據庫的錯誤日志出現這些級別的錯誤信息時,就會收到告警郵件。相當的方便、簡單、高效。
【4】根據T-SQL監控錯誤日志
--檢索24小時內出現的錯誤日志
declare@start_time datetime,@end_time datetime set @start_time = CONVERT(char(10),GETDATE() - 1,120) set @end_time = GETDATE() if OBJECT_ID('tempdb..#tmp_error_log') is not null drop table #tmp_error_log create table #tmp_error_log ( logdate datetime, processinfo varchar(100), info varchar(8000) ) insert into #tmp_error_log exec dbo.xp_readerrorlog 0,1,NULL,NULL,@start_time,@end_time,N'desc' select COUNT(1) as num, MAX(logdate) as logdate,info from #tmp_error_log where (info like '%ERROR%' or info like '%WARN%' or info like '%FAIL%' or info like '%STOP%') and info not like '%CHECKDB%' and info not like '%Registry startup parameters%' and info not like '%Logging SQL Server messages in file%' and info not like '%previous log for older entries%' group by info