相信不少运维和开发同学都有过这种经历:业务系统跑了好多年,关键数据都沉在SQL Server 2014里,平时要看报表要么让开发写临时查询,要么靠DBA导出Excel。想看个库文件增长趋势,得先把几十个库的磁盘使用情况手工汇总;想盯一下昨天的死锁次数,连个像样的趋势图都画不出来。我接过好几个这样的项目,最后都是把Grafana接到SQL Server上解决的。
这篇文章要聊的就是怎么把Grafana和SQL Server 2014对接起来,从环境准备、插件配置、写查询到踩坑排查,完整走一遍。适合手头有老版本SQL Server、又想做可视化监控看板的DBA、运维工程师,也适合想给业务方做自助报表的开发同学。整个过程不复杂,但有几个坑不提前说清楚,大概率会卡在"Test连接失败"那一步。
1. 先说结论:这个组合能帮你解决哪些具体问题
很多人一听到"SQL Server 2014"就觉得是老古董,觉得应该用新版本数据库。但实际上,国内还有大量生产环境跑着SQL Server 2014,尤其是一些制造业ERP、金融行业的历史系统、医疗信息化系统,不是说升级就能升级的。数据已经积累了七八年,报表需求却越来越急迫。这时候你去引一套全新的BI平台,学习成本和实施周期都扛不住。Grafana的价值就在于它足够轻,轻到你可以在一个下午之内把现有数据库里的关键指标变成一张能实时刷新的看板。
具体来说,Grafana接SQL Server 2014之后,最常见的几个使用场景是这样的:
- 数据库运行状态看板:文件剩余空间、日志增长率、连接数、死锁次数、阻塞会话数,这些指标SQL Server内部都有计数器,只是平时没有好的可视化方式。接上Grafana后,每五分钟刷新一次,页面一拉就能看到趋势。
- 业务报表替代:很多业务系统自带的报表模块查个历史数据要半天,而且只能出固定格式。直接把底层业务表接入Grafana,拖几个面板就能做出按日、按周、按月聚合的自由报表,业务部门自己就能看。
- 告警通知:文件空间低于阈值、备份超过48小时没执行、死锁超过一定次数,这些都可以在Grafana里配告警规则,触发后推到钉钉、企业微信或邮件,不用再靠人肉巡检。
- 多数据源打通:如果机房里面还有Prometheus、MySQL或者其他时序数据库,Grafana可以把它们和SQL Server的数据放到同一张看板上,做统一运维视图。这也是为什么很多团队宁可用Grafana也不用商业BI的原因之一。
我在实施过程中最大的感受是,Grafana的SQL Server数据源插件已经非常成熟,官方长期维护,不是那种装完就没人管的半成品。所以不用太担心"2014版本太老没人支持"的问题——只要SQL Server开着TCP/IP端口、允许SQL Server身份验证登录,剩下的都是配置层面的事。
2. 环境准备阶段最容易翻车的三个细节
连接数据库这件事,80%的问题都出在环境准备阶段。SQL Server 2014本身是Windows时代的产物,而Grafana常常跑在Linux服务器或Docker里面,两边默认配置一碰撞,就会出现各种奇怪现象。我总结下来,这三个细节最值得提前处理。
2.1 确认Grafana版本和部署方式
Grafana从7.0开始把Microsoft SQL Server数据源做成了内置插件,也就是说装完Grafana就能直接添加数据源,不用再去插件市场单独下载。如果你用的是5.x或者6.x的老版本,需要去Grafana插件库手动安装grafana-sqlserver-datasource,非常麻烦,所以安装Grafana时尽量选8.x、9.x甚至10.x的新版本。
部署方式方面,我自己的习惯是:生产环境优先用apt/yum装到Linux服务器上,或者用Docker管理;临时测试就直接下载Windows版安装包。不管哪种方式,只要Grafana能正常启动,后续数据源配置过程几乎一模一样。唯一需要注意的是Docker部署时要把端口映射出来,比如docker run -d --name=grafana -p 3000:3000 grafana/grafana,否则浏览器访问不到。
2.2 SQL Server侧打开TCP/IP并确认端口
这一步是新手最容易忽略的。SQL Server默认安装时,很多实例只开启了Shared Memory和Named Pipes,TCP/IP协议是禁用状态。Grafana从别的机器连过来,靠的就是TCP协议,所以必须到"SQL Server配置管理器"里把TCP/IP启用。
启用之后还要注意两个坑:一是确认TCP端口是不是默认的1433,如果不是(比如多实例环境),连接字符串里必须显式写端口;二是实例名的问题,用默认实例的话可以直接填IP或主机名,用命名实例的话,建议先给实例配置固定的TCP端口,避免依赖SQL Server Browser服务去动态解析端口。
验证SQL Server是否真的在监听端口,可以在服务器本机执行这个查询:
SELECT DISTINCT local_tcp_port FROM sys.dm_exec_connections WHERE local_tcp_port IS NOT NULL;有结果就说明端口起来了。然后用另一台机器试一下TCP连通性,用telnet或者PowerShell的Test-NetConnection都行。
2.3 准备专用只读账号,别用sa去连
我见过有人图省事,直接在Grafana里面填sa账号和密码,这种做法非常不可取。Grafana的面板信息是整个团队都能看到的,连接串也可能会被导出,一旦泄露就是数据库最高权限泄露。而且Grafana为了做时间过滤,会在你的表上执行带BETWEEN条件的查询,如果账号权限太大,误操作的风险也高。
正确的做法是创建一个只读监控账号:
CREATE LOGIN grafana WITH PASSWORD = 'YourStrongPassword'; GO CREATE USER grafana FOR LOGIN grafana; GO ALTER ROLE db_datareader ADD MEMBER grafana; GO这样Grafana对数据库只有读权限,能做查询和看板分析,但改不了任何数据。如果你要做跨库查询,需要给这个账号授予对应库的db_datareader,或者用GRANT VIEW ANY DATABASE TO grafana;让它可以看所有库的元数据。只读权限还可以进一步细化到只允许访问特定表,核心敏感表不想让看板人员看到的话,REVOKE掉SELECT权限即可。
3. 数据源接入实操:从安装插件到Test成功
环境准备好之后,真正配置数据源的流程不复杂,但每个配置项背后的含义最好搞清楚,不然出了问题无从排查。
3.1 添加数据源的标准路径
登录Grafana后台,左侧菜单进入"Configuration"(齿轮图标)→ "Data Sources" → "Add data source",在列表里搜"SQL Server",选中Microsoft SQL Server。如果这一步搜索不到,先检查Grafana版本是不是太老,或者Docker镜像是否缺少内置插件。
进入配置页后,需要填写以下几项:
| 配置项 | 填写内容 | 说明 |
|---|---|---|
| Host | 例如192.168.1.10:1433 | 格式是IP或主机名:端口,端口必须写正确 |
| Database | 例如MonitorDB | Grafana查询的默认数据库 |
| User | 例如grafana | 之前创建的只读账号 |
| Password | 对应的密码 | 密码建议用Grafana自带的Secret管理功能 |
| TLS/SSL | 按需选择 | SQL Server 2014建议选Disable,见下文说明 |
页面底部有"Save & Test"按钮,点击后如果看到绿色的"Database Connection OK",数据源就算接通了。
3.2 关于TLS/SSL的那点事
很多人在这一步会遇到一个很经典的问题:Grafana版本很新、SQL Server 2014也很正常,但Test的时候报错要么是TLS Handshake Failed,要么是Server name does not match。这个问题的根源在于SQL Server 2014默认情况下对TLS 1.2的支持并不完整,新版本的Grafana底层驱动默认要求加密连接,双方协商不到一块去。
解决方式有两种。一是给SQL Server 2014打上最新的Service Pack,并在Windows上启用TLS 1.2协议,这个方案最正规,但需要维护窗口,很多生产库不敢轻易动;二是在Grafana的Connection string选项里手动加参数,关闭加密需求,比如:
encrypt=disable;trustservercertificate=true实测下来,测试和中小型环境用第二个方案最省事。安全性方面也不用过度焦虑,内网环境加上防火墙限制访问来源,风险是可控的。如果数据库在公网或者跨机房,还是建议花时间把TLS 1.2搞定。
3.3 连接字符串里的隐藏参数
除了encrypt之外,Connection string里还可以通过app name参数标记连接来源。这样在SQL Server的活动监视器里,能看到所有Grafana发起的连接,方便和业务连接区分开:
app name=grafana;encrypt=disable;trustservercertificate=true这个习惯我在做所有第三方系统接数据库时都会保留,尤其数据库出问题要排查时,能一眼看出哪些查询是Grafana发起的,哪些是业务系统发起的。另外,connect timeout参数也建议设置一下,默认15秒有时候不够用,尤其是跨网段查询慢的时候,可以改成30秒:
app name=grafana;encrypt=disable;trustservercertificate=true;connect timeout=304. 第一条查询和第一块面板:把数据画出来
数据源接通的成就感只能维持三分钟,因为真正的挑战在写查询。Grafana的SQL Server数据源和普通SQL工具不太一样,它有几套专门的时间宏,不好好用的话,面板上要么显示不出数据,要么时间范围完全错乱。
4.1 理解Grafana的时间宏机制
Grafana面板右上角有一个时间范围选择器,你选"最近6小时"或者"最近7天",这个范围会通过宏的方式注入到SQL里。最常用的是$__timeFilter(列名),它会自动生成类似日期列 BETWEEN '2025-01-01T00:00:00' AND '2025-01-01T06:00:00'的片段。不要自己手写时间条件,否则面板切换时间范围时,查询完全不会跟着变。
写时间序列查询时,还有一个硬性要求:返回结果里必须有一列是时间,一列是数值,否则Grafana画不出时间曲线。最标准的写法是这样:
SELECT $__time(记录时间), server_name AS metric, 磁盘剩余MB AS value FROM 磁盘监控表 WHERE $__timeFilter(记录时间) ORDER BY 记录时间;这里$__time(记录时间)负责把SQL Server的datetime类型转成Grafana能识别的带时区时间。你也可以用$__timeEpoch(记录时间)返回Unix时间戳,效果一样,只在处理某些历史遗留表时可能有细微区别。
4.2 用表格式查询做明细报表
不是所有面板都需要画趋势线。比如你想做一个"最近24小时登录失败明细"的表格,展示账号、来源IP、失败时间、错误信息,这时候就不适合用时间序列格式。在Query选项里把Format As从"Time series"改成"Table",查询结果就会直接渲染成表格,同时支持排序和搜索。
表格查询同样可以用$__timeFilter来跟随面板的时间范围,只是你不需要返回时间列。给个例子:
SELECT login_time AS 登录时间, user_name AS 账号, client_ip AS 来源IP, error_message AS 错误信息 FROM 登录审计表 WHERE $__timeFilter(login_time) ORDER BY login_time DESC;这种表格面板在给业务方做对账、给安全团队做审计时非常实用。
4.3 借助模板变量实现"一个面板看所有库"
真正用熟Grafana的人,一定会用模板变量(Templating)。举个最典型的场景:你想看到所有数据库文件的剩余空间趋势,但不要建几十个面板,而是用下拉框切换数据库。这时候在Dashboard Settings → Variables里新建一个Query类型变量,SQL写:
SELECT name FROM sys.databases WHERE state = 0 ORDER BY name;然后在面板查询里引用这个变量:
SELECT $__time(记录时间), db_name AS metric, 剩余空间MB AS value FROM 文件空间历史表 WHERE $__timeFilter(记录时间) AND db_name = '${database}';这样一来,看板顶部就多了一个数据库下拉框,切换哪个库,面板就显示哪个库的数据。这个方法也可以用在服务器列表、业务系统分类、区域节点等维度上,是Grafana使用里投入产出比最高的小技巧。
5. 踩坑实录:连接失败、数据错乱、查询超时的完整排查链路
配置过程顺利的话,四十分钟能完成。但很多环境没这么听话,下面几个问题是我在多个项目里反复遇到的,每一种都给出排查逻辑,方便你照着走一遍。
5.1 "Login failed for user 'grafana'":先查认证模式再查密码策略
这个报错最常见。SQL Server 2014默认可能处于Windows身份验证模式,Grafana是用SQL账号密码登录的,自然会被拒绝。先执行下面的语句确认认证模式:
SELECT SERVERPROPERTY('IsIntegratedSecurityOnly');返回1表示只能Windows认证,返回0表示混合模式。如果是1,需要在SQL Server Management Studio里右键服务器属性,把身份验证模式改成"SQL Server和Windows身份验证模式",改完记得重启SQL Server服务。
如果认证模式没问题,检查账号是否被锁定或者密码过期。SQL Server 2014的默认密码策略比较严格,创建账号时最好用一个满足复杂度要求的强密码。我用过一个取巧的方法:先用ssms用windows账号登录,执行ALTER LOGIN grafana WITH PASSWORD = 'xxx' UNLOCK;,确认账号状态正常之后再去Grafana里Test。
5.2 面板显示"无数据",但同一句SQL在SSMS里能查出数据
这个现象迷惑性极强。我排查这类问题时的第一反应永远是:检查返回的那列时间数据是不是SQL Server的datetime类型,以及它里面有没有NULL值。Grafana的时间序列查询要求结果集里每行都带有效时间,如果某几行的记录时间字段为NULL,整个面板可能直接判定无数据。
另外常见的是时区问题。Grafana在展示时默认按浏览器的时区渲染,但SQL Server里存的如果用GETDATE()获取的是服务器本地时间,并没有带上时区信息。Grafana会按UTC来解析,结果就是所有数据凭空偏移了8个小时。正确的做法是,在SQL Server里尽量用SYSUTCDATETIME()来记录时间,或者查询时主动用AT TIME ZONE转成UTC:
SELECT $__time(记录时间 AT TIME ZONE 'China Standard Time' AT TIME ZONE 'UTC'), ...这个是困扰了很多人的隐性坑,尤其是服务器在中国、数据库存的是北京时间的情况下,第一次看到曲线整体平移的时候,很容易绕进别的排查方向。
5.3 查询超时或看板加载缓慢
看板加载慢,80%是因为查询走了全表扫描。历史监控数据表动辄上百万行,Grafana每隔几分钟刷新一次,没有索引谁也扛不住。给时间列加索引几乎是一本万利的事情:
CREATE NONCLUSTERED INDEX IX_监控表_记录时间 ON 监控表(记录时间);如果查询里还经常按服务器名或者数据库名过滤,可以把这些列加进索引列里。另外可以在SQL Server数据源的配置里适当调高Timeout参数,默认是30秒,长查询建议改成60秒。但注意,调大超时只是治标,索引才是治本。
还有一个容易忽略的点:Grafana面板的Min time interval。如果面板刷新时间是5分钟,而你建的聚合查询是按秒粒度的数据,数据量会非常大。合理的做法是在聚合查询里用$__timeGroup:
SELECT $__timeGroup(记录时间, '5m'), AVG(cpu使用率) AS cpu_avg FROM 性能采集表 WHERE $__timeFilter(记录时间) GROUP BY $__timeGroup(记录时间, '5m') ORDER BY 1;这样一来,每五分钟只有一个聚合点,加载速度能快一个数量级。
5.4 报表里的中文乱码或者特殊字符截断
Grafana的SQL Server数据源在返回中文时偶尔会出现乱码,尤其是直接从早期版本的SQL Server表里读nvarchar字段时。遇到这类问题,优先检查SQL语句里是否加了N前缀来标记Unicode字符串,比如WHERE 产品名称 = N'笔记本电脑'。如果查询结果里面板显示正常但导出CSV乱码,那是CSV编码的问题,换用UTF-8的CSV导出即可。
6. 进阶玩法:告警规则与SQL Server日常监控建议
把面板搭好只是第一步,Grafana的另一个核心价值是告警。SQL Server 2014本身有SQL Agent可以做数据库内部告警,但它的通知渠道很老套,配置也麻烦。Grafana的告警优势在于:一个规则,多种通知渠道,还能和看板联动。
6.1 配置一条"数据库文件空间不足"告警
在面板的Alert页签里,添加一条告警规则。条件可以写成:最近一次查询的剩余空间平均值,低于设定的阈值(比如5000MB)时触发。需要注意,告警查询里的$__timeFilter会引用一个独立的告警周期,比如每5分钟评估一次,它会自动查询最近5分钟的数据,这需要历史表的数据更新足够及时。
通知渠道方面,Grafana 9之后的统一告警做得相当顺手,支持在Contact points里配置钉钉Webhook、企业微信Webhook、邮件、Slack等。钉钉通知我实测只需要一个Webhook地址加一段自定义JSON模板,参考官方文档配置半小时内能搞定。告警一旦触发,还可以在Annotations里记录当时的指标值,事后排查很有帮助。
6.2 推荐的SQL Server监控指标体系
根据我做过几个SQL Server看板的经验,下面这些指标最值得优先纳入监控:
- 文件空间与增长量:每个数据库文件(mdf/ldf)的当前大小、剩余空间、日增长量。空间问题永远是数据库最大的隐形杀手。
- 备份状态:每个库最近一次全量备份、日志备份的时间。超过预期周期未备份,直接触发告警。
- 性能计数器:SQL Server的Buffer Cache Hit Ratio、Page Life Expectancy、Batch Requests/sec,这些对判断实例整体健康度很有参考价值。
- 连接数与阻塞:当前活动连接数、阻塞会话数量。系统卡顿多半能在阻塞数上看出苗头。
- 错误日志:从
sys.dm_os_ring_buffers或者错误日志里抓取严重错误,作为告警源。
6.3 权限管控和看板复用建议
最后给个实施层面的建议:Grafana支持多组织(Organization)和用户权限分级,不要让所有团队共用一个管理员账号。每个业务线建独立的文件夹存放自己的看板,设置只读权限给查看者,编辑权限只开放给对应的DBA或开发负责人。这样即使业务方误操作,也不会影响其他团队的看板。
另外,官方Grafana模板市场(Grafana Dashboards)上有很多现成的SQL Server模板可以导入,搜"SQL Server"能找到不少DBA贡献的成品。直接导入比自己从零搭要快很多,但注意模板里连接的数据库名和表结构不一定跟你的环境一致,导入后需要逐个改数据源变量。
按照我这个流程走一遍之后,最直观的感受就是:SQL Server 2014这台老机器突然变得透明了。以前DBA每天上班第一件事是跑脚本来回翻几十个库的状态,现在打开Grafana一个页面全搞定。我个人实际做项目时的建议是,第一个看板不要贪多,就把文件空间和备份状态这两块先跑起来,稳定运行一周后再陆续加性能计数器和业务报表。毕竟监控看板这东西,用得越久积累的历史数据越有价值,等三个月后再看当时的趋势曲线,很多优化结论会自然浮出来。