オンライン MYSQL 同期エラーのトラブルシューティング方法の概要 (必読)

オンライン MYSQL 同期エラーのトラブルシューティング方法の概要 (必読)

序文

フェイルオーバーが発生した後、よくある問題は同期エラーです。データベースが小さい場合は、ダンプしてからインポートすることで簡単に処理できます。ただし、オンラインデータベースは150G〜200Gです。この方法だけを使用すると、コストが高すぎます。そのため、調査期間を経て、いくつかの処理方法がまとめられました。

実稼働環境のアーキテクチャ図

現在のネットワーク アーキテクチャでは、データのコピーが 2 つ保存され、非同期レプリケーションを使用して高可用性クラスターが作成され、2 台のマシンが外部サービスを提供します。障害が発生した場合は、スレーブに切り替えてマスターに変えます。故障したマシンは新しいマスターと逆方向に同期します。障害を処理する際に最もよく発生する問題は、マスター スレーブ エラーです。以下は私が収集したエラーメッセージです。

よくある間違い

最も一般的な3つの状況

これら 3 つの状況は、HA 切り替え中に発生します。非同期レプリケーションと sync_binlog=0 により、binlog の一部が受信されず、同期エラーが発生します。

1 つ目は、マスターでレコードが削除されたが、スレーブで見つからないというものです。

Last_SQL_Error: テーブル hcy.t1 で Delete_rows イベントを実行できませんでした。
't1' にレコードが見つかりません。
Error_code: 1032; ハンドラー エラー HA_ERR_KEY_NOT_FOUND;
イベントのマスターログ mysql-bin.000006、end_log_pos 254

2 番目のタイプ: 重複する主キー。レコードはスレーブにすでに存在し、同じレコードがマスターに挿入されます。

Last_SQL_Error: テーブル hcy.t1 で Write_rows イベントを実行できませんでした。
キー「PRIMARY」の重複エントリ「2」
エラーコード: 1062;
ハンドラエラー HA_ERR_FOUND_DUPP_KEY; イベントのマスターログ mysql-bin.000006、end_log_pos 924

3 番目のタイプ: マスターでレコードが更新されましたが、スレーブで見つからないため、データが失われます。

Last_SQL_Error: テーブル hcy.t1 で Update_rows イベントを実行できませんでした。
't1' にレコードが見つかりません。
エラーコード: 1032;
ハンドラエラー HA_ERR_KEY_NOT_FOUND; イベントのマスターログ mysql-bin.000010、end_log_pos 263

非同期半同期の違い

非同期レプリケーション<br /> 簡単に言うと、マスターがバイナリログを送信し、スレーブがそれを受信または実行したかどうかに関係なくアクションが終了します。

半同期レプリケーション<br /> 簡単に言うと、マスターがバイナリログを送信し、スレーブがそれを受信したことを確認します。実行されたかどうかに関係なく、マスターはそれを受信したという信号を送信し、アクションが完了します。 (コードは Google によって書かれ、5.5 で正式に適用されました。)

非同期のデメリット<br /> マスターが書き込み操作でビジー状態の場合、現在の POS ポイントは、たとえば 10 で、スレーブの IO_THREAD スレッドは 3 を受け取ります。このとき、マスターがクラッシュし、7 ポイントの差がスレーブに送信されず、データが失われます。

特別な事情

スレーブのリレー ログ relay-bin が破損しています。
Last_SQL_Error: リレー ログ位置の初期化エラー: バイナリ ログからヘッダーを読み取るときに I/O エラーが発生しています
Last_SQL_Error: リレー ログ位置の初期化エラー: Binlog に不正なマジック番号があります。
このバージョンのMySQLで使用できるバイナリログファイルではありません

この場合、SLAVE が停電やマザーボードの焼損などによりダウンまたは不法にシャットダウンされ、リレー ログが破損し、同期が停止します。

人為的ミスに注意してください: 複数のスレーブに重複したサーバー ID があります
この場合、同期は遅延され、完了しません。上記の 2 行の情報が常にエラー ログに表示されます。解決策は、サーバー ID を不整合になるように変更することです。

スレーブ: サーバーから終了パケットを受信しました。マスターがシャットダウンしたようです。
スレーブ I/O スレッド: ログ イベントの読み取りに失敗しました。再試行のために再接続しています。位置 106 に 'mysql-bin.000012' がログに記録されています。

問題解決

削除に失敗しました

マスター上のレコードを削除しましたが、スレーブ上で見つかりません。

Last_SQL_Error: テーブル hcy.t1 で Delete_rows イベントを実行できませんでした。
't1' にレコードが見つかりません。
Error_code: 1032; ハンドラー エラー HA_ERR_KEY_NOT_FOUND;
イベントのマスターログ mysql-bin.000006、end_log_pos 254

解決:

マスターはレコードを削除したいが、スレーブはそれを見つけられずエラーを報告します。この場合、マスターはレコードを削除したので、スレーブはそれを直接スキップできます。使用可能なコマンド:

奴隷を停止します。
グローバル sql_slave_skip_counter を 1 に設定します。
スレーブを起動します。

