mysql高可用详解(四):二进制日志

【二进制日志的结构】

二进制日志事件又称为binlog事件存储在一系列的binlog文件中,另外还有一个binlog的索引文件,用来追踪已有的binlog文件。

当前服务器正在写入的binlog文件称为活动文件。

索引文件的每一行都包含一个二进制日志的binlog文件名;

【binlog事件结构】

每个binlog事件由4部分组成:

通用头(Common header)

提交头(Post header)

事件体(Event body)

校验和(Checksum)

http://www.linuxidc.com/Linux/2017-03/142322.htm

【Format_description事件、Rotate事件】

这两个日志事件的长度是固定的

 

【事件校验】

MySQL5.6引入复制事件校验和。这写入事件的时候添加一个校验和;然后在读取这些事件的时候,计算这个校验和,并与之前的校验和进行比较,如果不匹配则在slave应用该事件之前终止执行;

可以使用相关命令进行设置;

【将语句写入日志】

写入数据操作语言(DML):》MySQL在写二进制日志的同时获取事务级锁,写完之后释放;

写入数据定义语言(DDL)语句:》对于一个数据库的表结构而言,只有一个锁来保护这些数据结构,所以数据库对象的创建、更新和销毁都可能带来性能问题。

写入查询:》需要将一些隐式的信息显示化的存储在日志中,以确保数据的一致性;

【二进制日志过滤器】

binlog-do-db:只是过滤特定数据库

binlog-ignore-db:忽略某个数据库而复制其他所有数据库

可以重复使用。

 

需要在my.cnf文件中进行设置:

[mysqld]

binlog-ignore-db=one_db

binlog-ignore-db=two_db

如果存在binlog-do-db机会忽略掉binlog-ignore-db语句

【记录日志的时候需要特别处理的结构:存储程序,即触发器、事件和存储例程】

存储例程stored routines是存储过程和存储函数的总称;

可以分为两种类型:

(1)定义、销毁或者更改存储程序的语句;

(2)调用它们的语句;

【LOAD_FILE函数】

LOAD_FILE可以读取某个文件,并将其使用在表达式中,但是这就要求slave上必须要有这个文件,因为复制过程并不会传递这个文件。而LOAD_DATA_INFILE中的文件将会被传递。所以可以使用LOAD_DATA_INFILE语句巧妙地重写带有LOAD_FILE函数的语句,或者自定义一个变量保存该文件的内容;

 

【将事务写入日志】

为了保证以事务为单位写二进制日志,服务器需要把语句分到不同的线程执行。提交事务的时候,服务器把所有这些语句一次性的全部写入二进制日志。为此,服务器为每个线程保留了一个事务缓存。将语句存放在事务缓存中,当事务提交的时候,将事务缓存的内容复制到二进制日志,然后清空;

【使用XA进行分布式事务处理】

MySQL5.0可以通过X/Open DTP(分布式事务处理)模型即XA,协调处理涉及不同资源的事务。

         XA由一个事务管理器(transaction manager)和一组资源管理器(resource manager)组成,资源管理器将全局事务以原子单位提交,事务管理器则负责协调这些资源管理器。每个事务有一个唯一的XID,供事务管理器和资源管理器使用。在MySQL服务器内部,事务管理器通常由二进制日志使用,而资源管理器由存储引擎使用。每个存储引擎都需要为提交做准备。只要有一个存储引擎返回的消息是否定的,就无法提交这个事务,提交被终止,所有引擎执行事务回滚;

 

 

普通事务是以带有COMMIT的普通Query事件结束,而XA事务以一个包含XID的Xid事件结束;

 

【二进制日志的组提交】

多个独立的事务可以按组的形式,一起写入磁盘,这就是组提交(group commit)。写磁盘的时间取决于磁盘头移动到正确磁盘位置的时间,与写入多少数据量无关,所以这样能够极大地提高性能;

 

【基于行的复制】

基于语句复制无法正确处理的问题:

(1)如果UPDATE、DELETE或者INSERT语句包含LIMIT从句,那么语句执行的时候倘若数据库崩溃,则可能导致错误;

(2)如果非事务型语句执行期间出错,无法保证master和slave上数据变化一致;

(3)如果语句含有UDF函数调用,则无法保证slave上的值和master上的相同;

(4)如果语句含有任何不确定的函数,例如USER、CURRENT_USER、CONNECTION_ID等,可能会导致master和slave上的结果不一致;

