news 2026/9/20 19:18:21

OneUptime SQL 监控(SQL Query Monitor)实战指南:只读查询探测、多层安全防线与告警标准配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OneUptime SQL 监控(SQL Query Monitor)实战指南:只读查询探测、多层安全防线与告警标准配置

OneUptime SQL 监控(SQL Query Monitor)实战指南:只读查询探测、多层安全防线与告警标准配置

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

本篇技术指南围绕 OneUptime 的 SQL 查询监控功能展开,讲解它如何从探针(Probe)按计划执行只读 SQL 查询、依据结果(行数、标量值、执行耗时、查询错误)触发告警的完整机制,覆盖支持的数据引擎、安全模型、配置项、查询编写规范、Monitor Secret 密码保护与告警标准(Criteria)搭建。读完本文,你将掌握在 OneUptime 中安全落地「跑一条查询、必要时开一个 Incident」这一典型场景的完整实操方案,并理解其探针侧实现的底层原理。

功能定位:为「执行查询并触发告警」而生

SQL 监控(SQL Query Monitor)解决的是这样一个经典可观测性需求:在业务数据库上按固定计划执行一条只读 SQL 查询,并根据查询结果判断系统是否健康。典型用例包括:

  • 最近五分钟内订单取消数量突然飙升;
  • 消息队列表堆积过大;
  • 某条关键业务记录意外消失。

由于查询是在探针(Probe)上执行的,而探针部署在你的网络内部,OneUptime 云端永远不需要直连你的数据库。更关键的是,完整的结果集永远不会离开探针——探针只回传一个小的、有边界的投影(projection)结果。

支持的数据库引擎

SQL 监控官方支持以下三种引擎(默认端口与仓库中 SqlDatabaseType.ts 的getDefaultPort()实现一致):

引擎默认端口
PostgreSQL5432
MySQL3306
Microsoft SQL Server1433

官方测试覆盖仅限上述三种。使用相同网络协议与 SQL 方言的 MySQL 兼容、PostgreSQL 兼容引擎通常也能工作,但不在官方测试范围之内。从源码看,探针分别使用pgmysql2/promisemssql三个纯 JS 驱动连接对应引擎(见 SqlMonitor.ts)。

工作原理:探针回传的紧凑投影

每次检查时,探针完成以下动作:连接数据库 → 在只读上下文中执行你的查询 → 最多读取有界行数 → 向 OneUptime 回传一个紧凑投影。随后,你配置的监控标准(Criteria)针对该投影进行求值。

探针回传五类数据:

  • 行数(Row Count)——查询返回的行数(受「最大行数」参数约束);
  • 标量值(Scalar Value)——第一行第一列的值,这是SELECT COUNT(*)类查询最自然的取值;
  • 首行(First Row)——第一行以「列/值」键值对形式呈现,用于在检查摘要中提供上下文;
  • 执行耗时(Execution Time)——查询执行耗时,单位毫秒;
  • 查询错误(Query Error)——查询失败时经过净化的错误消息。

完整结果集永远不会发送到 OneUptime,因此客户数据不会被复制进 OneUptime 的存储。这一点在源码中有直接印证:shapeRows()方法只从结果中抽取rowCount、第一列的scalarValuefirstRow,并在行数超过上限时置isRowsCapped标志(见 SqlMonitor.ts)。

安全模型:多层防线保障生产库安全

生产数据库上执行一条由客户提供的 SQL 属于敏感操作,因此 SQL 监控在设计上就是只读的,并叠加了多层控制:

1. 最小权限数据库用户(首要防线)始终使用一个专用的、只读的数据库用户连接,该用户仅能访问查询所需的表。这是最重要的一层控制,具体创建方法见下文「创建只读数据库用户」。

2. 只读执行(执行期强制)

  • PostgreSQLMySQL上,探针会开启READ ONLY事务,无论查询文本如何,任何写入(包括可写 CTE)都会被拒绝;
  • Microsoft SQL Server没有只读事务,探针改为在**始终回滚(rollback)**的事务中执行查询。

