目录
一、主从复制的必要性
随着业务的增加,如果单单靠一台服务器的话,负载过重,就容易造成宕机。MySQL 本身就自带有一个主从复制的功能,可以帮助我们实现负载均衡和读写分离。
对于主服务器(Master)来说,主要负责写,从服务器(Slave)主要负责读,这样的话,就会大大减轻压力,从而提高效率。
二、主从复制原理
以MySQL一主两从架构为为例:一个master节点下有两个slave节点,在这套架构下,写操作统一交给master节点,读请求交给两个slave节点处理。
为了保证master节点和slave节点数据一致,在master节点写入数据后,会同时将数据复制到对应的slave节点。主从复制数据的过程中会用到三个线程,master节点上的binlog dump线程,slave节点的I\O线程和SQL线程。
小结:主从复制:就是从服务器要同步主服务器的“日志”,并且执行日志中的记录到自己的从服务器数据库中。
三、主从复制过程
MySQL 的主从复制工作过程大致如下:
主体:
两日志:二进制日志(主服务器上)、中继日志(从服务器上)
三线程:dump线程(主服务器上)、I/O线程(从服务器上)、SQL线程(从服务器上)
解析:
①当主服务的二进制日志发生变化时,此时,在主服务器上处于监听状态的dump线程,会把更新的二进制日志打包给I/O线程。
② 从服务器上的I/O线程一直监听着dump线程。并像主服务器暴露从服务器的日志位置、超时时间等信息。
当I/O线程接收到DUMP线程的更新时,会把更新的内容写入到从服务器的中继日志中。
③中继日志的更新内容会被SQL线程捕捉到,然后会被写入到slave服务器中。
小结:
master上的dump线程作用:监听主服务器二进制日志状态;
记录I/O线程对应的slave位置
同步二进制日志更新内容到I/O线程
I/O线程的作用:
监听master的dump线程
将slave信息发送给主服务器,包括从服务器的位置、日志的记录位置、超时时间......
接收master的dump线程传递过来的更新信息
将更新内容写入中继日志中
SQL线程作用:
监听中继日志
将中继日志中的更新内容写入到自己的数据库中,尽量保持主从服务器数据一致性
四、MySQL主从复制实验搭建
1、实验准备3台虚拟机均安装MySQL
主机名 | IP地址 |
zwb_mysql_master | 192.168.159.68 |
zwb_mysql_slave1 | 192.168.159.11 |
zwb_mysql_slave2 | 192.168.159.10 |
2、主从服务区器时间同步
三台服务器都要执行时间同步的操作
[root@zwb_nginx_mysql3 ~]# yum -y install ntp
[root@zwb_nginx_mysql3 ~]# ntpdate ntp.aliyun.com ## 时间同步,找个时间同步参考点,尽
量保持时间的一致性
[root@zwb_mysql_slave2 ~]# crontab -e ## 建立一个时间同步的周期性任务
no crontab for root - using an empty one
*/10 * * * * /usr/sbin/ntpdate ntp.aliyun.com
3、master服务器开启二进制日志
重启数据库
[root@zwb_mysql_master ~]# systemctl restart mysqld.service
[root@zwb_mysql_master ~]# netstat -antp | grep 3306
tcp6 0 0 :::3306 :::* LISTEN 10972/mysqld
4、提权grant;用于主从对接
## 提权
mysql> grant replication slave on *.* to 'myslave'@'192.168.159.%' identified by 'abc123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
## 刷新
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status; ## 显示当前位置为604
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 604 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
5、 开启从服务器功能
5.1、slave1服务器配置
重启:
systemctl restart mysqld.service
在slave1上配置:
mysql> change master to master_host='192.168.159.68',master_user='myslave',master_password='abc123',master_log_file='master-bin.000001',master_log_pos=604;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave; ### 开启slave
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.159.68
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 604
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 321
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Yes ###两个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: 604
Relay_Log_Space: 526
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: 9517b872-3764-11ed-bf4f-000c2966d92f
Master_Info_File: /usr/local/mysql/data/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:
1 row in set (0.00 sec)
5.2、slave2服务器配置
重启:
systemctl restart mysqld.service
在slave2上配置:
mysql> change master to master_host='192.168.159.68',master_user='myslave',master_password='abc123',master_log_file='master-bin.000001',master_log_pos=604;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave; ### 开启slave
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.159.68
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 604
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 321
Relay_Master_Log_File: master-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: 604
Relay_Log_Space: 526
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: 9517b872-3764-11ed-bf4f-000c2966d92f
Master_Info_File: /usr/local/mysql/data/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:
1 row in set (0.00 sec)
6、验证
在master 上创建zhuchongfuzhi数据库;
mysql> show databases; ## 查看当前数据库服务器的所以数据库
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database zhuchongfuzhi; ## 创建数据库名为zhuchongfuzhi
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| zhuchongfuzhi |
+--------------------+
5 rows in set (0.00 sec)
在slave1上查看当前服务器上的所有数据库
mysql> show databases; ## 查看所有数据库
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| zhuchongfuzhi | ## 已经同步存在
+--------------------+
5 rows in set (0.00 sec)
在slave2上查看当前服务器上的所有数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| zhuchongfuzhi | ## 已同步存在
+--------------------+
5 rows in set (0.00 sec)