(5)如果语句同时更新两个含有autoincrement字段的表,则无法保证正确性。因为只有最后插入的那个ID会被复制到slave上然后同时应用到两张表中去,而对于master来说,每张表的插入ID是不同的;

 

 

 

基于行的复制(row-based replication):复制插入表中的真实数据

 

 

使用基于行复制还是基于语句复制:

(1)如果语句要更新大量的行,则基于语句的复制更快(如果语句的优化和执行计划很复杂,也可能基于行的复制更快);

(2)如果master和slave上的数据不一致,执行语句的结果也会不同。这就需要基于行的复制来避免这种情况的发生;

 

 

【启用基于行的复制】

配置MySQL的配置文件:配置基于行的复制参数

binlog-format=ROW

 

【使用混合模式】

混合模式复制的原理:正常情况下使用基于语句的复制,而对不安全的语句则切换到基于行的复制。

 

例如以下情况混合模式会切换到基于行的复制:

(1)该语句调用了UUID函数、用户自定义函数、CURRENT_USER或者USER函数、LOAD_FILE函数

(2)一个语句同时更新了两个或者两个以上含有AUTO_INCREMENT列的表;

(3)语句中使用了服务器变量;

(4)存储引擎不允许使用基于语句的复制,例如:MySQL Cluster引擎;

【二进制日志管理】

因为二进制日志由多个文件组成,有必要将它们分隔成适当的组,构成一个binlog文件序列。为了操作安全,向二进制日志添加一些特殊的事件(轮换事件);

【binlog文件轮换】

因为操作系统对文件的大小有限制,,根据上下文不同,切换到新文件的过程称为二进制日志轮换,或者binlog文件轮换;

 

主要有4种行为导致轮换:

(1)服务器停止

(2)binlog文件大小达到最大限制(可以通过binlog-cache-size来控制binlog文件的大小)

(3)二进制日志被显示刷新:

         FLUSH LOGS命令将所有日志写入磁盘,然后创建一个新文件继续写二进制日志。当PITR管理恢复镜像的时候,是很有用的。从一个打开的binlog文件可能会读到预料之外的结果,因此建议在试图使用binlog文件执行恢复前,强制进行显示刷新;

(4)服务器上发生故障

【事故】

(1)Stop:服务器正常停止;不会影响复制;

(2)Incident:当slave重放二进制日志时,如果遇到Incident事件,就会因为错误而停止。如果在MySQL集群重载时候发现Incident事件,表明需要重新同步集群,很可能还需要找到那些binlog文件中丢失的事件;

【清除binlog文件】

设置expire-logs-days选项:服务器可以自动清除binlog文件(可在my.cnf文件中配置)

手动清除命令:PURGE BINARY LOGS BEFORE datetime

                                     该命令清除给定时间前的所有文件。

                                     PURGE BINARY LOGS TO ‘filename’

                                     该命令清除给定文件前的所有文件。即,在SHOW MASTER LOGS 命令显示的所有文件中,filename前的文件都会被清除,从而filename变成第一个binlog文件;

【mysqlbinlog实用工具】

http://blog.chinaunix.net/uid-22570852-id-4992233.html

 

对管理员十分有用的一个工具是客户端程序mysqlbinlog。这是一个小程序,可以审查binlog文件以及中继日志文件的内容。除了在本地读取binlog文件,mysqlbinlog同样可以从其他服务器上远程读取binlog文件;

读取远程文件:read-from-remote-server读取远程binlog文件,其参数包括需要连接服务器的主机和用户、可选的端口号以及密码

从远程服务器上读取binlog文件的时候,只需要给出binlog文件的名字,而不需要给出它的全路径;

【二进制日志的选项和变量】

有一组选项和变量用于对二进制日志进行多方面的配置;

有几个选项用于存储诸如binlog文件名和索引文件名这样的属性。大多数选项可以同时作为服务器变量处理。

【基于行的复制参数】

配置基于行的复制需要以下参数:

binlog-format

binlog-max-row-event-size

         指定何时开始下一个包含行事件。由于事件在处理的时候被完全读入内存,该参数粗略的控制那些包含行的事件的大小,保证处理行的时候不会消耗过多的内存;

binlog-rows-query-log-events

         该选项使服务器在行事件之前向二进制添加一个信息事件。这个信息事件包含产生这些行的原始查询;

 

猜你喜欢

转载自blog.csdn.net/qq_36807862/article/details/81289318