mysql high availablity

配置一个服务器作为master
配置一个服务器作为slave
将slave连接到master

配置master
修改my.cnf
添加
log-bin       = master-bin
log-bin-index = master-bin.index
server-id     = 1

创建一个用户用于复制(可以为每个slave配置不同的用户)
mysql -uroot -p
create user repl_user;
grant replication slave on . to repl_user identified by 'repl_user';

配置slave
修改my.cnf
添加
server-id = 2
relay-log-index = slave-relay-bin.index
relay-log       = slave-relay-bin

**在master和slave数据库,配置复制的用户的权限,用来配置复制,可以不用root来操作

grant replication slave , reload, create user,super on . to mats@'%' with grant option;
权限说明
创建用户需要 create user
将replication slave权限赋予复制用的账号还需要 grant option 的 replication slave权限
执行 flush log 需要 reload
执行 show master status 和 show slave status 需要 super 或 replacation client
执行change master to 命令 需要 super 权限

连接master
需要知道 master的4个信息: ip,端口,具备replication slave的用户名和密码
用上面配置的mats用户登录slave数据库执行
将slave定向到master
change master to master_host = 'ip' , master_port = 3306, master_user = 'repl_user' ,master_password = 'repl_user';
启动复制
start slave;

观察复制的动作
在master库执行一些语句
create table a(aaa text);
insert value a values("aaa");
select * from a;

flush logs
flush logs 命令强制切换rotate 二进制日志,从而得到一个完整的二进制文件。
查看二进制日志中有那些事件
show binlog events\g

查看指定二进制日志中的事件
show binlog events in 'master-bin.000002'\g

查看当前正在写入的二进制日志文件
show master status;

停止并重置slave,会清空slave上复制用的所有文件,重新开始。
stop slave;
执行reset前需stop slave确保slave上没有活动的复制
reset slave;

重置master,会删除所有二进制日志文件,并清空二进制日志索引。执行前需确保没有slave连接到该master
reset master

克隆master库
在master运行一段时间后,建立新的slave。
通过 change master to 的两个参数,master_log_file和 master_log_pos指定master开始发送日志事件的binlog的位置
r;步骤
1、配置新的slave
2、备份master
3、记下备份对应的binlog位置,即master当前状态的最后一个事件的位置
4、在slave上恢复备份
5、配置slave从这个binlog位置开始复制。

flush tables with read lock;
刷新并锁定数据库,防止binlog位置变化。
show master status;
记录binlog文件和位置
mysqldump --all-database --host=master-1 >backup.sql
备份所有数据库;
unlock tables;
解锁数据库
mysql --host=slave-1 <backup.sql
在slave上恢复
change master to
master_host ='master-1',
master_port='3306',
master_user='slave-1',
master_password='xyzz',
master_log_file='master-bin.000042',
master_log_pos=456552;
在slave库配置slave复制
start slave;
启动复制

mysqldump可以自动执行前面所有步骤
mysqldump --host=master-1 --all-databases --master-data=1 >backup-soruce.sql
对master所有库进行备份, --master-data=1会是mysqldump自动产生change master to 语句 ,其参数为二进制文件位置。
mysql --host=slave-1 <backup-source.sql
直接恢复就可以了
*注意只有克隆master库是菜能执行带--master-data=1参数的 mysqldump,后面克隆slave时这些步骤都要分开执行。
*由于可能有大量数据要同步,在将slave联机前,首先要阅读第六章 数据的一致性管理

克隆slave
只要有一个slave已经在运转,就可以通过这个slave来创建新的slave,而不需要offline master了。
和克隆master的区别在于如何找到binlog的位置。

首先
stop slave;
必须在备份前停止slave的复制。
show slave status;
查找relay_master_log_file 和 exec_master_log_pos 确定从何处启动复制
mysqldump --host='slave'
备份数据

恢复
change master to
master_host ='master-1',
master_port='3306',
master_user='slave-1',
master_password='xyzz',
master_log_file='master-bin.000042',
master_log_pos=456552;
在新slave设置复制的起点
start slave;
启动复制

***创建备份的常见做法是调用flush tables with read lock
然后在数据库被读锁所住时复制一份数据库文件的副本,这比mysqldump要快。
但注意这种方式在innodb中是不安全的。阻止新事物后,innodb还是有可能会写数据文件。
安全的备份innodb的方法
1、关闭服务器,复制数据库文件
2、执行flush tables with read lock 锁表,然后 使用mysqldump --single-transaction 获得一致的快照,这个参数只对innodb有效。
3、执行flush tables with read lock 锁表,执行某种快照方案,如lvm 或者zfs
4、使用mysql企业备份工具或者xtrabackup做mysql联机备份。

stop slave;
show slave status\g
记录slave当前读取到的binlog文件名
show binary logs;
显示master上的binlog文件列表
mysqlbinlog --force --read-from-remout-server --host=master1 --start-datetime='2009-09-25 23:55:00' --stop-datetime='2009-09-25 23:59:59' capult-bin.00004
将slave停止时的binlog文件之后的所有binlog文件名作为参数,用mysqlbinlog查找最后时间点在那个binlog里以及这个的事物号。
start slave until master_log_pos='capulet-bin.000004',master_log_pos=2650;
恢复到指定位置,命令会立刻返回,恢复动作会在后台运行。
select master_post_wait('capulet-bin.000004',2650);
阻塞只到恢复到指定位置

