MySQL:slave_skip_errors引數對MGR可用性的影響
整個問題提出和測試由 @gc @甘露寺的姑子@乙酉 完成,文件記錄由 @gc @乙酉完成。
我只是進行了問題分析和文件整理
歡迎關注我的《深入理解MySQL主從原理 32講 》,如下:
一、案例描述
MGR在遇到表不存在的情況下,節點沒有退出節點而是爆出一個警告,並且節點狀態也正常,警告如下:
2019-10-17T21:16:11.564211+08:00 10 [Warning] Slave SQL for channel
group_replication_applier': Worker 1 failed executing transaction 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:8' at master log , end_log_pos 220;
Error executing row event: 'Table 'test.a_1' doesn't exist', Error_code: 1146
叢集狀態如下:
[root@mysql.sock][test]>select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 9fd479bb-f0d8-11e9-9381-000c29105312 | mysql_1 | 3306 | ONLINE |
| group_replication_applier | a8833a96-f0d8-11e9-a9f4-000c291fd9a5 | mysql_2 | 3306 | ONLINE |
| group_replication_applier | b2968fe2-f0d8-11e9-a8ff-000c29c89e42 | mysql_3 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)
當時覺得很奇怪,我們知道這種錯誤即便是在主從情況下也是報錯的SQL執行緒退出的,MGR居然還能線上,這種情況資料已經不同步了,應該報錯並且剔除節點才對。
二、問題分析
隨即一些感興趣的同學馬上進行了測試,測試結果和上面不一致,測試結果是報錯而不是出警告如下:
2019-10-17T09:16:34.317542Z 84 [ERROR] Slave SQL for channel
'group_replication_applier': Error executing row event:
'Table 'test.emp1' doesn't exist', Error_code: 1146
並且這種情況表不存在的節點已經被剔除掉了。下面是正常情況的節點狀態:
secondary 1節點:
[root@mysql.sock][test]>select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | a8833a96-f0d8-11e9-a9f4-000c291fd9a5 | mysql_2 | 3306 | ERROR |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)
secondary 2節點:
[root@mysql.sock][test]>select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | b2968fe2-f0d8-11e9-a8ff-000c29c89e42 | mysql_3 | 3306 | ERROR |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)
那麼疑問就是為什麼同樣是MGR一個是警告一個是錯誤呢,並且前者還能處於正常同步狀態。不錯看到題目就知道這裡和slave_skip_errors引數有關。
三、測試模擬
我們知道再Master-Slave中如果遇到從庫表不存在肯定是報錯的,除非設定slave_skip_errors引數,當然我線上上重來沒有設定過這個引數,並且通過這個案例我們發現本引數對MGR也有影響,如下測試方法:
我們在3個節點都開啟slave-skip-errors= ddl_exist_errors
如下圖:
然後搭建3節點single-primary模式的MGR叢集。
叢集搭建正常。
然後執行如下操作:
[root@mysql.sock][(none)]>set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)
[root@mysql.sock][(none)]>create table test.a_1(id bigint auto_increment primary key,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
[root@mysql.sock][(none)]>set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)
此時primary節點是有a_1表的,但是因為binlog關閉的原因,兩個secondary節點是不存在a_1表的。
然後我們插入資料:
[root@mysql.sock][test]>insert into test.a_1 values(null,'tom');
Query OK, 1 row affected (0.02 sec)
此時,primary節點因為存在a_1表,所以能夠插入,但是兩個secondary節點不存在a_1表,所以插入是失敗的。資料產生不一致。正常情況下這種資料不一致會導致2個secondary節點被提出叢集才對。但是實際上3個節點都是正常的,叢集並沒有失效。
[root@mysql.sock][test]>select * from test.a_1;
+----+------+
| id | name |
+----+------+
| 1 | tom |
+----+------+
1 row in set (0.00 sec)
[root@mysql.sock][test]>select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 9fd479bb-f0d8-11e9-9381-000c29105312 | mysql_1 | 3306 | ONLINE |
| group_replication_applier | a8833a96-f0d8-11e9-a9f4-000c291fd9a5 | mysql_2 | 3306 | ONLINE |
| group_replication_applier | b2968fe2-f0d8-11e9-a8ff-000c29c89e42 | mysql_3 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)
此時去2個secondary節點讀取test.a_1表,表是不存在的。
secondary 1:
[root@mysql.sock][test]>select * from test.a_1;
ERROR 1146 (42S02): Table 'test.a_1' doesn't exist
[root@mysql.sock][test]>
secondary 2:
[root@mysql.sock][test]>select * from test.a_1;
ERROR 1146 (42S02): Table 'test.a_1' doesn't exist
error log輸出資訊:(set global log_error_verbosity = 3;)
2019-10-17T21:16:11.564211+08:00 10 [Warning] Slave SQL for channel
'group_replication_applier': Worker 1 failed executing transaction 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:8' at master log ,
end_log_pos 220; Error executing row event: 'Table 'test.a_1' doesn't exist', Error_code: 1146
四、slave_skip_errors原始碼生效點
這個設定在Rows_log_event::do_apply_event 函式中生效,也就是DML Event開始應用的時候生效,這是常規的SQL執行緒(或者Worker執行緒)呼叫的。
#ifdef HAVE_REPLICATION
if (opt_slave_skip_errors)
add_slave_skip_errors(opt_slave_skip_errors);
#endif
if (open_and_lock_tables(thd, rli->tables_to_lock, 0))//開啟表
{
uint actual_error= thd->get_stmt_da()->mysql_errno();
if (thd->is_slave_error || thd->is_fatal_error)
{
if (ignored_error_code(actual_error)) //這裡受到 slave_skip_errors 引數控制 ignored_error_code會將slave_skip_errors的引數設定讀取出來
{
if (log_warnings > 1)
rli->report(WARNING_LEVEL, actual_error,
"Error executing row event: '%s'",
(actual_error ? thd->get_stmt_da()->message_text() :
"unexpected success or fatal error"));
thd->get_stmt_da()->reset_condition_info(thd);
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
error= 0;
goto end;
}
else
{
rli->report(ERROR_LEVEL, actual_error,
"Error executing row event: '%s'",
(actual_error ? thd->get_stmt_da()->message_text() :
"unexpected success or fatal error"));
thd->is_slave_error= 1;
const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
DBUG_RETURN(actual_error);
}
}
可以看到MGR的執行邏輯受到了該引數的影響。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2660860/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java教程:影響MySQL效能的配置引數JavaMySql
- JVM 引數調整對 sortx 的影響JVM
- Kafka之acks引數對訊息持久化的影響Kafka持久化
- MySQL:Innodb:innodb_flush_log_at_trx_commit引數影響的位置MySqlMIT
- MySQL:簡單記錄character_set_server影響引數MySqlServer
- 瞭解 ignore_above 引數對 Elasticsearch 中磁碟使用的影響Elasticsearch
- MySQL alter 新增列對dml影響MySql
- MySQL:查詢欄位數量多少對查詢效率的影響MySql
- 資料可用性問題對如今的區塊鏈有何影響?區塊鏈
- MySQL:MGR修改max_binlog_cache_size引數導致異常MySql
- mysql事務對效率的影響分析總結JILEMySql
- 伺服器IO瓶頸對MySQL效能的影響伺服器MySql
- 16、MySQL Case-索引key對select count(*)的影響MySql索引
- 數字化轉型的影響是什麼?數字化轉型對企業的影響?
- JPEG的量化引數QP如何影響壓縮質量
- mysql的DDL操作對業務產生影響測試MySql
- 1.迭代次數對精確度的影響
- 深入理解MySQL5.7GTID系列(七)binlog_gtid_simple_recovery引數的影響總結MySql
- 影響mysql效能的因素都有哪些MySql
- 影響MySQL效能的硬體因MySql
- 影響MySQL效能的硬體因素MySql
- unusable index對DML/QUERY的影響Index
- Nologging對恢復的影響(二)
- 語言對思維的影響
- Nologging對恢復的影響(一)
- 度量BGP監測源數量對AS可見性的影響
- 網線的分類與對網速的影響 網線對網速影響大嗎?
- mysql之 CentOS系統針對mysql引數優化MySqlCentOS優化
- 浮動的盒子對img的影響
- MySQL運維實戰(5.6) 字符集設定對mysqldump的影響MySql運維
- 第49問:如何快速判斷 IO 延遲對 MySQL 效能的影響MySql
- MySQL中join語句的基本使用教程及其欄位對效能的影響MySql
- 來電對播放音樂的影響
- python:super()對多繼承的影響Python繼承
- DB2 HADR對效能的影響DB2
- INDEX建立方式對SQL的影響IndexSQL
- 關於OPcache對Swoole影響的理解opcache
- 數字經濟對於製造業數字化轉型影響的思考