目录
异步复制(Asynchronous replication)
全同步复制(Fully synchronous replication)
半同步复制(Semisynchronous replication)
注:
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。
由于使用MySQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MySQL Proxy 内置变量和MySQL Protocol 的人来说是非常困难的。
Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层。
实验准备:
Master 服务器:192.168.88.22 mysql5.7
Slave1 服务器:192.168.88.40 mysql5.7
Slave2 服务器:192.168.88.13 mysql5.7
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
yum install ntp -y
vim /etc/ntp.conf
--末尾添加--
server 127.127.88.0 #设置本地是时钟源,注意修改网段
fudge 127.127.88.0 stratum 8 #设置时间层级为8(限制在15内)
service ntpd start
yum install ntp ntpdate -y
systemctl start ntpd
/usr/sbin/ntpdate 192.168.88.22 #进行时间同步
crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.88.22
vim /etc/my.cnf
server-id=1
log-bin=mysql-bin #添加,主服务器开启二进制日志
binlog_format=mixed
#选配项
expire_logs_days=7 #设置二进制日志文件过期时间,默认值为0,表示logs不过期
max_binlog_size=500M #设置二进制日志限制大小,如果超出给定值,日志就会发生滚动,默认值是1GB
skip_slave_start=1 #阻止从库崩溃后自动启动复制,崩溃后再自动复制可能会导致数据不一致的
#"双1设置",数据写入最安全
innodb_flush_log_at_trx_commit=1
#redo log(事务日志)的刷盘策略,每次事务提交时MySQL都会把事务日志缓存区的数据写入日志文件中,并且刷新到磁盘中,该模式为系统默认
sync_binlog=1
#在进行每1次事务提交(写入二进制日志)以后,Mysql将执行一次fsync的磁盘同步指令,将缓冲区数据刷新到磁盘
systemctl restart mysqld
mysql -u root
grant replication slave on *.* to 'myslave'@'192.168.88.%' identified by '123';
#给从服务器授权
flush privileges;
show master status;
vim /etc/my.cnf
server-id = 2 #修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin #开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=relay-log-bin.index #定义中继日志文件的位置和名称,一般和relay-log在同一目录
选配项
innodb_buffer_pool_size=2048M
#用于缓存数据和索引的内存大小,让更多数据读写内存中完成,减少磁盘操作,可设置为服务器总可用内存的 70-80%
sync_binlog=0
#MySQL不做任何强制性的磁盘刷新指令,而是依赖操作系统来刷新数据到磁盘
innodb_flush_log_at_trx_commit=2
#每次事务log buffer会写入log file,但一秒一次刷新到磁盘
log-slave-updates=0
#slave 从 master 复制的数据会写入二进制日志文件里,从库做为其他从库的主库时设置为 1
relay_log_recovery=1
#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log, 并且重新从 master 上获取日志,这样就保证了 relay-log 的完整性。默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启。
systemctl restart mysqld
mysql -u root
change master to master_host='192.168.88.22',master_user='myslave',master_password='123',master_log_file='mysql-bin.000011',master_log_pos=603;
start slave;
show slave status\G
//确保 IO 和 SQL 线程都是 Yes,代表同步正常。
Slave_IO_Running: Yes #负责与主机的io通信
Slave_SQL_Running: Yes #负责自己的slave mysql进程
#一般 Slave_IO_Running: No 的可能性:
1、网络不通
2、my.cnf配置有问题
3、密码、file文件名、pos偏移量不对
4、防火墙没有关闭
vim /etc/my.cnf #在 [mysqld] 区域添加下面内容
plugin-load=rpl_semi_sync_master=semisync_master.so #加载mysql半同步复制的插件
rpl_semi_sync_master_enabled=ON #或者设置为"1",即开启半同步复制功能
rpl-semi-sync-master-timeout=1000 #超时时间为1000ms,即1s
systemctl restart mysqld
vim /etc/my.cnf
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=ON
systemctl restart mysqld
show status like 'Rpl_semi_sync_master_status';
show variables like 'rpl_semi_sync_master_timeout';
show status like 'Rpl_semi_sync_slave_status';
stop slave io_thread; #关闭数据库上的IO线程
start salve io_thread; #启动数据库上的IO线程
show status like '%Rpl_semi%';
参数说明:
Rpl_semi_sync_master_clients #半同步复制客户端的个数
Rpl_semi_sync_master_net_avg_wait_time #平均等待时间(默认毫秒)
Rpl_semi_sync_master_net_wait_time #总共等待时间
Rpl_semi_sync_master_net_waits #等待次数
Rpl_semi_sync_master_no_times #关闭半同步复制的次数
Rpl_semi_sync_master_no_tx #表示没有成功接收slave提交的次数
Rpl_semi_sync_master_status #表示当前是异步模式还是半同步模式,on为半同步
Rpl_semi_sync_master_timefunc_failures #调用时间函数失败的次数
Rpl_semi_sync_master_tx_avg_wait_time #事物的平均传输时间
Rpl_semi_sync_master_tx_wait_time #事物的总共传输时间
Rpl_semi_sync_master_tx_waits #事物等待次数
Rpl_semi_sync_master_wait_pos_backtraverse #可以理解为"后来的先到了,而先来的还没有到的次数"
Rpl_semi_sync_master_wait_sessions #当前有多少个session因为slave的回复而造成等待
Rpl_semi_sync_master_yes_tx #成功接受到slave事物回复的次数
注:
实验准备:
Master 服务器:192.168.88.22 mysql5.7
Slave1 服务器:192.168.88.40 mysql5.7
Slave2 服务器:192.168.80.13 mysql5.7
Amoeba 服务器:192.168.88.31 jdk1.6、Amoeba
客户端 服务器:192.168.88.50 mysql
cd /opt/
cp jdk-6u14-linux-x64.bin /usr/local/
cd /usr/local/
chmod +x jdk-6u14-linux-x64.bin
./jdk-6u14-linux-x64.bin
//按yes,按enter
mv jdk1.6.0_14/ /usr/local/jdk1.6
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
source /etc/profile
java -version
mkdir /usr/local/amoeba
tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
chmod -R 755 /usr/local/amoeba/
/usr/local/amoeba/bin/amoeba
##如显示amoeba start|stop说明安装成功
#先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问
grant all on *.* to test@'192.168.88.%' identified by 'yy.com';
cd /usr/local/amoeba/conf/
cp amoeba.xml amoeba.xml.bak
vim amoeba.xml #修改amoeba配置文件
##30行##
<property name="user">amoeba</property>
##32行##
<property name="password">123456</property>
##115行##
<property name="defaultPool">master</property>
##117-去掉注释-
<property name="writePool">master</property>
<property name="readPool">slaves</property>
cp dbServers.xml dbServers.xml.bak
vim dbServers.xml #修改数据库配置文件
##23行##注释掉 作用:默认进入test库 以防mysql中没有test库时,会报错
<!-- <property name="schema">test</property> -->
##26##修改
<property name="user">test</property>
##28-30##去掉注释
<property name="password">123.com</property>
##45##修改,设置主服务器的名Master
<dbServer name="master" parent="abstractServer">
##48##修改,设置主服务器的地址
<property name="ipAddress">192.168.80.10</property>
##52##修改,设置从服务器的名slave1
<dbServer name="slave1" parent="abstractServer">
##55##修改,设置从服务器1的地址
<property name="ipAddress">192.168.80.11</property>
##58##复制上面6行粘贴,设置从服务器2的名slave2和地址
<dbServer name="slave2" parent="abstractServer">
<property name="ipAddress">192.168.80.12</property>
##65行##修改
<dbServer name="slaves" virtual="true">
##71行##修改
<property name="poolNames">slave1,slave2</property>
/usr/local/amoeba/bin/amoeba start& #启动Amoeba软件,按ctrl+c 返回
netstat -anpt | grep java #查看8066端口是否开启,默认端口为TCP 8066
yum install -y mariadb-server mariadb
systemctl start mariadb.service
mysql -u amoeba -p123 -h 192.168.88.31 -P8066
#通过amoeba服务器代理访问mysql ,在通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器
use ikun;
create table test (id int(10),name varchar(10),address varchar(20));
stop slave;
use ikun;
##在slave1上
insert into test values('1','zhangsan','this_is_slave1');
##在slave2上
insert into test values('2','lisi','this_is_slave2');
##在主服务器上
insert into test values('3','wangwu','this_is_master');
use ikun;
select * from test;
##客户端会分别向slave1和slave2读取数据,显示的只有在两个从服务器上添加的数据,没有在主服务器上添加的数据
1.master服务器高并发,形成大量事务
2.网络延迟
3.主从硬件设备导致
4.是同步复制、而不是异步复制