mysql 主从复制的原理
主(master)数据库启动 bin 二进制日志,这样会有一个 Dump 线程,这个线程是把主(master)数据
库的写入操作都会记录到这个 bin 的二进制文件中。
然后从(slave)数据库会启动一个 I/O 线程(监控主服务器的二进制日志的变化),这个线程主要是把
主(master)数据库的 bin 二进制文件读取到本地,并写入到中继日志(Relay log)文件中。
最后从(slave)数据库其他 SQL 线程,把中继日志( Relay log)文件中的事件再执行一遍,更新从(slave)
数据库的数据,保持主从数据一致,重新写入数据库。
mysql 读写分离的原理
读写分离就是只在主服务器上写,只在从服务器上读,基本原理是让主数据库处理事务性查询( select ,
update , insert ),而从数据库处理 select 查询。数据库复制被用来把事务性查询导致的变更同步到群
集中的从数据库。
案例实现思路
(1)安装MySQL数据库;
(2)配置MySQL主从复制;
(3)安装并配置Amoeba;
(4)客户端测试读写分离;
1.建立时间同步环境
(1)安装NTP
yum -y install ntp
(2)配置NPT
vim /etc/ntp.conf //添加如下两行
server 127.127.1.0
fudge 127.127.10.0 stratum 8
(3)重启服务
systemctl restart ntpd
2.配置防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
3:在从节点上进行时间同步
yum -y install ntp
ntpdate 192.168.10.102
4:在所有服务器上安装mysql数据库步骤略
5:配置mysql master主服务器
vi /etc/my.cnf
在[mysqld]模块中修改或添加:
server-id=11 ##修改
log-bin=master-bin ##修改
log-slave-updates=true ##添加 (可不用添加)
binlog-format = MIXED
log-slave-updates=true #Slave可以是其他 Slave 的 Master,从而扩散 Master 的更新
binlog-ignore-db=test #不记录指定的数据库的二进制日志
replicate-ignore-db=test #设置不需要同步的库
binlog_cache_size = 1M #日志缓存的大小
expire_logs_days=3 #自动过期清理日志的天数
以上参数在[mysqld]模块中设置
systemctl restart mysqld
mysql> grant replication slave on *.* to 'myslave'@'192.168.10.%' identified by '123456' ;
mysql> flush privileges;
mysql> show master status;
6:从服务器的配置
vi /etc/my.cnf
在[mysqld]模块中修改或添加:
server-id= 22 ##修改,值不能和其他mysql服务器重复
systemctl restart mysqld
mysql -u root -p
mysql> change master to master_host='192.168.10.101',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=337;
mysql> start slave;
mysql> show slave status\G ##注意后面不要加分号
7:验证主从复制
(1)在主从服务器上分别查询数据库
mysql> show databases;
(2)在主服务器上创建数据库
mysql> create database db_test;
mysql> show databases;
(3)在从服务器上再次查询数据库,可以看到从服务器上也有了db_test数据库了
mysql> show databases;
搭建Mysql读写分离
1:在主机amoeba上安装java环境
chmod +x jdk-6u14-linux-x64.bin
./jdk-6u14-linux-x64.bin
mv jdk1.6.0_14/ /usr/local/jdk1.6
vi /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:$JAVA_HOME/bin
export AMOEBA_HOME=/usr/local/amoeba/
export PATH=$PATH:$AMOEBA_HOME/bin
source /etc/profile
java -version ##查询版本,确定java安装成功
2:安装并配置amoeba
[root@localhost local]# mkdir /usr/local/amoeba
[root@localhost ~]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@localhost ~]# chmod -R 755 /usr/local/amoeba/
[root@localhost ~]# /usr/local/amoeba/bin/amoeba
amoeba start|stop ##有此提示表示成功
3:配置amoeba读写分离
(1)在三个mysql服务器中开放权限给amoeba访问
mysql> grant all on *.* to test@'192.168.10.%' identified by '123.com';
(2)在amoeba上配置amoeba.xml文件
[root@localhost amoeba]# systemctl stop firewalld
[root@localhost ~]# cd /usr/local/amoeba/conf
[root@localhost conf]# vi amoeba.xml
修改部分,此处设置的是mysql客户端连接amoeba时用的账号和密码
<property name="user">amoeba</property> ##30行
<property name="password">123456</property> ##32行
..............
<property name="defaultPool">master</property> ##115行
<property name="writePool">master</property> ##118行
<property name="readPool">slaves</property> ##119行此处的注释去掉
(3)编辑dbServer.xml文件
vi dbServers.xml
修改(注意去掉注释),slave2的复制一个slave1
<!-- mysql user -->
<property name="user">test</property> ##26行
<property name="password">123.com</property> ##29行,去掉注释符
</factoryConfig>
<dbServer name="master" parent="abstractServer"> ##45行
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.1.101</property> ##48行
</factoryConfig>
</dbServer>
<dbServer name="slave1" parent="abstractServer"> ##52行
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.1.102</property> ##55行
</factoryConfig>
</dbServer>
<dbServer name="slave2" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.1.103</property>
</factoryConfig>
</dbServer>
<dbServer name="slaves" virtual="true"> ##59行
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name="loadbalance">1</property>
<!-- Separated by commas,such as: server1,server2,server1 -->
<property name="poolNames">slave1,slave2</property> ##65行
</poolConfig>
</dbServer>
(4)启动amoeba软件
cd /usr/local/amoeba/
bin/amoeba start&
netstat -anpt | grep java
4:测试
(1):在client上
yum -y install mariadb
mysql -u amoeba -p 123456 -h 192.168.10.104 -P 8066
(2):在master服务器上创建表
mysql> stop slave;
MySQL [test]> use auth
MySQL [auth]> create table users (id int(10),name char(20));
(3):在两个slave服务器上
mysql> stop slave;
(4):在master服务器上
mysql> insert into users values ('1','zhangsan');
(5):在slave1上
mysql> use auth;
mysql>insert into zang values ('2','zhangsan');
(6):在slave2上
mysql> use auth;
mysql>insert into zang values ('3','zhangsan);
(7):在client上查询三次
mysql> use auth;
mysql> select * from users;
对比三次的输出,验证读操作,发现没有在master写入的数据,而slave上写的能查到
(8):在client上
mysql> use auth;
mysql>insert into users values ('4','zhangsan');
mysql> select * from users; ##发现在client上查询不到自己写的数据
(9):在master上
mysql> select * from users; ##能查到在client上写入的数据,说明写操作在master上
(10):在slave上
mysql> select * from users; ##发现没有数据,说明写入的操作是在master上