これが頻繁に発生する場合は、私が作成したスクリプト skip_error_replcation.sh を使用できます。このスクリプトは、デフォルトで 10 個のエラーをスキップします (この状況のみをスキップし、他の状況ではエラー結果を出力して処理を待機します)。このスクリプトは、maakit ツールキットの mk-slave-restart 原則を参照してシェルで作成されています。独自の関数をいくつか定義し、すべてのエラーをスキップするわけではありません。 )

重複した主キー

レコードはスレーブにすでに存在し、同じレコードがマスターに挿入されます。

Last_SQL_Error: テーブル hcy.t1 で Write_rows イベントを実行できませんでした。 
キー「PRIMARY」の重複エントリ「2」 
エラーコード: 1062; 
ハンドラエラー HA_ERR_FOUND_DUPP_KEY; イベントのマスターログ mysql-bin.000006、end_log_pos 924

解決:

スレーブで desc hcy.t1 を使用します。まず、次のテーブル構造を確認します。

mysql> desc hcy.t1;
+-------+---------+------+------+--------+-------+
| フィールド | タイプ | Null | キー | デフォルト | 追加 |
+-------+---------+------+------+--------+-------+
| id | int(11) | NO | PRI | 0 | | 
| 名前 | char(4) | はい | | NULL | | 
+-------+---------+------+------+--------+-------+

重複した主キーを削除する

mysql> t1 から id=2 を削除します。
クエリは正常、1 行が影響を受けました (0.00 秒)

mysql> スレーブを起動します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql> スレーブステータスを表示します\G;
…
スレーブIO実行中: はい
スレーブSQL実行中: はい
…
mysql> t1 から * を選択します。ここで、id=2 です。

マスターとスレーブで再度確認してください。

更新が失われました

マスター上でレコードが更新されましたが、スレーブ上で見つからないため、データが失われます。

Last_SQL_Error: テーブル hcy.t1 で Update_rows イベントを実行できませんでした。 
't1' にレコードが見つかりません。 
エラーコード: 1032; 
ハンドラ エラー HA_ERR_KEY_NOT_FOUND; 
イベントのマスターログ mysql-bin.000010、end_log_pos 794

解決:

マスター上で、mysqlbinlog を使用して、間違った binlog ログが何を実行しているかを分析します。

/usr/local/mysql/bin/mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS mysql-bin.000010 | grep -A '10' 794

#120302 12:08:36 サーバー ID 22 end_log_pos 794 Update_rows: テーブル ID 33 フラグ: STMT_END_F
### hcy.t1 を更新
###どこ
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### @2='bbc' /* STRING(4) meta=65028 nullable=1 is_null=0 */
### セット
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### @2='BTV' /* STRING(4) meta=65028 nullable=1 is_null=0 */
# 794 で
#120302 12:08:36 サーバー ID 22 end_log_pos 821 Xid = 60
専念 /*!*/;
区切り文字 ;
# ログファイルの終了
ROLLBACK /* mysqlbinlog によって追加されました */;
/*!50003 COMPLETION_TYPE を @OLD_COMPLETION_TYPE に設定*/;

スレーブ上で、存在しないはずの更新されたレコードを見つけます。

mysql> t1 から * を選択します。ここで、id=2 です。
空のセット (0.00 秒)

それからマスターに行って確認する

mysql> t1 から * を選択します。ここで、id=2 です。
+----+------+
| ID | 名前 |
+----+------+
| 2 | テレビ 
+----+------+
セット内の 1 行 (0.00 秒)

スレーブ上で不足しているデータを入力し、エラーをスキップします。

mysql> t1 値に挿入します (2、'BTV');
クエリは正常、1 行が影響を受けました (0.00 秒)

mysql> t1 から * を選択します。ここで、id=2 です。  
+----+------+
| ID | 名前 |
+----+------+
| 2 | テレビ 
+----+------+
セット内の 1 行 (0.00 秒)

mysql> スレーブを停止します。グローバル sql_slave_skip_counter を 1 に設定します。スレーブを起動します。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)
クエリは正常、影響を受けた行は 0 行 (0.00 秒)
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql> スレーブステータスを表示します\G;
…
 スレーブIO実行中: はい
 スレーブSQL実行中: はい
…

リレーログの破損

スレーブのリレー ログ relay-bin が破損しています。

Last_SQL_Error: リレー ログ位置の初期化エラー: バイナリ ログからヘッダーを読み取るときに I/O エラーが発生しています
Last_SQL_Error: リレー ログ位置の初期化エラー: Binlog に不正なマジック番号があります。 
このバージョンのMySQLで使用できるバイナリログファイルではありません

手動修復

解決策:同期された binlog と POS ポイントを見つけて、それらを再同期し、新しいリレー日の値を取得します。

例:

mysql> スレーブステータスを表示します\G;
************************** 1. 行 ****************************
       マスターログファイル:mysql-bin.000010
     読み取りマスターログ位置: 1191
        リレーログファイル: vm02-relay-bin.000005
        リレーログ位置: 253
    リレーマスターログファイル: mysql-bin.000010
       スレーブIO実行中: はい
      スレーブSQL実行中: いいえ
       レプリケート_Do_DB: 
     レプリケート_無視_DB: 
      テーブルの複製: 
    無視テーブルを複製: 
   Replicate_Wild_Do_Table: 
 Replicate_Wild_Ignore_Table: 
          最終エラー番号: 1593
          Last_Error: リレー ログ位置の初期化エラー: バイナリ ログからヘッダーを読み取るときに I/O エラーが発生しています
         スキップカウンタ: 1
     実行マスターログポジション: 821

