> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashduty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 数据库拉取告警 (DB Pull)

> Flashduty 按周期主动查询 MySQL、PostgreSQL 或 ClickHouse 数据库，将符合条件的行转换为标准告警事件；适用于告警数据已写入关系型数据库、无法主动推送的场景。

通过配置数据库连接和一条 SELECT 查询，Flashduty 会按照您设定的周期主动连接数据库，利用游标分页增量拉取新行，将每行按照字段映射规则转换为 [标准告警事件](/zh/on-call/integration/alert-integration/alert-sources/standard%20alert) 并写入告警通道。整个过程不需要您的系统具备推送能力。

<Tip>
  DB Pull 适合 **告警数据已落入关系型数据库**、**无法或不希望改造已有系统以支持 webhook 推送** 的场景。如果您的数据库所在网络无法被 Flashduty 访问，请考虑使用支持推送的集成方式，或先将告警导出到可公网访问的 HTTP 接口后再用 HTTP Pull 集成。
</Tip>

<div className="hide">
  ## 操作步骤

  ***

  ### 在 Flashduty

  <AccordionGroup>
    <Accordion title="使用专属集成">
      当您不需要根据告警内容路由到不同的协作空间时，优先选择此方式，更简单。

      1. 进入 Flashduty 控制台，选择 **协作空间**，进入某个空间的详情页面。
      2. 选择 **集成数据** tab，点击 **添加一个集成**，进入添加集成页面。
      3. 选择 **DB Pull** 集成。
      4. 按下文「配置项」说明填写表单，点击 **保存**。
    </Accordion>

    <Accordion title="使用共享集成">
      当您需要根据告警事件的 Payload 信息，将告警路由到不同协作空间时，优先选择此方式。

      1. 进入 Flashduty 控制台，选择 **集成中心 ⇒ 告警事件**，进入集成选择页面。
      2. 选择 **DB Pull** 集成，并填写 **集成名称**。
      3. 配置 **默认路由**，选择对应的协作空间（集成创建后可前往 **路由** 配置更多路由规则）。
      4. 按下文「配置项」说明填写表单，点击 **保存** 完成。
    </Accordion>
  </AccordionGroup>
</div>

## 配置项

***

### 数据库驱动

|     字段     |  必填 | 说明                                                                            |
| :--------: | :-: | :---------------------------------------------------------------------------- |
| 驱动（driver） |  是  | 数据库类型，支持 `mysql`、`postgres`（或 `postgresql`）、`clickhouse`。填写时不区分大小写，系统会自动转为小写。 |

### 连接信息

|       字段      |  必填 | 说明                                                                                  |
| :-----------: | :-: | :---------------------------------------------------------------------------------- |
|    主机（host）   |  是  | 数据库服务器的主机名或 IP 地址。**不允许填写回环地址（127.x.x.x / ::1）、私有网段或链路本地地址**，以防止 SSRF 攻击。           |
|    端口（port）   |  是  | 数据库监听端口，例如 MySQL 默认 `3306`，PostgreSQL 默认 `5432`，ClickHouse 默认 `9000`。               |
| 用户名（username） |  是  | 连接数据库使用的账号，建议授予只读权限。                                                                |
|  密码（password） |  是  | 连接密码，加密存储，写入后不可明文查看。                                                                |
| 数据库（database） |  是  | 要连接的数据库名称。                                                                          |
|  扩展参数（params） |  否  | Key-Value 形式的额外连接参数，不同驱动对应不同的 DSN 参数，例如 MySQL 的 `timeout`、PostgreSQL 的 `sslmode` 等。 |

### 查询配置

|           字段           |  必填 |  默认值  | 说明                                                                                                                                                                                                                    |
| :--------------------: | :-: | :---: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|       查询语句（query）      |  是  |   -   | 一条只读 SELECT 语句（或以 `WITH` 开头的 CTE 查询）。**禁止**包含 `INSERT`、`UPDATE`、`DELETE`、`DROP` 等 DML/DDL 关键字，**禁止**使用 `?` 占位符，**禁止**包含 `LIMIT` / `OFFSET` 等分页子句（系统自动处理分页）。查询输出列中**必须包含**游标字段（`time_column` 与 `id_column`），否则保存时校验失败。 |
|     超时时间（timeout，秒）    |  是  |  `5`  | 单页查询的最长执行时间，范围 `1 ~ 10` 秒，超过 `10` 秒时系统自动截断为 `10`。                                                                                                                                                                     |
| 拉取周期（cycle\_seconds，秒） |  是  |   -   | Flashduty 触发下一次拉取的间隔（秒）。                                                                                                                                                                                              |
|    最大页数（max\_pages）    |  是  |  `5`  | 单次拉取最多查询多少页，范围 `1 ~ 10`，超过 `10` 时截断为 `10`。每页行数达到 `page_size` 时翻页，否则停止。                                                                                                                                                |
|    每页行数（page\_size）    |  是  | `500` | 单页最多返回的行数，范围 `1 ~ 1000`，超过 `1000` 时截断为 `1000`。                                                                                                                                                                        |

<Note>
  单次拉取最多摄入的行数受全局上限约束（`max_pages × page_size`），并不会超过系统内部的事件总数上限。建议将 `page_size` 设置为数据库能高效处理的批量大小（通常 200 \~ 500 行），`max_pages` 根据告警产出速率合理调整。
</Note>

### 游标配置

Flashduty 使用 **游标分页**（Keyset Pagination）增量拉取新行，避免全表扫描。每次拉取结束后，系统将最后一行的游标位置持久化，下次拉取从该位置继续。

