MySQL

gh-ost: Trigger-Free Online MySQL Schema Migrations

Migrate MySQL schema changes online with gh-ost using binlog streaming instead of triggers. Covers dynamic throttling via Unix socket, postpone-cut-over flag, and test-on-replica mode.

JusDB Team
August 15, 2025
Updated June 20, 2026
5 min read

gh-ost (GitHub's Online Schema Transmogrifier) is an alternative to pt-online-schema-change that uses binlog streaming instead of triggers, making it safer and more controllable.

gh-ost vs pt-osc

text
Feature              gh-ost              pt-osc
---------------------|---------------------|------------------
Mechanism            Binlog streaming      Triggers
Works with triggers  Yes                   No
Pause/resume         Yes (via socket)      No
Throttle dynamically Yes                   Limited
Risk of trigger bugs None                  Possible
Requires binlog      Yes (ROW format)      No

Installation

bash
# Download binary
wget https://github.com/github/gh-ost/releases/download/v1.1.6/gh-ost-binary-linux-amd64-20231207134705.tar.gz
tar xzf gh-ost*.tar.gz
sudo mv gh-ost /usr/local/bin/

Basic Migration

bash
gh-ost \
  --user=root --password=secret \
  --host=localhost \
  --database=myapp \
  --table=orders \
  --alter='ADD COLUMN score INT NOT NULL DEFAULT 0' \
  --allow-on-master \
  --execute

Throttle and Control via Unix Socket

bash
# While migration is running, pause it
echo throttle | nc -U /tmp/gh-ost.orders.sock

# Resume
echo no-throttle | nc -U /tmp/gh-ost.orders.sock

# Check status
echo status | nc -U /tmp/gh-ost.orders.sock

# Gracefully complete (skips remaining rows, cuts over)
echo unpostpone | nc -U /tmp/gh-ost.orders.sock

Safe Throttle Configuration

bash
gh-ost \
  --user=root --password=secret \
  --host=localhost \
  --database=myapp --table=orders \
  --alter='ADD INDEX idx_orders_score (score)' \
  --max-load='Threads_running=20' \
  --critical-load='Threads_running=40' \
  --chunk-size=500 \
  --default-retries=120 \
  --postpone-cut-over-flag-file=/tmp/gh-ost.postpone \
  --allow-on-master \
  --execute

# --postpone-cut-over-flag-file: create this file to delay the final cutover
# touch /tmp/gh-ost.postpone  # delays cutover until file is removed

Test Mode (No Actual Migration)

bash
# Validate migration plan without touching production
gh-ost \
  --user=root --password=secret \
  --host=localhost \
  --database=myapp --table=orders \
  --alter='DROP COLUMN legacy_col' \
  --test-on-replica

Key Takeaways

  • gh-ost uses binlog streaming — no triggers, so it works on tables that already have triggers
  • Use the Unix socket to pause, throttle, or postpone cutover during peak traffic
  • Use --postpone-cut-over-flag-file to control exactly when the final lock happens
  • Test with --test-on-replica before running on production

JusDB Can Help

Large-table schema migrations are high-risk operations. JusDB can plan and execute your MySQL schema changes with zero downtime.

Share this article

Database engineering notes

Articles like this one, in your inbox. No spam, unsubscribe anytime.

JusDB Team

Official JusDB content team

Keep reading

MySQL Explained (2026): InnoDB, 8.4 LTS, Replication & Production Patterns

Everything you need to know about MySQL: storage engines, replication topologies, performance tuning, and cloud deployment. From basics to advanced optimization.

MySQL9 minMay 13, 2026
Read

MySQL binlog Retention, Rotation & Purge: Production Guide (2026)

Configure MySQL binlog retention safely: binlog_expire_logs_seconds, manual purging rules, AWS RDS retention, and the disk-exhaustion failure mode you should monitor for.

MySQL10 minMay 9, 2026
Read

MySQL "Communications Link Failure": Fix wait_timeout, HikariCP & All 8 Timeout Variables

MySQL wait_timeout, net_read_timeout, innodb_lock_wait_timeout and max_execution_time — production tuning rules and the HikariCP alignment trick that prevents 'communications link failure' errors.

MySQL6 minMay 9, 2026
Read