AB、主从复制
一,什么是主从复制
1,主从复制
- 是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;
- 主数据库一般是准实时的业务数据库。
2,主从复制的作用
1.做数据的热备,
- 作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
2.架构的扩展。
- 业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
3.读写分离,使数据库能支撑更大的并发。
- 1–在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)
- 2–在从服务器进行备份,避免备份期间影响主服务器服务;(确保数据安全)
二,主从复制的原理
- 实现整个主从复制,需要由slave服务器上的IO进程和Sql进程共同完成.
- 要实现主从复制,首先必须打开Master端的binary log(bin-log)功能,
- 因为整个MySQL 复制过程实际上就是Slave从Master端获取相应的二进制日志,然后再在自己slave端完全顺序的执行中继日志中所记录的各种操作。
- 1,在主库上把数据更改(DDL DML DCL)记录到二进制日志(Binary Log)中。
- 2, 备库I/O线程将主库上的日志复制到自己的中继日志(Relay Log)中。
- 3, 备库SQL线程读取中继日志中的事件,将其重放到备库数据库之上。
master 负责写操作 -----A主库
slave relay-log -----B从库
I/O 负责通信读取binlog日志
SQL 负责写数据
步骤一
- 主库数据的更新事件(update、insert、delete)被写到binlog
步骤二
- 从库发起连接,连接到主库
步骤三
- 此时主库创建一个binlog dump thread线程,把binlog的内容发送到从库
步骤四
- 从库启动之后,创建一个I/O线程,读取主库传过来的binlog内容并写入到relay log.
步骤五
- 从库创建一个SQL线程,从relay log里面读取内容,将更新内容写入到slave的db.
三,主从复制的作用及可以解决的问题
主从复制的作用
- 1.主数据库出现问题,可以切换到从服务器。
- 2.可以进行数据库层面的读写分离。
- 3.可以在从数据库上进行日常备份。
主从复制可以解决的问题
数据分布
- 随意开始或停止复制,
并在不同地理位置分布数据备份。负载均衡
- 降低单个服务器的I/O压力。
高可用和故障切换
- 帮助应用程序避免单点失败
升级测试
- 可以用更高版本的MySQL
作为从库。
四,M-S 架构GTID 基于事务ID复制
1,什么是GTID
- 全局事务标识:global transaction identifiers
- 是用来代替传统复制的方法,GTID复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置。
2,GTID工作原则
- 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。
3,部署主从复制
准备两台机器一主一从
关闭防火墙和selinux。—两台机器环境必须一致。时间也得一致,安装mysql 15.7
安装详细看博主博客,里有详细的安装过程
# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# vim /etc/yum.repos.d/mysql-community.repo
#yum -y install mysql-community-server
省略......
# systemctl start mysqld
# systemctl enable mysqld
# netstat -lntp | grep 3306
\\两台机器以上操作一样
主服务器操作
配置主服务器的配置文件
vim /etc/my.cnf
插入以下内容
server-id=1
\\定义server id master必写
log-bin = mylog
\\开启binlog日志,master比写
gtid_mode = ON
\\开启gtid
enforce_gtid_consistency=1
\\强制gtid
# systemctl restart mysqld
\\重启
给主服务器创建用户
mysql> grant replication slave,reload,super on *.* to 'slave'@'%' identified by 'Xin@12345!';
mysql> flush privileges;
主服务器注意事项
- 生产环境中密码采用高级别的密码,实际生产环境中将’%'换成从服务器的ip
- 如果不成功删除以前的binlog日志
- replication slave:拥有此权限可以查看从服务器,从主服务器读取二进制日志。
- super权限:允许用户使用修改全局变量的SET语句以及CHANGE MASTER语句
- reload权限:必须拥有reload权限,才可以执行flush [tables | logs | privileges]
从服务器操作
配置从服务器的配置文件
# vim /etc/my.cnf
插入以下内容
server-id=2
gtid_mode = ON
enforce_gtid_consistency=1
master-info-repository=TABLE
relay-log-info-repository=TABLE
连接主服务器
# systemctl restart mysqld
# mysql -uroot -p'xin@123'
mysql> \e
change master to
master_host='master1',
\\主ip 地址 最好用域名
master_user='授权用户',
\\主服务上面创建的用户
master_password='授权密码',
master_auto_position=1;
-> ;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
\\启动slave角色
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
\\查看状态,验证sql和IO是不是yes。
测试主从复制
在主数据库插入数据,创建数据,更新、删除等操作,看看从服务器有没有同步
主从复制 bin log 日志方式
两台机器做hosts 解析
vim /etc/hosts
添加域名解析
192.168.246.135 mysql-master
IP 解析名(自定义)
192.168.246.136 mysql-slave
安装mysql
# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
略...
# systemctl start mysqld
# systemctl enable mysql
配置主服务器
- 1、在主服务器上,必须启用二进制日志记录并配置唯一的服务器ID。需要重启服务器。
编辑mysql 配置文件 my.cnf
# vim /etc/my.cnf
添加以下内容
[mysqld]
log-bin=/var/log/mysql/mysql-bin
server-id=1
创建日志目录,并赋予权限
# mkdir /var/log/mysql
# chown mysql.mysql /var/log/mysql
重启服务
# systemctl restart mysqld
修改mysql密码,并创建mysql主从同步用户
# grep pass /var/log/mysqld.log
# mysqladmin -uroot -p'Ns0_3jgPIM*5' password 'xin@12345'
# mysql -uroot -p'xin@12345'
mysql> GRANT REPLICATION SLAVE ON *.* TO 'lin'@'%' identified by 'xin@12345';
mysql> flush privileges;
查看用户信息
mysql> show master status\G
配置从数据库
编译mysql 的配置文件my.cnf
# vim /etc/my.cnf
[mysqld]
server-id=2
重启服务,并修改密码
# systemctl restart mysqld
# grep pass /var/log/mysqld.log
# mysqladmin -uroot -p'ofeUcgA)4/Yg' password 'xin@12345'
登入数据库,连接主服务器的用户bin log日志
# mysql -uroot -p'xin@12345'
mysql> \e
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='lin',
MASTER_PASSWORD='xin@12345!',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=849;
mysql> ;
mysql> start slave;
mysql> show slave status\G
\\查看从服务状态
IO SQL 显示yes 为主从配置成功
在主库更新数据,查看从库是否同步
参数解析
参数解释:
CHANGE MASTER TO
\\解释器
MASTER_HOST='master2.example.com',
\\主服务器ip 或 域名解析名
MASTER_USER='xin',
\\主服务器用户
MASTER_PASSWORD='password',
\\用户密码
MASTER_PORT=3306,
\\端口
MASTER_LOG_FILE='master2-bin.001',
\\binlog日志文件名称
MASTER_LOG_POS=4,
\\日志位置
故障排查
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,一个个的检查:
检查主从server_id
检查主库
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 |
+---------------+-------+
1 row in set (0.01 sec)
检查从库
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 2 |
+---------------+-------+
1 row in set (0.01 sec)
server_id不一样,排除。
查看主从状态
查看主库
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
查看从库
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 306 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
File一样,排除。
查看自动配置文件里的server-uuid
# vim /var/lib/mysql/auto.cnf
[auto]
server-uuid=4f37a731-9b79-11e8-8013-000c29f0700f
主从库查看方式一样
- 最后检查发现他们的auto.cnf中的server-uuid是一样的
- 修改uuid并重启服务