読者です 読者をやめる 読者になる 読者になる

InnoDBの共有テーブルスペースにrawデバイスを使う

すごくハマったのでメモ。 公式ドキュメントに手順が載っているが、これだけではできなかった。

MySQL :: MySQL 5.6 Reference Manual :: 14.5.8 Using Raw Disk Partitions for the Shared Tablespace

環境

  • MySQL 5.6.19
    • ソースからインストール
    • basedir: /opt/mysql
    • datadir: /var/lib/mysql
  • 使うデバイス: /dev/sdb1
  • mysqldを動かすユーザー: mysql

手順

1. innodb_file_per_tableを無効に

5.6.6 以降はデフォルトでinnodb_file_per_tableが有効になっていて、テーブルごとにファイルを作ってしまう。 /etc/my.cnfを開いて[mysqld]セクションに無効にする設定を追加しておく。

またこの時点ではinnodb_data_file_pathはデフォルト値に設定しておく。 rawデバイス用の設定にするとmysql_install_dbでデータディレクトリを初期化したときにエラーが生じ、rootパスワードが勝手に設定されてmysqlにログインできなかった。

[mysqld]
innodb_file_per_table=OFF
innodb_data_file_path=ibdata1:12M:autoextend

2. mysql_install_dbでデータディレクトリの初期化

$ sudo /opt/mysql/scripts/mysql_install_db --user=mysql --datadir=/var/lib/mysql

必要に応じて--datadirオプションを付けてデータディレクトリを指定する。

3. mysqlデータベース中のテーブルのダンプと削除

ibdata1中にはmysqlデータベース中のいくつかのテーブルが含まれている。5.6 以前ではibdata1が削除されるとそれらのテーブルは再び作られるが、5.6 では再び作られないらしい。
innodb - Cannot open table mysql/innodb_index_stats - Database Administrators Stack Exchange

なのでこれらのテーブルをダンプしておいて、後でリストアする。 これらのテーブルを復元しないでおくとInnoDB: Error: Table "mysql"."innodb_table_stats" not found.というようなエラーが大量に出ていた。

mysqldを起動してテーブルをダンプして削除。その後mysqldを停止。

$ sudo service mysql.server start

$ mysqldump -u root mysql \
innodb_index_stats \
innodb_table_stats \
slave_master_info \
slave_relay_log_info \
slave_worker_info \
> mysql_innodb_tables.sql

$ mysql -u root -D mysql -e "DROP TABLE innodb_index_stats, innodb_table_stats, slave_master_info, slave_relay_log_info, slave_worker_info"

$ sudo service mysql.server stop

4. ログファイルの削除

ドキュメントには書かれていなかったが、ib_logfile0などのログファイルが存在するとログが書き込めないというエラーが生じた。

$ sudo rm /var/lib/mysql/ib_logfile*

5. rawデバイスの初期化のための設定

ここからやっとドキュメントの手順開始。
/etc/my.cnfを開いてinnodb_data_home_dirinnodb_data_file_pathを設定する。

[mysqld]
innodb_data_home_dir=
innodb_data_file_path=/dev/sdb1:300Gnewraw

使うデバイスの所有者がmysqldを動かすユーザーと同じでないとデバイスを開けないので、所有者を変更しておく。

$ sudo chown mysql:mysql /dev/sdb1

6. rawデバイスの初期化

mysqldを起動するとrawデバイスの初期化が始まる。大きい容量を指定していると長い時間がかかる。
初期化が終わったら何もせずにmysqlを停止させる。

$ sudo service mysql.server start && sudo service mysql.server stop

7. rawデバイス用の設定

/etc/my.cnfを開いてinnodb_data_file_pathの値がnewrawであったところをrawに変更する。

[mysqld]
innodb_data_home_dir=
innodb_data_file_path=/dev/sdb1:300Graw

8. ダンプしたテーブルのリストア

mysqldを起動してさっきダンプしたテーブルをリストアする。

$ sudo service mysql.server start

$ mysql -u root -D mysql < mysql_innodb_tables.sql

以上で完了。