可用性级别(指标) | 年度宕机时间 | 描述 | 叫法 |
---|---|---|---|
99% | 3.65天/年 | 基本可用系统 | 2个9 |
99.9% | 8.76小时/年 | 可用系统 | 3个9 |
99.99% | 52.6分钟/年 | 高可用系统 | 4个9 |
99.999% | 5.3分钟/年 | 抗故障系统 | 5个9 |
99.9999% | 32秒/年 | 容错系统 | 6个9 |
计算方法:
1年 = 365天 = 8760小时 99% = 8760 * 1% = 8760 * 0.01 = 87.6小时=3.65天 99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时 99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟 99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟
简单来说,master将数据库的改变写入 二进制日志 ,slave同步这些二进制日志,并根据这些二进制日志进行 数据重演操作 ,实现数据异步同步。
详细描述:
当主从同步配置完毕后:
relay log
中继日志
作用:记录从(slave)服务器接收来自主(master)服务器的二进制日志.
场景:用于 主从复制
master主服务器将自己的二进制日志发送给slave从服务器,slave先保存在自己的 中继日志中 ,然后再执行自己本地的relay log里的sql达到数据库更改和master保持一致。
如何开启?
默认中继日志没有开启,可以通过修改配置文件完成开启,如下
# vim my.cnf [mysqld] #指定二进制日志存放位置及文件名 relay-log=/mysql_3306/data/relaylog
默认情况下,master接受读写请求,slave只接受读请求以减轻master的压力。
**优点:**进一步分担读压力
**缺点:**slave1 出现故障,后面的所有级联slave服务器都会同步失败
优点 :解决上面的slave1的单点故障,同时也分担读压力
缺点:间接增加master的压力(传输二进制日志压力)
特点:
从命名来看,两台master好像都能接受读、写请求,但实际上,往往运作的过程中,同一时刻只有其中一台master会接受写请求,另外一台接受读请求。
注意:在配置MySQL主从架构时,必须保证数据库的版本高度一致,这里同一统一版本为5.7.31
两个Linux服务器
编号 | 主机名称 | 主机ip | 角色信息 |
---|---|---|---|
1 | master | 192.168.44.120 | master服务器 |
2 | slave | 192.168.44.150 | slave从服务器 |
由于两台机器处于集群架构,需要互相连接。绑定主机名称与IP地址到/etc/hosts
# vim /etc/hosts 192.168.44.120 master 192.168.44.150 slave
上传MySQL软件包到Master与Slave服务器
在Master端安装、初始化以及运行mysql软件
安装需求:
选项 | 值(自定义也可以采用默认形式) |
---|---|
安装路径 | /usr/local/mysql |
数据路径 | /usr/local/mysql/data |
端口号 | 3306 |
vim mysql.sh #!/bin/bash yum install libaio -y tar -xf mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz rm -rf /usr/local/mysql mv mysql-5.7.31-linux-glibc2.12-x86_64 /usr/local/mysql useradd -r -s /sbin/nologin mysql rm -rf /etc/my.cnf cd /usr/local/mysql mkdir mysql-files chown mysql:mysql mysql-files chmod 750 mysql-files bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql &> /root/password.txt bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data cp support-files/mysql.server /etc/init.d/mysqld service mysqld start echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile source /etc/profile # source mysql.sh
Shell脚本其实就是命令的堆砌,把一堆Linux命令写在同一个文件中,一起执行。
# mysql_secure_installation 先输入刚刚默认生成的密码(保存在/root/psssword.txt里) 再设置新密码 确认新密码 再直接回车 后面一路y
# cd /usr/local/mysql # vim my.cnf [mysqld] basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/tmp/mysql.sock port=3306 log-error=/usr/local/mysql/data/master.err log-bin=/usr/local/mysql/data/binlog => 一定要开启二进制日志 server-id=10 character_set_server=utf8mb4 => utf8mb4相当于utf8升级版 配置完成后,重启mysqld服务 # service mysqld restart # chkconfig --add mysqld # chkconfig mysqld on
① 安装MySQL软件
# vim mysql.sh #!/bin/bash yum install libaio -y tar -xf mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz rm -rf /usr/local/mysql mv mysql-5.7.31-linux-glibc2.12-x86_64 /usr/local/mysql useradd -r -s /sbin/nologin mysql rm -rf /etc/my.cnf cd /usr/local/mysql mkdir mysql-files chown mysql:mysql mysql-files chmod 750 mysql-files cp support-files/mysql.server /etc/init.d/mysqld echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile source /etc/profile
执行脚本文件
# source mysql.sh
相对于主服务器MySQL的安装与配置,从服务器端不需要进行初始化操作,因为其数据将来都来自于主服务器。
② 配置my.cnf文件
# cd /usr/local/mysql # vim my.cnf [mysqld] basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/tmp/mysql.sock port=3310 log-error=/usr/local/mysql/data/slave.err relay-log=/usr/local/mysql/data/relaylog => 开启中继日志 server-id=100 character_set_server=utf8mb4
③ 把master主服务器的数据目录同步到slave从服务器
—把master服务器中的mysqld停止掉
# service mysqld stop
# rm -rf /usr/local/mysql/data/auto.cnf
3.把master服务器中/usr/local/mysql中的data目录拷贝一份到slave从服务器的/usr/local/mysql目录
# rsync -av /usr/local/mysql/data [email protected]:/usr/local/mysql/
service mysqld start
④ 配置master-slave主从同步
1.在 master 主服务器中创建一个账号,专门用于实现数据同步
MySQL5.7及以下版本:
mysql> grant replication slave on *.* to 'slave'@'192.168.44.%' identified by '123';
MySQL新版本中:
mysql> create user 'slave'@'10.1.1.%' identified by '123'; mysql> grant replication slave on *.* to 'slave'@'10.1.1.%'; mysql> flush privileges;
2.在master中锁表,然后查看二进制文件的名称及位置
mysql> flush tables with read lock; Query OK, 0 rows affected (0.00 sec) mysql> show master status; +---------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+----------+--------------+------------------+-------------------+ | binlog.000003 | 449 | | | | +---------------+----------+--------------+------------------+-------------------+
3.在slave从服务器中,使用change master to指定主服务器,并实现数据同步
mysql> change master to master_host='192.1668.44.120',master_user='slave',master_password='123',master_port=3306,master_log_file='binlog.000003',master_log_pos=449; master_host:主机的IP地址 master_user:主机的user账号 master_password:主机的user账号密码 master_port:主机MySQL的端口号 master_log_file:二进制日志文件名称(从上一步操作获取) master_log_pos:二进制日志文件位置 (从上一步操作获取)
技巧:主从复制的change master to语句记不住怎么办?答:求帮助,mysql> help change master to; CHANGE MASTER TO MASTER_HOST='master2.example.com', MASTER_USER='replication', MASTER_PASSWORD='password', MASTER_PORT=3306, MASTER_LOG_FILE='master2-bin.001', MASTER_LOG_POS=4, MASTER_CONNECT_RETRY=10;
4.启动slave数据同步
mysql> start slave; mysql> show slave status\G
常见问题解决方案
在配置主从时,一般遇到错误,大部分都是change master to语句写错了(80%),解决方案:
mysql> stop slave; mysql> reset slave; mysql>change master to master_host='192.1668.44.120',master_user='slave',master_password='123',master_port=3306,master_log_file='binlog.000003',master_log_pos=449; mysql> start slave;
⑤ 主MASTER服务器解锁
mysql> unlock tables; Query OK, 0 rows affected (0.01 sec)
server-id
不一致先在主服务器master上创建测试数据
mysql> create database db_test; mysql> use db_test; mysql> create table tb_student ( -> id int auto_increment primary key, -> name varchar(20), -> sex enum('男','女') -> ) default charset=utf8mb4; mysql> insert into tb_student values (null,'张三','男'); mysql> insert into tb_student values (null,'李四','男');
在从服务器slave上查看数据是否同步
mysql> use db_test; mysql> select * from tb_student; +----+--------+------+ | id | name | sex | +----+--------+------+ | 1 | 张三 | 男 | | 2 | 李四 | 男 | +----+--------+------+
这时我们在从服务器slave上插入一条数据
mysql> insert into tb_student values(null,'老王','男'); mysql> insert into tb_student values(null,'老六','女');
再往主服务master服务器上插入这两条数据
mysql> insert into tb_student values(null,'老王','男'); mysql> insert into tb_student values(null,'老六','女');
再在从服务器上查看状态
mysql> show slave status\G
遇到以上问题:如果数量较少,还可以通过跳过当前语句的方式解决。但是如果从服务器写入数据过多,则以上架构必须要重新搭建了!
解决方案:
问:
如果由于人为操作或者其他原因直接将数据更改到从服务器导致数据同步失效,怎么解决?
答:可以通过变量 sql_slave_skip_counter
临时跳过事务进行处理
SET GLOBAL sql_slave_skip_counter = N N代表跳过N个事务 举例说明: mysql> SET GLOBAL sql_slave_skip_counter=1; mysql> stop slave; mysql> start slave; 注意: 1. 跳过事务应该在slave上进行 2. 传统的AB复制方式可以使用变量:sql_slave_skip_counter,基于GTIDs的方式不支持
执行完以上操作后,就又可以同步了
GTIDs(Global transaction identifiers) 全局事务标识符 ,是mysql 5.6新加入的一项技术
当使用GTIDs时,每一个事务都可以被 识别并且跟踪
添加新的slave或者当发生故障需要将master身份或者角色迁移到slave上时,都无需考虑是哪一个二进制日志以及哪个position值, 极大简化了相关操作
GTIDs是完全基于事务的,因此 不支持MYISAM存储引擎
GTID由source_id和transaction_id组成:
1)source_id来自于server_uuid,可以在auto.cnf中看到
2)transation_id是一个序列数字,自动生成.
接下来我们就利用已有的环境升级至基于GITDs的Replication
〇 思路
修改 master
服务器的 my.cnf
配置文件
# vim my.cnf 在末尾添加一下内容 gtid-mode=on log-slave-updates=1 enforce-gtid-consistency
再修改 slave
服务器的 my.cnf
配置文件
# rm -rf /usr/local/mysql/data/binlog.* # vim my.cnf ... log-bin=/usr/local/mysql/data/binlog => 必须要开启二进制 gtid-mode=on log-slave-updates=1 enforce-gtid-consistency skip-slave-start => 当MASTER主服务器GTIDs没有启动时,跳过SLAVE服务器的启动
说明:
1)开启GITDs需要在master和slave上都配置gtid-mode,log-bin,log-slave-updates,enforce-gtid-consistency(该参数在5.6.9之前是–disable-gtid-unsafe-statement)
2)其次,slave还需要增加skip-slave-start参数,目的是启动的时候,先不要把slave起来,需要做一些配置
3)基于GTIDs复制从服务器必须开启二进制日志!
主从都要重新启动
# service mysqld restart
mysql> set @@global.read_only=ON;
mysql> stop slave; mysql> reset slave; mysql> change master to master_host='192.168.44.120',master_user='slave',master_password='123',master_port=3306,master_auto_position=1; 注意: 1.确保有复制用户 2.主要区别于传统复制的参数是:master_auto_position=1 mysql> start slave; mysql> show slave status\G
set @@global.read_only=OFF;
在主服务器上插入数据
mysql> use db_test; mysql> insert into tb_student values (null,'小明','男');
在从服务上传查询测试
mysql> use db_test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from tb_student; +----+--------+------+ | id | name | sex | +----+--------+------+ | 1 | 张三 | 男 | | 2 | 李四 | 男 | | 3 | 老王 | 男 | | 4 | 老六 | 女 | | 5 | 赵六 | 女 | | 6 | 小明 | 男 | +----+--------+------+
方法一:跳过事务
先模拟写入数据,在从服务器上
mysql> insert into tb_student values (null,'八戒','男');
去 data
目录下找 relay.*的文件查看
通过大概时间找到要跳过的事物
指定需要跳过的GTIDs编号 SET GTID_NEXT='aaa-bbb-ccc-ddd:N'; 开始一个空事务 BEGIN; COMMIT; 使用下一个自动生成的全局事务ID。 SET GTID_NEXT='AUTOMATIC'; 举例说明: mysql> stop slave; mysql> SET @@SESSION.GTID_NEXT= 'bc4b2e0e-29a4-11ed-a811-000c29492e7c:2'/*!*/; mysql> BEGIN; mysql> commit; mysql> SET @@SESSION.GTID_NEXT= 'AUTOMATIC'; mysql> start slave; mysql> show slave status\G 说明:需要跳过哪个事务,需要手动查看relaylog文件得到 [root@slave1 data]# ../bin/mysqlbinlog relay.000003|less
方法二:重新同步data目录,重新change master to…