diff --git a/backend/src/db/migrations/20241007052449_partition-audit-logs.ts b/backend/src/db/migrations/20241007052449_partition-audit-logs.ts index a8b68ef83..e132bb5ef 100644 --- a/backend/src/db/migrations/20241007052449_partition-audit-logs.ts +++ b/backend/src/db/migrations/20241007052449_partition-audit-logs.ts @@ -28,6 +28,7 @@ const isUsingDedicatedAuditLogDb = Boolean(process.env.AUDIT_LOGS_DB_CONNECTION_ export async function up(knex: Knex): Promise { if (!isUsingDedicatedAuditLogDb && (await knex.schema.hasTable(TableName.AuditLog))) { + console.info("Dropping primary key of Audit Log table..."); await knex.schema.alterTable(TableName.AuditLog, (t) => { // remove existing keys t.dropPrimary(); @@ -55,10 +56,12 @@ export async function up(knex: Knex): Promise { }) .toString(); + console.info("Creating partition table..."); await knex.schema.raw(` ${createTableSql} PARTITION BY RANGE ("createdAt"); `); + console.log("Adding indices..."); await knex.schema.alterTable(TableName.PartitionedAuditLog, (t) => { t.index(["projectId", "createdAt"]); t.index(["orgId", "createdAt"]); @@ -67,15 +70,20 @@ export async function up(knex: Knex): Promise { t.index("projectId"); }); + console.log("Adding GIN indices..."); + await knex.raw( `CREATE INDEX IF NOT EXISTS "audit_logs_actorMetadata_idx" ON ${TableName.PartitionedAuditLog} USING gin("actorMetadata" jsonb_path_ops)` ); + console.log("GIN index for actorMetadata done"); await knex.raw( `CREATE INDEX IF NOT EXISTS "audit_logs_eventMetadata_idx" ON ${TableName.PartitionedAuditLog} USING gin("eventMetadata" jsonb_path_ops)` ); + console.log("GIN index for eventMetadata done"); // create default partition + console.log("Creating default partition..."); await knex.schema.raw( `CREATE TABLE ${TableName.PartitionedAuditLog}_default PARTITION OF ${TableName.PartitionedAuditLog} DEFAULT` ); @@ -86,6 +94,7 @@ export async function up(knex: Knex): Promise { // attach existing audit log table as a partition ONLY if using the same DB if (!isUsingDedicatedAuditLogDb) { + console.log("Attaching existing audit log table as a partition..."); await knex.schema.raw(` ALTER TABLE ${TableName.AuditLog} ADD CONSTRAINT audit_log_old CHECK ( "createdAt" < DATE '${nextDateStr}' ); @@ -96,6 +105,7 @@ export async function up(knex: Knex): Promise { } // create partition from now until end of month + console.log("Creating audit log partitions ahead of time... next date:", nextDateStr); await createAuditLogPartition(knex, nextDate, new Date(nextDate.getFullYear(), nextDate.getMonth() + 1)); // create partitions 4 years ahead @@ -112,6 +122,7 @@ export async function up(knex: Knex): Promise { } await Promise.all(partitionPromises); + console.log("Partition migration complete"); } } @@ -126,6 +137,7 @@ export async function down(knex: Knex): Promise { const isAuditLogAPartition = partitionSearchResult.rows.length > 0; if (isAuditLogAPartition) { // detach audit log from partition + console.log("Detaching original audit log table from new partition table..."); await knex.schema.raw(` ALTER TABLE ${TableName.PartitionedAuditLog} DETACH PARTITION ${TableName.AuditLog}; @@ -133,6 +145,7 @@ export async function down(knex: Knex): Promise { `); // revert audit log modifications + console.log("Reverting changes made to the audit log table..."); if (await knex.schema.hasTable(TableName.AuditLog)) { await knex.schema.alterTable(TableName.AuditLog, (t) => { // we drop this first because adding to the partition results in a new primary key @@ -147,4 +160,5 @@ export async function down(knex: Knex): Promise { } await knex.schema.dropTableIfExists(TableName.PartitionedAuditLog); + console.log("Partition rollback complete"); }