一、MySQL主从原理

1、 主从形式

(1) 一主一从
(2) 主主复制
(3) 一主多从---扩展系统读取的性能,因为读是在从库读取的;
(4) 多主一从---5.7 开始支持
(5) 联级复制

2、 主从复制原理

MySQL主从复制
(1) Slave 服务器的执行 start slave,开启主从复制开关,产生 IO Thread 和 SQL Thread 线程。
(2)此时, Slave 服务器的 IO 线程会根据 master.info 文件的内容请求连接 Master 服务器,并请求 Master
服务器发送指定 binlog 日志文件的指定位置点之后的 binlog 日志。
(3) Master 服务器接收到 Slave 服务器的 IO 线程的请求后, Master 服务器首先进行验证,验证通过后负责复
制的 IO 线程根据 Slave 的 IO 线程请求读取指定的 binlog 日志文件的指定位置之后的 binlog 日志信息,连同本次
返回日志内容后在 Master 服务器上的新的 binlog 文件名以及下一个指定更新的位置点一起发送给 Slave 服务器的 IO
线程。
(4) Slave 服务器的 IO 线程接收到信息后,将 binlog 日志内容依次写入到中继日志(Relay Log)文件的最末
端(MySQL-relay-bin.xxxxxx),将将新的 binlog 文件名和位置记录到 master.info 文件中,以便一下次从新的
位置读取。
(5)Slave 服务器的 SQL 线程会实时检测到本地 Relay Log 中新增加的日志内容,如有更新,则及时把 Relay Log
文件中的内容解析为在 Master 上执行过的 SQL 语句,按顺序在 Slave 服务器上执行。并在应用完毕后清理应用过的日志。
(6) 经过上面步骤后,一般可以确保在 Master 和 Slave 上执行同样的 SQL 语句。在正常情况下可以保证 Master
和 Slave 上的数据完全一样。

二、总结主从复制步骤:

1、主库操作:

  • (1)开启binlog功能
    grep log-bin /data/3306/my.cnf
    log-bin = /data/3306/mysql-bin
  • (2)确保所有实例的server-id不同
egrep server-id /data/{3306,3307,3308}/my.cnf
#以上两个参数在[mysqld]下增加
  • (3)主库授权复制的用户rep
mysql -uroot -p123456 -S /data/3306/mysql.sock
grant replication slave on *.* to rep@'192.168.56.%' identified by "123456";
flush privileges;
select user,host from mysql.user;
show grants for rep@'192.168.56.%';
  • (4)锁表,查看binlog文件及位置点(--master-data=2)。
flush table with read lock;
show master status;
  • (5)新开窗口主库导出全备
mkdir /server/backup -p
mysqldump -uroot -p123456 -A -B --events -S /data/3306/mysql3306.sock |gzip > /server/backup/rep_bak_$(date +%F).sql.gz
ls -lrt /server/backup/
  • (6)解锁表,开放用户写入功能
unlock table;

2、从库操作:

  • (1)确保所有实例的server-id不同
egrep "server-id" /data/{3306,3307,3308}/my.cnf
  • (2)把主库的全备导入到从库
    gzip -d /server/backup/rep_bak_2018-01-09.sql.gz
    mysql -uroot -p123456 -S /data/3307/mysql.sock </server/backup/rep_bak_2018-01-09.sql.gz
  • (3)找位置点,配置master.info
    mysql-bin.000138 |3320
    mysql>change master to,
    master_host='192.168.56.11',
    master_port=3306,
    master_user=rep,
    master_password='123456',
    master_log_file='mysql-bin.000138',
    master_log_pos=3320;
    find /data/3307/data/ -type f -name "*.info"
  • (4)开启slave开关
start slave;
show slave status\G
  • (5)测试
    主库创建库,从库查看是否存在

三、MySQL主从实战

主库操作:
(1)开启binlog功能
[root@linux-node2 ~]# grep log-bin /data/3306/my.cnf
log-bin = /data/3306/mysql-bin

(2)确保所有实例的server-id不同
[root@linux-node2 ~]# egrep server-id /data/{3306,3307}/my.cnf
/data/3306/my.cnf:server-id = 1
/data/3307/my.cnf:server-id = 23)主库授权复制的用户rep
[root@linux-node2 ~]# mysql -uroot -p123456 -S /data/3306/mysql3306.sock 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.12 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]> select user,host from mysq.user;
ERROR 1146 (42S02): Table 'mysq.user' doesn't exist
MySQL [(none)]> grant replication slave on *.* to rep@'192.168.56.%' identified by "123456";
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> select user,host from mysql.user;
+------+--------------+
| user | host         |
+------+--------------+
| root | 127.0.0.1    |
| rep  | 192.168.56.% |
| root | ::1          |
|      | linux-node2  |
| root | linux-node2  |
|      | localhost    |
| root | localhost    |
+------+--------------+
7 rows in set (0.00 sec)

