一、优点
安全、可靠、实时数据
二、类型
1、异步复制
不可靠
主库在执行完客户端提交地事务后会立刻将结果返回给客户端,并不关心从库是否已经接受并处理了事务
2、全部复制
耗时长
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端
3、半同步复制
比异步复制可靠,比全部复制时间短
主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接受到并写到relay log中才返回给客户端
三、支持的复制方式
1、基于SQL语句的复制
在主服务器上执行的SQL语句,在从服务器上执行同样的SQL语句,效率比较高
2、基于行的复制
主服务器把表的行变化作为事件写入到二进制日志中,主服务器把代表了行变化的事件复制到从服务器中
3、混合模式复制
先采用基于语句的复制,一旦发现基于语句无法精确复制时,再采用行
四、工作原理
(一台主服务器,多台从数据服务器,主服务器开启日志功能,且建立一个允许从数据服务器访问的账号,从数据服务器开启从服务,主服务器所以产生的数据记录在日志文件里保存到本地磁盘,当日志文件发生变化时,从数据服务器通过IO线程同步变化的数据,把变化的二进制文件传到从数据服务器并告知主数据服务数据没有问题然后保存到本地磁盘,从数据服务器和主数据服务有一样的数据,所以当读取数据时通过SQL线程调用从数据服务器,而主服务器只负责写,减轻主数据服务器压力)
种类:一主一从、一主两从、一主多从
IO:读写线程
当文件发生变化,立马通过读写线程同步数据
SQL:复制线程
五、部署时间实时同步
rpm -q ntp #检查ntp是否安装,未安装则用yum安装
yum -y install ntp
vim /etc/ntp.conf #编辑配置文件
server 192.168.1.1
fudge 192.168.1.1 stratun 8 #IP地址填写可上网的主机IP,实现同步世界时间
systemctl start ntpd #开启服务
systemctl enable ntpd #开机自启
rpm -q ntpdate #(在其他主机上查看是否下载)
ntpdate 192.168.1.2 #(在其他主机上同步这台主机的时间,可写入计划任务,定时执行)
六、部署主从同步
1、master主服务器配置
yum -y mariadb mariadb-server #yum下载mysql数据库
vim /etc/my.cnf #修改配置文件
server-id=1 #编号
log-bin=mysql-binlog #启动日志
log-slave-updates=true #开启主从复制
systemctl start mariadb #启动服务
mysql #登录
grant replication slave on *.* to 'myslave'@'192.168.200.%' identified by '密码'; #创建myslave用户并及于权限,%标识这个网段的所有
replication slave #用于复制性从属服务器(若数据库是刚创建里面没有数据可略过此步骤,否则会报错)
flush privileges; #刷新权限
show master status; #获取二进制文件名跟二进制文件位置id
mysqldump -uroot --all-databases > /root/alldbbackup.sql #备份master主服务器原有数据(因主从同步开启后,从服务器不会同步主数据库原有数据,若没有元数据则跳过此步及以下两步)
scp /root/alldbbackup.sql root@从服务器的IP:/root/ #通过scp传输给从服务器,从服务器再导入数据库
mysql -uroot -p < /root/alldbbackup.sql #将主数据库源文件导入数据库
从服务器验证
关闭防火墙
mysql -umyslave -p密码 -h主服务器IP地址 #验证是否可以登录主数据库
2、slave1从1服务器配置
yum -y mariadb mariadb-server #yum下载mysql数据库
vim /etc/my.cnf #修改配置文件
server-id=2 #编号
relay-log=relay-log-bin #中继日志
relay-log-index=slave-relay-bin.index #定义日志索引(开启服务则可同步主库日志)
mysql -uroot -p密码 < 库备份脚本的路径 #导入主数据库的源文件(若没有从主服务器导过来的元数据文件则可跳过此步)
systemctl start mariadb #启动数据库
mysql #登录
stop slave; #停止从服务
change master to master_host='主服务器ip',master_user='主服务器授权的用户',master_password='授权用户的密码',master_log_file='主服务器查的二进制文件名',master_log_pos=二进制文件id; #授权主服务器
start slave; #开启从服务
show slave status\G #查看状态
3、slave2从2服务器配置
yum -y mariadb mariadb-server #yum下载mysql数据库
vim /etc/my.cnf #修改配置文件
server-id=3 #编号
relay-log=relay-log-bin #中继日志
relay-log-index=slave-relay-bin.index #定义日志索引(开启服务则可同步主库日志)
mysql -uroot -p密码 < 库备份脚本的路径 #导入主数据库的源文件(若没有从主服务器导过来的元数据文件则可跳过此步)
systemctl start mariadb #启动数据库
mysql #登录
stop slave; #停止从服务
change master to master_host='主服务器ip',master_user='主服务器授权的用户',master_password='授权用户的密码',master_log_file='主服务器查的二进制文件名',master_log_pos=二进制文件id; #授权主服务器
start slave; #开启从服务
show slave status\G #查看状态
七、部署读写分离
1、概念
(基本的原理是让主数据库处理事务性查询,而从数据库处理select查询,数据库复制被用来把事务性查询导致的改变更新同步到集群中的从数据库)
只在主服务器上写,只在从服务器上读
登录amoeba服务,他本身连接主和从数据库,根据操作不同调用相应数据库,和负载均衡相似
至少五台主机,一台主数据库,两台以上从数据库,一台maoeba服务器,一个客户端
负载均衡,高可用性,SQL过滤,读写分离
2、端口
8066
3、实现方法
基于程序代码内部实现
(在代码中根据select,insert进行路由分类,这类方法也是目前大型生产环境应用最广泛的,优点是性能最好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支,缺点是需要开发人员来实现,运维人员无从下手)
基于中间代理层实现
(代理一般位于客户端和数据库服务器之间,代理服务器接到客户端请求后通过判断转发到后端数据库,代表性程序:
(1)mysql-proxy为mysql开发早期开源项目,通过其自带的lua脚本进行SQL判断,虽然是mysql的官方产品,但是mysql官方不建议将其应用到生产环境。
(2)Amoeba(变形虫)该程序由java语言及逆行开发,阿里巴巴将其应用于生产环境,它不支持事物和存储过程)
4、安装
安装java环境(Amoeba是基于jdk1.5版本开发的,所以官方推荐使用1.5或者1.6版本,高版本不建议使用)
上传java安装文件jdk-6u31-linux-x64.bin (本身是一个二进制文件,脚本,省略了编译的过程,直接给执行权限安装)
chmod +x jdk-6u31-linux-x64.bin #给执行权限
./jdk-6u31-linux-x64.bin #运行文件(中途回车,命令不是存在一个目录里)
mv jdk1.6.0_31/ /usr/local/jdk1.6 #移动文件到自己想要的路径
vim /etc/profile #编辑配置文件,添加变量
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
source /etc/profile #使编译文件生效
rm -rf /usr/bin/java #删除原jdk(之前没安装的话可略过此步)
安装amoeba
上传amoeba安装包amoeba-mysql-binary-2.2.0.tar
mkdir /usr/local/amoeba #创建目录
tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ #解压到创建的目录内
chmod -R 755 /usr/local/amoeba/ #给创建的目录执行权限
5、配置
grant all on *.* to 'test'@'192.168.200.%' identified by '123.com'; #创建amoede
(在Master、Slave1、Slave2服务器中配置Amoeba的访问授权)
vim /usr/local/amoeda/conf/amoeba.xml #在amoeda服务器编辑配置文件,实现用户连接amoeba
30行 <property name="user">amoeba</property> #用户名
32行 <property name="password">123456</property> #连接amoeba的密码
115行 <property name="defaultPool">master</property> #默认池
118行 <property name="writePool">master</property> #写入池
119行 <property name="readPool">slaves</property> #读的池
vim /usr/local/amoeba/conf/dbServers.xml #在amoeda服务器编辑配置文件,实现主从服务器连接amoeda
22行 <property name="port">3306</property> #端口号
23行 <property name="schema">test</property> #连接mysql的用户,MySQl授权的用户(这个用户可以不改,如果数据库设置的其他用户的话,只要下面的用户名是设置的用户即可;否则可以登录但是查不到数据显示断开数据连接)
26行 <property name="user">test</property> #登录用户和授权用户一致
29行 <property name="password">123.com</property> #MySQL授权的密码
45行 <dbServer name="master" parent="abstractServer"> #定义master主服务器
48行 <property name="ipAddress">192.168.200.111</property> #master主服务器IP地址
52行 <dbServer name="slave1" parent="abstractServer"> #定义slave1从1服务器
55行 <property name="ipAddress">192.168.200.112</property> #定义slave1从1服务器IP地址
复制52-57行并在57行下放粘贴,用来定义slave2
59行 <dbServer name="slave2" parent="abstractServer"> #定义slave2从服务器
62行 <property name="ipAddress">192.168.1.223</property> #定义slave2从服务器IP地址
65行 <dbServer name="slaves" virtual="true"> #定义读的池slave
68行 property name="loadbalance">1</property>
71行 <property name="poolNames">slave1,slave2</property> #轮询
/usr/local/amoeba/bin/amoeba start & #启动amoeba并放入后台运行,等待8066端口号出来就启动成功了
netstat -anptl | gret 8066 #查看8066端口是否开启
netstat -anptl | gret 3306 #查看3306端口是否开启
6、验证(客户端)
yum -y install mariadb* #客户端安装
mysql -uamoeba -p123456 -h amoeba的IP地址 -P 8066 #登录amoeba
use Rich #选择数据库
insert into student values('4','Rich','write_test'); #客户端写入数据
insert into student values('2','Rich','write_test_slave1'); #在从1服务器写入数据
insert into student values('3','Rich','write_test_slave2'); #在从2服务器写入数据
select * from student; #查看数据库内的内容,没刷新一次两个从就跳转一次
关闭从的从服务
insert into student values('5','Rich','write_test'); #客户端写入数据
select * from student; #在客户端查看数据库内容,这时则只能看到从服务武器关闭前的数据内容
开启从的从服务
select * from student; #在客户端查看数据库内容,这是则能看到刚刚插入的数据