I think the proper solution would be to delete the V004_ migration. This migration originally landed in the 0.14.0 release. Removing this migration means an upgrade directly from 0.13.0 to 0.18.0 would not be possible, but I suspect it wouldn't be possible for other reasons as well (i.e. too large of a jump in mesos versions for a single upgrade).
Unfortunately I didn't account for this scenario when I wrote the MigrationManager[1]. Specifically, the way it handles rollbacks is by comparing the list of applied migrations from the CHANGELOG table (descending by id) to the migrations found on the classpath. If it finds a migration in the CHANGELOG table that doesn't exist on the classpath, it will invoke the downgrade script that was stored in the CHANGELOG table when the migration was first applied. Thankfully as soon as it finds a migration that has been applied and still exists, it assumes no rollback and short circuits the process. So, in practice, as long as the V005_ migration still exists on the classpath, deleting the V004_ migration shouldn't have an impact. That said, it would still make me nervous to leave that gap there, due to the potential for unforeseen consequences and the possibly disastrous nature of inadvertently rolling back a DB change that shouldn't be rolled back. Perhaps a better solution is to just update the V004_ migration so that its `getUpScript` and `getDownScript` methods are just no-op SQL statements. That way people starting fresh after this change will still have a record of the migration being run, it will just have been a no-op. I think we'd need to think the various scenarios through carefully though (clean install, roll forward between releases, roll back between releases...), to ensure there are no cases I'm missing. [1] https://github.com/apache/aurora/blob/master/src/main/java/org/apache/aurora/scheduler/storage/db/MigrationManagerImpl.java On Wed, Feb 15, 2017 at 12:20 PM, Nicolas Donatucci <ndonatu...@medallia.com > wrote: > Hi, I'm currently working on removing the deprecated fields numCpus, ramMb > and diskMb from the TaskConfig. > > After removing them from the schema.sql and adding the corresponding DB > migration, when building, there are four tests that fail. > > These are: > > - testMigrateToDBTaskStore > - testMigrateFromDBTaskStore > - testNoDBTaskStore > - testDBTaskStore > > They all throw a Storage Exception and the stacktrace (for > testMigrateToDBTaskStore) is: > > 0215 15:17:53.635 [main, h2database] jdbc[4] exception > org.h2.jdbc.JdbcSQLException: Column "T.NUM_CPUS" not found; SQL statement: > MERGE INTO task_resource(task_config_id, type_id, value) > KEY(task_config_id, type_id, value) SELECT t.id, rt.id, t.num_cpus FROM > task_configs t JOIN resource_types rt ON rt.name = 'CPUS' > [42122-193] > at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.message.DbException.get(DbException.java:179) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.message.DbException.get(DbException.java:155) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:147) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.command.dml.Select.prepare(Select.java:853) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.command.dml.Merge.prepare(Merge.java:260) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.command.Parser.prepareCommand(Parser.java:259) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.engine.Session.prepareLocal(Session.java:561) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.engine.Session.prepareCommand(Session.java:502) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1203) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:170) > ~[h2-1.4.193.jar:1.4.193] > at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:158) > ~[h2-1.4.193.jar:1.4.193] > at > org.apache.ibatis.jdbc.ScriptRunner.executeStatement( > ScriptRunner.java:235) > [mybatis-3.4.1.jar:3.4.1] > at org.apache.ibatis.jdbc.ScriptRunner.handleLine(ScriptRunner.java:208) > [mybatis-3.4.1.jar:3.4.1] > at > org.apache.ibatis.jdbc.ScriptRunner.executeLineByLine( > ScriptRunner.java:140) > [mybatis-3.4.1.jar:3.4.1] > at org.apache.ibatis.jdbc.ScriptRunner.runScript(ScriptRunner.java:107) > [mybatis-3.4.1.jar:3.4.1] > at > org.apache.ibatis.migration.operations.UpOperation. > operate(UpOperation.java:50) > [mybatis-migrations-3.2.0.jar:3.2.0] > at > org.apache.aurora.scheduler.storage.db.MigrationManagerImpl.migrate( > MigrationManagerImpl.java:65) > [production/:na] > at > org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl$ > 1.restoreFromSnapshot(SnapshotStoreImpl.java:176) > [production/:na] > at > org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl. > lambda$applySnapshot$1(SnapshotStoreImpl.java:498) > [production/:na] > at > org.apache.aurora.scheduler.storage.Storage$MutateWork$ > NoResult.apply(Storage.java:152) > ~[production/:na] > at > org.apache.aurora.scheduler.storage.Storage$MutateWork$ > NoResult.apply(Storage.java:147) > ~[production/:na] > at > org.apache.aurora.scheduler.storage.db.DbStorage. > transactionedWrite(DbStorage.java:162) > ~[production/:na] > at > org.apache.aurora.scheduler.storage.db.DbStorage$$ > EnhancerByGuice$$df3385de.CGLIB$transactionedWrite$4(<generated>) > ~[guice-3.0.jar:na] > at > org.apache.aurora.scheduler.storage.db.DbStorage$$ > EnhancerByGuice$$df3385de$$FastClassByGuice$$4b048fd7.invoke(<generated>) > ~[guice-3.0.jar:na] > at > com.google.inject.internal.cglib.proxy.$MethodProxy. > invokeSuper(MethodProxy.java:228) > ~[guice-3.0.jar:na] > at > com.google.inject.internal.InterceptorStackCallback$ > InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) > ~[guice-3.0.jar:na] > at > org.mybatis.guice.transactional.TransactionalMethodInterceptor.invoke( > TransactionalMethodInterceptor.java:101) > ~[mybatis-guice-3.7.jar:3.7] > at > com.google.inject.internal.InterceptorStackCallback$ > InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) > ~[guice-3.0.jar:na] > at > com.google.inject.internal.InterceptorStackCallback.intercept( > InterceptorStackCallback.java:52) > ~[guice-3.0.jar:na] > at > org.apache.aurora.scheduler.storage.db.DbStorage$$ > EnhancerByGuice$$df3385de.transactionedWrite(<generated>) > ~[guice-3.0.jar:na] > at > org.apache.aurora.scheduler.storage.db.DbStorage.lambda$ > write$0(DbStorage.java:176) > ~[production/:na] > at > org.apache.aurora.scheduler.storage.db.DbModule$1$1. > closeDuring(DbModule.java:213) > ~[production/:na] > at > org.apache.aurora.scheduler.storage.db.DbStorage.write(DbStorage.java:174) > ~[production/:na] > at > org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.applySnapshot( > SnapshotStoreImpl.java:494) > [production/:na] > at > org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.applySnapshot( > SnapshotStoreImpl.java:77) > [production/:na] > at > org.apache.aurora.scheduler.storage.log.SnapshotStoreImplIT. > testMigrateToDBTaskStore(SnapshotStoreImplIT.java:144) > ~[test/:na] > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > ~[na:1.8.0_112] > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: > 62) > ~[na:1.8.0_112] > at > sun.reflect.DelegatingMethodAccessorImpl.invoke( > DelegatingMethodAccessorImpl.java:43) > ~[na:1.8.0_112] > at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112] > at > org.junit.runners.model.FrameworkMethod$1.runReflectiveCall( > FrameworkMethod.java:50) > ~[junit-4.12.jar:4.12] > at > org.junit.internal.runners.model.ReflectiveCallable.run( > ReflectiveCallable.java:12) > ~[junit-4.12.jar:4.12] > at > org.junit.runners.model.FrameworkMethod.invokeExplosively( > FrameworkMethod.java:47) > ~[junit-4.12.jar:4.12] > at > org.junit.internal.runners.statements.InvokeMethod. > evaluate(InvokeMethod.java:17) > ~[junit-4.12.jar:4.12] > at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) > ~[junit-4.12.jar:4.12] > at > org.junit.runners.BlockJUnit4ClassRunner.runChild( > BlockJUnit4ClassRunner.java:78) > ~[junit-4.12.jar:4.12] > at > org.junit.runners.BlockJUnit4ClassRunner.runChild( > BlockJUnit4ClassRunner.java:57) > ~[junit-4.12.jar:4.12] > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) > ~[junit-4.12.jar:4.12] > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) > ~[junit-4.12.jar:4.12] > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) > ~[junit-4.12.jar:4.12] > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) > ~[junit-4.12.jar:4.12] > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) > ~[junit-4.12.jar:4.12] > at org.junit.runners.ParentRunner.run(ParentRunner.java:363) > ~[junit-4.12.jar:4.12] > at org.junit.runner.JUnitCore.run(JUnitCore.java:137) > ~[junit-4.12.jar:4.12] > at > com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs( > JUnit4IdeaTestRunner.java:117) > ~[junit-rt.jar:na] > at > com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs( > JUnit4IdeaTestRunner.java:42) > ~[junit-rt.jar:na] > at > com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart( > JUnitStarter.java:262) > ~[junit-rt.jar:na] > at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84) > ~[junit-rt.jar:na] > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > ~[na:1.8.0_112] > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: > 62) > ~[na:1.8.0_112] > at > sun.reflect.DelegatingMethodAccessorImpl.invoke( > DelegatingMethodAccessorImpl.java:43) > ~[na:1.8.0_112] > at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112] > at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) > ~[idea_rt.jar:na] > > So the problem seems to be that the migration V004 is running, and it tries > to read the no-longer existing values. > Removing the call to "migration()" in the V004 getUpScript() solves the > issue. > > Has anyone got an idea on what can be done with this? > Thanks! >