首页 > 解决方案 > 启动 liquibase 命令“dropAllForeignKey”时内存不足

问题描述

我在 Sybase 数据库上运行 liquibase 命令“dropAllForeignKey”,其中包含超过 12000 个表和超过 380000 个列。由于 liquibase 代码正在尝试查询数据库中的所有列,因此出现内存不足异常。

JVM 使用以下命令启动:-Xms64M -Xmx512M(如果我将其增加到 5GO,它会起作用,但我不明白为什么我们必须查询数据库中的所有列)

我正在使用的脚本:

<dropAllForeignKeyConstraints baseTableName="Table_Name"/>

当我检查 liquibase 代码时,我发现:

  1. 在 DropAllForeignKeyConstraintsChange: 我们为 xml 中提到的表创建一个快照

    表目标 = SnapshotGeneratorFactory.getInstance().createSnapshot(new Table(catalogAndSchema.getCatalogName(), catalogAndSchema.getSchemaName(), database.correctObjectName(getBaseTableName(), Table.class)) , database);

  2. 在 JdbcDatabaseSnapshot 中:当我们调用 getColumns 时,我们调用 bulkFetchQuery() 而不是 fastFetchQuery(),因为该表既不是“DatabaseChangeLogTableName”也不是“DatabaseChangeLogLockTableName”。在这种情况下,bulkFetchQuery 不会过滤 dropAllForeignKey xml 中给出的表。相反,它使用 SQL_FILTER_MATCH_ALL,因此它将检索数据库中的所有列。(查询所有列已经需要时间了)

  3. 在 ColumnMapRowMapper 中:对于每个表,我们创建一个大小等于列数的 LinkedHashMap。在这里,我正在失去记忆

在删除给定表的所有外键时查询所有列是否正常?如果是这样,为什么我们需要这样做,是否有解决我的问题而不增加 JVM 大小的方法?

PS:还有另一个名为 dropForeignKey 的命令可以删除外键,但它需要外键的名称作为输入,而我没有。实际上,我可以找到给定数据库的外键名称,但是我在不同的数据库上运行此命令,并且外键名称从一个更改为另一个,我需要进行通用的 liquibase 更改. 所以,我不能使用 dropForeignKey,我需要使用 dropAllForeignKey。

这里的堆栈:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.LinkedHashMap.newNode(LinkedHashMap.java:256)
at java.base/java.util.HashMap.putVal(HashMap.java:637)
at java.base/java.util.HashMap.put(HashMap.java:607)
at liquibase.executor.jvm.ColumnMapRowMapper.mapRow(ColumnMapRowMapper.java:35)
at liquibase.executor.jvm.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:72)
at liquibase.snapshot.ResultSetCache$ResultSetExtractor.extract(ResultSetCache.java:297)
at liquibase.snapshot.JdbcDatabaseSnapshot$CachingDatabaseMetaData$3.extract(JdbcDatabaseSnapshot.java:774)
at liquibase.snapshot.ResultSetCache$ResultSetExtractor.extract(ResultSetCache.java:288)
at liquibase.snapshot.JdbcDatabaseSnapshot$CachingDatabaseMetaData$3.bulkFetchQuery(JdbcDatabaseSnapshot.java:606)
at liquibase.snapshot.ResultSetCache$SingleResultSetExtractor.bulkFetch(ResultSetCache.java:353)
at liquibase.snapshot.ResultSetCache.get(ResultSetCache.java:59)
at liquibase.snapshot.JdbcDatabaseSnapshot$CachingDatabaseMetaData.getColumns(JdbcDatabaseSnapshot.java:539)
at liquibase.snapshot.jvm.ColumnSnapshotGenerator.addTo(ColumnSnapshotGenerator.java:106)
at liquibase.snapshot.jvm.JdbcSnapshotGenerator.snapshot(JdbcSnapshotGenerator.java:79)
at liquibase.snapshot.SnapshotGeneratorChain.snapshot(SnapshotGeneratorChain.java:49)
at liquibase.snapshot.DatabaseSnapshot.include(DatabaseSnapshot.java:286)
at liquibase.snapshot.DatabaseSnapshot.init(DatabaseSnapshot.java:102)
at liquibase.snapshot.DatabaseSnapshot.<init>(DatabaseSnapshot.java:59)
at liquibase.snapshot.JdbcDatabaseSnapshot.<init>(JdbcDatabaseSnapshot.java:38)
at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:217)
at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:246)
at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:230)
at liquibase.change.core.DropAllForeignKeyConstraintsChange.generateChildren(DropAllForeignKeyConstraintsChange.java:90)
at liquibase.change.core.DropAllForeignKeyConstraintsChange.generateStatements(DropAllForeignKeyConstraintsChange.java:59)

标签: javaout-of-memorysybaseliquibase

解决方案


推荐阅读