AppSuite:DBMigration: Difference between revisions

From Open-Xchange
No edit summary
 
(13 intermediate revisions by 4 users not shown)
Line 3: Line 3:
{{VersionFrom|7.6.1}}
{{VersionFrom|7.6.1}}


<div class="title">How to write custom bundles to execute database migration statements.</div>
<div class="title">Database migration for Open-Xchange server.</div>


'''Summary''': With release 7.6.1 it is possible to change the database schema based on usage of the open source tool Liquibase. Currently only updating the configdb with the new mechanism is desired. This article gives a short introduction based on an existing sample bundle how to write custom database migration bundles and how to attach your custom statements to those given by Open-Xchange.  
'''Summary''': With release 7.6.1 it is possible to change the database schema based on usage of the open source tool Liquibase. Currently this applies to the config database, as well as so-called global databases for storing cross-context data (available with v7.8). This article gives a short introduction about the current implementation.


Please have a look at liquibase, its features and documentation before writing custom bundles: http://www.liquibase.org/documentation/ .
Please have a look at Liquibase, its features and documentation before working with database migrations for Open-Xchange server: http://www.liquibase.org/documentation/ and http://www.liquibase.org/bestpractices.html .
 
Ho to create custom bundles is explained in an extra article: http://oxpedia.org/wiki/index.php?title=AppSuite:CustomDBMigration


__TOC__
__TOC__


== Prerequisite ==
== Database migration bundles ==
This article is based on an existing sample bundle located in the public git repository backend-samples. Clone the repository by executing
The following bundles provide the functionality for executing database migration statements. All are included within the open-xchange-core package.


<code><pre>
* com.openexchange.database.migration: Provides the service to execute database migrations and the core database ChangeLogs
git clone https://git.open-xchange.com/git/examples/backend-samples
* com.openexchange.database.migration.clt: Provides a command line tool that might help by working with database migrations based on Liquibase
</pre></code>
 
The required bundle is named 'com.openexchange.sample.database.migration'.


== Current restrictions ==
== Current restrictions ==
* Database migrations can only be applied to the configdb!
* Open-Xchange server currently uses Liquibase version 3.0.7. All features provided with later versions cannot be used.
* Open-Xchange server currently uses liquibase version 3.0.7. All features provided with later versions cannot be used.
 
== Bundle dependencies ==
To execute custom database migration for the configdb you have to track the service com.openexchange.database.migration.DBMigrationExecutorService (default provided within bundle com.openexchange.database.migration).
 
If you would like to have the Open-Xchange database migrations executed before your custom statements are used you even have to track the service com.openexchange.database.migration.ox.DBMigrationOXExcecutorService which is provided within the bundle com.openexchange.database.migration.ox


== Liquibase ==
== Liquibase ==
The following chapter describes in short the liquibase features and how they are used by Open-Xchange. For further information have a look at the official liquibase documentation: http://www.liquibase.org/documentation/
The following chapter describes shortly the Liquibase features and how they are used by Open-Xchange. For further information have a look at the official Liquibase documentation: http://www.liquibase.org/documentation/


=== ChangeLog file / changeSets ===
=== ChangeLog file / changeSets ===
A ChangeLog file is the heart of this database migration and contains all information required to change database structure and/or contents. It consists of ChangeSets that are used to define a migration. Normally ChangeSets are executed transactionally.
A ChangeLog file is the heart of this database migration and contains all information required to change database structure and/or contents. It consists of ChangeSets that are used to define a migration. Normally ChangeSets are executed transactionally.
You have to provide a ChangeLog file that contains some ChangeSets that reflect your desired database migration. Within the sample bundle the file 'custom.changelog.xml' is referenced.


=== Tags ===
=== Tags ===
A ChangeSet can be used to tag the database at a current state. Open-Xchange uses this mechanism to tag the database to be ready for a new release.  
A ChangeSet can be used to tag the database at a current state. Open-Xchange uses this mechanism to tag the database to be ready for a new release.  
Tags are not used in the sample custom bundle.
=== Preconditions ===
You are even able to define dependencies between ChangeSets. With that you can attach your custom ChangeSet to whatever ChangeSet you would like to. Open-Xchange uses this for ChangeSets that should be executed after the database has been tagged for a new release. All ChangeSets after tagging checks if the precondition is true. You can create complex conditions by using nested conditions. For further information have a look at the following documentation: http://www.liquibase.org/documentation/preconditions.html
Within the custom bundle the precondition is defined as follows: the changeSet with id="7.6.1:login2context:login_info", author="martin.schneider" and changeLogFile="release-7.6.1/1.login_info.changelog.xml" have to be executed (defined in ox.changelog.xml) so that all changeSets within custom.changelog.xml will become executed.


