chore(db): 压缩 Flyway 迁移链为单基线

原 V1–V10 的净结构全部合并进 V1__flight_state_baseline.sql,迁移链收敛为一条。
表集合、逐列类型/非空/默认值、表级约束、索引与种子行经重放比对与旧链条一致;
仅丢弃 5 条只对既有库有意义的存量数据语句(RECEIVED_AT/ENQUEUED_AT 回填、
schd 与开放请求去重、SENT_AT 回写)。

已按旧链迁移过的库版本链与校验和对不上,必须重建 schema 或删除数据卷后重跑,
禁止手工 repair 或改写 flyway_schema_history。

- 删除 V2–V10 共 9 个迁移文件
- 注释统一范式并改用稳定 ID(INV-x/C-x/G-x),修正 KAFKA_MSG/KAFKA_SCHD 与实际值不符
- 同步 docs/reference.md、docs/user-stories.md、oracle11g/README.md、README、application.yml、compose.yaml
- FlywayMigrationTest 改为断言单基线,并补 MSG_EVENT.SENT_AT 覆盖
This commit is contained in:
windyboy
2026-09-13 16:31:14 +08:00
parent 62f61ad9e4
commit 800d7617f2
17 changed files with 163 additions and 356 deletions
@@ -1,23 +1,34 @@
-- =====================================================================
-- 航班运行数据接入与当前状态管理 · 全量基线
-- 自有 PostgreSQL 全量基线(单迁移链条目)
-- ---------------------------------------------------------------------
-- 权威设计:docs/flight-state.md(审计定稿)。本脚本整体取代历史迁移
-- V1.0.0V1.4.0 已删除),按 §3.2 表职责建立全部分层:
-- · 决策层:FLIGHT_SCHD + 8 张资源明细表 + FLIGHT_ROUTE_POINT —— 承担正确性;
-- · 管道层:PIPELINE_LOCK / PROC_STATE / MSG_EVENT(outbox) / REQ_TRACK / BACKFILL_TODO
-- · 留痕层:SCHD_SNAP_LOG —— 只追加、不参与决策、可重建
-- · 证据层:报文原文归档 —— 冷路径,尚未交付(ARCHIVE_KEY 仅留引用位)。
-- 核心定案(对照文档章节):
-- · 身份:FLID 主键;OPERATION_DAY 一经确定不可变(§3.1/§5.3,应用层校验);
-- STATE ∈ {ACTIVE, DELETED},无 ARCHIVED —— 物理清除只发生在历史归档成功之后(§8.2);
-- · 无名单差删:主链路无集合删除;删除入口只有 FDEL(§6.2)与历史归档(§8.2);
-- · 版本:每次成功写入推进 STATE_VERSIONKafka 判旧 = (FLID, STATE_VERSION, UPDATED_AT)(§7.3);
-- · 出站:COUTMSGS 是共享 MySQL 信箱(他人系统库,本系统不建表,迁移不覆盖)。
-- 类型口径:TIMESTAMP(6) WITH TIME ZONE 统一 UTC 语义;无 JSONB/CLOB 依赖;
-- BIGSERIAL 为 PostgreSQL 方言(Oracle 适配见 §10,未定前不预设)。
-- 范围:本迁移只作用于自有 PostgreSQL。共享 MySQL 信箱(CMINMSGS/COUTMSGS)是他人
-- 系统库,只做契约内 DML,不建表、不改结构(C-14)。
--
-- 本文件原为 V1 基线;原 V2–V10 的净结构已全部合并进来,版本链收敛为一条:
-- · INBOX_CURSOR 及 SEEDED_AT(原 V2/V5
-- · PROC_STATE 的收信/入队时间与回填事实列,独立待办表 BACKFILL_TODO 不再存在
-- (原 V2/V3/V4/V6/V7:回填意图并入 PROC_STATE,处理开始时间列加后即删);
-- · REQ_TRACK 开放态部分唯一索引 uq_req_open(原 V8);
-- · MSG_EVENT 的 schd 单行唯一索引 uq_schd_event、SENT_AT,以及已无消费者的
-- idx_evt_flid 下线(原 V9/V10)。
-- 原 V2–V10 中只对既有库有意义的数据搬迁语句(存量 RECEIVED_AT / ENQUEUED_AT 回填、
-- 重复开放请求与重复 schd 事件去重、存量 SENT_AT 回写)一律不再保留——基线只服务
-- 全新库,而 Flyway 的迁移链一旦发布即不可改写,故这些语句的语义只能在此说明。
--
-- 升级路径:已应用过 V1–V10 的库无法直接升级(版本链与校验和都对不上)。重建 schema
-- 或删除数据卷后重跑迁移;禁止对生产库手工 repair 或改写 flyway_schema_history。
--
-- 分层(职责与写者见 docs/flight-state.md、docs/design.md):
-- · 决策层:FLIGHT_SCHD + 8 张资源明细表 + FLIGHT_ROUTE_POINT —— 权威当前态(INV-11);
-- · 管道层:PIPELINE_LOCK / INBOX_CURSOR / PROC_STATE / MSG_EVENT / REQ_TRACK
-- · 留痕层:SCHD_SNAP_LOG —— 只追加、可重建、不参与决策;
-- · 证据层:报文原文归档 —— 冷路径,尚未交付(ARCHIVE_KEY 仅留引用位,G-REPLAY-CHANNEL)。
-- 类型口径:TIMESTAMP(6) WITH TIME ZONE 统一 UTC 语义;BIGSERIAL 为 PostgreSQL 方言
-- Oracle 11g 等价 DDL 见同目录 oracle11g/README.md)。
-- =====================================================================
-- ① 单行锁:串行化状态写事务(§1 边界:只串行化 DB 事务,不代替消息认领/选主/故障切换)
-- ① 单行锁:事务内串行化状态写事务(只串行化本地 DB 事务,不代替消息认领选主
-- 故障切换,PRE-5)。历史清理与主泵处理器共用它互斥(INV-18)。
CREATE TABLE PIPELINE_LOCK (
LOCK_ID INT NOT NULL PRIMARY KEY, -- 恒为 1
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
@@ -25,50 +36,80 @@ CREATE TABLE PIPELINE_LOCK (
INSERT INTO PIPELINE_LOCK (LOCK_ID, UPDATED_AT) VALUES (1, now());
-- ② 处理伴生状态:与共享信箱 CMINMSGS 一一对应(MSG_ID = CMINMSGS_ID)。
-- 兼作快照重放判定(§5.1 步骤 2):MSG_ID 已有成功终态重放,直接记幂等成功。
-- 一信一行、一身份一记录(INV-9);MSG_ID 已有成功终态即判重放,直接记幂等成功。
-- 处理终态与回填意图在本表同表同行:不存在第二处落账,也不存在独立的回填待办表(INV-8)。
-- 状态不可逆:已提交的 SUCCEEDED 不因回填或投递失败回改(INV-6)。
CREATE TABLE PROC_STATE (
MSG_ID BIGINT NOT NULL PRIMARY KEY,
STATE VARCHAR(16) NOT NULL, -- PENDING/FAILED/SUCCEEDED/SKIPPED/DEAD
IDENTITY_KEY VARCHAR(200), -- SNDR|TYPE|STYP|SEQNdecode 后首次绑定;SEQN 同会话顺序观测 §5.5)
STATE VARCHAR(16) NOT NULL, -- PENDING/FAILED/SUCCEEDED/SKIPPED/DEADARCHIVED 属未建归档能力 G-PROC-HST
IDENTITY_KEY VARCHAR(200), -- SNDR|TYPE|STYP|SEQN,解码后首次绑定
ATTEMPTS INT NOT NULL DEFAULT 0,
NEXT_ATTEMPT_AT TIMESTAMP(6) WITH TIME ZONE,
ERROR_CLASS VARCHAR(20), -- MALFORMED/PROTOCOL/INFRA/UNSUPPORTED/EXHAUSTED(§9
NEXT_ATTEMPT_AT TIMESTAMP(6) WITH TIME ZONE, -- 退避到期时刻;未到期不得被后续消息越过(INV-3)
ERROR_CLASS VARCHAR(20), -- MALFORMED/PROTOCOL/INFRA/UNSUPPORTED/EXHAUSTED
LAST_ERROR VARCHAR(1000),
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
-- ==== 时间基准 ====
RECEIVED_AT TIMESTAMP(6) WITH TIME ZONE, -- 复制自信箱 DATE_RECEIVED:库方时钟、可为 NULL,仅用于对账与展示(PRE-4)
ENQUEUED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT now(), -- 本地入队时间:非空、与判据 NOW 同源,是超期期限 R 的唯一比较对象(PRE-4、CLM-4
-- ==== 回填事实(INV-7/INV-8====
BACKFILL_AT TIMESTAMP(6) WITH TIME ZONE, -- 非空 = 处理标记已确认写入
BACKFILL_NEXT_AT TIMESTAMP(6) WITH TIME ZONE, -- 非空 = 还欠一次回填;与终态同语句写下
BACKFILL_ATTEMPTS INT NOT NULL DEFAULT 0,
BACKFILL_ERROR VARCHAR(512),
BACKFILL_ABANDONED_AT TIMESTAMP(6) WITH TIME ZONE, -- 非空 = 已停止自动重试;**不等于**标记已确认(C-8、C-16)
BACKFILL_ABANDONED_REASON VARCHAR(64), -- MISSING_ROW(确定性)/ TRANSIENT_DEADLINE(暂时性耗尽 R
CONSTRAINT uk_proc_identity UNIQUE (IDENTITY_KEY)
);
CREATE INDEX idx_proc_head ON PROC_STATE (STATE, MSG_ID); -- 主泵队头查询(严格 FIFO
CREATE INDEX idx_proc_head ON PROC_STATE (STATE, MSG_ID); -- 主泵队头查询(严格 FIFOINV-3
-- 回填扫描:只覆盖仍需自动回填的行;按 (ATTEMPTS, MSG_ID) 轮转,避免最旧失败行长期占满批次。
CREATE INDEX idx_proc_backfill_due ON PROC_STATE (BACKFILL_ATTEMPTS, MSG_ID)
WHERE BACKFILL_AT IS NULL AND BACKFILL_ABANDONED_AT IS NULL;
-- ③ 航班当前态主行:一行一 FLID(决策层权威;展示视图是投影,不是权威 §3.3)
-- ③ 消费水位:全表只有一行。W 只随新 ID 成功入队推进、只增不减,遇空洞即停;
-- 入队与水位推进同事务(INV-2),因此不存在「水位已推进、消息未入队」的持久化状态。
-- HOLE_SINCE 持久化空洞观测时刻,进程重启不丢计时;老化阈值取
-- PARAM:msgx.pipeline.max-commit-delay,超期只放行空洞本身、不越过任何已存在的行。
CREATE TABLE INBOX_CURSOR (
CURSOR_ID INT NOT NULL PRIMARY KEY, -- 固定为 1
COMMITTED_UP_TO BIGINT NOT NULL, -- 水位 W:到哪个 ID 为止已全部读进自有库
HOLE_SINCE TIMESTAMP(6) WITH TIME ZONE, -- 后续缺号最早被发现的时间;不缺号时为 NULL
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
SEEDED_AT TIMESTAMP(6) WITH TIME ZONE -- 记录「已按 PARAM:msgx.pipeline.cutover-watermark 播种」这一事实;
-- 为 NULL **不等于**从未消费——已有库新增列后同样为 NULL
);
-- 初值 W=0:首轮把信箱现存行全部重新读一遍,重复登记不会建出第二行。
INSERT INTO INBOX_CURSOR (CURSOR_ID, COMMITTED_UP_TO, HOLE_SINCE, UPDATED_AT) VALUES (1, 0, NULL, now());
-- ④ 航班当前态主行:一行一 FLID(决策层权威;展示视图是投影,不是权威,INV-11)
CREATE TABLE FLIGHT_SCHD (
FLID VARCHAR(32) NOT NULL PRIMARY KEY, -- AODB 实例 IDNumber(1-12)SIS §3.16.2
OPERATION_DAY DATE NULL, -- 运营保障日;一经确定不可变(§3.5);NULL=尚未被快照收录
STATE VARCHAR(8) NOT NULL, -- ACTIVE/DELETED(§3.1,无第三态)
STATE_VERSION BIGINT NOT NULL DEFAULT 0, -- 每次成功写入 +1(§4
FLID VARCHAR(32) NOT NULL PRIMARY KEY, -- AODB 实例 IDNumber(1-12));不得由航班号或资源号推断
OPERATION_DAY DATE NULL, -- 运营保障日:未由日计划收录时为 NULL;非空后不可变(INV-12
STATE VARCHAR(8) NOT NULL, -- ACTIVE/DELETED,无第三态;删除只由 FDEL 或受控历史清理触发(INV-15
STATE_VERSION BIGINT NOT NULL DEFAULT 0, -- 每次成功写入 +1,重复消息不重复推进(INV-13
LAST_MSG_ID BIGINT NULL, -- 最近一次成功写入的消息 ID
-- ==== SCHD.FLTR 标量字段(保持 AODB 字符串原样;缺失语义由处理层决定,§5.4====
-- ==== SCHD.FLTR 标量字段(保持 AODB 字符串原样;未携带不隐式清空,INV-14====
ALCD VARCHAR(64) NULL, -- 航空公司代码
ALSC VARCHAR(64) NULL, -- 航空公司简称
FLNO VARCHAR(64) NULL, -- 航班号(展示用,不参与身份判定 §3.1
FLNO VARCHAR(64) NULL, -- 航班号(展示用,不参与身份判定)
MVIN VARCHAR(64) NULL, -- 进离港标识(A/D
SODT VARCHAR(64) NULL, -- 计划运行时间(ddMMMyyHHmmOPERATION_DAY 计算源 §3.5
SODT VARCHAR(64) NULL, -- 计划运行时间(ddMMMyyHHmmOPERATION_DAY 的推导源
FLTY VARCHAR(64) NULL, -- 航班类型
FLIN VARCHAR(64) NULL, -- 国内/国际/混合
ACFT VARCHAR(64) NULL, -- 机型
RENO VARCHAR(64) NULL, -- 机尾号
TAOP VARCHAR(64) NULL, -- 过站实际承运人代码(§3.4过站关联,非代码共享)
TAOP VARCHAR(64) NULL, -- 过站实际承运人代码(过站关联,非代码共享)
TAFL VARCHAR(64) NULL, -- 过站实际承运航班号
TAID VARCHAR(64) NULL, -- 过站关联航班 FLID
TRML VARCHAR(64) NULL, -- 航站楼
MAXP VARCHAR(64) NULL, -- 最大旅客数
CSOP VARCHAR(64) NULL, -- 共享承运人代码(§3.4
CSOP VARCHAR(64) NULL, -- 共享承运人代码
CSFT VARCHAR(64) NULL, -- 共享航班号
MAID VARCHAR(32) NULL, -- 共享主航班 FLID
MAID VARCHAR(32) NULL, -- 共享主航班 FLID:主/共享关系的事实来源;MAFL 由它派生(INV-21、INV-22
ESTT VARCHAR(64) NULL, -- 预计时间
ACTT VARCHAR(64) NULL, -- 实际时间
STND VARCHAR(64) NULL, -- 备降站/机位
PHAG VARCHAR(64) NULL, -- 地服代理(值机)
CNCL VARCHAR(64) NULL, -- 取消时间(§8.1 历史判定依据
CNCL VARCHAR(64) NULL, -- 取消时间;受控历史清理的判定依据之一(INV-15、INV-18
REMC VARCHAR(256) NULL, -- 备注
BOTM VARCHAR(64) NULL, -- 摆渡车时间
LACL VARCHAR(64) NULL, -- 行李确认时间
@@ -87,22 +128,23 @@ CREATE TABLE FLIGHT_SCHD (
EXSR VARCHAR(256) NULL, -- 例外原因
FTSS VARCHAR(64) NULL, -- 航班状态
PEDT VARCHAR(64) NULL, -- 前序估计时间
NAAT VARCHAR(64) NULL, -- 到港终态时间(§8.1业务含义待术语表确认 §10
NEAT VARCHAR(64) NULL, -- 离港终态时间(§8.1业务含义待术语表确认 §10
NAAT VARCHAR(64) NULL, -- 到港终态时间(业务含义待术语表确认)
NEAT VARCHAR(64) NULL, -- 离港终态时间(业务含义待术语表确认)
PADT VARCHAR(64) NULL, -- 旅客登机时间
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
);
CREATE INDEX idx_flight_schd_opday ON FLIGHT_SCHD (OPERATION_DAY);
CREATE INDEX idx_flight_schd_state ON FLIGHT_SCHD (STATE);
-- OPERATION_DAY 不可变的数据库层强化(§7.4:快照 upsert 一律带
-- OPERATION_DAY 不可变INV-12)的库层强化方式:快照 upsert 一律带
-- WHERE OPERATION_DAY IS NULL OR OPERATION_DAY = :day,行级条件更新即满足;
-- 不使用触发器(Oracle/PG 双方言成本)。
-- 资源明细表 ×8 + 路线点表每 FLID 多行;明细集合按组先删后插 §3.3
-- ORDINAL 保留输入顺序,SOURCE_SEQ 只存上游序号 §3.2
-- 删除一律标记在主行 STATE,明细物理清除只发生在历史归档 §8.2)
-- ④-1 登机门 GTDT
-- 资源明细表 ×8 + 路线点表每 FLID 多行;每次完整状态写入按该 FLID 先删后插,
-- 以完整合并结果为准(INV-14)。ORDINAL 是持久化顺序(从 1 起),SOURCE_SEQ 是上游
-- 序号(允许为空或重复);相同资源号不代表同一条分配,禁止按资源号去重。删除一律
-- 标记在主行 STATE,明细物理清除只发生在受控历史归档(INV-15)。
-- ⑤-1 登机门 GTDT
CREATE TABLE FLIGHT_GATE (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -117,7 +159,7 @@ CREATE TABLE FLIGHT_GATE (
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -2 值机柜台 CKDT
-- -2 值机柜台 CKDT
CREATE TABLE FLIGHT_CHECKIN (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -133,7 +175,7 @@ CREATE TABLE FLIGHT_CHECKIN (
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -3 行李转盘 CLDT
-- -3 行李转盘 CLDT
CREATE TABLE FLIGHT_BELT (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -149,7 +191,7 @@ CREATE TABLE FLIGHT_BELT (
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -4 计划机位 PSDT
-- -4 计划机位 PSDT
CREATE TABLE FLIGHT_STAND_PLAN (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -161,23 +203,23 @@ CREATE TABLE FLIGHT_STAND_PLAN (
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -5 滑槽 CHDT
-- -5 滑槽 CHDT
CREATE TABLE FLIGHT_CHUTE (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
SOURCE_SEQ VARCHAR(64),
CHUT VARCHAR(64),
CHCLS VARCHAR(64),
PCBT VARCHAR(64), -- 计划开始SIS 线格式 PCBT
PCET VARCHAR(64), -- 计划结束PCET
CBTM VARCHAR(64), -- 实际开始CBTM
CETM VARCHAR(64), -- 实际结束CETM
PCBT VARCHAR(64), -- 计划开始
PCET VARCHAR(64), -- 计划结束
CBTM VARCHAR(64), -- 实际开始
CETM VARCHAR(64), -- 实际结束
CHTYP VARCHAR(64),
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -6 延误 DELY(业务上任意时刻仅 1 个有效延误,保留多行能力以无损承接)
-- -6 延误 DELY(业务上任意时刻仅 1 个有效延误,保留多行能力以无损承接)
CREATE TABLE FLIGHT_DELAY (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -190,7 +232,7 @@ CREATE TABLE FLIGHT_DELAY (
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -7 靠撤桥 ABTM(桥号 ABDGA/D 各一条)
-- -7 靠撤桥 ABTM(桥号 ABDGA/D 各一条)
CREATE TABLE FLIGHT_BRIDGE_OP (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -202,7 +244,7 @@ CREATE TABLE FLIGHT_BRIDGE_OP (
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -8 轮挡 CHOT(机位 CHIDON/OFF 各一条)
-- -8 轮挡 CHOT(机位 CHIDON/OFF 各一条)
CREATE TABLE FLIGHT_CHOCK_OP (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -214,7 +256,7 @@ CREATE TABLE FLIGHT_CHOCK_OP (
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
PRIMARY KEY (FLID, ORDINAL)
);
-- -9 路线点 ROUT/ERUT 共用(ROUTE_KIND 区分 §3.210 类集合 9 张表
-- -9 路线点 ROUT/ERUT 共用(ROUTE_KIND 区分两类;主键含该列,避免序号冲突
CREATE TABLE FLIGHT_ROUTE_POINT (
FLID VARCHAR(32) NOT NULL,
ORDINAL INT NOT NULL,
@@ -236,27 +278,33 @@ CREATE INDEX idx_flight_delay_flid ON FLIGHT_DELAY (FLID);
CREATE INDEX idx_flight_bridge_flid ON FLIGHT_BRIDGE_OP (FLID);
CREATE INDEX idx_flight_chock_flid ON FLIGHT_CHOCK_OP (FLID);
-- 统一投递事件 outbox§7.3KAFKA_MSG 只通知变化;KAFKA_SCHD 发整态
-- tombstone 仅在 ACTIVE→DELETED 时与删除同事务登记,投递失败持续重试
-- 统一投递事件 outboxINV-10、INV-17):KAFKA:schd 发整态、KAFKA:msg 只通知变化
-- tombstone 仅在 ACTIVE→DELETED 时与删除同事务登记,投递失败按退避持续重试
-- 目标级全序投递是当前实现,按 FLID 保序见 CLM-7。
CREATE TABLE MSG_EVENT (
EVENT_ID BIGSERIAL PRIMARY KEY,
TARGET VARCHAR(30) NOT NULL, -- KAFKA_MSG / KAFKA_SCHD
PARTITION_KEY VARCHAR(32) NOT NULL, -- 恒为 FLID
EVENT_ID BIGSERIAL PRIMARY KEY, -- 对 KAFKA:msg 是稳定事件身份并决定投递顺序;对 KAFKA:schd 是每次接受 upsert 时替换的写代次
TARGET VARCHAR(30) NOT NULL, -- KAFKA:msg / KAFKA:schd
PARTITION_KEY VARCHAR(32) NOT NULL, -- 当前恒为 FLIDQ4 定案前为假定,C-29
EVENT_TYPE VARCHAR(16) NOT NULL DEFAULT 'UPSERT', -- UPSERT / TOMBSTONE
STATE_VERSION BIGINT NOT NULL, -- 发布时航班版本;聚合按 FLID 取最新(§7.3
PAYLOAD_JSON TEXT NOT NULL, -- TOMBSTONE 时至少含 FLID/STATE_VERSION/DELETED
STATE VARCHAR(16) NOT NULL, -- PENDING/SENT/DEAD
STATE_VERSION BIGINT NOT NULL, -- 发布时航班版本;schd 聚合按 FLID 只进不退
PAYLOAD_JSON TEXT NOT NULL, -- TOMBSTONE 时至少含 FLID/STATE_VERSION/DELETED
STATE VARCHAR(16) NOT NULL, -- PENDING/SENT/DEAD
ATTEMPTS INT NOT NULL DEFAULT 0,
NEXT_ATTEMPT_AT TIMESTAMP(6) WITH TIME ZONE,
ERROR_CLASS VARCHAR(20),
LAST_ERROR VARCHAR(1000),
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
SENT_AT TIMESTAMP(6) WITH TIME ZONE -- 投递确认的同一条 UPDATE 内写入;是保留期判定的唯一基准(G-EVENT-RETENTION
);
CREATE INDEX idx_evt_head ON MSG_EVENT (TARGET, STATE, EVENT_ID); -- 每 target 队头
CREATE INDEX idx_evt_flid ON MSG_EVENT (PARTITION_KEY, STATE_VERSION); -- 同 FLID 未发事件合并
-- KAFKA:schd 按 FLID 单行(只保留最新 STATE_VERSION);KAFKA:msg 仍是多行 append-log,不受此约束。
CREATE UNIQUE INDEX uq_schd_event
ON MSG_EVENT (TARGET, PARTITION_KEY)
WHERE TARGET = 'KAFKA:schd';
-- 请求状态机(§7.1:只有 RESP 完成 RQFD 请求,按(运营日、发送方、请求类型)
-- 匹配最新一条 PENDING同类请求只留一条有效,新请求置旧为 EXPIRED
-- 请求状态机:只有 RESP 完成 RQFD 请求,按(运营日、发送方、请求类型)匹配最新一条
-- 开放请求。同类请求只留一条有效,新请求置旧请求为 EXPIRED。登记、超时与应答匹配
-- 尚未实现(G-REQ-TRACK、C-24)。
CREATE TABLE REQ_TRACK (
REQ_ID BIGSERIAL PRIMARY KEY,
REQ_TYPE VARCHAR(20) NOT NULL,
@@ -268,26 +316,14 @@ CREATE TABLE REQ_TRACK (
COMPLETED_AT TIMESTAMP(6) WITH TIME ZONE,
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
);
CREATE INDEX idx_req_open ON REQ_TRACK (REQ_TYPE, OPERATION_DAY, SENDER, STATE);
CREATE INDEX idx_req_open ON REQ_TRACK (REQ_TYPE, OPERATION_DAY, SENDER, STATE); -- 仍服务含关闭态的查询
-- 开放态(PENDING/SENT)内 (REQ_TYPE, OPERATION_DAY, SENDER) 唯一;关闭态行可并存。
CREATE UNIQUE INDEX uq_req_open
ON REQ_TRACK (REQ_TYPE, OPERATION_DAY, SENDER)
WHERE STATE IN ('PENDING', 'SENT');
-- ⑦ 共享信箱回填补偿待办(§7.2:提交后回填;回填失败不得把 SUCCEEDED 改回 FAILED
-- 目标形态 = 业务事务内预登记,消除「提交后写待办」的崩溃窗口,§10 当前偏差)
CREATE TABLE BACKFILL_TODO (
MSG_ID BIGINT NOT NULL PRIMARY KEY,
SNDR VARCHAR(64) NOT NULL,
TYPE VARCHAR(32) NOT NULL,
STYP VARCHAR(32),
SEQN BIGINT,
ATTEMPTS INT NOT NULL DEFAULT 0,
NEXT_ATTEMPT_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
LAST_ERROR VARCHAR(512),
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
);
CREATE INDEX idx_backfill_todo_due ON BACKFILL_TODO (NEXT_ATTEMPT_AT);
-- ⑧ SCHD 快照留痕(§5.5):事务外追加,只追加留痕、不参与决策;一行=一次尝试,重放也记;
-- RESULT 与 FLAGS 分列(可「成功且告警」);写失败只记指标;保留 90 天,按 (SCOPE_END, RECV_AT) 清理
-- ⑧ SCHD 快照留痕:事务外追加,只追加留痕、不参与决策;一行=一次尝试,重放也记。
-- RESULT 与 FLAGS 分列(可「成功且告警」);写失败只记指标。
CREATE TABLE SCHD_SNAP_LOG (
LOG_ID BIGSERIAL PRIMARY KEY,
MSG_ID BIGINT NOT NULL,
@@ -302,5 +338,5 @@ CREATE TABLE SCHD_SNAP_LOG (
ARCHIVE_KEY VARCHAR(200), -- 原文归档引用(证据层,尚未交付)
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
);
CREATE INDEX idx_snaplog_cleanup ON SCHD_SNAP_LOG (SCOPE_END, RECV_AT);
CREATE INDEX idx_snaplog_cleanup ON SCHD_SNAP_LOG (SCOPE_END, RECV_AT); -- 保留期清理扫描
CREATE INDEX idx_snaplog_msg ON SCHD_SNAP_LOG (MSG_ID);