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):デザインへの情熱を持ち続ける

推薦する

vue-element-admin プロジェクトのインポートとエクスポートの実装

vue-element-admin インポートコンポーネントのカプセル化テンプレートとスタイルまず、...

MySQLでストアドプロシージャをデバッグする最も簡単な方法

同僚から、一時テーブルを使用して変数データを挿入して表示する方法を教わったことがありますが、この方法...

Vue要素のバックグラウンド認証プロセスの分析

序文:最近、プロジェクトで管理システムに遭遇しました。権限設定が非常に興味深いと思いました。自分の学...

Linux システムでログを手動でスクロールする方法

ログローテーションは、Linux システムでは非常に一般的な機能です。ログローテーションは、システム...

MySQL の簡単な分析 - MVCC

バージョンチェーンInnoDB エンジン テーブルでは、クラスター化インデックス レコードに 2 つ...

RedisとMySQLの違いを簡単に説明してください

MySQL はディスクに保存される永続的なストレージであり、取得には一定の IO が伴うことはご存じ...

CSS ロリポップを描くサンプルコード

背景: 毎日少しずつ進歩し、少しずつ積み重ねていけば、どんどん良くなっていきますコード: <!...

Docker-compose チュートリアルのインストールとクイックスタート

目次1. Compose の紹介2. ComposeとDockerの互換性3. Dockerをインス...

MySQLデッドロックの原因と解決策

データベースは、オペレーティング システムと同様に、複数のユーザーが使用する共有リソースです。複数の...

mysql8.0 でユーザーを作成して権限を付与する際のエラーの解決方法の詳細な説明

質問1:エラーを報告する書き込み方法: GRANT OPTION を使用して、'123123...

HTML ページジャンプのパラメータ渡しの問題

効果は以下のとおりです。ページジャンプボタンをクリックした後 対応する値はページ b で取得できます...

jsはシンプルなカウントダウンを実装します

この記事の例では、参考までに簡単なカウントダウンを実装するためのjsの具体的なコードを共有しています...

MySQLクエリ結果をCSVにエクスポートする方法

MySQL クエリ結果をcsvにエクスポートするには、通常、php を使用して mysql に接続し...

CSS を使用して 3 つのステップでショッピング モールのカード クーポンを作成する

今日は618日、主要なショッピングモールはすべてプロモーション活動を行っています。今日は、次のように...

ウェブページのグリッドデザインを考える

<br />元のアドレス: http://andymao.com/andy/post/8...