-- IM file-message link msgid Snowflake compatibility migration. -- Scope: the shared business database (for example meeting_im). -- Fixes: im_filemsglinks.msgid was INT (max 2147483647) while message ids are -- snowflake int64 values (~1.58e18), so every INSERT into the link table -- failed with MySQL error 1264 "Out of range value for column 'msgid'". -- Under Kafka persistence that failure retried forever and stalled the -- consumer partition, blocking persistence for every message queued -- behind it. -- Notes: im_filemsglinks is a global (non tenant-sharded) table, but in -- tenant-scoped-DB deployments every tenant database has its own copy — -- run this script once per database. -- Re-running is safe (MODIFY to the same shape is idempotent). -- NOT REVERSIBLE: converting back to INT would truncate snowflake ids. -- Review and back up before execution. This script does not replay dead letters. -- 1. Preflight: confirm the live column shape before touching anything. SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_TYPE, IS_NULLABLE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'im_filemsglinks' AND COLUMN_NAME = 'msgid'; -- 2. Upgrade the column (keeps the nullable semantics of the original schema). ALTER TABLE `im_filemsglinks` MODIFY COLUMN `msgid` BIGINT DEFAULT NULL; -- 3. Post-check: this query must return zero rows. SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'im_filemsglinks' AND COLUMN_NAME = 'msgid' AND DATA_TYPE <> 'bigint'; -- 4. Observe pending recovery work caused by the overflow (and, before the -- startup schema-contract check existed, by any other drift). Replay only -- after the post-check passes and the referenced files still exist. SELECT status, last_reason, COUNT(*) AS entry_count, MIN(created_at) AS first_created_at, MAX(created_at) AS last_created_at FROM im_kafka_dead_letters WHERE last_error LIKE '%Out of range value for column %' OR last_error LIKE '%file lifecycle enqueue failed: not found%' GROUP BY status, last_reason ORDER BY status, last_reason;