web-dev-qa-db-ja.com

MySql-ライブデータベースのinnodb_file_per_tableの変更

大規模なMySql DB(150GB)を使用していますが、innodb_file_per_tableoffに設定され、DB全体が1つのファイル(ibdata1)。アクティベートしたいinnodb_file_per_tableそして、DBを遡及的にいくつかのファイルに分割しました。これを行うための最良の方法は何ですか?

19
Ran

これを実現する方法は本当に1つしかありません。 mysqldumpsを使用してデータをエクスポートし、すべてのデータベースをドロップし、mysqldをシャットダウンし、ib_logfile0を削除し、ib_logfile1を削除し、ibdata1を削除し、innodb_file_per_table見出しの下に[mysqld]を追加し、mysqlを開始する必要があります。

2010年10月にStackOverflowにこの回答を投稿しました

以下は、垂直方向にリストされたステップです。

ステップ01)MySQLDumpですべてのデータベースをSQLテキストファイル(SQLData.sqlと呼びます)

ステップ02)すべてのデータベースを削除する(mysqlスキーマを除く)

ステップ03)mysqlをシャットダウンする

[〜#〜]警告[〜#〜]:InnoDBファイルからコミットされていないトランザクションを完全に削除するには、これを実行します

mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop

ステップ04)/etc/my.cnfに次の行を追加します

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

補足:innodb_buffer_pool_sizeの設定が何であれ、innodb_log_file_sizeがinnodb_buffer_pool_sizeの25%であることを確認してください。

ステップ05)ibdata1、ib_logfile0およびib_logfile1を削除します

この時点では、/ var/lib/mysqlにmysqlスキーマのみがあるはずです。

ステップ06)mysqlを再起動します

これにより、ibdata1が10MB、ib_logfile0とib_logfile1がそれぞれ1Gで再作成されます。

ステップ07)SQLData.sqlをmysqlにリロードします

ibdata1は大きくなりますが、テーブルメタデータのみが含まれます

各InnoDBテーブルはibdata1の外に存在します

Mydb.mytableという名前のInnoDBテーブルがあるとします。/var/lib/mysql/mydbに移動すると、テーブルを表す2つのファイルが表示されます。

  • mytable.frm(ストレージエンジンヘッダー)
  • mytable.ibd(mydb.mytableのテーブルデータとテーブルインデックスのホーム)

ibdata1にInnoDBデータとインデックスが含まれることはなくなります。

/etc/my.cnfのinnodb_file_per_tableオプションを使用すると、OPTIMIZE TABLE mydb.mytableを実行でき、ファイル/var/lib/mysql/mydb/mytable.ibdは実際に圧縮されます。

私はこれをMySQL DBAとしてのキャリアの中で何度も行ってきました

実際、これを初めて行ったとき、50GBのibdata1ファイルを500MBに縮小しました。

試してみる。これについてさらに質問がある場合は、メールでお問い合わせください。私を信じて。これは短期的にも長期的にも機能します。 !!!

ibdata1を縮小せずにInnoDBテーブルを抽出する代替手段があります

ステップ01)/etc/my.cnfに次の行を追加します

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

ステップ02)service mysql restart

ステップ03)mydb.mytableという単一のInnoDBテーブルを抽出するには、次のようにします。

ALTER TABLE mydb.mytable ENGINE=InnoDB;

これにより、1つのファイルが作成され、元の構造ファイルが保持されます。

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

これは、すべてのInnoDBテーブルに対して実行できます。残念ながら、ibdata1は150GBのままです。

32
RolandoMySQLDBA

Rolando が指摘するように、ibdataのスペースを取り戻したい場合は、ダンプ/復元が唯一の選択肢です。これを実行することも、おそらくパフォーマンスにとって最良です。

ただし、損失を減らしてハードドライブで150 GBを「失う」だけの場合は、innodb_file_per_table my.cnfで、サーバーを再起動します。

次に、各テーブルについて、以下を発行します。

ALTER TABLE x DISABLE KEYS;
ALTER TABLE x ENGINE=InnoDB;
ALTER TABLE x ENABLE KEYS; 

ここでの問題は、大きなテーブルスペースにはしばらく時間がかかることです。

私が提案するのは、ライブデータベースのスレーブを設定し、スレーブで変換を実行してから、マスター/スレーブを停止して新しいデータスペースをマスターにコピーするか、追いついたらスレーブをマスターに昇格させることです。 。

ダウンタイムがないと、この変更を行うのが困難になります。

5
Derek Downey