Skip to content

How to rollback patches

ulisespulido edited this page Nov 10, 2011 · 3 revisions

One of the features since AutoPatch 1.2 is that patches can be rolled back. A rollback is when a patch of a system is removed. AutoPatch can execute rollback anywhere from one patch to multiple patches on a system(Depending on the strategy being used.). All you have to do is let AutoPatch know what patch(es) you'd like to rollback and then AutoPatch will do the rest.

Rollback process on the default migration strategy (Ordered strategy)

To execute a rollback, reuse the StandaloneMigrationLauncher and specify a few additional parameters. These are: -rollback to indicate that the desired migration is a rollback and an integer indicating the desired patch level. So, to run a rollback from the command line java StandaloneMigrationLauncher -rollback 5. This command would instruct AutoPatch to rollback the system to patch level 5. Additionally, there is a -force parameter. This parameter tells AutoPatch to ignore a check to see if all patches are rollbackable and to force a rollback. Note that forcing a rollback is dangerous as it can quite easily cause an exception scenario.

The important thing to recognize with patch levels is that a rollback will reduce the patch level. For example, if you execute a rollback of patch level 5, the patch level of the system will be at patch level 4 after the rollback has completed. Rollbacks are executed in a descending manner.

Rollback process on the Missing Patch migration strategy

To execute a rollback, reuse the StandaloneMigrationLauncher and specify a few additional parameters. These are: -rollback to indicate that the desired migration is a rollback and an integer or a list of integers separated by comma indicating the desired patches to rollback. So, to run a rollback from the command line java StandaloneMigrationLauncher -rollback 5,8. This command would instruct AutoPatch to remove the patch 5 AND 8 from the system. Additionally, there is a -force parameter. This parameter tells AutoPatch to ignore a check to see if all patches are rollbackable and to force a rollback. Note that forcing a rollback is dangerous as it can quite easily cause an exception scenario.

The important thing to recognize with patch levels is that a rollback will remove the patch but it does not imply that the patch level is reduced. For example, if you execute a rollback of the patch 5 in a system with patch level 8, the patch level of the system will remain 8 after the rollback but the patch 5 does not longer exist.

General process for all Migration Strategies when rollbacking.

Similar to the patch process, applications that use rollbacks need to instantiate a MigrationLauncher. You can accomplish this by implementing an Adapter that executes upon application startup or using one of the provided launchers. Instead of calling doMigrations, the Launcher should call doRollbacks. This method takes in an array of ints and a boolean. The array of integers indicates the level that the system should rollback to, in case of the ordered strategy, or the patches to remove from the system in case of the missing patch strategy.

The boolean indicates if the system should attempt to force a rollback. Why would you need to force a rollback? Because the people may have implemented their own tasks by implementing the MigrationTask interface, it is possible that there are migrations that do not currently support rollbacks. Moreover, there are "destructive" migrations that are fundamentally not rollbackable. By default, a rollback will only occur if all of the rollback tasks are rollbackable. This check happens before any of the rollbacks are executed, so if you attempt to initiate a rollback for a set of tasks and one of the tasks is not rollbackable, no rollbacks will execute. The logs generated by AutoPatch will indicate which tasks are not rollbackable. To provide the greatest level of flexibility, we have included a way of getting around this rule, which is using the "-force" flag. This flag tells AutoPatch that it should ignore the rollbackable check and proceed with the rollback. Please keep in mind that this is risky as it's possible to try to rollback tasks that throw exceptions if a rollback is attempted. The best option is to make your tasks adhere to the new RollbackableMigrationTask interface. If you need to be able to force rollbacks, implement the down method to be a no-op method and then also set isRollbackSupported to true. Following these steps will allow for AutoPatch to successfully execute the task as a rollback.

The next step is to find the patches. To make this easy, what we've done is deprecated the existing MigrationTask object and added a new interface called RollbackableMigrationTask. Additionally, we've extended the functionality that loads SQL scripts into tasks to include rollback scripts. So, for your existing patches, you'll just need to create a new SQL script and make it available for AutoPatch to load. Rollback scripts are named as follows: patch-rollback_{patch name}.sql. An example of a valid rollback file name is patch111-rollback_testname.sql. In this case, the 111 is the level of the patch. Conceptually, you should think of this script as inherently linked to the forward patch. The mechanism that associates a patch SQL script and a rollback SQL script is the level. So, patch111_testname.sql and patch111-rollback_testname.sql are linked. Please note that the name of the patch does not have any role in linking a patch and its rollback. In fact, patch111.sql and patch111-rollback_foo.sql would be associated.

Just as with the up process for patching, the ordering in which rollbacks execute is important. Autopatch executes rollbacks in a descending manner based upon the patch level. So, if you were to issue a rollback to level 10 and the system is at level 13, the patches that rollback would be 13, 12 and 11 in case of the ordered migration strategy and if you were to issue a rollback to patches 10,12,11 the patches that rollback would be 12,11,10 for the missing patch strategy.