sql server錯誤日志


【1】 錯誤日志簡介

【1.1】. Windows事件日志與SQL Server 錯誤日志

  Windows事件日志中,應用程序里的SQL Server和SQL Server Agent服務,分別對應來源自MSSQLSERVER和SQLSERVERAGENT的日志信息;
  SQL Server錯誤日志中信息,與Windows事件日志里來源自MSSQLSERVER的日志信息基本一致,不同的是,Windows事件日志里信息為應用程序級,較為簡潔些,而SQL Server錯誤日志里通常有具體的數據庫錯誤信息。比如:
  Windows事件日志中錯誤信息:
  Login failed for user 'sa'. Reason: Password did not match that for the login provided. [CLIENT: 10.213.20.8]
  SQL Server錯誤日志中錯誤信息:
  Login failed for user 'sa'. Reason: Password did not match that for the login provided. [CLIENT: 10.213.20.8]
  Error: 18456, Severity: 14, State: 8.

【1.2】. 如何理解SQL Server的Error message?

  以上面的Error: 18456, Severity: 14, State: 8.為例:
  (1) Error,錯誤編號,可以在系統表里查到對應的文本信息;
  select * From sys.messages where message_id = 18456
  (2) Severity,錯誤級別,表明這個錯誤的嚴重性,一共有25個等級,級別越高,就越需要我們去注意處理,20~25級別的錯誤會直接報錯並跳出執行,用SQL語句的TRY…CATCH是捕獲不到的;
  (3) State,錯誤狀態,比如18456錯誤,幫助文檔記載了如下狀態,不同狀態代表不同錯誤原因:
  1. Error information is not available. This state usually means you do not have permission to receive the error details. Contact your SQL Server administrator for more information.
  2.  User ID is not valid.
  5.  User ID is not valid.
  6.  An attempt was made to use a Windows login name with SQL Server Authentication.
  7.  Login is disabled, and the password is incorrect.
  8.  The password is incorrect.
  9.  Password is not valid.
  11. Login is valid, but server access failed.
  12. Login is valid login, but server access failed.
  18. Password must be changed.
  還有文檔未記載的State: 10, State: 16,通常是SQL Server啟動帳號權限問題,或者重啟SQL Server服務就好了。

【1.3】. SQL Server 錯誤日志包含哪些信息

  SQL Server錯誤日志中包含SQL Server開啟、運行、終止整個過程的:運行環境信息、重要操作、級別比較高的錯誤等:
  (1)  SQL Server/Windows基本信息,如:版本、進程號、IP/主機名、端口、CPU個數等;
  (2) SQL Server啟動參數及認證模式、內存分配;
  (3) SQL Server實例下每個數據打開狀態(包括系統和用戶數據庫);
  (4) 數據庫或服務器配置選項變更,KILL操作,開關DBCC跟蹤,登錄失敗等等
  (5) 數據庫備份/還原的記錄;
  (6) 內存相關的錯誤和警告,可能會DUMP很多信息在錯誤日志里;
  (7) SQL Server調度異常警告、IO操作延遲警告、內部訪問越界 (也就是下面說到的Error 0);
  (8) 數據庫損壞的相關錯誤,以及DBCC CHECKDB的結果;
  (9) 實例關閉時間;
  另外,可以手動開關一些跟蹤標記(trace flags),來自定義錯誤日志的內容,比如:記錄如用戶登入登出記錄(login auditing),查詢的編譯執行等信息,比較常用的可能是用於檢查死鎖時的1204/1222 跟蹤標記。
  通常錯誤日志不會記錄SQL語句的性能問題,如:阻塞、超時的信息,也不會記錄Windows層面的異常(這會在windows事件日志中記載)。
  SQL Server Agent錯誤日志中同樣也包括:信息/警告/錯誤這幾類日志,但要簡單很多。