Slave_IO_Running: マスターからバイナリログ情報を受信する

マスターログファイル
マスターログ位置の読み取り

Slave_SQL_Running: 書き込み操作を実行

リレーマスターログファイル
実行マスターログポジション

バイナリログと POS 実行ポイントが優先されます。

リレーマスターログファイル: mysql-bin.000010
実行マスターログポジション: 821
mysql> スレーブを停止します。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql> MASTERをMASTER_LOG_FILE='mysql-bin.000010'、MASTER_LOG_POS=821に変更します。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql> スレーブを起動します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)


mysql> スレーブステータスを表示します\G;
************************** 1. 行 ****************************
        Slave_IO_State: マスターがイベントを送信するのを待機中
         マスターホスト: 192.168.8.22
         マスターユーザー: repl
         マスターポート: 3306
        接続再試行: 10
       マスターログファイル:mysql-bin.000010
     読み取りマスターログ位置: 1191
        リレーログファイル: vm02-relay-bin.000002
        リレーログ位置: 623
    リレーマスターログファイル: mysql-bin.000010
       スレーブIO実行中: はい
      スレーブSQL実行中: はい
       レプリケート_Do_DB: 
     レプリケート_無視_DB: 
      テーブルの複製: 
    無視テーブルを複製: 
   Replicate_Wild_Do_Table: 
 Replicate_Wild_Ignore_Table: 
          最終エラー番号: 0
          最終エラー: 
         スキップカウンタ: 0
     実行マスターログポジション: 1191
       リレーログスペース: 778
       Until_Condition: なし
        ログファイルまで: 
        ログ位置まで: 0
      マスターSSL許可: いいえ
      マスターSSLCAファイル: 
      マスターSSLCAパス: 
       マスターSSL証明書: 
      マスターSSL暗号: 
        マスターSSLキー: 
    マスターより遅れている秒数: 0
Master_SSL_Verify_Server_Cert: いいえ
        最終IOエラー番号: 0
        最後のIOエラー: 
        最終SQLエラー番号: 0
        最後のSQLエラー: 
Ibバックアップ

あらゆるトリックを使用しましたが、スレーブ データが失われすぎています。ibbackup (有料) を使用する時期です。

Ibbackup ホット バックアップ ツールは有料です。 Xtrabackup は無料で、同じ機能を備えています。

Ibbackup はバックアップ中にテーブルをロックしません。バックアップ中にトランザクションが開始され (スナップショットの作成に相当)、ポイントが記録されます。その後のデータ変更は ibbackup_logfile ファイルに保存されます。リカバリ中に、ibbackup_logfile 内の変更されたデータが ibdata に書き戻されます。

Ibbackup はデータ (ibdata、.ibd) のみをバックアップし、テーブル構造 .frm はバックアップしません。

以下にデモンストレーションの例を示します。

バックアップ: ibbackup /bak/etc/my_local.cnf /bak/etc/my_bak.cnf

復元: ibbackup --apply-log /bak/etc/my_bak.cnf

[root@vm01 など]# my_local.cnf の詳細 

データディレクトリ = /usr/local/mysql/data
innodb_data_home_dir = /usr/local/mysql/data
innodb_data_file_path = ibdata1:10M:自動拡張
innodb_log_group_home_dir = /usr/local/mysql/data
innodb_buffer_pool_size = 100M
innodb_log_file_size = 5M
innodb_log_files_in_group=2


[root@vm01 など]# ibbackup /bak/etc/my_local.cnf /bak/etc/my_bak.cnf 

InnoDB Hot Backup バージョン 3.0.0; Copyright 2002-2005 Innobase Oy
ライセンス A21488 は vm01 ([email protected]) に付与されます
(--apply-log はホスト名に関係なくどのコンピュータでも動作します)
ホスト名が「vm01」のコンピュータで使用するためにライセンスされています
2012-5-1 (年-月-日) 00:00 に期限切れ
詳細については、http://www.innodb.com を参照してください。
詳細なライセンス条項についてはibbackup --licenseと入力し、ヘルプについては--helpと入力してください。

/bak/etc/my_local.cnf の内容:
innodb_data_home_dir の値は /usr/local/mysql/data です
innodb_data_file_path の値が ibdata1:10M:autoextend になりました
datadir の値は /usr/local/mysql/data です
innodb_log_group_home_dir の値は /usr/local/mysql/data です
innodb_log_files_in_group の値は 2 です
innodb_log_file_size の値は 5242880 です

/bak/etc/my_bak.cnf の内容:
innodb_data_home_dir の値は /bak/data です
innodb_data_file_path の値が ibdata1:10M:autoextend になりました

datadir の値は /bak/data です
innodb_log_group_home_dir の値は /bak/data です
innodb_log_files_in_group の値は 2 です
innodb_log_file_size の値は 5242880 です