=== Database ===
=== Database ===
Line 52: Line 36:
Liquibase creates two tables to handle its current state:
Liquibase creates two tables to handle its current state:


* LIQUIBASECHANGELOG: Contains information about the execution status of ChangeSets. Each executed ChangeSet will be added to this table. If there is no entry available for a ChangeSet liquibase will try to execute the statement.
* DATABASECHANGELOG: Contains information about the execution status of ChangeSets. Each executed ChangeSet will be added to this table. If there is no entry available for a ChangeSet Liquibase will try to execute the statement.
* LIQUIBASECHANGELOGLOCK: Handles access to the database to not execute database migration statements twice.
* DATABASECHANGELOGLOCK: Handles access to the database to not execute database migration statements twice.


==== Database lock ====
==== Database lock ====


Liquibase uses a lock to only grant one liquibase instace access to the database to change. For this purpose a table named 'DATABASECHANGELOGLOCK' is created. In cluster environments the first node that successfully aquired the lock will execute the database migration statements. During this time all other nodes are blocked. After the lock was released the second node will get access to the database and read already executed ChangeSets. If all ChangeSets have been executed nothing will be done and the lock will be released. This happens with each node within the cluster.
Liquibase uses a lock to only grant one Liquibase instace access to the database to change. For this purpose a table named 'DATABASECHANGELOGLOCK' is created. In cluster environments the first node that successfully aquired the lock will execute the database migration statements. During this time all other nodes are blocked. After the lock was released the second node will get access to the database and read already executed ChangeSets. If all ChangeSets have been executed nothing will be done and the lock will be released. This happens with each node within the cluster.


=== Custom Java Classes ===
=== Custom Java Classes ===


Within your custom ChangeLog xml file you are not only able to define changes descriptive but even execute database statements defined within a class that implements CustomSqlChange.
Implementing CustomSqlChange enables you to write custom SQL statements instead of using declarative statements
 
== Implementation details ==
 
The Open-Xchange server will wait within the startup until all provided Liquibase update tasks have been executed to ensure consistent data usage!


Have a look at the sample bundle which references and executes com.openexchange.sample.database.migration.custom.ExampleCustomSqlChange.
== Command line tool ==
Currently a command line tools is provided to manage the migrations: ''/opt/open-xchange/sbin/dbmigrations'' (Note: in versions prior v7.8, the utitlity is named ''configdbmigrations'', and the ''name'' option is missing):


== Command line tools ==
usage: dbmigrations
-A,--adminuser <arg>        Admin username
-h,--help                    Prints a help text
-l,--login <arg>            The optional JMX login (if JMX
                              authentication is enabled)
-ll,--list-locks            Lists all currently acquired locks.
-n,--name <arg>              The database schema name to use
-P,--adminpass <arg>        Admin password
-p,--port <arg>              The optional JMX port (default:9999)
-r,--run                    Forces a run of the current core changelog.
    --responsetimeout <arg>  The optional response timeout in seconds
                              when reading data from server (default: 0s;
                              infinite)
-s,--password <arg>          The optional JMX password (if JMX
                              authentication is enabled)
-t,--host <arg>              The optional JMX host (default:localhost)
-u,--force-unlock            Forces a release of all locks.
Prints the current migration status if no option is set.


== Important hints ==  
== Important hints ==  
* changeSets are uniquely identified by its id, author and path. Use the parameter 'logicalFilePath' for every changeSet you create to set a path that can be globally identified! If you do not set a logical file path liquibase will use the physical path of the file the changeSet is located in. With that each changeSet on different cluster nodes might have been identified as a new one.
* ChangeSets are executed top-down within a ChangeLog, so always add new migrations at the bottom of the file. For migrations regarding core components always use the configdbChangeLog.xml in com.openexchange.database.migration/resource/liquibase. For non-core components see [[AppSuite:CustomDBMigration]].
* if you would like to use <include> statements to reference other files with liquibase statements we suggest adding parameter 'relativeToChangelogFile="true"' to avoid adding complete paths.
* ChangeSets must be constructed in an idempotent manner, i.e. they must not fail or break something if they are run several times. Use preconditions with onFail="MARK_RAN" to achieve this.
* If you are adding the first migration for an upcoming release, add an according milestone tag after the actual migration ChangeSets!
* If you would like to use <include> statements to reference other files with Liquibase statements we suggest adding parameter 'relativeToChangelogFile="true"' to avoid adding complete paths.
* http://www.liquibase.org/documentation/sql_output.html


