mysql 主从复制

Posted honeycomb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 主从复制相关的知识,希望对你有一定的参考价值。

mysql复制允许将主实例(master)上的数据同步到一个或多个从实例(slave)上,默认情况下复制是异步进行的,从库也不需要一直连接到主库来同步数据
MySQL复制的数据粒度可以是主实例上所有的数据库,也可以是指定的一个或多个数据库,也可以是一个数据库里的指定的表
MySQL复制所带来的优势在于:
• 扩展能力:通过复制功能可以将MySQL的性能压力分担到一个或多个slave上。这要求所有 的写操作和修改操作都必须在Master上完成,而读操作可以被分配到一个或多个slave上。 将读写分离到不同服务器执行之后,MySQL的读写性能得到提升
• 数据库备份:由于从实例是同步主实例的数据,所以可以将备份作业部署到从库
• 数据分析和报表:同样,一些数据分析和报表的实现可以在从实例执行,以减少对主库的性能影响
• 容灾能力:可以在物理距离较远的另一个数据中心建立一个slave,保证在主实例所在地区遭遇灾难时,在另一个数据中心能快速恢复;

MySQL复制有两种方法:
• 传统方式:基于主库的bin-log将日志事件和事件位置复制到从库,从库再加以 应用来达到主从同步的目的
• Gtid方式:global transaction identifiers是基于事务来复制数据,因此也就不依赖日志文件位置,同时又能更好的保证主从库数据一致性
MySQL复制有多种类型:
• 异步复制:一个主库,一个或多个从库,数据异步同步到从库
• 同步复制:在MySQL Cluster中特有的复制方式
• 半同步复制:在异步复制的基础上,确保任何一个主库上的事务在提交之前至 少有一个从库已经收到该事务并日志记录下来
• 延迟复制:在异步复制的基础上,人为设定主库和从库的数据同步延迟时间,即保证数据延迟至少是这个参数

复制的工作原理是数据库修改事件记录到bin log中并传递到slave,然后slave在本地还原的过程。而事件记录到bin log的格式会有所不同。
MySQL复制有三种核心格式
• 基于语句的复制(statement based replication):基于主库将SQL语句写入到 bin log中完成复制
• 基于行数据的复制(row based replication):基于主库将每一个行数据变化的信息作为事件写入到bin log中完成日志
• 混合复制(mixed based replication):上述两者的结合。默认情况下优先使用基于语句的复制,只有当部分语句如果基于语句复制不安全的情况下才会自动切换为基于行数据的复制

主库
mysql> show variables like %binlog_format%;                                                                                              
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.01 sec)

mysql> show variables like %log_bin%;
+---------------------------------+------------------------------------+
| Variable_name                   | Value                              |
+---------------------------------+------------------------------------+
| log_bin                         | ON                                 |
| log_bin_basename                | /usr/local/mysql/data/binlog       |
| log_bin_index                   | /usr/local/mysql/data/binlog.index |
| log_bin_trust_function_creators | OFF                                |
| log_bin_use_v1_row_events       | OFF                                |
| sql_log_bin                     | ON                                 |
+---------------------------------+------------------------------------+
6 rows in set (0.01 sec)
主库和每个从库都必须有一个唯一ID,server_id;
mysql> show variables like %server_id%;
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| server_id      | 1     |
| server_id_bits | 32    |
+----------------+-------+
2 rows in set (0.01 sec)

从库1和2配置相同

从库
mysql> show variables like ‘%log_bin%‘;
+---------------------------------+------------------------------------+
| Variable_name                   | Value                              |
+---------------------------------+------------------------------------+
| log_bin                         | ON                                 |
| log_bin_basename                | /usr/local/mysql/data/binlog       |
| log_bin_index                   | /usr/local/mysql/data/binlog.index |
| log_bin_trust_function_creators | OFF                                |
| log_bin_use_v1_row_events       | OFF                                |
| sql_log_bin                     | ON                                 |
+---------------------------------+------------------------------------+
6 rows in set (0.03 sec)

