Mysqldump がレプリケーション エラーを作成します。これはこれが原因です。

著者は、mysqldump ビルド レプリケーションの失敗の問題分析プロセスと改善提案を詳細に分析しました。

著者: 李福強

Acson DBA チームのメンバーで、MySQL、TiDB、OceanBase、その他のデータベースに精通しています。正しいことをしっかり続けていけば、また違った収穫があると思います。

この記事の出典: 元の寄稿

  • Aikesheng オープンソース コミュニティによって作成されており、オリジナルのコンテンツを許可なく使用することはできません。転載する場合は編集者に連絡し、出典を明示してください。

症状

お客様から、mysqldump を使用してスレーブ ライブラリを構築すると、レプリケーションの開始後にレプリケーション エラーが発生すると報告されましたCould not execute Write_rows event on table xxx; Duplicate entry 'xxx' for key 'PRIMARY'

クライアントが使用するコマンド (問題ないようです)。

-- 主库备份
shell> mysqldump -uroot -pxxx --master-data=2 --single-transaction -A --routines --events --triggers >/tmp/xxx.sql
  
-- 从服务器还原备份并启动复制
mysql>reset master;
mysql>reset slave all;
mysql>source /tmp/xxx.sql ;
mysql>change master to master_host='xxx',master_port=3306,master_user='xxx',master_password='xxx',master_auto_position=1;
mysql>start slave;

トラブルシューティング

レプリケーション エラー テーブルのテーブル構造を確認し、テーブルのストレージ エンジンが MyISAM エンジンであることを確認します。お客様からのフィードバックによると、テーブルアクセスが頻繁であり、mysqldump --single-transactionこのオプションでは InnoDB エンジンのテーブルバックアップの整合性のみ保証できますが、MyISAM エンジンのテーブルバックアップの整合性は保証できないという点に問題がある可能性があります。

問題が解決しました

テーブルのストレージ エンジンを InnoDB に変更した後、再度バックアップと復元を行うと、スレーブ ライブラリが正常に構築できるようになります。

問題の再発

以下で問題を再現してみましょう。

環境情報

オペレーティング·システム CentOS Linux リリース 7.5.1804 (コア)
バージョン MySQL 5.7.25
メインライブラリ 10.186.60.187
図書館から 10.186.60.37
マスタースレーブ GTID を有効にする

ステップ

メイン ライブラリで、Sysbench を使用して 1000w データを含む InnoDB エンジン テーブルを作成しますtestdb_innodb.sbtest1(1000w データを作成する主な目的は、InnoDB エンジン テーブルのバックアップ時間を長くすることです)。

shell> sysbench /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua \
--mysql-host=10.186.60.187 --mysql-port=3307 --mysql-user=root \
--mysql-password=1 --mysql-db=testdb_innodb --oltp-table-size=10000000 --oltp-tables-count=1 --threads=4    --report-interval=3 prepare
  
-- 表结构如下
mysql> show create table  testdb_innodb.sbtest1;
CREATE TABLE `sbtest1` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `k` int(10) unsigned NOT NULL DEFAULT '0',
  `c` char(120) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
  `pad` char(60) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=10000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
  
  
-- 表总行数如下:
mysql> select count(*) from testdb_innodb.sbtest1;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+

メインデータベースに MyISAM エンジンのテーブルを作成しますtestdb_myisam.sbtest2

-- 表结构如下:
mysql> CREATE TABLE testdb_myisam.`sbtest2` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `k` int(10) unsigned NOT NULL DEFAULT '0',
  `c` char(120) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
  `pad` char(60) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=myisam AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

メイン ライブラリで、mysqldump 論理バックアップを開始し、バックアップ中にテーブルにデータを挿入しますtestdb_innodb.sbtest1(バックアップ順序: 最初にtestdb_innodbライブラリをバックアップします) 。testdb_myisam.sbtest2

-- 执行 mysqldump 备份
shell> /data/mysql/base/5.7.25/bin/mysqldump -h10.186.60.187 -P3307 -uroot -p1 --master-data=2 --single-transaction -A --routines --events --triggers  >/tmp/dump.sql
 
 
-- 执行备份 testdb_innodb.sbtest1 期间,往 testdb_myisam.sbtest2 表插入一条数据
mysql> insert into testdb_myisam.`sbtest2`(k,c,pad)  values(2,'myisam','myisam');
  
-- 通过 MySQL general_log 观察备份情况
  
