MySQLで容量の大きいバイナリデータを保存する場合

画像などのバイナリデータをMySQLに格納するために、BLOB型やMEDIUMBLOB型を利用することがありました。

BLOB型でサイズの大きいデータをMySQLに格納しようとするとMySQLのログにエラーログが出力されています。

100906 00:00:00 InnoDB: ERROR: the age of the last checkpoint is 9440228,
InnoDB: which exceeds the log group capacity 9433498.
InnoDB: If you are using big BLOB or TEXT rows, you must set the
InnoDB: combined size of log files at least 10 times bigger than the
InnoDB: largest such row.
調べたところ、MySQLのログファイルのサイズが小さいために発生している模様。

MySQLは、テーブルスペースの更新に時間がかかるため、直接テーブルスペースを更新するのではなく、最初にログファイルに全ての更新を書き込み、そのあと非同期でテーブルスペースを更新するという仕組みになっています。

このログファイル・サイズはデフォルトで5MBが設定されていますが、ログファイルの合計サイズは、 innodb_log_files_in_group という設定値(デフォルト2)と、innodb_log_file_size との積で、トータル10MBとなります。

そのため、10MB以上のファイルをDB(MEDIUMBLOB/BLOB型のカラム)に格納しようとするとログファイルサイズをオーバーしてしまい、エラーとなるため、ログファイルのサイズを拡張しなければなりません。

変更方法は以下のとおりです。

MySQLサーバを普通にシャットダウンした場合、テーブルスペースに反映されていないデータがログファイルに残る可能性があるため、ログファイルのサイズを変更する場合は、MySQLサーバの停止と同時にテーブルスペースへログファイルの内容をすべて反映する必要があります。具体的には、innodb_fast_shutdown=0 を設定しなければなりません。

設定値の確認コマンド。
mysql> show variables like ‘innodb_fast_shutdown’;
Variable_name Value
innodb_fast_shutdown 1
上記の場合、設定値が1であるため、ログファイルのデータがテーブルスペースに反映されない可能性があります。

設定値の変更コマンド。
mysql> SET GLOBAL innodb_fast_shutdown=0;

ログファイルサイズの確認コマンド。
mysql> show variables like ‘innodb_log_file_size’;
Variable_name Value
innodb_log_file_size 5242880
ValueはByte表示。

innodb_fast_shutdownの設定が終わったら、サービスを停止し、それからMySQLサーバを停止。
#MySQLサーバを停止する前に、mysqldump等でバックアップを取得しておくことを推奨。
# /etc/init.d/mysqld stop

次にログファイルを適当な場所に退避。
mv /var/lib/mysql/ib_logfile* ~/mysql/

次にログファイルサイズの設定値の変更。
“[mysqld]” の設定に以下を追加します。

innodb_log_file_size=64M

MySQLサーバの起動コマンド
# /etc/init.d/mysqld start
すると、ログファイルが新規に作成され、サーバが起動します。
本当に64MBのログファイルが作成されたかを確認するには、mysqlのログ( /var/log/mysqld/mysql.log )を確認しましょう。

100906 00:00:00 InnoDB: Log file ./ib_logfile0 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile0 size to 64 MB
InnoDB: Database physically writes the file full: wait…
100906 00:00:00 InnoDB: Log file ./ib_logfile1 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile1 size to 64 MB
InnoDB: Database physically writes the file full: wait…
このログから、64MBのログファイルが2つ作成されたことがわかります。

再度、設定値の確認コマンド。
mysql> show variables like ‘innodb_log_file_size’;

以上が手順です。