MySQLデータ損失のトラブルシューティング事例

MySQLデータ損失のトラブルシューティング事例

序文

最近、友人が突然WeChatで連絡してきて、MySQLでデータ損失が発生したと教えてくれました。間違いなく、DBAにとって、これは間違いなく最もストレスの多いことです。その知らせを聞いて、私はすぐに問題のトラブルシューティングを始めました。

現地調査

最初にこのニュースを聞いたとき、もちろんとても緊張しましたが、すぐに落ち着いて調査を始めました。

(1)インスタンスの状態は正常ですか? --確認後、インスタンスの状態は正常です

(2)ビジネスライブラリはどれですか?それはまだ存在しますか?削除されましたか? --事業在庫は

(3)エラーを報告する際にビジネス部門はどのテーブルにアクセスしましたか?テーブルは存在しますか?削除されましたか? --確認後、ビジネステーブルが存在する

(4)アプリケーションユーザーの権限は正常ですか? --アプリケーションユーザーがビジネスライブラリのすべての権限を持っていることが確認されました

(5)ビジネスアクセス中にどのようなエラーメッセージが報告されますか? --確認後、ビジネス側は特定のページにアクセスする際にエラーを報告します

(6)この時点での調査では、一方ではアプリケーションに異常があるのではないかと疑い、他方では一部のレコードが失われているのではないかと疑います。開発側と運用保守側が同時に調査しています。ここで運用保守側が調査するアイデアは、業務テーブルに主キーがあるかどうかです。ビジネス側のアクセス エラーとビジネス テーブルの対応関係は何ですか?対応するレコードを見つけることができますか?

(7)さらに分析すると、業務テーブルに主キーがあり、開発側もクエリレコードを提供していることが判明しました。確認したところ、レコードは存在しており、誤って削除されたわけではありませんでした。開発側がアプリケーションを確認したところ、ログにはエラー情報が明確に出力されていませんでした。

(8)この場合、その夜に何か変更やリリースがあったかどうかしか尋ねられないのでしょうか? --その夜にいくつかのテーブルDDLの変更が行われたことが確認されました

調査を続けると、その夜の DDL 変更にはビジネス テーブルの操作が関係していることがわかりました。変更は、フィールドの長さを変更するもので、alter table xxx modify column xxx char(x) に似ています。この時点で、問題について考え始めました。次に、sql_mode 構成を確認し、対応する完全な行レコードをクエリして開発者に確認し始めました。最終的に、DDL 変更によってフィールドが切り捨てられたことを確認しました。最終的には、バックアップによってのみ復元でき、問題はようやく解決しました。

ケースの再現

先ほどのトラブルシューティングのプロセスを読んだ後、フィールドの長さを変更するとデータが切り捨てられるのはなぜかという疑問が多くの方に生じると思います。 MySQL はデータ検証を行わないのですか?引き続き下を見ていきましょう。

(1)シナリオ1

mysql> sbtest2 から * を選択し、制限 1 を設定します。
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
| id | k | c | パッド |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
| 1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
セット内の 1 行 (0.00 秒)

mysql> alter table sbtest2 列 pad char(1) を変更します。
エラー 1265 (01000): 行 1 の列 'pad' のデータが切り捨てられました

mysql> sbtest2 から * を選択し、制限 1 を設定します。
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
| id | k | c | パッド |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
| 1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
セット内の 1 行 (0.00 秒)

(2)シナリオ2

mysql> sbtest2 から * を選択し、制限 1 を設定します。
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
| id | k | c | パッド |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
| 1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------+
セット内の 1 行 (0.00 秒)

mysql> alter table sbtest2 列 pad char(1); クエリは正常、100 行が影響を受け、100 個の警告 (0.06 秒)
レコード: 100 重複: 0 警告: 100

mysql> sbtest2 から * を選択し、制限 1 を設定します。
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+------+
| id | k | c | パッド |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+------+
| 1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 6 |
+----+---------+------------------------------------------------------------------------------------------------------------------------------------------------------+------+
セット内の 1 行 (0.00 秒)