ibbackup: lsn 0 1636898 にチェックポイントが見つかりました
ibbackup: lsn 0 1636864 からログスキャンを開始しています
120302 16:47:43 ibbackup: ログをコピーしています...
120302 16:47:43 ibbackup: ログがコピーされました、lsn 0 1636898
ibbackup: データ ファイルのコピーを開始する前に 1 秒待機します...
120302 16:47:44 ibbackup: /usr/local/mysql/data/ibdata1 をコピーしています
ibbackup: コピーされたデータベース ページが 0 1636898 で変更されました
ibbackup: lsn 0 1636898 までのログをスキャンしました
ibbackup: lsn 0 1636898 までのログを解析できました
ibbackup: ログレコードの最大ページ番号 0
120302 16:47:46 ibbackup: 完全バックアップが完了しました!
[root@vm01 など]#
[root@vm01 など]# cd /bak/data/
[root@vm01 データ]# ls
ibbackup_logfile ibdata1

[root@vm01 データ]# ibbackup --apply-log /bak/etc/my_bak.cnf 

InnoDB Hot Backup バージョン 3.0.0; Copyright 2002-2005 Innobase Oy
ライセンス A21488 は vm01 ([email protected]) に付与されます
(--apply-log はホスト名に関係なくどのコンピュータでも動作します)
ホスト名が「vm01」のコンピュータで使用するためにライセンスされています
2012-5-1 (年-月-日) 00:00 に期限切れ
詳細については、http://www.innodb.com を参照してください。
詳細なライセンス条項についてはibbackup --licenseと入力し、ヘルプについては--helpと入力してください。

/bak/etc/my_bak.cnf の内容:
innodb_data_home_dir の値は /bak/data です
innodb_data_file_path の値が ibdata1:10M:autoextend になりました
datadir の値は /bak/data です
innodb_log_group_home_dir の値は /bak/data です
innodb_log_files_in_group の値は 2 です
innodb_log_file_size の値は 5242880 です

120302 16:48:38 ibbackup: ibbackup_logfile の作成パラメータ:
ibbackup: 開始 lsn 0 1636864、終了 lsn 0 1636898、
ibbackup: チェックポイント 0 1636898 を開始


ibbackup: チェックポイント 0 1636898 を開始
InnoDB: リカバリを実行しています: ログ シーケンス番号 0 1636898 までスキャンしました
InnoDB: データベースへのログ レコードの適用バッチを開始しています...
InnoDB: 進捗状況(パーセント): 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .....99
ログファイルのサイズを 0 5242880 に設定
ibbackup: ibbackup_logfileを解析できました
ibbackup: lsn 0 1636898
ibbackup: 最後の MySQL binlog ファイルの位置 0 1191、ファイル名 ./mysql-bin.000010
ibbackup: 最初のデータファイルは '/bak/data/ibdata1' です
ibbackup: 新しく作成されたログファイルは '/bak/data/' にあります
120302 16:48:38 ibbackup: リカバリ用の完全バックアップが正常に準備されました。

[root@vm01 データ]# ls
ibbackup_logfile ibdata1 ib_logfile0 ib_logfile1

ibdata1 ib_logfile0 ib_logfile1 をスレーブにコピーし、.frm もコピーします。MySQL を起動したら、同期します。その時点が上記の出力です。

ibbackup: 最後の MySQL binlog ファイルの位置 0 1191、ファイル名 ./mysql-bin.000010
MASTER を MASTER_LOG_FILE='mysql-bin.000010'、MASTER_LOG_POS=1191 に変更します。

Maatkit ツールキット
http://www.maatkit.org/

導入

MaatKit は、MySQL の日常的な管理を支援するオープン ソース ツールキットです。現在はPercona社が買収し、管理しています。で:

mk-table-checksum は、マスターとスレーブのテーブル構造とデータが一貫しているかどうかを確認するために使用されます。

mk-table-sync は、マスター データとスレーブ データ間の不整合を修復するために使用されます。

これら 2 つのツールキットをライブ ネットワークで実際に操作した経験はありません。これは、新しいテクノロジーと学術的な交流についての議論にすぎません。次に、その使用方法を示します。

http://www.actionsky.com/products/mysql-others/maatkit.jsp

[root@vm02]# mk-table-checksum h=vm01,u=admin,p=123456 h=vm02,u=admin,p=123456 -d hcy -t t1
Perl DBI モジュールがインストールされていないか見つからないため、MySQL に接続できません。 
Perl が DBI を検索するディレクトリを確認するには、「perl -MDBI」を実行します。
DBI がインストールされていない場合は、次を試してください。
 Debian/Ubuntu apt-get で libdbi-perl をインストールします
 RHEL/CentOS yum インストール perl-DBI
 OpenSolaris pgk インストール pkg:/SUNWpmdbi

perl-DBI モジュールが見つからないというメッセージが表示されたら、直接 yum install perl-DBI を実行します。

[root@vm02 bin]# mk-table-checksum h=vm01,u=admin,p=123456 h=vm02,u=admin,p=123456 -d hcy -t t1
データベース テーブル チャンク ホスト エンジン カウント チェックサム 時間 待機 統計 遅延
hcy t1 0 vm02 InnoDB NULL 1957752020 0 0 NULL NULL
hcy t1 0 vm01 InnoDB NULL 1957752020 0 0 NULL NULL