binlog
隐式信息implicit必须显示化

当前数据库
用户自定义变量值
rand函数的种子
当前时间
auto_increment字段的插入值
调用last_insert_id函数返回值
线程ID
load data infile语句

binlog过滤器
my.cnf
[mysqld]
binlog-do-db=run_db
binlog-ignore-db=one_db
binlog-ignore-db=two_db
过滤是根据线程上下文的当前数据库来过滤的,有表名其他数据库前缀是没用的,当前数据库只要匹配上,语句就会被滤掉
**不推荐使用binlog--db这个功能,而是使用replicate--db在slave上滤掉事件,binlog-*-db选项会把语句从二进制日志中过滤出去,这样一旦发生崩溃无法从二进制日志恢复数据库。

存储过程,函数,触发器,事件,的同步,很少用到略过(用到的看p62)
其他特殊结构
LOAD_FILE函数,这个函数要求slave上也要有文件,可以用load data infile来替换

非事物型变更和错误处理
复制不能处理任意的非事务型存储引擎

将事物写入日志
以下几种情况会开始一个事物
start transaction 或 begin 命令
autocommit=1
autocommit=0 使用commit 或rollback

并不是事物开始后所有语句都属于这个事物,
例外1、非事务型语句
2、隐式提交的语句 1 写文件的语句ddl语句 2 修改mysql数据表的语句 3 锁定表的,用于管理的 load data infile

事物缓存
服务器为每个线程保留了一个事物缓存transaction cache 语句将放在事物缓存里,当事物提交时,写入二进制日志。

如何写入非事务型语句和其带来的复制问题
mysql5.6开始,可以通过binlog_direct_non_transactional_updates 强制非事务型语句直接写入二进制日志。

使用XA进行分布式事物处理。
mysql 5.0版本,服务器内部使用xa来协调二进制日志和存储引擎。

二进制日志的组提交
每个事物都要写盘会带来性能问题,多个独立事物可以按组的形式一起写入磁盘,这就是组提交(group commit)。
mysql 5.6增加了二进制日志组提交(binary log group commit )
每个线程只能有一个事物进入组
组提交的三个步骤
步骤       步骤互斥体      步骤队列互斥体
flush      LOCK_log       LOCK_flush_queue
sync       LOCK_sync      LOCK_sync_queue
commit     LOCK_commit    LOCK_commit_queue
每个步骤的操作如下:
flush步骤:每个会话的事物按照他们进入flush的顺序flush到二进制日志
sync步骤: 执行一个fsync调用,写盘   (最慢,如果有阵列卡写缓存会快很多)
commit步骤:存储引擎中事物的提交顺序与他们登记的一致
事物必须按顺序提交,这样在线备份方法(xtrabackup或mysql企业备份)才能正确操作,如果有特殊需求可以通过binlog_order_commits控制事物是否按顺序提交,默认为ON。平行commit并不会明显提高性能!!
flush步骤的优化,flush并不是处理整个flush队列,是每次处理队列中的一个事务,如果此时还有事物入队,则会持续flush,让更多的事物入队。这回极大提高吞吐,但会产生延迟
可以通过 binlog_max_flush_queue_time参数,控制leader线程从flush队列搬运会话的时间,单位为毫秒,超时则直接flush整个队列。注意这个时间并不是事物延迟的阀值,只是在这个时间以后要leader线程flush整个队列进入sync步骤

基于行的复制
前面介绍了基于语句的复制,可能会带来的各种问题,不确定函数,自增,非事务型语句,update、delete、insert语句包含limit语句(??)
有这些情况时,最好复制那些插入表中的真实数据,即基于行的复制。
选择复制时基于行还是基于语句,要考虑如下问题
1、这些语句是否会操作大量行?
2、是否需要知道执行了那些语句? 基于行的复制难以解码(mysql5.6可以语句和行一起也如二进制日志,见后面)
3、基于语句的复制模型比较简单,基于行的复制如果出问题,可能比较难解决。
4、如果master和slave的数据不同,语句更新的数据也会不同。

启用基于行的复制
写入二进制日志时,通过 binlog-format选项来控制使用哪种模式
改值可以是全局变量,也可以是会话变量。 会话可以暂时切换模式,但需要super权限,会话变量也要。
取值为STATEMENT 或 MIXED 或 ROW
确保服务器启动时使用基于行的复制需停止master并更改配置文件
[mysqld]
添加
binlog-format = ROW

使用混合模式 MIXED
从mysql5.1开始 binlog-format默认为MIXED 也是推荐的值
原理是,正常情况下使用语句复制,不安全的语句则切换到行复制。
总结一下,如下情况混合模式需要切换到行复制:
1、语句调用了
UUID函数
用户自定义函数
CUCURRENT_USER
或USER函数
LOD_FILE函数
2、一个语句同时更新了两个或两个以上含有auto_increment的列的表
3、语句中使用了服务器变量
4、存储引擎使用了不允许基于语句的复制,如mysql cluster引擎
这些并不完整,详见mysql参考手册

二进制日志的管理


保证复制不丢数据 的最重要的仨选项


[mysqld]
sync_binlog=1;
innodb_flush_log_at_trx_commit=1;
innodb_support_xa=1;


二进制日志和系统崩溃安全
事务型存储引擎会保证数据库和二进制日志的一致性,
sync-binlog=1时每1次提交(5.6是每二进制日志组提交)写盘一次。确保每个事务都写盘,最大限度保证一致性。

binlog文件轮换
4中行为导致轮换:
1服务器停止
2binlog文件达到最大限制,可以通过binlog-cache-size控制binlog文件大小
3二进制日志被显式刷新,flush logs命令将所有日志写入磁盘,然后轮换
4服务器上发生了事故
binlog文件第一个事件是Format_description事件,有三个地方值得关注:
binlog-in-use标记,标识文件是否被正确关闭,防止正在写binlog时系统崩溃,binlog不完整带来的各种问题。
binlog文件格式版本,
服务器版本,
为了在系统系统崩溃时也能安全轮换二进制日志,服务器采用(write-ahead)预写策略。
5.6版本之前二进制日志可能被部分写入,5.6版本中,二进制日志调整为删除那些部分写入的事物。

事故
术语事故(incident)指不产生数据变更,但必须诶如二进制日志的事件,比如服务器启停。
有两种incident事件
stop,表示服务器正常停止,崩溃不会有。slave重放会忽略stop事件
Incident,5.1中新引入,包含一个标识符指定发生的事故类型,表明服务器被迫执行了一些操作,可能导致二进制日志变更丢失。如数据库重新装载,或非事务型事件过大。slave遇到Incident事件会因错误停止。

清除binlog文件
设置expire-logs-days可以自动清除旧的binlog文件。值代表存储binlog的天数。
手工清除binlog文件可以使用purge binary logs命令
purge binary logs before datetime 清除给定时间之前的所有文件,如果时间在某日志中间,这个日志之前的所有文件都被删除 '2008-06-22 13:00:00'  三天前 DATE_SUB( NOW( ), INTERVAL 3 DAY)
purge binary logs to 'filename' 清除给定文件前的所有文件。 show master logs显示的 filename都的文件都被删除

mysqlbinlog实用工具
针对基于语句的复制mysqlbinlog输出的是可执行的sql,针对基于行的复制,会在第8章讨论。
基本用法
连接到master
show binary logs;

mysqlbinlog         \
--short-form     \
--force-if-open  \
--base64-output=never \
/var/lig/mysql/mysqldl-bin.000038
short-form 只输出sql语句,不输出注释信息
force-if-open 禁止输出binlog文件未被正确关闭的警告
base64-output=never 阻止输出base64编码的事件,基于语句的复制不需要这个
限制输出结果
start-position=
stop-position=
start-datetime=
stop-datetime=

读取远程文件
--read-from-remote-server
--host=master.example.com
--user=repl_user
--password
只需给出binlog文件名字,不需要路径

读取日志文件的原始二进制文件
--raw 可以获取binlog文件的备份,当无法访问master机器的shell,但有mysql复制权限时。
命令只存储文件,不解析。
mysqlbinlog --raw  --read-from-remote-server --host=master.example.com --user=repl_user --password master-bin.000012 master-bin.000013 master-bin.000014
另外一些有用的选项
--result-file=prefix 本地文件名的前缀(可以是目录名)默认是空串,按master上相同文件名写入。
--to-last-log     只需给定开始的日志文件,会自动获取后面所有日志文件
--stop-never      到达最后一个也不停止获取,会继续等待获取。在做及时备份恢复时很有用,见15章 备份和mysql复制

解释事件
--hexdump选项输出日志的实际字节

二进制日志的选项和变量
expire-log-days=days     binlog文件保留的天数,当日志轮换或服务器重启时,比这个数旧的文件会删除,默认0,永远不删
log-bin[=basename]       开启二进制日志,建议必须指定文件名,不指定参数会使用主机名作为binlog文件名,为防止改变主机名导致文件名变化。
log-bin-index[=filename]  设定索引文件名,和bin-log一样必须指定文件名。可以加路径放到不同的地方
log-bin-trust-function-creators    允许在slave上创建存储函数,可能会创建一些有安全问题的函数。?
binlog-cache-size=bytes             事物缓存在内存中的字节,超过此值会写盘,如果经常有大事物,适当调大可提高性能
max-binlog-size=bytes         binlog文件的大小。注意如果事物或语句超过了max-binlog-size,日志将轮换,该事物作为一个整体写入一个新文件(这时如果事务较大,文件大小有可能会超过设置值)。 **事物永远不会被分割到不同的binlog文件,
sync-binlog=period            指定多少个事物(组)调用fdatasync(2)写一次盘。1时表示一个事物写一次盘。不丢数据 0表示信任操作系统,按操作系统机制刷盘。
read-only                  阻止任何客户端线程(除具有super权限的slave线程和用户)更改服务器上的任何数据(不包括临时表)。保护slave数据是有用。

基于行的复制的参数
binlog-format
STATEMENT      基于语句
ROW            基于行,ddl语句仍然是语句
MIXED          基于语句的复制的安全版本,5.1以后推荐此模式。混合模式中默认以语句方式复制,语句不安全时,切换为行复制模式。
binlog-max-row-event-size        指定最大行复制事件的大小,由于事件处理时被完全读入内存,该参数粗略控制包含行的时间的大小,防止消耗过多内存。
binlog-rows-query-log-evnets     (mysql 5.6新增)在行事件前向二进制日志添加一个信息事件(informational event),包含产生这些行的原始查询。用来更好的分析行复制。
必须master和slave都在5.6.2版本,之前的版本slave会因为无法解析该事件而停止。

小结

面向高可用性的复制
冗余

应急计划
slave故障
master故障
relay故障

灾难恢复

方法

热备份
master  standby slave 三台机器

处理切换
master切换到standby
执行切换的基本思路:在完全相同的位置停止运行slave和standby然后把slave重定向到standby,

查看停止后,两个备机的master binlog的位置。
standby>show slave status\g
slave>show slave status\g
如果slave比standby靠后,则通过命令使slave追上standby和standby保持一致
slave>start slave until master_log_file = 'master-bin.000096',master_log_pos=756648
slave>start select master_pos_wait( 'master-bin.000096',756648);

查看standby当前的binlog位置
standby>show master status\g
将slave切换到standby当前的binlog位置
slave>change master to master_host ='standby.example.com',
master_port = 3306,
master_user = 'repl_user',
master_password = 'xyxzz',
master_log_file ='standby-bin.000019',
master_log_pos = 56447;
启动slave的复制
slave>start slave;

双主结构(dual masters)
两个master相互复制,故障切换不需要重新配置主master。
服务器可以是主动的(active)或者被动的(passive)
主动的指可以接受写操作。写操作可以通过复制传播到其他地方。
被动的是指不接受写,只跟着主动的master,一旦主master故障可以替代他。
双主有两种配置
主动-主动 active-active
写操作同时到达两个服务器,然后将变更发送给对方
主动-被动 active-passive
负责处理写的为主动master,另一个为被动master与主动master保持同步。
这跟前面的热备份差不多,但由于它是对称的,很容易在两个master间切换。
##注意,这跟配置不需要被动master响应查询,稍后将看到,有些方案中被动master其实是一个冷备份
主动-主动 模式可能会导致两边数据不一致
主动-被动 模式可以一定程度上解决这个问题。其中主动服务器又称为主服务器(primary)被动服务器又称为备用服务器(secondary)
主动-被动 模式的一个重要问题是,解决两台服务器同时称为主动的风险,又称为裂脑综合症(split-brain syndrome)
为组织这种情况发生,最常用的方法是确保那个刮倒的服务器真的挂掉了,通过一种称为STONITH(打爆另一个节点的头)的技术实现,比如执行kill -9 ,关闭网卡,关掉服务器电源等。

共享磁盘

