2019年4月22日月曜日

gh-ostの最後のステップの `RENAME TABLE ..` を任意のタイミングまで遅延させる

TL;DR

  • --postpone-cut-over-flag-file でテキトーなファイルを指定する
  • RENAME TABLE .. (gh-ostの cut-over フェーズ)をしても良いタイミングになったら、「指定したファイルを消す」または 「 Interactive commandsunpostpone コマンドを放り込む」

gh-ost は起動してからよしなにバイナリーログを吸い上げてゴーストテーブル(スキーマに対する変更を適用しつつ、オリジナルのテーブルへの更新とオリジナルのテーブルからデータを少しずつフェッチしてマージしたもの)を作り、最後にはオリジナルのテーブルとゴーストテーブルを RENAME TABLE .. で入れ替えることでオンラインスキーマ変更を実現している。デフォルトでは用済みになったオリジナルのテーブルもドロップしない。
pt-online-schema-change がトリガーを仕掛けてゴーストテーブル(Percona Toolkitではそうは呼ばないけれど)を組み立てて、 RENAME TABLE .. をかけてトリガーも片付けて更に入れ替えて用済みになったオリジナルのテーブルに対して DROP TABLE までかけてくれる(デフォルト。しないようにもできる)のに比べれば、メタデータロックを取らないといけない操作も少ないし突然のLazy Drop Tableで死ぬことも少ないのだけれども。
それでも「その瞬間だけSELECTすらブロックするような」でかいロックを取る操作の前には心の準備として一拍置きたい気持ちがあったりなかったりする。
オリジナルのテーブルへのアクセスが十分少ない(人によって変わると思う)場合、pt-oscくらい何回もメタデータロックを取っていても全然問題なかったりする。なので別にこれがデフォルトになってほしいとは思わない(大概の場合、迷っているより流れちゃった方がさっさと済むのだ)
前置きが長くなったけど、やり方は TL;DR の通り。
$ gh-ost --database=d1 --table=t1 --alter="Engine = InnoDB" --port=64057 --user=root --host=127.0.0.1 --allow-on-master --execute --ok-to-drop-table --postpone-cut-over-flag-file=/tmp/moge
..
Copy: 0/2 0.0%; Applied: 0; Backlog: 0/1000; Time: 0s(total), 0s(copy); streamer: bin.000014:566423; State: migrating; ETA: N/A
Copy: 0/2 0.0%; Applied: 0; Backlog: 0/1000; Time: 1s(total), 1s(copy); streamer: bin.000014:570719; State: migrating; ETA: N/A
Copy: 2/2 100.0%; Applied: 0; Backlog: 0/1000; Time: 1s(total), 1s(copy); streamer: bin.000014:571447; State: migrating; ETA: due
Copy: 2/2 100.0%; Applied: 0; Backlog: 0/1000; Time: 2s(total), 1s(copy); streamer: bin.000014:575747; State: postponing cut-over; ETA: due
Copy: 2/2 100.0%; Applied: 0; Backlog: 0/1000; Time: 3s(total), 1s(copy); streamer: bin.000014:580057; State: postponing cut-over; ETA: due
..
cut-overの遅延が有効になっている場合、ゴーストテーブルを組み立て終わった時点で State: postponing cut-over になる。
この状態ではもうオリジナルテーブルからのマージは終わっているから、ひたすらバイナリーログを吸い上げてはその差分を適用し続けるだけの状態。
$ ll /tmp/moge
-rwxr-xr-x 1 yoku0825 yoku0825 0 Apr 22 15:51 /tmp/moge

$ file /tmp/moge
/tmp/moge: empty
--postpone-cut-over-flag-file に渡したパスには空っぽのファイルが出来上がっていて、これを消すかInteractive commandsから unpostpone を放り込むとcut-overフェーズに突入する。
$ rm /tmp/moge

..
Copy: 2/2 100.0%; Applied: 0; Backlog: 1/1000; Time: 10s(total), 1s(copy); streamer: bin.000014:611206; State: migrating; ETA: due
# Migrating `d1`.`t1`; Ghost table is `d1`.`_t1_gho`
# Migrating 163-44-175-117:64057; inspecting 163-44-175-117:64057; executing on 163-44-175-117
# Migration started at Mon Apr 22 16:49:10 +0900 2019
# chunk-size: 1000; max-lag-millis: 1500ms; dml-batch-size: 10; max-load: ; critical-load: ; nice-ratio: 0.000000
# throttle-additional-flag-file: /tmp/gh-ost.throttle
# postpone-cut-over-flag-file: /tmp/moge
# Serving on unix socket: /tmp/gh-ost.d1.t1.sock
Copy: 2/2 100.0%; Applied: 0; Backlog: 0/1000; Time: 10s(total), 1s(copy); streamer: bin.000014:611647; State: migrating; ETA: due
[2019/04/22 16:49:20] [info] binlogsyncer.go:164 syncer is closing...
[2019/04/22 16:49:21] [error] binlogstreamer.go:77 close sync with err: sync is been closing...
[2019/04/22 16:49:21] [info] binlogsyncer.go:179 syncer is closed
# Done
State: migrating になって、最後の処理である RENAME TABLE .. などが行われる。

ところで、この cut-over を遅延させるための(ファイルを指定する以外の)オプションだと思っていた --cut-over というのがあったんだけれど、こっちは何の関係もなかった。。
$ gh-ost .. --cut-over=two-step
..

2019-04-22T15:37:48.792707+09:00           40 Query     lock /* gh-ost */ tables `d1`.`t1` write
2019-04-22T15:37:49.793151+09:00           40 Query     alter /* gh-ost */ table `d1`.`t1` rename `_t1_del`
2019-04-22T15:37:49.798139+09:00           42 Query     alter /* gh-ost */ table `d1`.`_t1_gho` rename `t1`
2019-04-22T15:37:49.800834+09:00           40 Query     unlock /* gh-ost */ tables

$ gh-ost .. --cut-over=atomic
..

2019-04-22T16:49:19.941893+09:00           81 Query     select get_lock('gh-ost.81.lock', 0)
2019-04-22T16:49:19.949646+09:00           81 Query     lock /* gh-ost */ tables `d1`.`t1` write, `d1`.`_t1_del` write
2019-04-22T16:49:20.942595+09:00           87 Query     rename /* gh-ost */ table `d1`.`t1` to `d1`.`_t1_del`, `d1`.`_t1_gho` to `d1`.`t1`
2019-04-22T16:49:20.948139+09:00           81 Query     unlock tables
2019-04-22T16:49:21.039657+09:00           81 Quit
atomic (こっちがデフォルト)の方が良さそう。

0 件のコメント :

コメントを投稿