fix(mysql): handle table initialization better in clustered database environments

The CREATE TABLE IF NOT EXISTS yields more locks than checking if the table exists using a SELECT first before running CREATE TABLE.
This makes more sense as the table usually already exists, so we optimize for the happy path.
This commit is contained in:
Joakim Carlstein 2024-05-29 15:06:10 +02:00 committed by Joakim Carlstein
parent e396266f3d
commit aef2d7c861
2 changed files with 23 additions and 1 deletions

View file

@ -0,0 +1,5 @@
---
'@emigrate/mysql': patch
---
Avoid "CREATE TABLE IF NOT EXISTS" as it's too locking in a clustered database when running it concurrently

View file

@ -156,9 +156,26 @@ const deleteMigration = async (pool: Pool, table: string, migration: MigrationMe
}; };
const initializeTable = async (pool: Pool, table: string) => { const initializeTable = async (pool: Pool, table: string) => {
const [result] = await pool.execute<RowDataPacket[]>({
sql: `
SELECT
1 as table_exists
FROM
information_schema.tables
WHERE
table_schema = DATABASE()
AND table_name = ?
`,
values: [table],
});
if (result[0]?.['table_exists']) {
return;
}
// This table definition is compatible with the one used by the immigration-mysql package // This table definition is compatible with the one used by the immigration-mysql package
await pool.execute(` await pool.execute(`
CREATE TABLE IF NOT EXISTS ${escapeId(table)} ( CREATE TABLE ${escapeId(table)} (
name varchar(255) not null primary key, name varchar(255) not null primary key,
status varchar(32), status varchar(32),
date datetime not null date datetime not null