使用DRBD复制磁盘
linux高可用性项目(http://www.linux-ha.org)有很多维护高可用的工具,有一个很有意思DRBD

双向复制
主动-主动配置的用途,当两个主只操作自己的数据的时候。例如每个分公司只操作自己的数据。
应用层要确保不要再分别两台更新相同的数据。
如果要把slave连接到其中一个master,要启用log-slave-updates选项。 log-slave-updates选项控制一个master作为slave接收到另一个master的日志更新库时是否写binlog,如果不打开,会导致其他连接到这个master的纯slave丢失另一个master发过来的数据。
replicate-same-server-id选项禁止服务器id检查,设置这个选项的服务器不能发送事件
使用主动-主动配置需要安全的处理冲突,最简单的方法,也是唯一推荐的方法,就是保证不同的主服务器,写不同的区域。
方案1,是为每个master分配不同的表或数据库
如果要两个主动服务器同时更新一个表 需要用到auto_increment_offset 和 auto_increment_increment 两个参数,详见 P130页

提升slave
之前讨论的都是master正常运行,能在切换前同步备份服务器和slave。
如果master突然死机,所有slave(包括备份服务器)的复制已经停止,你无法知道每个slave上有啥,如果备机在所有slave前面,那么只需要在每个slave上运行复制,到备机的位置就好了。
如果备用服务器滞后于人行一个slave,就不能使用备用服务器作为新的master,因为slave知道的比master多。
实际上,把值得的最多的那个slave就当是master就好了。
##这就是提升slave处理master故障的方法,不保持一个专门的备用服务器(当然也就没有最佳候选备用),而是每一个slave都能被提升为master。
还有一个问题:所有slave都要从新master读取事件

提升slave的传统方法
传统的方法可以很好的说明问题
要求:
每个可提升的slave必须有一个复制账户
每个可提升的slave运行时必须使用log-bin选项,即启动二进制日志
每个可提升的slave运行时必须不使用log-slave-updates选项(稍后会明白原因)
步骤:
1、 all slave> stop slave
2、 new master>reset master
3、 other slave>change master ....
问题:
该方法假设slave能够接收到master的所有更新,但实际上总有slave在不同程度上落后master。也就是说,每个slave都需要获取丢失的事物,而如果其他slave都没有启用二进制日志,这就无法实现。
解决的办法,是找到知道的做多的slave,执行整库同步,或者使用类似mysqldbcompare工具比对差异。

提升slave的修正方法
使用mysql 5.6引入的GTID(见第八章),或者手动实现一个GTID,见P135方法5-5和附录B
由于slave执行来自master的事件后,向二进制日志写一个新的事件,新的binlog位置,与原master上的binlog位置玩去没关系。

环形复制
两个以上的master相互复制,由于每个slave只能连接一个master,只能用环形方式搭建。
5.6以前不推荐,当发生故障时,有很多问题无法处理。5.6以后引入全局事物ID后可以了
如果某个服务器故障时,只需要使用change master 命令加上 master_auto_postion=1选项,将下游服务器连接到上游服务器
由于每个服务器都有事物记录,故障服务器发出的任何事物会在剩余的每个服务器上执行一次。问题就解决了。

小结

第六章 面向横向扩展的mysql复制
横向扩展读操作而不是写操作
异步复制的价值
管理复制拓扑
应用层负载均衡
mysql原生驱动器的复制和负载均衡插件

级联复制
每个master处理slave数量有限,通过添加一个slave作为中继(relay),来减轻master的复制负载。这种方式就是 中继方式的级联复制(hierarchical replication)
默认,slave从master得到的变更不会写入slave的二进制日志。
另一方面,中继服务器(relay)需要二进制日志记录,因为relay需要把变更传给其他slave。与普通slave不同的是,relay本身并不需要应用这些变更,因为他不影响任何查询。
简而言之,普通slave需要应用变更不需要二进制日志,relay需要二进制日志,但不应用变更
relay使用一个称谓 Blackhold的存储引擎,接收所有语句,总是报告成功。
replay引入了额外的延迟,可能replay落后的比普通slave更多。这也是replay配置困难的原因。

配置replay

第七章 数据分片

第八章 深入复制
目标
如何更安全的将slave提升为master
崩溃后避免数据库损坏的技巧
多源复制(Multisource replication)
基于行的复制(Row-based replaction
全局事务标识符(Global transaction identifiers
多线程复制(Multithreaded replication

复制的基础架构

中继日志的结构
除和binlog类似的结构外,中继日志还维护两个文件来跟踪复制进度。 这两个文件的名字由my.cnf的相应参数来控制
中继日志信息文件 relay-log-info-file=filename 如果没有提供完整文件名,位于数据目录下,默认文件名为relay-log.info
master日志信息文件 master-info-file=filename   默认文件名为master.info
master.info文件中的信息优先于my.cnf
请谨慎执行reset slave 这个命令将删除master.info和relay-log.info以及所有中继日子文件。
master.info文件包含master的读取位置,以及连接master和启动复制必须的所有信息。当slave的I/O线程启动时,如果有master.info则线程从这个文件读取信息。
master.info文件没有加密,为保护文件确保只有mysql服务器才能读取它。
实例8-1 master.info 文件的内容(mysql 5.6.12)
1 23
2 master-bin.000001
3 151
4 localhost
5 root
6
7 13000
8 60
9 0
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql4.1之前的版本没有第一行,4.1.1版本加了行号,5.1.16版本加入了第15行,剩下后面的都是5.6系列新增的

relay-log.info文件跟踪复制的进度,并由sql线程负责更新。
文件内容实例,这些对应下一个即将执行的事件的开始
./slave-relay-bin.000003         中继日志文件 relay_log_file
380                              中继日志文件位置  relay_log_pos
master1-bin.000001               master日志文件 relay_master_log_file
234                              master日志位置 exec_master_log_pos
如果这两个配置文件不可用,在slave启动时,能够根据my.cnf文件和chanage master to命令重建,注意在执行start slave时才会重建。

复制线程
master转储线程
当slave I/O线程连接master时创建,负责从master的binlog读取记录,发给slave。每个slave都有一个
slave I/O线程
负责连接master并请求所有更新转储到中继日志。每个slave都有一个此线程,一旦建立连接,线程一直都在。
slave SQL线程
读取中继日志,然后在slave数据库上应用这些更新。负责协调其他mysql线程,保证这些更新不与mysql服务器上的其他活动冲突。

启动和停止slave线程
服务器启动时,如果有master.info文件,还会同时启动slave线程。(使用start slave会启动线程,创建master.info文件,启动过复制,下次服务器启动时会自动启动复制)
slaveI/O线程从master.info文件读取的最后读取位置进行恢复。会类似于binlog进行文件轮换
slaveSQL线程从relay-log.info文件读取中继日志位置进行恢复。
start slave启动slave线程
stop slave停止slave线程
start slave io_thread 和 stop slave io_thread 启停I/O线程
start slave sql_thread 和 stop slave sql_thread 启停sql线程

通过internet运行复制
主要是配置ssl加密
使用内置的支持建立安全复制
使用Stunnel建立安全复制

细粒度控制复制
关于复制的状态信息
master>show slave hosts
显示使用report-host参数的slave信息,slave使用report-host参数告诉master服务器连接信息。
除主机名外以下参数也提供了关于连接slave的信息
report-host 连接中的slave主机名
report-port 监听端口
report-user 只有服务器使用show-slave-auth-info时才有这个参数
report-password
show-slave-auth-info 如果启用 show slave hosts 将输出用户名和密码
master>show slave hosts;

master> show master logs;
查看master的二进制文件

master>show master status;
给出下一个事件即将写入二进制日志的位置。

slave>show slave status;
查看slave线程状态

slave I/O线程和sql线程的状态
slave_io_running和slave_sql_running分别表示IO线程和sql线程是否运行。
如果io线程不在运行,last_io_errno和last_io_error字段将给出线程停止的原因。
如果sql线程不在运行,last_sql_errno和last_sql_error字段将给出线程停止的原因。 last_errno和last_error是带sql的同义词
slave_io_state描述io线程状态:
等待master更新
连接master
检查master版本
在master注册slave
请求binlog转储
等待master发送事件
master事件排队等待写入中继日志
action后等待重新连接
action失败后重新连接
等待slave互斥体退出
等待slave的sql线程释放中继日志空间

二进制日志位置和中继日志的位置

半同步复制

rpl-semi-sync-master-timeout=milliseconds
在指定时间收不到slave确认就转为异步复制
rpl-semi-sync-master-wait-no-slave={ON|OFF}
ON时表示master没有可用的slave时转为异步复制。

监控半同步复制

rpl_semi_sync_master_clients
master变量,支持并启用半同步的slave数量
rpl_semi_sync_master_status
master上的半同步复制状态,1 表示活动 0 表示非活动。 如果未启动或者启动了但还原为异步 则为0
rpl_semi_sync_slave_status
salve上的半同步状态 1表示活动 0 非活动

show status或者information_schema.global_status查看这些参数
select * from information_schema.global_status where variable_name='Rpl_semi_sync_master_status';

全局事物标识符

使用GTID配置复制
主服务器
log-bin = master-bin
gtid-mode =on
enforce-gtid-consistency

配置备用服务器
[mysqld]
log-bin = master-bin
gtid-mode =on
log-slave-update
enforce-gtid-consistency

使用gtid切换master
slave>change master to
master_auto_position=1;

** 使用 wait_until_sql_thread_after_gtids函数,阻塞到gtid组中的所有gtid都被sql线程处理完毕
show slave status/g;  查找Retrieved_Gtid_Set最后一个收到的gtid
select wait_until_sql_thread_after_gtids(输入这个gtid); 等待到这个最后的gtid执行完
show slave status/g;  Retrieved_Gtid_Set 和 Executed_Gtid_Set 应该一样了。

show slave status查看gtid位置

slave的安全和恢复

事务型复制
配置事物型复制
[mysqld]
master_info_repository = table
relay_log_info_repository = table

5.6.6以前默认引擎是myisam,需要改为innodb
alter table mysql.slave_master_info engine = innodb;
alter table mysql.slave_replay_log_info engine = innodb;

slave_master_info选项

监控master复制
show master status
show binary logs
show master logs
show binlog events
master的状态变量
com_change_master
com_show_master_status

监控slave
show slave status
show binary logs
show binlog events

slave的状态变量
Com_show_slave_hosts
Com_show_slave_status
Com_slave_start
Com_slave_stop
Slave_heartbeat_period
Slave_last_heartbeat
Slave_open_temp_tables
Slave_received_heartbeats
Slave_retride_transactions
Slave_runing

其他需要考虑的问题
网络
slave_compressed_protocol 配置压缩
change master命令的master_heartbeat_period=秒 配置心跳间隔可以用Slave_heartbeat_period ,Slave_last_heartbeat 来监控

监控和管理slave滞后
show slave status
seconds_behind_master : 146 比master滞后的秒

使用Gtid
相关系统变量
enforce_gtid_consistency  禁止执行任何不安全的事物,包括事务中create table..select 和create temporary table
gtid_execute  显示当前写入缓存的事物
gtid_mode     是否在使用gtid
gtid_next     gtid的创建方式,automatic表示通过全局唯一机制创建gtid,anonymous表示使用文件和位置生成gtid,不是唯一的
gtid_owned    当前用于的所有gtid列表
gtid_purged   限制已经从二进制日志中清除的事物,恢复备份时,可以使用这个变量排除已经应用过的gtid
在master做全备份,设置gtid_purged中的gtid列表,然后在slave上恢复

多线程复制
mysql 5.6多线程复制好像只能两个库间使用,同一个库不能用
slave_parallel_workers

第14章 复制的故障排除

Master上的问题
master崩溃及内存表被占用
重启带来的内存表数据不一致
master崩溃及二进制日志事件丢失
设置sync_binlog=1 之前还有两个选项innodb_flush_log_at_trx_commit=1; innodb_support_xa=1;
master上查询正常但在slave上出错
可以使用sql_slave_skip_counter变量在slave上跳过事件,指定master的事件数
崩溃之后表损坏
查看服务器错误日志
使用mysqlcheck命令修复
修复会导致master和slave不一致,尤其是丢失数据时。这时要对比master和slave的数据
master上的二进制日志损坏
检查二进制日志中的可恢复事件,使用flush logs轮换master上的日志。
slave可能会丢失数据,而且大多会出现错误。
最好的方法是使用重新备份恢复,同步master和slave
杀死非事务型表上长时间运行的查询
不安全的语句
应避免不安全的语句,最好的办法是培训用户那些语句是不安全的,监视复制警告。
全部使用事务型表和基于行的复制。
在线参考手册“确定二进制日志中的安全和不安全语句”

slave上的问题
**确保slave更强大的方法是使用log-slave-updates开启二进制日志,这将导致slave在二进制日志中记录中继日志执行的事件,当中继日志损坏时,可以使用二进制日志进行重放
slave服务器崩溃及复制无法启动
使用show slave status确认slave最后执行的事件,chanage master 重建到master的复制
slave连接超时反复重连
多个slave时server_id不唯一
slave上的查询结果与master不同
执行不安全的语句,写操作发给slave,混合事务型和非事务型存储引擎,master和slave的查询选项集不同(如SQL_MODE),字符集不同,存储引擎不同,表定义不同,
当尝试重启ssl时slave出错
内存表数据丢失
slave崩溃后的临时表丢失
slave运行慢且与master不同步
slave滞后,又称为过度滞后(excessive lag)。
监控show slave status 输出结果,检查secons_behind_master字段,确保他的值在应用允许范围内
将某些数据库移到其他slave减少slave的负载。
slave崩溃后数据丢失
slave可能会崩溃,从而没有记录最近可知的master的binlog位置。这些信息存储在relay_log.info文件中。
如果是slave试图执行重复的查询报错,可以跳过重复的事件。
重复的事件可能导致数据被改变,这不太容易发现,需要检查binlog事件和master的二进制日志以确定哪些事件不是重复的。
崩溃后表损坏
重新备份恢复slave
slave上中继日志损坏
确认master二进制日志最后执行已知事件的位置,然后使用change master命令重启复制。
slave重启时的多个错误
检查错误日志和show slave status的输出
检查master和slave上的max_allowed_packaget 大小。 如果master上的记录事件大小比slave大,这会导致看起来不合逻辑的随机错误。
slave上事物失败的后果
避免混合使用非事务型表,都用事务型存储引擎
I/O线程问题
到master的连接丢失
到master的连接断断续续
slave严重滞后与master
解决:
从slave状态输出的Last_IO_Errno和Last_IO_Error字段可以看到master连接错误。而且,Slave_IO_Running的状态可能为NO。
检查change master 确保使用的是正确的用户证书
检查master复制的用户证书
在slave上用ping master IP检查网络连通性
使用telnet maser IP:端口,确认端口可达
都没问题还是出现严重滞后,则考虑使用多线程slave,或复制过滤。在不同slave组间隔离数据库。
SQL线程问题:不一致
最常见的问题是语句在slave上执行失败。
检查master和slave之间的一致性,mysqldbcompare,这是一个离线工具,可以在活动不频繁的slave上运行,或者如果将表锁定一段时间是安全的,也可以运行这个工具。
slave上的错误不一样

高级复制问题
变更没有在拓扑中被复制
例如alter table复制了,但flush、repair table及类似的命令没有复制。
需查阅DML和维护命令的限制。
只要对数据库做了重大变更,如在文件级别或使用维护命令改变其结构,请在所有slave上执行这些命令
专业的人员使用脚本完成这些工作,脚本按顺序停止复制,应用更新,自动重启复制。
环形复制的问题
多master的问题
HA_ERR_KEY_NOT_FOUND错误
该错误在基于行的复制拓扑中很常见。
可能的原因是:需要被更新或删除的行不存在或以改变,导致存储引擎找不到它。
找到冲突的根源并修复数据,或跳过有问题的事件。
GTID问题
如果slave比master滞后,或者并没有master上的全部数据,通常应该在slave上恢复master的一个最近的备份。 还可以这么做,不过需要再slave上设置gtid_purged变量,将master执行的全部GTID(即master的gtid_executed系统变量值)都包含进来
备份恢复数据时的gtid_purged相关错误
使用mysqldump 或者mysqldbcopy、mysqldbexport和mysqldbimport命令。正确的GTID语句会自动生成。
但是,如果想在slave上设置gtid_purged变量,可能会遇到类似“gtid_purged只能在gtid_executed为空时设置”的错误。这是因为目标服务器并不是处在赶紧的复制状态。
更正这个错误,首先在slave上发出 reset master命令清空gtid_purged变量,然后设置gtid_purged变量。
**在使用gtid的主动复制拓扑中,千万不要再master上执行reset master命令。
复制的故障排除工具
show processlist
show master status和show slave status
show grants for 复制用户
chanage master
stop/start slave
检查配置文件
检查服务器日志
show slave hosts
show binlog events
mysqlbinlog
purge binary logs 该命令允许删除二进制日志中的某些事件。

最佳实践
了解你的拓扑结构
你应该拥有一份拓扑系统的文本或者图形形式的图纸,在上面表名过滤器(master和slave),以及各个服务器在拓扑中的角色。还要包含change master命令,所有选项以及所有服务器的配置文件内容。
星型(单master
链式
循环(环形
多主
混合
检查所有服务器的状态
定期检查拓扑结构中的所有服务器状态。可以通过定时任务,自启动mysql客户端发出show master status和show slave status命令,然后发送结果。
检查日志
定期检查服务器的日志(errorlog)
检查配置
定期检查服务器配置文件
有序的执行关闭操作
锁住mster上的表,刷新二进制日志,等待所有slave跟上,再关闭slave。保证所有slave上的事件都被执行。
如果问题修复需要很长事件,最好停止master上的更新。
可以考虑完全关闭复制。
有序的执行故障后的重启操作
手动执行失败的查询
检查中继日志或二进制日志中的查询。隔离有问题的slave,并尝试手动执行查询,可能会得到更多错误信息。
**应该总是在诊断数据变更之前备份数据。
不要混合使用事务型表和非事务型表
都使用innodb
一般步骤
复制失败的故障排除
1、检查master的状态,并记录其异常信息
2、检查slave的状态,并记录其异常信息
3、阅读所有服务器上的错误日志。
4、检查每个服务器上的进程列表,查找状态中的异常信息
5、如果没有报告错误,则试图重启slave,并记录出现的任何错误
6、检查有问题的服务器的配置信息,以确保没有什么被改变
7、检查笔记,并未研究和修复问题制订计划。
暂停复制
从主master(第一个master开始)
在master上运行
1、 flush table with read loack
2、 show master status
3、记录master的二进制日志和位置
在slave上运行
1、运行select master_post_wait(binary_log_name,postion)
2、show slave status 直到slave与master 同步
这时关闭slave是安全的。

报告复制错误
http://bugs.mysql.com
小结
在线参考手册中“复制功能和问题”一节

第15章 保护你的资产
什么事信息保护
信息保障IA
NSA网站中的IA章节 http://www.nsa.gov/ia   NSA。。。国家安全局
信息保障的三个实践
信息安全
信息完整性
信息价值
信息保障为什么重要
信息完整性、灾难恢复及备份的职责
信息完整性有时又称为业务连续性
**记住,硬件可能失效,最终也一定会失效,所以请提前做好准备
数据完整性
通信完整性
系统完整性
高可用性与灾难恢复
灾难恢复
灾难恢复规划
灾难恢复工作流
灾难恢复工具
数据恢复的重要性
术语
RPO Recovery Point Objective 恢复点目标,系统运营可接受的状态。服务(运行能力)下降的最大可接受程度或数据丢失的最大可接受承兑。使用这些标准可衡量恢复操作是否成功。
RTO Recovery Time Objective  能够容忍系统不可用的最长时间
备份和恢复
为什么要备份
备份的期望
完全备份
差异备份
增量备份
还原过程的期望
逻辑备份与物理备份
制定归档计划
首先问问自己,我可以承受多少数据损失,然后从头恢复他们?

备份实用程序和操作系统层的解决方案
mysql企业备份
使用mysql实用工具集进行数据库的导入和导出
mysqldump工具
使用mysqldump巩固执行innodb表热备份。 --single-transaction 以一致性读的方式读取表。
--single-transaction 和 --lock-tables 是排斥的。
物理物理文件复制

停止mysql直接复制所有数据文件
逻辑卷管理快照
lvm快照
lvm入门
XtraBackup
备份方法比较

备份和mysql复制
备份和恢复
PITR
恢复到某个精确时间点
使用复制进行备份和恢复
PITR

第16章 mysql企业版监控

第17章 使用mysql实用工具管理mysql复制
常见的mysql复制任务
状态检查
show slave status

停止复制
stop slave
stop slave to_thread
stop slave sql_thread
start slave
start slave until sql_before_gtids gtid_set
start slave until sql_after_gtids gtid_set
start slave until master_log_file='file', master_log_pos=position
start slave until relay_log_file='file', relay_log_pos=position
reset slave
reset master

添加slave
使用master上的副本重写数据。通常是将master上的备份文件应用到slave
前滚master的二进制日志
连接到master,等待slave赶上来

1、如果没有使用gtid 确保 slave的 --server-id 被设置成其中一个master或slave的唯一标识
2、在slave上准备数据
3、在slave上执行change master命令 如果使用了gtid,使用master_auto_position=1 代替master 二进制日志文件和位置
4、在slave执行start slave命令
5、使用show slave status检查是否有错误

级联复制

© 2017, 新之助meow. 原创文章转载请注明: 转载自http://www.xinmeow.com

0.00 avg. rating (0% score) - 0 votes
点赞