-- ============================================================================= -- 脚本:05-fairness-late-replay-upgrade.sql -- 用途:增加 API 任务调度优先级,并创建迟到告警规则重放所需的两张表。 -- 性质:增量数据库结构变更脚本,会修改表结构和数据。 -- 执行时机:04 预检通过后,部署三个新版服务之前。 -- -- 前置条件: -- 1. 已完成数据库备份; -- 2. API 拉取任务已经暂停; -- 3. syslog-serve、syslog-consumer、syslog-consumer-rule 旧版本已停止; -- 4. SCHEDULER_PRIORITY 字段和两张 ANALYSIS_* 表尚不存在。 -- -- 注意:本脚本不是重复执行脚本。执行成功后不要再次执行。 -- 如果中途报错,应先执行 06 验证已经创建的对象,再决定如何处理。 -- ============================================================================= -- 第 1 步:增加任务调度优先级。 -- 数值越大,在到期时间相同的情况下越先执行;默认值 0 兼容旧任务。 ALTER TABLE device_collect_api_config ADD scheduler_priority INTEGER DEFAULT 0 NOT NULL; ALTER TABLE device_collect_api_config ADD CONSTRAINT ck_dc_api_cfg_priority CHECK(scheduler_priority BETWEEN -1000 AND 1000); CREATE INDEX idx_dc_api_cfg_priority_due ON device_collect_api_config(enabled,next_run_at,scheduler_priority,collect_task_id); -- 第 2 步:设置现有 NDR 任务的默认优先级。 -- 同一 NDR 主机只有一个并发许可时,让低流量告警优先于高流量原始网络日志。 UPDATE device_collect_api_config SET scheduler_priority=100,updated_at=SYSDATE WHERE stream_key='NDR_ALERT'; UPDATE device_collect_api_config SET scheduler_priority=10,updated_at=SYSDATE WHERE stream_key='NDR_FLOW_LOG'; -- 第 3 步:创建迟到告警分钟桶表。 -- 标准化告警入库时,如果其事件分钟已经被实时分析处理过,就在此表登记补处理请求。 CREATE TABLE analysis_late_alarm_bucket ( id VARCHAR2(36) NOT NULL, device_id BIGINT NOT NULL, bucket_start TIMESTAMP NOT NULL, bucket_end TIMESTAMP NOT NULL, last_observed_at TIMESTAMP NOT NULL, requested_generation BIGINT DEFAULT 1 NOT NULL, claimed_generation BIGINT DEFAULT 0 NOT NULL, processed_generation BIGINT DEFAULT 0 NOT NULL, status VARCHAR2(16) DEFAULT 'PENDING' NOT NULL, attempt_count INTEGER DEFAULT 0 NOT NULL, fencing_token BIGINT DEFAULT 0 NOT NULL, lease_owner VARCHAR2(128), lease_expires_at TIMESTAMP, last_error_code VARCHAR2(128), last_error_summary VARCHAR2(2000), created_at TIMESTAMP DEFAULT SYSDATE NOT NULL, updated_at TIMESTAMP DEFAULT SYSDATE NOT NULL, CONSTRAINT pk_analysis_late_alarm_bucket PRIMARY KEY(id), CONSTRAINT uk_analysis_late_alarm_bucket UNIQUE(device_id,bucket_start), CONSTRAINT ck_analysis_late_bucket_status CHECK(status IN ('PENDING','RUNNING','COMPLETED','FAILED')), CONSTRAINT ck_analysis_late_bucket_gen CHECK(requested_generation>=claimed_generation AND claimed_generation>=processed_generation AND processed_generation>=0), CONSTRAINT ck_analysis_late_bucket_count CHECK(attempt_count>=0 AND fencing_token>=0), CONSTRAINT ck_analysis_late_bucket_window CHECK(bucket_end>bucket_start), CONSTRAINT ck_analysis_late_bucket_lease CHECK((lease_owner IS NULL AND lease_expires_at IS NULL) OR (lease_owner IS NOT NULL AND lease_expires_at IS NOT NULL)) ); CREATE INDEX idx_analysis_late_bucket_due ON analysis_late_alarm_bucket(status,lease_expires_at,bucket_start); -- 第 4 步:创建规则重放窗口表。 -- 系统根据分钟桶和当时适用的规则生成重放窗口,处理结果与正常实时窗口分开记录。 CREATE TABLE analysis_rule_replay_window ( id VARCHAR2(36) NOT NULL, source_bucket_id VARCHAR2(36) NOT NULL, rule_id VARCHAR2(128) NOT NULL, rule_version VARCHAR2(64) NOT NULL, window_start TIMESTAMP NOT NULL, window_end TIMESTAMP NOT NULL, requested_generation BIGINT DEFAULT 1 NOT NULL, claimed_generation BIGINT DEFAULT 0 NOT NULL, processed_generation BIGINT DEFAULT 0 NOT NULL, status VARCHAR2(16) DEFAULT 'PENDING' NOT NULL, attempt_count INTEGER DEFAULT 0 NOT NULL, input_count BIGINT DEFAULT 0 NOT NULL, output_count BIGINT DEFAULT 0 NOT NULL, fencing_token BIGINT DEFAULT 0 NOT NULL, lease_owner VARCHAR2(128), lease_expires_at TIMESTAMP, next_retry_at TIMESTAMP, last_error_code VARCHAR2(128), last_error_summary VARCHAR2(2000), started_at TIMESTAMP, finished_at TIMESTAMP, created_at TIMESTAMP DEFAULT SYSDATE NOT NULL, updated_at TIMESTAMP DEFAULT SYSDATE NOT NULL, CONSTRAINT pk_analysis_rule_replay PRIMARY KEY(id), CONSTRAINT fk_analysis_rule_replay_bucket FOREIGN KEY(source_bucket_id) REFERENCES analysis_late_alarm_bucket(id), CONSTRAINT uk_analysis_rule_replay UNIQUE(rule_id,rule_version,window_start,window_end), CONSTRAINT ck_analysis_rule_replay_status CHECK(status IN ('PENDING','RUNNING','COMPLETED','FAILED','BLOCKED')), CONSTRAINT ck_analysis_rule_replay_gen CHECK(requested_generation>=claimed_generation AND claimed_generation>=processed_generation AND processed_generation>=0), CONSTRAINT ck_analysis_rule_replay_count CHECK(attempt_count>=0 AND input_count>=0 AND output_count>=0 AND fencing_token>=0), CONSTRAINT ck_analysis_rule_replay_window CHECK(window_end>window_start), CONSTRAINT ck_analysis_rule_replay_lease CHECK((lease_owner IS NULL AND lease_expires_at IS NULL) OR (lease_owner IS NOT NULL AND lease_expires_at IS NOT NULL)) ); CREATE INDEX idx_analysis_rule_replay_due ON analysis_rule_replay_window(status,next_retry_at,lease_expires_at,window_start); -- 第 5 步:写入数据字典注释,方便后续运维排查。 COMMENT ON COLUMN device_collect_api_config.scheduler_priority IS '到期时间相同时的竞争优先级,数值越大越先调度;逾期更久的任务优先'; COMMENT ON TABLE analysis_late_alarm_bucket IS '标准化告警同事务写入的事件分钟 outbox;代数防止运行期间新通知丢失'; COMMENT ON COLUMN analysis_late_alarm_bucket.last_observed_at IS '本事件分钟最近一次事务内观察时间,仅供审计,不代表事务提交时间'; COMMENT ON TABLE analysis_rule_replay_window IS '迟到告警影响的独立规则重放窗口;不修改正常 RULE checkpoint'; COMMENT ON COLUMN analysis_rule_replay_window.rule_version IS '必须与正常 analysis_checkpoint 的规则语义版本完全一致'; COMMENT ON COLUMN analysis_rule_replay_window.processed_generation IS '已完整重放的请求代数;小于 requested_generation 时必须再次执行'; -- 提交本脚本中的优先级更新。 COMMIT; -- 执行完成后,请立即执行 06-fairness-late-replay-verify.sql。