Home

技術系のメモと日々の雑感

Couldn't execute 'SHOW DATABASES'

毎日取っている MySQL のダンプのサイズが、ある日を境に極端に小さくなった。
試しにコマンドを叩いてみると

mysqldump: Couldn't execute 'SHOW DATABASES': Out of memory (Needed 1675556 bytes) (5)

うわっ!
恐ろしいメッセージ・・・。
このマシンはメモリを 4GB 積んでいるので、innodb_buffer_pool_size には半分の 2GB を割り当ててたんだけど、これが原因だろうな。
そこで実メモリの 4 分の 1 まで減らしてみたら、今のところ大丈夫そう。
いや〜、久しぶりに焦った。
ダンプが取れないままじゃ年を越せないもんねぇ。

mysqladmin flush-hosts と skip-name-resolve

とある MySQL の環境を別のマシンに移動したときに、設定は間違ってないはずなのに接続できなくなった。

$ mysql -u fuga -h hoge.example.com -p
Enter password:
ERROR 1130 (00000): Host 'hoge.example.com' is not allowed to connect to this MySQL server

サブネットで接続元を許可しているから、環境を移動しても特にここの設定を変更する必要はないはずだった。
マニュアルによると、このパターンにハマったときは

mysqladmin flush-hosts

を実行して、MySQL が持っているホスト名キャッシュをクリアしたら治るとのこと。
でも試してみたらダメ。
そこで、my.cnf に

skip-name-resolve

を書いて MySQL のデーモンを再起動する方法を試したら解決した。
この後 skip-name-resolve を消しても問題なかったので、ひょっとしたら mysqladmin flush-hosts を実行した後はデーモンを再起動しないといけないのかもしれないね。

master and slave have equal MySQL server ids

MySQL でレプリケーションを組むときは server-id がユニークになるように十分に注意しているつもりだった。
ところが、この前うっかりマスタと同じ値をスレーブに振ってしまった。
show slave status を実行すると

Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

という丁寧なメッセージが出るので一目瞭然だね。
何か問題が発生すると思っていたので絶対にしたくないミスだったんだけど、値を修正すれば何事もなかったように動いた。
そんなにビビる必要はなかったのか・・・。

The total number of locks exceeds the lock table size

MySQL のスレーブでエラー出た。
show slave status を見ると Last_Error が

Error 'The total number of locks exceeds the lock table size' on query. Default database: 'hoge'. Query: 'CREATE TABLE fuga SELECT * FROM fugafuga'

となっている。
Slave_IO_Running は Yes だけど Slave_SQL_Running は No だ。
後で分かったんだけど、エラーが出ているのは2台あるスレーブのうちの1台だけだった。
ログを見たら

100817  7:33:07 [ERROR] Slave SQL: Error 'The total number of locks exceeds the lock table size' on query. Default database: 'hoge'. Query: 'CREATE TABLE fuga SELECT * FROM fugafuga', Error_code: 1206
100817  7:33:07 [Warning] Slave: The total number of locks exceeds the lock table size Error_code: 1206
100817  7:33:07 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000038' position 616542968

と出ていたので stop slave して start slave したら、ひとまずエラーは消えた。
でも Exec_Master_Log_Pos の値が変わらず、Read_Master_Log_Pos の値がどんどん離れていく。
そしてしばらくしたら再発。
一時的なエラーかと思ったけど、そうじゃないんだね。
情報を探してみると、innodb_buffer_pool_size の値が小さいときに出ることがあるらしい。
そういえば、とある事情でこっちのスレーブだけデフォルト値(8MB)を使っていたんだった。
値を増やしたら今度は大丈夫そう。
Seconds_Behind_Master が 687765 なんて値になっていたけど、少しずつ減っていっている。
このスレーブは InnoDB 関係のパラメータを全部見直して環境を作り直す予定だったんで、まぁ起こるべくして起きたエラーといったところか。
それにしても、定期的に show slave status をチェックする仕組みを入れておいてよかった〜。

MySQL の動きを MRTG でグラフ化

ちょっと忙しそうにしている DB サーバがあるので、MySQL の動きを MRTG でグラフ化してみた。
設定はとっても簡単。
まず、MySQL が載っているサーバで次のようなシェルスクリプトを作って、cron で5分ごとに実行しておく。

#!/bin/sh
/usr/local/bin/mysqladmin -u root -pXXXX extended-status | grep 'Threads_connected' | awk '{print $4}'
/usr/local/bin/mysqladmin -u root -pXXXX extended-status | grep 'Threads_running' | awk '{print $4}'
uptime | awk '{print $3$4}' | sed 's/,//g'
echo 'MySQL Threads'

書くまでもないけど、ひとつ目の値は現在の接続数、ふたつ目は実行中のスレッド数だ。
我ながらヒネリがないな。
まぁ、気にせず mrtg.cfg に設定を追加してしまおう。
見ての通り、この前のエントリとほとんど一緒だ。

Target[mysql]:`/root/mysql_threads.sh`    #上のシェルスクリプトを指定
Title[mysql]: MySQL Threads
PageTop[mysql]: <H1>MySQL Threads</H1>
Options[mysql]: absolute,gauge,growright,integer,nolegend,nopercent
MaxBytes[mysql]: 10000
YLegend[mysql]: Threads
ShortLegend[mysql]: Threads
LegendI[mysql]: Connected
LegendO[mysql]: Running

load average と似たようなグラフになるのかと思ったら、ぜんぜん違ってて興味深い。