Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
[ICSE '17] Zero-Downtime SQL Database Schema Ev...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Michael de Jong
May 25, 2017
Research
1
850
[ICSE '17] Zero-Downtime SQL Database Schema Evolution for Continuous Deployment
Presentation given at ICSE 2017 in Buenos Aires in the "Software Engineering In Practice" track.
Michael de Jong
May 25, 2017
Tweet
Share
More Decks by Michael de Jong
See All by Michael de Jong
[SIC '16] Zero-Downtime Database Schema Evolution
michaeldejong
0
170
Zero-Downtime SQL Database Schema Evolution for Continuous Deployment
michaeldejong
0
390
[RELENG '15] Continuous Deployment & Schema Evolution in SQL Databases
michaeldejong
0
1.4k
[CHISEL] Introduction to zero-downtime schema evolution in SQL databases.
michaeldejong
2
260
[CHISEL] Software Engineering at Magnet.me
michaeldejong
1
340
Contributing to RxJava
michaeldejong
2
640
Other Decks in Research
See All in Research
視覚から身体性を持つAIへ: 巧緻な動作の3次元理解
tkhkaeio
1
220
病院向け生成AIプロダクト開発の実践と課題
hagino3000
0
580
FUSE-RSVLM: Feature Fusion Vision-Language Model for Remote Sensing
satai
3
250
英語教育 “研究” のあり方:学術知とアウトリーチの緊張関係
terasawat
1
600
LLM-jp-3 and beyond: Training Large Language Models
odashi
1
790
【SIGGRAPH Asia 2025】Lo-Fi Photograph with Lo-Fi Communication
toremolo72
0
140
R&Dチームを起ち上げる
shibuiwilliam
1
200
ScoreMatchingRiesz for Automatic Debiased Machine Learning and Policy Path Estimation with an Application to Japanese Monetary Policy Evaluation
masakat0
0
160
データサイエンティストをめぐる環境の違い2025年版〈一般ビジネスパーソン調査の国際比較〉
datascientistsociety
PRO
0
980
生成的情報検索時代におけるAI利用と認知バイアス
trycycle
PRO
0
400
A History of Approximate Nearest Neighbor Search from an Applications Perspective
matsui_528
1
210
生成AI による論文執筆サポート・ワークショップ 論文執筆・推敲編 / Generative AI-Assisted Paper Writing Support Workshop: Drafting and Revision Edition
ks91
PRO
0
170
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
9.8k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
130
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.1k
Evolving SEO for Evolving Search Engines
ryanjones
0
170
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
150
Scaling GitHub
holman
464
140k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
980
WCS-LA-2024
lcolladotor
0
490
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
140
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
240
Speed Design
sergeychernyshev
33
1.6k
Transcript
Zero-Downtime SQL Database Schema Evolution for Continuous Deployment
Michael de Jong Magnet.me Arie van Deursen Delft University of
Technology Anthony Cleve University of Namur
None
30+ 1.200+ 90.000+ 2 Employees Companies Students Countries
Full-time developers (Micro)services Master is green? deploy! No manual testing!
6 20+
We deploy frequently and we’re not the only ones [3][13]
version deploys/month schema changes/month ~1.400 ~16
version deploys/month schema changes/month ~1.400 ~16 Roughly doubled since writing
the paper
Blocking schema operations Why are my schema changes crashing my
service?
Mixed-State How to deal with combinations of different versions of
the database schema and your application
Result: manual deploys Can’t deploy new schema during the day
because it’s not safe, so you have to deploy it manually at night
Result: manual deploys Can’t deploy new schema during the day
because it’s not safe, so you have to deploy it manually at night Not Continuous Deployment
Understanding behaviour blocking
Experiments Created test database Simulated application running on top Tested
19 different schema operations Using different version of MySQL / PG Plotted when queries were executed
Activity plots Adding a non-nullable column (PG 9.4) Making a
column non-nullable (MySQL 5.6) Adding a non-nullable column (MySQL 5.6)
Activity plots Before applying schema operation Adding a non-nullable column
(PG 9.4) Making a column non-nullable (MySQL 5.6) Adding a non-nullable column (MySQL 5.6)
Activity plots While applying schema operation Adding a non-nullable column
(PG 9.4) Making a column non-nullable (MySQL 5.6) Adding a non-nullable column (MySQL 5.6)
Activity plots Adding a non-nullable column (PG 9.4) Making a
column non-nullable (MySQL 5.6) Adding a non-nullable column (MySQL 5.6)
Activity plots Blocking Adding a non-nullable column (PG 9.4) Making
a column non-nullable (MySQL 5.6) Adding a non-nullable column (MySQL 5.6)
Activity plots Read-only Blocking Adding a non-nullable column (PG 9.4)
Making a column non-nullable (MySQL 5.6) Adding a non-nullable column (MySQL 5.6)
Activity plots Blocking Read-only Non-blocking Adding a non-nullable column (PG
9.4) Making a column non-nullable (MySQL 5.6) Adding a non-nullable column (MySQL 5.6)
MySQL 5.5 MySQL 5.6 PostgreSQL 9.3 PostgreSQL 9.4 S1 Read-only
Non-Blocking Blocking Blocking S2 Read-only Non-Blocking Non-Blocking Non-Blocking S3 Read-only Non-Blocking Non-Blocking Non-Blocking S4 Read-only Non-Blocking Non-Blocking Non-Blocking S5 Read-only Non-Blocking Non-Blocking Non-Blocking S6 Read-only Non-Blocking Non-Blocking Non-Blocking S7 N/A N/A Non-Blocking Non-Blocking S8 N/A N/A Non-Blocking Non-Blocking S9 N/A N/A Blocking Blocking S10 Read-only Read-only Non-Blocking Non-Blocking S11 Read-only Read-only Blocking Blocking S12 Non-Blocking Non-Blocking Non-Blocking Non-Blocking S13 Non-Blocking Non-Blocking Non-Blocking Non-Blocking S14 Read-only Read-only Blocking Blocking S15 Read-only Read-only Blocking Blocking S16 Read-only Non-Blocking Non-Blocking Non-Blocking S17 N/A N/A Non-Blocking Blocking S18 Blocking Non-Blocking Non-Blocking Non-Blocking S19 Non-Blocking Non-Blocking Non-Blocking Non-Blocking
Observations Schema changes are high-risk CD leads to frequent schema
changes We need to automate this process Are there any tools already out there?
OpenArk Kit TableMigrator pt-online-schema-change (Percona) Large Hadron Migrator (SoundCloud) Online
Schema Change (Facebook) Gh-ost (GitHub) Existing tools
Limitations Only support MySQL None support defining changesets All use
an atomic switchover None support Referential Integrity
R1: Non-Blocking Schema Changes R2: Schema Changesets R3: Concurrently Active
Schemas R4: Referential Integrity R5: Schema Isolation R6: Non-Invasive R7: Resilience
QuantumDB
movies rentals customers Netflix 2.0
changelog.addChangeSet(“Add referral column to customers table”, addColumn(“customers”, “referred_by”, integer()), addForeignKey(“customers”,
“referred_by”) .named(“customer_referred_by_fk”) .onDelete(NO_ACTION) .referencing(“customers”, “id”)); Defining changes
movies rentals customers Evolving the schema
movies rentals customers customers* Evolving the schema Forking the table
under change
Ghost table: Structural copy of an existing table with schema
changes already applied to it movies rentals customers customers* Evolving the schema Forking the table under change
movies rentals customers customers* Evolving the schema Forking the table
under change
movies rentals rentals* customers customers* Evolving the schema Forking dependent
tables
movies rentals* customers* rentals customers Evolving the schema A structurally
forked database schema
movies rentals* customers* rentals customers Evolving the schema Creating forward
database triggers (1-way sync)
movies rentals* customers* rentals customers Evolving the schema Copy data
from original tables to their ghost tables
movies customers* rentals customers rentals* Evolving the schema Creating backward
database triggers (2-way sync)
movies rentals* customers* rentals customers Accessing the database Original Schema
New Schema Original Schema movies rentals* customers* rentals customers Accessing
the database Two co-existing database schemas
Application Driver Accessing the database
Application Wrapper Driver Accessing the database Intercepting database interactions
Connection connection = DriverManager.getConnection( “jdbc:postgresql://localhost:5432/database”, “username”, “password”); Connection connection =
DriverManager.getConnection( “jdbc:quantumdb:postgresql://localhost:5432/database? version=80bfa11”,“username”, “password”); Accessing the database Intercepting database interactions
SELECT * FROM rentals WHERE customer_id = 2372 AND return_date
< NOW() AND returned = false; SELECT * FROM rentals* WHERE customer_id = 2372 AND return_date < NOW() AND returned = false; Accessing the database Rewriting intercepted queries
movies rentals customers Dropping a version When it’s no longer
needed rentals* customers*
movies rentals customers Dropping a version Drop the database triggers
rentals* customers*
movies rentals* customers* Dropping a version Drop tables only used
in the obsolete version
movies rentals* customers* Dropping a version Leaving you with the
resulting schema New Schema
Evaluation
Experiments
MySQL 5.5 MySQL 5.6 PostgreSQL 9.3 PostgreSQL 9.4 PG 9.4
+ QuantumDB S1 Read-only Non-Blocking Blocking Blocking Non-Blocking S2 Read-only Non-Blocking Non-Blocking Non-Blocking Non-Blocking S3 Read-only Non-Blocking Non-Blocking Non-Blocking Non-Blocking S4 Read-only Non-Blocking Non-Blocking Non-Blocking Non-Blocking S5 Read-only Non-Blocking Non-Blocking Non-Blocking Non-Blocking S6 Read-only Non-Blocking Non-Blocking Non-Blocking Non-Blocking S7 N/A N/A Non-Blocking Non-Blocking Non-Blocking S8 N/A N/A Non-Blocking Non-Blocking Non-Blocking S9 N/A N/A Blocking Blocking Non-Blocking S10 Read-only Read-only Non-Blocking Non-Blocking Non-Blocking S11 Read-only Read-only Blocking Blocking Non-Blocking S12 Non-Blocking Non-Blocking Non-Blocking Non-Blocking Non-Blocking S13 Non-Blocking Non-Blocking Non-Blocking Non-Blocking Non-Blocking S14 Read-only Read-only Blocking Blocking Non-Blocking S15 Read-only Read-only Blocking Blocking Non-Blocking S16 Read-only Non-Blocking Non-Blocking Non-Blocking Non-Blocking S17 N/A N/A Non-Blocking Blocking Non-Blocking S18 Blocking Non-Blocking Non-Blocking Non-Blocking Non-Blocking S19 Non-Blocking Non-Blocking Non-Blocking Non-Blocking Non-Blocking
Industry case
Changesets (11 month period ’15/‘16) of these contain blocking operations
95 37%
supported by QuantumDB partially supported not yet supported 64% 25%
11%
Due to missing support for Executing DML queries during migration
User-defined functions User-defined database triggers User-defined views
Benchmarking “Normal” method Done using Liquibase Requires downtime in production
(ie. serving error pages or limiting functionality) ~8 minutes in total for all 95 changesets (on test server without any load on the database)
Benchmarking QuantumDB method Done using QuantumDB No downtime required at
all (ie. service can operate normally) ~2h 25m in total for all 95 changesets (on test server without any load on the database)
Where to next?
Add more support for views, functions, and triggers Start testing
in a live production environment Which allows us to get real-world measurements, and developer input
Future research direction? Using QuantumDB to perform A/B testing of
database schemas
Summary CD leads to frequent code/schema deploys Not all schema
ops are safe in production We need a tool to do evolution safely QuantumDB is that tool
QuantumDB Zero-Downtime SQL Database Schema Evolution for Continuous Deployment Open-Source
github.com/quantumdb quantumdb.io We need your help! Contribute code, insights, or more research