[[Category: OX7]]
[[Category: OX7]]

Latest revision as of 10:03, 14 March 2019


This information is valid from 7.6.1 on.
Database migration for Open-Xchange server.

Summary: With release 7.6.1 it is possible to change the database schema based on usage of the open source tool Liquibase. Currently this applies to the config database, as well as so-called global databases for storing cross-context data (available with v7.8). This article gives a short introduction about the current implementation.

Please have a look at Liquibase, its features and documentation before working with database migrations for Open-Xchange server: http://www.liquibase.org/documentation/ and http://www.liquibase.org/bestpractices.html .

Ho to create custom bundles is explained in an extra article: http://oxpedia.org/wiki/index.php?title=AppSuite:CustomDBMigration

Database migration bundles

The following bundles provide the functionality for executing database migration statements. All are included within the open-xchange-core package.

  • com.openexchange.database.migration: Provides the service to execute database migrations and the core database ChangeLogs
  • com.openexchange.database.migration.clt: Provides a command line tool that might help by working with database migrations based on Liquibase

Current restrictions

  • Open-Xchange server currently uses Liquibase version 3.0.7. All features provided with later versions cannot be used.

Liquibase

The following chapter describes shortly the Liquibase features and how they are used by Open-Xchange. For further information have a look at the official Liquibase documentation: http://www.liquibase.org/documentation/

ChangeLog file / changeSets

A ChangeLog file is the heart of this database migration and contains all information required to change database structure and/or contents. It consists of ChangeSets that are used to define a migration. Normally ChangeSets are executed transactionally.

Tags

A ChangeSet can be used to tag the database at a current state. Open-Xchange uses this mechanism to tag the database to be ready for a new release.

Database

Database tables

Liquibase creates two tables to handle its current state:

  • DATABASECHANGELOG: Contains information about the execution status of ChangeSets. Each executed ChangeSet will be added to this table. If there is no entry available for a ChangeSet Liquibase will try to execute the statement.
  • DATABASECHANGELOGLOCK: Handles access to the database to not execute database migration statements twice.

Database lock

Liquibase uses a lock to only grant one Liquibase instace access to the database to change. For this purpose a table named 'DATABASECHANGELOGLOCK' is created. In cluster environments the first node that successfully aquired the lock will execute the database migration statements. During this time all other nodes are blocked. After the lock was released the second node will get access to the database and read already executed ChangeSets. If all ChangeSets have been executed nothing will be done and the lock will be released. This happens with each node within the cluster.

Custom Java Classes

Implementing CustomSqlChange enables you to write custom SQL statements instead of using declarative statements.

Implementation details

The Open-Xchange server will wait within the startup until all provided Liquibase update tasks have been executed to ensure consistent data usage!

Command line tool

Currently a command line tools is provided to manage the migrations: /opt/open-xchange/sbin/dbmigrations (Note: in versions prior v7.8, the utitlity is named configdbmigrations, and the name option is missing):

usage: dbmigrations

-A,--adminuser <arg>         Admin username
-h,--help                    Prints a help text
-l,--login <arg>             The optional JMX login (if JMX
                             authentication is enabled)
-ll,--list-locks             Lists all currently acquired locks.
-n,--name <arg>              The database schema name to use
-P,--adminpass <arg>         Admin password
-p,--port <arg>              The optional JMX port (default:9999)
-r,--run                     Forces a run of the current core changelog.
   --responsetimeout <arg>   The optional response timeout in seconds
                             when reading data from server (default: 0s;
                             infinite)
-s,--password <arg>          The optional JMX password (if JMX
                             authentication is enabled)
-t,--host <arg>              The optional JMX host (default:localhost)
-u,--force-unlock            Forces a release of all locks.

Prints the current migration status if no option is set.

Important hints

  • ChangeSets are executed top-down within a ChangeLog, so always add new migrations at the bottom of the file. For migrations regarding core components always use the configdbChangeLog.xml in com.openexchange.database.migration/resource/liquibase. For non-core components see AppSuite:CustomDBMigration.
  • ChangeSets must be constructed in an idempotent manner, i.e. they must not fail or break something if they are run several times. Use preconditions with onFail="MARK_RAN" to achieve this.
  • If you are adding the first migration for an upcoming release, add an according milestone tag after the actual migration ChangeSets!
  • If you would like to use <include> statements to reference other files with Liquibase statements we suggest adding parameter 'relativeToChangelogFile="true"' to avoid adding complete paths.
  • http://www.liquibase.org/documentation/sql_output.html