MySQLにALTERぶん投げて投げてワタワタしたお話
仕事でALTERぶん投げたときにワタワタしたので忘れない用にメモ。
## 想定(実際の数字とは違う)
- 1億件のデータ入ってるテーブルをどうしても変更する必要があったので、ALTER文を使って変更する
- サービスのメンテナンス時間はある程度確保
- stagingである程度のテストは終わってるが、データ量が違いすぎるので予想しにくい
## 下準備
- MySQLでALTER TABLE文を投げても進捗がわからないと思っていたが、わかるらしい
- MySQLでALTER TABLE文の進捗状況を確認する
- そっからほとんどコピペしてシェルを作った
- ALTER文投げる前に"SHOW GLOBAL STATUS LIKE 'Handler_write';"を実行して、数をとっておく
- シェルが吐き出す数字と実行前に取った数字の差分がinsertされてる件数なので目安にする
#!/bin/bash
shopt -s expand_aliases
alias mysql-master='mysql -uroot -p'
while true
do
echo "SHOW GLOBAL STATUS LIKE 'Handler_write';"
sleep 5
done | mysql-master -N
# 実行するとこんなん
./sample.sh
Handler_write 1111111111
Handler_write 1111111322
- レプリケーションの遅延のことを考慮しておくこと
- show slave statusを投げて、どれだけ遅延が起きてるか確認できる
## いざ本番にそぉい
- ペースが悪い!(余裕でメンテナンス時間超えそう)
- テンパる
- 死にたくなる
- "show full processlist"で確認すると、テンポラリ領域に頑張ってるところ
- 案①ALTER文投げてるプロセスをKILLして、なかったことにする(絶対的に対応しないとだめな用件でもなかったので)
- 案②mysqldumpを使って必要な領域のみをdumpし、ALTER文を投げるテーブルと同じ構成のものをCREATE。そこにdumpしたデータを入れたあとにALTER文を投げて変更。その後、リネームして元のテーブル名に戻す
- 案③MySQLの機嫌を伺いながら、耐える
- ②をやろうと試行錯誤してたら、急にハイペースになる
- 余裕で終わった
- master-slave構成なので、slaveへのレプリケーション遅延が発生。
- show slave statusを投げて進捗を確認しようとしたら、権限がなくて実行できない!
- 死にたくなる
- でももう止めれないので祈る
- masterに投げた時間+10%ぐらいの時間で無事終了。
## まとめ
見積もりも甘かったし、権限もそうだし、いろいろ確認しておこう。
## 追記
シェルを変更した
#!/bin/bash
shopt -s expand_aliases
alias mysql-master='mysql -uroot -p'
begin=`echo "SHOW GLOBAL STATUS LIKE 'Handler_write';" | mysql-master -N | awk '{print $2}'`
while true
do
tmp=`echo "SHOW GLOBAL STATUS LIKE 'Handler_write';" | mysql-master -N | awk '{print $2}'`;
result=`expr $tmp - $begin`
echo ${result}
sleep 5
done