【IT168 技术】为了保持SQL Server运行正常且平稳,就需要不间断的进行日常维护和监测工作。如果没有时刻保持警惕性,SQL Server的性能和稳定性将遭受损害。更严重的是数据库可能无法恢复,甚至彻底崩溃。本文将讨论DBA需要完成的日常工作,此外还将提供一部分脚本和建议,帮助大家缩短日常工作的时间。但是每个不同的环境,日常工作也会有所区别,本文提到的工作即使不能适用于所有的SQL Server设备,但对绝大多数情况都可以适用。
验证服务的可用性
需要确保起关键作用的SQL Server服务器的可用性。首先每天早晨上班时需要确定是否所有的SQL Server服务器都正常运转,这一项工作最好是积极主动并且反应迅速的。如果被用户打电话投诉某个服务器存在故障,后果将非常严重。
理想的情况是使用监控工具,可以在服务器不在正常运转时自动发送Email报告故障,这种方式可以使服务器在发生故障时立即做出反应并开始进行补救措施。该监控工具可以自己开发,也可以购买现成的。如果没有配置自动化的监控工具,也可以使用SQL Server Management Studio 里的Registered Servers工具向服务器发送单独的T-SQL语句。确保每个SQL Server实例能够正常运行,并且可以对简单的T-SQL语句进行响应,这样就可以轻松的了解每个实例预期的响应结果。通过监测实例,可以避免大部分询问特定服务器是否正常运行的尴尬问题。
系统补丁或者服务升级包安装后检验服务器的工作状况尤为重要,有时候服务器没有正确的在线恢复是由于系统的维护工作没做好。不要过度依赖业务人员对服务器的检验,通常情况下,他们申请关键补丁更新时,会有成百上千个服务器补丁。正因为这样,他们经常会忽略某个故障或者问题,因此最好在安装系统补丁或者服务器升级包后对服务器进行详细检查。
监控SQL代理作业
SQL代理作业在DBA所管理的每个SQL Server实例上运行了至少一整夜,因此需要每天检查这些作业,以确保它们能够正常运行。当然也可以在SQL Server作业中加入通知,当作业发生错误时自动发送邮件。但是通知邮件有时会跟其他大量邮件堆在一起,很有可能被忽视。因此,每天早上的第一件事就是对SQL代理作业进行快速扫描,以确保其每晚都已成功运行。
快速审查SQL Server代理作业有很多方法,其中Reporting Services报告提供了所有报错的SQL Server代理作业清单,还有访问管理所有实例的作业步骤。只要订阅这个报告就能够在每天早晨收到一封Email,得知前一天晚上的作业是否出错。有了这个包含所有实例的单独报告,DBA可以快速确定SQL Server代理作业的报错信息。如果发现一个报错信息,需要在其他人没有发现前修复这个错误,并且重新运行。下面是Reporting Services报告的代码:
DECLARE @c INT
-- Table of failed jobs
DECLARE @failed_jobs TABLE (
job_id uniqueidentifier,
step_id int,
step_name sysname,
sql_message_id int,
sql_severity int,
message nvarchar(1024),
run_status int,
FailureDate datetime,
server nvarchar(30)
)
INSERT @failed_jobs( job_id, step_id, step_name, sql_message_id, sql_severity,
message, run_status, FailureDate, server )
SELECT job_id, step_id, step_name, sql_message_id, sql_severity,
message, run_status, FailureDate, server
FROM ( SELECT job_id, step_id, step_name, sql_message_id, sql_severity,
message, run_status,
( DATEADD(ss, CAST(SUBSTRING(CAST( jh.run_duration
+ 1000000 AS char(7)), 6, 2) AS int),
DATEADD(mi, CAST(SUBSTRING(CAST( jh.run_duration
+ 1000000 AS char(7)), 4, 2) AS int),
DATEADD(hh, CAST(SUBSTRING(CAST( jh.run_duration
+ 1000000 AS char(7)), 2, 2) AS int),
DATEADD(ss, CAST(SUBSTRING(CAST( jh.run_time
+ 1000000 AS char(7)), 6, 2) AS int),
DATEADD(mi, CAST(SUBSTRING(CAST( jh.run_time
+ 1000000 AS char(7)), 4, 2) AS int),
DATEADD(hh, CAST(SUBSTRING(CAST( jh.run_time
+ 1000000 AS char(7)), 2, 2) AS int),
CONVERT(datetime, CAST(jh.run_date AS char(8))) )))))) )
AS FailureDate,
server
FROM msdb.dbo.sysjobhistory AS jh ) AS jh
WHERE (GETDATE() > jh.FailureDate)
AND (jh.run_status = 0)
-- Identify how many days to go back and look for failures
AND (DATEADD(dd, -1 , GETDATE()) < jh.FailureDate)
SELECT @c=count(*)
FROM @failed_jobs
IF @c > 0
BEGIN
SELECT SUBSTRING(j.name, 1, 50) AS JobName,
SUBSTRING(jh.step_name, 1, 50) AS StepName, message,
jh.FailureDate AS FailureDate
FROM @failed_jobs jh INNER JOIN
msdb.dbo.sysjobs j ON jh.job_id = j.job_id
END
ELSE
SELECT 'No Failed Jobs For Reporting Period' JobName, ' ' StepName, ' ' FailureDate
▲最近24小时报错的作业列表
当DBA监控SQL Server代理作业时,同样应该审核作业历史记录,因为偶尔会出现一些状况导致作业运行时间延长。如果能够了解SQL Server代理作业的平均运行时间,就能根据运行时间的延长或缩短分析SQL Server存在的问题。
有时会看到SQL Server代理作业被挂起。当这种情况发生时,如果这个作业被挂起且持续运行,那么下个步骤将不会进行。为了避免错过作业的下一个运行周期,需要确保被挂起的作业已经停止运行,另外需要明确导致作业被挂起的原因,并在下个步骤开始运行之前解决该问题。因此就需要监测长时间运行的作业是否已经被挂起,有很多方法可以进行这项监控。如果在网上搜索“长时间运行的SQL代理作业(long running SQL Agent jobs)”能够找到一些辨别长时间运行的作业是否被挂起的解决方法。
监控数据库备份
了解数据库是否有备份是至关重要的,事实上,这是作为一位DBA首先应当考虑的问题之一。没有备份就无法恢复数据库,因此DBA需要每天检查并确保数据库的备份策略是否运行正常,是否按照预期备份所有的数据库。因此每天早上都需要核查备份集,其中的一种方法就是运行脚本文件,类似于下面的一段代码:
SELECT name AS database_name
, backup_finish_date
, coalesce(type,'NO BACKUP') AS last_backup_type
FROM
(SELECT database_name
, backup_finish_date
, CASE WHEN type = 'D' THEN 'Full'
WHEN type = 'I' THEN 'Differential'
WHEN type = 'L' THEN 'Transaction Log'
WHEN type = 'F' THEN 'File'
WHEN type = 'G' THEN 'Differential File'
WHEN type = 'P' THEN 'Partial'
WHEN type = 'Q' THEN 'Differential partial' END AS type
FROM msdb.dbo.backupset x
WHERE backup_finish_date
= (SELECT max(backup_finish_date)
FROM msdb.dbo.backupset
WHERE database_name = x.database_name ) ) a
RIGHT OUTER JOIN sys.databases b
ON a.database_name = b.name
WHERE b.name <> 'tempdb' -- Exclude tempdb
AND (backup_finish_date < dateadd(d,-1,getdate())
或者:
▲显示在过去24小时内所有未备份的数据库列表
以上的脚本列出的每个数据库在过去的24小时内没有完成备份,它记录了上一次备份运行的时间以及备份的类型。该脚本返回的结果用来核查每个数据库在过去的24小时内是否已经备份。
检查事件日志
电脑硬件总是容易出现问题,其中的一些问题,如硬盘故障,可能会很快出现又很难解决。系统事件日志经常会提醒DBA硬件存在间歇性的问题。
此外,SQL Server以及其他应用,将消息写入事件日志。这些消息中有一些是信息(informational),其他的是警告或者错误。这些应用程序的错误可能不会导致应用问题的发生,因此很容易被人们忽视。通过每天查看这些事件日志的警告和错误类型的消息,DBA得到一个解决问题的好机会,如果忽略这些问题,可能会导致服务器或者SQL Server实例中断。
DBA应当每天都查看事件日志,并确保审阅了所有不同的事件日志,如系统日志、应用程序日志等。每天检查这些日志可以让DBA对工作更有信心,能够了解到服务器运行正常,没有反常或者流氓软件。
检查SQL Server错误日志文件
SQL Server维护一个错误日志文件(ERRORLOG file),错误日志文件中包含两种信息,即警告信息和错误信息。一部分写入错误日志中的事件能够表明SQL Server实例中存在一些问题,如数据库损坏或者I/O请求响应速度缓慢。DBA应当检查当前错误日志文件里的所有不正常的信息,这样做可以在其升级为严重问题或者SQL Server实例中断运行之前解决它。因此应该养成习惯每天检查错误日志。
使用名为xp_readerrorlog的未公开的扩展存储过程读取错误日志文件是非常便捷的,浏览网页可以找到有关如何使用未公开存储过程读取错误日志的更多信息。同样也可以使用SQL Server Management Studio或者其他文本编辑器查看错误日志。
磁盘空间可用性
由于数据库随着时间的推移容量变得越来越大,吞噬掉了磁盘里越来越多的可用空间。只要不关闭数据库的自动增长选项,数据库的容量就会自动增长直到装满整个磁盘。如果某些大型流氓数据导入程序运行时,这些自动增长事件会迅速占用绝大多数甚至全部的磁盘可用空间。
给数据库增长提供足够的空间是至关重要的,要明确磁盘有适当的可用空间,以及自动增长事件没有占用大量的磁盘可用空间,这就需要监控可用的磁盘空间。未公开的xp_fixeddrrives扩展存储过程可以用来显示每个磁盘的可用空间。创建xp_fixeddrives的输出进程,当磁盘可用空间低于自定义的阈值时会发出警报,提醒DBA磁盘可用空间不足。
积极主动 监控每一天
DBA们应该每天积极主动的监测每个SQL Server环境,通过日常监控可以快速识别问题或者潜在问题,并且在演变成更大的问题之前解决它们。本文中的列表和脚本并不完整,作为DBA应当仔细思考所在工作环境中什么是需要每天监测的重要内容。一旦有了自己的监测列表,DBA需要将每天早晨的监测工作自动化以帮助简化整个监测过程。