MySQL [(none)]> show grants for rep@'192.168.56.%';
+---------------------------------------------------------------------------------------------------------------------------+
| Grants for rep@192.168.56.%                                                                                               |
+---------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'rep'@'192.168.56.%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
+---------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

(4)锁表,查看binlog文件及位置点
MySQL [(none)]> flush table with read lock;
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

(5)新开窗口主库导出全备
[root@linux-node2 mysql]# mkdir /server/backup -p
[root@linux-node2 mysql]# mysqldump -uroot -p123456 -A -B --events -S /data/3306/mysql3306.sock |gzip > /server/backup/rep_bak_$(date +%F).sql.gz
[root@linux-node2 mysql]# ll /server/backup/
总用量 160
-rw-r--r-- 1 root root 160789 19 16:42 rep_bak_2018-01-09.sql.gz

(6)主库解锁表,开放用户写入功能
MySQL [(none)]> unlock table;

从库操作:
(1)把主库的全备导入到从库
[root@linux-node2 mysql]# gzip -d /server/backup/rep_bak_2018-01-09.sql.gz 
[root@linux-node2 mysql]# mysql -uroot -p654321 -S /data/3307/mysql3307.sock < /server/backup/rep_bak_2018-01-09.sql 
[root@linux-node2 mysql]# mysql -uroot -p654321 -S /data/3307/mysql3307.sock
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.12 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]> 
MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| student            |
| test               |
+--------------------+
5 rows in set (0.00 sec)

MySQL [(none)]> use student;
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 [student]> show tables;
+-------------------+
| Tables_in_student |
+-------------------+
| test              |
+-------------------+
1 row in set (0.00 sec)

MySQL [student]> select * from test;
+----+--------------+-----+
| id | name         | age |
+----+--------------+-----+
|  1 | gaoyuliang   |  60 |
|  2 | gaoxiaoqin   |  30 |
|  3 | chenhai      |  40 |
|  4 | houliangping |  40 |
+----+--------------+-----+
4 rows in set (0.00 sec)

(2)找位置点,配置master.info
MySQL [(none)]> change master to master_host='192.168.56.12',master_user='rep',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=120,master_port=3306;
Query OK, 0 rows affected, 2 warnings (0.04 sec)

(3)开启slave开关
MySQL [(none)]> start slave;
Query OK, 0 rows affected (0.04 sec)

MySQL [(none)]> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.12
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 120
               Relay_Log_File: linux-node2-relay-bin.000002
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000001
             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: 120
              Relay_Log_Space: 462
              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: 88efb286-f50f-11e7-9631-000c29876389
             Master_Info_File: /data/3307/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           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
1 row in set (0.00 sec)

(4)测试
主库创建course库,和test表插入,并在从库上查看是否同步。
MySQL [student]> create database course;
Query OK, 1 row affected (0.00 sec)

MySQL [student]> insert into test values(5,"lili",10);
Query OK, 1 row affected (0.01 sec)

MySQL [student]> select * from test;
+----+--------------+-----+
| id | name         | age |
+----+--------------+-----+
|  1 | gaoyuliang   |  60 |
|  2 | gaoxiaoqin   |  30 |
|  3 | chenhai      |  40 |
|  4 | houliangping |  40 |
|  5 | lili         |  10 |
+----+--------------+-----+
5 rows in set (0.00 sec)

四、 主从复制原理要点

1)异步方式同步
(2) 逻辑同步模式(binlog 有三种模式: SQL、混合、 rowlevel),默认是通过 SQL 语句执行
(3)主库通过记录 binlog 实现对从库的同步
(4)主库 1 个线程(IO 线程),从库 2 个线程(IO 和 SQL)来完成
(5)从库的关键文件: master.info、 relay-log、 relay-info
(6)如果从库还想级联从库,需打开 log-bin 和 log-slave-updates 参数

五、生产场景快速配置 MySQL 主从复制的方案

(1)安装好要配置从库的数据库,配置好 log-bin 和 server-id 参数。
(2)无需配置主库的 my.cnf 文件,主库的 log-bin 和 server-id 参数默认就是配置好的。
(3)登陆主库增加用于从库连接的帐户,并授 replication slave 的权限。
(4)半夜使用 mysqldump 带--master-data=1 参数全备主库,并在从库进行恢复。
(5)在从库执行 change master to 语句,无需 binlog 文件及对应位置点。
(6)在从库开启同步开关 start slave。
(7)从库 show slave status\G,检查同步状态,并在主库进行更新测试。

tips:
(1)主从库服务器的配置差距不要太大。
(2)撰写方案文档和实施步骤。如可能需要停机维护,需要事先申请停机维护时间