fix(schema-diff): reduce MySQL metadata query pressure
Co-authored-by: zipg <4047349+zipg@users.noreply.github.com>
This commit is contained in:
1 parent
d65f656704
commit
5a8b129edf
3 files changed
+202
-29
No files matched your search
@@ -15,10 +15,11 @@ import SchemaDiffDeployStep from "@/components/diff/SchemaDiffDeployStep.vue";
|
||||
import SchemaDiffOptionsPanel from "@/components/diff/SchemaDiffOptionsPanel.vue";
|
||||
|
||||
import { getSchemaDiffOptionsForDbType } from "@/lib/schemaDiffOptions";
|
||||
import { createConcurrencyLimiter, mapWithConcurrency, schemaDiffMetadataConcurrency } from "@/lib/schemaDiffMetadataLoad";
|
||||
import { normalizeSchemaDiffCompareOptions } from "@/types/schemaDiff";
|
||||
import type { SchemaDiffCompareOptions, SchemaDiffConfig } from "@/types/schemaDiff";
|
||||
import type { ObjectSourceKind } from "@/types/database";
|
||||
import { buildDeploySqlForObjects, convertToSchemaDiffObjects, groupDiffObjects, type OperationGroup, type SchemaDiffObject, type DiffOperationType, type DiffObjectKind, type SchemaDiffPreparation } from "@/lib/schemaDiff";
|
||||
import type { ObjectSourceKind, TableInfo } from "@/types/database";
|
||||
import { buildDeploySqlForObjects, convertToSchemaDiffObjects, groupDiffObjects, type OperationGroup, type SchemaDiffObject, type DiffOperationType, type DiffObjectKind, type SchemaDiffPreparation, type TableSchemaDetail } from "@/lib/schemaDiff";
|
||||
import { compileSchemaDiffTableFilter, filterSchemaDiffTables } from "@/lib/schemaDiffTableFilter";
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
import "splitpanes/dist/splitpanes.css";
|
||||
@@ -279,13 +280,45 @@ function isViewOrMaterializedView(tableType: string): ObjectSourceKind | undefin
|
||||
}
|
||||
}
|
||||
|
||||
interface SchemaDetailLoadContext {
|
||||
connectionId: string;
|
||||
database: string;
|
||||
schema: string;
|
||||
dbType: string;
|
||||
options: SchemaDiffCompareOptions;
|
||||
}
|
||||
|
||||
function shouldLoadIndexes(options: SchemaDiffCompareOptions): boolean {
|
||||
return options.indexes || options.primaryKeys || options.uniqueKeys;
|
||||
}
|
||||
|
||||
async function loadSchemaDetails(tables: TableInfo[], context: SchemaDetailLoadContext): Promise<TableSchemaDetail[]> {
|
||||
const concurrency = schemaDiffMetadataConcurrency(context.dbType, tables.length);
|
||||
const runMetadataQuery = createConcurrencyLimiter(concurrency);
|
||||
|
||||
return mapWithConcurrency(tables, concurrency, async (table) => {
|
||||
const objectType = isViewOrMaterializedView(table.table_type);
|
||||
const [columns, indexes, foreignKeys, triggers, ddl] = await Promise.all([
|
||||
runMetadataQuery(() => api.getColumns(context.connectionId, context.database, context.schema, table.name)),
|
||||
shouldLoadIndexes(context.options) ? runMetadataQuery(() => api.listIndexes(context.connectionId, context.database, context.schema, table.name)) : Promise.resolve([]),
|
||||
context.options.foreignKeys ? runMetadataQuery(() => api.listForeignKeys(context.connectionId, context.database, context.schema, table.name)) : Promise.resolve([]),
|
||||
context.options.triggers ? runMetadataQuery(() => api.listTriggers(context.connectionId, context.database, context.schema, table.name)) : Promise.resolve([]),
|
||||
runMetadataQuery(() => api.getTableDdl(context.connectionId, context.database, context.schema, table.name, objectType)),
|
||||
]);
|
||||
|
||||
return { name: table.name, columns, indexes, foreignKeys, triggers, ddl };
|
||||
});
|
||||
}
|
||||
|
||||
async function handleCompare() {
|
||||
loading.value = true;
|
||||
step.value = "compare";
|
||||
|
||||
try {
|
||||
const sourceConfig = store.getConfig(sourceConnectionId.value);
|
||||
const targetConfig = store.getConfig(targetConnectionId.value);
|
||||
const dbType = targetConfig?.db_type || "mysql";
|
||||
const sourceDbType = sourceConfig?.db_type || dbType;
|
||||
const opts = normalizeSchemaDiffCompareOptions(activeConfig.value?.options, dbType);
|
||||
const tableFilter = compileSchemaDiffTableFilter(opts);
|
||||
|
||||
@@ -295,34 +328,21 @@ async function handleCompare() {
|
||||
const [srcTables, tgtTables] = await Promise.all([api.listTables(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value), api.listTables(targetConnectionId.value, targetDatabase.value, targetSchema.value)]);
|
||||
const { sourceTables, targetTables } = filterSchemaDiffTables(srcTables, tgtTables, tableFilter);
|
||||
|
||||
// Load schema details in parallel
|
||||
const sourceDetails = await Promise.all(
|
||||
sourceTables.map(async (table) => {
|
||||
const objectType = isViewOrMaterializedView(table.table_type);
|
||||
const [columns, indexes, foreignKeys, triggers, ddl] = await Promise.all([
|
||||
api.getColumns(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, table.name),
|
||||
api.listIndexes(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, table.name),
|
||||
api.listForeignKeys(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, table.name),
|
||||
api.listTriggers(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, table.name),
|
||||
api.getTableDdl(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, table.name, objectType),
|
||||
]);
|
||||
return { name: table.name, columns, indexes, foreignKeys, triggers, ddl };
|
||||
}),
|
||||
);
|
||||
const sourceDetails = await loadSchemaDetails(sourceTables, {
|
||||
connectionId: sourceConnectionId.value,
|
||||
database: sourceDatabase.value,
|
||||
schema: sourceSchema.value,
|
||||
dbType: sourceDbType,
|
||||
options: opts,
|
||||
});
|
||||
|
||||
const targetDetails = await Promise.all(
|
||||
targetTables.map(async (table) => {
|
||||
const objectType = isViewOrMaterializedView(table.table_type);
|
||||
const [columns, indexes, foreignKeys, triggers, ddl] = await Promise.all([
|
||||
api.getColumns(targetConnectionId.value, targetDatabase.value, targetSchema.value, table.name),
|
||||
api.listIndexes(targetConnectionId.value, targetDatabase.value, targetSchema.value, table.name),
|
||||
api.listForeignKeys(targetConnectionId.value, targetDatabase.value, targetSchema.value, table.name),
|
||||
api.listTriggers(targetConnectionId.value, targetDatabase.value, targetSchema.value, table.name),
|
||||
api.getTableDdl(targetConnectionId.value, targetDatabase.value, targetSchema.value, table.name, objectType),
|
||||
]);
|
||||
return { name: table.name, columns, indexes, foreignKeys, triggers, ddl };
|
||||
}),
|
||||
);
|
||||
const targetDetails = await loadSchemaDetails(targetTables, {
|
||||
connectionId: targetConnectionId.value,
|
||||
database: targetDatabase.value,
|
||||
schema: targetSchema.value,
|
||||
dbType,
|
||||
options: opts,
|
||||
});
|
||||
|
||||
const isPostgresLike = dbType === "postgres" || dbType === "opengauss";
|
||||
|
||||
|
||||
Reference in new issue
Block a user