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