> gh-ost
--host localhost \
--database testdb \
--user root \
--password root \
--table transactions \
--alter 'ADD COLUMN is_deleted TINYINT' \
Julien Roy @ Bankin'
Aide à la gestion d’argent
Agregation données bancaire
Interface de virements bancaire
B2C : Application iOS / Android ( bankin.com )
B2B : API SaaS ( bridgeapi.io )
Backend Java
Bases de données MySQL ( 3 To )
Hébergement AWS RDS Aurora
Mise en production sans downtime
Migration de schéma de base de données
MySQL lock toute la table durant le processus
Peux prendre des heures pour certaines tables
Triggerless online schema migration for MySQL
GitHub ( Shlomi Noach ) : http://code.openark.org
Open Source
> gh-ost
--host localhost \
--database testdb \
--user root \
--password root \
--table transactions \
--alter 'ADD COLUMN is_deleted TINYINT' \
Intégré au pipeline de déploiement
Orchestré par FlywayDB
Utilisation de JDBC pour les CREATE TABLE
Utilisation de gh-ost pour les ALTER TABLE
class GhostMigrationExecutor : MigrationExecutor {
override fun execute(context: Context) {
val jdbcTemplate = JdbcTemplate(context.connection)
for (statement in sqlScript.sqlStatements) {
if (isAlterTable(statement.sql)) {
executeWithGhost(context, statement)
} else {
executeSql(jdbcTemplate, statement)
}
}
}
...
private fun executeSql(jdbc: Jdbc, statement: Statement) {
val results = jdbc.executeStatement(statement.sql)
...
}
private fun executeWithGhost(table: String, alter: String) {
val cmds: MutableList<String> = ArrayList()
cmds.add("gh-ost")
cmds.add("--user=$user")
cmds.add("--password=$password")
cmds.add("--host=${connexion.host}")
...
cmds.add("--table=$table")
cmds.add("--alter=$alter")
cmds.add("--chunk-size=10000")
cmds.add("--cut-over=atomic")
cmds.add("--execute")
ProcessBuilder().inheritIO().command(cmds).start()
...
try {
val p = processBuilder.start()
if (p.waitFor() != 0) {
throw FlywayException("Migration failed !")
}
} catch (e: IOException) {
throw FlywayException("Migration failed !", e)
} catch (e: InterruptedException) {
throw FlywayException("Migration failed !", e)
}
}
Tester sur un replicat
Tester en dry-run en Prod
Verifier les synchronisation entre les tables
Utiliser une session background ( screen
, tmux
)
Bin log activé ( mode RBR )
Foreign key non supporté
Triggers non supporté
Tables doivent partager une clé unique
Percona : pt-online-schema-change
Facebook : OnlineSchemaChange
SoundCloud : lhm
MySQL : Online DDL ( bcp de limitations , pas de pause , throttle, or rollback )
AWS Aurora : FastDDL ( Seulement mode lab, non recommandé en Production )