高性能MySQL 第十章

本文深入探讨了MySQL的复制技术,包括基于语句和基于行的复制方式,异步复制的工作原理,以及复制过程中的主从延迟问题。详细阐述了复制的三个步骤,强调了主库的二进制日志和备库的中继日志在复制过程中的关键作用。同时,介绍了配置复制的步骤,推荐的复制配置选项,并讨论了复制可能导致的数据不一致情况及解决策略。
摘要由CSDN通过智能技术生成

备库也可以配置成另一台备库的主库


1.基于语句的复制,也被称为逻辑复制

2.基于行的复制,5.1版本才被加进来。

异步复制,会有延迟。


复制通常不会增加主库的开销,主要是启用二进制日志带来的开销。

基于行的复制会比基于语句的复制带来更大的带宽压力。

DNS轮询,即一个机器名指向多个IP地址。或者LVS。



总的来说,复制有三个步骤:(三个线程,两种日志。)

1.主库的更改记录到二进制日志(binary log)中(这些记录称为二进制日志事件)

            mysql会按事务提交的顺序来记录二进制日志,而不是每条语句执行的顺序。在记录二进制日之后,主库会告诉存储引擎可以提交事务了。

2.备库将主库上的日志复制到自己的中继日志(relay log)中。 IO线程 ,binlog dump 线程。

            IO线程跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转储线程。

            如果dump线程追赶上了主库,它将进入睡眠状态,直到主库发送信号量通知其有新的事件产生才会被唤醒。

3.备库读取中继日志的事件,将其重放到备库数据之上。 SQL线程

            当sql线程追赶上IO线程时,中继日志通常已经在系统缓存中,所以中继日志的开销很低。



主库上冰法运行的查询在备库只能串行化执行,因为只有一个sql线程来重放中继日志中的事件。


配置复制步骤:

1.主备库创建复制账号

2.配置主备库

3,通知备库连接到主库并从主库复制数据


mysql会赋予一些特殊的权限给复制线程

备库IO线程以复制账号为用户名连接到主库并读取二进制日志。


bin_log,server_id


IO线程和sql线程总是运行在system user账户下(show processlist看到的结果)



已运行一段时间的主库建立备库:

1.某个时间点的快照

2.日志文件坐标,即主库获得快照时的日志文件,以及获得快照时在该二进制日志文件中的偏移量。(日志文件,偏移量)

3.从快照时间到现在的二进制日志


克隆备库的方法

1.冷备份 ,关库,数据复制到备库,重启主库,备库change master to。。。。缺点是得关库。

2.热备份,myisam表,使用mysqlhotcopy或者rsync来复制。

3.使用mysqldump,innodb表。

4.使用快照或备份,需要知道对应的二进制日志坐标。

5.使用percona xtrabackup

6.使用另外的备库


推荐的复制配置:

1.主库二进制日志最重要的选项是sync_binlog=1  ,视图提交前会把二进制日志同步到磁盘上,保证服务器崩溃时不丢失事件。

    如果使用innodb,强烈推荐如下选项:

     innodb_flush_logs_at_trx_commit

     innodb_support_xa=1   V5.0

     innodb_safe_binlog      V4.1


     推荐明确指定二进制日志的名字,以保证二进制日志在所有服务器上是一致的,避免因为服务器名的变化导致的日志文件名变化。(因为二进制日志默认的文件名和服务器名相关,服务器名修改可能会引起问题)

     binlog   relay_log都推荐设置名字

     指定绝对路径可以避免多个mysql版本中存在的bug,zhexiebug可能会导致中继日志在一个意料外的位置创建


      skip_slave_start能够阻止备库在崩溃后自己启动复制,并且处于不一致的状态。

      read_only


      sync_master_info

      sync_relay_log

      sync_relay_log_info


      relay_log_purge:sql线程重放完一个中继日志的事件后会尽快将其删除,在主备库延迟很大时有用,下一个参数也是。

      relay_log_space_limit   不是特别推荐,因为在某些特殊极端情况下会有隐藏的问题。具体看书。



复制的原理

5.0以前只支持基于语句的复制,即逻辑复制。只是把主库执行过的SQL执行一遍。实现简单,带宽小。                缺点:例如时间,用户等,可能会有问题。还有其他问题不列举。

51.开始支持基于行的复制,正确的复制每一行。复杂查询但更新少量行的时候,负载比基于语句的复制小很多。

mysql能在这两种复制之间动态切换,默认使用基于语句的复制,如果需要可以自动切换到基于行的复制模式。

还可以根据需要来设置会话级别的变量 binlog_format ,控制二进制日志的格式。


基于语句的复制,在用存储过程,触发器时有大量bug。
几乎没有基于行的复制模式无法处理的场景,除非在备库修改schema这样的事情。减少锁。
另外在一些情况下,基于行的二进制日志还会记录发生改变之前的数据,因此这可能有利于某些数据恢复。
不需要像基于语句的复制那样建立执行计划,执行查询等操作,因此占用更少CPU。
在某些情况下,行复制能帮助更快的找到并解决数据不一致的问题。
但无法判断执行了那些SQL


相关文件
mysql-bin.index文件     每一行包含了二进制文件的文件名,如果没有这个文件,mysql无法识别二进制文件。
mysql-relay-bin.index   跟上面一样
master.info             保存备库连接到主库所需的信息,不能删除,否则备库重启后连接不上主库。
relay-log.info          当前备库复制的二进制日志和中继日志坐标。不要删除,否则可能会导致重放已经执行过的语句。
但这些文件不是同步写的,所以服务器断电重启后,文件中记录的数据可能错误。




expire_logs_days 参数,定期清理二进制日志。


log_slave_updates


server_id 是为了打破复制无限循环。当复制SQL线程读中继日志的时候,会丢弃事件中记录的服务器ID和该服务器本身ID相同的事件,从而打破了复制过程中的无限循环。在某个拓扑结构中打破复制无线循环非常重要,比如M-M复制结构。


复制过滤(除非万不得已,不要启用复制过滤,容易导致很多问题)
有两种:
1.主库上过滤记录到二进制日志中的事件
2.备库上过滤记录到中级日志的事件
主库:
binlog_do_db
binlog_ignore_do
通常不需要开启,数据永久丢失。
过滤的是当前数据库,不是目标数据库。(切记,容易出问题。基于语句的复制会出现这样的问题,但基于行的复制不会。)
备库:
replicate_*选项
过滤的是当前数据库,不是目标数据库。(切记,容易出问题。基于语句的复制会出现这样的问题,但基于行的复制不会。)


10.4


主主复制问题非常多   auto_increment_increment       auto_increment_offset

主动-被动模式下的主主复制,主要的区别是其中的一台服务器是只读的被动服务器。使得故障转移和故障恢复更容易,也可以在不关闭服务器的情况下执行维护、优化表,升级操作系统或其他任务。(举例如alter table操作)

拥有备库的主主复制

环形复制

分发主库

可以通过设置slave_compressed_protocol来节约一些主库带宽,这对跨数据中心复制很有好处。

还可以通过分发主库实现其他目的,如对二进制日志进行过滤,或者重写规则。效率更高。

但是blackhole引擎有一些bug。

还有,在备库上使用不同于主库的引擎总是会导致一些问题。

使用分发主库的另外一个主要的缺点是无法使用一个备库来代替主库,因为由于分发主库的存在,导致各个备库与原始主库的二进制日志坐标已经不相同。


树形或金字塔结构  减轻了主库的负担,但是中间层出现的任何错误都会影响多个服务器。


选择性复制    replicate_wild_do_table=sale.%

分离功能

数据归档:在主库上选择性的禁止二进制日志    在备库上使用replicate_ignore_db规则    但两种方法都很危险

将备库用作全文检索


测量备库延迟: pt-heartbeat

确定主备是否一致:pt-table-checksum

从主库重新同步备库:pt-table-sync

复制可能导致数据不一致的情况:


备库意外关闭,重启之后需要读master.info文件以找到上次停止复制的位置,但master.info中的信息并不一定是同步刷新到磁盘的,所以位置可能会有错误,可能导致备库重做已经做过的日志。  

pt-slave-start 工具


如果使用的是MyISAM表,那么在关闭mysql之前需要先stop slave,否则一些正在执行的查询或更新会终止,下次启动之后不会继续执行,也不会回滚,导致主从不一致。


混合事务性和非事务性表,如果发生回滚的话,事务性表会自动回滚,但是非事务性表则永久的更新了。此时mysql会记录此查询并记录一条rollback语句到日志中。从而保证了数据的一致性。

但是混合使用事务型表和非事务型表会有一些问题,应尽量避免混合使用。


基于语句的复制使用临时表会有很多限制,如果关闭或重启备库,很容易导致数据不一致。所以在关闭或重启备库之前,应在stop slave之后,确认slave_open_temp_tables为0,也就是没有打开的临时表。


mysql单线程复制的设计让备库很容易落后于主库。主库是并发执行的。

备库上的查询也有可能阻塞复制线程。


pt-query-digest

log_slow_slave_statement记录在备库上复制线程执行的语句,查看复制时那些语句执行慢了。


mk-slave-prefetch 数据预取,加快备库sql线程执行速度。


mysql二进制日志转储进程并没有通过轮询的方式从主库请求事件,而是主库来通知备库新的事件。


半同步复制的误区:

有三个,

第一个 备库提示其已经收到事件前,会阻塞主库上事务的提交。这是错误的。事实上,此时主库已经提交,只是在收到备库的提示之前,不会去通知客户端。


半同步复制比主库在关闭sync_binlog的情况下更安全。因为写入远程的内存,比写入本地的磁盘刷新更快。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值