web-dev-qa-db-ja.com

`ERROR 1114(HY000)the table ... is full` in innodb_file_per_table set to autoextend

大量のデータを保持するMySQLデータベースを持っています(100-200GB-一連の科学的測定値)。データの大部分は1つのテーブルSampleに格納されます。ここで、データベースのスレーブレプリカを作成しています。プロセス中に_innodb_file_per_table_の利点を活用したいと思いました。したがって、スレーブ構成で_innodb_file_per_table_を設定し、データベースのダンプをインポートしました。驚いたことに、それは失敗しました

5602行目のエラー1114(HY000):テーブル「Sample」がいっぱいです

ファイル_Sample.ibd_は現在約93GBであり、パーティションに600GB以上の空き容量があるため、ディスクの空き容量の問題ではありません。どちらのファイルシステムの制限にも達していないようです(私はext4を使用しています)。

何が原因なのか、何を調べればよいのか、どんなアイデアにも感謝します。


pdate:mysql Ver 14.14 Distrib 5.1.66, for debian-linux-gnu (x86_64)を使用しています。

_SELECT @@datadir; -- returns `/home/var/lib/mysql/`
SHOW VARIABLES LIKE '%innodb_data_file_path%'; -- ibdata1:10M:autoextend 

df -h /home/var/lib/mysql/
768G   31G  699G   5% /home
_
26
Petr Pudlák

事実

ext4を使用しているとのことですが、ファイルサイズの上限は16TBです。したがって、Sample.ibdがいっぱいであってはなりません。

あなたのinnodb_data_file_pathibdata1:10M:autoextendだと言いました。したがって、ibdata1ファイル自体には、OS以外のサイズに上限はありません。

なぜこのメッセージが出てくるのですか?メッセージが「ディスク...がいっぱいです」ではなく、「テーブル...がいっぱいです」であることに注意してください。 このテーブルの完全な状態は、論理的な観点からです。 InnoDBについて考えてみてください。どんな相互作用が起こっていますか?

私の推測では、InnoDBは93GBのデータを単一のトランザクションとしてロードしようとしています。 Table is Fullメッセージはどこから発信されますか?私はibdata1を、その物理的なサイズ(既に除外されている)ではなく、どのトランザクション制限に達しているかという観点で調べます。

innodb_file_per_table が有効になっていて、新しいデータをMySQLにロードする場合、ibdata1内には何がありますか?

  • データ辞書
  • 二重書き込みバッファ
    • データの破損を防止するセーフティネット
    • キャッシングのためのOSのバイパスを支援
  • バッファの挿入(セカンダリインデックスへの変更を合理化)
  • ロールバックセグメント
  • ログを元に戻す
  • ここをクリックしてibdata1の図解をご覧ください

私の疑いは、元に戻すログややり直しログのせいだと私に言います。

これらのログとは何ですか? The Book によると

sxs

第10章:「ストレージエンジン」203ページパラグラフ3,4では、次のように述べています。

InnoDBエンジンは、元に戻すログとやり直しログの2種類のログを保持します。 undo logの目的は、トランザクションをロールバックすることと、それを必要とするトランザクション分離レベルで実行されているクエリの古いバージョンのデータを表示することです。元に戻すログを処理するコードは、storage/innobase/buf/log/log0log.cにあります。

redo logの目的は、クラッシュリカバリで使用される情報を保存することです。これにより、回復プロセスは、クラッシュの前に完了したかどうかに関係なく、トランザクションを再実行できます。これらのトランザクションを再実行した後、データベースは一貫した状態になります。 REDOログを処理するコードは、storage/innobase/log/log0recv.cにあります。

分析

1023個の元に戻すログがあります ibdata1内(ロールバックセグメントと元に戻すスペースを参照) 。元に戻すログはリロード前と同じようにデータのコピーを保持するため、すべての1023元に戻すログが上限に達しています。別の見方をすると、すべての1023元に戻すログは、Sampleテーブルをロードする1つのトランザクション専用である可能性があります。

ちょっと待って...

あなたはおそらく「空のSampleテーブルをロードしています」と言っているでしょう。元に戻すログはどのように関係していますか? Sampleテーブルに93GBのデータがロードされる前は、テーブルは空でした。存在しなかったすべての行を表すには、元に戻すログのハウスクリーニングスペースを使用する必要があります。 ibdata1に注がれるデータの量を考えると、1023の取り消しログがいっぱいになるのは簡単なことです。私はこれを疑う最初の人ではありません:

MySQL 4.1ドキュメントから、Posted by Chris Calender on September 4 2009 4:25pmに注意してください:

5.0(5.0.85より前)および5.1(-5.1.38より前)では、InnoDBがアンドゥスロットを使い果たすと、InnoDBテーブルの「テーブルがいっぱいです」というエラーを受け取る可能性があることに注意してください(バグ#18828)。

MySQL 5.0のバグレポートは次のとおりです。 http://bugs.mysql.com/bug.php?id=18828

提案

Sampleテーブルのmysqldumpを作成するときは、 -no-autocommit を使用してください

mysqldump --no-autocommit ... mydb Sample > Sample.sql

これは、INSERTの後に明示的なCOMMIT;を置きます。次に、テーブルをリロードします。

これが機能しない場合(これは好きではありません)、これを行います

mysqldump --no-autocommit --skip-extended-insert ... mydb Sample > Sample.sql

これにより、各INSERTは1行だけになります。 mysqldumpははるかに大きく(10倍以上)、リロードに10〜100倍の時間がかかる可能性があります。

どちらの場合も、これにより、元に戻すログが氾濫するのを防ぐことができます。

試してみる !!!

2013年6月3日更新13:05 EDT

追加の提案

InnoDBシステムテーブル(別名ibdata1)がファイルサイズの制限に達し、ログの取り消しを使用できない場合は、別のシステムテーブルスペース(ibdata2)を追加するだけで済みます。

ちょうど2日前にこの状況に遭遇しました。以前の投稿を自分のやったことで更新しました:参照 データベースの設計-テーブルサイズの制限という頭痛の種を避けるために複数のデータベースを作成する

基本的に、新しいシステムテーブルスペースファイルに対応するには、 innodb_data_file_path を変更する必要があります。方法を説明しましょう:

シナリオ

ディスク(ext3)では、クライアントのサーバーには次のものがありました。

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  2 00:15 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  2 00:15 ibdata2

設定は

innodb_data_file_path=ibdata1:346M;ibdata2:500M:autoextend:max:10240000M

ibdata22145386484Mである2196875759616に成長したことに注意してください。

ibdata2のファイルサイズをinnodb_data_file_pathに埋め込み、ibdata3を追加する必要がありました

innodb_data_file_path=ibdata1:346M;ibdata2:2196875759616;ibdata3:10M:autoextend

Mysqldを再起動すると、うまくいきました。

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  3 17:02 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  3 17:02 ibdata2
-rw-rw---- 1 s-em7-mysql s-em7-mysql   32315015168 Jun  3 17:02 ibdata3

40時間後に、ibdata3は31Gに成長しました。 MySQLが再び機能しました。

33
RolandoMySQLDBA

私も同じ問題を抱えていて、1つのことを行っただけでうまくいきました。

innodb_data_file_path構成ファイルのmy.cnfの最大サイズが小さすぎるようです。以下のコードを変更するだけです-

innodb_data_file_path = ibdata1:10M:autoextend:max:512M

重要な注意すべてのInnoDBテーブルで、512MBを超えるデータをホストすることはできません。

innodb_file_per_tableを使用して、テーブルごとのinnodb-スキームに切り替えることもできます。

3
Joomler