MySQL テーブルスペースの断片化の概念と関連する問題の解決策

MySQL テーブルスペースの断片化の概念と関連する問題の解決策

背景

MySQL を頻繁に使用すると、MySQL データ ファイルのディスク容量が一般的に増加し続け、データを削除したり、データのバッチを挿入したりしても、ディスク容量が変更されないことがあります。この奇妙な現象の原因は、MySQL テーブル スペースの断片化です。

表領域の断片化とは何ですか?

表領域の断片化とは、表領域内に断片が存在することを意味します。よりわかりやすい比喩を使うと、これは A4 用紙のようなものです。「表領域の断片化」とは、この A4 用紙を細かく裂いてから、再びまとめるようなものです。断片の間には隙間ができ、この隙間が「表領域の断片」です。再構成された断片は、実際には完全な A4 用紙よりも 1 サイズ大きくなり、テーブル スペースによって簡単に引き起こされる問題、つまり無駄なスペースも表します。

背景で説明した現象は、図で説明できます。

図中の数字は実際のデータ行を表し、角丸四角形はテーブルの表スペースを表します。左から右へ、最初の操作はデータを削除することです。MySQL はスペースを積極的に解放しないように設計されているため、テーブル内のデータ行が削除されると、データは「削除」されますが、この部分のスペースは実際には解放されず、テーブル A によって引き続き占有されます。そのため、ログ テーブル内の大量のデータが削除されても、MySQL のディスク スペースは削減されないというシナリオが発生します。

PS: スペースを解放しないこの設計は、主に遅延削除に関連しています。初期のデータベースの設計では、使用されていた IO デバイスは一般に機械式ディスクであり、その読み取りおよび書き込みパフォーマンスは SSD よりもはるかに劣っていたため、削除操作によってディスク上のデータが直接削除されることはほとんどありませんでした。

データが削除された後、元々連続していたスペースに 2 つの空白領域が出現していることがわかります。これは一般にテーブルスペース ホールと呼ばれます。ホールが多すぎる場合は、テーブルスペースの断片化 (対応するテーブルスペースが連続している) と呼ばれます。この部分のスペースは解放されませんが、再利用可能としてマークされます。右端のテーブルスペース図 (3 番目の角丸四角形) を参照してください。新しいデータが挿入されると、新しいデータはテーブルスペースの穴に再度書き込まれます。これは、大規模なデータ削除されたテーブルにデータを書き込むときに、テーブルスペースが大幅に増加しないか、まったく増加しない可能性があることも意味します。

実際、テーブルスペースの穴を引き起こす可能性がある操作は削除だけではありません。更新もこの問題を引き起こす可能性があります。たとえば、varchar などの可変長文字列のデータを変更する場合、列が短くなると非常に小さな穴が発生します。列が長くなると、スペース不足のためにデータ行の一部のデータが他の場所に移動される可能性があります。

表領域の断片化を確認する方法

MySQL のシステム テーブルにはテーブルスペースの使用状況が記録されます。これは次のクエリで確認できます。

SELECT CONCAT(テーブルスキーマ,'.',テーブル名) AS 'テーブル名',
                table_rows AS '行数'、
                CONCAT(ROUND(データ長/(1024*1024),2),'M') AS 'データサイズ',
                CONCAT(ROUND(インデックス長/(1024*1024),2),'M') AS 'インデックスサイズ',
                CONCAT(ROUND(データフリー/(1024*1024),2),'M') AS'データフリー',
                CONCAT(ROUND(データ空き容量/データ長,2),'%') AS 'データ空き容量',
                ENGINE を「エンジン」として
information_schema.TABLES から
ここで、table_schema = 'テーブル名' 
data_free desc で ORDER します。

data_free はテーブルスペースの断片化の合計スペースサイズを指し、data_free_pct はこのテーブルの断片化の割合を指します。効果は次のとおりです。

mysql> SELECT CONCAT(table_schema,'.',table_name) AS 'table_name',
    -> table_rows AS '行数'、
    -> CONCAT(ROUND(データ長/(1024*1024),2),' M') AS 'データサイズ',
    -> CONCAT(ROUND(インデックス長/(1024*1024),2),' M') AS 'インデックスサイズ',
    -> CONCAT(ROUND(data_free/(1024*1024),2),' M') AS'data_free',
    -> CONCAT(ROUND(データ空き容量/データ長,2),' %') AS 'データ空き容量',
    -> ENGINE を 'engine' として
    -> information_schema.TABLES から
    -> WHERE table_schema = 'sbtest'
    -> data_free desc で ORDER します。