源码印证:PostgreSQL 执行器会执行START TRANSACTION READ ONLY并配合SET LOCAL statement_timeout(见 SqlMonitor.ts);MySQL 执行器同样执行START TRANSACTION READ ONLY(见 SqlMonitor.ts);SQL Server 执行器则始终在finally中回滚事务(见 SqlMonitor.ts)。

3. 单语句 + 白名单首关键字查询必须是单条语句,且以SELECTWITHVALUESTABLE之一开头。堆叠语句(如SELECT 1; DROP TABLE …)以及写入/DDL 会在探针连接数据库之前被拒绝。校验是**注释感知(comment-aware)和字符串字面量感知(string-literal-aware)**的,藏在注释或字符串里的关键字不会蒙混过关。

源码印证:SqlQueryValidator.getRejectionReason()会先剥离块注释/行注释(stripComments)和字符串字面量(stripStringLiterals),再检查分号、首 token 白名单(ALLOWED_FIRST_TOKENS)以及禁用关键字列表FORBIDDEN_CONSTRUCTS(覆盖insert/update/delete/merge/truncate/drop/alter/...、远程数据源访问openquery/openrowset/...、系统存储过程xp_/sp_等),见 SqlMonitor.ts。测试用例覆盖了「注释中隐藏写入关键字」「字符串中的分号不误判」「无分号的 T-SQL 第二条语句」等绕过手法(见 SqlMonitor.test.ts)。

4. 语句超时每条查询都有硬性时间上限,执行过久的查询会被取消。源码中 PostgreSQL 同时设置了服务端statement_timeout与客户端query_timeout兜底(statementTimeoutInMs + 2000),MySQL/SQL Server 则用withHardTimeout()做客户端硬超时竞速(见 SqlMonitor.ts)。

5. 有界行数探针最多读取「最大行数 + 1」行(多出的 1 行用于检测截断),从而限制探针内存占用与回传载荷大小。PostgreSQL 用游标FETCH FORWARD maxRows+1(SqlMonitor.ts)、MySQL 用流式读取到上限即销毁连接(SqlMonitor.ts)、SQL Server 用SET ROWCOUNT maxRows+1(SqlMonitor.ts)。

6. 凭据脱敏数据库错误在存储前会被净化——密码以及任何连接字符串都会被脱敏,凭据不会泄漏到错误消息中。源码中sanitizeError()会替换密码子串、其余 secret 型连接字段、postgres:///mysql://等连接 URI,以及password=形式的连接串键值对(见 SqlMonitor.ts),并有对应单测验证(SqlMonitor.test.ts)。

前置条件

  • 一台探针(Probe),且对数据库主机和端口具备网络可达性。数据库可从公网访问时可用 OneUptime 托管探针;运行在你网络内部时使用自托管探针。
  • 一个只读数据库用户及连接信息(主机、端口、数据库名、用户名、密码)。

配置 SQL 监控

新建一个监控器,选择SQL Query(SQL 查询)作为监控类型,然后填写连接信息:

  • 数据库类型(Database Type)——PostgreSQL、MySQL 或 Microsoft SQL Server;选择类型会联动填充默认端口;
  • 主机(Host)——探针可达的数据库主机(例如db.internal);
  • 端口(Port)——数据库端口;
  • 数据库名(Database Name)——执行查询的目标数据库;
  • 用户名(Username)——只读、最小权限的数据库用户;
  • 密码(Password)——强烈建议用 Monitor Secret 以{{monitorSecrets.name}}形式引用,而非明文输入(见下文);
  • SQL 查询(SQL Query)——要执行的只读查询(见「编写查询」);
  • 使用 SSL/TLS(Use SSL/TLS)——开启后通过 TLS 连接;若数据库使用自签名证书,可同时关闭验证服务器证书(Verify server certificate)

高级选项

参数默认值最大值说明
连接超时(ms)1000030000等待建立连接的时间
语句超时(ms)1500060000查询可运行时长的硬上限
最大行数(Max Rows)1001000从数据库回读行数的上限

这些上限在服务端/探针侧强制执行,用户无法在界面上调得更高——常量与钳位函数定义于 MonitorStepSqlMonitor.ts,execute()在执行前会对三个参数分别调用clampSqlStatementTimeoutInMsclampSqlConnectionTimeoutInMsclampSqlMaxRows做归一化(见 SqlMonitor.ts)。

