MySQL は、大量のデータを削除した後にスペースが解放されない問題をどのように解決しますか?
この記事では、mysql に関する関連知識を提供します。主に、大量のデータを削除した後にスペースが解放されないという関連問題を整理します。MySQL での挿入と更新の両方で、ページ分割が発生する可能性があります。このように断片化されていますので、一緒に見ていきましょう。
推奨学習: mysql ビデオ チュートリアル
MySQL のいくつかのデフラグ ソリューションの概要 (スペースが解放されない問題を解決するため)大量のデータを削除した後) 質問)
1. 背景知識?
#1.1 なぜフラグメントが存在するのですか?
- MySQL で挿入と更新の両方を行うと、ページが分割される可能性があるため、断片化が発生します。 UPDATE が多数の場合、ファイルの断片化も発生します。Innodb の最小物理ストレージ割り当て単位はページであり、UPDATE によってもページ分割が発生する可能性があります。ページ分割が頻繁に行われると、ページが断片化します。疎になり、不規則に埋められるため、最終的にはデータが断片化します。
- delete ステートメントは、実際にはデータにマークを付けてリンク リストに記録するだけで、空白スペースが形成されます。 InnoDB では、一部の行が削除されると、これらの行はインデックスから物理的に削除されるのではなく、「削除済み」としてマークされるだけなので、スペースは実際には解放および再利用されません。 InnoDB のパージ スレッドは、これらの不要なインデックス キーと行を非同期的にクリーンアップします。
- 挿入操作を実行するとき、MySQL は空白スペースを使用しようとしますが、特定の空白スペースが適切なサイズのデータで占有されていない場合、完全に占有することはできません。フラグメンテーション;
- 概要:
- #テーブルの追加、削除、および変更操作により、データ ホールが発生する可能性があります。テーブルに対して追加、削除、および変更操作が実行されます。最後に、データ ホールが存在する可能性が高くなります。
-
MySQL でデータを削除するいくつかの状況と、ディスク領域を解放するかどうか:
- drop、truncate は、ディスク領域がすぐに解放されます。 Innodb と MyISAM です;
- truncate table は、実際には、テーブルを削除してから作成するのと少し似ていますが、テーブルの作成プロセスが最適化されている点が異なります。たとえば、テーブル構造ファイルが次のようになります。以前から存在していた、などしたがって、速度はテーブルのドロップの速度に近い必要があります。
- delete from table_name を実行すると、テーブル内のすべてのデータが削除されます。MyISAM の場合、ディスク領域はすぐに解放されます (特別に処理されるため、より合理的です) )、InnoDB はディスク領域を解放しません;
- テーブル名からの削除 (xxx の場合); 条件付き削除では、innodb も MyISAM もディスク領域を解放しません;
- 使用します操作テーブル table_name の削除後に最適化すると、ディスク領域がすぐに解放されます。 innodb であっても myisam であっても。したがって、ディスク領域を解放するという目的を達成するには、削除後にテーブルの最適化操作を実行します。
- from テーブルを削除してもディスク領域は解放されませんが、この領域は次回データを挿入するときに引き続き使用できます。
- MySQL がデータをスキャンするとき、オブジェクトは実際にはリストの容量要件の上限、つまりデータが書き込まれる領域のピーク位置;
- MySQL データベース内のテーブルは、複数回の削除、更新、挿入後、表スペースは断片化されます。表スペースを定期的にデフラグして断片化を解消すると、表スペースへのアクセスのパフォーマンスが向上します。
- この種の断片化では、ストレージ コストが増加するだけでなく、データの断片化によりテーブルのスキャン効率も低下します。
- フラグメントが最適化されていない場合、フラグメントが長時間ディスク領域を占有し、ディスク使用量がますます増加する可能性があります。
- データベース内の断片化されたすべてのテーブルの表示
mysql> select concat('optimize table ',table_schema,'.',table_name,';'),data_free,engine from information_schema.tables where data_free>0 and engine !='MEMORY'; +-----------------------------------------------------------+-----------+--------+ | concat('optimize table ',table_schema,'.',table_name,';') | DATA_FREE | ENGINE | +-----------------------------------------------------------+-----------+--------+ | optimize table abc.t_user_answer; | 2097152 | InnoDB | | optimize table mysql.time_zone_transition; | 4194304 | InnoDB | | optimize table mysql.time_zone_transition_type; | 4194304 | InnoDB | | optimize table mysql.user; | 4194304 | InnoDB | 。。。。
ログイン後にコピー - 指定されたテーブルの断片化状況の表示
りー
Data_free: 4194304 は、フラグメント内のバイト数を表します。データ テーブルが頻繁に削除されると、大量の Data_free レコードが頻繁に削除されたり、可変長フィールドを持つテーブルが変更されたりすることになります。
- 最も深刻に断片化されたテーブルを見つける
mysql> show table status like 't_user'\G *************************** 1. row *************************** Name: t_user Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 4333 Avg_row_length: 589 Data_length: 2555904 Max_data_length: 0 Index_length: 2719744 Data_free: 4194304 Auto_increment: NULL Create_time: 2021-11-19 10:13:31 Update_time: 2022-04-20 14:28:42 Check_time: NULL Collation: utf8mb4_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec)
ログイン後にコピー
公式文書リファレンス
通常有这几种做法
- alter table tb_test engine=innodb; (本质上是 recreate)
- optimize table tb_test; (本质上是 recreate,但是在不同创建下会有区别)
- ALTER TABLE tablename FORCE (在InnoDB表中等价于 alter table tb_test engine=innodb; )
- mysqlcheck 批量表空间优化
- gh-ost/pt-osc
- pt-online-schema-change (本质上也是 先备份旧表数据,然后 truncate 旧表)
1. alter table tb_test engine=innodb 原理介绍
这其实是一个NULL操作,表面上看什么也不做,实际上重新整理碎片了.当执行优化操作时,实际执行的是一个空的 ALTER 命令,但是这个命令也会起到优化的作用,它会重建整个表,删掉未使用的空白空间.
Running ALTER TABLE tbl_name ENGINE=INNODB on an existing InnoDB table performs a “null” ALTER TABLE operation, which can be used to defragment an InnoDB table, as described in Section 15.11.4, “Defragmenting a Table”. Running ALTER TABLE tbl_name FORCE on an InnoDB table performs the same function.
MySQL5.6 开始采用 Inplace 方式重建表,Alter 期间,支持 DML 查询和更新操作,语句为 alter table t engine=innodb, ALGORITHM=inplace;之所以支持 DML 更新操作,是因为数据拷贝期间会将 DML 更新操作记录到 Row log 中。 重建过程中最耗时的就是拷贝数据的过程,这个过程中支持 DML 查询和更新操作,对于整个 DDL 来说,锁时间很短,就可以近似认为是 Online DDL。 执行过程: 1、获取 MDL(Meta Data Lock)写锁,innodb 内部创建与原表结构相同的临时文件 2、拷贝数据之前,MDL 写锁退化成 MDL 读锁,支持 DML 更新操作 3、根据主键递增顺序,将一行一行的数据读出并写入到临时文件,直至全部写入完成。并且,会将拷贝期间的 DML 更新操作记录到 Row log 中 4、上锁,再将 Row log 中的数据应用到临时文件 5、互换原表和临时表表名 6、删除临时表
2. optimize table xxx;
OPTIMIZE TABLE语句可以重新组织表、索引的物理存储,减少存储空间,提高访问的I/O效率。类似于碎片整理功能。
MySQL可以通过optimize table
语句释放表空间,重组表数据和索引的物理页,减少表所占空间和优化读写性能
-
使用语法
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_n说ame [, tbl_name] …
- 对于主从架构, LOCAL 参数可以让这个过程不写入 binlog ,这样在主库上执行时就不会同步给从库了
- 默认情况下,MySQL将OPTIMIZE TABLE语句写入二进制日志,以便它们复制到slave服务器。如果不想写二进制日志,使用命令时加上NO_WRITE_To_BINLOG或LOCAL关键字即可。
- 使用这个语句需要具有对目标表的SELECT、INSERT权限。
-
注意:
需要有足够的空间才能进行OPTIMIZE TABLE。 (剩余空间必须 > 被 OPTIMIZE 的表的大小)
-
OPTIMIZE 只对独立表空间(innodb_file_per_table=1)才有用,对共享表空间不起作用。
对于共享表空间,如果需要瘦身: 必须将数据导出,删除ibdata1,然后将 innodb_file_per_table 设置为独立表空间, 然后将数据导入进来。
-
对于InnoDB的表,OPTIMIZE TABLE 的工作原理如下
对于InnoDB表, OPTIMIZE TABLE映射到ALTER TABLE … FORCE(或者这样翻译:在InnoDB表中等价 ALTER TABLE … FORCE),它重建表以更新索引统计信息并释放聚簇索引中未使用的空间。
当您在InnoDB表上运行时,它会显示在OPTIMIZE TABLE的输出中,如下所示: mysql> OPTIMIZE TABLE foo; +----------+----------+----------+---------------------------------------+ | Table | Op | Msg_type | Msg_text | +----------+----------+----------+---------------------------------------+ | test.foo | optimize | note | Table does not support optimize, doing recreate + analyze instead | | test.foo | optimize | status | OK | +----------+----------+----------+---------------------------------------+ # 但这个提示语可以忽略,从严格的意义讲,说InnoDB不支持optimize table,其实不太准确。 因为 MYSQL的文档说明了,当INNODB 的表,MYSQL会以 ALTER TABLE force + analyze 去执行这个命令(相当于做了recreate和analyze)。 所以最终还是会看到 OK 的状态。 # https://stackoverflow.com/questions/30635603/what-does-table-does-not-support-optimize-doing-recreate-analyze-instead-me
ログイン後にコピー 对于MYISAM表,OPTIMIZE TABLE 的工作原理:
1. 如果表已删除或分隔行,就修复该表。
2. 如果索引页没有排序,就排序它们。
3. 如果表的统计信息不是最新的(而且修复不能通过对索引进行排序),就更新它们。-
**执行时也可以发现报错: Temporary file write failure. **
建议参考这片文章:
Mysql optimize table 时报错 Temporary file write failure. 的解决方案
-
optimize 语句的官网介绍
如果您已经删除了表的一大部分,或者如果您已经对含有可变长度行的表(含有VARCHAR, BLOB或TEXT列的表)进行了很多更改,则应使用 OPTIMIZE TABLE。
被删除的记录被保持在链接清单中,后续的INSERT操作会重新使用旧的记录位置。您可以使用OPTIMIZE TABLE来重新利用未使用的空间,并整理数据文件的碎片。
在多数的设置中,您根本不需要运行OPTIMIZE TABLE。即使您对可变长度的行进行了大量的更新,您也不需要经常运行,每周一次或每月一次 即可,只对特定的表运行。
Mysql 5.6 之前 在OPTIMIZE TABLE运行过程中,MySQL会锁定表,5.6之后有了 Online DDL 则大大减少了锁表时间。
3. alter table、analyze table和optimize table区别
-
alter table tb_test engine = innodb;
- (也就是 recreate)MySQL 5.5以前用Offline的方式重建表,5.6以后用Online的方式重建表;
-
analyze table tb_test ;
- 重新统计表的索引信息,不会修改数据,不会重建表,整个过程加MDL读
-
optimize table tb_test ;
- は alter table xxx = innodb;analyze table xxx; の処理です。
4. OPTIMIZE TABLE または ALTER TABLE xxxx ENGINE= INNODB はどちらが優れていますか?
- OPTIMIZE TABLE または ALTER TABLE xxxx ENGINE= INNODB 基本的には同じ。ただし、場合によっては、ALTER TABLE xxxx ENGINE= INNODB の方が優れています。
- 例: old_alter_table システム変数が有効になっていないなど。
- さらに: MyISAM タイプのテーブルの場合、ALTER TABLE xxxx ENGINE= INNODB を使用する方が、OPTIMIZE TABLE よりも明らかに優れています。
2.3 公式推奨事項
MySQL では、デフラグを頻繁に (時間ごとまたは毎日) 行わないことを公式に推奨しています。一般に、実際の状況に応じて、デフラグは週に 1 回または月に 1 回だけ行う必要があります。 (現在、毎月午前 4 時にすべての mysql インスタンスのテーブル フラグメントをクリアしています)
推奨学習: mysql ビデオ チュートリアル
以上がMySQL は、大量のデータを削除した後にスペースが解放されない問題をどのように解決しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









