自動インクリメント変数の永続性[MySQL][データベース]

自己増分変数の永続性

MySQL 8.0より前では、自己インクリメントする主キーAUTO_INCREMENTの値がmax(主キー)+ 1より大きい場合、MySQLの再起動後、AUTO_INCREMENT = max(主キー)+1がリセットされます。ビジネスの主キーの競合などが発生します。見つけにくい問題

  • この問題の理由は、MySQL 5.7では、自己インクリメントする主キーの割り当てルールが、メモリに保持され、ディスクに保持されないInnoDBデータディクショナリ内のカウンターによって決定されるためです。 disk)、データベースが再起動されると、カウンターが初期化され、この時点での初期化の結果は次のようになります。auto_increment = max(primary key)+1

MySQL 8.0では、自己インクリメント主キーのカウンターがREDOログに保持されます。カウンターが変更されるたびに、REDOログに書き込まれます。この時点でデータベースを再起動すると、InnoDBデータディクショナリメモリカウンタの値は、REDOログの情報に従って初期化されます

  • 次に、この方法を使用してREDOログのカウンターを保持し、REDOログをディスクに保存します。このとき、電源が切れた場合(またはデータベースを再起動した後)でも、REDOログは私たちを記憶します。最後の自己インクリメント値、今回はMySQL5.7で問題はありません
ここでは、例を使用して、永続化されない前(つまり、MySQL 8.0の前)と自己増加変数が永続化された後(つまり、MySQL 8.0の起動後)の自己増加変数の違いを示します。
  1. まず、MySQL5.7の状況を分析しましょう
    • つまり、自己インクリメント変数の永続化はまだ実行されていません。
CREATE TABLE test9(
id INT PRIMARY KEY AUTO_INCREMENT
);
  • ここでは、最初にデータテーブルを作成し、このデータテーブルに自動インクリメント列を設定します
INSERT INTO test9
VALUES (0),(0),(0),(0);
  • この時点で、test9テーブルに4つのレコードを追加しました。この時点で0を追加すると、自動インクリメント列に0またはnullを追加できず、テーブルに4つの追加レコードが追加されないため、実際にはデフォルトの割り当てになります。現時点では、idフィールドの値は次のとおりです:1、2、3、4
DELETE FROM test9
WHERE id = 4;
  • このとき、テーブル内のID4のフィールドを削除します
INSERT INTO test9
VALUES(0);
  • このとき、引き続きtest9テーブルにレコードを追加します。この時点で追加するレコードのIDはどのようになりますか?—この時点で、レコードを削除したため、結果は5であることがわかります。前のテーブルのid4。、現時点では、次の自動インクリメントのテーブルにid 4のフィールドがない場合でも、今回は4を追加せず、5を追加します。実際、これは時間、自動インクリメントの主キーauto_incrementの値がmax(primary key)+1より大きい
DELETE FROM test9
WHERE id = 5;
  • このとき、テーブル内のID5のレコードを削除します。
このステップは重要です:

このとき、データベースを再起動する必要があります

  • では、データベースを再起動するにはどうすればよいでしょうか。
    1. データベースを閉じるには、cmd(コマンドプロンプト)で「netstopdatabase」コマンドを使用する必要があります
      • 注:ここでのデータベースは特定のデータベース名ではなく、バックグラウンドで開始したデータベースの名前です。開いたバックグラウンドに移動して、この名前を照会できます(コンピューターから右クリックして管理を入力し、次に、管理でサービスとアプリケーションを検索し、サービスをクリックして、リストからデータベースの名前を検索します(注:データベースが既に開始されていることが前提です)。
    2. 次に、「netstartdatabase」コマンドを使用してデータベースを起動します
INSERT INTO test9
VALUES(0);
  • 次に、データベースを再起動した後、test9テーブルにレコードを追加し、実際にはデフォルトの追加方法である0のIDを追加します。この時点で追加されるIDは6になりますか? 4と5が削除されているので、6と考えてください)

    • ただし、現時点では、実行後、ここでの実行結果に追加されたレコードのid値は次のようになります。4
    • これは、データベースを再起動するとデータベースメモリ内のデータが消えるためです。今回はMySQL 5.7です。このとき、自己インクリメント主キーのカウンタはメモリ内に保持されます。このとき、メモリが消えた場合、つまり、カウンタを再初期化する必要があります。このとき、カウンタの初期化では、自動インクリメントの主キーauto_incrementをmax(primary key)+1に設定します。つまり、テーブル内の最大id+1まで値を自動インクリメントします

ただし、上記のすべての操作をMySQL 8.0で実行すると、現時点では結果が異なります。

MySQL 8.0で同じ操作を行った場合、前のすべての手順の実行結果は同じですが、データを追加する最後の操作(つまり、データベースを再起動した後の操作)では、実行結果が異なります。 --MySQL 8.0の場合、データを追加する最後の操作の後、テーブル内のデータをクエリして、追加したデータのIDが6であることを確認します。なぜ、現時点では6なのですか?

  • MySQL 8.0では自己インクリメント列の永続化機能があるため、MySQL 8.0では、REDOログに各自己増分列カウンターの変更を記録するREDOログを追加し、REDOログはディスクに永続化されます。したがって、データベースを再起動しても、REDOログのデータは消えません。データベースを再起動すると、自己インクリメントの主キーカウンターがREDOログを介して初期化され、ここに追加されたレコードのIDは次のようになります。 6、ID4および5のレコードが削除されたため。

おすすめ

転載: blog.csdn.net/m0_57001006/article/details/123625810