数据库高可用HA实现

1.什么是数据库高可用 

1.1什么是高可用集群

N+1原则:N就是集群,1就是高可用,高可用的核心就是冗余;集群式保证服务最低使用标准的

1.2高可用集群的衡量标准

一般是通过系统的可靠性和可维护性来衡量的

MTTF:平均无故障时间,这是衡量可靠性的

MTTR:衡量系统的可维护性能

HA=MTTF/(MTTF+MTTR)*100%

SLA: 99.999%-表示一年故障时间不超过6分钟 ;普通系统999到9999之间 

1.3实现高可用的三种方式

  • 主从方式(非对称)

      这种方式的组织形式通常都是通过两个节和一个或多个服务器,其中一台作为主节点(active),

另外一台作为备份节点(standy),备份节点应该随时都在检测主节点的健康状况,当主节点发生故障,服务会自动切换到备份

节点保障服务正常运行

数据库高可用HA实现_第1张图片

                                   主从对外方式

  • 对称方式

       两个节点,都运行着不同的服务,且相互备份,相互检测对方的健康,当任意一个节点发送故障,这个节点上的服务就会

自动切换到另一个节点。

  • 多机方式

       包含多个节点多个服务,每个节点都要备份运行不同的服务,出现问题自动迁移

            

              思考:公司的数据库服务主从是否自动切换?

  

1.4 mysql数据的高可用实现 

1.4.1 主从方式(非对称)

  • 资源:两条同版本的mysql数据库 

  • 主从实现的内部运行原理和机制

1.主数据库服务会把数据的修改记录记录进binlog日志,binlog一定要打开

2.从库的i/o进行读取主库的binlog内容后存入自己的relay log(中继日志)中,这个i/o线程会和

主库建立一个普通的客户端连接,然后主库启动一个二进制转储线程 ,i/o线程通过转储线程读取

binlog更新事件,同步完毕后i/o进行sleep,有新的更新会唤醒。(不大清楚)

1.relay log和binlog的格式是一样的,可以用mysqlbinlog读取,也可show

2.show relaylog events in 'relay-log.00001';

目前数据库有两种复制方式 

1.binlog日志点positon

2.GTID方式:全局事务id,也要依赖binlog

3.从服务器的sql进程会从relaylog中读取事件并在从库中重放

从服务器执行重放操作时可以在配置里声明是否写入服务器的binlog日志中

数据库高可用HA实现_第2张图片

1.4.2 配置主从服务步骤

1.4.2.1 binlog日志点方式配置主从同步

  • 配置主从服务器参数

  • 在master服务器上创建用于复制并授权的数据库账号

  • 备份master数据库并初始化slave服务器数据

  • 启动复制链路

master服务配置

chown -R mysql:mysql /usr/local/binlog/ #授权

数据库配置文件(主库):

server_id=153 #主库ip

log_bin=/usr/local/binlog/mysql-bin

 

 

slave服务配置

chown -R mysql:mysql /usr/local/binlog/ #授权

数据库配置文件(从库):

server_id=152 #从库ip

log_bin=/usr/local/binlog/mysql-bin

relay_log=/usr/local/relaylog/relay-bin

relay_log_recovery=1 #当slave宕机后,如果relay log损坏了,导致一部分中继日志没有处理,则放弃所有未完成的,重新获取执行,保证完整性

read_only=on #让从库数据只读,super用户和root用户可写入(super_read_only=on #super不可写入设置,不建议)

skip_slave_start=on #从库的复制链路服务不会随数据库重启而重启,需要手动启动 

#确保数据一致性,通过innoDb的崩溃恢复机制来保护

master_info_repository=TABLE

relay_log_info_repository=TABLE

 

#select * from mysql.slave_master_info;

#select * from mysql.slave_relay_log_info;

疑问:mysql、information_schema是干么用的(思考题)

 

主库授权

use mysql;

grant replication slave on *.* to 'root'@'118.190.173.250' identified by '123456';;  #syncuser用户允许192.168.0.103访问

#密码等级改低,长度改6位 set global validate_password_policy=LOW;    set global validate_password_length=6; 

flush privileges; #刷新权限 

 

 

初始化数据

create database mydbTest1; #建数据库

use mydbTest1; #使用数据库

create table test1(name varchar(10),age int,dateTime dateTime); #建表

insert into test1 values('zhou',10,'2019-12-19 00:00:00');#初始化数据