【1.4】. SQL Server 錯誤日志存放在哪里

  假設SQL Server被安裝在X:\Program Files\Microsoft SQL Server,則SQL Server 與SQL Server Agent的錯誤日志文件默認被放在:
  X:\Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\ ERRORLOG ~ ERRORLOG.n
  X:\Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\SQLAGENT.n and SQLAGENT.out.
  如果錯誤日志路徑被管理員修改,可以通過以下某種方式找到:
  (1) 操作系統的應用程序日志里,SQL Server啟動時會留下錯誤日志文件的路徑;
  (2) 通過SSMS/管理/錯誤日志,SQL Server啟動時會留下錯誤日志文件的路徑;
  (3) SQL Server配置管理器里,點擊SQL Server實例/屬性/高級/啟動參數 (Startup parameters) ;
  (4) 通過一個未記載的SQL語句 (在SQL Server 2000中測試無效,2005及以后可以):
  SELECT SERVERPROPERTY('ErrorLogFileName')

【1.5】. SQL Server 錯誤日志目錄下的其他文件

  在錯誤日志目錄下除了SQL Server和SQL Server Agent的日志,可能還會有以下文件:
  (1) 維護計划產生的report文件 (SQL Server 2000的時候,后來的維護計划log記錄在msdb);
  (2) 默認跟蹤(default trace) 生成的trace文件,PS: 審計(Audit) 產生的trace文件在\MSSQL\DATA下;
  (3) 全文索引的錯誤、日志文件;
  (4) SQLDUMP文件,比如:exception.log/SQLDump0001.txt/SQLDump0001.mdmp,大多是發生Error 0時DUMP出來的,同時在錯誤日志里通常會有類似如下記錄:
  Error: 0, Severity: 19, State: 0
  SqlDumpExceptionHandler: Process 232 generated fatal exception c0000005 EXCEPTION_ACCESS_VIOLATION. SQL Server is terminating this process.
  順便說下ERROR 0 的解釋:
  You've hit a bug of some kind - an access violation is an unexpected condition. You need to contact Product Support (http://support.microsoft.com/sql) to help figure out what happened and whether there's a fix available.
  Is your server up to date with service packs? If not, you might try updating to the latest build. This error is an internal error in sql server. If you are up to date, you should report it to MS.

【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錯誤日志

  SQL Server Agent錯誤日志文件數量共為10個:1個正在用的(SQLAGENT.OUT),9個歸檔的(SQLAGENT.1 - SQLAGENT.9),個數不可以修改。
  但可以配置日志所記載的信息類型:信息、警告、錯誤。

如何查看?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)可不可以根據文件大小來歸檔?
  可能有人會覺得,雖然很久沒歸檔,但是錯誤日志確實不大,沒必要定期歸檔,最好可以根據文件大小來判斷。有以下幾種方法:
  (1) 有些監控工具,比如:SQL Diagnostic manager,就有檢測錯誤日志文件大小,並根據大小來決定是否歸檔的功能;
  (2) 自定義腳本也可以,比如:powershell, xp_enumerrorlogs 都可以檢查錯誤日志大小;

【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)個級別。猜測應該是一些留作擴展用,一些留作用戶自定義錯誤消息的級別。

clipboard

 

clipboard[1]

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賬號錯誤密碼登錄數據庫,一分鍾后,我立馬回收到一封告警郵件

clipboard[2]

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 錯誤日志

 

clipboard[3]

 

Windows事件日志

clipboard[4]

 

我們依次建立16-25級別的告警來監控數據庫錯誤日志的錯誤信息。如下所示:

16_25告警監控

 

執行完上面腳本后,就會建立下面幾個告警。當數據庫的錯誤日志出現這些級別的錯誤信息時,就會收到告警郵件。相當的方便、簡單、高效。

clipboard[5]

【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

 

【參考文檔】

錯誤日志的概念:http://www.51testing.com/html/30/n-867830-3.html

監控錯誤日志:https://www.cnblogs.com/kerrycode/p/4056491.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM