Mysql主從同步延遲發(fā)生
現(xiàn)象:
Show slave status\G;
Relay_Master_Log_File: mysql_bin.002597
.
Exec_Master_Log_Pos: 645248292
.
Seconds_Behind_Master: 2447
.
Slave_SQL_Running_State: Reading event from the relay log
pos一直保持不變,并且behind一直在增加,
備庫執(zhí)行:
Show processlist;
SQL thread State列狀態(tài)如下:
Reading event from the relay log
代表 線程已經(jīng)從中繼日志讀取一個事件夹界,可以對事件進行處理了嘁捷。
查看binlog:
/home/mysql/mysql3502/bin/mysqlbinlog --start-position="645248292" --base64-output=decode-rows -v ./mysql_bin.002597 >mysqlbinlog.log
vi mysqlbinlog.log
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 645248292
#170226 2:28:35 server id 5123502 end_log_pos 645248340 CRC32 0x081bbaca GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '5c580bf9-0161-4e14-943b-751a3a09508b:5817253'/*!*/;
# at 645248340
.
.
BEGIN
/*!*/;
# at 645248419
#170226 2:28:35 server id 5123502 end_log_pos 645248550 CRC32 0xbf8a6c8c Table_map: `****`.`****` mapped to number 41501
# at 645248550
#170226 2:28:35 server id 5123502 end_log_pos 645256612 CRC32 0x7c9e1837 Delete_rows: table id 41501
# at 645256612
#170226 2:28:35 server id 5123502 end_log_pos 645264682 CRC32 0xa1e4d6e7 Delete_rows: table id 41501
# at 645264682
#170226 2:28:35 server id 5123502 end_log_pos 645272881 CRC32 0xa1d560d0 Delete_rows: table id 41501
# at 645272881
#170226 2:28:35 server id 5123502 end_log_pos 645281037 CRC32 0x6e9df23b Delete_rows: table id 41501
# at 645281037
#170226 2:28:35 server id 5123502 end_log_pos 645289102 CRC32 0x8bb31581 Delete_rows: table id 41501
# at 645289102
#170226 2:28:35 server id 5123502 end_log_pos 645297192 CRC32 0xcc940bb0 Delete_rows: table id 4150
.
.
### DELETE FROM `****`.`****`
### WHERE
### @1=****
### @2=****
### @3=****
### @4=****
### @5=****
### @6=****
### @7=****
### @8=****
### DELETE FROM `****`.`****`
### WHERE
### @1=****
### @2=****
### @3=****
### @4=****
### @5=****
### @6=****
### @7=****
### @8=****
.
.
查看表結(jié)構(gòu)發(fā)現(xiàn)沒有主鍵和索引窖逗。
mysql> show create table `****`.`****`\G;
*************************** 1. row ***************************
Table: ****
Create Table: CREATE TABLE `****` (
`uuid` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`loginname` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
****
****
****
`edittime` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
延遲發(fā)生原因:
首先mysql主從是基于行的復(fù)制累奈。
舉例解釋下什么是基于行的復(fù)制,假設(shè)主庫執(zhí)行以下sql刪除了表A中的100條數(shù)據(jù):
delete from a where id<101彻桃;
這時mysql會把這個SQL按照每條記錄坛善,拆分成100條delete SQL在備庫上執(zhí)行,mysql這么做的目的也是最大程度的保證同步數(shù)據(jù)的可靠性邻眷。
但是可靠性的提升伴隨而來的便是日志量的增多眠屎,同步過程會占用大量帶寬。
其次肆饶,該表即無主鍵改衩,也沒有索引。
假設(shè)還是以上對A表的刪除操作驯镊,拆成的100條delete SQL傳遞并且在備庫執(zhí)行葫督,因為表即無主鍵竭鞍,也沒有索引,所以每執(zhí)行一次都要做全表掃描才能定位到要刪除的那一條數(shù)據(jù)橄镜,可想而知同步效率會低很多偎快。
解決方案:
1 表設(shè)計時就要有主鍵;
2 如果延遲已經(jīng)發(fā)生洽胶,并且表不是特別大的情況下晒夹,在備庫上為該表創(chuàng)建索引或是主鍵。