MySQLデータベースでは、ユーザーとデータベースの関係は、アクセス許可と表によって定義されます。ユーザーには、データベースにアクセスするためのユーザー名とパスワードがあります。許可は助成金コマンドを通じて付与され、テーブルはCreate Tableコマンドによって作成されます。ユーザーとデータベースの関係を確立するには、データベースを作成し、ユーザーを作成してから許可を付与する必要があります。

MySQLは、インストールが簡単で、強力で管理しやすいため、初心者に適しています。 1.さまざまなオペレーティングシステムに適した、単純なインストールと構成。 2。データベースとテーブルの作成、挿入、クエリ、更新、削除などの基本操作をサポートします。 3.参加オペレーションやサブクエリなどの高度な機能を提供します。 4.インデックス、クエリの最適化、テーブルパーティション化により、パフォーマンスを改善できます。 5。データのセキュリティと一貫性を確保するために、バックアップ、リカバリ、セキュリティ対策をサポートします。

NAVICAT自体はデータベースパスワードを保存せず、暗号化されたパスワードのみを取得できます。解決策:1。パスワードマネージャーを確認します。 2。NAVICATの「パスワードを記憶する」機能を確認します。 3.データベースパスワードをリセットします。 4.データベース管理者に連絡してください。

1.正しいインデックスを使用して、データの量を削減してデータ検索をスピードアップしました。テーブルの列を複数回検索する場合は、その列のインデックスを作成します。あなたまたはあなたのアプリが基準に従って複数の列からのデータが必要な場合、複合インデックス2を作成します2。選択した列のみを避けます。必要な列のすべてを選択すると、より多くのサーバーメモリを使用する場合にのみサーバーが遅くなり、たとえばテーブルにはcreated_atやupdated_atやupdated_atなどの列が含まれます。

