On 28-12-15 14:16, Rafael Weingärtner wrote:
> Hi all devs,
> First of all, sorry the long text, but I hope we can start a discussion
> here and improve that part of ACS.
> 
> A while ago I have faced the code that Apache CloudStack (ACS) uses to
> upgrade from a version to newer one and that did not seem to be a good way
> to execute our upgrades. Therefore, I decided to use some time to search
> for alternatives.
> 

I think we all saw that happen once or more :)

> I have read some material about versioning of scripts used to upgrade a
> database (DB) of a system and went through some frameworks that could help
> us.
> 
> In the literature of software engineering, it is firmly stated that we have
> to version DB scripts as we do with the source code of the application,
> using the baseline approach. Gladly, we were not that bad at this point, we
> already versioned our routines for DB upgrade (.sql and .java). Therefore,
> it seemed that we just did not have used a practical approach to help us
> during DB upgrades.
> 
> From my readings and looking at the ACS source code I raised the following
> requirement:
> •    We should be able to write more than one routine to upgrade to a
> version; those routines can be written in Java and SQL. We might have more
> than a routine to be executed for each version and we should be able to
> define an order of execution. Additionally, to go to an upper version, we
> have to run all of the routines from smaller versions first, until we
> achieve the desired version.
> 
> We could also add another requirement that is the downgrade from a version,
> which we currently do not support. With that comes my first question for
> discussion:
> •    Do we want/need a method to downgrade from a version to a previous one?
> 

I personally do not care. Usually people should create a backup PRIOR to
a upgrade. If that fails they can restore the backup.

> I found an explanation for not supporting downgrades, and I liked it:
> http://flywaydb.org/documentation/faq.html#downgrade
> 
> So, what I devised for us:
> First the bureaucracy part  - our migrations occur basically in three (3)
> steps, first we have a "prepare script", then a cleanup script and finally
> the migration per se that is written in Java, at least, that is what we can
> expect when reading the interface “com.cloud.upgrade.dao.DbUpgrade”.
> 
> Additionally, our scripts have the following naming convention:
> schema-<currentVersion>to<desiredVersion>, which in IMHO may cause some
> confusion because at first sight we may think that from the same version we
> could have different paths to an upper version, which in practice is not
> happening. Instead of a <currentVersion>to<version> we could simply use
> V_<numberOfVersion>_<sequencial>.<fileExtension>, giving that, we have to
> execute all of the V_<version> scripts that are smaller than the version we
> want to upgrade.
> 
> To clarify what I am saying, I will use an example. Let’s say we have just
> installed ACS and ran the cloudstack-setup-database. That command will
> create a database schema in version 4.0.0. To upgrade that schema to
> version 4.3.0 (it is just an example, it could be any other version), ACS
> will use the following mapping:
> 
> _upgradeMap.put("4.0.0", new DbUpgrade[] {new Upgrade40to41(), new
> Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430())
> 
> After loading the mapping, ACS will execute the scripts defined in each one
> of the Upgrade path classes and the migration code per se.
> 
> Now, let’s say we change the “.sql” scripts name to the pattern I
> mentioned, we would have the following scripts; those are the scripts found
> that aim to upgrade to versions between the interval 4.0.0 – 4.3.0
> (considering 4.3.0, since that is the goal version):
> 
> 
>    - schema-40to410, can be named to:  V_410_A.sql
>    - schema-40to410-cleanup, can be named to:  V_410_B.sql
>    - schema-410to420, can be named to:  V_420_A.sql
>    - schema-410to420-cleanup , can be named to:  V_420_b.sql
>    - schema-420to421, can be named to:  V_421_A.sql
>    - schema-421to430, can be named to:  V_430_A.sql
>    - schema-421to430-cleanup, can be named to:  V_430_B.sql
> 
> 
> Additionally, all of the java code would have to follow the same
> convention. For instance, we have “com.cloud.upgrade.dao.Upgrade40to41”,
> which has some java code to migrate from 4.0.0 to 4.1.0. The idea is to
> extract that migration code to a Java class named:  V_410_C.java, giving
> that it has to execute the SQL scripts before the java code.
> 
> In order to go from a smaller version (4.0.0) to an upper one (4.3.0), we
> have to run all of the migration routines from intermediate versions. That
> is what we are already doing, but we do all of that manually.
> 
> Bottom line, I think we could simple use the convention
> V_<numberOfVersion>_<sequencial>.<fileExtension> to name upgrade routines.
> That would facilitate us to use a framework to help us with that process.
> Additionally, I believe that we should always assume that to go from a
> smaller version to a higher one, we should run all of the scripts that
> exist between them. What do you guys think of that?
> 

That seems good to me. But we still have to prevent that we perform
database changes in a X.Y.Z release since that is branched off to a
different branch.

Imho database changes should only happen in X.Y releases.

> After the bureaucracy, we can discuss tools. If we use that convention to
> name migration (upgrade) routines, we can start thinking on tools to
> support our migration process. I found two (2) promising ones: Liquibase
> and Flywaydb (both seem to be under Apache license, but the first one has
> an enterprise version?!). After reading the documentation and some usage
> examples I found the flywaydb easier and simpler to use.
> 
> What are the options of tools that we can use to help us manage the
> database upgrade, without needing to code the upgrade path that you know?
> 
> After that, I think we should decide if we should create another
> project/component to take care of migrations, or we can just  add the
> dependency of the tool to a project such as “cloud-framework-db” and start
> using it.
> 
> The “cloud-framework-db” project seems to have a focus on other things such
> as managing transactions and generating SQLs from annotations (?!? That
> should be a topic for another discussion). Therefore, I would rather create
> a new project that has the specific goal of managing ACS DB upgrades.  I
> would also move all of the routines (SQL and Java) to this new project.
> This project would be a module of the CloudStack project and it would
> execute the upgrade routines at the startup of ACS.
> 
> I believe that going from a homemade solution to one that is more
> consolidated and used by other communities would be the way to go.
> 
> I can volunteer myself to create a PR with the aforementioned changes and
> using flywaydb to manage our upgrades. However, I prefer to have a good
> discussion with other devs first, before starting coding.
> 
> Do you have suggestions or points that should be raised before we start
> working on that?

Rohit suggested Chimp earlier this year:
http://mail-archives.apache.org/mod_mbox/cloudstack-dev/201508.mbox/%3c677bd09f-fc75-4888-8dc8-2b7af7439...@shapeblue.com%3E

The thread is called: "[DISCUSS] Let's fix CloudStack Upgrades and DB
migrations with CloudStack Chimp"

Maybe there is something good in there.

> 
> --
> Rafael Weingärtner
> 

Reply via email to