2023-07-11T16:15:50.900581+08:00         2692 Connect   [email protected] on  using TCP/IP
2023-07-11T16:15:50.901124+08:00         2692 Query     /*!40100 SET @@SQL_MODE='' */
2023-07-11T16:15:50.901529+08:00         2692 Query     /*!40103 SET TIME_ZONE='+00:00' */
2023-07-11T16:15:50.901743+08:00         2692 Query     FLUSH /*!40101 LOCAL */ TABLES
2023-07-11T16:15:50.938083+08:00         2692 Query     FLUSH TABLES WITH READ LOCK
2023-07-11T16:15:50.938281+08:00         2692 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
2023-07-11T16:15:50.938410+08:00         2692 Query     START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
2023-07-11T16:15:50.938678+08:00         2692 Query     SHOW VARIABLES LIKE 'gtid\_mode'
2023-07-11T16:15:50.980335+08:00         2692 Query     SELECT @@GLOBAL.GTID_EXECUTED
2023-07-11T16:15:50.980566+08:00         2692 Query     SHOW MASTER STATUS
2023-07-11T16:15:50.980758+08:00         2692 Query     UNLOCK TABLES
...略
2023-07-11T16:15:51.541911+08:00         2692 Init DB   testdb_innodb
2023-07-11T16:15:51.542012+08:00         2692 Query     SHOW CREATE DATABASE IF NOT EXISTS `testdb_innodb`
2023-07-11T16:15:51.542139+08:00         2692 Query     SAVEPOINT sp
2023-07-11T16:15:51.542224+08:00         2692 Query     show tables
2023-07-11T16:15:51.542405+08:00         2692 Query     show table status like 'sbtest1'
2023-07-11T16:15:51.543353+08:00         2692 Query     SET SQL_QUOTE_SHOW_CREATE=1
2023-07-11T16:15:51.543467+08:00         2692 Query     SET SESSION character_set_results = 'binary'
2023-07-11T16:15:51.543548+08:00         2692 Query     show create table `sbtest1`
2023-07-11T16:15:51.543729+08:00         2692 Query     SET SESSION character_set_results = 'utf8'
2023-07-11T16:15:51.543837+08:00         2692 Query     show fields from `sbtest1`
2023-07-11T16:15:51.544172+08:00         2692 Query     show fields from `sbtest1`
2023-07-11T16:15:51.544477+08:00         2692 Query     SELECT /*!40001 SQL_NO_CACHE */ * FROM `sbtest1`
2023-07-11T16:15:57.603435+08:00         2683 Query     insert into testdb_myisam.`sbtest2`(k,c,pad)  values(2,'myisam','myisam')
2023-07-11T16:16:27.456357+08:00         2692 Query     SET SESSION character_set_results = 'binary'
2023-07-11T16:16:27.471239+08:00         2692 Query     use `testdb_innodb`
2023-07-11T16:16:27.471589+08:00         2692 Query     select @@collation_database
2023-07-11T16:16:27.472065+08:00         2692 Query     SHOW TRIGGERS LIKE 'sbtest1'
2023-07-11T16:16:27.506025+08:00         2692 Query     SET SESSION character_set_results = 'utf8'
2023-07-11T16:16:27.506225+08:00         2692 Query     ROLLBACK TO SAVEPOINT sp
2023-07-11T16:16:27.506383+08:00         2692 Query     RELEASE SAVEPOINT sp
2023-07-11T16:16:27.506538+08:00         2692 Query     show events
2023-07-11T16:16:27.507226+08:00         2692 Query     use `testdb_innodb`
2023-07-11T16:16:27.507346+08:00         2692 Query     select @@collation_database
2023-07-11T16:16:27.507457+08:00         2692 Query     SET SESSION character_set_results = 'binary'
2023-07-11T16:16:27.507629+08:00         2692 Query     SHOW FUNCTION STATUS WHERE Db = 'testdb_innodb'
2023-07-11T16:16:27.621194+08:00         2692 Query     SHOW PROCEDURE STATUS WHERE Db = 'testdb_innodb'
2023-07-11T16:16:27.622726+08:00         2692 Query     SET SESSION character_set_results = 'utf8'
2023-07-11T16:16:27.622900+08:00         2692 Init DB   testdb_myisam
2023-07-11T16:16:27.623005+08:00         2692 Query     SHOW CREATE DATABASE IF NOT EXISTS `testdb_myisam`
2023-07-11T16:16:27.623102+08:00         2692 Query     SAVEPOINT sp
2023-07-11T16:16:27.623211+08:00         2692 Query     show tables
2023-07-11T16:16:27.623566+08:00         2692 Query     show table status like 'sbtest2'
2023-07-11T16:16:27.624197+08:00         2692 Query     SET SQL_QUOTE_SHOW_CREATE=1
2023-07-11T16:16:27.624314+08:00         2692 Query     SET SESSION character_set_results = 'binary'
2023-07-11T16:16:27.624401+08:00         2692 Query     show create table `sbtest2`
2023-07-11T16:16:27.624518+08:00         2692 Query     SET SESSION character_set_results = 'utf8'
2023-07-11T16:16:27.624605+08:00         2692 Query     show fields from `sbtest2`
2023-07-11T16:16:27.625027+08:00         2692 Query     show fields from `sbtest2`
2023-07-11T16:16:27.625391+08:00         2692 Query     SELECT /*!40001 SQL_NO_CACHE */ * FROM `sbtest2`
2023-07-11T16:16:27.636073+08:00         2692 Query     SET SESSION character_set_results = 'binary'
2023-07-11T16:16:27.636213+08:00         2692 Query     use `testdb_myisam`
2023-07-11T16:16:27.636317+08:00         2692 Query     select @@collation_database
2023-07-11T16:16:27.636429+08:00         2692 Query     SHOW TRIGGERS LIKE 'sbtest2'
2023-07-11T16:16:27.636923+08:00         2692 Query     SET SESSION character_set_results = 'utf8'
2023-07-11T16:16:27.637034+08:00         2692 Query     ROLLBACK TO SAVEPOINT sp
2023-07-11T16:16:27.637116+08:00         2692 Query     RELEASE SAVEPOINT sp
2023-07-11T16:16:27.637195+08:00         2692 Query     show events
2023-07-11T16:16:27.637517+08:00         2692 Query     use `testdb_myisam`
2023-07-11T16:16:27.637631+08:00         2692 Query     select @@collation_database
2023-07-11T16:16:27.637741+08:00         2692 Query     SET SESSION character_set_results = 'binary'
2023-07-11T16:16:27.637839+08:00         2692 Query     SHOW FUNCTION STATUS WHERE Db = 'testdb_myisam'
2023-07-11T16:16:27.639206+08:00         2692 Query     SHOW PROCEDURE STATUS WHERE Db = 'testdb_myisam'
2023-07-11T16:16:27.640377+08:00         2692 Query     SET SESSION character_set_results = 'utf8'
2023-07-11T16:16:27.663274+08:00         2692 Quit