mysql> show variables like ‘%server_id%‘;
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| server_id      | 2     |
| server_id_bits | 32    |
+----------------+-------+
2 rows in set (0.00 sec)


mysql>  show variables like ‘%binlog_format%‘; 
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

在主库创建一个专门用来做复制的数据库用户,这样所有从库都可以用这个用户来连接主库,也可以确保这个用户只有复制的权限虽然可以用任何拥有复制权限的MySQL用户来建立复制关系,但由于被使用的用户名和密码会明文保存在备库的master.info文件中,所以为安全起见,最好是使用仅有复制权限的独立用户

创建主从复制用户
主库
mysql> create user repl@192.168.204.% identified by mysql;
Query OK, 0 rows affected (0.12 sec)
mysql> grant replication slave on *.* to repl@192.168.204.%;
Query OK, 0 rows affected (0.07 sec)

mysql 基于binlog 复制,初始化方法1

主库上锁
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000008 |      709 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
主库
[[email protected] ~]# mysqldump --all-databases --master-data -u root -p > dbdump.db
Enter password: 
mysql> unlock tables; [[email protected]
~]# ls anaconda-ks.cfg dbdump.db mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz [[email protected] ~]# sftp -oPort=22 192.168.204.133 [email protected]192.168.204.133s password: Connected to 192.168.204.133. sftp> put dbdump.db Uploading dbdump.db to /root/dbdump.db dbdump.db 100% 906KB 905.8KB/s 00:00 从库导入 mysql> source dbdump.db; mysql> show databases; +--------------------+ | Database | +--------------------+ | A1 | | A2 | | course | | course2 | | course3 | | course4 | | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 10 rows in set (0.01 sec)

方法2

拷文件的方式
主库和从库都关闭
主库
[[email protected] ~]# /etc/init.d/mysql.server stop
Shutting down MySQL..... SUCCESS! 
[[email protected] ~]# cd /usr/local/mysql/data/
[[email protected] data]# cd ..
[[email protected] mysql]# tar -zcvf data.tar.gz ./data/
[[email protected] mysql]# sftp -oPort=22 [email protected]192.168.204.133
[email protected]192.168.204.133s password: 
Permission denied, please try again.

[email protected]192.168.204.133s password: 
Connected to 192.168.204.133.
sftp> lls
bin  data  data.tar.gz    docs  include  lib  LICENSE  LICENSE.router  man  README  README.router  share    support-files
sftp> put data.tar.gz
Uploading data.tar.gz to /root/data.tar.gz
data.tar.gz                                                                                                                           100% 5594KB   5.5MB/s   00:00    
sftp> 
从库
[[email protected] mysql]# mv data data_bak
[[email protected] mysql]# tar xf data.tar.gz 
[[email protected] mysql]# ll
总用量 6080
drwxr-xr-x.  2 mysql mysql    4096 2月  17 10:05 bin
drwxr-xr-x. 12 mysql mysql    4096 3月  30 14:32 data
drwxr-xr-x.  6 mysql mysql    4096 3月  30 19:25 data_bak
-rw-r--r--.  1 mysql mysql 5751938 3月  30 14:42 data.tar.gz
drwxr-xr-x.  2 mysql mysql      82 2月  17 10:05 docs
drwxr-xr-x.  3 mysql mysql    4096 2月  17 10:04 include
drwxr-xr-x.  6 mysql mysql    4096 2月  17 10:05 lib
-rw-r--r--.  1 mysql mysql  335809 10月  7 16:44 LICENSE
-rw-r--r--.  1 mysql mysql  101807 10月  7 16:44 LICENSE.router
drwxr-xr-x.  4 mysql mysql      28 2月  17 10:04 man
-rw-r--r--.  1 mysql mysql     687 10月  7 16:44 README
-rw-r--r--.  1 mysql mysql     700 10月  7 16:44 README.router
drwxr-xr-x. 28 mysql mysql    4096 2月  17 10:05 share
drwxr-xr-x.  2 mysql mysql      86 2月  17 10:14 support-files
[[email protected] mysql]# cd data
[[email protected] data]# rm auto.cnf -f

