主从同步原理
核心:两个日志、三个线程
两个日志:master的二进制日志、slave的中继日志
三个线程:master的dump线程、slave的I/O线程和SQL线程
MySQL支持的复制类型:基于sql语句的复制、基于行的复制、混合类型的复制。
同步的三种策略:全同步、半同步、异步(默认)。
MySQL主从同步的工作过程:
①、在每个事务更新数据完成之前,Master 在二进制日志(Binary log)记录这些改变。写入二进制日志完成后,Master 通知存储引擎提交事务。
②、Slave 将 Master 的复制到其中继日志(Relay log)。首先slave开始一个工作线程(I/o),I/o线程在 Master 上打开一个普通的连接,然后开始 Binlog dump process。Binlog dump process 从 Master 的二进制日志中读取事件,如果已经跟上 Master,它会睡眠并等待Master 产生新的事件,I/o线程将这些事件写入中继日志。
③、SQL slave thread(SQL从线程)处理该过程的最后一步,SQL线程从中继日志读取事件,并重放其中的事件而更新 Slave 数据,使其与 Master 中的数据一致,只要该线程与 I/O线程保持一致,中继日志通常会位于 os 缓存中,所以中继日志的开销很小。复制过程有一一个很重要的限制,即复制在 Slave 上是串行化的, 也就是说 Master上的并行更新操作不能在 Slave 上并行操作。
实验
实验环境:
master:192.168.177.114 安装MySQL5.7
slave1:192.168.177.115 安装MySQL5.7
slave2:192.168.177.116 安装MySQL5.7
client:192.168.177.110 安装mariadb
amoeba:192.168.177.111 安装jdk1.6 和 amoeba
首先master、slave1、slave2 需要时钟同步,安装ntp服务 ,同步阿里云的时钟服务器
yum -y install ntp
ntpstat ntp.aliyun.com
主从同步
1、Master 服务器配置:
server-id = 11 //服务器id标识,不可重复
log-bin=master-bin //开启二进制日志,生成的二进制日志文件名以master-bin.开头
log_slave_updates=true //开启从服务日志同步
vim /etc/my.cnf
[mysqld]
......//省略部分内容
server-id = 11
log-bin=master-bin
log_slave_updates=true
2、Slave 服务器配置:slave1、slave2 配置相同,除了server id 不可以相同
server-id = 22 //服务器id标识,不可重复 slave1 id=22,slave2 id=33
log-bin=mysql-bin //开启二进制日志文件
relay-log=relay-log-bin //从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index //定义relay-log的位置和名称(index索引)
vim /etc/my.cnf
[mysqld]
......//省略部分内容
server-id = 22
log-bin=mysql-bin
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
3、master服务器配置规则
登录master数据库,配置规则
mysql -uroot -p123456
//规则说明:给从服务器提权,允许使用myslave的身份复制master的所有数据库的所有表,并指定密码为123456
grant replication slave on *.* to 'myslave'@'192.168.177.%' identified by '123456';
//刷新权限表(mysql.user表)
flush privileges;
查看master数据库的状态,根据查到的position字段的值,设置slave服务器开始同步的位置
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 452 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
4、slave1、slave2 服务器配置
登录slave1、slave2数据库,配置change
change master to master_host='192.168.177.114',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=452;
配置解读:
master_host:指定主服务器IP
master_user:指定登录主服务器用户名
master_password:指定登录主服务器密码
master_log_file:指定需要同步主二进制日志文件名
master_log_pos:指定同步主二进制日志文件的起始位置
开启同步
slave start;
查看从服务器状态
show slave status;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.177.114
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 1485
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 1354
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Yes //说明成功开启同步
Slave_SQL_Running: Yes //说明成功开启同步
......//省略部分内容
Last_Errno: 0 //当出现不同步时,需要查看的内容
Last_Error:
......//省略部分内容
Last_IO_Errno: 0 //当出现不同步时,需要查看的内容
Last_IO_Error:
Last_SQL_Errno: 0 //当出现不同步时,需要查看的内容
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 11
Master_UUID: 33a359ce-e797-11eb-a9d5-000c29c6543f
Master_Info_File: /usr/local/mysql/data/master.info
......//省略部分内容
mysql>
读写分离
Amoeba 服务器安装jdk1.6 和 amoeba
上传jdk-6u14-linux-x64.bin 和 amoeba-mysql-binary-2.2.0.tar.gz到/opt目录下
复制jdk到/usr/local/ 目录下
cp jdk-6u14-linux-x64.bin /usr/local/
因为jdk是bin文件(二进制可执行文件)所以直接执行(先修改执行权限)
cd /usr/local
chmod +x jdk-6u14-linux-x64.bin && ./jdk-6u14-linux-x64.bin //按空格到最后看到提示信息输入yes、按enter
重命名jdk
mv jdk1.6.0_14/ /usr/local/jdk1.6
添加环境变量
cp /etc/profile /opt/profile.bak //做个备份,以免操作失误导致所有命令不可使用
vim /etc/profile
//在文件末尾追加以下内容
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
安装amoeba软件
因为上文配置环境变量中 添加了此行export AMOEBA_HOME=/usr/local/amoeba
所以需要创建/usr/local/amoeba 该目录
mkdir /usr/local/amoeba
//解压amoeba的tar包到/usr/local/amoeba目录下
tar xzvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
//修改权限
chmod -R 755 /usr/local/amoeba
因为之前做了环境变量所以直接输入amoeba,如果显示amoeba start|stop 说明安装成功
配置amoeba读写分离,两个slave读负载均衡
先在master、slave1、slave2 的mysql上开放权限给amoeba访问
grant all on *.* to 'test'@'192.168.177.%' identified by '123456';
修改amoba.xml主配置文件
cp amoeba.xml amoeba.xml.bak
vim amoeba.xml
//定位到30行,这里定义的是client登录amoeba服务器的用户名
<property name="user">amoeba</property>
//定位到32行,这里定义的是client登录amoeba服务器的密码
<property name="password">123456</property>
//定位到115行,修改默认池
<property name="defaultPool">master</property>
//定位到117行,解开注释,修改“读池”和“写池”
<!-- -->
<property name="writePool">master</property>
<property name="readPool">slaves</property>
修改dbServers.xml数据库服务配置文件
cp dbServers.xml dbServers.xml.bak
vim dbServers.xml
//定位到23行,将test修改为mysql
<property name="schema">mysql</property>
//定位到26行,修改amoeba服务器访问三台MySQL服务器的用户名
<property name="user">test</property>
//定位到29行,修改amoeba服务器访问三台MySQL服务器的密码
<property name="password">123456</property>
//定位到45行,修改数据库主服务器名/地址
<dbServer name="master" parent="abstractServer">
//定位到48行,修改master服务器ip
<property name="ipAddress">192.168.177.114</property>
//定位到52行修改从服务器名
<dbServer name="slave1" parent="abstractServer">
//定位到55行修改从服务器地址
<property name="ipAddress">192.168.226.115</property>
//将slave1的6行配置复制一份,在slave1配置段下面粘贴并修改为slave2
<dbServer name="slave2" parent="abstractServer">
//修改第二 台服务器IP
<property name="ipAddress">192.168.226.116</property>
//定位到65行,修改多个服务器池(multiPool)的名称(修改为slaves)
<dbServer name="slaves" virtual-"true">
定位到71行,添加两个从服务器的服务器名(slave1 slave2)
<property name="poolNames">slavel,slave2</property>
client端 安装 mariadb 用来访问amoeba服务器
yum -y install mariadb
远程登录amoeba服务器
mysql -uamoeba -p123456 -h 192.168.177.130 -P 8066