web-dev-qa-db-ja.com

MySQLでデータベースダンプの複数の挿入ステートメントをバッチ処理する方法は?

いくつかの大きなテーブルを持つMySQLデータベースがあります。特に、最大のテーブル(これまでのところ)には現在、最大で11,000,000行があります。私が実行したクエリによると、テーブルは約1.7GBで動作しますが、それはMyISAMであり、明らかにその数は信頼できません(とにかく大きなテーブルです)。データベースはmysqldumpを使用して毎日バックアップされます。

現在、このダンプファイルからデータベースを復元するのに10時間ほどかかり、悪化するだけです。 --skip-extended-insertオプションを使用しています。これは、テーブル内のすべての行に対して単一の多値挿入ステートメントで復元が失敗するためです。 max_allowed_packetは最大1GBまで拡張できると私は理解していますが、それでもまだ十分ではありません。

これは十分に一般的な問題であり、一般に受け入れられている解決策があるかもしれないと思いましたが、何も見つけることができません。だから、私の質問は:

  • mysqldumpには、テーブルごとに複数値の挿入をバッチ処理できるオプションがありますか。単一の挿入を作成する代わりに、n行に複数の挿入を作成します
  • そうでない場合、これを達成するためのユーティリティ/代替策は他にありますか、または制限句を使用してテーブル行をnのバッチでクエリする独自のバックアップスクリプトをロールバックして、手動で挿入ステートメントを手動で作成する必要がありますか?

MySQL v5.5.40
テーブルはMyISAMとInnoDBの混合です。バックアップはローカルで行われます。

3
RTF

問題には、OSまたはMySQLの構成設定が含まれる場合があります

歴史的な例

数年前、私がウェブサイトの会社で働いていたとき、私は--skip-extended-insertを使用して、2GBのRAMを持つDBサーバーをロードしました。私がそれをダンプしたサーバーには64GB RAMがあり、クライアントはより小さなマシン上のデータを望んでいたので、それは私にとって意味のある世界でした。

私の現在の就職先では、外部のベンダーがSQL Serverからデータをダンプし、mysqldump互換のダンプファイルを作成しました。そのダンプファイルの問題は、各テーブルにすべての行を含む1つの挿入があったことです。 1つのテーブルには350万がありました。社内に読み込むことができませんでしたVMは8GB未満になりますRAM構成されました。驚いたことに、ラップトップにファイルをscpするという解決策がそれを私のラップトップのMySQL 5.5.37にロードし、そこからmysqldumpを実行して、新しいmysqldumpをLinux CentOS VMに送り返し、mysqldumpをロードします。

ところで、MySQLの設定を変更せずに、4.5時間でWindows 7ラップトップに1回の挿入としてロードされた350万行のテーブル。正直に言うと、ラップトップのmysqldumpをダンプで動作するように再構成しなかったため、「暗闇でのショット」が機能すると信じていました。私の推測では、ibdata1のundoログがディスク上で成長し、すべてを保持しているため、ロードされた可能性があります。

同じマシンでリロード時にダンプする場合、skip-extended-insertまで生きる必要はありません。

提案

私が私の答えをタイプしている間に、あなたが質問に以下を注入するのを見ました

私が実行したクエリによると、テーブルは約1.7GBで動作しますが、それはMyISAMであり、明らかにその数は信頼できません(とにかく大きなテーブルです)。

提案#1

その1つのMyISAMテーブルに1.7GBがあり、1100万行ある場合、バルク挿入バッファーのサイズを増やすことをお勧めします。一括挿入バッファーはMyISAMでのみ使用され、拡張挿入をサポートします。 bulk_insert_buffer_size を256Mに設定します。

My.cnfまたはmy.iniに移動して、これを追加します

bulk_insert_buffer_size = 256M

次に、MySQLにログインして実行します。

mysql> SET GLOBAL bulk_insert_buffer_size = 1024 * 1024 * 256;

提案#2

InnoDBについては、 大きなログバッファー を使用する必要があります。これをmy.cnfに追加して、64Mに設定します

innodb_log_buffer_size = 64M

新しい値を使用するには、MySQLを再起動する必要があります。

提案#3

innodb_log_file_size を増やして、より大きなInnoDBログが必要になる場合もあります。これには、次のように手動での介入が必要です。

ステップ01:このコマンドをrootとして実行

mysql> SET GLOBAL index_fast_shutdown = 0;

ステップ02:mysqlをシャットダウン

  • Linux:service mysql stop
  • Windows(管理者として):net stop mysql

ステップ03:このオプションをmy.cnfまたはmy.iniに追加します

innodb_log_file_size = 1G

STEP 04:OSで、ib_logfile0およびib_logfile1が配置されているフォルダーに移動して実行します

Linux

mv ib_logfile0 ib_logfile0.bak
mv ib_logfile1 ib_logfile1.bak

ウィンドウズ

rename ib_logfile0 ib_logfile0.bak
rename ib_logfile1 ib_logfile1.bak

ステップ05:mysqlを起動します(ログファイルが再作成されるため、起動にはさらに1〜2分かかります)

  • Linux:service mysql start
  • Windows(管理者として):net start mysql

これらの提案された変更を1つ以上行った後、ダンプして再ロードしてみてください。スムーズに進みます。 SUGGESTION #1だけから始めて、お試しください。他の2つを試して、さらに改善するかどうかを確認してください。

概要

My.cnfまたはmy.iniのターゲットMySQL DBサーバーにこれらのオプションが必要です

bulk_insert_buffer_size = 256M
innodb_log_buffer_size = 64M
innodb_log_file_size = 1G
max_allowed_packet = 1G

試してみる !!!

1
RolandoMySQLDBA

Mysqldumpには、各値の挿入をテーブルごとにバッチ処理できるオプションがありますか?

はい。 net_buffer_length-クライアント/サーバー通信用のバッファーの初期サイズ。

1