创建主从关系

[[email protected] data]# /etc/init.d/mysql.server start
mysql> 
mysql> CHANGE MASTER TO
    -> MASTER_HOST=192.168.204.132,
    -> MASTER_PORT=3306,
    -> MASTER_USER=repl,
    -> MASTER_PASSWORD=mysql,
    -> MASTER_LOG_FILE=binlog.000008,
    -> MASTER_LOG_POS=709;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.02 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.204.132
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000009
          Read_Master_Log_Pos: 155
               Relay_Log_File: centos7-relay-bin.000003
                Relay_Log_Pos: 363
        Relay_Master_Log_File: binlog.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 155
              Relay_Log_Space: 737
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: e30d70f7-325a-11e9-811b-000c2940fa33
             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: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)
mysql> stop slave;
Query OK, 0 rows affected (0.03 sec)

创建主从复制报错

主从复制保错
Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; 
Last_IO_Error: error connecting to master [email protected]:3306 - retry-time: 60  retries: 1
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: Could not find first log file name in binary log index file

重置主从关系
主库操作
mysql> stop slave;
mysql> reset slave all;

如果主库不能锁表,主库上有业务操作

模拟操作
mysql> use A1;
mysql> delimiter //
mysql> create procedure proc1()
    -> begin
    -> declare n int default 1;
    -> while n<=20000 do
    -> insert into temp values(n,mike);
    -> set n=n+1;
    -> end while;
    -> end;
    -> //
mysql> delimiter ;
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000009 |     1158 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> create table temp(id int,name varchar(20));
Query OK, 0 rows affected (0.03 sec)

mysql> call proc1();
Query OK, 1 row affected (2 min 10.79 sec)

错误的方式创建主从关系

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000009 |  5642155 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> call proc1();
Query OK, 1 row affected (31.77 sec)


[[email protected] ~]# mysqldump --all-databases --master-data -u root -p > dbdump.db
Enter password: 
mysql> select count(*) from temp;
+----------+
| count(*) |
+----------+
|    20000 |
+----------+
1 row in set (0.02 sec)
[[email protected] ~]# sftp -oPort=22 192.168.204.133
[email protected]192.168.204.133s password: 
Connected to 192.168.204.133.
sftp> put dbdump.db 
Uploading dbdump.db to /root/dbdump.db
dbdump.db                                                                                                                                                                      100%  965KB 964.6KB/s   00:00    
sftp> 

从库
mysql> source dbdump.db
mysql> CHANGE MASTER TO
    -> MASTER_HOST=192.168.204.132,
    -> MASTER_PORT=3306,
    -> MASTER_USER=repl,
    -> MASTER_PASSWORD=mysql,
    -> MASTER_LOG_FILE=binlog.000009,
    -> MASTER_LOG_POS=5642155;
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> start slave;
Query OK, 0 rows affected (0.10 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.204.132
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000009
          Read_Master_Log_Pos: 11282155
               Relay_Log_File: centos7-relay-bin.000002
                Relay_Log_Pos: 3577207
        Relay_Master_Log_File: binlog.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 9219043
              Relay_Log_Space: 5640529
              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: 124
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: e30d70f7-325a-11e9-811b-000c2940fa33
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: waiting for handler commit
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

从库报错数据不一致

mysql> select count(*) from temp;
+----------+
| count(*) |
+----------+
|    24230 |
+----------+
1 row in set (0.01 sec)

mysql> select id,count(*) from temp group by id having count(*)>=2;
+------+----------+
| id   | count(*) |
+------+----------+
| 1794 |        2 |
| 1795 |        2 |
| 1796 |        2 |
| 1797 |        2 |
| 1798 |        2 |
| 1799 |        2 |
| 1800 |        2 |

正确方案

正确方案
主库操作
mysqldump --all-databases --master-data=2 -u root -p  > dbdump.db
mysqldump --all-databases --master-data=2 --single-transaction -u root -p >dbdump.db
vi dbdump.db  
CHANGE MASTER TO MASTER_LOG_FILE=‘binlog.000009‘, MASTER_LOG_POS=18811367;
从库操作
mysql> reset slave all;
Query OK, 0 rows affected (0.01 sec)

mysql> 
mysql> 
mysql> CHANGE MASTER TO
    -> MASTER_HOST=192.168.204.132,
    -> MASTER_PORT=3306,
    -> MASTER_USER=repl,
    -> MASTER_PASSWORD=mysql,
    -> MASTER_LOG_FILE=binlog.000009,
    -> MASTER_LOG_POS=18811367;
Query OK, 0 rows affected, 2 warnings (0.05 sec)

mysql> start slave;
Query OK, 0 rows affected (0.04 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.204.132
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000009
          Read_Master_Log_Pos: 22964381
               Relay_Log_File: centos7-relay-bin.000002
                Relay_Log_Pos: 2073019
        Relay_Master_Log_File: binlog.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 20884067
              Relay_Log_Space: 4153543
              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: 429
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: e30d70f7-325a-11e9-811b-000c2940fa33
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: waiting for handler commit
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

ERROR: 
No query specified
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| A1                 |
| A2                 |
| A3                 |
| course             |
| course2            |
| course3            |
| course4            |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
11 rows in set (0.00 sec)

mysql> use A1;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select count(*) from temp;
+----------+
| count(*) |
+----------+
|    20000 |
+----------+
1 row in set (0.01 sec)

第二个从节点创建主从关系方法同上

第二个从节点
[[email protected]-mysql-slave2 ~]# vi dbdump.db  #查看MASTER_LOG_FILE/MASTER_LOG_POS
[email protected]-mysql-slave2 ~]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.13 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
mysql> source dbdump.db

mysql> CHANGE MASTER TO  
    -> MASTER_HOST=10.0.0.200,  
    -> MASTER_PORT=3306,  
    -> MASTER_USER=repl,  
    -> MASTER_PASSWORD=mysql,  
    -> MASTER_LOG_FILE=binlog.000043,  
    -> MASTER_LOG_POS=7570317;
Query OK, 0 rows affected, 2 warnings (0.07 sec)

mysql> start slave;
Query OK, 0 rows affected (0.06 sec)
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.0.0.200
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000043
          Read_Master_Log_Pos: 11644030
               Relay_Log_File: oldboy-mysql-slave2-relay-bin.000002
                Relay_Log_Pos: 226135
        Relay_Master_Log_File: binlog.000043
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 7796133
              Relay_Log_Space: 4074254
              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: 2947
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: fc58cc2d-164b-11e9-95af-000c29129a95
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: waiting for handler commit
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

方法2 利用从库1

[[email protected] mysql]#/etc/init.d/mysql.server stop
[[email protected]-mysql-slave1 mysql]# tar -zcvf data.tar.gz data
data/
data/ibdata1
data/ib_logfile1
data/undo_001
data/undo_002
data/ib_logfile0
[[email protected]-mysql-slave1 mysql]# sftp [email protected]10.0.0.202
The authenticity of host 10.0.0.202 (10.0.0.202) cant be established.
ECDSA key fingerprint is SHA256:/yqIM0T3ZqFIt1SdWZb50q8qffjj7PbwKr+aLXFSw+4.
ECDSA key fingerprint is MD5:6c:33:8b:79:5b:b3:a6:5e:78:b8:e6:4f:47:bf:0b:07.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 10.0.0.202 (ECDSA) to the list of known hosts.
[email protected]10.0.0.202s password: 
Connected to 10.0.0.202.
sftp> put data.tar.gz
Uploading data.tar.gz to /root/data.tar.gz
data.tar.gz                                                          100%  285MB  27.7MB/s   00:10    
sftp> exit
二从节点
[[email protected]-mysql-slave2 mysql]# tar -zxvf data.tar.gz 
data/
data/ibdata1
data/ib_logfile1
data/undo_001
data/undo_002
data/ib_logfile0
data/#innodb_temp/
data/mysql.ibd
[[email protected]-mysql-slave2 data]# rm -rf auto.cnf 
[[email protected]-mysql-slave2 data]# /etc/init.d/mysql.server start
Starting MySQL.Logging to /data/mysql/mysql/data/oldboy-mysql-slave2.err.
.... SUCCESS! 
[[email protected]-mysql-slave2 data]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.13 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type help; or \h for help. Type \c to clear the current input statement.

mysql> 
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.0.0.200
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000043
          Read_Master_Log_Pos: 11644030
               Relay_Log_File: oldboy-mysql-slave1-relay-bin.000002
                Relay_Log_Pos: 4074032
        Relay_Master_Log_File: binlog.000043
             Slave_IO_Running: No
            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: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 11644030
              Relay_Log_Space: 0
              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: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: fc58cc2d-164b-11e9-95af-000c29129a95
             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: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)