NAVICATプレミアムを使用してデータベースを作成します。データベースサーバーに接続し、接続パラメーターを入力します。サーバーを右クリックして、[データベースの作成]を選択します。新しいデータベースの名前と指定された文字セットと照合を入力します。新しいデータベースに接続し、オブジェクトブラウザにテーブルを作成します。テーブルを右クリックして、データを挿入してデータを挿入します。

次のコマンドでmysqlデータベースを表示します。サーバーに接続します:mysql -u username -pパスワードrun showデータベース。すべての既存のデータベースを取得するコマンド[データベース]を選択します。データベース名を使用します。テーブルを表示:表を表示します。テーブル構造を表示:テーブル名を説明してください。データを表示:[テーブル名]から[ *]を選択します。

Passwordが暗号化された形式で保存されているため、MariadbのNavicatはデータベースパスワードを直接表示できません。データベースのセキュリティを確保するには、パスワードをリセットするには3つの方法があります。NAVICATを介してパスワードをリセットし、複雑なパスワードを設定します。構成ファイルを表示します(推奨されていない、高リスク)。システムコマンドラインツールを使用します(推奨されません。コマンドラインツールに習熟する必要があります)。

MySQLでテーブルをコピーするには、新しいテーブルの作成、データの挿入、外部キーの設定、インデックスのコピー、トリガー、ストアドプロシージャ、および機能が必要です。特定の手順には、同じ構造を持つ新しいテーブルの作成が含まれます。元のテーブルからデータを新しいテーブルに挿入します。同じ外部キーの制約を設定します(元のテーブルに1つがある場合)。同じインデックスを作成します。同じトリガーを作成します(元のテーブルに1つがある場合)。同じストアドプロシージャまたは関数を作成します(元のテーブルが使用されている場合)。
