(これはコメントに埋もれている質問のいくつかに答えています。)
誤称 「空き」スペースには、ブロック全体のみが含まれ、ブロック内の予備の部屋やその他の多くの詳細は含まれません。
ケース1:すべてのテーブルはibdata1
にあります -SHOW TABLE STATUS
(またはinformation_schema
への同等のクエリ 同じData_free
が表示されます 値、つまりibdata1
の空き容量 。このスペースは、どのテーブルでも再利用できます。 OSにスペースを戻すのは難しいです。
ケース2:すべてのテーブルはfile_per_table
-各Data_free
テーブルのスペースを指します。そしてSUM()
意味があります。 (ibdata1はまだ存在しますが、実際のテーブルは含まれていません。InnoDBが必要とするものは他にもたくさんあります。)
ケース3:混合物 --file_per_tableをさまざまな時点でオン/オフにすると、一部のテーブルはibdata1にあり、一部には独自のテーブルスペースがあります。
ケース4:5.7でテーブルスペースを作成する -たとえば、データベースごとにテーブルスペースを作成できます。
ケース5:パーティションテーブル -各パーティションはテーブルのように機能します。
ケース6: 8.0 -さらに多くの変更が予定されています。
データベース==ディレクトリ MySQLのディレクトリツリーでは、各データベースはファイルシステムディレクトリと見なすことができます。そのディレクトリ内には、各テーブルのファイルのセットが表示されます。 .frm
ファイルにはテーブル定義が含まれています。 .ibd
の場合 ファイルが存在する場合、テーブルはfile_per_tableで作成されました。これは、テーブルがfile_per_tableであるかどうかを検出するための最も信頼できる方法である可能性があります。 (8.0ではここで重要な変更があります。)
どのくらいのスペースを再利用できますか ?良い答えはありません。通常、行を挿入すると、その行が属するブロック内にスペースが見つかり、Data_freeは縮小されません。ただし、ブロック分割があった場合、Data_freeは16KB(ブロックサイズ)または4MB(「エクステントサイズ」-または8MBですか?)の倍数でドロップする可能性があります。また、ランダムに挿入すると、BTreeブロックが平均して約69%いっぱいになります。
innodb_file_per_table
を変更する 次のCREATE TABLE
まで効果はありません またはALTER TABLE
。そして、それは新しく作成/コピーされたデータ+インデックス(ibdata1または.ibd)を配置する場所にのみ影響します。データを破壊することはありません。
大きなテーブル 通常、4MBから7MBのData_freeがあります。追加できる行数を計算するときは、Data_freeがその範囲を下回ることを計画しないでください。
Avg_row_size 役に立つはずです。しかし、それ(および行)の近似が不十分な場合があります。それらの積(Data_length)は常に正しいです。したがって、これは可能性があります 「OSからより多くのスペースを取得する前に進むべき行:
(Data_free - 7M) / Avg_row_size
テーブルスペースの推奨事項 :「big」テーブルをfile_per_tableに配置します。 'tiny'テーブルをibdata1またはデータベース固有のテーブルスペース(5.7)に配置します。申し訳ありませんが、「big」と「tiny」の境界線に関する簡単な推奨事項はありません。そして、テーブルを移行するのは不器用です:SET global innodb_file_per_table = ...;
;ログアウト;ログイン(グローバルを取得するため); ALTER TABLE tbl ENGINE=InnoDB;
。そして、それは必然的にテーブルの完全なコピーです。
(警告 :多くの詳細を省略しました。)