mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Add support for upgrading database directly from DSpace 5.x to 7.x
This commit is contained in:
@@ -562,6 +562,12 @@ public class DatabaseUtils {
|
||||
log.info("Loading Flyway DB migrations from: " + StringUtils.join(scriptLocations, ", "));
|
||||
flywayConfiguration.locations(scriptLocations.toArray(new String[scriptLocations.size()]));
|
||||
|
||||
// Tell Flyway NOT to throw a validation error if it finds older "Ignored" migrations.
|
||||
// For DSpace, we sometimes have to insert "old" migrations in after a major release
|
||||
// if further development/bug fixes are needed in older versions. So, "Ignored" migrations are
|
||||
// nothing to worry about...you can always trigger them to run using "database migrate ignored" from CLI
|
||||
flywayConfiguration.ignoreIgnoredMigrations(true);
|
||||
|
||||
// Set flyway callbacks (i.e. classes which are called post-DB migration and similar)
|
||||
// In this situation, we have a Registry Updater that runs PRE-migration
|
||||
// NOTE: DatabaseLegacyReindexer only indexes in Legacy Lucene & RDBMS indexes. It can be removed
|
||||
@@ -691,8 +697,13 @@ public class DatabaseUtils {
|
||||
flyway = flywayConfiguration.load();
|
||||
flyway.baseline();
|
||||
} else {
|
||||
// Otherwise, database already initialized with Flyway. Just load our configuration.
|
||||
// Otherwise, this database already ran Flyway before
|
||||
// So, just load our Flyway configuration, initializing latest Flyway.
|
||||
flyway = flywayConfiguration.load();
|
||||
|
||||
// Now, check our Flyway database table to see if it needs upgrading
|
||||
// *before* any other Flyway commands can be run.
|
||||
FlywayUpgradeUtils.upgradeFlywayTable(flyway, connection);
|
||||
}
|
||||
|
||||
// Determine pending Database migrations
|
||||
|
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.storage.rdbms;
|
||||
|
||||
import static org.dspace.storage.rdbms.DatabaseUtils.FLYWAY_TABLE;
|
||||
import static org.dspace.storage.rdbms.DatabaseUtils.executeSql;
|
||||
import static org.dspace.storage.rdbms.DatabaseUtils.getCurrentFlywayState;
|
||||
import static org.dspace.storage.rdbms.DatabaseUtils.getDbType;
|
||||
import static org.dspace.storage.rdbms.DatabaseUtils.getSchemaName;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.text.StringSubstitutor;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.storage.rdbms.migration.MigrationUtils;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* Utility class used to detect issues with the Flyway migration history table and attempt to correct/fix them.
|
||||
* These issues can occur when attempting to upgrade your database across multiple versions/releases of Flyway.
|
||||
* <p>
|
||||
* As documented in this issue ticket, Flyway does not normally support skipping over any
|
||||
* major release (for example going from v3 to v5 is unsuppored): https://github.com/flyway/flyway/issues/2126
|
||||
* <p>
|
||||
* This class allows us to do a migration (where needed) through multiple major versions of Flyway.
|
||||
*
|
||||
* @author Tim Donohue
|
||||
*/
|
||||
public class FlywayUpgradeUtils {
|
||||
/**
|
||||
* log4j category
|
||||
*/
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(FlywayUpgradeUtils.class);
|
||||
|
||||
// Resource path of all Flyway upgrade scripts
|
||||
private static final String UPGRADE_SCRIPT_PATH = "org/dspace/storage/rdbms/flywayupgrade/";
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
private FlywayUpgradeUtils() { }
|
||||
|
||||
/**
|
||||
* Ensures the Flyway migration history table (FLYWAY_TABLE) is upgraded to the latest version of Flyway safely.
|
||||
* <P>
|
||||
* Unfortunately, Flyway does not always support skipping major versions (e.g. upgrading directly from Flyway
|
||||
* v3.x to 5.x is not possible, see https://github.com/flyway/flyway/issues/2126).
|
||||
* <P>
|
||||
* While sometimes it's possible to do so, other times you MUST upgrade through each major version. This method
|
||||
* ensures we upgrade the Flyway history table through each version of Flyway where deemed necessary.
|
||||
*
|
||||
* @param flyway initialized/configured Flyway object
|
||||
* @param connection current database connection
|
||||
*/
|
||||
protected static synchronized void upgradeFlywayTable(Flyway flyway, Connection connection)
|
||||
throws SQLException {
|
||||
// Whether the Flyway table needs updating or not
|
||||
boolean needsUpgrade = false;
|
||||
|
||||
// Determine if Flyway needs updating by running a simple info() command.
|
||||
// This command will not run any pending migrations, but it will throw an exception
|
||||
// if the Flyway migration history table is NOT valid for the current version of Flyway
|
||||
try {
|
||||
flyway.info();
|
||||
} catch (Exception e) {
|
||||
// ignore error, but log info statement to say we will try to upgrade to fix problem
|
||||
log.info("Flyway table '{}' appears to be outdated. Will attempt to upgrade it automatically. " +
|
||||
"Flyway Exception was '{}'", FLYWAY_TABLE, e.toString());
|
||||
needsUpgrade = true;
|
||||
}
|
||||
|
||||
if (needsUpgrade) {
|
||||
// Get the DSpace version info from the LAST migration run.
|
||||
String lastMigration = getCurrentFlywayState(connection);
|
||||
// If this is an older DSpace 5.x compatible database, then it used Flyway 3.x.
|
||||
// Because we cannot upgrade directly from Flyway 3.x -> 6.x, we need to FIRST update this
|
||||
// database to be compatible with Flyway 4.2.0 (which can be upgraded directly to Flyway 6.x)
|
||||
if (lastMigration.startsWith("5.")) {
|
||||
// Based on type of DB, get path to our Flyway 4.x upgrade script
|
||||
String dbtype = getDbType(connection);
|
||||
String scriptPath = UPGRADE_SCRIPT_PATH + dbtype + "/upgradeToFlyway4x.sql";
|
||||
|
||||
log.info("Attempting to upgrade Flyway table '{}' using script at '{}'",
|
||||
FLYWAY_TABLE, scriptPath);
|
||||
// Load the Flyway v4.2.0 upgrade SQL script as a String
|
||||
String flywayUpgradeSQL = MigrationUtils.resourceToString(
|
||||
new ClassPathResource(scriptPath, FlywayUpgradeUtils.class.getClassLoader()));
|
||||
|
||||
// As this Flyway upgrade SQL was borrowed from Flyway v4.2.0 directly, it contains some inline
|
||||
// variables which need replacing, namely ${schema} and ${table} variables.
|
||||
// We'll use the StringSubstitutor to replace those variables with their proper values.
|
||||
Map<String, String> valuesMap = new HashMap<>();
|
||||
valuesMap.put("schema", getSchemaName(connection));
|
||||
valuesMap.put("table", FLYWAY_TABLE);
|
||||
StringSubstitutor sub = new StringSubstitutor(valuesMap);
|
||||
flywayUpgradeSQL = sub.replace(flywayUpgradeSQL);
|
||||
|
||||
// Run the script to update the Flyway table to be compatible with FLyway v4.x
|
||||
executeSql(connection, flywayUpgradeSQL);
|
||||
}
|
||||
// NOTE: no other DSpace versions require a specialized Flyway upgrade script at this time.
|
||||
// DSpace 4 didn't use Flyway. DSpace 6 used Flyway v4, which Flyway v6 can update automatically.
|
||||
|
||||
// After any Flyway table upgrade, we MUST run a Flyway repair() to cleanup migration checksums if needed
|
||||
log.info("Repairing Flyway table '{}' after upgrade...", FLYWAY_TABLE);
|
||||
flyway.repair();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
--
|
||||
-- Copyright 2010-2017 Boxfuse GmbH
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
--
|
||||
-----------------
|
||||
-- This is the Oracle upgrade script from Flyway v4.2.0, copied/borrowed from:
|
||||
-- https://github.com/flyway/flyway/blob/flyway-4.2.0/flyway-core/src/main/resources/org/flywaydb/core/internal/dbsupport/oracle/upgradeMetaDataTable.sql
|
||||
--
|
||||
-- The variables in this script are replaced in FlywayUpgradeUtils.upgradeFlywayTable()
|
||||
------------------
|
||||
|
||||
DROP INDEX "${schema}"."${table}_vr_idx";
|
||||
DROP INDEX "${schema}"."${table}_ir_idx";
|
||||
ALTER TABLE "${schema}"."${table}" DROP COLUMN "version_rank";
|
||||
ALTER TABLE "${schema}"."${table}" DROP PRIMARY KEY DROP INDEX;
|
||||
ALTER TABLE "${schema}"."${table}" MODIFY "version" NULL;
|
||||
ALTER TABLE "${schema}"."${table}" ADD CONSTRAINT "${table}_pk" PRIMARY KEY ("installed_rank");
|
||||
UPDATE "${schema}"."${table}" SET "type"='BASELINE' WHERE "type"='INIT';
|
@@ -0,0 +1,29 @@
|
||||
--
|
||||
-- Copyright 2010-2017 Boxfuse GmbH
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
--
|
||||
-----------------
|
||||
-- This is the PostgreSQL upgrade script from Flyway v4.2.0, copied/borrowed from:
|
||||
-- https://github.com/flyway/flyway/blob/flyway-4.2.0/flyway-core/src/main/resources/org/flywaydb/core/internal/dbsupport/oracle/upgradeMetaDataTable.sql
|
||||
--
|
||||
-- The variables in this script are replaced in FlywayUpgradeUtils.upgradeFlywayTable()
|
||||
------------------
|
||||
|
||||
DROP INDEX "${schema}"."${table}_vr_idx";
|
||||
DROP INDEX "${schema}"."${table}_ir_idx";
|
||||
ALTER TABLE "${schema}"."${table}" DROP COLUMN "version_rank";
|
||||
ALTER TABLE "${schema}"."${table}" DROP CONSTRAINT "${table}_pk";
|
||||
ALTER TABLE "${schema}"."${table}" ALTER COLUMN "version" DROP NOT NULL;
|
||||
ALTER TABLE "${schema}"."${table}" ADD CONSTRAINT "${table}_pk" PRIMARY KEY ("installed_rank");
|
||||
UPDATE "${schema}"."${table}" SET "type"='BASELINE' WHERE "type"='INIT';
|
Reference in New Issue
Block a user