我在这里就已经成功了

联级复制

从库打开log_slave_updates,主库修改数据会记录到从库的binlog中,用于从库之间做联级复制
mysql> show variables like "%log_slave_updates%";
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| log_slave_updates | ON    |
+-------------------+-------+
1 row in set (0.12 sec)

mysql> show variables like "%log_bin%";
+---------------------------------+------------------------------------+
| Variable_name                   | Value                              |
+---------------------------------+------------------------------------+
| log_bin                         | ON                                 |
| log_bin_basename                | /usr/local/mysql/data/binlog       |
| log_bin_index                   | /usr/local/mysql/data/binlog.index |
| log_bin_trust_function_creators | OFF                                |
| log_bin_use_v1_row_events       | OFF                                |
| sql_log_bin                     | ON                                 |
+---------------------------------+------------------------------------+
6 rows in set (0.00 sec)

[[email protected]-slave1 data]# mysqlbinlog -v binlog.000007 > abc.log
### INSERT INTO `test`.`dept2`
### SET
###   @1=1
###   @2=math
# at 895587
#190401 22:58:11 server id 1  end_log_pos 895618 CRC32 0xeff2d5c4       Xid = 531
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= AUTOMATIC /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET [email protected]_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

[[email protected]-slave1 data]# cat /etc/my.cnf
[mysqld]
server-id=2
log_slave_updates=1
replicate-do-db=test

replicate-do-db:该参数用来指定需要复制的数据库。在基于语句复制的环境中,指定该参数之后,则slave的SQL thread进程只会应用在本数据库下的对象相关的语句。如果有多个数据库需要复制,则这

个参数要使用多次。但如果是涉及到跨库操作语句,则复制会丢失;

[[email protected] data]# /etc/init.d/mysql.server restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL. SUCCESS! 
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.138.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000007
          Read_Master_Log_Pos: 1490
               Relay_Log_File: mysql-slave1-relay-bin.000006
                Relay_Log_Pos: 319
        Relay_Master_Log_File: binlog.000007
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: test
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1490
              Relay_Log_Space: 534
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 849ecaa5-3386-11e9-9db6-000c29c16499
             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: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

ERROR: 
No query specified

主库
mysql> use test;
Database changed
mysql> insert into dept2 values(3,chinese);
Query OK, 1 row affected (0.07 sec)

mysql> use course;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from test;
+------+-------+
| id   | name  |
+------+-------+
|    1 | houpj |
+------+-------+
1 row in set (0.00 sec)

mysql> insert into test values(2,wang);
Query OK, 1 row affected (0.07 sec)

从库 只有test库更新
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from dept2;
+------+---------+
| id   | name    |
+------+---------+
|    1 | history |
|    1 | math    |
|    3 | chinese |
+------+---------+
3 rows in set (0.00 sec)

mysql> use course;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from test;
+------+-------+
| id   | name  |
+------+-------+
|    1 | houpj |
+------+-------+
1 row in set (0.00 sec)

