MySQL で置換操作を使用したときにデータ損失が発生する問題の解決策

MySQL で置換操作を使用したときにデータ損失が発生する問題の解決策

序文

同社の開発者は、データの更新時に replace into ステートメントを使用していました。不適切な使用により、大量のデータが失われました。この記事では、データ損失がどのように発生したかを分析します。

1. 問題の説明

同社の開発者は、データの更新時に replace into ステートメントを使用していました。不適切な使用により、大量のデータが失われました。以下は、データ損失が発生した原因の分析です。

2. 問題分析

a. REPLACE原則

REPLACE INTO 原則の公式な説明は次のとおりです。

REPLACE は INSERT とまったく同じように動作しますが、テーブル内の古い行の値が PRIMARY KEY または UNIQUE インデックスの新しい行の値と同じである場合、新しい行が挿入される前に古い行が削除される点が異なります。

新しく挿入された行の主キーまたは一意キーがテーブル内に既に存在する場合、元のレコードは削除され、新しい行が挿入されます。テーブル内に存在しない場合は、直接挿入されます。

アドレス: https://dev.mysql.com/doc/refman/5.6/en/replace.html

b. 問題の症状

欠損データのテーブル構造は次のとおりです。

テーブル `active_items` を作成します (

実行される置換ステートメントは次のとおりです (複数)。

active_items(ad_id,score) VALUES('XXXXXXX', 1800) に置き換えます。

binlog をクエリして実行記録を検索すると、次のような結果が表示されます。

### `items`.`active_items` を更新します
### @21=0 /* TINYINT meta=0 nullable=0 is_null=0 */

操作対象のad_idは既に存在するため、一旦削除してから挿入します。指定したad_idとスコア以外はデフォルト値に変更され、元のデータが失われていることがわかります(ログでは更新に変換されていますが)

c. 比較テスト

次に、以下のテストを実施しました。

  • MySQL 置換操作中のデータ損失
  • 左側では REPLACE ステートメントを使用し、右側では DELETE + INSERT ステートメントを使用します。最終結果はまったく同じです。
  • 元の主キーIDが1の行は削除され、新しく挿入された行の主キーIDは4に更新され、フィールドcには指定された内容なしでデフォルト値が挿入されます。
  • REPLACE を使用してデータ行が更新され、MySQL は影響を受ける行の数が 2 行であると表示しました。

要約すると、行が削除され、行が挿入されることを意味します。

3. データ復旧

データの損失またはデータ エラーが発生した場合、回復する方法はいくつかあります。

  1. ビジネス側は回復のための独自のスクリプトを作成する
  2. MySQL binlog を使用して不正な SQL を見つけ出し、データ回復用の逆 SQL を生成します (SQL データ量が小さい場合に適しています)
  3. 履歴バックアップファイルと増分バイナリログを使用して、誤った操作が発生する前の時点にデータの状態を復元します。

4. 問題の拡張

上記の分析から、REPLACE は古い行を削除して新しい行を挿入しますが、binlog はそれを更新の形式で記録するため、別の問題が発生することがわかります。

スレーブデータベースの自己成長値はマスターデータベースの自己成長値よりも小さい

1. テスト

a. マスタースレーブ一貫性:

メインライブラリ:

mysql> テーブル tG の作成を表示

ライブラリから:

mysql> テーブル tG の作成を表示

b. メインライブラリの置換:

メインライブラリ:

mysql> t (a,b)values(1,7) に置き換えます。

ライブラリから:

mysql> テーブル tG の作成を表示

マスターテーブルとスレーブテーブルの AUTO_INCREMENT 値が異なっていることに注意してください。

c. スレーブからマスターへのアップグレードをシミュレートし、スレーブ データベースで INSERT を実行します。

mysql> t に (a,b,c) 値 (4,4,4) を挿入します。

データベースから挿入する場合、エラーが報告され、主キーが重複します。エラーが報告された後、AUTO_INCREMENT が +1 されるため、再度実行すれば挿入が成功します。

2. 結論

この問題は通常の状況では影響はありませんが、

マスター データベースが定期的に大量の REPLACE ステートメントを使用し、スレーブ データベースの AUTO_INCREMENT 値がマスター データベースより大幅に遅れている場合、マスターとスレーブの切り替えが発生すると、データが再度挿入されるときに新しいマスター データベースに多数の主キー重複エラーが発生し、データの挿入が失敗します。

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。

以下もご興味があるかもしれません:
  • dockerがredisを再起動するとmysqlデータが失われる問題を解決する
  • サーバーがダウンしたときにMySQLデータの損失を防ぐためのいくつかのソリューション
  • MySQLデータ損失の原因と解決策
  • MySQLデータ損失のトラブルシューティング事例

<<:  Vueプラグインの実装で発生した問題の概要

>>:  Windows Server 2019 のセットアップ方法 (画像とテキスト付き)

推薦する

Zabbix 監視 Docker アプリケーション構成

コンテナの応用はますます一般的になっていますが、大量のコンテナをどのように管理すればよいのでしょうか...

MySQLにログインする際のエラー「ERROR 1045 (28000)」を解決する方法

今日はサーバーにログインして、データベース内のいくつかのものを変更する準備をしました。しかし、パスワ...

wgetはウェブサイト全体(サブディレクトリ全体)または特定のディレクトリをダウンロードします

wgetコマンドを使用して、親ディレクトリの下のサブディレクトリ全体をダウンロードします。親ディレク...

Linuxはsttyを使用して端末の回線設定を表示および変更します。

Sttty は、Linux で端末設定を変更および印刷するための一般的なコマンドです。 1. パラ...

Windows での MySQL コミュニティ サーバー 8.0.16 のインストールと構成方法のグラフィック チュートリアル

最近、MySQL関連の構文をよく見かけます。また、MySQLストアドプロシージャの書き方も学びたいの...

Vueは書籍ショッピングカートの機能を実現

この記事の例では、書籍ショッピングカート機能を実現するためのVueの具体的なコードを参考までに共有し...

VUEトークンの無効化プロセスの詳細な説明

目次ターゲット思考分析コード着陸要約するターゲットトークンの有効期限切れシナリオの処理トークンは、ユ...

MySQL 学習ノート ヘルプ ドキュメント

システムヘルプを表示help contents mysql> ヘルプコンテンツ; ヘルプ カテ...

検証例 MySQL | 同じ値を持つフィールドを更新すると、binlog に記録されます

1. はじめに数日前、開発仲間から、フィールドを同じ値に更新すると binlog が記録されるかどう...

Excel エクスポートは docker 環境では常に失敗する

Excel のエクスポートは、docker 環境では常に失敗します。最も直接的な原因は、中国語フォン...

ドロップダウンメニューを実装するためのネイティブ js

ドロップダウン メニューも実生活では非常に一般的です。実装に使用される js コードは、タブ選択やア...

Docker で ElasticSearch をデプロイする方法

1. ElasticSearch とは何ですか? Elasticsearch も Java で開発さ...

Vue で lodop 印刷コントロールを使用してブラウザ互換の印刷を実現する方法

序文このコントロールを直接印刷すると下部に透かしが入りますが、公式 Web サイトから購入することで...

MySQL 8.0.16 winx64 のインストールと設定方法のグラフィックチュートリアル

最近、データベースについて学び始めました。最初にやったことは、データベースとは何か、データベースとデ...

Vue はシームレスなカルーセル効果 (マーキー) を実現します

この記事では、シームレスなカルーセル効果を実現するためのVueの具体的なコードを例として紹介します。...