|          字段         |  必填 | 说明                                                                                     |
| :-----------------: | :-: | :------------------------------------------------------------------------------------- |
|  时间列（time\_column）  |  是  | 用于排序和分页的时间类型列名，列名只能包含字母、数字和下划线且不能以数字开头。该列必须出现在 SELECT 输出中。                             |
|   ID 列（id\_column）  |  是  | 与时间列联合用于分页的唯一标识列名（通常为自增主键或 UUID），规则同上。当同一时刻有多行时，ID 列用于消除时间列的排序歧义，防止漏行。                 |
| 初始时间（initial\_time） |  否  | 首次拉取（或检查点重置后）使用的起始时间，格式为 `YYYY-MM-DD HH:MM:SS`。若不填，系统以配置保存时的当前时间作为起点，**已存在的历史行不会被拉取**。 |

**分页查询原理**

系统将您的 SELECT 语句包装成子查询，并在外层自动添加如下 Keyset 条件与排序：

```sql theme={null}
SELECT * FROM (<您的查询>) AS _src
WHERE (_src.<time_column> > ? OR (_src.<time_column> = ? AND _src.<id_column> > ?))
ORDER BY _src.<time_column> ASC, _src.<id_column> ASC
LIMIT <page_size>
```

因此您的查询语句不应自带 `ORDER BY`、`LIMIT` 或 `OFFSET`，由系统统一控制。

**检查点自动重置**

系统对查询来源的关键字段计算指纹：`driver`、`host`、`port`、`database`、`query`、`time_column`、`id_column`、`initial_time`。当上述任意字段发生变更时，检查点自动失效，下次拉取从 `initial_time` 重新开始。修改字段映射或严重程度映射**不会**触发检查点重置，不会导致历史行重放。

### 字段映射

字段映射决定数据库行的哪些列（或常量值）映射到标准告警事件的哪些字段。

#### 标准字段映射（fields）

每条映射规则由 **目标字段**（标准事件字段名）和 **规则** 组成，规则有三种类型：

| 规则类型 |   type 值   | value 说明                                                                                                     |
| :--: | :--------: | :----------------------------------------------------------------------------------------------------------- |
|  列映射 |  `column`  | 直接取数据库行中该列名对应的值。例如 `"type": "column", "value": "alert_title"` 表示取 `alert_title` 列。                           |
|  常量  |   `const`  | 固定字符串，每行均使用相同的值。例如 `"type": "const", "value": "Critical"` 表示始终填入 `Critical`。                                 |
|  模板  | `template` | Go 模板字符串，可引用行中任意列。例如 `"type": "template", "value": "{{.host}}: {{.message}}"` 会将 `host` 和 `message` 列拼接为字符串。 |

当目标字段为 `event_time` 时，系统会将列值自动转换为 Unix 时间戳（秒）；支持的输入格式包括 `time.Time`、Unix 毫秒整数、`"2006-01-02T15:04:05"`、`"2006-01-02 15:04:05"` 等常见格式。

#### 标签映射（labels）

标签映射决定如何将数据库列转换为告警事件的 `labels` 字典，支持四种模式：

|   模式   |       mode 值      | 说明                                                                           |
| :----: | :---------------: | :--------------------------------------------------------------------------- |
|   指定列  | `include_columns` | 仅将 `columns` 列表中列出的列作为标签，标签名即列名，标签值为列值字符串。                                   |
|   全部列  |   `all_columns`   | 将查询结果中所有列（排除游标列和已被 `fields` 引用的列）自动转为标签。适合列数较少且不确定列名的场景。                     |
| JSON 列 |   `json_column`   | 将指定列的 JSON 字符串（`{"key": "value", ...}`）解析为标签字典。该列的值必须是合法的 JSON 对象。           |
|  手动映射  |      `manual`     | 显式指定标签名到列名的映射，例如 `{"region": "dc_region", "env": "deploy_env"}`，标签名为键，源列名为值。 |

### 严重程度映射

外部系统的告警级别字段取值往往不一致，Flashduty 通过 **严重程度映射** 将外部值翻译为标准的 `Critical / Warning / Info`。

* 系统读取经过字段映射后得到的 `event_status` 字段值，按映射表查找对应的 Flashduty 严重程度。
* **未命中兜底**：若 `event_status` 没有匹配到映射表中的任何键，默认降级为 `Warning`。

示例配置：

```json theme={null}
{
  "P0": "Critical",
  "P1": "Critical",
  "P2": "Warning",
  "P3": "Info"
}
```

## 默认路由

***

新增「共享集成」时必须配置默认路由，否则拉取到的事件将被丢弃。集成创建后可在 **路由** 中追加更细粒度的规则。

「专属集成」（在某个协作空间的 **集成数据** 中创建）会自动绑定到所在空间，不需要单独配置默认路由。

## 注意事项

***

* **数据库账号权限**：建议为 DB Pull 单独创建只读账号，仅授予目标表的 `SELECT` 权限，禁止写入权限，降低安全风险。
* **网络可达性**：Flashduty 服务端必须能够通过公网或专线访问到数据库的 `host:port`。私有网段（`10.x.x.x`、`192.168.x.x`、`172.16~31.x.x`）和回环地址会被系统拒绝连接。
* **游标列索引**：为保证拉取性能，建议在 `time_column` 和 `id_column` 组合上建立复合索引，避免全表扫描。
* **时间列精度**：系统以微秒精度（`2006-01-02 15:04:05.999999`）记录游标时间，建议数据库时间列的精度不低于毫秒（`DATETIME(3)` 或 `TIMESTAMP(6)`），以避免在同一秒内产生大量数据时发生漏行。
* **查询幂等性**：同一行在检查点重置后可能被重复拉取，请确保您的字段映射中包含能唯一标识一条告警的字段（作为 `alert_key`），以便 Flashduty 正确去重。
