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

推薦する

MySQL のクエリパフォーマンスに対する制限の影響

I. はじめにまず、MySQL のバージョンについて説明します。 mysql> バージョンを選...

Dockerコンテナの操作手順の概要と詳細説明

1. コンテナを作成して実行するdocker run -it --rm centos:latest ...

ウェブフロントエンドエンジニアにおすすめのヒント

まず、Webフロントエンドエンジニアの価値についてお話ししましょう。現在、Web製品のインタラクショ...

フロントエンドの状態管理(パート2)

目次1. 再出発1.1. ストア(司書) 1.2. 状態(書籍) 1.3. アクション(図書貸出リス...

画像ボタンをフォームのリセットボタンとして使用する方法

フォームを作成するときに、送信ボタンとリセットボタンを配置することがよくあります。ページの外観を考慮...

CentOS に Redis と MySQL をインストールする

1|0MySQL(MariaDB) 1|11. 説明MariaDB データベース管理システムは My...

CSS 命名: BEM、スコープ付き CSS、CSS モジュール、CSS-in-JS の説明

CSS の適用範囲はグローバルです。プロジェクトがどんどん大きくなり、参加する人が増えるにつれて、命...

ファイルのアップロードの進行状況を示す React の例

目次React アップロードファイル表示の進行状況デモフロントエンドにReactアプリケーションを素...

このポイントのJavaScriptの基本

目次これ方法オブジェクト内これを隠した厳密モード要約するJavaScript の this も不思議...

エコー後に要素編集フォームel-radioが選択できない問題を解決します

目次序文質問オンラインソリューション序文この記事の内容は私がこの業界に入ったときのメモを元にしている...

Dockerコンテナのエクスポートとインポートの例

目次DockerコンテナのエクスポートDockerコンテナのインポ​​ートこの記事では主に、コンテナ...

Vue3 を使用してポップアップ コンポーネントをカプセル化するのは簡単ですか?

目次最初に要約: 🌲🌲 序文: 🍬🍬公開🍬🍬 🍬🍬グローバル🍬🍬 🍬🍬ボールボックス🍬🍬 🎉🎉🎉結論...

Mysql のフィールドのデータの一部をバッチ置換する (推奨)

MYSQL のフィールドのデータの一部をバッチで置き換えます。具体的な導入は次のとおりです。 1....

Centos8でdockerがインストールできない問題の解決方法

問題 [root@zh ~]# [root@zh ~]# [root@zh ~]# yum -y d...

JS 継承の詳細

目次序文準備する要約する継承方法プロトタイプ継承プロトタイプチェーン継承コンストラクタの借用(クラス...