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


18

私は大規模なMySql DB(150GB)を持っinnodb_file_per_tableoffいますが、DB全体が1つのファイル(ibdata1)でホストされるように設定されていることに気づきました。アクティブ化innodb_file_per_tableして、DBをいくつかのファイルにさかのぼって分割したいのですが、これを行う最良の方法は何ですか?

回答:


32

これを実現する方法は本当に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を再起動します

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

ステップ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のままです。


.sqlファイルからリロードを実行しているときに、次のエラーが発生ERROR 1071 (42000) at line 25: Specified key was too long; max key length is 1000 bytesしましたか?
ラン

@Ranは別の質問として投稿してください。
-RolandoMySQLDBA


すべてのテーブルで設定innodb_file_per_tableしてから実行ALTER TABLEする場合、ibdata1ファイルを削除して、復元せずにスペースを再利用できますか?
SystemParadox

1
@SystemParadoxは絶対に!!!!!!!! データディクショナリが失われます。
-RolandoMySQLDBA

5

ibdataのスペースを再利用する場合は、Rolandoが指摘しているように、ダンプ/リストアが唯一の選択肢です。これを行うには、おそらくパフォーマンスにとっても最適です。

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

次に、各テーブルに対して、次を発行します。

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

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

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

ダウンタイムなしでこの変更を行うのは困難です。


残酷に正直であり、「あなたの損失を削減する」と言って+1。あなたも「弾丸をかむ」と言ったかもしれません。
RolandoMySQLDBA

pt-online-schema-changeを使用して、alterテーブルの実行中のダウンタイムを回避できます。
コーナーノート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.