スレーブ サーバー上で、上記の mysqldump 論理バックアップ ファイルを使用してリカバリを実行し、スレーブ ライブラリを構築します。

-- 从库查看数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
 
 
-- 清空从库 binlog 和 gtid 信息
mysql> reset master;
  
-- 查看确认
mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 154
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
 
 
  
-- 执行 mysqldump 逻辑备份文件恢复
mysql> source /tmp/dump.sql;
-- 建立复制,并启动复制
mysql> change master to MASTER_HOST='10.186.60.187',MASTER_PORT=3307,master_user='repl',master_password='1',MASTER_AUTO_POSITION=1;
mysql> start slave;

-- 查看复制状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.186.60.187
                  Master_User: repl
                  Master_Port: 3307
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000015
          Read_Master_Log_Pos: 190088135
               Relay_Log_File: mysql-relay.000002
                Relay_Log_Pos: 414
        Relay_Master_Log_File: mysql-bin.000015
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 1062
                   Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '19112042-1f97-11ee-bf09-02000aba3cbb:3747' at master log mysql-bin.000015, end_log_pos 190087781. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 190087413
              Relay_Log_Space: 1339
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 1062
               Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '19112042-1f97-11ee-bf09-02000aba3cbb:3747' at master log mysql-bin.000015, end_log_pos 190087781. See error log and/or   performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 629181509
                  Master_UUID: 19112042-1f97-11ee-bf09-02000aba3cbb
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp: 230711 17:03:01
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: 19112042-1f97-11ee-bf09-02000aba3cbb:3747-3748
            Executed_Gtid_Set: 19112042-1f97-11ee-bf09-02000aba3cbb:1-3746
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)
  
  
-- 查看复制具体报错内容
mysql> select * from  performance_schema.replication_applier_status_by_worker\G;
*************************** 1. row ***************************
         CHANNEL_NAME:
            WORKER_ID: 1
            THREAD_ID: NULL
        SERVICE_STATE: OFF
