记录备忘。
参考博文:https://blog.csdn.net/wzy0623/article/details/90081518
目录
一、概述
二、binlog简介
三、刷盘方式
四、复制流程
五、实验
5.1 环境规划
5.2 mysql安装
5.3 配置复制
5.3.1 停机
5.3.2 联机
简单说,复制就是将一个MySQL数据库服务器(主库)的数据复制到一个或多个MySQL数据库服务器(从库)。复制的桥梁就是二进制日志。
复制给主库增加的开销主要体现在启用二进制日志带来的I/O,但是开销并不大,MySQL官方文档中称开启二进制日志会产生1%的性能损耗。出于对历史事务备份以及从介质失败中恢复的目的,这点开销是非常必要的。除此之外,每个从库也会对主库产生一些负载,例如网络和I/O开销。当从库读取主库的二进制日志时,可能会造成一定的I/O开销。如果从一个主库上复制到多个从库,唤醒多个复制线程发送二进制日志内容的开销将会累加。但所有这些复制带来的额外开销相对于应用对MySQL服务器造成的高负载来说是很小的。
二进制日志包含描述数据库更改的事件,如建表操作或对表数据的更改等。通过设置log-bin系统变量开启二进制日志,MySQL 8中缺省是开启的。
二进制日志有STATEMENT、ROW、MIXED三种格式,通过binlog-format系统变量设置:
二进制日志的存放位置最好设置到与MySQL数据目录不同的磁盘分区,以降低磁盘I/O的竞争,提升性能,并且在数据磁盘故障的时候还可以利用备份和二进制日志恢复数据
主从数据是否一致还与重做日志和二进制日志的写盘方式有关。innodb_flush_log_at_trx_commit和sync_binlog系统变量分别控制两者的落盘策略
innodb_flush_log_at_trx_commit
控制事物提交是否刷盘,有0、1、2三个可选值。
0:表示每秒进行一次刷新,但是每次事务提交不进行任何操作
1:表示每次事务提交都会进行刷新,这是最安全的模式
2:表示每秒刷新,每次事务提交时不刷新,而是调用write将重做日志缓冲区里面的内容刷到操作系统页面缓存
从数据安全性和性能比较三种策略的优劣为:0表示每秒刷新,每次事务提交不进行任何操作,所以MySQL或操作系统崩溃时最多丢失一秒的事务。1由于每次事务提交都会是重做日志落盘,所以是最安全的,但是由于fsync的次数增多导致性能下降比较严重。2相对于0来说了多了每次事务提交时的一个write操作,此时数据虽然没有落磁,但是只要没有操作系统崩溃,即使MySQL崩溃,那么事务也是不会丢失的。
sync_binlog
MySQL在提交事务时调用MYSQL_LOG::write完成写二进制日志,并根据sync_binlog决定是否进行刷盘。
0:由系统决定什么时候刷
1:每提交一次事务,写一次binlog,并使用fdatasync()同步到硬盘
n:每提交一次事务,写一次binlog,达到sync_binlog 设定的值后,调用fdatasync()同步到硬盘
sync_binlog=N和innodb_flush_log_at_trx_commit=N推荐配置组合 |
|
---|---|
N=1,1 |
适合数据安全性要求非常高,而且磁盘IO写能力足够支持业务,比如充值消费系统 |
N=1,0 |
适合数据安全性要求高,磁盘IO写能力支持业务不富余,允许备库落后或无复制 |
N=2,0或2,m(0 |
适合数据安全性有要求,允许丢失一点事务日志,复制架构的延迟也能接受 |
N=0,0 |
磁盘IO写能力有限,无复制或允许复制延迟稍微长点能接受,例如:日志性登记业务 |
当两个参数设置为双1的时候,写入性能最差,当俩个参数设置为N(N>1 ),M(0 总的来说,MySQL复制有五个步骤: 软件版本 参考 “MySQL安装脚本” 主库上建立复制专属用户(主库) 复制为异步复制,基于master_log_file和master_log_pos,只做整服务器级别的复制,不考虑对个别库表或使用过滤复制的情况。 如果应用允许一定时间的脱机,这种场景下常用的做法是先直接将主库的数据目录整体拷贝到从库,再启动复制。具体步骤如下: 1、停掉复制涉及的实例(主、从库) 2、 将主库的数据目录复制到从库 3、启动所有实例(主、从) 4、配置主从关系 5、查看主从关系是否正常(从库) 另外在MySQL的日志中也有主从同步信息记录。 大多数情况下是不允许停机的,配置复制被要求在不影响线上业务的情况下进行,而且还要求对线上库的影响越小越好。这种场景下有两种备选的复制方案:使用mysqldump程序或使用如XtraBackup的第三方工具。 这两种方案有各自的适用场合: 5.3.2.1 mysqldump方式 1、安装MySQL,见上文“5.2 MySQL安装” 2、从库配置主库的信息(从库) 注意!在上面这条命令中并没有指定主库二进制文件的文件名和位置。 3、用mysqldump建立复制(从库) 4、确认复制状态,见上文“5.3.1 停机”中的第5步 5.3.2.2 xtrabackup方式 1、安装MySQL,见上文“5.2 MySQL安装” 2、安装xtrabackup(主、从) 3、主库导出备份 注意! MySQL用户的密码认证方式是mysql_native_password。MySQL8默认认证方式报错 4、从库解压并恢复 4、配置复制 查看备份中xtrabackup_binlog_info文件,其中记录了binlog-file和binlog-pos 执行命令向主库 5、确认复制状态,见上文“5.3.1 停机”中的第5步 异步复制的几种搭建方式记录完成。 四、复制流程
MySQL会按事务提交的顺序而非每条语句的执行顺序来记录二进制日志。在记录二进制日志后,主库会告诉存储引擎可以提交事务了。
从库会启动一个工作线程,称为I/O线程,I/O线程跟主库建立一个普通的客户端连接
主库上启动一个特殊的二进制日志转储(binlog dump)线程,它会读取主库上二进制日志中的事件,但不会对事件进行轮询。如果从库追赶上了主库,它将进入睡眠状态,直到主库发送信号通知其有新的事件时才会被唤醒。
从库I/O线程会将接收到的事件记录到中继日志中
SQL线程执行最后一步,该线程从中继日志中读取事件并在从库上执行。当SQL线程追赶I/O线程时,中继日志通常已经在系统缓存中,所以重放中继日志的开销很低。五、实验
5.1 环境规划
IP
角色
192.168.56.11
主
192.168.56.12
从
软件名称
OS
CentOS Linux release 7.3.1611 (Core)
MySQL
mysql-8.0.21
路径
用途
/home/mysql/mysql8
MySQL主目录
/home/mysql/mysql8/data
MySQL数据目录
/home/mysql/mysql8/logs/binlog
MySQL二进制日志目录
/home/mysql/mysql8/logs/relaylog
MySQL中继日志目录
5.2 mysql安装
-- 主库执行SQL
create user 'repl'@'192.168.56.%' identified with mysql_native_password by '123456';
grant replication client,replication slave on *.* to 'repl'@'192.168.56.%';
5.3 配置复制
5.3.1 停机
# 主从库都执行
/home/mysql/mysql8/bin/mysqladmin -uroot -p111111 -S/home/mysql/mysql8/logs/mysqld.sock shutdown
# 从库执行,删除原文件否则主从关系建立会有问题
rm -fr /home/mysql/mysql8/data
rm -fr /home/mysql/mysql8/logs
# 主库执行,拷贝数据文件
scp -r /home/mysql/mysql8/data [email protected]:/home/mysql/mysql8/
# 主库执行,如果日志不在data文件夹下,需要吧binlog也拷贝过去
scp -r /home/mysql/mysql8/logs [email protected]:/home/mysql/mysql8/
# 从库执行,修改权限
chown mysql.mysql /home/mysql/mysql8/* -R
# 从库执行,注意!server_id和server_uuid不能重复,确保server_uuid不重复,删掉auto.cnf
rm -fr /home/mysql/mysql8/data/auto.cnf
# 主从库都执行
/home/mysql/mysql8/mysqld start
-- 主库执行SQL,查看binlog信息。
show master status;
mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| bin-log.000006 | 156 | | | |
+----------------+----------+--------------+------------------+-------------------+
-- 从库执行以下SQL,指向主库
CHANGE MASTER TO
MASTER_HOST='192.168.56.11',
MASTER_PORT=3308,
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='bin-log.000006',
MASTER_LOG_POS=156;
-- 从库执行SQL,查看主从关系
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
...............
Connect_Retry: 60
Master_Log_File: bin-log.000006 -- IO线程正在读取主库的binlog
Read_Master_Log_Pos: 156 -- IO线程正在读取主库binlog的pos
Relay_Log_File: relay-log.000002 -- 正在应用的本地应用中继日志
Relay_Log_Pos: 322 -- 中继日志的位置
Relay_Master_Log_File: bin-log.000006 -- SQL线程正在执行操作对应的master的binlog
Slave_IO_Running: Yes -- IO线程状态(No为停止,Yes运行)
Slave_SQL_Running: Yes -- SQL线程状态(No为停止,Yes运行)
.................. -- 省略一些不重要状态
Exec_Master_Log_Pos: 156 -- SQL线程正在执行操作对应的master的pos
.................... -- 省略一些不重要状态
Seconds_Behind_Master: 0 -- 从库落后主库时间,单位秒
...................... -- 省略一些不重要状态
1 row in set (0.00 sec)
5.3.2 联机
优点:无需额外安装,支持部分复制,replicate-do-table=db1.*用这种方法可以只复制db1库,忽略其它事件
缺点:生成主库转储数据的SQL语句,占用空间,主要是恢复慢
优点:支持在线热备份,物理备份备份和恢复速度快
缺点:不支持部分复制,需要额外安装xtrabackup及依赖包-- 从库执行SQL
CHANGE MASTER TO
MASTER_HOST='192.168.56.11',
MASTER_PORT=3308,
MASTER_USER='repl',
MASTER_PASSWORD='123456';
# 从库执行
/home/mysql/mysql8/bin/mysqldump \
--single-transaction \
--all-databases \
--master-data=1 \
--host=192.168.56.11 \
--user=admin \
--password=admin \
--apply-slave-statements | \
/home/mysql/mysql8/bin/mysql -uroot -p111111 -S/home/mysql/mysql8/logs/mysqld.sock
对Innodb表执行非锁定导出。
转储输出包含 CHANGE MASTER TO MASTER_LOG_FILE='binlog.000004', MASTER_LOG_POS=1480的语句。
如果选项值为2,则CHANGE MASTER TO语句将写为SQL注释,因此仅提供信息,不会执行。
如果参数值为1,则该语句不会写为注释,并在重新加载转储文件时执行。
如果未指定选项值,则默认值为1。
转储输出包含STOP SLAVE语句,在输出结尾处添加START SLAVE语句,自动开启复制。# 主库从库都执行
# 下载xtrabackup
cd /usr/local/src
curl -O https://www.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.14/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.14-1.el7.x86_64.rpm
# 安装
yum -y install \
perl \
perl-devel \
libaio \
libaio-devel \
perl-Time-HiRes \
perl-DBD-MySQL\
perl-Digest-MD5 \
perl-DBI \
percona-xtrabackup-80-8.0.14-1.el7.x86_64.rpm
# 主库执行
# 主库xtrabackup备份
xtrabackup -uadmin -padmin --socket=/home/mysql/mysql8/logs/mysqld.sock \
--no-lock --backup --compress --compress-threads=4 \
--target-dir=/home/mysql/mysql8/backup
# 复制到从库
scp -r /home/mysql/mysql8/backup [email protected]:/home/mysql/mysql8/
# 从库执行
# 解压备份需要安装qpress,如果验证不通过执行下 yum update percona-release
yum -y install https://www.percona.com/redir/downloads/percona-release/redhat/1.0-24/percona-release-1.0-24.noarch.rpm
yum -y install qpress
# 解压备份
rm -fr /home/mysql/mysql8/data
mv /home/mysql/mysql8/backup /home/mysql/mysql8/data
xtrabackup --decompress --parallel=4 --remove-original --target-dir=/home/mysql/mysql8/data
# 准备备份
xtrabackup --prepare --target-dir=/home/mysql/mysql8/data
# 启动MySQL
chown mysql.mysql /home/mysql/mysql8/* -R
# 从库执行
cat /home/mysql/mysql8/data/xtrabackup_binlog_info
-- 从库执行
CHANGE MASTER TO
MASTER_HOST='192.168.56.11',
MASTER_PORT=3308,
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='bin-log.000021',
MASTER_LOG_POS=156;