ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OneUptime SQL Query Monitor 完整指南:只读 SQL 数据库监控与告警实战

OneUptime SQL Query Monitor 完整指南:只读 SQL 数据库监控与告警实战 OneUptime SQL Query Monitor 完整指南只读 SQL 数据库监控与告警实战【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptimeSQL Query MonitorSQL 查询监控器是 OneUptime 开源可观测性平台中的一种监控类型它按计划从探针Probe向你的数据库执行一条只读 SQL 查询并对结果进行告警——例如过去五分钟内取消订单数量是否飙升、队列表是否过大、关键数据行是否消失。本文将以仓库中的官方文档fa 版原文与 en 版原文为骨架结合 SqlMonitor.ts、SqlQueryGuard.ts、SqlMonitorCriteria.ts 等源码系统讲解支持的数据库、工作原理、安全模型、完整配置、查询编写规范、只读用户创建与告警规则配置帮助你把这个运行一条查询并触发事件的监控场景在生产环境中落地。支持的数据引擎SQL Query Monitor 官方支持以下三种数据库引擎各引擎默认端口在文档中已注明引擎默认端口PostgreSQL5432MySQL3306Microsoft SQL Server1433与 MySQL 或 PostgreSQL 兼容、且使用相同 wire 协议与 SQL 方言的引擎如 MariaDB、TiDB 等通常也能工作但官方只对上述三种引擎做过正式测试。在源码层面探针侧通过三个独立的驱动执行查询——pgPostgreSQL、mysql2/promiseMySQL与mssqlSQL Server由 runQuery 分发逻辑 按databaseType分发到不同的执行器这意味着一旦选定引擎后续的连接方式与超时语义都走对应驱动的专有实现。工作原理一次检查的完整数据流每次检查check发生时探针完成以下动作连接到你的数据库连接参数来自监控配置在只读上下文中执行你配置的查询至多读取一个有界上限的行数Max Rows把一份紧凑的投影结果projection上报给 OneUptime监控规则criteria基于这份投影结果评估监控状态。关键点在于完整结果集永远不会离开探针。探针只上报五种有限的投影数据这与 SqlMonitor.shapeRows() 的实现完全一致——该方法只保留有界行数、首行与首单元格Row Count—— 查询返回的行数受 Max Rows 限制。当实际行数超过 Max Rows 时isRowsCapped会被置为 true检查摘要会标记结果为已封顶。Scalar Value—— 第一行第一列的值。这是SELECT COUNT(*)风格查询的自然取值对象。First Row—— 第一行以列/值键值对形式呈现显示在检查摘要中作为上下文。Execution Time—— 查询耗时单位毫秒。Query Error—— 查询失败时的净化sanitized错误消息。因为完整结果集从不发送给 OneUptime客户数据不会被复制进 OneUptime 的存储中——这是该监控器在数据隐私方面的核心设计。源码中 coerceCell() 进一步保证了投影数据的可序列化性Date转为 ISO 字符串、二进制转为[binary]占位符、bigint转为字符串、结构化值 JSON 序列化最终投影永远是一组 JSON 安全的原始类型。安全模型多层防线在生产数据库上运行客户提供的查询是敏感操作因此 SQL Query Monitor 在设计上天生只读并层层叠加了多项控制。下面结合源码逐一展开1. 最小权限数据库用户首要控制始终使用专用的、只读的数据库用户连接该用户只应拥有查询所需的表权限。这是最重要的一道防线——即使其他所有控制失效一个最小权限用户也决定了损害范围。文末创建只读用户一节给出了三种引擎的完整 SQL 示例。2. 只读执行数据库事务层在PostgreSQL与MySQL上探针开启READ ONLY事务无论查询文本如何任何写操作包括可写 CTE都会被拒绝。PostgreSQL 执行器的实现见 runPostgresQuery()它执行START TRANSACTION READ ONLY、设置SET LOCAL statement_timeout并始终以ROLLBACK结束。在Microsoft SQL Server上由于没有只读事务概念探针在事务内执行并始终回滚。3. 单语句 白名单起始关键字查询必须是一个单一语句且必须以SELECT、WITH、VALUES或TABLE之一开头。堆叠语句如SELECT 1; DROP TABLE …与写入/DDL 会在探针连接数据库之前就被拒绝。这一静态校验由 SqlQueryValidator 实现细节值得展开注释与字符串感知stripComments()会移除--行注释与/* */块注释stripStringLiterals()会把字符串字面量中的内容抹掉。因此隐藏在注释或字符串里的关键字无法蒙混过关——例如SELECT DROP TABLE x可以通过校验字符串内容被抹平而SELECT 1; DROP TABLE x会因为抹平字符串后仍存在;而被拒绝。禁止构造清单denylistFORBIDDEN_CONSTRUCTS使用整词边界正则匹配insert/update/delete/merge/truncate/drop/alter/create/rename/grant/revoke/call/exec/execute/backup/restore/dbcc/shutdown/reconfigure/waitfor/into/outfile/dumpfile以及远程数据源访问类openquery/openrowset/opendatasource/openxml和 SQL Server 系统存储过程xp_/sp_。词边界的设计让created_at、updated_at、delete_flag这类包含子词的标识符不会被误伤REPLACE被刻意排除在禁止清单之外因为它是常见的只读字符串函数。;检查的局限与补强源码注释明确指出仅凭分号搜索不足以覆盖 T-SQL——SQL Server 的批处理可以仅靠空白分隔多条语句分号可省略所以SELECT 1 EXEC xp_cmdshell …能通过首关键字白名单。denylist 恰好弥补了这个缺口无论分隔符是什么都会拒绝第二条语句或副作用构造同时它也能拦截READ ONLY事务拦不住的读取期文件写入如 MySQL 的SELECT … INTO OUTFILE。白名单与游标的配合PostgreSQL 执行器会把查询嵌入DECLARE ... NO SCROLL CURSOR FOR ...中执行因此只允许能在游标中运行的语句SELECT/WITH/VALUES/TABLE——SHOW、EXPLAIN这类非游标化读取语句会被拒绝。这一点在 SqlMonitor.test.ts 的对应用例 中有明确验证。4. 语句超时硬性上限每条查询都有硬性的时间上限运行过久的查询会被取消。详见下文高级选项。5. 有界行数最多只读取 Max Rows外加一行用于检测截断行数据这限制了探针内存与上报包大小。PostgreSQL 与 MySQL 执行器均通过FETCH FORWARD ${maxRows 1} FROM cursor或流式读取方式实现多读一行用于截断检测。6. 凭据净化redaction数据库错误在存储前会被净化——密码和任何连接串都会被抹掉凭据永远不会泄漏进错误消息。sanitizeError() 的实现会将配置中的密码原样替换为***对长度 ≥ 4 的其他秘密字段host、username、databaseName同样逐字替换避免db这类过短通用值破坏消息可读性用正则抹掉连接 URIpostgres://user:passhost/db等 →[redacted-dsn]抹掉password/pwd形式的连接串键值对兼容与:分隔符、引号/花括号/含空格值。另外OneUptime 服务端还有一份面向外部数据源Data Source的通用守卫 SqlQueryGuard.ts它对#注释、反斜杠转义引号做了更保守的处理#在 T-SQL 中是临时表前缀而非注释反斜杠引号在各引擎中语义不同一律拒绝与探针侧的校验构成纵深防御。前置条件开始配置前需要准备两样东西一个能访问你数据库主机与端口的探针Probe。如果数据库可从公网访问可以使用 OneUptime 托管的探针否则需要在你的网络内部署自托管探针。自定义探针的安装方式见探针文档。一个只读数据库用户及其连接信息主机、端口、数据库名、用户名、密码若使用 SQL Server 集成认证Windows Integrated Authentication则准备一个只读的 Windows/域身份。配置指南创建新监控器并选择监控类型为SQL Query然后填写连接信息。下表汇总了文档中的全部配置项配置项说明Database TypePostgreSQL、MySQL 或 Microsoft SQL Server。选择类型会自动设置默认端口。Host探针可达的数据库主机例如db.internal。Port数据库端口。Database Name查询将要执行的数据库。Use Windows Integrated Authentication仅限 Microsoft SQL Server。改用运行探针的账户进行身份认证而不是 SQL 用户名/密码。见下方Windows 集成认证。Username只读、最小权限的数据库用户。Password数据库密码。强烈建议用{{monitorSecrets.name}}引用 Monitor Secret对应文档位于 monitor-secrets.md而不是明文输入见下文。SQL Query要执行的只读查询见编写查询。Use SSL/TLS启用后通过 TLS 连接。若数据库使用自签名证书可关闭Verify server certificate。Windows 集成认证仅 SQL Server启用Use Windows Integrated Authentication后探针将使用自身进程身份打开可信连接trusted connection此时Username 与 Password 字段会被忽略且不会传给驱动。由于探针需要你的域所信任的身份此认证模式必须使用自托管探针。Windows 探针以拥有 SQL Server 只读登录权限的域账户运行探针服务。Linux / macOS 探针为 SQL Server 域配置 Kerberos并通过 keytab 等方式给探针进程一张有效票据。官方 Linux 探针镜像内置 Microsoft ODBC Driver 18、unixODBC 与 Kerberos 客户端。需要把 Kerberos 配置与票据缓存挂载进容器、对探针进程可读并在路径非默认时设置KRB5_CONFIG或KRB5CCNAME环境变量。探针需要一个已安装的 Microsoft ODBC Driver for SQL Server。官方探针镜像自带ODBC Driver 18自托管或自定义探针会自动检测并使用主机上注册的最新版ODBC Driver N for SQL Server例如装了 Driver 17 就用 17——不必恰好是 18。若想固定某个具体驱动可在探针上设置环境变量SQL_SERVER_ODBC_DRIVER为驱动全名如ODBC Driver 17 for SQL Server。这部分在源码中有完整的落点。探针侧的 resolveSqlServerOdbcDriver() 按以下优先级解析驱动名①SQL_SERVER_ODBC_DRIVER环境变量操作员显式覆盖② 主机上注册的最新ODBC Driver N for SQL Server③ 官方镜像内置的ODBC Driver 18 for SQL Server兜底。驱动检测通过平台原生机制完成——Windows 上用reg query查询注册表、Unix 上用odbcinst -q -dunixODBC且以异步子进程方式运行、带 3 秒超时避免拖慢探针事件循环探针在同一事件循环上多路复用大量监控器。检测到真实驱动或显式覆盖的结果会被记忆缓存而默认兜底刻意不缓存——驱动列表为空既可能是主机真没有驱动也可能是odbcinst/reg瞬时不可用不缓存可让下一次集成认证查询重新探测。测试注入 lister/env 并支持禁用缓存的隔离设计见 SqlMonitor.test.ts 及配套的resetSqlServerOdbcDriverCache。此外还有几个环境要求SQL Server 必须有合适的MSSQLSvc服务主体名SPN、探针与域控制器时钟必须同步、探针必须通过该 SPN 覆盖的主机名解析并访问 SQL Server。只把监控查询所需的数据库权限授予受信身份。高级选项配置项说明默认值最大值Connection Timeout (ms)建立连接的最长等待时间1000030000Statement Timeout (ms)查询执行时间的硬性上限1500060000Max Rows从数据库读回的行数上限1001000这些钳制clamp行为在 MonitorStepSqlMonitor.ts 中定义clampSqlStatementTimeoutInMs/clampSqlConnectionTimeoutInMs/clampSqlMaxRows三个函数会在值缺失时回退到默认值、超过上限时压到最大值。探针执行时execute()会先对所有三个参数做钳制确保越界配置不会生效。超时还有更细的分层PostgreSQL 执行器同时设置了服务端statement_timeout主超时控制与客户端query_timeout比服务端多 2 秒的兜底再叠加 withHardTimeout() 的客户端竞速硬超时超时后主动拆掉连接/请求避免被遗弃的查询继续消耗资源。错误分类方面探针通过错误文本识别超时Postgres 的canceling statement、MySQL 的maximum statement execution time、SQL Server 的request timed out等并把isTimeout标记返回给上层见 execute 中的lowerCased.includes(...)逻辑。编写查询查询必须是单一只读语句以SELECT、WITH、VALUES或TABLE之一开头。允许末尾带一个分号多个语句不允许。查询要尽量廉价且范围收窄——它每次检查都会执行所以优先使用索引列和窄时间窗口。三种引擎下统计最近取消订单数的等价写法文档原样-- 统计最近的取消订单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计数本身来自第一列。要对多少个进行告警请用Scalar Value比较。从源码角度补充两点最佳实践想要告警的值必须放在第一列因为投影只上报行数、首单元格标量与首行。shapeRows()从第一行的第一个对象键提取标量而行对象由各驱动按投影顺序构建所以第一列即标量来源。校验是大小写与空白不敏感的select 1、select 1都能通过白名单见测试用例 SqlMonitor.test.ts#L68-L70。用 Monitor Secret 保护密码为避免数据库密码以明文形式存储在监控器上请创建一个 Monitor Secret并在 Password 字段引用它进入 OneUptime 控制台 → Monitors → Settings → Secrets → Create Monitor Secret。创建一个秘密例如dbPassword并把该监控器对此秘密的访问权限授予它。在监控器的 Password 字段中输入{{monitorSecrets.dbPassword}}。OneUptime 会在把配置下发给探针之前在服务端解析该秘密。OneUptime 不会替用户创建这些秘密——是否引用完全是你的选择。密码以加密形式静态存储这正是文档建议优先使用 Monitor Secret 而非明文密码的原因。设置告警规则Criteria添加规则criteria来决定监控器何时被判定为在线online、降级degraded或离线offline。SQL Query Monitor 提供以下可用的检查项检查项说明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对应文档位于 javascript-expression.md。这些规则的求值逻辑在 SqlMonitorCriteria.ts 中逐项实现与上表一一对应SqlIsOnline直接比较dataToProcess.isOnline布尔值SqlQueryRowCount把阈值转为数字后与sqlResponse.rowCount数值比较SqlQueryExecutionTime优先使用sqlResponse.responseTimeInMs缺失时回退到整体响应时间SqlQueryScalarValue实现了文档描述的数值优先、字符串兜底逻辑当阈值可转为数字、标量不是布尔且Number(scalarValue)不是 NaN 时走数值比较否则走字符串比较SqlQueryError先做空/非空判断再做字符串匹配。示例取消订单激增时告警沿用上面的查询降级Degraded规则——SQL Query Scalar Value大于10。离线Offline规则——SQL Query Scalar Value大于50或SQL Is Online为false。把值班策略on-call policy附加到规则上让合适的人被呼叫paged。创建只读用户始终使用专用只读用户连接。以下是三种引擎的完整示例文档原样注意 PostgreSQL 的默认权限还覆盖了未来新建的表-- 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;实战注意事项汇总查询每次检查都会执行务必保持廉价使用索引与窄时间窗口并把 Statement Timeout 作为最后的兜底防线。只上报行数、首单元格标量与首行——设计查询时确保你要告警的值位于第一列。结果若因超过 Max Rows 被截断检查摘要会标记为已封顶capped。仅在确有必要时提高 Max Rows——更大的结果集会消耗更多探针内存。写入与 DDL 永远被拒绝。如果你需要测试写路径这个监控器并不适合。优先使用 Monitor Secret 而非明文密码让凭据在静态存储时保持加密。只读事务与静态校验构成纵深防御探针侧的SqlQueryValidator是第二道防线首要保证来自只读事务与最小权限数据库用户FORBIDDEN_CONSTRUCTS中的xp_/sp_模式与exec/execute等关键字拦截了 SQL Server 批处理与存储过程逃逸即使没有分号也无法绕过。相关资源官方文档原文fa/sql-monitor.md、en/sql-monitor.md探针执行器packages/Probe/Utils/Monitors/MonitorTypes/SqlMonitor.ts参数钳制与类型定义packages/Common/Types/Monitor/MonitorStepSqlMonitor.ts规则求值packages/Common/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.ts服务端通用只读守卫packages/Common/Server/Utils/DataSource/SqlQueryGuard.ts单元测试packages/Probe/Tests/Utils/Monitors/MonitorTypes/SqlMonitor.test.ts相关文档monitor-secrets.md、javascript-expression.md【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表