关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » SQL Server »SQL Server自动化运维系列:监控磁盘剩余空间及SQL Server错误日

    SQL Server自动化运维系列:监控磁盘剩余空间及SQL Server错误日

    2015-05-25 00:00:00 出处:longliqiang88
    分享

    《SQL Server自动化运维系列:监控性能指标脚本》
    《SQL Server自动化运维系列:监控磁盘剩余空间及SQL Server错误日志》
    《SQL Server自动化运维系列:关于邮件通知那点事》
    《SQL Server自动化运维系列:监控跑批Job运行状态》
    《SQL Server自动化运维系列:关于数据收集》

    需求描述

    在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等。如果发生异常,需要提前预警的,通知形式一般为发邮件告知。

    在所有的自检流程中最基础的一个就是磁盘剩余空间检测。作为一个高效的DBA不可能每天都要上生产机上查看磁盘剩余或者直到磁盘无剩余空间报错后才采取扩容措施。

    当然,作为微软的服务器有着自己的监控软件:SCCM(System Center Configuration Manager)。但该文就介绍如果通过Power shell实现状态值监控,相比SCCM更轻量级和更具灵活性。

    该文实现

    1、每天检测磁盘剩余空间大小,如果剩余空间超过了阀值,则发邮件告诉管理员

    2、每天检测SQL Server运行的错误日志(Window平台的错误日志),形成邮件附件发送给管理员

    监控脚本

    首先我们来解决第一个问题,关于磁盘剩余空间的问题,对于磁盘的监控的存在两个需要解决的问题:

    <1>一般监控我们需要监控很多台服务器的磁盘,所以对于服务器的量控制我们需要生成一个配置文件。

    <computernames>
            <computername>
                    wuxuelei-pc
            </computername>
    </computernames>

    配置文件名字:computername.xml,这样就解决很多服务器的问题,只需要在配置文件中增加就可以,因为我在本地测试,所以就配置了我的本地电脑。

    <2>对于服务器的磁盘监控也需要定义一个阀值,用来动态改变,用来定义生成预警的阀值。简单点就是定义我们检测的磁盘剩余空间到了多少了就自动发邮件提醒。

    <Counters>
            <Counter alter = "10" operator = "gt" >C:</Counter>
            <Counter alter = "10" operator = "gt" >D:</Counter>
            <Counter alter = "10" operator = "gt" >E:</Counter>
            <Counter alter = "10" operator = "gt" >F:</Counter>
    </Counters>

    文件名为:alter_disk.xml,我定义了四个盘符:C: D: E: F:

    当以上四个盘符那个盘符少于10G了就生成邮件预警。

    实现代码如下:

    $server = "(local)"
    $uid = "sa"
    $db="master"
    $pwd="password"
    $mailprfname = "TestMail"
    $recipients = "787449667@qq.com"
    $subject = "老大,快去看看这个服务器的磁盘空间马上就不够了!"
    $computernamexml = "F:PowerShell发送邮件computername.xml"
    $alter_xml = "F:PowerShell发送邮件alter_disk.xml"
    function GetServerName($xmlpath)
    {
        $xml = [xml] (Get-Content $xmlpath)
        $return = New-Object Collections.Generic.List[string]
        for($i = 0;$i -lt $xml.computernames.ChildNodes.Count;$i++)
        {
            if ( $xml.computernames.ChildNodes.Count -eq 1)
            {
                $cp = [string]$xml.computernames.computername
            }
            else
            {
                $cp = [string]$xml.computernames.computername[$i]
            }
            $return.Add($cp.Trim())
        }
        $return
    }
    
    function GetAlterCounter($xmlpath)
    {
        $xml = [xml] (Get-Content $xmlpath)
        $return = New-Object Collections.Generic.List[string]
        $list = $xml.counters.Counter
        $list
    }
    
    function CreateAlter($message)
    {
        $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
        $CnnString ="Server = $server; Database = $db;User Id = $uid; Password = $pwd" 
        $SqlConnection.ConnectionString = $CnnString 
        $CC = $SqlConnection.CreateCommand(); 
        if (-not ($SqlConnection.State -like "Open")) { $SqlConnection.Open() } 
    
        $cc.CommandText=
                " EXEC msdb..sp_send_dbmail 
                 @profile_name  = '$mailprfname'
                ,@recipients = '$recipients'
                ,@body = '$message'
                ,@subject = '$subject'
                "
        $cc.ExecuteNonQuery()|out-null 
        $SqlConnection.Close();
    }
    
    $names = GetServerName($computernamexml)
    $pfcounters = GetAlterCounter($alter_xml)
    foreach($cp in $names)
    {
        $p = New-Object Collections.Generic.List[string]
        $report = ""
        foreach ($pfc in $pfcounters)
        {
            $b = ""
            $counter ="\"+$cp+"LogicalDisk("+$pfc.get_InnerText().Trim()+")% Free Space"
            $p.Add($counter)        
        }    
        $count = Get-Counter $p
        #Write-Host $count.CounterSamples.Count;
        for ($i = 0; $i -lt $count.CounterSamples.Count; $i++)
        {
            $v = $count.CounterSamples.Get($i).CookedValue
            $pfc = $pfcounters[$i]
            #$pfc.get_InnerText()
            $b = ""
            $lg = ""
           if ($pfc.operator -eq "gt")
            {
                if( $v -le [double]$pfc.alter)
                    {
                        $b = "alter"
                        $lg = "Less Than"
                    }
                    if($b -eq "alter")
                    {
                        $path = "机器名:"+$cp+"; 盘符:"+$pfc.get_InnerText()
                        $diskFree="; 当前剩余空间为:"+[math]::truncate($v).ToString()+"G;"
                        $aler=" 超过了你预定的阀值:"+$pfc.alter.Trim()+"G;速度去处理吧!"            
                        $item = "{0} {1} {2}" -f $path,$diskFree,$aler
                        $report += $item + "`n"
                    }
            }           
        }
        if($report -ne "")
        {
            #生产警告 参数 计数器,阀值,当前值
            CreateAlter $report
        }
    }

    通过如上脚本,生成跑批任务,就可以自动的检测磁盘剩余空间了,而不需要我们去手动检测了。

    上述代码中,有两个技术点:1、需要自己配置SQL Server邮件代理;2、需要自己配置跑批计划,方法自己网上搜,很简单。

    效果图如下

    嘿…看到上面的邮件,就是需要联系硬件架构师,让其扩容或者清除冗余数据的时候了。

    在上面的脚本中,的确只有我的F盘符超了阀值,所以警报了!

    其次,我们来解决第二个问题,关于SQL Server错误日志的问题,作为日常的DBA管理系统中,查看SQL Server错误日志是一种常用的方式。当然,如果系统运行正常,不会产生错误日志,一单出现问题,就会生成错误日志,但是对于SQL Server错误日志会产生很多条,为了方便查找,我们会让其生成一个文本篇文章件。

    以邮件附件的形式,告知管理员,然后管理员就可以通过日志文件快速的定位问题的源头。

    同样,该文也是通过computername.xml文件,对多台服务器进行错误日志进行筛选

    脚本很简单,如下

    $server = "(local)"
    $uid = "sa"
    $db="master"
    $pwd="password"
    $mailprfname = "TestMail"
    $recipients = "787449667@qq.com"
    $subject = "老大,快去看看这个服务器的SQL Server出问题了!"
    $Info="附件为SQL Server错误日志....."
    $computernamexml = "F:PowerShell发送邮件computername.xml"
    function GetServerName($xmlpath)
    {
        $xml = [xml] (Get-Content $xmlpath)
        $return = New-Object Collections.Generic.List[string]
        for($i = 0;$i -lt $xml.computernames.ChildNodes.Count;$i++)
        {
            if ( $xml.computernames.ChildNodes.Count -eq 1)
            {
                $cp = [string]$xml.computernames.computername
            }
            else
            {
                $cp = [string]$xml.computernames.computername[$i]
            }
            $return.Add($cp.Trim())
        }
        $return
    }
    
    function GetAlterCounter($xmlpath)
    {
        $xml = [xml] (Get-Content $xmlpath)
        $return = New-Object Collections.Generic.List[string]
        $list = $xml.counters.Counter
        $list
    }
    
    function CreateAlter($message)
    {
        $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
        $CnnString ="Server = $server; Database = $db;User Id = $uid; Password = $pwd" 
        $SqlConnection.ConnectionString = $CnnString 
        $CC = $SqlConnection.CreateCommand(); 
        if (-not ($SqlConnection.State -like "Open")) { $SqlConnection.Open() } 
    
        $cc.CommandText=
                " EXEC msdb..sp_send_dbmail 
                 @profile_name  = '$mailprfname'
                ,@recipients = '$recipients'
                ,@body = '$Info'
                ,@subject = '$subject'
                ,@file_attachments='$message'
                "
        $cc.ExecuteNonQuery()|out-null 
        $SqlConnection.Close();
    }
    
    $names = GetServerName($computernamexml)
    foreach($cp in $names)
    {
            #输出系统日志中某个特定程序的日志到文件,比如SQL Server,然后选择错误类型为Error
            Get-EventLog -ComputerName  $cp application | where-object{$_.source-like "MSSQLSERVER"} | where-object{$_.entryType -eq "error"} >F:PowerShell$cp+"SQLErrLog.txt"
    
            #生产警告 参数 计数器,阀值,当前值
            CreateAlter F:PowerShell$cp+"SQLErrLog.txt"
    }

    效果图如下

    直接下载附件,然后查看错误日志就可以了。

    该错误日志还是挺详细的,发生时间,错误明细等。

    (查看大图)

    当然,上述脚本还欠缺一点逻辑:

    比如:筛选一段时间周期的错误日志、或者只查看上次启动之后的错误日志等。

    这些逻辑加上也不麻烦,本身PowerShell实现起来就很简单。这里就不展开了,自己灵活实现。

    但是,在我们日常的分析中,在日志记录多的时候,用文本分析的方式还是比较慢,通常用Excel查看效果会好很多。

    这个实现也不麻烦,只需要更改脚本如下:

    #输出系统日志中某个特定程序的日志到文件,比如SQL Server,然后选择错误类型为Error
            #Get-EventLog -ComputerName  $cp application | where-object{$_.source-like "MSSQLSERVER"} | where-object{$_.entryType -eq "error"} >F:PowerShell$cp+"SQLErrLog.txt"
    
            #输出系统日志中某个特定程序的日志到文件,比如SQL Server,然后选择错误类型为Error,支持Excel打开
            Get-EventLog -ComputerName  $cp application | where-object{$_.source-like "MSSQLSERVER"} | where-object{$_.entryType -eq "error"} | Export-Clixml –Path F:PowerShell$cp+"SQLErrLog.xml" –Depth 2 
    
            #生产警告 参数 计数器,阀值,当前值
            CreateAlter F:PowerShell$cp+"SQLErrLog.xml"

    我们下载生成的日志文件,然后打开Excel,然后选择:数据——>从Xml文件导入:

    (查看大图)

    如此分析就方便多了。

    结语

    该文就列举了一下利用PowerShell实现自动化运维和检测。算作抛砖引玉了吧,自己另有需求可以自己灵活实现。

    关于SQL Server自动化运维和检测的内容很广泛,其中很多都是从日常的经验中出发,一步步的从手动到自动的过程。

    后面的文章,我们将会更深入关于SQL Server的自动化优化运维进行分析。有兴趣的童鞋,可以提前关注。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    技术热点

    如何删除自带的不常用应用为windows 7减负

    MySQL中多表删除方法

    改进的二值图像像素标记算法及程序实现

    windows 7 32位系统下手动修改磁盘属性例如M盘修改为F盘

    windows 7中怎么样在家庭组互传文件

    Linux应用集成MySQL数据库访问技巧

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。