fix: backfill wallet outbox initdb migrations

This commit is contained in:
zhx 2026-05-25 19:52:13 +08:00
parent 1b3cf31a7d
commit ccd1967242

View File

@ -78,6 +78,62 @@ CREATE TABLE IF NOT EXISTS wallet_outbox (
KEY idx_wallet_outbox_tx (app_code, transaction_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钱包事件 outbox 表';
-- 老环境可能已经存在 wallet_outboxCREATE TABLE IF NOT EXISTS 不会补齐后续新增的投递锁字段。
-- 这里用 information_schema 生成幂等 ALTER保证重复执行 initdb 时不会因重复列名失败。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'wallet_outbox' AND COLUMN_NAME = 'worker_id') = 0,
'ALTER TABLE wallet_outbox ADD COLUMN worker_id VARCHAR(128) NOT NULL DEFAULT '''' COMMENT ''MQ 投递 worker ID'' AFTER status',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 投递锁过期时间用于多实例 claim outbox老库缺这个列时会导致 worker 查询直接 1054。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'wallet_outbox' AND COLUMN_NAME = 'lock_until_ms') = 0,
'ALTER TABLE wallet_outbox ADD COLUMN lock_until_ms BIGINT NULL COMMENT ''MQ 投递锁过期时间UTC epoch ms'' AFTER worker_id',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 下一次重试时间让失败 outbox 可延迟重投;老库缺列时待投递扫描会直接失败。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'wallet_outbox' AND COLUMN_NAME = 'next_retry_at_ms') = 0,
'ALTER TABLE wallet_outbox ADD COLUMN next_retry_at_ms BIGINT NULL COMMENT ''下一次 MQ 投递重试时间UTC epoch ms'' AFTER retry_count',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- pending 索引的列顺序跟 outbox 扫描条件绑定;为兼容历史索引,存在就先删除再按当前结构重建。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'wallet_outbox' AND INDEX_NAME = 'idx_wallet_outbox_pending') > 0,
'ALTER TABLE wallet_outbox DROP INDEX idx_wallet_outbox_pending',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := 'ALTER TABLE wallet_outbox ADD INDEX idx_wallet_outbox_pending (app_code, status, next_retry_at_ms, created_at_ms)';
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- claim 索引用于查找锁过期的消息;仅在缺失时添加,避免重复执行 initdb 报重复索引。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'wallet_outbox' AND INDEX_NAME = 'idx_wallet_outbox_claim') = 0,
'ALTER TABLE wallet_outbox ADD INDEX idx_wallet_outbox_claim (app_code, status, lock_until_ms, created_at_ms)',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CREATE TABLE IF NOT EXISTS wallet_gift_prices (
app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离',
gift_id VARCHAR(96) NOT NULL COMMENT '礼物 ID',