+----------------+----------------+-----------+------------+-----------+---------------+---------+
| table_name | 行数 | data_size | index_size | data_free | data_free_pct | engine |
+----------------+----------------+-----------+------------+-----------+---------------+---------+
| sbtest.sbtest5 | 0 | 0.02 M | 0.00 M | 44.00 M | 2816.00 % | InnoDB |
| sbtest.sbtest4 | 986400 | 214.70 M | 15.52 M | 4.00 M | 0.02 % | InnoDB |
| sbtest.sbtest3 | 986400 | 214.70 M | 15.52 M | 4.00 M | 0.02 % | InnoDB |
| sbtest.sbtest2 | 986400 | 214.70 M | 15.52 M | 4.00 M | 0.02 % | InnoDB |
| sbtest.sbtest1 | 987400 | 199.70 M | 15.52 M | 4.00 M | 0.02 % | InnoDB |
+----------------+----------------+-----------+------------+-----------+---------------+---------+
セット内の行数は 5 です (0.00 秒)

最初のデータ行はテストに使用されます。テーブル内のすべてのデータが削除されているため、計算された data_free_pct は 100% を超えています。

表スペースの断片化問題を解決する方法

現在、テーブル スペースを再利用する方法は 1 つしかなく、最適化、テーブルの変更などを含む、テーブルの再構築です。一部の alter table 操作は、テーブルを再構築することによってのみ完了できます。そのため、大規模なテーブルでメンテナンス操作を実行した後、ディスク領域の使用量が減少することがあります。これは、テーブル領域のフラグメントによって解放された領域が再利用されたためです。

一般的な経験から、テーブル スペースの断片化回復操作を頻繁に実行することは推奨されません。テーブルの再構築はサーバー リソースに大きな影響を与え、このテーブルの書き込み操作に影響を与えるため、月に 1 回で十分です。ディスク容量が非常に少なく、ログが基本的にクリアされていない限り、断片化率 (data_free_pct) が 20% 未満であれば、あまり心配する必要はありません。

スペースの再利用の問題について

一部のログ テーブルや地域特性を持つテーブルについては、MySQL パーティション テーブルを使用して管理することをお勧めします。 データのバッチをクリーンアップする必要がある場合は、パーティション切り捨てを使用してクリーンアップし、ディスク領域を直接解放できます。

上記は、MySQL テーブル スペースの断片化の概念と関連する問題の解決方法の詳細な内容です。MySQL テーブル スペースの断片化の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL でテーブルスペースの断片化を解消する詳細な例
  • MySQLテーブルの断片化の原因とクリーンアップを分析する
  • MySQL テーブルの断片化を解消し、スペースを再利用する方法

<<:  個人的な意見: デザインについて語る

>>:  入力ボックスのプレースホルダーアニメーションと入力検証を実現する純粋なCSS

推薦する

vuexプロジェクトにおけるログインステータス管理の実践プロセス

目次道具:ログインシナリオ:練習する:シナリオ1: 思考と実践シナリオ2: 思考と実践要約する道具:...

WeChatアプレットはふるいを振る効果を実現

この記事では、WeChatアプレットの具体的なコードを参考までに共有します。具体的な内容は次のとおり...

Html+CSS 描画三角形アイコン

まずはレンダリングを見てみましょう: XML/HTML コードコンテンツをクリップボードにコピー&l...

Docker コンテナの uid と gid の詳細な理解

デフォルトでは、コンテナ内のプロセスは root ユーザー権限で実行され、この root ユーザーは...

SQL ステートメント実行の詳細な説明 (MySQL アーキテクチャの概要 -> クエリ実行プロセス -> SQL 解析順序)

序文:私はずっと、SQL 文がどのように、どのような順序で実行されるのかを知りたいと思っていました。...

HTML テーブル マークアップ チュートリアル (1): テーブルの作成

<br />これは 123WORDPRESS.COM が提供する一連のチュートリアルです...

JavaScript の構造化代入の一般的なシナリオと例 5 つ

目次序文1. データを抽出する2. エイリアス値3. 動的プロパティ4. オブジェクトの分解における...

Linux で xargs コマンドを使用する詳細なチュートリアル

みなさんこんにちは。私は梁旭です。 Linux を使用しているときに、いくつかのコマンドを連結する必...

MySQLトリガーの使用

トリガーにより、ステートメントの実行前または実行後に他の SQL コードを実行できます。トリガーは、...

MySQL クエリのソートとクエリ集計関数の使用法の分析

この記事では、例を使用して、MySQL クエリのソート関数とクエリ集計関数の使用方法を説明します。ご...

Docker で SVN サーバーを構築するチュートリアル

SVN は Subversion の略称で、ブランチ管理システムを使用して効率的に管理するオープンソ...

画像をクリックして切り替えるJavaScript

クリックして画像を切り替えることは、日常生活で非常によく行われることです。今日の練習は、画像を切り替...

js における浅いコピーと深いコピーの詳細な説明

目次1. jsメモリ2. 譲渡3. 浅いコピー4. ディープコピー序文:以下の記事を読む前に、記憶に...

MySQL のフィールドに一意のインデックスを追加および削除する方法

1. PRIMARY KEY(主キーインデックス)を追加するmysql>ALTER TABLE...

JS ES6 変数分割代入の詳細な説明

目次1. 脱構築とは何か? 2. 配列の分割3. 配列モードと代入モードの統一4. デフォルト値の構...