补充:SQL Server Windows 集成身份验证

对于 Microsoft SQL Server,官方英文文档还支持Windows 集成身份验证(Windows Integrated Authentication)模式:以探针进程的运行身份建立受信连接,此模式下用户名与密码字段被忽略、不会传给驱动。由于探针需要一个被域信任的身份,此模式应使用自托管探针:

  • Windows 探针:以拥有只读 SQL Server 登录的域账户运行探针服务;
  • Linux / macOS 探针:为 SQL Server 所在域配置 Kerberos,并给探针进程提供有效票据(如通过 keytab)。官方 Linux 探针镜像内置 Microsoft ODBC Driver 18、unixODBC 与 Kerberos 客户端,需将 Kerberos 配置与票据缓存挂载进容器并保证探针进程可读,非默认路径时设置KRB5_CONFIGKRB5CCNAME

驱动探测细节:探针宿主机需装有 Microsoft ODBC Driver。官方探针镜像内置ODBC Driver 18;自托管/自定义探针会自动探测宿主机上注册的最新ODBC Driver N for SQL Server(例如装的是 Driver 17 就用 17),无需严格匹配 18。如需固定某个版本,可设置探针环境变量SQL_SERVER_ODBC_DRIVER为精确驱动名。该逻辑实现于 SqlMonitor.ts(resolveSqlServerOdbcDriver的解析顺序为:环境变量覆盖 → 宿主机最新已注册驱动 → 镜像内置默认值)。另外还需满足:SQL Server 有合适的MSSQLSvc服务主体名(SPN)、探针与域控时钟同步、探针通过该 SPN 覆盖的主机名解析并访问 SQL Server。受信身份只需授予监控查询所需的数据库权限。

编写查询

查询必须是单条只读语句,以SELECTWITHVALUESTABLE之一开头。允许结尾有一个分号;多条语句不允许。

由于查询每次检查都会执行,请保持查询廉价且有界:优先使用索引列和窄时间窗口。以下是三种引擎下「统计最近取消订单数」的等价写法:

-- 统计近期取消订单(PostgreSQL) SELECT COUNT(*) AS cancelled FROM orders WHERE status = 'CANCELLED' AND created_at > NOW() - INTERVAL '5 minutes';
-- 同样的思路(MySQL) SELECT COUNT(*) AS cancelled FROM orders WHERE status = 'CANCELLED' AND created_at > NOW() - INTERVAL 5 MINUTE;
-- 同样的思路(Microsoft SQL Server) SELECT COUNT(*) AS cancelled FROM orders WHERE status = 'CANCELLED' AND created_at > DATEADD(minute, -5, GETDATE());

COUNT(*)类查询有一个容易混淆的点:计数既可作为行数(Row Count)(此时恒为1,因为只返回一行),也可作为标量值(Scalar Value)(计数本身,取自第一列)。要针对「有多少」告警,应比较标量值。这也与shapeRows()的实现一致:标量值取第一行的第一列(见 SqlMonitor.ts)。

使用 Monitor Secret 保护密码

为避免数据库密码以明文存储在监控器上,可以创建 Monitor Secret 并在密码字段中引用它:

  1. 进入 OneUptime 仪表盘 →Monitors → Settings → Secrets → Create Monitor Secret
  2. 创建一个 secret(例如dbPassword),并授权该监控器访问它;
  3. 在监控器的密码字段填入{{monitorSecrets.dbPassword}}

OneUptime 在服务端解析该 secret 之后,才会把配置下发给探针。OneUptime 永远不会替你创建这些 secret——是否引用由你决定。从源码看,MonitorStepSqlMonitor的敏感字段(密码,以及其他任意字段)都可包含{{monitorSecrets.name}}引用(见 MonitorStepSqlMonitor.ts),而sanitizeError()之所以脱敏用户名/主机/库名,正是因为它们同样可能由 secret 支撑。

配置告警标准(Criteria)

