Skip to content

Commit 9566abf

Browse files
dahliaclaude-sonnet-4-6
andcommitted
Change ordering_key column from VARCHAR(512) to TEXT
ordering_key is an arbitrary string (often a URL in Fedify), so the previous VARCHAR(512) limit could silently truncate or reject values longer than 512 characters at insert time with an opaque DB error. Switch the column to TEXT so there is no fixed-length cap. Because InnoDB requires a prefix length when indexing TEXT columns, the composite index now uses ordering_key(766): 766 chars * 4 bytes (utf8mb4) + 8 bytes (DATETIME(6)) = 3072 bytes which exactly hits InnoDB's 3072-byte key limit. Existing tables created with the old VARCHAR(512) definition will continue to work; operators who want to lift the 512-char cap must ALTER the column manually (or drop and recreate the table via drop()). #599 (comment) Co-Authored-By: claude-sonnet-4-6 <claude-sonnet-4-6@anthropic.com>
1 parent 6c67e95 commit 9566abf

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

packages/mysql/src/mq.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -539,10 +539,10 @@ export class MysqlMessageQueue implements MessageQueue {
539539
try {
540540
await this.#pool.query(
541541
`CREATE TABLE IF NOT EXISTS \`${this.#tableName}\` (
542-
\`id\` CHAR(36) NOT NULL,
543-
\`message\` JSON NOT NULL,
544-
\`deliver_after\` DATETIME(6) NOT NULL DEFAULT NOW(6),
545-
\`ordering_key\` VARCHAR(512) NULL DEFAULT NULL,
542+
\`id\` CHAR(36) NOT NULL,
543+
\`message\` JSON NOT NULL,
544+
\`deliver_after\` DATETIME(6) NOT NULL DEFAULT NOW(6),
545+
\`ordering_key\` TEXT NULL DEFAULT NULL,
546546
PRIMARY KEY (\`id\`)
547547
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`,
548548
);
@@ -558,9 +558,14 @@ export class MysqlMessageQueue implements MessageQueue {
558558
try {
559559
// Composite index to speed up #findOrderingKeyCandidate():
560560
// scans for the oldest ready message per ordering key.
561+
// ordering_key uses a 766-character prefix because TEXT columns
562+
// require a prefix length for indexing, and InnoDB's 3072-byte key
563+
// limit in utf8mb4 (4 bytes/char) leaves room for 766 chars once the
564+
// DATETIME(6) companion column (8 bytes) is included:
565+
// 766 * 4 + 8 = 3072 bytes exactly.
561566
await this.#pool.query(
562567
`CREATE INDEX \`idx_${this.#tableName}_ok_da\`
563-
ON \`${this.#tableName}\` (\`ordering_key\`, \`deliver_after\`)`,
568+
ON \`${this.#tableName}\` (\`ordering_key\`(766), \`deliver_after\`)`,
564569
);
565570
} catch (e) {
566571
// Ignore duplicate index (ER_DUP_KEYNAME) from concurrent init

0 commit comments

Comments
 (0)