DBAtlas · 데이터베이스 운영 아틀라스

gh-ost로 트리거 없는 온라인 스키마 변경

MySQL온라인 작업

명령어

# Connects to a replica and reads its binlog; postpones cut-over until the flag file is removed
gh-ost --host=db2 --port=3306 --user=ghost --password='Gh0st#2024' \
  --database=shop --table=orders \
  --alter="ADD COLUMN channel VARCHAR(20) NULL, ADD INDEX ix_channel (channel)" \
  --max-load=Threads_running=50 --critical-load=Threads_running=200 --max-lag-millis=1500 \
  --exact-rowcount --concurrent-rowcount --default-retries=120 \
  --postpone-cut-over-flag-file=/tmp/ghost.postpone --panic-flag-file=/tmp/ghost.panic \
  --serve-socket-file=/tmp/gh-ost.shop.orders.sock --ssl --ssl-allow-insecure --execute
# While running: status / throttle / cut-over
echo status | nc -U /tmp/gh-ost.shop.orders.sock
echo throttle | nc -U /tmp/gh-ost.shop.orders.sock
rm /tmp/ghost.postpone

하는 일

ghost 테이블을 만들고 행을 복사하며, 동시 변경은 트리거 대신 binlog를 읽어 적용한다. throttling, 일시 중지, cut-over 시점은 socket이나 flag 파일로 런타임에 제어한다.

사용 시점

트리거 오버헤드를 허용할 수 없는 쓰기가 많은 대형 테이블에서, cut-over 시점(예: 트래픽이 적은 시간대)을 직접 선택하고 싶을 때.

주의

binlog_format=ROW와 binlog_row_image=FULL이 필요하며, 연결하는 replica에는 log_replica_updates=ON이 필요하다. 사용자에게 SUPER 또는 REPLICATION CLIENT / REPLICATION SLAVE와 테이블에 대한 ALL이 필요하다. foreign key가 있는 테이블(부모 또는 자식)은 지원되지 않는다. cut-over 후 이전 테이블은 _<table>_del로 남으므로 검증 후 수동으로 삭제한다(--ok-to-drop-table은 자동으로 삭제한다). 1.1.8 이전 gh-ost 릴리스는 SHOW SLAVE STATUS를 사용하므로 MySQL 8.4에서 오류 1064로 멈춘다. 8.4 지원은 1.1.8에서 추가되었다. gh-ost는 --postpone-cut-over-flag-file에 지정한 파일을 직접 생성하며, 파일이 제거될 때까지 cut-over가 일어나지 않는다.

DBAtlas에서 열기 →

관련 항목