Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize DBCL checksum query and set fetch size on all statements (DAT-17267) #5842

Merged
merged 6 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,12 @@ public void init() throws DatabaseException {
}

SqlStatement databaseChangeLogStatement = new SelectFromDatabaseChangeLogStatement(
new SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum(),
new SelectFromDatabaseChangeLogStatement.ByCheckSumNotNullAndNotLike(ChecksumVersion.latest().getVersion()),
new ColumnConfig().setName("MD5SUM"));
List<Map<String, ?>> md5sumRS = ChangelogJdbcMdcListener.query(getDatabase(), ex -> ex.queryForList(databaseChangeLogStatement));

if (!md5sumRS.isEmpty()) {
//check if any checksum is not using the current version
databaseChecksumsCompatible = md5sumRS.stream().allMatch(m -> m.get("MD5SUM").toString().startsWith(ChecksumVersion.latest().getVersion() + ":"));
}
//check if any checksum is not using the current version
databaseChecksumsCompatible = md5sumRS.isEmpty();


} else if (!changeLogCreateAttempted) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ public Object execute(StatementCallback action, List<SqlVisitor> sqlVisitors) th
throw new DatabaseException("Cannot execute commands against an offline database");
}
stmt = ((JdbcConnection) con).getUnderlyingConnection().createStatement();
if (Boolean.TRUE.equals(SqlConfiguration.ALWAYS_SET_FETCH_SIZE.getCurrentValue())) {
stmt.setFetchSize(database.getFetchSize());
}
Statement stmtToUse = stmt;

Object object = action.doInStatement(stmtToUse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class SqlConfiguration implements AutoloadedConfigurations {
public static final ConfigurationDefinition<Level> SHOW_AT_LOG_LEVEL;
public static final ConfigurationDefinition<Boolean> SHOW_SQL_WARNING_MESSAGES;

public static final ConfigurationDefinition<Boolean> ALWAYS_SET_FETCH_SIZE;

static {
ConfigurationDefinition.Builder builder = new ConfigurationDefinition.Builder("liquibase.sql");

Expand All @@ -26,5 +28,10 @@ public class SqlConfiguration implements AutoloadedConfigurations {
.setDescription("Show SQLWarning messages")
.setDefaultValue(Boolean.TRUE)
.build();
ALWAYS_SET_FETCH_SIZE = builder.define("alwaysSetFetchSize", Boolean.class)
.setDescription("If true, all queries will have their fetch size set to the fetch size defined in their database implementation. This has the effect of informing the driver how many rows should be fetched when processing the result set. This is not guaranteed to be respected by the driver, but if respected, should improve query performance significantly.")
.setDefaultValue(Boolean.TRUE)
.setHidden(true)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@
import liquibase.change.ColumnConfig;
import liquibase.database.Database;
import liquibase.database.ObjectQuotingStrategy;
import liquibase.database.core.AbstractDb2Database;
import liquibase.database.core.MSSQLDatabase;
import liquibase.database.core.MySQLDatabase;
import liquibase.database.core.OracleDatabase;
import liquibase.database.core.PostgresDatabase;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.database.core.*;
import liquibase.exception.ValidationErrors;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
Expand Down Expand Up @@ -48,13 +43,7 @@ public Sql[] generateSql(SelectFromDatabaseChangeLogStatement statement, final D

SelectFromDatabaseChangeLogStatement.WhereClause whereClause = statement.getWhereClause();
if (whereClause != null) {
if (whereClause instanceof SelectFromDatabaseChangeLogStatement.ByTag) {
sql += " WHERE "+database.escapeColumnName(null, null, null, "TAG")+"='" + ((SelectFromDatabaseChangeLogStatement.ByTag) whereClause).getTagName() + "'";
} else if (whereClause instanceof SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum) {
sql += " WHERE "+database.escapeColumnName(null, null, null, "MD5SUM")+" IS NOT NULL";
} else {
throw new UnexpectedLiquibaseException("Unknown where clause type: " + whereClause.getClass().getName());
}
sql += whereClause.generateSql(database);
}

if ((statement.getOrderByColumns() != null) && (statement.getOrderByColumns().length > 0)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package liquibase.statement.core;

import liquibase.change.ColumnConfig;
import liquibase.database.Database;
import liquibase.statement.AbstractSqlStatement;
import lombok.Data;
import lombok.Getter;

public class SelectFromDatabaseChangeLogStatement extends AbstractSqlStatement {

Expand Down Expand Up @@ -57,12 +60,19 @@ public SelectFromDatabaseChangeLogStatement setLimit(Integer limit) {

public interface WhereClause {

String generateSql(Database database);

}

public static class ByNotNullCheckSum implements WhereClause {

@Override
public String generateSql(Database database) {
return String.format(" WHERE %s IS NOT NULL", database.escapeColumnName(null, null, null, "MD5SUM"));
}
}

@Getter
public static class ByTag implements WhereClause {

private final String tagName;
Expand All @@ -71,8 +81,20 @@ public ByTag(String tagName) {
this.tagName = tagName;
}

public String getTagName() {
return tagName;
@Override
public String generateSql(Database database) {
return String.format(" WHERE %s='%s'", database.escapeColumnName(null, null, null, "TAG"), getTagName());
}
}

@Data
public static class ByCheckSumNotNullAndNotLike implements WhereClause {
private final int notLikeCheckSumVersion;

@Override
public String generateSql(Database database) {
final String md5SUMColumnName = database.escapeColumnName(null, null, null, "MD5SUM");
return String.format(" WHERE %s IS NOT NULL AND %s NOT LIKE '%d:%%'", md5SUMColumnName, md5SUMColumnName, notLikeCheckSumVersion);
}
}

Expand Down