Files
orbit/internal/storage/mysql/baseline.sql

976 lines
102 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- Orbit fresh-install baseline, generated from migration version 33.
-- This file intentionally contains no database-level relation constraints.
CREATE TABLE `orbit_application_resources` (
`application_id` binary(16) NOT NULL COMMENT '所属应用标识及主键,跨命名空间共享额度',
`revision` bigint unsigned NOT NULL DEFAULT '1' COMMENT '配置乐观版本,用量变化不增加版本',
`created_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,UTC 微秒',
`updated_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后配置更新时间,UTC 微秒',
`max_unfinished_tasks` int unsigned NOT NULL DEFAULT '1000000' COMMENT '应用未终结任务上限,降额保留已有任务',
`unfinished_tasks` bigint unsigned NOT NULL DEFAULT '0' COMMENT '等待、预占、运行及待核查任务总数,重试不重复计数',
`max_concurrency` int unsigned NOT NULL DEFAULT '10000' COMMENT '预占与运行尝试总上限,降额不撤销已有尝试',
`active_attempts` bigint unsigned NOT NULL DEFAULT '0' COMMENT '当前预占与运行尝试总数,结果确认或到期恢复释放',
`pending_starts` bigint unsigned NOT NULL DEFAULT '0' COMMENT '已预占但未开始尝试数,包含在活跃尝试中',
`rate_per_second` int unsigned NOT NULL DEFAULT '100000' COMMENT '一秒固定窗口内开始授权上限,不是业务请求速率',
`start_window_until` datetime(6) DEFAULT NULL COMMENT '数据库时间的一秒窗口结束时刻,空表示尚未建立窗口',
`starts_in_window` int unsigned NOT NULL DEFAULT '0' COMMENT '窗口中已确认的开始次数,重复回执不计数',
PRIMARY KEY (`application_id`),
CONSTRAINT `ck_app_resources_limits` CHECK (((`max_unfinished_tasks` > 0) and (`max_concurrency` > 0) and (`rate_per_second` > 0))),
CONSTRAINT `ck_app_resources_pending` CHECK ((`pending_starts` <= `active_attempts`)),
CONSTRAINT `ck_app_resources_revision` CHECK ((`revision` > 0)),
CONSTRAINT `ck_app_resources_window` CHECK (((`start_window_until` is not null) or (`starts_in_window` = 0)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='应用跨命名空间共享额度与持久化用量,无数据库外键';
CREATE TABLE `orbit_applications` (
`id` binary(16) NOT NULL COMMENT '应用标识,全局唯一',
`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;不能代替并发版本',
`name` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用;关闭后拒绝相应的新接入或新操作',
PRIMARY KEY (`id`),
UNIQUE KEY `uq_application_name` (`name`),
CONSTRAINT `ck_orbit_applications_0` CHECK ((`revision` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='接入应用,承载通用应用身份与启停配置';
CREATE TABLE `orbit_audit_events` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`operation_id` binary(16) NOT NULL COMMENT '管理操作的稳定身份,重复操作必须保留同一身份',
`actor_id` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '经认证的操作主体标识,不能直接信任请求自报值',
`action` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '执行的管理动作,例如暂停、取消或核查',
`resource_kind` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '关联资源类型;多态关联需要服务层额外校验',
`resource_id` binary(16) NOT NULL COMMENT '关联资源标识,不能单独作为访问授权依据',
`reason` varchar(1024) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '操作原因或处理说明,需要保留审计信息',
`before` json DEFAULT NULL COMMENT '操作前的受控摘要 JSON,须脱敏',
`after` json DEFAULT NULL COMMENT '操作后的受控摘要 JSON,须脱敏',
`evidence_ref` varchar(512) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '业务核查证据的引用;为空表示没有附加引用',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_audit_operation` (`namespace_id`,`operation_id`),
KEY `ix_audit_resource` (`namespace_id`,`resource_kind`,`resource_id`,`created_at`,`id`),
CONSTRAINT `ck_orbit_audit_events_0` CHECK ((`revision` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='不可改写的管理审计,保留操作身份、原因和变更摘要';
CREATE TRIGGER `trg_audit_event_immutable` BEFORE UPDATE ON `orbit_audit_events` FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Audit events are append-only';
CREATE TABLE `orbit_credentials` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`name` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`secret_digest` binary(32) NOT NULL COMMENT '凭据秘密的 SHA-256 摘要,不保存或输出原文',
`secret_key_id` varchar(64) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL COMMENT '当前 Token 密文使用的主密钥标识;空表示尚未保管,主密钥不存数据库',
`secret_ciphertext` varbinary(1024) DEFAULT NULL COMMENT '当前 Token 的 AES-256-GCM nonce 与认证密文;空表示旧凭据仅存摘要',
`previous_secret_digest` binary(32) DEFAULT NULL COMMENT '上一代秘密的 SHA-256 摘要;为空表示无过渡令牌,不保存原文',
`previous_valid_until` datetime(6) DEFAULT NULL COMMENT '上一代令牌过渡截止,UTC;不晚于其原到期时间,与旧摘要同时为空或非空',
`permissions` json NOT NULL COMMENT '授权范围的 JSON 快照,必须由服务端解释和校验',
`expires_at` datetime(6) DEFAULT NULL COMMENT '凭据过期时间,统一 UTC;为空表示没有配置到期时间',
`revoked_at` datetime(6) DEFAULT NULL COMMENT '撤销时间;为空表示尚未撤销',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_credential_name` (`namespace_id`,`name`),
CONSTRAINT `ck_orbit_credentials_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_credential_ciphertext` CHECK ((secret_key_id IS NULL AND secret_ciphertext IS NULL) OR (secret_key_id IS NOT NULL AND secret_ciphertext IS NOT NULL AND LENGTH(secret_key_id)>0 AND LENGTH(secret_ciphertext)>=28)),
CONSTRAINT `ck_credential_overlap` CHECK ((previous_secret_digest IS NULL AND previous_valid_until IS NULL) OR (previous_secret_digest IS NOT NULL AND previous_valid_until IS NOT NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='命名空间凭据、认证摘要、授权范围及可选的当前 Token 密文';
CREATE TABLE `orbit_deliveries` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`subscription_id` binary(16) NOT NULL COMMENT '目标订阅标识',
`event_id` binary(16) NOT NULL COMMENT '来源持久化事件标识,用于消费去重',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'PENDING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`available_at` datetime(6) NOT NULL COMMENT '该事件最早允许再次交付的时间,统一 UTC',
`lease_owner` binary(16) DEFAULT NULL COMMENT '租约持有者标识;未持有租约时为空',
`lease_epoch` bigint unsigned NOT NULL DEFAULT '0' COMMENT '递增的执行或消费代次,用于隔离旧授权',
`lease_until` datetime(6) DEFAULT NULL COMMENT '交付租约截止时间;没有交付租约时为空',
`attempts` int unsigned NOT NULL DEFAULT '0' COMMENT '已产生的交付尝试次数,不等同于业务执行次数',
`acknowledged_at` datetime(6) DEFAULT NULL COMMENT '接收方可靠处理后的确认时间;未确认时为空',
`attempt_budget` int unsigned NOT NULL DEFAULT '20' COMMENT '累计允许交付次数,人工追加预算不重置已使用次数和租约代次',
`token_digest` binary(32) DEFAULT NULL COMMENT '最近一次交付秘密的SHA256摘要;从未发出或历史占位记录为空,确认后保留以核对重复确认',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_delivery_event` (`namespace_id`,`subscription_id`,`event_id`),
KEY `ix_delivery_due` (`namespace_id`,`state`,`available_at`,`id`),
KEY `fk_orbit_deliveries_2` (`namespace_id`,`event_id`),
KEY `ix_delivery_subscription_due` (`namespace_id`,`subscription_id`,`state`,`available_at`,`id`),
KEY `ix_delivery_subscription_lease` (`namespace_id`,`subscription_id`,`state`,`lease_until`,`id`),
KEY `ix_delivery_history` (`namespace_id`,`subscription_id`,`created_at`,`id`),
KEY `ix_delivery_state_history` (`namespace_id`,`subscription_id`,`state`,`created_at`,`id`),
KEY `ix_delivery_observe_state_available` (`state`,`available_at`,`id`),
CONSTRAINT `ck_delivery_budget` CHECK (((`attempts` <= `attempt_budget`) and (`attempt_budget` > 0))),
CONSTRAINT `ck_orbit_deliveries_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_orbit_deliveries_1` CHECK ((`state` in (_utf8mb4'PENDING',_utf8mb4'LEASED',_utf8mb4'ACKED',_utf8mb4'EXPIRED'))),
CONSTRAINT `ck_orbit_deliveries_2` CHECK ((((`state` = _utf8mb4'LEASED') and (`lease_owner` is not null) and (`lease_until` is not null)) or ((`state` <> _utf8mb4'LEASED') and (`lease_owner` is null) and (`lease_until` is null))))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='单个事件向一个订阅的可靠交付记录';
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_events` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`aggregate_kind` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '产生事件的聚合类型,例如任务或流程',
`aggregate_id` binary(16) NOT NULL COMMENT '产生事件的聚合标识',
`aggregate_revision` bigint unsigned NOT NULL COMMENT '来源聚合的状态版本,用于去重与迟到事件判断',
`type` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '事件或信号的稳定类型标识',
`payload` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`occurred_at` datetime(6) NOT NULL COMMENT '事件发生时间,统一 UTC',
`workflow_id` binary(16) GENERATED ALWAYS AS ((case when (`aggregate_kind` = _utf8mb4'workflow') then `aggregate_id` when ((`aggregate_kind` in (_utf8mb4'workflow_step',_utf8mb4'workflow_signal')) and (json_type(json_extract(`payload`,_utf8mb4'$.workflow_id')) = _utf8mb4'STRING') and (length(json_unquote(json_extract(`payload`,_utf8mb4'$.workflow_id'))) = 32) and (length(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(lower(json_unquote(json_extract(`payload`,_utf8mb4'$.workflow_id'))),_utf8mb4'0',_utf8mb4''),_utf8mb4'1',_utf8mb4''),_utf8mb4'2',_utf8mb4''),_utf8mb4'3',_utf8mb4''),_utf8mb4'4',_utf8mb4''),_utf8mb4'5',_utf8mb4''),_utf8mb4'6',_utf8mb4''),_utf8mb4'7',_utf8mb4''),_utf8mb4'8',_utf8mb4''),_utf8mb4'9',_utf8mb4''),_utf8mb4'a',_utf8mb4''),_utf8mb4'b',_utf8mb4''),_utf8mb4'c',_utf8mb4''),_utf8mb4'd',_utf8mb4''),_utf8mb4'e',_utf8mb4''),_utf8mb4'f',_utf8mb4'')) = 0)) then unhex(json_unquote(json_extract(`payload`,_utf8mb4'$.workflow_id'))) else NULL end)) STORED COMMENT '从不可变事件派生的流程查询标识;无范围或非法历史值为空,读取仍核对父资源,不能作为授权依据',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_event_revision` (`namespace_id`,`aggregate_kind`,`aggregate_id`,`aggregate_revision`,`type`),
KEY `ix_event_workflow_history` (`namespace_id`,`workflow_id`,`occurred_at`,`id`),
KEY `ix_event_observe_type_occurred` (`type`,`occurred_at`,`id`),
CONSTRAINT `ck_orbit_events_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_orbit_events_1` CHECK ((`aggregate_revision` > 0)),
CONSTRAINT `ck_orbit_events_payload_json` CHECK (((`payload` is null) or json_valid(`payload`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='追加保存的状态事件,供外部订阅或内部流程接续';
CREATE TRIGGER `trg_event_immutable` BEFORE UPDATE ON `orbit_events` FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'State events are append-only';
CREATE TABLE `orbit_idempotency_keys` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`operation` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '稳定操作类型,用于区分不同接口的幂等作用域',
`scope_key` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT '' COMMENT '资源作用域标识;空字符串表示当前操作的默认作用域',
`key_digest` binary(32) NOT NULL COMMENT '稳定幂等键或资源键的 SHA-256 摘要',
`request_digest` binary(32) NOT NULL COMMENT '规范化请求语义的 SHA-256 摘要,用于识别同键不同内容',
`resource_kind` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '关联资源类型;多态关联需要服务层额外校验',
`resource_id` binary(16) NOT NULL COMMENT '关联资源标识,不能单独作为访问授权依据',
`response` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`expires_at` datetime(6) NOT NULL COMMENT '幂等保留截止时间,不应短于约定的重发与恢复窗口',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_idempotency_scope` (`namespace_id`,`operation`,`scope_key`,`key_digest`),
KEY `ix_idempotency_expiry` (`expires_at`,`namespace_id`,`id`),
CONSTRAINT `ck_orbit_idempotency_keys_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_orbit_idempotency_keys_response_json` CHECK (((`response` is null) or json_valid(`response`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='请求幂等记录,关联语义摘要与首次受理响应';
CREATE TABLE `orbit_namespaces` (
`id` binary(16) NOT NULL COMMENT '命名空间标识,全局唯一',
`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;不能代替并发版本',
`application_id` binary(16) NOT NULL COMMENT '所属应用标识',
`name` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`environment` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '环境标识,用于区分开发、测试和生产等隔离范围',
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用;关闭后拒绝相应的新接入或新操作',
PRIMARY KEY (`id`),
UNIQUE KEY `uq_namespace_name` (`application_id`,`environment`,`name`),
CONSTRAINT `ck_orbit_namespaces_0` CHECK ((`revision` > 0))
) 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 COLLATE utf8mb4_0900_as_cs 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';
CREATE TABLE `orbit_subscriptions` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`name` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`credential_id` binary(16) NOT NULL COMMENT '关联的命名空间凭据标识',
`filter` json NOT NULL COMMENT '创建时冻结的结果事件类型数组JSON,不允许修改以免漏消费',
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用新交付;暂停保留积压和在途结果,仍可接受有效确认',
`queue_id` binary(16) DEFAULT NULL COMMENT '冻结订阅队列;历史占位配置为空且不可消费,须通过新接口创建有效订阅',
`cursor_sequence` bigint unsigned NOT NULL DEFAULT '0' COMMENT '已扫描并可靠创建交付记录的结果序号;不是消费者确认位置',
`pending_count` int unsigned NOT NULL DEFAULT '0' COMMENT '已物化但未确认数量,包含等待、租约中和耗尽次数的交付',
`max_pending` int unsigned NOT NULL DEFAULT '100' COMMENT '未确认交付上限,1至1000;达到后暂停物化但保留来源结果',
`max_attempts` int unsigned NOT NULL DEFAULT '20' COMMENT '每条新交付的初始发送次数上限,1至100,不包含任务执行业务次数',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_subscription_name` (`namespace_id`,`name`),
KEY `fk_orbit_subscriptions_1` (`namespace_id`,`credential_id`),
CONSTRAINT `ck_orbit_subscriptions_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_subscription_window` CHECK (((`max_pending` between 1 and 1000) and (`max_attempts` between 1 and 100) and (`pending_count` <= `max_pending`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='事件订阅配置,绑定授权凭据及过滤规则';
CREATE TABLE `pulse_attempt_evidence` (
`namespace_id` binary(16) NOT NULL COMMENT '证据所属命名空间,与尝试一致',
`id` binary(16) NOT NULL COMMENT '证据记录标识',
`revision` bigint unsigned NOT NULL DEFAULT '1' COMMENT '记录版本;证据追加保存,不覆盖',
`created_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '首次收到证据的数据库时间,UTC',
`updated_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '写入时间,追加记录与创建时间相同',
`attempt_id` binary(16) NOT NULL COMMENT '证据所属执行尝试',
`message_id` binary(16) NOT NULL COMMENT '结果消息身份,重报保持不变',
`outcome` varchar(16) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT 'Worker 声明的结果:SUCCEEDED、FAILED、UNKNOWN 或已确认停止且本次无遗留效果的 CANCELLED',
`error_code` varchar(64) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '稳定错误分类;无错误时为空,不保存原始异常正文',
`payload` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '结果或证据引用的 JSON 文本,保留精确数字',
`request_digest` binary(32) NOT NULL COMMENT '结果语义摘要,排除会话与秘密',
`reason` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '证据未改写权威结果的原因:LEASE_LOST、NOT_STARTED 或 RESULT_CONFLICT',
`retryable` tinyint(1) NOT NULL DEFAULT '0' COMMENT '原失败报告的安全重试声明,证据本身不触发重试',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_attempt_evidence_message` (`namespace_id`,`attempt_id`,`message_id`),
KEY `ix_evidence_history` (`namespace_id`,`attempt_id`,`created_at`,`id`) COMMENT '执行证据按尝试和时间稳定分页',
CONSTRAINT `ck_attempt_evidence_json` CHECK (json_valid(`payload`)),
CONSTRAINT `ck_attempt_evidence_outcome` CHECK ((`outcome` in (_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'UNKNOWN',_utf8mb4'CANCELLED'))),
CONSTRAINT `ck_attempt_evidence_reason` CHECK ((`reason` in (_utf8mb4'LEASE_LOST',_utf8mb4'NOT_STARTED',_utf8mb4'RESULT_CONFLICT'))),
CONSTRAINT `ck_attempt_evidence_revision` CHECK ((`revision` > 0)),
CONSTRAINT `ck_evidence_retryable` CHECK (((`retryable` in (0,1)) and ((`retryable` = false) or (`outcome` = _utf8mb4'FAILED'))))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='迟到与冲突结果的追加证据,不自动改变任务终态';
CREATE TRIGGER `immutable_attempt_evidence` BEFORE UPDATE ON `pulse_attempt_evidence` FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='attempt evidence is immutable';
CREATE TABLE `pulse_attempt_receipts` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`attempt_id` binary(16) NOT NULL COMMENT '关联的独立执行尝试标识',
`operation` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '稳定操作类型,用于区分不同接口的幂等作用域',
`message_id` binary(16) NOT NULL COMMENT '可靠操作消息身份,跨重连重报时保持稳定',
`request_digest` binary(32) NOT NULL COMMENT '规范化请求语义的 SHA-256 摘要,用于识别同键不同内容',
`response` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`expires_at` datetime(6) NOT NULL COMMENT '过期时间,统一 UTC;到期后的行为由对应资源策略决定',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_attempt_receipt` (`namespace_id`,`attempt_id`,`operation`,`message_id`),
KEY `ix_result_receipt` (`namespace_id`,`attempt_id`,`operation`,`request_digest`) COMMENT '同一结果换消息身份重报时读取原始已应用回执',
CONSTRAINT `ck_pulse_attempt_receipts_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_attempt_receipts_response_json` CHECK (((`response` is null) or json_valid(`response`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='执行操作的持久化确认,用于断线或确认丢失后的幂等补取';
CREATE TABLE `pulse_attempts` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`task_id` binary(16) NOT NULL COMMENT '关联的 Pulse 任务标识',
`epoch` bigint unsigned NOT NULL COMMENT '该任务的授权代次,同一任务内唯一且递增',
`session_id` binary(16) NOT NULL COMMENT '当前执行归属的 Worker 会话标识',
`token_digest` binary(32) NOT NULL COMMENT '执行秘密令牌的 SHA-256 摘要,不输出原令牌',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'LEASED' COMMENT '当前执行尝试的状态,不能代替整个任务的状态',
`lease_until` datetime(6) NOT NULL COMMENT '已确认的租约截止时间,必须用数据库时间核验',
`authorized_at` datetime(6) DEFAULT NULL COMMENT '平台允许处理器开始的时间;不能证明业务副作用已经发生',
`ended_at` datetime(6) DEFAULT NULL COMMENT '本次尝试结束时间;尚未结束时为空',
`error_code` varchar(64) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '稳定错误分类,供恢复策略判断;不得写入敏感原始错误',
`result` mediumtext COLLATE utf8mb4_0900_as_cs COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`result_digest` binary(32) DEFAULT NULL COMMENT '结果语义摘要,用于识别确认重报与冲突结果',
`retryable` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Worker 明确失败时声明可安全重试,不用于未知效果或证明实际已安排重试',
`concurrency_token` bigint unsigned NOT NULL DEFAULT '0' COMMENT '当前资源键的单调许可序号,零表示未启用;重连不变,新尝试递增,不可单独证明执行授权',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_attempt_epoch` (`namespace_id`,`task_id`,`epoch`),
UNIQUE KEY `uq_attempt_task_id` (`namespace_id`,`task_id`,`id`),
KEY `ix_attempt_session_state` (`namespace_id`,`session_id`,`state`),
CONSTRAINT `ck_attempt_lifecycle` CHECK ((((`state` in (_utf8mb4'LEASED',_utf8mb4'RUNNING')) and (`ended_at` is null)) or ((`state` not in (_utf8mb4'LEASED',_utf8mb4'RUNNING')) and (`ended_at` is not null)))),
CONSTRAINT `ck_attempt_retryable` CHECK (((`retryable` in (0,1)) and ((`retryable` = false) or (`state` = _utf8mb4'FAILED')))),
CONSTRAINT `ck_attempt_start` CHECK ((((`state` = _utf8mb4'LEASED') and (`authorized_at` is null)) or ((`state` = _utf8mb4'RUNNING') and (`authorized_at` is not null)) or (`state` not in (_utf8mb4'LEASED',_utf8mb4'RUNNING')))),
CONSTRAINT `ck_pulse_attempts_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_attempts_1` CHECK ((`state` in (_utf8mb4'LEASED',_utf8mb4'RUNNING',_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED',_utf8mb4'EXPIRED',_utf8mb4'UNKNOWN'))),
CONSTRAINT `ck_pulse_attempts_2` CHECK ((`epoch` > 0)),
CONSTRAINT `ck_pulse_attempts_result_json` CHECK (((`result` is null) or json_valid(`result`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次任务执行尝试,保存租约、授权代次与独立结果';
CREATE TABLE `pulse_concurrency_limits` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`scope_key` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '资源作用域标识;空字符串表示当前操作的默认作用域',
`key_digest` binary(32) NOT NULL COMMENT '稳定幂等键或资源键的 SHA-256 摘要',
`max_permits` int unsigned NOT NULL COMMENT '该共享资源允许占用的许可上限',
`used_permits` int unsigned NOT NULL DEFAULT '0' COMMENT '已占用的有效许可数,必须与许可记录同事务维护',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_limit_key` (`namespace_id`,`scope_key`,`key_digest`),
CONSTRAINT `ck_pulse_concurrency_limits_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_concurrency_limits_1` CHECK (((`max_permits` > 0) and (`used_permits` <= `max_permits`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='跨节点共享的并发限制,实际额度更新必须处于事务内';
CREATE TABLE `pulse_execution_gates` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`paused` tinyint(1) NOT NULL DEFAULT '0' COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`control_revision` bigint unsigned NOT NULL DEFAULT '1' COMMENT '暂停、继续等控制操作的版本,避免旧操作覆盖新决定',
`reason` varchar(1024) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '操作原因或处理说明,需要保留审计信息',
PRIMARY KEY (`namespace_id`,`id`),
CONSTRAINT `ck_pulse_execution_gates_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_execution_gates_1` CHECK ((`control_revision` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='通用执行门控,协调暂停与新执行授权的竞争';
CREATE TABLE `pulse_permits` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`limit_id` binary(16) NOT NULL COMMENT '关联的并发限制记录标识',
`attempt_id` binary(16) NOT NULL COMMENT '关联的独立执行尝试标识',
`lease_until` datetime(6) NOT NULL COMMENT '已确认的租约截止时间,必须用数据库时间核验',
`released_at` datetime(6) DEFAULT NULL COMMENT '许可释放时间;为空表示尚未记录释放',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_permit_attempt` (`namespace_id`,`limit_id`,`attempt_id`),
KEY `ix_permit_expiry` (`released_at`,`lease_until`,`namespace_id`,`id`),
KEY `fk_pulse_permits_2` (`namespace_id`,`attempt_id`),
CONSTRAINT `ck_pulse_permits_0` CHECK ((`revision` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次执行尝试占用的并发许可及释放历史';
CREATE TABLE `pulse_queues` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`name` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`paused` tinyint(1) NOT NULL DEFAULT '0' COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`max_concurrency` int unsigned NOT NULL COMMENT '允许同时持有的有效执行许可上限,必须大于零',
`rate_per_second` int unsigned NOT NULL COMMENT '每秒新执行的速率配置;实际限流由共享协调逻辑落实',
`policy` json NOT NULL COMMENT '队列资源与执行配置的 JSON 文档',
`max_unfinished_tasks` int unsigned NOT NULL DEFAULT '100000' COMMENT '队列允许积压的未终结任务上限;降额不删除已有任务',
`unfinished_tasks` bigint unsigned NOT NULL DEFAULT '0' COMMENT '未终结任务数,包含待核查;受理增加、首次进入终态减少,重试不重复计数',
`start_window_until` datetime(6) DEFAULT NULL COMMENT '数据库时间的一秒开始限流窗口结束时刻;空表示尚未开始计数',
`starts_in_window` int unsigned NOT NULL DEFAULT '0' COMMENT '当前窗口已提交的开始授权次数,回执重报不重复计数,降额不清零',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_queue_name` (`namespace_id`,`name`),
CONSTRAINT `ck_pulse_queues_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_queues_1` CHECK ((`max_concurrency` > 0)),
CONSTRAINT `ck_pulse_queues_2` CHECK ((`rate_per_second` > 0)),
CONSTRAINT `ck_queue_start_window` CHECK (((`start_window_until` is not null) or (`starts_in_window` = 0))),
CONSTRAINT `ck_queue_unfinished_limit` CHECK ((`max_unfinished_tasks` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='任务路由与资源控制队列,不要求每个租户单独创建队列';
CREATE TABLE `pulse_schedule_occurrences` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`schedule_id` binary(16) NOT NULL COMMENT '所属调度计划标识',
`schedule_version` bigint unsigned NOT NULL COMMENT '该触发点采用的计划版本号',
`scheduled_at` datetime(6) NOT NULL COMMENT '原计划触发时间,统一 UTC;参与触发去重',
`decision` varchar(16) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '触发处理决定:已触发、已跳过或已合并',
`task_id` binary(16) DEFAULT NULL COMMENT '关联的 Pulse 任务标识',
`covered_until` datetime(6) DEFAULT NULL COMMENT '合并或跳过范围的排除边界,范围为原计划时间至该边界,不包含边界',
`reason` varchar(1024) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '操作原因或处理说明,需要保留审计信息',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_occurrence_time` (`namespace_id`,`schedule_id`,`scheduled_at`),
UNIQUE KEY `uq_occurrence_task` (`namespace_id`,`task_id`),
KEY `fk_pulse_schedule_occurrences_1` (`namespace_id`,`schedule_id`,`schedule_version`),
CONSTRAINT `ck_occurrence_range` CHECK (((`covered_until` is null) or (`covered_until` > `scheduled_at`))),
CONSTRAINT `ck_pulse_schedule_occurrences_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_schedule_occurrences_1` CHECK ((`decision` in (_utf8mb4'FIRED',_utf8mb4'SKIPPED',_utf8mb4'COALESCED'))),
CONSTRAINT `ck_pulse_schedule_occurrences_2` CHECK ((((`decision` = _utf8mb4'SKIPPED') and (`task_id` is null)) or ((`decision` in (_utf8mb4'FIRED',_utf8mb4'COALESCED')) and (`task_id` is not null))))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一个原计划触发点的处理记录,包含触发、跳过或合并决定';
CREATE TABLE `pulse_schedule_versions` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`schedule_id` binary(16) NOT NULL COMMENT '所属调度计划标识',
`version` bigint unsigned NOT NULL COMMENT '不可变发布版本;同版本不同内容必须拒绝',
`effective_at` datetime(6) NOT NULL COMMENT '该计划版本开始生效的时间',
`timezone` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '计划计算使用的 IANA 时区名称',
`specification` json NOT NULL COMMENT '版本化规则定义 JSON;发布后禁止原地修改',
`task_template` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`misfire_policy` varchar(16) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '漏跑策略:跳过、合并或有界补跑',
`overlap_policy` varchar(16) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '上次未完成时的策略:并行、串行或跳过',
`catchup_limit` int unsigned NOT NULL COMMENT '单次漏跑补偿上限;补跑策略必须配置正数',
`catchup_window_ms` bigint unsigned NOT NULL DEFAULT '86400000' COMMENT '未处理触发点最大保留时长,单位毫秒,过旧范围记录跳过',
`grace_ms` bigint unsigned NOT NULL DEFAULT '5000' COMMENT '正常派发允许延迟的毫秒数,超过后按漏跑策略处理',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_schedule_version` (`namespace_id`,`schedule_id`,`version`),
CONSTRAINT `ck_pulse_schedule_versions_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_schedule_versions_1` CHECK ((`version` > 0)),
CONSTRAINT `ck_pulse_schedule_versions_2` CHECK ((`misfire_policy` in (_utf8mb4'SKIP',_utf8mb4'COALESCE',_utf8mb4'CATCH_UP'))),
CONSTRAINT `ck_pulse_schedule_versions_3` CHECK ((`overlap_policy` in (_utf8mb4'PARALLEL',_utf8mb4'SERIAL',_utf8mb4'SKIP'))),
CONSTRAINT `ck_pulse_schedule_versions_4` CHECK (((`misfire_policy` <> _utf8mb4'CATCH_UP') or (`catchup_limit` > 0))),
CONSTRAINT `ck_pulse_schedule_versions_task_template_json` CHECK (((`task_template` is null) or json_valid(`task_template`))),
CONSTRAINT `ck_schedule_window` CHECK (((`catchup_window_ms` between 1000 and 2592000000) and (`grace_ms` between 1000 and 60000) and (`grace_ms` <= `catchup_window_ms`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='已发布的不可变计划版本,记录规则与任务模板';
CREATE TRIGGER `trg_schedule_version_immutable` BEFORE UPDATE ON `pulse_schedule_versions` FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Published schedule versions are immutable';
CREATE TABLE `pulse_schedules` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`name` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`current_version` bigint unsigned NOT NULL COMMENT '当前生效的计划版本号,发布时与版本记录原子更新',
`paused` tinyint(1) NOT NULL DEFAULT '0' COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`next_fire_at` datetime(6) DEFAULT NULL COMMENT '下一计划触发时间;没有后续触发时为空',
`queue_id` binary(16) DEFAULT NULL COMMENT '计划终身绑定队列;旧结构人工行为空,不允许执行',
`processing_version` bigint unsigned NOT NULL DEFAULT '1' COMMENT '当前处理积压的不可变版本,不因发布新版本丢弃旧进度',
`check_at` datetime(6) DEFAULT NULL COMMENT '下一可扫描时间,UTC;补跑批次之间持久化至少一秒间隔,为空表示没有扫描工作',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_schedule_name` (`namespace_id`,`name`),
KEY `ix_schedule_due` (`paused`,`next_fire_at`,`namespace_id`,`id`),
KEY `ix_schedule_scan` (`paused`,`check_at`,`namespace_id`,`id`),
KEY `ix_schedule_list` (`namespace_id`,`queue_id`,`created_at`,`id`),
CONSTRAINT `ck_pulse_schedules_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_schedules_1` CHECK ((`current_version` > 0)),
CONSTRAINT `ck_schedule_cursor` CHECK (((`processing_version` > 0) and (`processing_version` <= `current_version`))),
CONSTRAINT `ck_schedule_enabled_scan` CHECK (((`queue_id` is not null) or (`check_at` is null)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='调度计划的当前控制状态,规则内容由不可变版本保存';
CREATE TABLE `pulse_tasks` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`queue_id` binary(16) NOT NULL COMMENT '任务所属队列,必须属于同一命名空间',
`gate_id` binary(16) DEFAULT NULL COMMENT '可选执行门控;为空表示没有流程级门控,仍受队列与权限控制',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'WAITING' COMMENT '任务状态;与执行尝试状态分开,未知业务效果进入待核查',
`handler` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务 Worker 注册的处理器名称',
`handler_version` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '处理器兼容版本,受理后不得静默替换',
`payload_version` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '输入参数的解释版本',
`payload` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`result` mediumtext COLLATE utf8mb4_0900_as_cs COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`policy_snapshot` json NOT NULL COMMENT '受理时冻结的实际生效策略 JSON',
`recovery_safety` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'RECONCILE_ONLY' COMMENT '恢复安全等级;未知值按需要核查处理,不能默认自动重跑',
`business_key` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin DEFAULT NULL COMMENT '可空业务关联键,精确匹配并区分大小写及尾部空格,不自动提供业务幂等',
`owner_kind` varchar(32) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '来源资源类型,例如流程激活;为空表示无来源关联',
`owner_id` binary(16) DEFAULT NULL COMMENT '来源资源标识,必须与来源类型同时有值或同时为空',
`priority` smallint NOT NULL DEFAULT '0' COMMENT '冻结任务优先级,0至9;每级带来30秒排序优势,不改变最早执行时间',
`available_at` datetime(6) NOT NULL COMMENT '最早可被领取或处理的时间,统一 UTC',
`start_deadline_at` datetime(6) DEFAULT NULL COMMENT '最晚允许新尝试开始的时间;为空时仅受总时限约束',
`deadline_at` datetime(6) NOT NULL COMMENT '总截止时间,统一 UTC;到期不能证明外部业务没有生效',
`attempt_timeout_ms` bigint unsigned NOT NULL COMMENT '单次尝试的超时时长,单位毫秒',
`max_attempts` int unsigned NOT NULL COMMENT '最多执行尝试数,包含首次尝试',
`attempt_count` int unsigned NOT NULL DEFAULT '0' COMMENT '已产生的执行尝试数,恢复时不得重置',
`current_attempt_id` binary(16) DEFAULT NULL COMMENT '当前关联的执行尝试,必须属于本任务',
`lease_epoch` bigint unsigned NOT NULL DEFAULT '0' COMMENT '递增的执行或消费代次,用于隔离旧授权',
`lease_until` datetime(6) DEFAULT NULL COMMENT '当前执行授权截止时间;没有有效授权时为空',
`cancel_requested_at` datetime(6) DEFAULT NULL COMMENT '取消意图的持久化时间;不等于取消已完成',
`retry_of` binary(16) DEFAULT NULL COMMENT '人工重试的原任务标识,同命名空间每个原任务最多一个直接后继;空表示非人工派生',
`completed_at` datetime(6) DEFAULT NULL COMMENT '终结时间;非终态为空,进入终态时必须写入',
`effect_uncertain` tinyint(1) NOT NULL DEFAULT '0' COMMENT '曾有已授权执行的效果尚未核实,重试与耗尽不清除,仅权威成功或核查可解除',
`concurrency_key` varchar(191) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '显式互斥资源键,同命名空间跨队列共享;空表示不启用,不代替业务幂等',
`concurrency_key_digest` binary(32) DEFAULT NULL COMMENT '资源键精确 UTF-8 字节的域分隔 SHA-256;与资源键同时为空或有值',
`dispatch_at` datetime(6) GENERATED ALWAYS AS ((`available_at` + interval (-(30) * `priority`) second)) STORED COMMENT '派发排序时间,由最早执行时间减优先级乘30秒生成;不是执行授权或可用时间',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_task_retry_parent` (`namespace_id`,`retry_of`) COMMENT '防止不同操作身份并发重新发起同一原任务',
KEY `ix_task_dispatch` (`namespace_id`,`queue_id`,`state`,`available_at`,`priority`,`id`),
KEY `ix_task_lease_recovery` (`state`,`lease_until`,`namespace_id`,`id`),
KEY `ix_task_business` (`namespace_id`,`business_key`,`created_at`,`id`),
KEY `fk_pulse_tasks_2` (`namespace_id`,`gate_id`),
KEY `fk_pulse_tasks_4` (`namespace_id`,`id`,`current_attempt_id`),
KEY `ix_task_created` (`namespace_id`,`queue_id`,`created_at`,`id`),
KEY `ix_task_state_created` (`namespace_id`,`queue_id`,`state`,`created_at`,`id`),
KEY `ix_task_deadline` (`state`,`deadline_at`,`namespace_id`,`id`),
KEY `ix_task_start_deadline` (`state`,`start_deadline_at`,`namespace_id`,`id`),
KEY `ix_task_owner_state` (`namespace_id`,`owner_kind`,`owner_id`,`state`,`id`),
KEY `ix_task_priority_dispatch` (`namespace_id`,`queue_id`,`state`,`dispatch_at`,`available_at`,`id`),
KEY `ix_task_queue_business_created` (`namespace_id`,`queue_id`,`business_key`,`created_at`,`id`) COMMENT '队列内按业务键及创建时间分页',
KEY `ix_task_queue_business_state_created` (`namespace_id`,`queue_id`,`business_key`,`state`,`created_at`,`id`) COMMENT '队列内按业务键和状态及创建时间分页',
KEY `ix_task_workflow_owner` (`namespace_id`,`owner_kind`,`owner_id`,`gate_id`,`id`),
KEY `ix_task_observe_state_available` (`state`,`available_at`,`id`),
KEY `ix_task_observe_terminal_completed` (`state`,`completed_at`,`id`),
CONSTRAINT `ck_pulse_tasks_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_tasks_1` CHECK ((`state` in (_utf8mb4'WAITING',_utf8mb4'LEASED',_utf8mb4'RUNNING',_utf8mb4'NEEDS_REVIEW',_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED'))),
CONSTRAINT `ck_pulse_tasks_2` CHECK ((`recovery_safety` in (_utf8mb4'IDEMPOTENT',_utf8mb4'RECONCILE_ONLY'))),
CONSTRAINT `ck_pulse_tasks_3` CHECK (((`max_attempts` > 0) and (`attempt_count` <= `max_attempts`))),
CONSTRAINT `ck_pulse_tasks_4` CHECK ((`attempt_timeout_ms` > 0)),
CONSTRAINT `ck_pulse_tasks_5` CHECK ((`deadline_at` > `available_at`)),
CONSTRAINT `ck_pulse_tasks_6` CHECK (((`start_deadline_at` is null) or (`start_deadline_at` <= `deadline_at`))),
CONSTRAINT `ck_pulse_tasks_7` CHECK ((((`state` in (_utf8mb4'LEASED',_utf8mb4'RUNNING')) and (`current_attempt_id` is not null) and (`lease_until` is not null)) or ((`state` not in (_utf8mb4'LEASED',_utf8mb4'RUNNING')) and (`lease_until` is null)))),
CONSTRAINT `ck_pulse_tasks_8` CHECK ((((`state` in (_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED')) and (`completed_at` is not null)) or ((`state` not in (_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED')) and (`completed_at` is null)))),
CONSTRAINT `ck_pulse_tasks_9` CHECK (((`owner_kind` is null) = (`owner_id` is null))),
CONSTRAINT `ck_pulse_tasks_payload_json` CHECK (((`payload` is null) or json_valid(`payload`))),
CONSTRAINT `ck_pulse_tasks_result_json` CHECK (((`result` is null) or json_valid(`result`))),
CONSTRAINT `ck_task_concurrency_key` CHECK (((`concurrency_key` is null) = (`concurrency_key_digest` is null))),
CONSTRAINT `ck_task_effect_uncertain` CHECK (((`effect_uncertain` in (0,1)) and ((`effect_uncertain` = false) or (`state` not in (_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED'))))),
CONSTRAINT `ck_task_priority` CHECK ((`priority` between 0 and 9)),
CONSTRAINT `ck_task_retry_not_self` CHECK (((`retry_of` is null) or (`retry_of` <> `id`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='任务主记录,执行尝试另存历史,终态不自动回退';
CREATE TABLE `pulse_worker_instances` (
`namespace_id` binary(16) NOT NULL COMMENT '进程所属命名空间,参与授权和所有关联',
`id` binary(16) NOT NULL COMMENT 'Worker 进程实例标识,进程重启必须换新值',
`revision` bigint unsigned NOT NULL DEFAULT '1' COMMENT '持久化变更版本,从一开始递增',
`created_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '首次注册时间,UTC 微秒精度',
`updated_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最近变更时间,不替代会话代次',
`credential_id` binary(16) NOT NULL COMMENT '初始注册凭据,进程生命周期内固定',
`queue_id` binary(16) NOT NULL COMMENT '绑定队列,切换队列需创建新进程实例',
`secret_digest` binary(32) NOT NULL COMMENT '随机进程恢复秘密的 SHA-256 摘要,不保存原文',
`registration_digest` binary(32) NOT NULL COMMENT '队列及处理器版本集合的语义摘要,重连必须匹配',
`session_epoch` bigint unsigned NOT NULL DEFAULT '0' COMMENT '最大已分配连接代次,注册前为零',
`current_session_id` binary(16) DEFAULT NULL COMMENT '当前会话,注册事务建立会话前为空',
`draining` tinyint(1) NOT NULL DEFAULT '0' COMMENT '持久化排空标记,重连不能清除',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_worker_credential` (`namespace_id`,`id`,`credential_id`),
KEY `fk_worker_instance_credential` (`namespace_id`,`credential_id`),
KEY `fk_worker_instance_queue` (`namespace_id`,`queue_id`),
KEY `fk_worker_instance_session` (`namespace_id`,`id`,`current_session_id`),
CONSTRAINT `ck_worker_instance_revision` CHECK ((`revision` > 0)),
CONSTRAINT `ck_worker_instance_session` CHECK ((((`session_epoch` = 0) and (`current_session_id` is null)) or ((`session_epoch` > 0) and (`current_session_id` is not null))))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='Worker 进程恢复身份和当前会话头,用于跨节点隔离旧连接';
CREATE TABLE `pulse_worker_sessions` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`worker_instance_id` binary(16) NOT NULL COMMENT 'Worker 进程实例标识,重连保留,进程重启应更换',
`credential_id` binary(16) NOT NULL COMMENT '关联的命名空间凭据标识',
`node_id` binary(16) NOT NULL COMMENT '承载当前连接的平台节点标识',
`session_epoch` bigint unsigned NOT NULL COMMENT '该 Worker 实例的连接代次,用于隔离旧会话',
`capabilities` json NOT NULL COMMENT '已登记的处理器版本、队列等能力快照',
`capacity` int unsigned NOT NULL COMMENT 'Worker 声明的执行容量,仍受平台权限和配额约束',
`capacity_sequence` bigint unsigned NOT NULL DEFAULT '0' COMMENT '会话内容量消息序号,重复上报不得重复增加额度',
`draining` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否正在排空连接;排空时不接收新任务',
`expires_at` datetime(6) NOT NULL COMMENT '过期时间,统一 UTC;到期后的行为由对应资源策略决定',
`concurrency_keys` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否明确支持资源键互斥与序号交付;未声明的旧 Worker 不领取带资源键任务',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_worker_epoch` (`namespace_id`,`worker_instance_id`,`session_epoch`),
UNIQUE KEY `uq_session_instance_id` (`namespace_id`,`worker_instance_id`,`id`),
KEY `ix_worker_expiry` (`expires_at`,`namespace_id`,`id`),
KEY `fk_pulse_worker_sessions_1` (`namespace_id`,`credential_id`),
KEY `fk_worker_session_instance` (`namespace_id`,`worker_instance_id`,`credential_id`),
CONSTRAINT `ck_pulse_worker_sessions_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_pulse_worker_sessions_1` CHECK ((`session_epoch` > 0)),
CONSTRAINT `ck_worker_session_capacity` CHECK ((`capacity` <= 256))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次 Worker 连接的持久化身份与能力快照';
CREATE TABLE `weave_activations` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`step_id` binary(16) NOT NULL COMMENT '所属逻辑步骤标识',
`sequence` int unsigned NOT NULL COMMENT '同一步骤的激活序号,人工恢复递增并保留旧记录',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'READY' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`task_id` binary(16) DEFAULT NULL COMMENT '关联的 Pulse 任务标识',
`input` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`output` mediumtext COLLATE utf8mb4_0900_as_cs COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`completed_at` datetime(6) DEFAULT NULL COMMENT '终结时间;非终态为空,进入终态时必须写入',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_activation_sequence` (`namespace_id`,`step_id`,`sequence`),
UNIQUE KEY `uq_activation_workflow_id` (`namespace_id`,`workflow_id`,`id`),
UNIQUE KEY `uq_activation_step_id` (`namespace_id`,`workflow_id`,`step_id`,`id`),
UNIQUE KEY `uq_activation_task` (`namespace_id`,`task_id`),
CONSTRAINT `ck_weave_activations_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_activations_1` CHECK ((`state` in (_utf8mb4'BLOCKED',_utf8mb4'READY',_utf8mb4'ACTIVE',_utf8mb4'WAITING',_utf8mb4'NEEDS_REVIEW',_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED',_utf8mb4'SKIPPED'))),
CONSTRAINT `ck_weave_activations_2` CHECK ((`sequence` > 0)),
CONSTRAINT `ck_weave_activations_input_json` CHECK (((`input` is null) or json_valid(`input`))),
CONSTRAINT `ck_weave_activations_output_json` CHECK (((`output` is null) or json_valid(`output`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='步骤的一次具体激活,人工恢复通过新激活保留历史';
CREATE TABLE `weave_definition_versions` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`definition_id` binary(16) NOT NULL COMMENT '稳定流程定义标识',
`version` varchar(64) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '不可变发布版本;同版本不同内容必须拒绝',
`schema_version` int unsigned NOT NULL COMMENT '流程定义文档的结构版本',
`specification` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`content_digest` binary(32) NOT NULL COMMENT '不可变定义内容的 SHA-256 摘要',
`published_by` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '发布版本的认证主体,用于追溯发布来源',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_definition_version` (`namespace_id`,`definition_id`,`version`),
UNIQUE KEY `uq_definition_version_id` (`namespace_id`,`definition_id`,`id`),
CONSTRAINT `ck_weave_definition_versions_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_definition_versions_1` CHECK ((`schema_version` > 0)),
CONSTRAINT `ck_weave_definition_versions_specification_json` CHECK (((`specification` is null) or json_valid(`specification`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='已发布的不可变流程定义版本';
CREATE TRIGGER `trg_definition_version_immutable` BEFORE UPDATE ON `weave_definition_versions` FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Published workflow versions are immutable';
CREATE TABLE `weave_definitions` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`name` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`description` varchar(1024) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT '' COMMENT '定义用途说明,不承载运行状态',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_definition_name` (`namespace_id`,`name`),
CONSTRAINT `ck_weave_definitions_0` CHECK ((`revision` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='流程定义的稳定身份,不保存可直接执行的业务代码';
CREATE TABLE `weave_inbox` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`event_id` binary(16) NOT NULL COMMENT '来源持久化事件标识,用于消费去重',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'PENDING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`available_at` datetime(6) NOT NULL COMMENT '最早可被领取或处理的时间,统一 UTC',
`lease_owner` binary(16) DEFAULT NULL COMMENT '租约持有者标识;未持有租约时为空',
`lease_epoch` bigint unsigned NOT NULL DEFAULT '0' COMMENT '递增的执行或消费代次,用于隔离旧授权',
`lease_until` datetime(6) DEFAULT NULL COMMENT '内部消费租约截止时间;没有消费租约时为空',
`processed_at` datetime(6) DEFAULT NULL COMMENT '内部事件完成消费的时间;尚未消费时为空',
`error_code` varchar(64) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '稳定错误分类,供恢复策略判断;不得写入敏感原始错误',
`source_task_id` binary(16) DEFAULT NULL COMMENT '来源Pulse任务标识;仅迁移前无法核实的历史记录允许为空',
`source_activation_id` binary(16) DEFAULT NULL COMMENT '事件发生时的Weave激活标识,保留旧激活归属;仅未核实历史记录可空',
`source_revision` bigint unsigned DEFAULT NULL COMMENT '来源任务的状态版本,必须大于零;仅未核实历史记录可空',
`snapshot` mediumtext COLLATE utf8mb4_0900_as_cs COMMENT 'schema_version版本化结果JSON文本,保留精确数字与当时状态;仅未核实历史记录可空',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_inbox_event` (`namespace_id`,`event_id`),
UNIQUE KEY `uq_weave_task_result` (`namespace_id`,`source_task_id`,`source_revision`),
KEY `ix_inbox_due` (`state`,`available_at`,`namespace_id`,`id`),
KEY `fk_weave_inbox_1` (`namespace_id`,`workflow_id`),
CONSTRAINT `ck_weave_inbox_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_inbox_1` CHECK ((`state` in (_utf8mb4'PENDING',_utf8mb4'LEASED',_utf8mb4'PROCESSED',_utf8mb4'QUARANTINED'))),
CONSTRAINT `ck_weave_inbox_2` CHECK ((((`state` = _utf8mb4'LEASED') and (`lease_owner` is not null) and (`lease_until` is not null)) or ((`state` <> _utf8mb4'LEASED') and (`lease_owner` is null) and (`lease_until` is null)))),
CONSTRAINT `ck_weave_inbox_source` CHECK ((((`state` in (_utf8mb4'PROCESSED',_utf8mb4'QUARANTINED')) and (`source_task_id` is null) and (`source_activation_id` is null) and (`source_revision` is null) and (`snapshot` is null)) or ((`source_task_id` is not null) and (`source_activation_id` is not null) and (`source_revision` is not null) and (`source_revision` > 0) and (`snapshot` is not null) and (length(`snapshot`) <= 524288) and json_valid(`snapshot`))))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='Weave 内部事件消费记录,和流程推进一起确认消费';
CREATE TABLE `weave_instances` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`definition_id` binary(16) NOT NULL COMMENT '稳定流程定义标识',
`definition_version_id` binary(16) NOT NULL COMMENT '实例固定使用的定义版本记录,不能随新版本发布而变化',
`gate_id` binary(16) NOT NULL COMMENT '执行门控标识,用于检查是否允许新的领取与开始',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'RUNNING' COMMENT '流程执行状态,与独立的暂停标记同时展示',
`paused` tinyint(1) NOT NULL DEFAULT '0' COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`control_revision` bigint unsigned NOT NULL DEFAULT '1' COMMENT '暂停、继续等控制操作的版本,避免旧操作覆盖新决定',
`input` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`output` mediumtext COLLATE utf8mb4_0900_as_cs COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`policy_snapshot` json NOT NULL COMMENT '受理时冻结的实际生效策略 JSON',
`business_key` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin DEFAULT NULL COMMENT '精确业务追踪键,保留尾部空格,不提供业务幂等',
`deadline_at` datetime(6) NOT NULL COMMENT '流程总截止时间,暂停默认不延长此业务边界',
`cancel_requested_at` datetime(6) DEFAULT NULL COMMENT '取消意图的持久化时间;不等于取消已完成',
`completed_at` datetime(6) DEFAULT NULL COMMENT '终结时间;非终态为空,进入终态时必须写入',
`retry_of` binary(16) DEFAULT NULL COMMENT '来源记录标识,人工重新发起时用于保留历史关联',
`stop_kind` varchar(16) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL COMMENT '首次停止原因:CANCEL为用户取消,FAILURE为固定失败策略;为空表示尚未要求结清',
`stop_requested_at` datetime(6) DEFAULT NULL COMMENT '首次停止意图的数据库时间,重报、进入核查或后来取消均不覆盖',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_workflow_gate` (`namespace_id`,`gate_id`),
KEY `ix_workflow_state` (`namespace_id`,`state`,`updated_at`,`id`),
KEY `ix_workflow_business` (`namespace_id`,`business_key`,`created_at`,`id`),
KEY `fk_weave_instances_1` (`namespace_id`,`definition_id`,`definition_version_id`),
KEY `fk_weave_instances_3` (`namespace_id`,`retry_of`),
KEY `ix_workflow_created` (`namespace_id`,`created_at`,`id`),
KEY `ix_workflow_state_created` (`namespace_id`,`state`,`created_at`,`id`),
KEY `ix_workflow_business_state_created` (`namespace_id`,`business_key`,`state`,`created_at`,`id`),
KEY `ix_workflow_definition_created` (`namespace_id`,`definition_id`,`created_at`,`id`),
KEY `ix_workflow_definition_state_created` (`namespace_id`,`definition_id`,`state`,`created_at`,`id`),
KEY `ix_workflow_definition_business_created` (`namespace_id`,`definition_id`,`business_key`,`created_at`,`id`),
KEY `ix_workflow_definition_business_state_created` (`namespace_id`,`definition_id`,`business_key`,`state`,`created_at`,`id`),
KEY `ix_workflow_observe_state_updated` (`state`,`updated_at`,`id`),
KEY `ix_workflow_observe_terminal_completed` (`state`,`completed_at`,`id`),
CONSTRAINT `ck_weave_instances_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_instances_1` CHECK ((`state` in (_utf8mb4'RUNNING',_utf8mb4'WAITING',_utf8mb4'CANCELLING',_utf8mb4'NEEDS_REVIEW',_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED'))),
CONSTRAINT `ck_weave_instances_2` CHECK ((`control_revision` > 0)),
CONSTRAINT `ck_weave_instances_3` CHECK ((((`state` in (_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED')) and (`completed_at` is not null)) or ((`state` not in (_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED')) and (`completed_at` is null)))),
CONSTRAINT `ck_weave_instances_input_json` CHECK (((`input` is null) or json_valid(`input`))),
CONSTRAINT `ck_weave_instances_output_json` CHECK (((`output` is null) or json_valid(`output`))),
CONSTRAINT `ck_workflow_stop_intent` CHECK ((((`stop_kind` is null) and (`stop_requested_at` is null)) or ((`stop_kind` is not null) and (`stop_kind` in (_ascii'CANCEL',_ascii'FAILURE')) and (`stop_requested_at` is not null))))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='流程运行实例,固定定义版本,暂停与执行状态分别保存';
CREATE TABLE `weave_pending_advances` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`step_id` binary(16) NOT NULL COMMENT '所属逻辑步骤标识',
`expected_step_revision` bigint unsigned NOT NULL COMMENT '恢复推进时要求的步骤版本,避免使用过期检查点',
`checkpoint` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`available_at` datetime(6) NOT NULL COMMENT '最早可被领取或处理的时间,统一 UTC',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_advance_step` (`namespace_id`,`workflow_id`,`step_id`),
KEY `ix_advance_due` (`available_at`,`namespace_id`,`id`),
CONSTRAINT `ck_weave_pending_advances_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_pending_advances_1` CHECK ((`expected_step_revision` > 0)),
CONSTRAINT `ck_weave_pending_advances_checkpoint_json` CHECK (((`checkpoint` is null) or json_valid(`checkpoint`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='暂停或分批推进后的续接检查点,避免仅依赖内存唤醒';
CREATE TABLE `weave_poll_rounds` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`activation_id` binary(16) NOT NULL COMMENT '所属步骤激活,区分旧轮次和人工恢复后的新轮次',
`round` int unsigned NOT NULL COMMENT '业务查询轮次编号,从首次激活起连续计数;人工恢复同一轮时保留编号,由激活身份区分对应任务',
`task_id` binary(16) NOT NULL COMMENT '关联的 Pulse 任务标识',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_poll_round` (`namespace_id`,`workflow_id`,`activation_id`,`round`),
UNIQUE KEY `uq_poll_task` (`namespace_id`,`task_id`),
CONSTRAINT `ck_weave_poll_rounds_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_poll_rounds_1` CHECK ((`round` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次业务查询轮次,一轮对应一个 Pulse 任务';
CREATE TABLE `weave_poll_states` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`activation_id` binary(16) NOT NULL COMMENT '所属步骤激活,区分旧轮次和人工恢复后的新轮次',
`max_rounds` int unsigned NOT NULL COMMENT '业务查询最多轮次,不等于单轮请求重试次数',
`used_rounds` int unsigned NOT NULL DEFAULT '0' COMMENT '已创建的查询轮次,重启或暂停继续不得重置',
`max_attempts_per_round` int unsigned NOT NULL COMMENT '每轮 Pulse 任务最多尝试数,包含该轮首次请求',
`interval_ms` bigint unsigned NOT NULL COMMENT '相邻业务查询轮次的等待间隔,单位毫秒',
`deadline_at` datetime(6) NOT NULL COMMENT '查询节点总截止时间,轮次和单轮重试都受此边界限制',
`next_poll_at` datetime(6) DEFAULT NULL COMMENT '最早允许下一轮查询的时间;为空表示当前不能直接推进',
`current_task_id` binary(16) DEFAULT NULL COMMENT '当前在途查询任务;非空时禁止重叠开启下一轮',
`resolved_at` datetime(6) DEFAULT NULL COMMENT '等待或查询节点结清的时间;尚未结清时为空',
`first_round` int unsigned NOT NULL DEFAULT '1' COMMENT '本激活保存的首个业务查询轮次;人工恢复沿用原轮次,不从1重新计数',
`first_round_attempts_used` int unsigned NOT NULL DEFAULT '0' COMMENT '首个业务轮次在旧激活中已消耗的执行尝试数;新任务只获得原单轮预算的剩余部分',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_poll_activation` (`namespace_id`,`workflow_id`,`activation_id`),
KEY `fk_weave_poll_states_2` (`namespace_id`,`current_task_id`),
CONSTRAINT `ck_poll_recovery_budget` CHECK (((`first_round` between 1 and `max_rounds`) and (`first_round_attempts_used` < `max_attempts_per_round`) and (((`used_rounds` = 0) and (`first_round` = 1) and (`first_round_attempts_used` = 0)) or (`first_round` <= `used_rounds`)))),
CONSTRAINT `ck_weave_poll_states_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_poll_states_1` CHECK (((`max_rounds` > 0) and (`used_rounds` <= `max_rounds`))),
CONSTRAINT `ck_weave_poll_states_2` CHECK (((`max_attempts_per_round` > 0) and (`interval_ms` > 0)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='有界查询节点的持久化预算与恢复检查点';
CREATE TABLE `weave_signals` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`key_digest` binary(32) NOT NULL COMMENT '稳定幂等键或资源键的 SHA-256 摘要',
`request_digest` binary(32) NOT NULL COMMENT '规范化请求语义的 SHA-256 摘要,用于识别同键不同内容',
`type` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL COMMENT '固定定义中的信号名称,新受理限制为128个ASCII字符',
`target_step_key` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '信号目标步骤键,用于早到信号的后续匹配',
`correlation_key` varbinary(764) NOT NULL COMMENT '精确UTF8操作关联,保留尾部空格;新信号最多512字节,历史兼容764字节',
`payload` mediumtext COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '业务无关 JSON 文本,保留原始数值精度,由版本化契约解释',
`actor_id` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '经认证的操作主体标识,不能直接信任请求自报值',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'PENDING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`accepted_at` datetime(6) NOT NULL COMMENT '信号可靠受理时间,不能用稍后的消费时间替代',
`expires_at` datetime(6) NOT NULL COMMENT '过期时间,统一 UTC;到期后的行为由对应资源策略决定',
`consumed_wait_id` binary(16) DEFAULT NULL COMMENT '消费该信号的等待记录;尚未消费时为空',
`payload_version` varchar(32) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL COMMENT '信号内容契约版本;为空仅表示未核实的历史记录',
`target_activation_sequence` int unsigned DEFAULT NULL COMMENT '固定目标步骤激活序号,早到首轮为1;为空仅表示未核实历史',
`evidence_ref` varchar(512) COLLATE utf8mb4_0900_as_cs DEFAULT NULL COMMENT '可选的受控证据引用;不保存秘密,也不由平台请求该地址',
`disposition` varchar(64) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL COMMENT '稳定消费或拒绝原因;PENDING时为空,不包含业务参数',
`available_at` datetime(6) NOT NULL COMMENT '未匹配信号下次到期检查时间;故障退避可延后检查,但不改变原截止',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_signal_identity` (`namespace_id`,`workflow_id`,`key_digest`),
KEY `ix_signal_match` (`namespace_id`,`workflow_id`,`target_step_key`,`correlation_key`,`state`,`accepted_at`),
KEY `fk_weave_signals_2` (`namespace_id`,`workflow_id`,`consumed_wait_id`),
KEY `ix_signal_expiry` (`state`,`available_at`,`namespace_id`,`id`),
KEY `ix_signal_activation` (`namespace_id`,`workflow_id`,`target_step_key`,`target_activation_sequence`,`state`,`accepted_at`,`id`),
KEY `ix_signal_history` (`namespace_id`,`workflow_id`,`accepted_at`,`id`),
CONSTRAINT `ck_signal_pending_identity` CHECK (((`state` <> _utf8mb4'PENDING') or ((`payload_version` is not null) and (`target_activation_sequence` is not null) and (`disposition` is null)))),
CONSTRAINT `ck_signal_version_sequence` CHECK ((((`payload_version` is null) and (`target_activation_sequence` is null)) or ((`payload_version` is not null) and (`payload_version` <> _ascii'') and (`target_activation_sequence` is not null) and (`target_activation_sequence` > 0)))),
CONSTRAINT `ck_weave_signals_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_signals_1` CHECK ((`state` in (_utf8mb4'PENDING',_utf8mb4'CONSUMED',_utf8mb4'EXPIRED',_utf8mb4'REJECTED'))),
CONSTRAINT `ck_weave_signals_2` CHECK ((((`state` = _utf8mb4'CONSUMED') and (`consumed_wait_id` is not null)) or ((`state` <> _utf8mb4'CONSUMED') and (`consumed_wait_id` is null)))),
CONSTRAINT `ck_weave_signals_payload_json` CHECK (((`payload` is null) or json_valid(`payload`)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='已可靠受理的外部信号,受理与消费是两个阶段';
CREATE TABLE `weave_steps` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`key` varchar(128) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '定义中的稳定步骤键,在同一流程实例内唯一',
`kind` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '节点或等待类型,决定由哪类推进规则处理',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'BLOCKED' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`current_activation_id` binary(16) DEFAULT NULL COMMENT '当前激活记录,必须属于本实例的本步骤',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_step_key` (`namespace_id`,`workflow_id`,`key`),
UNIQUE KEY `uq_step_workflow_id` (`namespace_id`,`workflow_id`,`id`),
KEY `fk_weave_steps_2` (`namespace_id`,`workflow_id`,`id`,`current_activation_id`),
CONSTRAINT `ck_weave_steps_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_steps_1` CHECK ((`state` in (_utf8mb4'BLOCKED',_utf8mb4'READY',_utf8mb4'ACTIVE',_utf8mb4'WAITING',_utf8mb4'NEEDS_REVIEW',_utf8mb4'SUCCEEDED',_utf8mb4'FAILED',_utf8mb4'CANCELLED',_utf8mb4'SKIPPED'))),
CONSTRAINT `ck_weave_steps_2` CHECK ((`kind` in (_utf8mb4'TASK',_utf8mb4'BRANCH',_utf8mb4'PARALLEL',_utf8mb4'JOIN',_utf8mb4'SIGNAL',_utf8mb4'TIMER',_utf8mb4'POLL')))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='实例中的逻辑步骤,指向该步骤当前的激活记录';
CREATE TABLE `weave_version_scopes` (
`namespace_id` binary(16) NOT NULL COMMENT '命名空间,参与版本身份及查询授权',
`definition_version_id` binary(16) NOT NULL COMMENT '固定定义版本标识,范围包含所有未执行分支',
`definition_id` binary(16) NOT NULL COMMENT '所属定义标识,服务端核对其与版本及实例的归属',
`content_digest` binary(32) NOT NULL COMMENT '原不可变定义摘要,防止跨版本使用范围',
`queue_ids` json NOT NULL COMMENT '去重队列标识数组,空数组表示无任务队列;只用于查询筛选,返回前仍需核验原定义',
`created_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '查询索引建立时间,UTC;不能替代原定义发布时间',
PRIMARY KEY (`namespace_id`,`definition_version_id`),
KEY `ix_version_scope_definition` (`namespace_id`,`definition_id`,`definition_version_id`),
CONSTRAINT `ck_version_scope_queues` CHECK (json_schema_valid(_utf8mb4'{"type":"array","maxItems":128,"uniqueItems":true,"items":{"type":"string","pattern":"^[0-9a-f]{32}$"}}',`queue_ids`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='不可变流程版本的查询队列范围,供实例列表在数据库内筛选当前权限';
CREATE TRIGGER `trg_version_scope_immutable` BEFORE UPDATE ON `weave_version_scopes` FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Workflow query scopes are immutable';
CREATE TABLE `weave_waits` (
`namespace_id` binary(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
`id` binary(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
`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;不能代替并发版本',
`workflow_id` binary(16) NOT NULL COMMENT '所属流程实例标识',
`activation_id` binary(16) NOT NULL COMMENT '所属步骤激活,区分旧轮次和人工恢复后的新轮次',
`kind` varchar(16) COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '节点或等待类型,决定由哪类推进规则处理',
`state` varchar(32) COLLATE utf8mb4_0900_as_cs NOT NULL DEFAULT 'WAITING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`correlation_key` varbinary(764) NOT NULL COMMENT '精确UTF8业务关联且保留尾部空格;新受理最多512字节,兼容历史191字符最多764字节,TIMER为空串',
`deadline_at` datetime(6) NOT NULL COMMENT '等待截止时间,用可靠受理时间判断信号是否按时到达',
`wake_task_id` binary(16) DEFAULT NULL COMMENT '内部定时唤醒任务;无需定时唤醒时为空',
`resolved_at` datetime(6) DEFAULT NULL COMMENT '等待或查询节点结清的时间;尚未结清时为空',
`signal_name` varchar(128) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL COMMENT '冻结信号名称;TIMER及待核实历史记录为空',
`payload_version` varchar(32) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL COMMENT '冻结信号内容契约版本;TIMER及待核实历史记录为空',
`winner_signal_id` binary(16) DEFAULT NULL COMMENT '胜出的外部信号标识;仅时间或查询结果结清时为空,所有者由同事务校验',
PRIMARY KEY (`namespace_id`,`id`),
UNIQUE KEY `uq_wait_workflow_id` (`namespace_id`,`workflow_id`,`id`),
UNIQUE KEY `uq_wait_winner_signal` (`namespace_id`,`winner_signal_id`),
KEY `ix_wait_deadline` (`state`,`deadline_at`,`namespace_id`,`id`),
KEY `fk_weave_waits_1` (`namespace_id`,`workflow_id`,`activation_id`),
KEY `fk_weave_waits_2` (`namespace_id`,`wake_task_id`),
CONSTRAINT `ck_weave_waits_0` CHECK ((`revision` > 0)),
CONSTRAINT `ck_weave_waits_1` CHECK ((`state` in (_utf8mb4'WAITING',_utf8mb4'SATISFIED',_utf8mb4'EXPIRED',_utf8mb4'CANCELLED'))),
CONSTRAINT `ck_weave_waits_2` CHECK ((`kind` in (_utf8mb4'SIGNAL',_utf8mb4'TIMER',_utf8mb4'POLL')))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='可恢复的信号或时间等待,不长期占用业务 Worker';
-- Orbit 控制台账号与会话;账号只用于人登录,业务 SDK 仍使用命名空间凭据。
CREATE TABLE orbit_console_users (
id BINARY(16) NOT NULL COMMENT '控制台账号标识,全局唯一',
namespace_id BINARY(16) NOT NULL COMMENT '登录后可访问的命名空间',
credential_id BINARY(16) NOT NULL COMMENT '登录后代表该账号调用 API 的业务凭据',
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',
username VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs NOT NULL COMMENT '登录名,大小写敏感',
display_name VARCHAR(128) NOT NULL COMMENT '展示名称',
password_hash VARCHAR(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'bcrypt 密码哈希,不保存明文',
enabled BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否允许登录',
PRIMARY KEY (id),
UNIQUE KEY uq_console_username (username),
KEY ix_console_user_principal (namespace_id, credential_id),
CONSTRAINT ck_console_users_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='控制台人类账号,不替代业务 SDK 凭据';
CREATE TABLE orbit_console_sessions (
id BINARY(16) NOT NULL COMMENT '会话记录标识',
user_id BINARY(16) NOT NULL COMMENT '控制台账号标识',
namespace_id BINARY(16) NOT NULL COMMENT '会话对应命名空间',
credential_id BINARY(16) NOT NULL COMMENT '会话对应业务凭据',
token_digest BINARY(32) NOT NULL COMMENT '会话令牌摘要,不保存令牌原文',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC',
expires_at DATETIME(6) NOT NULL COMMENT '会话过期时间,统一 UTC',
last_seen_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最近一次使用时间,统一 UTC',
revoked_at DATETIME(6) NULL COMMENT '撤销时间;为空表示未撤销',
user_agent VARCHAR(512) NOT NULL DEFAULT '' COMMENT '登录时的客户端摘要',
remote_addr VARCHAR(64) NOT NULL DEFAULT '' COMMENT '登录时的来源地址',
PRIMARY KEY (id),
UNIQUE KEY uq_console_session_token (token_digest),
KEY ix_console_session_user (user_id, revoked_at, expires_at),
KEY ix_console_session_expiry (expires_at, revoked_at),
CONSTRAINT ck_console_sessions_0 CHECK (expires_at > created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='控制台 HttpOnly 登录会话,只保存令牌摘要';
-- 命名空间级历史保留策略;只保存窗口和开关,不执行自动删除。
-- 归档执行器必须在独立事务中核对状态、备份和归档证明后再使用这些窗口。
CREATE TABLE orbit_retention_policies (
namespace_id BINARY(16) NOT NULL COMMENT '策略所属命名空间,服务端核对登录会话后使用',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '策略乐观并发版本,从1开始;首次默认策略未落库时版本为0',
enabled BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否允许归档执行器使用策略;默认关闭,不触发删除',
idempotency_days INT UNSIGNED NOT NULL DEFAULT 90 COMMENT '请求幂等记录至少保留天数,范围90至3650',
task_history_days INT UNSIGNED NOT NULL DEFAULT 365 COMMENT '终态任务和执行证据至少保留天数,范围1至3650',
workflow_history_days INT UNSIGNED NOT NULL DEFAULT 365 COMMENT '终态流程、步骤、等待和流程事件至少保留天数,范围1至3650',
event_log_days INT UNSIGNED NOT NULL DEFAULT 365 COMMENT '状态事件和结果事件至少保留天数,范围1至3650',
delivery_history_days INT UNSIGNED NOT NULL DEFAULT 90 COMMENT '已确认结果交付至少保留天数,未确认交付不得按窗口清理',
inbox_history_days INT UNSIGNED NOT NULL DEFAULT 90 COMMENT '已处理流程Inbox事件至少保留天数,未处理记录不得清理',
audit_log_days INT UNSIGNED NOT NULL DEFAULT 2555 COMMENT '管理审计至少保留天数,普通清理不得处理审计记录',
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_retention_policy_revision CHECK (revision > 0),
CONSTRAINT ck_retention_policy_idempotency CHECK (idempotency_days BETWEEN 90 AND 3650),
CONSTRAINT ck_retention_policy_task CHECK (task_history_days BETWEEN 1 AND 3650),
CONSTRAINT ck_retention_policy_workflow CHECK (workflow_history_days BETWEEN 1 AND 3650),
CONSTRAINT ck_retention_policy_event CHECK (event_log_days BETWEEN 1 AND 3650),
CONSTRAINT ck_retention_policy_delivery CHECK (delivery_history_days BETWEEN 1 AND 3650),
CONSTRAINT ck_retention_policy_inbox CHECK (inbox_history_days BETWEEN 1 AND 3650),
CONSTRAINT ck_retention_policy_audit CHECK (audit_log_days BETWEEN 1 AND 3650)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='命名空间历史数据保留策略,只配置窗口和开关,不自动删除';
-- 周期计划、固定范围作业和领取租约;不使用数据库外键,不删除历史源记录。
CREATE TABLE orbit_archive_plans (
namespace_id BINARY(16) NOT NULL COMMENT '所属命名空间,由事务核验',
kind VARCHAR(16) NOT NULL COMMENT '固定历史类别,同一命名空间每类一个计划',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '配置版本,后台触发不修改此版本',
enabled BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否触发新作业,不中断已有作业',
policy_revision BIGINT UNSIGNED NOT NULL COMMENT '管理员确认的保留策略版本',
storage_id BINARY(16) NOT NULL COMMENT '固定归档卷身份,接管节点必须挂载同一物理卷',
interval_seconds INT UNSIGNED NOT NULL COMMENT '周期秒数,3600至2592000,错过多次合并一次',
batch_size INT UNSIGNED NOT NULL COMMENT '每批根记录上限,1至100',
max_bytes BIGINT UNSIGNED NOT NULL COMMENT '新作业累计文件字节预算,1MiB至1GiB',
next_run_at DATETIME(6) NOT NULL COMMENT '下次触发UTC时间,首次启用立即到期',
active_job_id BINARY(16) NULL COMMENT '未完成或失败待处理作业,成功或关闭后为空',
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,kind),
KEY ix_archive_plan_due(storage_id,enabled,next_run_at),
CONSTRAINT ck_archive_plan_kind CHECK(kind IN ('tasks','workflows','events','audit','deliveries','inbox','idempotency')),
CONSTRAINT ck_archive_plan_config CHECK(revision>0 AND policy_revision>0 AND interval_seconds BETWEEN 3600 AND 2592000 AND batch_size BETWEEN 1 AND 100 AND max_bytes BETWEEN 1048576 AND 1073741824)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='按命名空间和类别配置的周期归档计划,无外键';
CREATE TABLE orbit_archive_jobs (
namespace_id BINARY(16) NOT NULL COMMENT '所属命名空间,由事务核验',
id BINARY(16) NOT NULL COMMENT '作业及目录及文件清单的固定标识',
kind VARCHAR(16) NOT NULL COMMENT '创建时固定的历史类别',
plan_revision BIGINT UNSIGNED NOT NULL COMMENT '创建时固定的计划版本',
policy_revision BIGINT UNSIGNED NOT NULL COMMENT '创建时固定的保留策略版本',
storage_id BINARY(16) NOT NULL COMMENT '固定归档卷身份,不允许跨独立磁盘接管',
batch_size INT UNSIGNED NOT NULL COMMENT '创建时固定的单批根记录上限',
max_bytes BIGINT UNSIGNED NOT NULL COMMENT '累计文件字节预算,人工重试仅可提高',
state VARCHAR(16) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING待领取RUNNING执行中SUCCEEDED完成FAILED待处理ABANDONED已关闭',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态并发版本,领取确认和人工操作递增',
attempts INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '累计领取次数,包含分批继续和崩溃接管',
batches INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已验证并入库的连续文件批次数',
roots BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已确认根记录总数',
bytes BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已确认清单及批次总字节数',
last_sha256 CHAR(64) NOT NULL DEFAULT '' COMMENT '已确认文件链尾摘要,恢复必须验证此前缀',
error_code VARCHAR(32) NOT NULL DEFAULT '' COMMENT '固定失败分类,不记录原始异常或业务内容',
lease_id BINARY(16) NULL COMMENT '领取随机代次,非执行中为空',
lease_until DATETIME(6) NULL COMMENT 'UTC租约截止,过期可接管,非执行中为空',
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,id),
KEY ix_archive_job_claim(storage_id,state,lease_until,updated_at),
KEY ix_archive_job_list(namespace_id,created_at,id),
CONSTRAINT ck_archive_job_state CHECK(state IN ('PENDING','RUNNING','SUCCEEDED','FAILED','ABANDONED')),
CONSTRAINT ck_archive_job_config CHECK(revision>0 AND plan_revision>0 AND policy_revision>0 AND batch_size BETWEEN 1 AND 100 AND max_bytes BETWEEN 1048576 AND 1073741824),
CONSTRAINT ck_archive_job_lease CHECK((state='RUNNING' AND lease_id IS NOT NULL AND lease_until IS NOT NULL) OR (state<>'RUNNING' AND lease_id IS NULL AND lease_until IS NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='持久归档作业及租约,只读源数据,无外键';
-- 通用资源退役,只关闭未来工作并释放活动订阅名额,不删除历史或审计;禁止外键。
ALTER TABLE pulse_queues
ADD retired_at DATETIME(6) NULL COMMENT '永久退役时间,UTC;NULL表示未退役,退役后禁止新工作且不可恢复',
ADD CONSTRAINT ck_queue_retired CHECK (retired_at IS NULL OR paused=TRUE);
ALTER TABLE orbit_subscriptions
ADD retired_at DATETIME(6) NULL COMMENT '永久退役时间,UTC;NULL表示仍占用订阅名额,退役保留历史交付',
ADD retired_sequence BIGINT UNSIGNED NULL COMMENT '退役事务锁定的结果流提交水位;NULL表示未退役,之后的事件不再订阅',
ADD KEY ix_subscription_active(namespace_id,retired_at),
ADD CONSTRAINT ck_subscription_retired CHECK ((retired_at IS NULL AND retired_sequence IS NULL) OR (retired_at IS NOT NULL AND retired_sequence IS NOT NULL AND enabled=FALSE AND pending_count=0));
-- 登录保护独立于业务凭据和命名空间;没有外键,不改变已有密码、会话或 Token。
CREATE TABLE orbit_console_login_guards (
kind VARCHAR(8) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'IP 或 ACCOUNT,固定先 IP 后账号加锁',
subject CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'IP 或规范账号身份的 SHA-256 十六进制键,不包含密码或 Token',
window_start DATETIME(6) NOT NULL COMMENT '固定请求限流窗口起点,UTC',
requests INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '当前窗口内已受理的尝试数,成功不归零',
failures INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '连续失败窗口内的失败数,成功后归零',
first_failed_at DATETIME(6) NULL COMMENT '失败窗口起点;空表示无连续失败',
locked_until DATETIME(6) NULL COMMENT '临时锁定截止;锁内请求不延长此时间',
expires_at DATETIME(6) NOT NULL COMMENT '非活动状态清理截止,晚于所有保护窗口',
PRIMARY KEY(kind,subject),
KEY ix_console_guard_expiry(expires_at),
CONSTRAINT ck_console_guard_kind CHECK(kind IN ('IP','ACCOUNT'))
) ENGINE=InnoDB COMMENT='跨节点持久登录限流及临时锁定状态';
CREATE TABLE orbit_console_login_audit (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '审计序号,仅用于有界倒序分页',
username VARCHAR(128) NOT NULL COMMENT '请求中的登录名,不证明账号存在',
remote_ip VARCHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT '实际连接或受信代理解析出的规范 IP',
user_agent VARCHAR(512) NOT NULL COMMENT '有界浏览器标识,不保存请求正文或认证头',
outcome VARCHAR(16) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'PENDING/SUCCESS/INVALID/LOCKED/ACCOUNT_LIMIT/IP_LIMIT/ERROR',
created_at DATETIME(6) NOT NULL COMMENT '开始时间,UTC',
finished_at DATETIME(6) NULL COMMENT '结果确认时间,空为未完成;异常中断由清理器标 ERROR',
retry_at DATETIME(6) NULL COMMENT '被锁定或限流时的最早重试时间;否则为空',
PRIMARY KEY(id),
KEY ix_console_login_audit_time(created_at),
KEY ix_console_login_audit_pending(outcome,created_at),
CONSTRAINT ck_console_login_outcome CHECK(outcome IN ('PENDING','SUCCESS','INVALID','LOCKED','ACCOUNT_LIMIT','IP_LIMIT','ERROR'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='全局登录审计,不含密码、Cookie 或 Token,仅管理员可查询';