ibdata1肥大化解消

学認連携Moodleのibdata1は11GBになっている。よく言われることだが、InnoDBはOSがどのていどのファイルを扱えるか認識できない。肥大化が困るのは、ファイルシステムを食い潰すことであり、最適化したとしても縮小することはない。一度ダンプからリストアするしかない。また、ファイルごとに.idbを作成する「innodb_file_per_table」が効果があるとされており、my.cnfに

[code]
innodb_data_file_path = ibdata1:1G
innodb_file_per_table
[/code]

を記述するという2009年の記事が見られるが、MySQLマニュアルを見ると、MySQL 5.6からこれがデフォルトになるそうだ。つまり、自動的にテーブルごとの.ibdを作成してくれるということである。先日のシステムメンテナンスで学認連携MoodleはMySQL 5.7にバージョンアップした。学認連携Moodleのデータディレクトリを見てみると、

[code]
-rw-r—– 1 mysql mysql 8720 3月 8 04:19 mdl_workshop_aggregations.frm
-rw-r—– 1 mysql mysql 147456 3月 8 04:20 mdl_workshop_aggregations.ibd
-rw-r—– 1 mysql mysql 9260 3月 8 04:19 mdl_workshop_assessments.frm
-rw-r—– 1 mysql mysql 147456 3月 8 04:20 mdl_workshop_assessments.ibd
-rw-r—– 1 mysql mysql 9222 3月 8 04:19 mdl_workshop_assessments_old.frm
-rw-r—– 1 mysql mysql 163840 3月 8 04:20 mdl_workshop_assessments_old.ibd
[/code]

のように、ダンプをリストアする作業を行っていないのもかかわらず、夜中のmysqlcheck時に自動的にこのようになっているようだ。つまりmy.cnfは一切変更する必要はない。

「innodb_data_file_path = ibdata1:1G」について、このサイズを越えたらどうなるのか見当がつかないので、明示的な固定サイズは止めることにした。しかしながら今のままの肥大を続けるのは良くないので、データベースのダンプをリストアする作業は必要である。この結果、ibdata1は11Gから79Mとなり、消費メモリが劇的に減少した。

security-learning のメモリ使用状況。メンテナンス後は空きメモリが劇的に増加している。
security-learning のメモリ使用状況。メンテナンス後は空きメモリが劇的に増加している。

作業手順は次の通り。この記事の流れが非常に参考になった。

0. Moodleを予告の後メンテナンスモードにする
/usr/bin/php /var/www/html/mdl/admin/cli/maintenance.php –enablelater=1440

1. データベースに影響するサービスの停止
cactiとmoodleのcronを止める

2. 全てのデータベースのバックアップ
sudo /usr/bin/mysqldump -uroot -p’pass’ –single-transaction –quick –lock-tables=false mdl | gzip > /tmp/mdl.sql
sudo /usr/bin/mysqldump -uroot -p’pass’ -x –all-databases | gzip > /tmp/all.sql

3. 全(InnoDB)データベースの削除
mysql -uroot -p’pass’ -e “drop database cacti”
mysql -uroot -p’pass’ -e “drop database mdl”
mysql -uroot -p’pass’ -e “drop database performancd_schema”
mysql -uroot -p’pass’ -e “drop database information_schema”
mysql -uroot -p’pass’ -e “drop database sys”
mysql -uroot -p’pass’ -e “drop database mysql”

4. MySQLの停止
sudo /etc/init.d/mysqld stop

#5. my.cnfに以下を追記(MySQL5.6以降は innodb_file_per_table がデフォルトになったので不要)
#innodb_data_file_path = ibdata1:1G
#innodb_file_per_table

6. ibdata1などの削除
データディレクトリ内をすべて削除する
sudo rm `sudo ls`

7. MySQLの初期化
sudo /etc/init.d/mysqld start

8. MySQLの停止
sudo /etc/init.d/mysqld stop

9. MySQLのセーフモードによる起動(3. でrootユーザのアクセス情報含めすべて削除したため)
sudo /usr/bin/mysqld_safe –skip-grant-tables –skip-networking&

10. バックアップからのリストア
mysql -uroot < /tmp/all.sql
# 次回から zcat /tmp/all.sql.gz | mysql -uroot とできるか検証

11. ibdが作成されているか確認
sudo ls -alF /var/lib/mysql/mdl/

12. MySQLの再起動
sudo /etc/init.d/mysqld restart

13. 停止したサービスの再稼働
cactiとmoodleのcronを有効にする

14. moodleのメンテナンスモードを解除
sudo /usr/bin/php /var/www/html/mdl/admin/cli/maintenance.php –disable

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です