另一个基于SQL语句复制和基于行复制的区别在于当语句中包含对多个数据库的表进行
操作时。比如设置replicate-do-db=db1,
USE db1;
UPDATE db1.table1 SET col1 = 10, db2.table2 SET col2 = 20;
基于SQL语句的复制会将table1和table2都在备库修改,而基于行的复制只会在备库修改table1表

主库修改
[[email protected] ~]# cat /etc/my.cnf
[mysqld]
server-id=1
binlog-format=statement

mysql> use test;
Database changed
mysql> update course.test2 set name=jiaojiao;
Query OK, 2 rows affected (0.03 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> use course;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> update test.dept2 set name=pengju;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0
从库1
[[email protected]-slave1 ~]# cat /etc/my.cnf
[mysqld]
server-id=2
log_slave_updates=1
replicate-do-db=test

mysql> use test;
Database changed
mysql> select * from dept2;
+------+-------+
| id   | name  |
+------+-------+
|    1 | houpj |
|    1 | houpj |
|    3 | houpj |
+------+-------+
3 rows in set (0.00 sec)

mysql> use course;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
mysql> select * from test2;
+----+----------+
| id | name     |
+----+----------+
|  1 | jiaojiao |
|  2 | jiaojiao |
+----+----------+
2 rows in set (0.00 sec)

replicate-do-table=db_name.tbl_name:通过该参数告知slave的SQL thread仅复制指定表上的数据。如果有多个表,则该参数要使用多次replicate-wild-do-table=db_name.tbl_name:通过该参数告知SQL的SQL thread仅复制符合匹配的表,可以使用_和%作为通配符。比如replicate-wild-do-table=foo%.bar%表示复制以foo打头的数据库下所有bar打头的表数据。如果是replicate-wild-do-table=foo%.%,则表示即复制foo打头的所有表的数据,也复制create/drop/alter database foo打头的命令

主库
mysql> use test;
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| course         |
| dept           |
| dept2          |
| dept3          |
| students       |
| students2      |
| teacher        |
| teacher_backup |
+----------------+
8 rows in set (0.00 sec)

mysql> insert into dept3 values(1,english),(2,math),(3,miniso);
Query OK, 3 rows affected (0.10 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from dept2;
+------+-------+
| id   | name  |
+------+-------+
|    1 | houpj |
|    1 | houpj |
|    3 | houpj |
+------+-------+
3 rows in set (0.00 sec)

mysql> insert into dept2 values(1,english),(2,math),(3,miniso);
Query OK, 3 rows affected (0.04 sec)
Records: 3  Duplicates: 0  Warnings: 0
从库1
[[email protected]-slave1 mysql]# cat /etc/my.cnf
[mysqld]
server-id=2
log_slave_updates=1
replicate-do-table=test.dept3



mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| course         |
| dept           |
| dept2          |
| dept3          |
| students       |
| students2      |
| teacher        |
| teacher_backup |
+----------------+
8 rows in set (0.00 sec)
没变化
mysql> select * from dept2;
+------+-------+
| id   | name  |
+------+-------+
|    1 | houpj |
|    1 | houpj |
|    3 | houpj |
+------+-------+
3 rows in set (0.00 sec)
有变化
mysql> select * from dept3;
+------+---------+
| id   | name    |
+------+---------+
|    1 | english |
|    2 | math    |
|    3 | miniso  |
+------+---------+
3 rows in set (0.00 sec)

show processlist

在主库可以通过执行show processlist命令查看主库的bin log日志生成进程
mysql> show processlist\G;
*************************** 1. row ***************************
     Id: 4
   User: event_scheduler
   Host: localhost
     db: NULL
Command: Daemon
   Time: 4882
  State: Waiting on empty queue
   Info: NULL
*************************** 2. row ***************************
     Id: 14
   User: root
   Host: localhost
     db: test
Command: Query
   Time: 0
  State: starting
   Info: show processlist
*************************** 3. row ***************************
     Id: 17
   User: repl
   Host: 192.168.138.133:49137
     db: NULL
Command: Binlog Dump
   Time: 4653
  State: Master has sent all binlog to slave; waiting for more updates
   Info: NULL
*************************** 4. row ***************************
     Id: 21
   User: repl
   Host: 192.168.138.132:43994
     db: NULL
Command: Binlog Dump
   Time: 902
  State: Master has sent all binlog to slave; waiting for more updates
   Info: NULL
4 rows in set (0.00 sec)

在statement(sql)模式下实验主从一个表数据不一致的情况下复制是否还能继续

从库操作
mysql> delete from dept3;
Query OK, 3 rows affected (0.10 sec)

主库操作
mysql> select * from dept3;
+------+---------+
| id   | name    |
+------+---------+
|    1 | english |
|    2 | math    |
|    3 | miniso  |
+------+---------+
3 rows in set (0.00 sec)

mysql> insert into dept3 values(4,history);
Query OK, 1 row affected (0.06 sec)

从库状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.138.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000008
          Read_Master_Log_Pos: 2952
               Relay_Log_File: mysql-slave1-relay-bin.000016
                Relay_Log_Pos: 625
        Relay_Master_Log_File: binlog.000008
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 2952
              Relay_Log_Space: 1837
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 849ecaa5-3386-11e9-9db6-000c29c16499
             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: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

row模式

从库
mysql> select * from dept3;
+------+---------+
| id   | name    |
+------+---------+
|    4 | history |
+------+---------+
1 row in set (0.00 sec)


主库操作

mysql> select * from dept3;
+------+---------+
| id   | name    |
+------+---------+
|    1 | english |
|    2 | math    |
|    3 | miniso  |
|    4 | history |
+------+---------+
4 rows in set (0.00 sec)

mysql> delete from dept3 where id=1;
Query OK, 1 row affected (0.09 sec)
从库状态
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.138.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000009
          Read_Master_Log_Pos: 445
               Relay_Log_File: mysql-slave1-relay-bin.000019
                Relay_Log_Pos: 363
        Relay_Master_Log_File: binlog.000009
             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: 1032
                   Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 5 failed executing transaction ANONYMOUS at master log binlog.000009, end_log_pos 414. 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: 155
              Relay_Log_Space: 1032
              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: 1032
               Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 5 failed executing transaction ANONYMOUS at master log binlog.000009, end_log_pos 414. 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: 1
                  Master_UUID: 849ecaa5-3386-11e9-9db6-000c29c16499
             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: 190402 05:23:51
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

slave-skip-errors=[err_code1,err_code2,...|all|ddl_exist_errors]:该参数决定了当slave的SQL thread执行过程中碰到何种错误时可以忽略并继续接下来的数据复制。正常情况下当有错误发生时,复制会停止而需要人工干预修复才能继续进行。除非非常自信可以忽略某些错误,否则不要使用这个参数,不然会导致虽然复制执行正常,但其实内部的数据已经完全不一致;

跳过错误
[[email protected]-slave1 ~]# cat /etc/my.cnf
[mysqld]
server-id=2
log_slave_updates=1
slave-parallel-workers=5
slave-skip-errors=1050
重启mysql
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.138.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000009
          Read_Master_Log_Pos: 782
               Relay_Log_File: mysql-slave1-relay-bin.000006
                Relay_Log_Pos: 319
        Relay_Master_Log_File: binlog.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 782
              Relay_Log_Space: 1547
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 849ecaa5-3386-11e9-9db6-000c29c16499
             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: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

默认创建的MySQL复制是异步的,意味着主库将数据库修改事件写入到自己的bin log,而并不知道从库是否获取了这些事件并应用在自己身上。所以当主库崩溃导致要主从切换时,有可能从库上的数据不是最新的
从5.7版本开始MySQL通过扩展的方式支持了半同步复制当主库执行一个更新操作事务时,提交操作会被阻止直到至少有一个半同步的复制slave确认已经接收到本次更新操作,主库的提交操作才会继续
半同步复制的slave发送确认消息只会在本次更新操作记录已经记录到本地的relay log之后如果没有任何slave发送确认消息而导致超时时,半同步复制会转换成异步复制
半同步复制会对MySQL性能产生影响,因为主库的提交动作只有在收到至少一个从库的确认消息之后才能执行。但这个功能是性能和数据可靠性方面的权衡

主库master
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME semisync_master.so;
Query OK, 0 rows affected (0.19 sec)

mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW STATUS LIKE rpl_semi_sync%;
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.01 sec)
从库
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME semisync_slave.so;
Query OK, 0 rows affected (0.25 sec)

mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;
Query OK, 0 rows affected (0.01 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.11 sec)

mysql> start slave;
Query OK, 0 rows affected (0.05 sec)

从库
mysql>  STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.09 sec)


