久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL中slave

202次閱讀
沒有評論

共計 5850 個字符,預計需要花費 15 分鐘才能閱讀完成。

這篇文章主要介紹 MySQL 中 slave_exec_mode 參數的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

無意當中看到參數 slave_exec_mode,從手冊里的說明看出該參數和 MySQL 復制相關,是可以動態修改的變量,默認是 STRICT 模式(嚴格模式),可選值有 IDEMPOTENT 模式(冪等模式)。設置成 IDEMPOTENT 模式可以讓從庫避免 1032(從庫上不存在的鍵)和 1062(重復鍵,需要存在主鍵或則唯一鍵)的錯誤,該模式只有在 ROW EVENT 的 binlog 模式下生效,在 STATEMENT EVENT 的 binlog 模式下無效。IDEMPOTENT 模式主要用于多主復制和 NDB CLUSTER 的情況下,其他情況不建議使用。從上面的介紹來看,這個參數的讓從庫跳過指定的錯誤,那問題來了:

1:和  sql_slave_skip_counter 比,有什么好處?

2:和 slave-skip-errors = N 比,有什么好處?

帶著這 2 個問題,本文來進行相關的測試和說明。 

環境:

MySQL 版本:Percona MySQL 5.7

復制模式:ROW,沒有開啟 GTID

測試:

① 1062 錯誤:Could not execute … event on table db.x; Duplicate entry xx for key PRIMARY , Error_code: 1062;

主從上的測試表結構:

CREATE TABLE `x` ( `id` int(11) NOT NULL AUTO_INCREMENT,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

主從上的表記錄:

M:

select * from x;
+----+
| id |
+----+
| 2 |
| 3 |
+----+
2 rows in set (0.01 sec)

S:

select * from x;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.00 sec)

主從上的表記錄本來就不一致了,主上缺少了 id= 1 的記錄。

此時從上的 slave_exec_mode 為默認的 STRICT 模式:

show variables like  slave_exec_mode 
+-----------------+--------+
| Variable_name | Value |
+-----------------+--------+
| slave_exec_mode | STRICT |
+-----------------+--------+
1 row in set (0.00 sec)

M 上的 binlog 模式為:

show variables like  binlog_format  +---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)

在 M 上執行:

insert into x values(1),(4),(5);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0

因為從上已經存在了 id= 1 的記錄,此時從的復制就報了 1062 的錯誤:

Last_SQL_Errno: 1062
Last_SQL_Error: Could not execute Write_rows event on table dba_test.x; Duplicate entry  1  for key  PRIMARY , Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event s master log mysql-bin-3306.000006, end_log_pos 7124

出現這個錯誤時,大家的一致做法就是執行:sql_slave_skip_counter=N。

1、set global sql_slave_skip_counter= N 中的 N 是指跳過 N 個 event
2、最好記的是 N 被設置為 1 時,效果跳過下一個事務。3、跳過第 N 個 event 后,位置若剛好落在一個事務內部,則會跳過這整個事務
4、一個 insert/update/delete 不一定只對應一個 event,由引擎和日志格式決定 

sql_slave_skip_counter 的單位是“event”,很多人認為該參數的單位是“事務”,其實是錯誤的,因為一個事務里包含了多個 event,跳過 N 個可能還是在同一個事務當中。對于上面出現 1062 的錯誤,把 N 設置成 1~4 效果是一樣的,都是跳過一個事務。因為執行的 SQL 生成了 4 個 event:

show binlog events in  mysql-bin-3306.000006  from 6950;
+-----------------------+------+------------+-----------+-------------+---------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-----------------------+------+------------+-----------+-------------+---------------------------------+
| mysql-bin-3306.000006 | 6950 | Query | 169 | 7026 | BEGIN |
| mysql-bin-3306.000006 | 7026 | Table_map | 169 | 7074 | table_id: 707 (dba_test.x) |
| mysql-bin-3306.000006 | 7074 | Write_rows | 169 | 7124 | table_id: 707 flags: STMT_END_F |
| mysql-bin-3306.000006 | 7124 | Xid | 169 | 7155 | COMMIT /* xid=74803 */ |
+-----------------------+------+------------+-----------+-------------+---------------------------------+
4 rows in set (0.00 sec)

所以處理該錯誤的方法有:

1:skip_slavesql_slave_skip_counter

stop slave; Query OK, 0 rows affected (0.00 sec)
set global sql_slave_skip_counter=[1-4];
Query OK, 0 rows affected (0.00 sec)
start slave;
Query OK, 0 rows affected (0.00 sec)

2:在配置文件里指定 slave-skip-errors=1062(需要重啟)

這 2 種方法都能讓復制恢復正常,但是會讓主從數據不一致(謹慎使用),讓從庫丟失了 id= 4 和 5 的記錄。并且第 2 種方法還需要重啟數據庫,這時本文介紹的 slave_exec_mode 參數就派上用場了。在從庫上設置該參數:

