主从复制原理
MySQL主从复制原理
MySQL的复制类型
1、基于语句的复制(STATEMENT, MySQL默认类型)
2、基于行的复制(ROW)
3、混合类型的复制(MIXED)
主从复制工作过程
★★两日志、三线程
(1)在每个事务更新数据完成之前,Master 在二进制日志( Binarylog)记录这些改变。写入二进制日志完成后,Master 通知存储引擎提交事务。
(2) Slave 将Master 的复制到其中继日志(Relay log)。首先slave开始-一个工作线程(I/O) ,I/o线程在Master 上打开一个普通的连接,然后开始Binlog dumpprocess。Binlog dump process 从Master 的二进制日志中读取事件,如果已经跟上Master,它会睡眠并等待Master产生新的事件,I/0线程将这些事件写入中继日志。
(3) SQL slavethread(SQL从线程)处理该过程的最后一-步,SQL线程从中继日志读取事件,并重放其中的事件更新Slave数据,使其Master 中的数据一致,只要该线程与I/O线程保持一致,中继日志通常会位于OS缓存中,所以中继日志的开销很小。复制过程有一个很重要的限制,即复制在Slave. 上 是串行化的,也就是说Master. 上的并行更新操作不能在Slave 上并行操作。
MYSQL设计思路
1、主从复制,让slave服务器中的中继日志同步master二进制日志
2、Mysql读写分离
3、MHA高可用,对master服务器做一个冗余备份工作
如果MHA还扛不住 ,有三种方式
1、纵向扩展:强化自己服务器(五大负载、内核优化)+数据库内的优化,索引、存储过程、select查询等等
2、横向扩展:增加服务器数量
3、借助于内存/缓存数据库Redis,来帮助mysql缓存一些高热数据,减少mysql压力
如果还扛不住,考虑是否需要做一些架构、服务上的改动
MySQL复制原理中的复制类型
Mysql主从复制默认使用过的机制
1、全同步
2、半同步
3、异步(默认)
主从复制原理在于2个日志文件、3个线程(4个线程)
2个日志:二进制和中继
三个线程:1、master上的dump线程 2、slave上的IO线程和SQL线程
目的:slave上的中继日志 趋近实时同步master上的二进制日志
首先,slave上的IO线程会去master上申请同步二进制日志的更新内容 ,dump会监听master上二进制日志的更新内容,dump线程会把同步的sql日志内容给予slave服务器,slave的IO线程就会写入自己的中继日志
slave 上的sql线程把日志中的更新语句同步执行到数据库内部,以达到master数据库趋近一致。
一、主从复制实验
虚拟机:
客户端 192.168.100.159
mysql-master 192.168.100.132
mysql-slave1 192.168.100.158
mysql-slave2 192.168.100.133
amoba 192.168.100.22
1、先关闭防火墙、selinux(五台虚拟机都做)
systemctl stop firewalld
setenforce 0
mysql服务器的resolves 都设置成114.114.114.114
2、同步时间(五台虚拟机都做)
ntpdate ntp.aliyun.com
可以设置计划每十分钟一次同步时间
crontab -e
*/10 * * * * /usr/sbin/ntpdate ntp.aliyun.com
3、修改对应服务器名称
4、三台mysql服务器安装mysql
1、先把mysql5.7的安装包导入opt下
2、解压mysql包
cd /opt
tar xzvf mysql-boost-5.7.20.tar.gz
3、安装环境依赖包
yum -y install ncurses ncurses-devel bison cmake
yum install -y perl perl-devel
4、创建运行用户
useradd -M -s /sbin/nologin mysql
5、编译安装
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=boost \
-DWITH_SYSTEMD=1
make && make install
6、给mysql程序用户配置权限
chown -R mysql:mysql /usr/local/mysql
chown mysql:mysql /etc/my.cnf
7、优化mysql自带命令,支持环境变量
echo "export PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH" >> /etc/profile
source /etc/profile
8、初始化数据库
cd /usr/local/mysql
bin/mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
9、添加mysql系统服务
cp usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
systemctl daemon-reload
systemctl start mysqld.service
systemctl enable mysqld
10、修改mysql登录密码
mysqladmin -u root -p password
11、修改主服务配置文件
vim /etc/my.cnf
主服务器:
server-id = 11
log-bin=master-bin #添加,主服务器开启二进制日志
log-slave-updates=true #添加,允许从服务器更新
systemctl restart mysqld
mysql -u root -p
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.59.%' IDENTIFIED BY '123456'; #给从服务器授权
FLUSH PRIVILEGES; #刷新权限
show master status;
12、修改从服务器配置
vim /etc/my.cnf
server-id = 22 #修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin #添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index #添加,定义中继日志文件的位置和名称
systemctl restart mysqld
mysql -u root -p
change master to master_host='192.168.59.129' , master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=1211; #配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致
start slave; #启动同步,如有报错执行 reset slave;
show slave status\G #查看 Slave 状态
//确保 IO 和 SQL 线程都是 Yes,代表同步正常。
13、测试是否同步
同步成功
如果主从复制失败,可以尝试以下方法解决
#忽略当前的错误执行下一步的同步
stop slave;
slave库中:set global sql_slave_skip_counter=1;
start slave;
#IO线程一直处于connecting状态
第一件事 看laster error 如果是位置点问题 binlog位置索引出问题,不要直接reset slave;(会删除change同步操作,搭建时可以)
stop slave;
chang master to master_log_file='mysql-bin.000001',master_log_pos=0; #指向对的地方
正确做法:
1、打开主服务器,进入mysql
2、执行flush logs; #刷新日志会重新创建一个binlog文件
3、在主服务器上执行show master status\G;
4、来到从服务器的Mysql
5、stop slave;
6、change master to master_log_file='mysql-bin.000012',master_log=154; #重新指向对应的地方
7、start slave;
8、show slave status\G
二、读写分离
1、只在主服务器上写,只在从服务器上读
2、主数据库处理事务性查询,从数据库处理SELECT查询,
3、数据库复制用于将事务性查询的变更同步到集群中的从数据库
amoeba服务器的作用:1、实现读写分离 2、隐藏数据库真实IP
1、安装java环境
在主从复制的基础上再添加两台服务器 一台amoeba服务 一台client读取和写入
因为amoeba是jdk1.5开发的 所以用jdk1.5或1.6,其他版本并不适用
cd /opt
把jdk-6u14-linux-x64.bin文件载入进去
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 #输出定义java的工作目录
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib #输出指定的java类文件
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin #将java加入路径环境变量
export AMOEBA_HOME=/usr/local/amoeba #输出定义amoeba的工作目录
export PATH=$PATH:$AMOEBA_HOME/bin #加入路径环境变量
source /etc/profile
java -version
2、安装amoeba
cd /opt
把amoeba软件包载入
mkdir /usr/local/amoeba
tar zxvf /opt/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
chmod -R 755 /usr/local/amoeba/ #给予权限,仅root用户可以写
/usr/local/amoeba/bin/amoeba #开启amoeba
#如显示amoeba start|stop 说明安装成功
3、配置读写分离
先在master、slave1、slave2的mysql上开启权限允许amoeba访问
grant all on *.* to test@'192.168.59.%' identified by '123.com';
然后在amoeba服务器上配置amoeba服务
cd /usr/local/amoeba/conf/
cp amoeba.xml amoeba.xml.bak #备份文件
vim amoeba.xml
cp dbServers.xml dbServers.xml.bak #备份文件
vim dbServers.xml #修改数据库配置文件
/usr/local/amoeba/bin/amoeba start& #启动amoeba
测试
前提client端上安装好mariadb
yum -y install mariadb
mysqladmin -u amoeba -p123456 -h 192.168.59.131 -P8066 #通过amoeba服务器代理访问mysql
现在两台从服务器上通知同步
分别在master、slave1、slave2上对同一个表插入信息
master:
slave1:
slave2:
现在在client端上查询
两台服务器再次开启同步
可以看出从服务器上同步了主服务和客户端还有本地服务器的信息,没有同步另一个从服务器的信息