-- SendGift V2 需要把首次成功结果和扣款后的恢复状态固化在 room-service owner 库。 -- 线上先执行该迁移再发布新 room-service;旧版本不会读取新增列和表,迁移可向前兼容。 ALTER TABLE room_command_log ADD COLUMN result_payload LONGBLOB NULL COMMENT '首次提交的 typed 结果,用于幂等原样重放' AFTER payload; CREATE TABLE IF NOT EXISTS room_gift_operations ( app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离', room_id VARCHAR(64) NOT NULL COMMENT '房间 ID', command_id VARCHAR(128) NOT NULL COMMENT '送礼全链路幂等 ID', actor_user_id BIGINT NOT NULL COMMENT '送礼用户 ID', command_payload LONGBLOB NOT NULL COMMENT '规范化 Room 命令,供载荷冲突校验', request_payload LONGBLOB NOT NULL COMMENT '原始 SendGiftRequest protobuf,供服务端恢复', status VARCHAR(32) NOT NULL COMMENT 'pending/debited/drawn/committed/compensated', billing_payload LONGBLOB NULL COMMENT '钱包稳定回执 protobuf', lucky_payload LONGBLOB NULL COMMENT '幸运礼物聚合结果 protobuf', result_payload LONGBLOB NULL COMMENT '首次提交的 SendGiftResultV2 protobuf', last_error TEXT NULL COMMENT '最近一次恢复错误', retry_count INT NOT NULL DEFAULT 0 COMMENT '服务端恢复次数', next_retry_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '下次允许恢复时间,UTC epoch ms', worker_id VARCHAR(128) NOT NULL DEFAULT '' COMMENT '当前恢复 worker', lock_until_ms BIGINT NULL COMMENT '恢复租约截止时间,UTC epoch ms', created_at_ms BIGINT NOT NULL COMMENT '创建时间,UTC epoch ms', updated_at_ms BIGINT NOT NULL COMMENT '更新时间,UTC epoch ms', PRIMARY KEY (app_code, room_id, command_id), KEY idx_room_gift_operation_recovery (status, next_retry_at_ms, lock_until_ms, updated_at_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='送礼跨钱包抽奖和房间提交 Saga';