UNPKG

@clickup/pg-microsharding

Version:
106 lines (98 loc) 2.71 kB
import compact from "lodash/compact"; import pRetry from "p-retry"; import type { TableInfo } from "./getTablesInSchema"; import { log } from "./logging"; import { libSchema, schemaNew, schemaOld, shardNo } from "./names"; import { ident, join, sql } from "./quote"; import { runSql } from "./runSql"; const ACTIVATION_RETRY_OPTIONS: pRetry.Options = { factor: 1.5, minTimeout: 100, maxTimeout: 3000, retries: 15, }; /** * Cleans up after the shard migration success. */ export async function resultCommit({ activateOnDestination, deactivateSQL, fromDsn, tables, toDsn, schema, }: { activateOnDestination: boolean; deactivateSQL?: string; fromDsn: string; tables: TableInfo[]; toDsn: string; schema: string; }): Promise<void> { if (!activateOnDestination) { await runSql( toDsn, sql` DROP SCHEMA IF EXISTS ${ident(schemaNew(schema))} CASCADE; ALTER SCHEMA ${ident(schema)} RENAME TO ${ident(schemaNew(schema))}; `, `Renaming just-migrated microshard on the destination to ${schemaNew(schema)}`, ); return; } // E.g. 2023-01-09T07:09:54.253Z const dateSuffix = new Date() .toISOString() .replace(/\..*$/, "") .replace(/[-T:Z]/g, ""); const shard = shardNo(schema); await runSql( fromDsn, join( compact([ sql`BEGIN`, shard !== null && sql`SELECT ${libSchema()}.microsharding_ensure_inactive(${shard})`, sql`ALTER schema ${ident(schema)} RENAME TO ${ident(schemaOld(schema, dateSuffix))}`, sql`COMMIT`, ]), "; ", ), "Renaming & deactivating microshard on the source", ); if (shard !== null) { await pRetry( async () => runSql( toDsn, sql`SELECT ${libSchema()}.microsharding_ensure_active(${shard})`, "DON'T INTERRUPT: Activating microshard on the destination while holding the write lock", ).catch((e: unknown) => { throw e instanceof Error ? e : Error(`${e}`); }), { ...ACTIVATION_RETRY_OPTIONS, onFailedAttempt: (error) => log.warning( `Activation attempt ${error.attemptNumber} of ${error.attemptNumber + error.retriesLeft} failed: ${error.message}`, ), }, ); } if (deactivateSQL && tables.length > 0) { await runSql( fromDsn, join( tables.map( ({ schema, name }) => deactivateSQL.replace( /\$1/g, sql`${sql`${ident(schema)}.${ident(name)}`.toString()}`.toString(), ) + ";", ), "\n", ), "Running custom deactivation script for microshard tables", ); } }