シナリオ 1 は私たちの予想に沿うもので、「データが切り捨てられました」というエラーが直接報告されます。シナリオ 2 は正常に実行され、「部分的なデータ損失」が発生します。では、MySQL はデータ検証を実行しないのでしょうか?実際、MySQL にはデータ検証機能があります。しかし、シナリオ 2 では、sql_mode 構成の問題と STRICT_TRANS_TABLES の設定の失敗により、MySQL は操作の実行を阻止できず、「データ損失」という悲劇が発生しました。

要約する

この時点で、「データ損失」の悲劇は終わりを迎えます。根本的な原因は、sql_mode が STRICT_TRANS_TABLES を設定していないことです。このケースは、sql_mode が非常に重要な構成であり、軽々しく設定または変更してはならないことも思い出させます。sql_mode の詳細については、次の記事で説明します。

上記は、MySQL データ損失のトラブルシューティング事例の詳細です。MySQL データ損失のトラブルシューティングの詳細については、123WORDPRESS.COM の他の関連記事に注意してください。

以下もご興味があるかもしれません:
  • dockerがredisを再起動するとmysqlデータが失われる問題を解決する
  • MySQL で置換操作を使用したときにデータ損失が発生する問題の解決策
  • サーバーがダウンしたときにMySQLデータの損失を防ぐためのいくつかのソリューション
  • MySQLデータ損失の原因と解決策

<<:  Docker で Elasticsearch Kibana と ik Word Segender をデプロイする詳細な説明

>>:  Webデザインチュートリアル(6):デザインへの情熱を持ち続ける

推薦する

画像をラベルとして使用すると、IE では for 属性が機能しません。

例えば:コードをコピーコードは次のとおりです。 <input type="check...

Node.js コンソールで強調表示されたコードを印刷する方法

序文コードを実行してエラーが発生すると、エラーが出力されます。エラーにはスタック情報が含まれており、...

Docker クリーニングキラー/Docker オーバーレイ ファイルがディスク領域を大量に占有する

[インターネット上の移行ファイルをすべて見ると、信頼性が低く、症状のみを治療し、根本的な原因を治療し...

MySQLデータベース入門:データベースバックアップ操作の詳細な説明

目次1. 単一データベースのバックアップ2. 圧縮バックアップ3. マルチデータベースバックアップ4...

Docker コンテナのネットワーク障害に対する 6 つの解決策

Docker コンテナのネットワーク障害に対する 6 つの解決策注: 以下の方法は、コンテナ内のパブ...

MySql クイック挿入数千万の大規模データの例

データ分析の分野では、データベースは私たちの強力な助けとなります。クエリ時間を受け入れるだけでなく、...

MySQLはbinlogを通じてデータを復元する

目次MySQL ログファイルバイナリログBinlogログがオンになっていますログ記録を有効にする方法...

ウェブデザインにおける2種類のタブアプリケーション

現在、Web デザインではタブが広く使用されていますが、一般的に次の 2 つのタイプに分けられます。...

フックを使用して React コンポーネントを書くときに注意すべき 5 つの点

目次01. レンダリングが不要な場合はuseStateを使用する02. リンクの代わりにrouter...

Mysqlはフィールドスプライシングのための3つの関数を実装している

データをオペレーションにエクスポートする場合、フィールドの結合は避けられません。MySQL でこれが...

AWSサーバーリソースを無料で使用する方法を教えます

AWS - Amazon のクラウド コンピューティング サービス プラットフォーム以前、AWS の...

MySQL 継続的集計の原理と使用法の分析

この記事では、例を使用して、MySQL の継続的な集計の原理と使用方法を説明します。ご参考までに、詳...

CSSをインポートする方法は何ですか?linkと@importの違いは何ですか?選択方法

Taobao のウェブページはインポートを使用していますが、多くのウェブサイトはリンクを使用していま...

Vueのprovideとinjectの使い方と原則を分析する

まず、provide/inject を使用する理由について説明しましょう。祖父コンポーネントと孫コン...

JSはプログレスバーのスムーズバージョンの詳細な計画を実装します

進捗バーがスムーズではないフロントエンドを学ぶ学生のほとんどは、オーディオプレーヤーやビデオプレーヤ...