insert into test1 values('zhou',10,'2019-12-19 00:00:00');#初始化数据

##dump查看数据 mysqldump -uroot-p123456--master-data=2--single-transaction--routines-

-triggers--events--databases mydb > mydb.sql

 

创建复制链路(从库)

CHANGE MASTER TO

MASTER_HOST='115.29.66.116',

MASTER_PORT=3306,

MASTER_USER='root',

MASTER_PASSWORD='123456',

MASTER_LOG_FILE='mysql-bin.000007',

master_LOG_POS=2648;

 

start slave;

show slave status;

 

查看从库更新结果: 实时更新完成

数据库高可用HA实现_第3张图片

 

 

从库的binlog是否写入

  • 默认情况下是不写入的:因为写入binlog会消耗I/O,所以性能会下降,如果需要在从库上恢复数据就到relaylog

里进行导出处理

  • 直接在从库上操作更新语句则会写入binlog

  • 如果就是需要写入?在从库的my.cnf: log_slave_update=on #开启同步并写入binlog

  • 开启同步并写入binlog应用于从到从的情况

#不同步哪些数据库

#master配置文件

binlog-ignore-db=mysql

binlog-ignore-db=mydbTest1

binlog-ignore-db=information_schema

#同步哪些库

binlog-do-db=game 

binlog-do-db=mydb 

 

#slave配置文件

#复制哪些数据库

replicate-do-db=mydb

#不复制哪些数据库

replicate-ignore-db=mysql

 

#指定表复制:忽略不不同的表

replicate-ignore-table=mydbTest1.test4

 

1.4.2.2 GTID的方式进行主从复制

跟position不同点

  • 主从服务器的参数有不同的地方

#在上面的基础上,需要给主从服务器都加上

gtid_mod=on

enforce_gtid_consistency=on #开启强制gtid的一致性确保事务 

  • gtid下复制链路的启动

change MASTER TO

MASTER_HOST='192.168.0.102',

MASTER_PORT=3306,

MASTER_USER='syncuser',

MASTER_PASSWORD='123456',

MASTER_AUTO_POSITION=1;

  • 启动gtid后以下数据库操作不可用

1.create table table name ....select 

2.在一个事务中创建临时表

3.在一个transaction中更新innoDb表和myisam表

 

2.数据库主从复制方式的容灾处理 

2.1mysql支持的复制格式

2.1.1 基于语句的复制(statement)

  • 优点:记录少、只记录执行语句,易懂,占用网络空间少

  • 缺点:insert into table(create_time) values(now()),这个now就不是当时的时间了

2.1.2 基于行复制(row)

  • 优点:几乎没有基于行复制无法处理的场景

  • 缺点:数据量太大了

2.1.3混合类型的复制(MIXED)

mixed格式默认采用statement,出现statement无法精确复制时,用row; 比如用到UUID(),ROW_COUNT()

 

2.2主从切换

练习:自己把主从数据库更换

  • 从库的binlog目前是没有写入的

  • 需要给old主库授权new主库的权限 

  • 并且在old主库上创建复制链路

  • 从库还需要把read_only关闭 

2.3mysql主从复制模式 

  • 异步复制:mysql默认就是异步复制,性能最好,但主从复制数据不一致性概率最大

  • 同步复制:当客户端发过来一个请求后,只有当所有的从库都写入到relay log中才回复给前端

该事务完成,性能最差,但一致性很强

  • 半同步复制:至少一个从库完成relay log写入后就返回事务完成给前端

 

#主从上都要安装

install plugin rpl_semi_sync_master soname='semisync_master.so' 

 

rpl_semi_sync_master_enabled

rpl_semi_sync_master_timeout #单位毫秒,如果主库等待从库回复超过这个时间就自动切换为异步

 

问题:做过主从复制,主从一般都是实时的同步的,如果出现数据库误操作,导致一大片数据错误如何解决?

 

  • update tableName set score=99; 

  • 从库是不是也会被直接更新掉? 

  • 一般情况下,从库对数据的实时性要求都不是非常高

  • 如果我们有一个从库更新可以延时10分钟

  • 如果运气好,在你拿到10分钟前的数据和你更新之间这个表没有操作,是不是完美解决? 

  • 设置一个从库,将延迟时间设置成能够处理和反映的周期长度即可 

stop slave;

change master to master_delay=600 #设置延时600s  sql_delay:600

start slave; 

 

 

 

 

 

你可能感兴趣的:(数据库,mysql)