テーブル データに矛盾がある場合、CHECKSUM 値は不等になります。

出力の意味を説明します。

DATABASE: データベース名
TABLE: テーブル名
CHUNK: チェックサムのおおよその値
HOST: MYSQL アドレス
エンジン: テーブルエンジン
COUNT: テーブル内の行数
CHECKSUM: チェックサム値
時間: かかった時間
WAIT: 待ち時間
STAT: MASTER_POS_WAIT() の戻り値
LAG: スレーブ遅延時間

等しくないテーブルを除外したい場合は、mk-checksum-filter ツールを使用できます。最後にパイプ文字を追加するだけです。

[root@vm02 ~]# mk-table-checksum h=vm01,u=admin,p=123456 h=vm02,u=admin,p=123456 -d hcy | mk-checksum-filter    
hcy t2 0 vm01 InnoDB NULL 1957752020 0 0 NULL NULL
hcy t2 0 vm02 InnoDB NULL 1068689114 0 0 NULL NULL

どのテーブルに不整合があるかがわかれば、mk-table-sync ツールを使用してそれらを処理できます。

注意: mk-table-checksum を実行するとテーブルがロックされます。テーブルのサイズは実行速度によって異なります。

MASTERのテーブルt2データ:

SLAVE 上のテーブル t2 データ:

mysql> t2 から * を選択します。mysql> t2 から * を選択します。  
+----+------+ +----+------+
| ID | 名前 | | ID | 名前 |
+----+------+ +----+------+
| 1 | は | | 1 | は | 
| 2 | ビット | | 2 | ビット | 
| 3 | ss | | 3 | ss | 
| 4 | 初心者向け | | 4 | 初心者向け | 
| 5 | ss | +----+------+
+----+------+ セット内の 4 行 (0.00 秒)
セット内の行数は 5 です (0.00 秒) 
                     mysql> \!ホスト名; 
mysql> \! ホスト名; vm02    
仮想通貨 
[root@vm02 ~]# mk-table-sync --execute --print --no-check-slave --transaction --databases hcy h=vm01,u=admin,p=123456 h=vm02,u=admin,p=123456 
`hcy`.`t2`(`id`, `name`) に挿入 VALUES ('5', 'ss') /*maatkit src_db:hcy src_tbl:t2 src_dsn:h=vm01,p=...,u=admin dst_db:hcy dst_tbl:t2 
dst_dsn:h=vm02、p=...、u=admin ロック:0 トランザクション:1 changing_src:0 複製:0 双方向:0 pid:3246 ユーザー:root ホスト:vm02*/;

その動作原理は、まずマスター ライブラリとスレーブ ライブラリのテーブルが行ごとに同じであるかどうかを確認します。違いがある場合は、削除、更新、挿入などの操作を実行して一貫性を保ちます。テーブルのサイズによって実行速度が決まります。

C<--transaction>が指定された場合、C<LOCK TABLES>は使用されません。代わりに、lock
およびロック解除は、トランザクションを開始してコミットすることによって実装されます。
例外は、L<"--lock"> が 3 の場合です。
C<--no-transaction>が指定された場合、C<LOCK TABLES>が使用される。
L<"--lock">の値。L<"--[no]transaction">を参照してください。
明示的または暗黙的に有効にすると、トランザクション分離レベルは
C<REPEATABLE READ>が設定され、トランザクションはC<WITH CONSISTENT>で開始されます。
スナップショット>

MySQL レプリケーション監視

一般的な MySQL エラーの種類

