From 8719e3e75e19683282e891d798cff7255255aa1d Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Wed, 9 Jul 2025 23:19:01 -0400 Subject: [PATCH 1/2] add index for referencing columns in identity access token This PR will address issue with very long identity deletions due to a sequential scan over ALL identity access rows during CASCADE --- ...250710022434_add-index-for-access-token.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 backend/src/db/migrations/20250710022434_add-index-for-access-token.ts diff --git a/backend/src/db/migrations/20250710022434_add-index-for-access-token.ts b/backend/src/db/migrations/20250710022434_add-index-for-access-token.ts new file mode 100644 index 000000000..7f85af74d --- /dev/null +++ b/backend/src/db/migrations/20250710022434_add-index-for-access-token.ts @@ -0,0 +1,47 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +const MIGRATION_TIMEOUT = 30 * 60 * 1000; // 30 minutes + +export async function up(knex: Knex): Promise { + const result = await knex.raw('SHOW statement_timeout'); + const originalTimeout = result.rows[0].statement_timeout; + + try { + await knex.raw(`SET statement_timeout = ${MIGRATION_TIMEOUT}`); + + await knex.raw(` + CREATE INDEX CONCURRENTLY IF NOT EXISTS ${TableName.IdentityAccessToken}_identityid_index + ON ${TableName.IdentityAccessToken} ("identityId") + `); + + await knex.raw(` + CREATE INDEX CONCURRENTLY IF NOT EXISTS ${TableName.IdentityAccessToken}_identityuaclientsecretid_index + ON ${TableName.IdentityAccessToken} ("identityUAClientSecretId") + `); + } finally { + await knex.raw(`SET statement_timeout = '${originalTimeout}'`); + } +} + +export async function down(knex: Knex): Promise { + const result = await knex.raw('SHOW statement_timeout'); + const originalTimeout = result.rows[0].statement_timeout; + + try { + await knex.raw(`SET statement_timeout = ${MIGRATION_TIMEOUT}`); + + await knex.raw(` + DROP INDEX IF EXISTS ${TableName.IdentityAccessToken}_identityid_index + `); + + await knex.raw(` + DROP INDEX IF EXISTS ${TableName.IdentityAccessToken}_identityuaclientsecretid_index + `); + } finally { + await knex.raw(`SET statement_timeout = '${originalTimeout}'`); + } +} + +export const config = { transaction: false }; \ No newline at end of file From 5e85de39370eb9b7428cb2ec6eedcf544b83eba6 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Wed, 9 Jul 2025 23:36:55 -0400 Subject: [PATCH 2/2] fix lint and short index name --- ...250710022434_add-index-for-access-token.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/backend/src/db/migrations/20250710022434_add-index-for-access-token.ts b/backend/src/db/migrations/20250710022434_add-index-for-access-token.ts index 7f85af74d..a0215891d 100644 --- a/backend/src/db/migrations/20250710022434_add-index-for-access-token.ts +++ b/backend/src/db/migrations/20250710022434_add-index-for-access-token.ts @@ -5,19 +5,20 @@ import { TableName } from "../schemas"; const MIGRATION_TIMEOUT = 30 * 60 * 1000; // 30 minutes export async function up(knex: Knex): Promise { - const result = await knex.raw('SHOW statement_timeout'); + const result = await knex.raw("SHOW statement_timeout"); const originalTimeout = result.rows[0].statement_timeout; - + try { await knex.raw(`SET statement_timeout = ${MIGRATION_TIMEOUT}`); + // iat means IdentityAccessToken await knex.raw(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS ${TableName.IdentityAccessToken}_identityid_index + CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_iat_identity_id ON ${TableName.IdentityAccessToken} ("identityId") `); await knex.raw(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS ${TableName.IdentityAccessToken}_identityuaclientsecretid_index + CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_iat_ua_client_secret_id ON ${TableName.IdentityAccessToken} ("identityUAClientSecretId") `); } finally { @@ -26,22 +27,22 @@ export async function up(knex: Knex): Promise { } export async function down(knex: Knex): Promise { - const result = await knex.raw('SHOW statement_timeout'); + const result = await knex.raw("SHOW statement_timeout"); const originalTimeout = result.rows[0].statement_timeout; - + try { await knex.raw(`SET statement_timeout = ${MIGRATION_TIMEOUT}`); await knex.raw(` - DROP INDEX IF EXISTS ${TableName.IdentityAccessToken}_identityid_index + DROP INDEX IF EXISTS idx_iat_identity_id `); await knex.raw(` - DROP INDEX IF EXISTS ${TableName.IdentityAccessToken}_identityuaclientsecretid_index + DROP INDEX IF EXISTS idx_iat_ua_client_secret_id `); } finally { await knex.raw(`SET statement_timeout = '${originalTimeout}'`); } } -export const config = { transaction: false }; \ No newline at end of file +export const config = { transaction: false };