set global slave_exec_mode= IDEMPOTENT 
Query OK, 0 rows affected (0.00 sec)
stop slave; Query OK, 0 rows affected (0.00 sec)
start slave;
Query OK, 0 rows affected (0.00 sec)

同樣在主上執行:

insert into x values(1),(4),(5);

可以驚喜的發現主從數據是同步的,沒有出現復制異常:

M:select * from x; +----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.00 sec)
select * from x; +----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.01 sec)

上面的測試可以看到,參數設置成 slave_exec_mode= IDEMPOTENT 后,可以跳過出一個錯誤的 event。

② 1032 錯誤:Could not execute … event on table db.x; Can t find record in x , Error_code: 1032;

這個錯誤的出現是因為 ROW 模式下的復制,對數據的一致性有了很嚴的要求

主從上的測試表結構:

CREATE TABLE `x` ( `id` int(11) NOT NULL AUTO_INCREMENT,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

主從上的表記錄:

M:

select * from x; +----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.00 sec)

S:

select * from x;
+----+
| id |
+----+
| 1 |
| 3 |
+----+
2 rows in set (0.00 sec)

主從上的表記錄本來就不一致了,從上缺少了 id= 2 的記錄。此時從上的 slave_exec_mode 為默認的 STRICT 模式:

show variables like  slave_exec_mode 
+-----------------+--------+
| Variable_name | Value |
+-----------------+--------+
| slave_exec_mode | STRICT |
+-----------------+--------+
1 row in set (0.00 sec)

M 上的 binlog 模式為:

show variables like  binlog_format  +---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)

在 M 上執行:

BEGIN;
INSERT INTO x SELECT 4;
DELETE FROM x WHERE id = 2;
INSERT INTO x SELECT 5;
COMMIT;

因為從上不存在了 id= 2 的記錄,此時從的復制就報了 1032 的錯誤:

Last_SQL_Errno: 1032
Last_SQL_Error: Could not execute Delete_rows event on table dba_test.x; Can t find record in  x , Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event s master log mysql-bin-3306.000006, end_log_pos 12102

同樣的,在上面測試中說明的 2 種方法可以讓復制正常,但是數據也一樣會丟失。丟失了 id= 4 和 5 的記錄,繼續在從庫上設置該參數:

set global slave_exec_mode= IDEMPOTENT 
Query OK, 0 rows affected (0.00 sec)
stop slave; Query OK, 0 rows affected (0.00 sec)
start slave;
Query OK, 0 rows affected (0.00 sec)

在 M 上執行同樣的操作:

BEGIN;
INSERT INTO x SELECT 4;
DELETE FROM x WHERE id = 2;
INSERT INTO x SELECT 5;
COMMIT;

也可以驚喜的發現主從數據是同步的,沒有出現復制異常。

注意:slave_exec_mode= IDEMPOTENT 不能對 DDL 操作冪等,并且也不能對字段長度不同導致的錯誤進行冪等,如把例子中的從庫表的 id 字段類型 int 改成 bigint。并且只能在 binlog_format 為 ROW 的模式下使用,而且只能對 1032 和 1062 進行冪等模式。

總結:

對于上面的測試總結,針對 slave_exec_mode 參數,它可以跳過 1062 和 1032 的錯誤,并且不影響同一個事務中正常的數據執行。如果是多個 SQL 組成的事務,則可以跳過有問題的 event。

看著這個參數很不錯,但手冊上說明不建議在普通的復制環境中開啟。對于 NDB 以外的存儲引擎,只有在確定可以安全地忽略重復鍵錯誤和沒有鍵的錯誤時,才應使用 IDEMPOTENT 模式。這參數是專門針對 NBD Cluster 進行設計的,NBD Cluster 模式下,該參數只能設置成 IDEMPOTENT 模式。所以要根據自己的應用場景來決定,正常情況下,主從是一致的,有任何錯誤發生都要報錯,不過在做特殊處理時,可以臨時開啟。

另外在 GTID 模式下的復制,sql_slave_skip_counter 是不支持的,該模式下的復制可以自行測試。

以上是“MySQL 中 slave_exec_mode 參數的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注丸趣 TV 行業資訊頻道!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-04發表,共計5850字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 淮安市| 崇仁县| 阿鲁科尔沁旗| 习水县| 安化县| 濉溪县| 铜山县| 上栗县| 海安县| 建始县| 福建省| 吉水县| 阜康市| 视频| 和硕县| 蒙自县| 水城县| 祁东县| 监利县| 靖西县| 扶余县| 池州市| 蕲春县| 鹤峰县| 康定县| 江山市| 巍山| 盐城市| 霍州市| 彝良县| 迁西县| 天全县| 金昌市| 射阳县| 萍乡市| 凌源市| 龙里县| 冷水江市| 南澳县| 新巴尔虎右旗| 广平县|