1005: テーブルの作成に失敗しました
1006: データベースの作成に失敗しました
1007: データベースは既に存在します。データベースの作成に失敗しました。
1008: データベースが存在しません。データベースの削除に失敗しました。
1009: データベース ファイルを削除できないため、データベースの削除に失敗しました
1010: データディレクトリの削除に失敗しました。データベースの削除に失敗しました。
1011: データベース ファイルの削除に失敗しました
1012: システム テーブルからレコードを読み取れません
1020: レコードは別のユーザーによって変更されました
1021: ハードディスクの空き容量が不足しています。ハードディスクの空き容量を増やしてください。
1022: キーワードが重複しているため、レコードの変更に失敗しました
1023: シャットダウン中にエラーが発生しました
1024: ファイルの読み取りエラー
1025: 名前の変更中にエラーが発生しました
1026: ファイルの書き込みエラー
1032: レコードが存在しません
1036: データ テーブルは読み取り専用であり、変更できません
1037: システムメモリが不足しています。データベースまたはサーバーを再起動してください。
1038: ソート用のメモリが不足しています。ソートバッファを増やしてください。
1040: データベース接続の最大数に達しました。使用可能なデータベース接続の数を増やしてください。
1041: システムメモリが不足しています
1042: ホスト名が無効です
1043: 無効な接続
1044: 現在のユーザーにはデータベースにアクセスする権限がありません
1045: データベースに接続できません。ユーザー名またはパスワードが正しくありません。
1048: フィールドは空にできません
1049: データベースが存在しません
1050: データテーブルが既に存在します
1051: データテーブルが存在しません
1054: フィールドが存在しません
1065: 無効なSQL文、SQL文が空です
1081: ソケット接続を確立できません
1114: データ テーブルがいっぱいで、レコードを格納できません。
1116: 開いているテーブルが多すぎます
1129: データベースが異常です。データベースを再起動してください。
1130: データベースへの接続に失敗しました。データベースに接続する権限がありません
1133: データベースユーザーが存在しません
1141: 現在のユーザーにはデータベースにアクセスする権限がありません
1142: 現在のユーザーにはデータ テーブルにアクセスする権限がありません
1143: 現在のユーザーにはデータ テーブル内のフィールドにアクセスする権限がありません
1146: データテーブルが存在しません
1147: テーブルへのユーザー アクセス権が定義されていません
1149: SQL ステートメントの構文エラー
1158: ネットワークエラー、読み取りエラー、ネットワーク接続状態を確認してください
1159: ネットワーク エラー、読み取りタイムアウト、ネットワーク接続状態を確認してください
1160: ネットワークエラー、書き込みエラーが発生しました。ネットワーク接続状態を確認してください
1161: ネットワーク エラー、書き込みタイムアウト、ネットワーク接続状態を確認してください
1062: フィールド値が重複しているため、保存に失敗しました
1169: フィールド値が重複しているため、レコードの更新に失敗しました
1177: データテーブルを開けませんでした
1180: トランザクションのコミットに失敗しました
1181: ロールバックトランザクションに失敗しました
1203: 現在のユーザーとデータベース間の接続数が、データベースの最大接続数に達しました。使用可能なデータベース接続数を増やすか、データベースを再起動してください。
1205: ロックタイムアウト
1211: 現在のユーザーにはユーザーを作成する権限がありません
1216: 外部キー制約チェックに失敗しました。子テーブル レコードの更新に失敗しました
1217: 外部キー制約チェックに失敗しました。プライマリ テーブル レコードの削除または変更に失敗しました。
1226: 現在のユーザーが使用しているリソースが許可されたリソースを超えています。データベースを再起動するか、サーバーを再起動してください。
1227: 権限が不十分です。この操作を実行する権限がありません。
1235: MySQL のバージョンが低すぎるため、この機能はありません。

監視スクリプトをコピーする

原文を元に修正しました。

オリジナル脚本

#!/bin/bash
#
#mysql_slave_replication_status をチェックする
#
#
#
パラサム=2
ヘルプメッセージ(){
 
猫 <<
 ヘルプ
+---------------------+
+エラー
 原因:
+あなた
 $parasum パラメータを入力する必要があります。
+1位
 : ホスト_IP
+2位
 : ホスト_ポート
ヘルプ
出口
}
 
[
 $#
 -ne ${parasum} ] && help_msg #パラメータが不十分な場合は、ヘルプ情報を出力して終了します export HOST_IP=$1
HOST_PORT=$2 をエクスポートする
MYUSER="root"     
マイパス="123456"
 
MYSQL_CMD="mysql
 -u$MYUSER -p$MYPASS"
MailTitle="" #メール件名 Mail_Address_MysqlStatus="[email protected]" #受信者のメールボックス time1=$(date +"%Y%m%d%H%M%S")
time2=$(日付 +"%Y-%m-%d
 %H:%M:%S")
 
スレーブステータスファイル=/tmp/salve_status_${HOST_PORT}.${time1} 
#メールの内容が保存されているファイル echo "--------------------Begin
 時刻: "$time2
 > $スレーブステータスファイル
エコー "" >>
 $スレーブステータスファイル
 
#得る
 奴隷状態
${MYSQL_CMD}
 -e "表示
 スレーブステータス\G" >>
 $SlaveStatusFile #スレーブプロセスのステータスを取得#get
 io_thread_status、sql_thread_status、last_errno 次のステータス値を取得します IOStatus=$(cat $SlaveStatusFile|grep Slave_IO_Running|awk '{print
 $2}')
SQLStatus=$(cat $SlaveStatusFile|grep Slave_SQL_Running
 |awk '{印刷
 $2}')
  Errno=$(cat $SlaveStatusFile|grep Last_Errno
 | awk '{印刷
 $2}')
  Behind=$(cat $SlaveStatusFile|grep Seconds_Behind_Master
 | awk '{印刷
 $2}')
 
エコー "" >>
 $スレーブステータスファイル
 
もし [
"$IOステータス" ==
"いいえ" ]
 || [ "$SQLステータス" ==
"いいえ" ]; then #エラーの種類を判断する if [
"$Errno" -eq 0
 ]; then #スレーブスレッドが開始されていない可能性があります $MYSQL_CMD
 -e "開始
 スレーブ io_thread;スレーブ sql_thread を開始します。"
      echo "原因
 スレーブ スレッドが実行されません。slsave io_thread; を開始しようとしています。start slave sql_thread;" >>
 $スレーブステータスファイル
      MailTitle="[警告]
 スレーブ スレッドが $HOST_IP $HOST_PORT で停止しました
    エリフ[
"$Errno" -eq 1007
 ] || [ "$Errno" -eq 1053
 ] || [ "$Errno" -eq 1062
 ] || [ "$Errno" -eq 1213
 ] || [ "$Errno" -eq 1032
 ]\
      ||
 [ "Errno" -eq 1158
 ] || [ "$Errno" -eq 1159
 ] || [ "$Errno" -eq 1008
 ]; then #これらのエラーを無視する $MYSQL_CMD
 -e "停止
 スレーブ;グローバル sql_slave_skip_counter を 1 に設定;スレーブを開始;"
      echo "原因
 スレーブ レプリケーションでエラーが発生し、カウンターをスキップしてスレーブを再起動しようとしています。スレーブを停止します。グローバル sql_slave_skip_counter を 1 に設定します。スレーブを開始します。" >>
 $スレーブステータスファイル
      MailTitle="[警告]
 $HOST_IP $HOST_PORT のスレーブ エラー! ErrNum: $Errno"
    それ以外
      エコー「スレーブ
 $HOST_IP $HOST_PORT がダウンしています!" >>
 $スレーブステータスファイル
      MailTitle="[エラー]スレーブ
 $HOST_IP $HOST_PORT でレプリケーションがダウンしています! ErrNum:$Errno"
    フィ