主库
mysql> update dept2 set name="haohan" where id=3;
Query OK, 2 rows affected (10.03 sec)
Rows matched: 2  Changed: 2  Warnings: 0
mysql> show status like rpl_semi_sync%;
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | OFF   |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.03 sec)
从库
mysql>  START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.03 sec)
主库
mysql> show status like rpl_semi_sync%;
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
从库2
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME semisync_slave.so;
Query OK, 0 rows affected (0.19 sec)

mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;
Query OK, 0 rows affected (0.01 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.05 sec)

mysql> start slave;
Query OK, 0 rows affected (0.05 sec)

mysql> show status like rpl_semi_sync%;
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 2     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

两个从库
slave1
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)
master 
mysql> insert into test2 values(3,houhou);
Query OK, 1 row affected (0.09 sec)
slave2
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)
master
mysql> insert into test2 values(4,qita);
Query OK, 1 row affected (10.16 sec)

延迟复制是指定从库对主库的延迟至少是指定的这个间隔时间,默认是0秒。可以通过change master to命令来指定
CHANGE MASTER TO MASTER_DELAY = N;其原理是从库收到主库的bin log之后,不是立即执行,而是等待指定的秒数之后再执行
延迟复制的使用场景比如:
确保在主库上被错误修改的数据能及时找回测试在从库IO集中在恢复bin log过程中对应用程序的访问影响保留一份若干天前的数据库状态,和当前状态可以做对比
show slave status中SQL_Delay值表明了设置的延迟时长

