MySQL主从复制概念
Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
注:在进行mysql复制时,所有对复制中的表的更新必须在主服务器上进行。否则必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
MySQL主从复制原理
(1)MySQL支持复制类型
- 基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时,会自动选着基于行的复制。
- 基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
- 混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
(2)MySQL主从复制过程
- MySQL主从复制基本流程图:
复制过程详解:
- 1、在每个事物更新数据完成之前,master主服务器在二进制日志记录这些改变,写入二进制日志完成后,master通知存储引擎提交事物。
- 2、slave将master主服务器的二进制日志Binary log 复制到其中继日志Relay log,首先slave(从服务器)开始一个工作线程——I/O线程,I/O线程在master上打开一个普通的连接,然后开始Binlog dump process,该进程从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件,而I/O线程将这些事件写入中继日志。
- 3、SQLslave thread(SQL从线程)处理该过程的最后一步,SQL线程从中继日志中读取事件,并重放其中的事件而更新salve数据,使其与master中数据保持一致,只要该线程与I/O线程保持一致,中继日志通常会位于OS缓存中(也就是内存当中),所以中继开销很小。
(3)主从复制注意点
- 1、master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
- 2、slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
- 3、Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
- 4、Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)。
- 5、master和slave两节点间时间需同步。
MySQL主从服务部署
实验环境
服务器 |
操作系统 |
ip地址 |
软件服务 |
MySQL主服务器 |
centos7.2 |
192.168.10.101 |
ntp,mysql5.7 |
MySQL从服务器 |
centos7.2 |
192.168.10.102 |
ntp,mysql5.7 |
MySQL从服务器 |
centos7.2 |
192.168.10.103 |
ntp,mysql5.7 |
一、MySQL主服务器
1、设置主服务器为本地时钟源
安装时间同步软件:
yum install ntp -y
vi /etc/ntp.conf
末行添加(如果能联网,直接启动ntpd服务即可):
server 192.168.10.0 //设置本地是时钟源,注意自己所在网段是192.168.10.0段
fudge 192.168.10.0 stratum 8 //设置时间层级为8(限制在15内)
systemctl start ntpd && systemctl enable ntpd
systemctl stop firewalld.service && systemctl disable firewalld.service
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
setenforce 0
2、安装MySQL软件
这里在centos7上安装MySQL5.7版本,详细过程请参见https://blog.csdn.net/weixin_41515615/article/details/82470121
安装好MySQL后:
[root@linux-node1 ~]# vi /etc/my.cnf
[mysqld]
user = mysql
character_set_server=utf8
init_connect='SET NAMES utf8'
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port = 3306
lower_case_table_names = 1
log-error=/var/log/mysqld.log
pid-file=/usr/local/mysql/data/mysqld.pid
server-id = 100 //设置主从服务器身份唯一标识
log-bin=master-bin //开启二进制日志
log-slave-updates=true //开启主从功能
[root@linux-node1 ~]# /etc/init.d/mysqld start //启动服务
[root@linux-node1 ~]# mysql -uroot -pAbc@123
mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.10.%' IDENTIFIED BY 'Abc@123'; ////将从服务器权限赋予账号myslave,可以在192.168.10.0网段登录,密码为Abc@123
mysql> flush privileges;
mysql> show master status; //查看主服务器状态
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000003 | 154 | | | |
+-------------------+----------+--------------+------------------+-------------------+
二、MySQL从服务器
- 1、安装ntp时间同步软件,由于我的是连接外网的ntp服务器,所以直接启动即可。
yum install ntp -y
systemctl start ntpd && systemctl enable ntpd
systemctl stop firewalld.service && systemctl disable firewalld.service
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
setenforce 0
2、安装MySQL软件:https://blog.csdn.net/weixin_41515615/article/details/82470121
[root@linux-node2 ~]# vi /etc/my.cnf
[mysqld]
user = mysql
character_set_server=utf8
init_connect='SET NAMES utf8'
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port = 3306
lower_case_table_names = 1
log-error=/var/log/mysqld.log
#pid-file=/usr/local/mysql/data/mysqld.pid
server-id = 110 //设置唯一身份标识
relay-log=relay-log-bin //打开中继日志功能
relay-log-index=slave-relay-bin.index //定义relay-log的位置和名称
[root@linux-node3 ~]# vi /etc/my.cnf
[mysqld]
user = mysql
character_set_server=utf8
init_connect='SET NAMES utf8'
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port = 3306
lower_case_table_names = 1
log-error=/var/log/mysqld.log
#pid-file=/usr/local/mysql/data/mysqld.pid
server-id = 111 //设置唯一身份标识
relay-log=relay-log-bin //打开中继日志功能
relay-log-index=slave-relay-bin.index //定义relay-log的位置和名称
[root@linux-node2 ~]# /etc/init.d/mysqld start
[root@linux-node3 ~]# /etc/init.d/mysqld start
3、进入数据库:
报错:
[root@linux-node2 ~]# mysql -uroot -pAbc@123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
解决方法:
[root@linux-node2 ~]# mkdir /var/lib/mysql/
[root@linux-node2 ~]# ln -s /tmp/mysql.sock /var/lib/mysql/mysql.sock
[root@linux-node2 ~]# mysql -uroot -pAbc@123
mysql> change master to master_host='192.168.10.101',master_user='myslave',master_password='Abc@123',master_log_file='master-bin.000003',master_log_pos=154; //切记根据主服务器状态更改相应二进制日志文件和偏移量;
mysql> start slave; //开启从服务器状态
mysql> show slave status\G //查看状态
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.101
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000003
Read_Master_Log_Pos: 154
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 321
Relay_Master_Log_File: master-bin.000003
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: 154
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: 100
Master_UUID: ef2c7def-b1de-11e8-8957-000c29f9b725
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)
验证主从结果
- 当选择在主MySQL服务器中创建数据,从服务器中也会同步更新数据文件。