フィ
もし [
 -n "$Behind" ];その後
    後ろ=0
フィ
echo "$Behind" >>
 $スレーブステータスファイル
 
#遅れ
 マスターの背後で遅延時間を決定する場合、[
 $Behind -gt 300 ];その後
  エコー `date +"%Y-%m%d
 %H:%M:%S"`
「奴隷
 マスター $Bebind 秒遅れています!" >>
 $スレーブステータスファイル
  MailTitle="[警告]スレーブ
 遅延 $Behind 秒、$HOST_IP $HOST_PORT から"
フィ
 
もし [
 -n "$MailTitle" ]; then #エラーが発生するか、遅延が300秒を超える場合は、メールを送信します cat ${SlaveStatusFile}
 | /bin/メール -s
"$MailTitle" $Mail_Address_MysqlStatus
フィ
 
#削除
 tmpfile:スレーブステータスファイル
>
 $スレーブステータスファイル

修正されたスクリプト

単純な整理のみを行い、Behind が NULL であるという判定を修正しましたが、テストは行われませんでした。

以下を追加することを検討してください:

修復実行結果の判断、周期的な修復、複数のエラーの検出と修復?

SlaveStatusFile 一時ファイルをキャンセルします。

Errno アラームと Behind アラームは個別に電子メールに送信され、アラーム本文には show slave 結果の元のテキストが追加されます。

crontab に追加できるように PATH を増やします。

crontab で定期的な実行を検討する (実行の競合を避けるためのロック、実行サイクルの選択)

実行ログを追加しますか?

#!/bin/sh
#
 チェック_mysql_スレーブ_レプリケーション_ステータス
#
 参考: http://www.tianfeiyu.com/?p=2062
 
使用法(){
  echo 使用法:
  エコー "$0
 ホスト ポート ユーザー パス"
}
 
[
 -z "$1" -o
 -z "$2" -o
 -z "$3" -o
 -z "$4" ]
 && 使用法 && 終了 1
ホスト=$1
ポート=$2
ユーザー=$3
パス=$4
 
MYSQL_CMD="mysql
 -h$ホスト -P$ポート -u$ユーザー -p$パスワード"
 
MailTitle="" #メール件名 Mail_Address_MysqlStatus="[email protected]" #受信者のメールボックス time1=$(date +"%Y%m%d%H%M%S")
time2=$(日付 +"%Y-%m-%d
 %H:%M:%S")
 
スレーブステータスファイル=/tmp/salve_status_${HOST_PORT}.${time1} 
#メールの内容が保存されているファイル echo "--------------------Begin
 時刻: "$time2
 > $スレーブステータスファイル
エコー "" >>
 $スレーブステータスファイル
 
#得る
 奴隷状態
${MYSQL_CMD}
 -e "表示
 スレーブステータス\G" >>
 $SlaveStatusFile #スレーブプロセスのステータスを取得#get
 io_thread_status、sql_thread_status、last_errno 次のステータス値を取得します IOStatus=$(cat $SlaveStatusFile|grep Slave_IO_Running|awk '{print
 $2}')
SQLStatus=$(cat $SlaveStatusFile|grep Slave_SQL_Running
 |awk '{印刷
 $2}')
  Errno=$(cat $SlaveStatusFile|grep Last_Errno
 | awk '{印刷
 $2}')
  Behind=$(cat $SlaveStatusFile|grep Seconds_Behind_Master
 | awk '{印刷
 $2}')
 
エコー "" >>
 $スレーブステータスファイル
 
もし [
"$IOステータス" =
「いいえ」 -o
"$SQLステータス" =
「いいえ」];その後
  ケース「$Errno」
  0)
    #
 スレーブが$MYSQL_CMDを開始していない可能性があります
 -e "開始
 スレーブ io_thread;スレーブ sql_thread を開始します。"
    echo "原因
 スレーブ スレッドが実行されません。slsave io_thread; を開始しようとしています。start slave sql_thread;" >>
 $スレーブステータスファイル
    ;;
  1007|1053|1062|1213|1032|1158|1159|1008)
    #
 これらのエラーを無視する $MYSQL_CMD
 -e "停止
 スレーブ;グローバル sql_slave_skip_counter を 1 に設定;スレーブを開始;"
    echo "原因
 スレーブ レプリケーションでエラーが発生し、カウンターをスキップしてスレーブを再起動しようとしています。スレーブを停止します。グローバル sql_slave_skip_counter を 1 に設定します。スレーブを開始します。" >>
 $スレーブステータスファイル
    MailTitle="[警告]
 $HOST:$PORT でスレーブ エラーが発生しました。ErrNum: $Errno"
    ;;
  *)
    エコー「奴隷
 $HOST:$PORT がダウンしています!" >>
 $スレーブステータスファイル
    MailTitle="[エラー]スレーブ
 $HOST:$PORT でレプリケーションがダウンしています。Errno:$Errno"
    ;;
  エサック
