sql_exporter DSN配置详解:一张表看懂四大数据库连接格式与隐藏坑
【免费下载链接】sql_exporterDatabase agnostic SQL exporter for Prometheus项目地址: https://gitcode.com/gh_mirrors/sqle/sql_exporter
sql_exporter是一款面向 Prometheus 的数据库无关(database agnostic)SQL 导出器,通过配置文件定义 SQL 查询,即可把 MySQL、PostgreSQL、SQL Server、ClickHouse 等任意数据库的状态指标暴露给 Prometheus。而所有连接的"总钥匙"就是配置里的data_source_name——一个 DSN(Data Source Name)字符串。本文带你一图看懂四种数据库的 DSN 写法差异,并提前避开那些让人抓狂的隐藏坑。
什么是 DSN?sql_exporter 如何"认出"你的数据库
sql_exporter 没有单独的 driver 配置项,它直接用 DSN 中://前面的协议前缀来判断该用哪个数据库驱动:
sqlserver://prom_user:prom_password@dbserver1.example.com:1433 └──────┘ 驱动名由这一部分决定这一逻辑由 sql.go 中的OpenConnection函数实现。理解这一点后,下面的对照表就非常好懂了。
一张表看懂四大数据库 DSN 格式
| 数据库 | sql_exporter 中的 DSN 写法 | 驱动实际收到的内容 | 特点 |
|---|---|---|---|
| MySQL | mysql://user:pass@protocol(host:port)/dbname | user:pass@protocol(host:port)/dbname | 前缀mysql://会被剥掉 |
| PostgreSQL | postgres://user:pass@host:port/dbname | 原样传递 | 最"标准"的 URI 风格 |
| SQL Server | sqlserver://user:pass@host:port/instance | 原样传递 | 路径部分写实例名 |
| ClickHouse | clickhouse://host:port?username=user&password=pass&database=dbname | tcp://host:port?username=... | 前缀会被替换为tcp:// |
📌 对照表原文出处:README.md 的 "Data Source Names" 章节。四种 DSN 的完整格式说明也写在 sql.go 的函数注释中。
⚠️ 请注意两个"不标准"的数据库:MySQL 的账号密码格式特殊(protocol(host:port)这种写法),而ClickHouse 的账号密码根本不在@后面,而是写在查询参数里。这是绝大多数连接失败问题的根源。
data_source_name 写在哪里?两种部署模式
sql_exporter 支持两种模式,DSN 的"安放位置"不同:
模式一:单目标模式(target)
适合"一个 exporter 只盯一个数据库"的场景,DSN 直接写在target下,参考 examples/sql_exporter.yml:
target: data_source_name: 'sqlserver://prom_user:prom_password@dbserver1.example.com:1433' collectors: [mssql_standard]模式二:多任务模式(jobs)
需要同时监控多个实例时,DSN 写在每个 job 的static_configs.targets里,键是目标名、值是 DSN,相关结构定义见 config/config.go:
jobs: - job_name: mysql_group collectors: [mysql_standard] static_configs: - targets: prod_db_1: 'mysql://monitor:secret@(tcp)(10.0.0.1:3306)/' prod_db_2: 'mysql://monitor:secret@(tcp)(10.0.0.2:3306)/'配置解析时,config/config.go 会强制校验:jobs和target二选一,必须且只能定义其中一个。
6 个隐藏坑,提前避开少走弯路
坑 1:DSN 缺少://前缀这是最常见的错误。DSN 里找不到://时,sql_exporter 会直接报错:missing driver in data source name. Expected format '<driver>://<dsn>'(见 sql.go)。比如把 MySQL 的 DSN 直接写成user:pass@tcp(host:3306)/(很多文档里的"原生格式")就会中招——一定要自己补上mysql://前缀。
坑 2:MySQL 的protocol(host:port)语法独此一家MySQL 驱动要求把协议和地址包在括号里,例如mysql://u:p@(tcp)(127.0.0.1:3306)/。写成常见的mysql://u:p@127.0.0.1:3306/是不符合该驱动规范的。
坑 3:ClickHouse 的账号密码要写在查询参数里clickhouse://后面不要写user:pass@,正确姿势是clickhouse://host:9000?username=user&password=pass&database=dbname。并且记住:exporter 会自动把它改写成tcp://再交给驱动(sql.go)。
坑 4:前缀会被"加工",日志里的驱动名可能与前缀不同MySQL 的mysql://被剥掉、ClickHouse 的clickhouse://被替换成tcp://,这是驱动本身决定的(Go 的database/sql不支持按 DSN 自动选驱动,详见 README.md)。排查问题时别被"为什么日志里是 tcp 驱动"搞糊涂。
坑 5:DSN 是 Secret 类型,输出时会被打码data_source_name在代码中是Secret类型(config/config.go),序列化时会显示为<secret>。这是安全设计,不是 bug——但也意味着不要试图从导出配置里反查密码。
坑 6:多目标模式下的重复与命名约束在同一个static_config中,目标名不能重复、DSN 也不能重复(config/config.go);且每个 target 至少要有一个 collector。另外提醒:数据库连不上时/metrics会返回HTTP 500,Prometheus 侧表现为up=0(见 target.go),这属于正常降级行为,先检查 DSN 和账号权限再怀疑 exporter 本身。
快速自查清单
部署前逐项核对,90% 的 DSN 问题都能解决:
- ✅ DSN 是否带有
协议://前缀,且前缀在mysql/postgres/sqlserver/clickhouse之中? - ✅ MySQL 是否写成
user:pass@protocol(host:port)/dbname格式? - ✅ ClickHouse 的账号密码是否放在了
?username=&password=查询参数中? - ✅
target与jobs是否只定义了其中一个? - ✅ 多目标时,目标名与 DSN 是否唯一、collector 引用是否存在?
- ✅ 数据库账号是否只授予了 SELECT 权限并能从 exporter 所在主机连通?
相关资料
📚 想深入阅读,推荐按以下顺序浏览项目文件:
- 完整注释版配置示例:documentation/sql_exporter.yml(其中 DSN 示例见 第 33 行)
- 最小可用配置:examples/sql_exporter.yml
- 开箱即用的标准采集器:examples/mssql_standard.collector.yml
- DSN 解析与驱动选择源码:sql.go
- 配置结构体与校验规则:config/config.go
💡 小贴士:由于 Go 无法动态加载第三方数据库驱动,若要监控其他数据库(如 Oracle),需要引入对应 Go 驱动后重新编译二进制文件,DSN 前缀即新驱动名。
【免费下载链接】sql_exporterDatabase agnostic SQL exporter for Prometheus项目地址: https://gitcode.com/gh_mirrors/sqle/sql_exporter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考