主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库。
1.做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
2.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
3.读写分离,使数据库能支撑更大的并发。
1--在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)。
2--在从服务器进行备份,避免备份期间影响主服务器服务;(确保数据安全)。
主节点 写
从节点1 读 从节点2 备份从节点过多,导致数据同步较慢
原理:
1、数据库有个bin-log二进制文件,记录了所有sql语句。
2、我们的目标就是把主数据库的bin-log文件的sql语句复制过来。
3、让其在从数据的relay-log(中继日志)重做日志文件中再执行一次这些sql语句即可。
具体原理:
1.binlog输出线程:每当有从库连接到主库的时候,主库都会创建一个线程然后发送binlog内容到从库。在从库里,当复制开始的时候,从库就会创建两个线程进行处理:
2.从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新记录,并拷贝这些更新记录到本地文件,其中包括relay log文件。
3.从库的SQL线程:从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行。
可以知道,对于每一个主从复制的连接,都有三个线程。拥有多个从库的主库为每一个连接到主库的从库创建一个binlog输出线程,每一个从库都有它自己的I/O线程和SQL线程。
master 对外提供 负责写数据
slave 读master日志写到relay-log
I/O进程:负责通信
SQL进程:负责写数据,根据log日志写数据。
总结:主从原理:从库slave生成两个线程,i/o线程和sql线程,i/o将变更记录写到二进制日志文件中,再写到中继日志中,sql线程读取中继日志,解析操作,最终数据统一。
面试题:
面试:
1.主从复制延迟大比较慢原因:
主服务器配置高,从服务器的配置低。
并发量大导致主服务器读的慢。从服务器写的慢
网络延迟比较高
从服务器的读写速度慢
从节点过多2.从数据库的读的延迟问题了解吗?如何解决?
解决方法:
半同步复制—解决数据丢失的问题
并行复制—-解决从库复制延迟的问题
环境:master原来没有旧数据(要是有旧数据,需要把数据导出,然后从库将数据导入,这个方法放到gtid主从复制实验时再说)
主服务器:
1、关闭防火墙,selinux,建议永久关闭(从服务器也要这样做)
# systemctl disable firewalld 设置防火墙开机不自启
# vim /etc/selinux/config 永久关闭selinux
selinux=disabled 保存退出后再临时关闭一下就永久关闭了,setenforce 0
2、开启binlog日志
[root@localhost ~]# vim /etc/my.cnf
log-bin=/var/lib/mysql/my1binlog
server-id=1
# /var/lib/mysql目录的属主属组是mysql,要是指定其他目录,记得创建对应目录,并修改属主属组为mysql
3、创建主从同步的用户
mysql> grant all on *.* to 'slave'@'%' identified by '1';
(replication slave,reload,super)
replication slave:
拥有此权限可以查看从服务器,从主服务器读取二进制日志。
super权限:
允许用户使用修改全局变量的SET语句以及CHANGE MASTER语句
reload权限:
必须拥有reload权限,才可以执行flush [tables | logs | privileges]
4、重启mysql(修改配置文件需要重启服务,创建用户后也要flush privileges; 这里两步骤合一起直接重启服务)
systemctl restart mysqld
从服务器:
1、关闭防火墙selinux
# systemctl disable firewalld 设置防火墙开机不自启
# vim /etc/selinux/config 永久关闭selinux
selinux=disabled 保存退出后再临时关闭一下就永久关闭了,setenforce 0
2、开启binlog日志,重启服务
[root@localhost ~]# vim /etc/my.cnf
log-bin=/var/lib/mysql/my2binlog
server-id=2
[root@localhost ~]# systemctl restart mysqld
3、help change master to 看从mysql编辑文件
>help change master to 查看从mysql编辑文件
CHANGE MASTER TO
MASTER_HOST='mysql-master-1.blackmed.cn/ip',
MASTER_USER='slave', //主服务器用户
MASTER_PASSWORD='big',
MASTER_PORT=3306,
MASTER_LOG_FILE='master2-bin.001', //日志文件
MASTER_LOG_POS=4, //日志位置
MASTER_CONNECT_RETRY=10; //默认尝试次数
4、编辑mysql文件
mysql> edit
CHANGE MASTER TO
MASTER_HOST='192.168.242.138',
MASTER_USER='slave',
MASTER_PASSWORD='1',
MASTER_PORT=3306,
MASTER_LOG_FILE='my1binlog.000001',
MASTER_LOG_POS=4,
MASTER_CONNECT_RETRY=10;
#保存退出wq
-> ;
mysql> start slave;
mysql> show slave status \G
然后就可以进行验证了,在主服务器上创建一个库,然后在从服务器上查看,可以看到在主服务器上创建的库。
故障排错
#### UUID一致,导致主从复制I/O线程不是yes
> Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work
致命错误:由于master和slave具有相同的mysql服务器uuid,导致I/O线程不进行;这些uuid必须不同才能使复制工作。
问题提示主从使用了相同的server UUID,一个个的检查:
1、检查配置文件binlog的server-id是否相同,必须是不同的
2、检查主从库状态
主库:mysql> show master status;
从库:mysql> show master status; 查看file是否一样,需要一样
3、查看server-uuid
vim /etc/lib/mysql/auto_cnf server-uuid必须是不同的
注意:
GTID:全局事务标识:global transaction identifiers
是用来代替传统复制的方法,GTID复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置,不再使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制。
1、master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
2、slave端的i/o 线程将变更的binlog,写入到本地的relay log中。
3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
5、如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。
GTID的组成:
GTID = source_id:transaction_id
source_id源id,用于鉴别原服务器,即mysql服务器唯一的server_uuid,由于GTID会传递到slave,所以也可以理解为源ID。
transaction_id事务id,为当前服务器上已提交事务的一个序列号,通常从1开始自增长的序列,一个数值对应一个事务。
示例:3E11FA47-71CA-11E1-9E33-C80AA9429562:23
前面的一串为服务器的server_uuid,即3E11FA47-71CA-11E1-9E33-C80AA9429562,后面的23为transaction_id
gtid主从复制部署:
主服务器:192.168.242.138
从服务器:192.168.242.139
主服务器:
1、关闭防火墙selinux,一定要确保关闭了
2、修改mysql的配置文件
[root@localhost ~]# vim /etc/my.cnf
log-bin
server-id=1
gtid_mode=ON
enforce_gtid_consistency=1
3、创建主从同步的用户
mysql> grant all on *.* to 'slave'@'%' identified by '1';
4、重启mysql服务,因为修改了配置文件,重启既能使配置文件生效也能使创建的用户更新到数据库
注:如果主从服务器数据不统一,需要统一数据
[root@localhost ~]# mysqldump -uroot -p1 --all-databases > b.sql
# 导出数据库数据到当前目录下以b.sql命名
[root@localhost ~]# scp b.sql [email protected]:./ 将数据远程复制到从服务器
从服务器:
1、关闭防火墙selinux,一定要确保关闭了
2、修改mysql的配置文件
[root@localhost ~]# vim /etc/my.cnf
log-bin
server-id=2
gtid_mode = ON
enforce_gtid_consistency=1
master-info-repository=TABLE
relay-log-info-repository=TABLE
//这两个参数会将master.info和relay.info保存在表中,默认是Myisam引擎,官方建议用
relay_log_recovery= on
[root@localhost ~]# systemctl restart mysqld //重启服务
注意:主从服务器数据不一致需要先同步一下
mysql> source b.sql #需要进入数据库执行source命令 source+数据库文件
3、编辑mysql文件
mysql> edit
CHANGE MASTER TO
MASTER_HOST='192.168.242.138',
MASTER_USER='slave',
MASTER_PASSWORD='1',
MASTER_AUTO_POSITION=1; 保存退出wq
mysql> ;
mysql> start slave;
mysql> show slave status \G
可以在主服务器数据库创建库等数据验证是否成功。
一、数据库集群部署(省略,以上文gtid主从复制为集群)
二、ngin+php部署
1、安装ngin+php并启动
[root@wordpress yum.repos.d]# yum -y install nginx php php-fpm php-mysql php-gd gd
[root@wordpress yum.repos.d]# systemctl start nginx php-fpm
2、直接进行产品上线(网站发布目录采用默认的)
[root@wordpress ]# wget http://www.xingdiancloud.cn:92/index.php/s/WZQJHBSPnMcSyMs/download/wordpress-4.9.1-zh_CN.tar.gz
[root@wordpress ~]# tar xf wordpress-4.9.1-zh_CN.tar.gz
[root@wordpress ~]# cp -r wordpress/* /usr/share/nginx/html/
3、nginx配置(开启nginx+php的连接)
先把原有的/etc/nginx/nginx.conf删除,然后把备用的改名
[root@wordpress ~]# rm -rf /etc/nginx/nginx.conf #这个文件内的内容不适合修改,难度比较大
[root@wordpress ~]# cp /etc/nginx/nginx.conf.default /etc/nginx/nginx.conf
vim /etc/nginx/nginx.conf
然后找到下图位置进行修改
三、在数据库主从集群中创建一个库,用来存放这个项目产生的数据
主服务器:
mysql> create database wordpress;
在浏览器输入web端的ip地址192.168.242.137,出现以下页面。之后按照提示做就行