添加标准来决定监控器何时被视为在线(Online)、降级(Degraded)或离线(Offline)。SQL 监控支持以下检查项:

  • SQL Is Online——数据库是否可达且查询是否成功;
  • SQL Query Row Count——返回的行数,可与大于、小于、等于等操作符比较;
  • SQL Query Scalar Value——第一行第一列的值;两侧均看似数值时按数值比较,否则按字符串比较;这是COUNT(*)类查询应使用的检查项;
  • SQL Query Execution Time (in ms)——查询耗时,用于捕捉数据库变慢;
  • SQL Query Error——查询错误消息;可在其为空/非空或匹配特定字符串时告警;
  • JavaScript Expression——用自定义 JavaScript 表达式实现完全控制,参见 JavaScript Expressions。

示例:取消量突增时告警

沿用上面的查询:

  • 降级(Degraded)标准——SQL Query Scalar Value大于10
  • 离线(Offline)标准——SQL Query Scalar Value大于50,或SQL Is Onlinefalse

将告警标准关联到值班策略(On-Call Policy),即可在条件满足时通知到正确的人。

创建只读数据库用户

始终使用专用的只读用户连接数据库。以下是三种引擎的示例:

-- PostgreSQL CREATE USER oneuptime_ro WITH PASSWORD 'a-strong-password'; GRANT CONNECT ON DATABASE orders TO oneuptime_ro; GRANT USAGE ON SCHEMA public TO oneuptime_ro; GRANT SELECT ON ALL TABLES IN SCHEMA public TO oneuptime_ro; -- 覆盖未来新建的表: ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO oneuptime_ro;
-- MySQL CREATE USER 'oneuptime_ro'@'%' IDENTIFIED BY 'a-strong-password'; GRANT SELECT ON orders.* TO 'oneuptime_ro'@'%'; FLUSH PRIVILEGES;
-- Microsoft SQL Server CREATE LOGIN oneuptime_ro WITH PASSWORD = 'a-strong-password'; USE orders; CREATE USER oneuptime_ro FOR LOGIN oneuptime_ro; ALTER ROLE db_datareader ADD MEMBER oneuptime_ro;

注意事项

  • 查询每次检查都会执行,务必保持廉价:使用索引、窄时间窗口,并把语句超时作为最后兜底;
  • 只回传行数、第一格(标量)与首行——设计查询时,把你要告警的值放在第一列
  • 若结果因超过最大行数被截断,检查摘要会标记为 capped(封顶)。仅在必要时调大最大行数,更大的结果集会占用更多探针内存;
  • 写入与 DDL 永远被拒绝。如果你需要测试写入路径,这不是本监控器的用途;
  • 优先使用 Monitor Secret 而非明文密码,确保凭据在静态时加密存储。

总而言之,OneUptime 的 SQL 查询监控通过「探针侧执行 + 只读事务 + 单语句白名单 + 超时与行数边界 + 凭据脱敏」的多层设计,把「对生产数据库执行客户查询」这一高风险操作约束在安全范围内,同时以紧凑投影的方式保证客户数据不出内网;配合行数、标量值、耗时、错误与 JavaScript 表达式等检查项,可以快速搭建覆盖数据库健康度与关键业务指标的可观测告警。

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 19:16:42

AI算力集群网络瓶颈:SRv6如何弥补VxLAN方案的不足

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 19:11:24

BrewUI:给Homebrew装个可视化驾驶舱,打造直观的包管理体验

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 19:09:56

计算机控制仿真选择与计算:离散化、采样周期与PID实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 19:08:51

信息素养期末冲刺:核心考点、检索策略与速查技巧

简介:信息素养课程期末考试答案Word版,面向正在备考信息素养—学术研究的必修课的高校学生,专门解决考试时题目与答案序号被打乱、难以快速匹配的痛点。文档基于课程考试常见知识点整理,内容涵盖学术信息交流的正式渠道与同行评审…

作者头像 李华
网站建设 2026/9/20 19:08:29

DGX Spark本地部署Qwen3.5-35B-A3B-FP8实战:从开箱到性能实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 19:07:25

债券投资组合管理实战:久期、信用利差与杠杆的协同策略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华