LAST_SEEN_TRANSACTION: 19112042-1f97-11ee-bf09-02000aba3cbb:3747
    LAST_ERROR_NUMBER: 1062
   LAST_ERROR_MESSAGE: Worker 1 failed executing transaction '19112042-1f97-11ee-bf09-02000aba3cbb:3747' at master log mysql-bin.000015, end_log_pos 190087781; Could not execute Write_rows event on table testdb_myisam.sbtest2; Duplicate entry '2' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 190087781
 LAST_ERROR_TIMESTAMP: 2023-07-11 17:03:01

原理分析

  1. mysqldump がバックアップを開始し、整合性ポイントを取得すると、それがT1時間UNLOCK TABLESとして記録されます。
  2. InnoDB テーブルのバックアップが完了します (InnoDB テーブルが最初にバックアップされると仮定します)。これはT2時間として記録されます。
  3. MyISAM エンジン テーブルのバックアップが完了し、時刻T3として記録されます。
  4. T1T2の間で、MyISAM エンジン テーブルで INSERT 操作がある場合、binlog が生成され、mysqldump はT1T2の間の MyISAM エンジン テーブルの INSERT データもバックアップします。
  5. このようにして、レプリケーションの開始後、SQL スレッドはT1からT2までのバイナリログを再生し、データのこの部分はすでにバックアップ ファイル内にあり、スレーブ ライブラリに復元されているため、SQL スレッドの再生では重複キーが報告されます。
  6. このオプションを使用する場合:一貫性のあるバックアップの取得は InnoDB エンジンにのみ適用されます。InnoDB エンジン テーブル バックアップの場合は、 T1mysqldump --single-transactionでのスナップショットが取得されます。InnoDB エンジン以外のテーブル バックアップの場合は、現在の最新データが取得されます。

改善のための提案

  1. 業務データベースの非InnoDBエンジンテーブルをInnoDBに変更し、再度バックアップ後にスレーブデータベースを構築します(テーブルのストレージエンジンの変更にはコストがかかり、ストレージエンジンの変更によるオンライン業務への影響も考慮する必要があるため、テーブルをInnoDBエンジンに変更できる場合に適しています)。

  2. 代わりに、Xtrabackup バックアップ ユーティリティを使用してください。InnoDB 以外のテーブルが比較的大きい場合、MyISAM エンジンのバックアップ中に、バックアップ スレッドがインスタンスのグローバル読み取りロック (FLUSH TABLES WITH READ LOCK) を保持する時間が増加し、データベースの可用性に影響を与えるため、業務時間の短い時間帯に実行する必要があります。(テーブル ストレージ エンジンを短期間に変更できない状況に適しています)。

さらに技術的な記事については、https: //opensource.actionsky.com/をご覧ください。

SQLEについて

Akson オープン ソース コミュニティの SQLE は、データベース ユーザーおよび管理者向けの SQL 監査ツールです。これは、マルチシナリオ監査をサポートし、標準化されたオンライン プロセスをサポートし、MySQL 監査をネイティブにサポートし、スケーラブルなデータベース タイプを備えています。

SQL取得

タイプ 住所
リポジトリ https://github.com/actiontech/sqle
書類 https://actiontech.github.io/sqle-docs/
リリースニュース https://github.com/actiontech/sqle/releases
データ監査プラグイン開発ドキュメント https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
2023年に最も需要の高いプログラミング言語8選:PHPは好調、C/C++の需要は鈍化マスク氏がTwitterの名前をXに変更、ロゴ も5年間 変更すると発表、Cython 3.0が正式リリース GPT-4はますますバカになっている?精度率は97.6%から2.4%に低下MySQL 8.1とMySQL 8.0.34が正式リリースC#とTypeScriptの父が最新のオープンソースプロジェクトを発表: TypeChat Meta Enlargementの動き: オープンソースの大規模言語モデルLlama 2をリリース、商用利用は無料これに耐えられず、Reactコア開発者のDan Abramov氏がMeta Chatからの辞任を発表 Android向けGPTは来週リリースされる. ニーズ? おそらくこの 5,000 スター GitHub オープン ソース プロジェクトが役立つかもしれません - MetaGPT
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/actiontechoss/blog/10090762