延迟复制
slave1
mysql> stop slave;
Query OK, 0 rows affected (0.09 sec)

mysql> CHANGE MASTER TO MASTER_DELAY = 60;
Query OK, 0 rows affected (0.07 sec)

mysql> start slave;
Query OK, 0 rows affected (0.10 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.138.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000009
          Read_Master_Log_Pos: 1366
               Relay_Log_File: mysql-slave2-relay-bin.000002
                Relay_Log_Pos: 319
        Relay_Master_Log_File: binlog.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1366
              Relay_Log_Space: 534
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 849ecaa5-3386-11e9-9db6-000c29c16499
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 60
          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: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

ERROR: 
No query specified
master
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000009 |     1366 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> insert into teacher_backup values(4,abc,5);
Query OK, 1 row affected (0.00 sec)

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000009 |     1667 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
从库
mysql> select * from teacher_backup;
+----+------+---------+
| id | name | dept_id |
+----+------+---------+
|  1 | abc  |       1 |
|  2 | abc  |       4 |
|  3 | abc  |       4 |
+----+------+---------+
3 rows in set (0.01 sec)
60s后
mysql> select * from teacher_backup;
+----+------+---------+
| id | name | dept_id |
+----+------+---------+
|  1 | abc  |       1 |
|  2 | abc  |       4 |
|  3 | abc  |       4 |
|  4 | abc  |       5 |
+----+------+---------+
4 rows in set (0.00 sec)

未完待续

以上是关于mysql 主从复制的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 主从复制与读写分离(原理深刻,过程详细,值得一看)

MySQL主从复制与读写分离

MySQL主从复制及读写分离实际部署与验证

MySQL主从复制及读写分离实际部署与验证

mysql实现主从复制/主从同步

MySQL主从复制以及读写分离(❤❤❤❤含理论和实验❤❤❤❤大家中秋快乐!㊗)