feat: add durable result journal and subscription delivery core
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
-- 结果日志按命名空间串行分配序号,与来源状态事件同事务提交;不使用自增 ID 推断提交顺序。
|
||||
-- 禁止外键;来源事件、队列和订阅归属由服务端事务校验。
|
||||
CREATE TABLE orbit_event_streams (
|
||||
namespace_id BINARY(16) NOT NULL COMMENT '结果流所属命名空间;主键同时作为该流序号分配的事务锁',
|
||||
last_sequence BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已分配结果序号;从1开始,与结果日志同事务提交,回滚不消耗序号',
|
||||
retained_from_sequence BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '最早保留序号;首版不清理结果日志,固定为1,供以后安全清理校验',
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一UTC,精度微秒',
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后分配序号时间,统一UTC,不代替序号',
|
||||
PRIMARY KEY(namespace_id),
|
||||
CONSTRAINT ck_event_stream_range CHECK (retained_from_sequence>0 AND retained_from_sequence-1<=last_sequence)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='命名空间结果流的提交序号和保留边界';
|
||||
|
||||
CREATE TABLE orbit_result_events (
|
||||
namespace_id BINARY(16) NOT NULL COMMENT '结果所属命名空间,参与主键与服务端关联校验',
|
||||
id BINARY(16) NOT NULL COMMENT '与来源orbit_events记录使用相同标识;跨订阅消费去重依据',
|
||||
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '不可变记录版本,固定为1',
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一UTC,精度微秒',
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '不可变记录的初始写入时间,统一UTC',
|
||||
sequence BIGINT UNSIGNED NOT NULL COMMENT '命名空间内事务分配的结果序号;较小序号必先提交或整体回滚',
|
||||
queue_id BINARY(16) NOT NULL COMMENT '来源任务的队列标识;订阅过滤和授权按该队列检查',
|
||||
snapshot MEDIUMTEXT NOT NULL COMMENT '版本化结果快照JSON文本,保留数值精度,不含任务输入和租约秘密',
|
||||
PRIMARY KEY(namespace_id,id),
|
||||
UNIQUE KEY uq_result_sequence(namespace_id,sequence),
|
||||
KEY ix_result_queue_sequence(namespace_id,queue_id,sequence),
|
||||
CONSTRAINT ck_result_event CHECK (revision=1 AND sequence>0 AND JSON_VALID(snapshot))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='不可变任务结果日志;与任务状态及来源事件一起提交';
|
||||
|
||||
CREATE TRIGGER orbit_result_events_immutable BEFORE UPDATE ON orbit_result_events FOR EACH ROW
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='result events are immutable';
|
||||
|
||||
ALTER TABLE orbit_subscriptions
|
||||
MODIFY COLUMN filter JSON NOT NULL COMMENT '创建时冻结的结果事件类型数组JSON,不允许修改以免漏消费',
|
||||
MODIFY COLUMN enabled BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用新交付;暂停保留积压和在途结果,仍可接受有效确认',
|
||||
ADD COLUMN queue_id BINARY(16) NULL COMMENT '冻结订阅队列;历史占位配置为空且不可消费,须通过新接口创建有效订阅',
|
||||
ADD COLUMN cursor_sequence BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已扫描并可靠创建交付记录的结果序号;不是消费者确认位置',
|
||||
ADD COLUMN pending_count INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已物化但未确认数量,包含等待、租约中和耗尽次数的交付',
|
||||
ADD COLUMN max_pending INT UNSIGNED NOT NULL DEFAULT 100 COMMENT '未确认交付上限,1至1000;达到后暂停物化但保留来源结果',
|
||||
ADD COLUMN max_attempts INT UNSIGNED NOT NULL DEFAULT 20 COMMENT '每条新交付的初始发送次数上限,1至100,不包含任务执行业务次数',
|
||||
ADD CONSTRAINT ck_subscription_window CHECK (max_pending BETWEEN 1 AND 1000 AND max_attempts BETWEEN 1 AND 100 AND pending_count<=max_pending);
|
||||
|
||||
-- 旧配置没有公开消费协议和队列授权绑定,保留原记录但不自动开启消费。
|
||||
UPDATE orbit_subscriptions SET enabled=FALSE;
|
||||
|
||||
ALTER TABLE orbit_deliveries
|
||||
ADD COLUMN attempt_budget INT UNSIGNED NOT NULL DEFAULT 20 COMMENT '累计允许交付次数,人工追加预算不重置已使用次数和租约代次',
|
||||
ADD COLUMN token_digest BINARY(32) NULL COMMENT '最近一次交付秘密的SHA256摘要;从未发出或历史占位记录为空,确认后保留以核对重复确认',
|
||||
ADD KEY ix_delivery_subscription_due(namespace_id,subscription_id,state,available_at,id),
|
||||
ADD KEY ix_delivery_subscription_lease(namespace_id,subscription_id,state,lease_until,id);
|
||||
|
||||
UPDATE orbit_deliveries SET attempt_budget=GREATEST(attempt_budget,attempts);
|
||||
ALTER TABLE orbit_deliveries ADD CONSTRAINT ck_delivery_budget CHECK (attempts<=attempt_budget AND attempt_budget>0);
|
||||
Reference in New Issue
Block a user