From c37c4fb51b053d462a4b3f623d384c2435cd67b2 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Thu, 1 May 2025 11:45:15 +0900 Subject: [PATCH] feat: add MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY option --- .../migration/1745378064470-composite-note-index.js | 10 +++++++--- packages/backend/migration/js/migration-config.js | 4 ++++ packages/backend/ormconfig.js | 3 ++- packages/backend/src/GlobalModule.ts | 9 +++++++-- 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 packages/backend/migration/js/migration-config.js diff --git a/packages/backend/migration/1745378064470-composite-note-index.js b/packages/backend/migration/1745378064470-composite-note-index.js index 773afb636c..6bbeb95979 100644 --- a/packages/backend/migration/1745378064470-composite-note-index.js +++ b/packages/backend/migration/1745378064470-composite-note-index.js @@ -3,12 +3,15 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { isConcurrentIndexMigrationEnabled } from "./js/migration-config.js"; + export class CompositeNoteIndex1745378064470 { name = 'CompositeNoteIndex1745378064470'; - transaction = false; + transaction = isConcurrentIndexMigrationEnabled() ? false : undefined; async up(queryRunner) { - await queryRunner.query(`CREATE INDEX CONCURRENTLY "IDX_724b311e6f883751f261ebe378" ON "note" ("userId", "id" DESC)`); + const mayConcurrently = isConcurrentIndexMigrationEnabled() ? 'CONCURRENTLY' : ''; + await queryRunner.query(`CREATE INDEX ${mayConcurrently} "IDX_724b311e6f883751f261ebe378" ON "note" ("userId", "id" DESC)`); await queryRunner.query(`DROP INDEX IF EXISTS "IDX_5b87d9d19127bd5d92026017a7"`); // Flush all cached Linear Scan Plans and redo statistics for composite index // this is important for Postgres to learn that even in highly complex queries, using this index first can reduce the result set significantly @@ -16,7 +19,8 @@ export class CompositeNoteIndex1745378064470 { } async down(queryRunner) { + const mayConcurrently = isConcurrentIndexMigrationEnabled() ? 'CONCURRENTLY' : ''; await queryRunner.query(`DROP INDEX IF EXISTS "IDX_724b311e6f883751f261ebe378"`); - await queryRunner.query(`CREATE INDEX CONCURRENTLY "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId")`); + await queryRunner.query(`CREATE INDEX ${mayConcurrently} "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId")`); } } diff --git a/packages/backend/migration/js/migration-config.js b/packages/backend/migration/js/migration-config.js new file mode 100644 index 0000000000..5a718fa66c --- /dev/null +++ b/packages/backend/migration/js/migration-config.js @@ -0,0 +1,4 @@ + +export function isConcurrentIndexMigrationEnabled() { + return process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1'; +} diff --git a/packages/backend/ormconfig.js b/packages/backend/ormconfig.js index 23774f21fd..f979c36ad7 100644 --- a/packages/backend/ormconfig.js +++ b/packages/backend/ormconfig.js @@ -1,6 +1,7 @@ import { DataSource } from 'typeorm'; import { loadConfig } from './built/config.js'; import { entities } from './built/postgres.js'; +import { isConcurrentIndexMigrationEnabled } from "./migration/js/migration-config.js"; const config = loadConfig(); @@ -14,5 +15,5 @@ export default new DataSource({ extra: config.db.extra, entities: entities, migrations: ['migration/*.js'], - migrationsTransactionMode: 'each', + migrationsTransactionMode: isConcurrentIndexMigrationEnabled() ? 'each' : 'all', }); diff --git a/packages/backend/src/GlobalModule.ts b/packages/backend/src/GlobalModule.ts index 5544eeeddd..435bd8dd45 100644 --- a/packages/backend/src/GlobalModule.ts +++ b/packages/backend/src/GlobalModule.ts @@ -24,8 +24,13 @@ const $config: Provider = { const $db: Provider = { provide: DI.db, useFactory: async (config) => { - const db = createPostgresDataSource(config); - return await db.initialize(); + try { + const db = createPostgresDataSource(config); + return await db.initialize(); + } catch (e) { + console.log(e); + throw e; + } }, inject: [DI.config], };