2. SQL Server數據庫狀態監控 - 錯誤日誌

不管是操做系統 (Unix 或者Windows),仍是應用程序 (Web 服務,數據庫系統等等) ,一般都有自身的日誌機制,以便故障時追溯現場及緣由。Windows Event Log和 SQL Server Error Log就是這樣的日誌, PS: SQL Server 中的錯誤日誌 (Error Log) 相似於 Oracle中的alert 文件。sql

. 錯誤日誌簡介shell

1. Windows事件日誌與SQL Server 錯誤日誌數據庫

Windows事件日誌中,應用程序裏的SQL Server和SQL Server Agent服務,分別對應來源自MSSQLSERVER和SQLSERVERAGENT的日誌信息;vim

SQL Server錯誤日誌中信息,與Windows事件日誌裏來源自MSSQLSERVER的日誌信息基本一致,不一樣的是,Windows事件日誌裏信息爲應用程序級,較爲簡潔些,而SQL Server錯誤日誌裏一般有具體的數據庫錯誤信息。好比:windows

Windows事件日誌中錯誤信息:服務器

Login failed for user 'sa'. Reason: Password did not match that for the login provided. [CLIENT: 10.213.20.8]app

SQL Server錯誤日誌中錯誤信息:編輯器

Login failed for user 'sa'. Reason: Password did not match that for the login provided. [CLIENT: 10.213.20.8]ide

Error: 18456, Severity: 14, State: 8.工具

 

2. 如何理解SQL ServerError 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服務就行了。

 

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錯誤日誌中一樣也包括:信息/警告/錯誤這幾類日誌,但要簡單不少。

 

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')

 

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. 錯誤日誌文件個數

1.1 SQL Server錯誤日誌

SQL Server錯誤日誌文件數量默認爲7個:1個正在用的(ERRORLOG)和6個歸檔的(ERRORLOG.1 – ERRORLOG.6),能夠配置以保留更多(最多99個);

(1) 打開到SSMS/管理/SQL Server Logs文件夾/右擊/配置;

(2) 經過未記載的擴展存儲過程,直接讀寫註冊表也行:

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

SQL Server做爲一個Windows下的應用程序,不少信息是寫在註冊表裏的,天然也能夠手動打開註冊表編輯器或寫SHELL去修改註冊表來做配置。

最後,能夠經過 以下SQL語句查看已存在的錯誤日誌編號、起止時間、當前大小。

EXEC master..xp_enumerrorlogs

 

1.2 SQL Server Agent錯誤日誌

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

(1) 打開到SSMS/SQL Server Agent/Error Logs文件夾/右擊/配置;

(2) 未記載的擴展存儲過程:

USE [msdb]
GO
EXEC msdb.dbo.sp_set_sqlagent_properties @errorlogging_level=7
GO

至於@errorlogging_level各個值的意思,因爲沒有文檔記載,須要本身測試並推算下。

 

2. 錯誤日誌文件歸檔

2.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.2 可不能夠根據文件大小來歸檔?

可能有人會以爲,雖然好久沒歸檔,可是錯誤日誌確實不大,不必按期歸檔,最好能夠根據文件大小來判斷。有如下幾種方法:

(1) 有些監控工具,好比:SQL Diagnostic manager,就有檢測錯誤日誌文件大小,並根據大小來決定是否歸檔的功能;

(2) 自定義腳本也能夠,好比:powershell, xp_enumerrorlogs 均可以檢查錯誤日誌大小;

(3) SQL Server 2012支持一個註冊表選項,如下語句限制每一個錯誤日誌文件爲5M,到了5M就會自動歸檔,在2008/2008 R2測試無效:

USE [master]
GO
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'ErrorLogSizeInKb', REG_DWORD, 5120;

 

. 錯誤日誌查看及告警

錯誤日誌以文本方式記錄,記事本就能夠查看,若是錯誤日誌很大,能夠選擇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 2000裏,僅支持一個參數,即錯誤日誌號,默認爲0~6:

exec dbo.xp_readerrorlog   --寫0或null都會報錯,直接運行便可
exec dbo.xp_readerrorlog 1
exec dbo.xp_readerrorlog 6

 

--sql server 2000 read error log
if OBJECT_ID('tempdb..#tmp_error_log_all') is not null
    drop table #tmp_error_log_all

create table #tmp_error_log_all
(
info varchar(8000),--datetime + processinfo + text
num  int
)

insert into #tmp_error_log_all
exec dbo.xp_readerrorlog

--split error text
if OBJECT_ID('tempdb..#tmp_error_log_split') is not null
    drop table #tmp_error_log_split
create table #tmp_error_log_split
(
logdate      datetime,--datetime
processinfo  varchar(100),--processinfo
info         varchar(7900)--text
)

insert into #tmp_error_log_split
select CONVERT(DATETIME,LEFT(info,22),120),
       LEFT(STUFF(info,1,23,''),CHARINDEX(' ',STUFF(info,1,23,'')) - 1),
       LTRIM(STUFF(info,1,23 + CHARINDEX(' ',STUFF(info,1,23,'')),''))
  from #tmp_error_log_all
 where ISNUMERIC(LEFT(info,4)) = 1
   and info <> '.'
   and substring(info,11,1) = ' '

select * from #tmp_error_log_split where info like '%18456%'

 

在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小時內的錯誤日誌:

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時才做告警。

 

小結

若是沒有監控工具,那麼可選擇擴展存儲過程,結合數據庫郵件的方式,做自動檢查及告警,並按期歸檔錯誤日誌文件以免文件太大。大體步驟以下 :

(1) 部署數據庫郵件;

(2) 部署做業:定時檢查日誌文件,如檢索到關鍵字,發郵件告警;

(3) 部署做業:按期歸檔錯誤日誌,可與步驟(2) 合併做爲兩個step放在一個做業裏。

相關文章
相關標籤/搜索