フィ
 
もし [
"$Behind" =
「NULL」 -o
 -z "$Behind" ];その後
  後ろ=0
フィ
echo "Behind:$Behind" >>
 $スレーブステータスファイル
 
#遅れ
 マスターの背後で遅延時間を決定する場合、[
 $Behind -gt 300 ];その後
  エコー `date +"%Y-%m%d
 %H:%M:%S"`
「奴隷
 マスター $Bebind 秒遅れています!" >>
 $スレーブステータスファイル
  MailTitle="[警告]スレーブ
 $HOST $PORT から $Behind 秒の遅延"
フィ
 
もし [
 -n "$MailTitle" ]; then #エラーが発生するか、遅延が300秒を超える場合は、メールを送信します cat ${SlaveStatusFile}
 | /bin/メール -s
"$MailTitle" $Mail_Address_MysqlStatus
フィ
 
#削除
 tmpfile:スレーブステータスファイル
>
 $スレーブステータスファイル

上記のオンライン MYSQL 同期エラーのトラブルシューティング方法の要約 (必読) は、編集者が皆さんと共有する内容のすべてです。 皆さんの参考になれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • mysql show processlist コマンドを使用して mysql ロックを確認する方法
  • mysql show processlistはmysqlクエリプロセスを表示します。
  • MYSQL マスターとスレーブの同期外れの問題に対する解決策
  • MySQLの遅いクエリが失敗の原因となった
  • MySQL での MHA 高可用性フェイルオーバー ソリューションのスーパー デプロイメント チュートリアル
  • MySQL レプリケーションの概要、インストール、トラブルシューティング、ヒント、ツール (Huo Ding による共有)
  • MySQLテーブル障害を検出する方法
  • MySQL 接続失敗の一般的な障害と原因
  • MySQL SHOW PROCESSLISTはトラブルシューティングの全プロセスを支援します

<<:  JSは文字列内の指定された文字列のn番目の出現位置を取得します

>>:  FileZilla Server の FTP サーバー構成と 425 エラーおよび TLS 警告の解決策の詳細な説明

推薦する

MySql のスロークエリ分析とスロークエリログの開き方の詳細説明

最近はMySQLのパフォーマンス最適化についても研究しているので、今日の投稿は勉強ノートとしても使え...

MySQL の sql_mode モード例の詳細な説明

この記事では、MySQL の sql_mode モードについて例を挙げて説明します。ご参考までに、詳...

MySQL データベース テーブルとデータベース パーティショニング戦略

まず、テーブルを分割する必要がある理由について説明します。データシートが数百万に達すると、1 回のク...

Linux ディスク領域解放問題の概要

IDC のサーバーの /partition 使用率がいっぱいです。 100% に到達しました!確認し...

MySQL データ アーカイブ ツール mysql_archiver の詳細な説明

目次I. 概要2. pt-archiverの主なパラメータ3. mysql_archiverのインス...

MySQL 8.0.15 winx64 のインストールと設定方法のグラフィックチュートリアル (Windows の場合)

この記事では、MySQL 8.0.15 winx64のインストールと設定方法を参考までに紹介します。...

Kali Linux システムのバージョンを確認する方法

1. Kali Linuxシステムのバージョンを確認するコマンド: cat /etc/issue 2...

Nginxはhttpとhttpsの両方のアクセスをサポートするために同じドメイン名を設定します

Nginx は同じドメイン名で構成されており、http と https の両方でアクセスできます。証...

指定したディレクトリに nginx をインストールする方法の例

会社の要件により、異なる場所にある 2 つの nginx サーバーを同じマシンにインストールする必要...

EXPLAIN を使って MySQL の SQL 実行プランを分析する方法

序文MySQL では、EXPLAIN コマンドを使用して、テーブルの接続方法や SELECT ステー...

MySQL テーブルパーティションの使用法と基本原理の詳細な説明

目次パーティションテーブルとはパーティションテーブルの適用シナリオパーティションテーブルの制限パーテ...

Reactでファイルパスエイリアスを素早く設定する方法

React は、ユーザー インターフェイスを構築するための JavaScript ライブラリです。F...

MySQL 条件付きクエリと使用法および優先順位の例の分析

この記事では、例を使用して、MySQL 条件クエリ and or の使用方法と優先順位を説明します。...

DockerプライベートイメージライブラリとAlibaba CloudオブジェクトストレージOSSの簡単な分析

Docker プライベートイメージライブラリDockerプライベートイメージライブラリとAlibab...

MySQL で CURRENT_TIMESTAMP を使用する方法

目次CURRENT_TIMESTAMPの使用CURRENT_TIMESTAMPを使用したタイムスタン...