五、流程#
通过fileName和position完成定位,从库会向主库发送命令,BINLOG_DUMP
,命令中包含有positon和fileName, 主库获取到这些信息之后,指定name到指定position往从库发送bin-log
六、可能会遇到的问题#
6.1、问题一:#
change master时报错了
报错说:ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active.
原因是我之前使用过gtid进行同步数据,当时将master_auto_position设置成了1,再想使用手动指定position的主从同步方式需要得像下面这样,change回去。
CHANGE MASTER TO MASTER_AUTO_POSITION=0;
6.2、问题二:#
如果我随便写了个position再搭建主从时,会发生什么?
下面的 MASTER_LOG_POS = 1003 就是我随便写的一个position,然后你可以看到两个现象
- Slave_IO_Running : No
- Last_IO_Error 位置报了个严重的错误
mysql> CHANGE MASTER TO -> MASTER_HOST='10.157.23.xxx', -> MASTER_USER='mysqlsync', -> MASTER_PASSWORD='mysqlsync123', -> MASTER_PORT=8882, -> MASTER_LOG_FILE='mysql-bin.000008', -> MASTER_LOG_POS=1003; Query OK, 0 rows affected, 2 warnings (0.01 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Master_Host: 10.157.23.123 Master_User: mysqlsync Master_Port: 8882 Connect_Retry: 60 Master_Log_File: mysql-bin.000008 Read_Master_Log_Pos: 1003 Relay_Log_File: relay-log.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000008 Slave_IO_Running: No Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: mysql.%,test.% Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1003 Relay_Log_Space: 521 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: 1236 Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the first event 'mysql-bin.000008' at 1003, the last event read from './mysql-bin.000008' at 123, the last byte read from './mysql-bin.000008' at 1022.' Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2787871625 Master_UUID: a5f1d6b2-8f9a-11ea-8138-b8599f2ef058 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: 200529 10:22:46 Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: 00c755a6-7a07-11ea-8701-b8599f2ef058:33-222, 40efcb1b-7a1f-11ea-84ac-b8599f229b38:1-20, 7e2dcb21-7d3b-11ea-aa0c-b8599f2ef058:1-18, 9e6027f2-7ae9-11ea-ac13-b8599f2ef058:1409-7176, a5f1d6b2-8f9a-11ea-8138-b8599f2ef058:6-9:12-13:15, e90fdd54-7e04-11ea-8b23-b8599f2ef058:1-11 Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec)
6.3、问题三:#
假设我们有这样的场景:
场景:现在主库有7条数据,从库有5条数据,搭建主从时如何让从库从第六条开始同步?
这种情况仅仅是我们在做这种小实验,为啥这样说呢?如果是为线上的业务搭建搭建主从MySQL的话,大概率我们会清空主库然后再做同步。如果数据很重要,我们会对主库中的数据进行一次全量拷贝到从库(拷贝var包)。再做主从同步。
在线上的环境中,主从的数据是会强一致的,从库只会接受业务方的读流量,也许网络环境很恶劣从库同步的速度明显比主库写入到速度低,但是只要从库没有说跳过了某个binlog而少同步了某条记录,我们都可以认为它们是正常的主从同步。不会出现主从中断的情况。
线上的环境中什么情况下会出现主从中断呢?比如说,从库同步数据时,从库同步binlog时丢了一条数据,这时业务上突然来了条update语句,要更新数据,然后从库美滋滋的回放在主库dump过来的binlog时发现,竟然自己没有需要更新的这条记录,就会报错,这时为了业务止损,我们要在第一时间下线从库,然后去分析哪里出现问题了。
针对这个实验我们这样去binlog中查看第5,6条数据的position,然后在从库中使用相应的position完成主从数据的同步。
进入主库,通过下面的命令查看binlog
mysqlbinlog --no-defaults -vv --base64-output=decode-rows ../var/mysql-bin.000008 | less
找到了指定的binlog和指定的end_log_pos
比如从库中没有第10,11条数据,我们就能通过end_log_pos = postion = 1013完成定位。
CHANGE MASTER TO MASTER_HOST='10.157.23.158', MASTER_USER='mysqlsync', MASTER_PASSWORD='mysqlsync123', MASTER_PORT=8882, MASTER_LOG_FILE='mysql-bin.000008', MASTER_LOG_POS=1013;
开启同步,并查看状态
start slave; show slave status\G;
再去查看从库就能发现,从你指定的position开始往后和主库的数据保持同步的。
6.4、问题四:#
问:主从接流量的情况是怎样的?业务的CRUD请求是如何被主从平分消费的?
答:默认这种架构下是读写分离,也就是说,仅读流量会打到从库中
问:那如果我们在从库所在的机器上本地登陆,然后手动执行删除的操作能成功吗?
答:是的,可以执行成功。
问:我可以简单粗暴的限制从库仅读吗?
答:可以的,像下面这样
mysql> show variables like '%read_only%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_read_only | OFF | | read_only | OFF | | super_read_only | OFF | | transaction_read_only | OFF | | tx_read_only | OFF | +-----------------------+-------+ 5 rows in set (0.00 sec) set global read_only=0; #关闭只读,可以读写 set global read_only=1; #开始只读模式
6.5、问题五:#
假设主库中有1~7 共7条数据,从库中有1~5五条数据。也就是说,主库从库中前五条数据一样,但是主库比从库多了两条新数据。
这时我们搭建主从同步时搞一搞事情,重复这个动作:在从库断开同步,然后查到主库第一个binlog中的数据的记录,确定我们要查找的position,再重新构建主从环境。观察一下从库这边数据的同步情况,以及会出现什么问题?从库这边的数据会成为double吗?
答:数据不会double的
6.6、问题六:#
假设从库执行changemaster时,主库MASTER_HOST填错了:
在查看slave 状态时,我们可以看到Last_IO_Error列有报错提示: error connecting to master
mysql> CHANGE MASTER TO -> MASTER_HOST='10.157.23.158', -> MASTER_USER='mysqlsync', -> MASTER_PASSWORD='mysqlsync123', -> MASTER_PORT=8882, -> MASTER_LOG_FILE='mysql-bin.000008', -> MASTER_LOG_POS=1013; Query OK, 0 rows affected, 2 warnings (0.01 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Connecting to master Master_Host: 10.157.23.123 Master_User: mysqlsync Master_Port: 8882 Connect_Retry: 60 Master_Log_File: mysql-bin.000008 Read_Master_Log_Pos: 1003 Relay_Log_File: relay-log.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: mysql-bin.000008 Slave_IO_Running: Connecting Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: mysql.%,test.% Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1003 Relay_Log_Space: 154 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: 2003 Last_IO_Error: error connecting to master 'mysqlsync@10.157.23.123:8882' - retry-time: 60 retries: 1 Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 0 Master_UUID: Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: 200529 10:13:34 Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: 00c755a6-7a07-11ea-8701-b8599f2ef058:33-222, 40efcb1b-7a1f-11ea-84ac-b8599f229b38:1-20, 7e2dcb21-7d3b-11ea-aa0c-b8599f2ef058:1-18, 9e6027f2-7ae9-11ea-ac13-b8599f2ef058:1409-7176, a5f1d6b2-8f9a-11ea-8138-b8599f2ef058:6-9:12-13:15, e90fdd54-7e04-11ea-8b23-b8599f2ef058:1-11 Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version:
6.7、问题七:#
假设这种场景:假设主从现在的数据是一致的,然后你在从库所在的机器上本地登陆,然后手动删除一条,再从主库写入数据,那从库还能同步成功吗?
答:从库依然会同步成功,但是其实这时候已经算是事故了,主从数据不一致,万一业务打来一条sql刚好使用你删的数据,那就会报错。