mysql(十)mysql主从复制--主库切换

概述

可能为了更迭升级服务器,或者主库出现问题,又或者只是希望重新分配容量,此时需要切换主库。

如果这是计划内的切换,会相对容易点。只需要在从库上使用CHANGE MASTER TO命令,并设置合适的值。大多数的值都是可选的,至少要指定需要改变的项即可。从库将抛弃之前的配置和中继日志并从新的主库开始复制。同样新的参数会被更新到master.info文件中,这样就算重启,从库配置也不会丢失。

整个过程中最难得就是获取新的主库上合适的二进制日志位置,这样从库才可以从和老主库相同的逻辑位置开始复制

把从库提升为主库要更困难一点。有两种场景需要将从库替换成主库,一种是计划内的,一种是计划外的

计划内的提升

把从库提升为主库理论上是简单的。

  1. 停止向老的库写入
  2. 让从库追赶上主库
  3. 将一台从库配置为新的主库
  4. 将从库和写操作指向新的主库,然后开启主库的写入

上述步骤中还是隐藏着很多细节,更深入一点,下面步骤就是大多数配置需要的步骤

  1. 停止当前主库上的所有写操作。如果可以,最好能将所有的客户端程序关闭 (除了复制连接)。为客户端程序建立一个“do not run”这样的类似标记可能会有所帮助如果正在使用虚拟IP 地址,也可以简单地关闭虚拟IP,然后断开所有的客户端连接以关闭其打开的事务。
  2. 通过FLUSH TABLES WITH READ LOCK在主库上停止所有活跃的写入,这一步是可选的。也可以在主库上设置 read_only选项。从这一刻开始,应该禁止向即将被替换的主库做任何写入。因为一旦它不是主库,写人就意味着数据丢失。注意,即使设置 read_only也不会阻止当前已存在的事务继续提交。为了更好地保证这一点,可以“kill”所有打开的事务,这将会真正地结束所有写入。
  3. 选择一个从库作为新的主库,并确保它已经完全跟上主库 (例如,让它执行完所有
    从主库获得的中继日志)。
  4. 确保新主库和旧主库的数据是一致的。可选
  5. 在新主库上执行STOP SLAVF
  6. 在新主库上执行 CHANGE MASTER TO MASTER HOST= ’ ',然后再执行 RESET SLAVE,使其断开与老主库的连接,并丢弃 master.info 里记录的信息(如果连接信息记录在my.cnf里,会无法正确工作,这也是我们建议不要把复制连接信息写到配置文件里的原因之一)。
  7. 执行 SHOW MASTER STATUS记录新主库的二进制日志坐标。
  8. 确保其他从库已经追赶上
  9. 关闭旧主库。
  10. 在MySQL51 及以上版本中,如果需要,激活新主库上事件
  11. 将客户端连接到新主库。
  12. 在每台从库上执行CHANGE MASTER TO语,使用之前通过SHOW MASTER STATUS获得的二进制日志坐标,来指向新的主库

计划外的提升

当主库崩溃的时候,需要提升一台从库来代替它,这个过程就不会太容易。如果只有一台从库,可以直接使用这台从库。但如果有超过一台的从库,就需要一些额外的工作。

另外,还有潜在的丢失复制事件。可能主库上已发生的修改还没有更新到它的任何一台设备上的情况。甚至还可能一条语句在主库上执行了回滚,但在从库上没有回滚,这样从库可能超过主库的逻辑复制位置。如果能在某一点恢复主库的数据,也许就可以取得丢失的语句并手动执行他们。

在以下的步骤中,需要确保在计算中使用Master_Log_File和Read_Master_Log_Pos的值

  1. 确定哪台从库的数据最新。检查每台备库上SHOW SLAVE STATUS 命的输出,选择其中Master_Log File/read_Master_Log_Pos 的值最新的那个。
  2. 让所有从库执行完所有其从崩溃前的旧主库那获得的中继日志。如果在未完成前修改从库的主库,它会抛弃剩下的日志事件,从而无法获知该从库在什么地方停止。
  3. 执行前一小节的5~7步。
  4. 比较每台从库和新主库上的 Master_Log_0File/Read_Master_Log_Pos 的值
  5. 执行前一小节的10~12 步。

再次需要注意,在配置主从复制的时候,所有从库开启log_binlog_slave_updates,这样就可以帮助你将所有的从库恢复到一个一致的时间点,如果没有开启这两个选项,则很难可靠的做到这一点。

确定期望的日志位置

如果有从库和新主库的位置不相同,则需要找到该从库最后一条执行的事件在新主库的二进制日志中相应的位置,然后再执行 CHANGE MASTER TO。可以通过mysglbinlog 工具来找到从库执行的最后一条查询,然后在主库上找到同样的查询,进行简单的计算即可得到。

为了便于描述,假设每个日志事件有一个自增的数字ID,最新的从库,也就是新的主库,在旧主库崩溃的时获得了编号为100的事件,假设有另外两台设备:replica2和replica3。replica2已经获得了99号事件,replica3获取了98号事件。如果把这两台从库都指向了新主库的同一个二进制日志的位置,他们将会从101号事件开始复制,从而导致数据不同步。但只要新主库的二进制日志已经通过log_slave_updates打开,就可以在新主库的二进制中找到99和100日志,从而将从库恢复到一致的状态。

由于服务器重启,不同的配置,日志轮转或者FLUSH LOGS命令,同一个事件在不同的服务器上可能有不同的偏移量。找到这些事件可能会耗很长时间并且枯燥,但是通常没有难度。通过mysqlbinlog从二进制日志或中继日志中解析出每台从库上执行的最后一事件,并同样使用该命令解析新主库上的二进制日志,找到相同的查询,mysglbinlog 会打印出该事件的偏移量,在 CHANGE MASTER TO命令中使用这个值

更快的方式是把新主库和停止的从库上的字节偏移量相减,它显示了字节位置的差异。然后把这个值和新主库当前的二进制日志的位置相减,就可以得到期望的查询的位置。然后验证一下就可以据此启动从库。

假设 server1是 server2和 server3 的主库,其中服务器server1已经崩溃。根据SHOW SLAVE STATUS获得 Master_Log_File/Read_Master_Log_Pos 的值,server2 已经执行完了 server1上所有的二进制日志,但 server3还不是最新数据。

在这里插入图片描述
如图所示,我们可以肯定 server2 已经执行完了主库上的所有二进制日志,因为Master_Log_File和Read Master_Log_Pos值和server1上最后的日志位置是相吻合的,因此我们可以将 server2 提升为新主库,并将 server3 设置为 server2的从库。

应该在server3上为需要执行的CHANGE MASTER TO语赋予什么样的参数呢?
这里需要做一点点计算和调查。server3 在偏移量 1493 停止,比 server2执行的最后一条语句的偏移量 1582要小89字节。server2正在向偏移量为8167的二进制日志写入,8167-89=8078,因此理论上我们应该将 server3 指向 server2的日志的偏移量为8078 的位置。最好去确认下这个位置附近的日志事件,以确定在该位置上是否是正确的日志事件,因为可能有别的例外,例如有些更新可能只发生在 server2 上。

假设我们观察到的事件是一样的,下面这条命令会将 server3 切换为 server2的从库

mysql > CHANGE MASTER TO MASTER_HOST="server2",MASTER_LOG_FILE="mysql-bin.000009",MASTER_LOG_POS=8078;

如果服务器在它崩溃时已经执行完成并记录了超过一个事件,会怎么样呢?
因为server2仅仅读取并执行到了偏移位置 1582,你可能永远地失去了一个事件。但是如果老主库的磁盘没有损坏,仍然可以通过 mysglbinlog 或者从日志服务器的二进制日志中找到丢失的事件。

上述流程中一个可调整的地方是使用可靠的方式来存储二进制日志,如 SAN 或分布式复制数据库设备 (DRBD)。即使主库完全失效,依然能够获得它的二进制日志。也可以设置一个日志服务器,把从库指向它,然后让所有从库赶上主库失效的点。这使得提升一个从库为新的主库没那么重要,本质上这和计划中的提升是相同的。

主从复制会有哪些问题以及解决方案

数据损坏或丢失的错误

主库意外关闭

描述:
如果没有设置主库的 sync_binlog 选项,就可能在崩溃前没有将最后的几个二进制日志事件刷新到磁盘中。从库I/0 线程因此也可一直处于读不到尚未写入磁盘的事件的状态中。当主库重新启动时,从库将重连到主库并再次尝试去读该事件,但主库会告诉从库没有这个二进制日志偏移量。二进制日志转储线程通常很快,因此这种情况并不经常发生。

解决方案:
解决这个问题的方法是指定从库从下一个二进制日志的开头读日志。但是一些日志事件将永久地丢失,建议使用 Percona Toolkit 中的pt-table-checksum 工具来检查主从一致性,以便于修复。可以通过在主库开启 sync_binlog 来避免事件丢失。

即使开启了 sync_binlog,MyISAM 表的数据仍然可能在崩溃的时候损坏,对于InnoDB事务,如果innodb_flush_log_at_trx_commit没有设为1,也可能丢失数据(但数据不会损坏)。

从库意外的关闭

当从库在一次非计划中的关闭后重启时,会去读 master.info 文件以找到上次停止复制的位置。不幸的是,该文件并没有同步写到磁盘,文件中存储的信息可能是错误的。从库可能会尝试重新执行一些二进制日志事件,这可能会导致唯一索引错误除非能确定从库在哪里停止 (通常不太可能),否则唯一的办法就是忽略那些错误。Percona Toolkit 中的pt-slave-restart 工具可以帮助完成这一点。

如果使用的都是InnoDB表可以在重启后观察MySQL错误日志。InnoDB在恢复过程中会打印出它的恢复点的二进制日志坐标。可以使用这个值来决定从库指向主库的偏移量。Percona Server 提供了一个新的特性,可以在恢复的过程中自动将这些信息提取出来,并更新 master.info 文件,从根本上使得复制能够协调好从库上的事务

主库上的二进制日志损坏

如果主库上的二进制日志损坏,除了忽略损坏的位置外,你别无选择。可以在主库上执行FLUSH LOGS命令,这样主库会开始一个新的日志文件,然后将从库指向该文件开始的位置。也可以试着去发现损坏区域的结束位置。某些情况下可以通过SET GLOBAL SQL_SLAVE_SKIP_COUNTER =1来忽略一个损坏的事件。如果有多个损坏的事件,就需要重复该步骤,直到跳过所有损坏的事件。但如果有太多的损坏事件,这么做可能就没有意义了。损坏的事件头会阻止服务器找到下一个事件。这种情况下,可能不得不手动的去找到下一个完好的事件。

从库上的中继日志损坏

如果主库上的日志是完好的,就可以通过CHANGE MASTER TO 命令丢弃并重新获取损坏的事件。只需要将从库指向它当前正在复制的位置(Relay_Master_Log_File/Exec_Master_Log_Pos)。这会导致从库丢弃所有在磁盘上的中继日志。就这点而言,MySQL 5.5之后的版本做了改进,它能够在崩溃后自动获取中继日志。

二进制日志和InnDB事务日志不同步

当主库崩溃时,InnDB可能将一个事务标记为已提交,此时该事物可能还没有记录到二进制日志当中。除非是某个从库的中继日志已经保存,否则没有任何办法恢复丢失的事务。在MySQL 5.0 版本可以设置 sync_binlog 选项来防止该问题,对于更早的MySQL4.1可以设置 sync_binlog和 safe_binlog选项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/101597.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国内免费无限制的chatgpt导航和ai画画

非常实用的AI网址导航,其实际使用体验非常便捷。该导航系统不仅提供了全面的网站分类和搜索功能,还对每个网站进行了精准的评估和排序。推荐高质量的网站资源,并实时检测网站的安全性,保障用户的上网安全。 总的来说&#xff1a…

leetcode 第 361 场周赛

2843. 统计对称整数的数目 核心思想:枚举每一个数是否是对称整数,第一种写法为python写法,第二种为一般写法我觉得更好,非常有思想性。 2844. 生成特殊数字的最少操作 核心思想:枚举特殊数字结尾的几种可能。其实自己做的时候一…

电商3D资产优化管线的自动化

如果你曾经尝试将从 CAD 程序导出的 3D 模型上传到 WebGL 或 AR 服务,那么可能会遇到最大文件大小、永无休止的进度条和糟糕的帧速率等问题。 为了创作良好的在线交互体验,优化 3D 数据的大小和性能至关重要。 这也有利于你的盈利,因为较小的…

h5微传单制作教程:快速轻松制作

在当今社交媒体充斥的时代,微传单作为一种新型的宣传推广方式,成为了企业和个人在传播信息时的重要工具。h5微传单相比传统的纸质传单更加灵活多样,并且能够通过手机、平板等设备随时随地进行浏览和分享,具有很高的传播效果。下面…

maven依赖,继承

目录 依赖的范围 依赖的传递性 依赖的排除 继承 在父工程中管理依赖 配置自定义属性 实际意义 聚合 依赖的范围 compile引入的依赖 对main目录下的代码有没有效,main目录下的代码能不能用compile引入的依赖中的类等 以test引入的依赖,在main中是否可以…

结构体对齐原理及在STM32中的设计原则和实现

在嵌入式系统开发中,结构体作为一种常见的数据组织方式,在内存中的布局方式对于程序性能和内存占用具有重要影响。本文将深入探讨单片机C语言中的结构体对齐原理、重要性以及不同的对齐方式,并通过示例演示结构体对齐如何影响内存占用、访问性…

React 第一个Demo

0x00 前言 CTF 加解密合集CTF Web合集网络安全知识库 次笔记仅记录学习React过程中的笔记&#xff0c;因为有必要掌握一门前端的框架&#xff0c; 在vue和React中选择了React。 0x01 正文 目标&#xff1a; 实现Demo&#xff1a; <!DOCTYPE html> <html lang&q…

Ansible-roles学习

目录 一.roles角色介绍二.示例一.安装httpd服务 一.roles角色介绍 roles能够根据层次型结构自动装载变量文件&#xff0c;tasks以及handlers登。要使用roles只需在playbook中使用include指令即可。roles就是通过分别将变量&#xff0c;文件&#xff0c;任务&#xff0c;模块以…

javaee之黑马乐优商城2

简单分析一下商品分类表的结构 先来说一下分类表与品牌表之间的关系 再来说一下分类表和品牌表与商品表之间的关系 面我们要开始就要创建sql语句了嘛&#xff0c;这里我们分析一下字段 用到的数据库是heima->tb_category这个表 现在去数据库里面创建好这张表 下面我们再去编…

Multimedia-播放器-架构2

目录 引言 问题1&#xff1a; 数据缓冲区 多线程模型 缓冲区的特点&#xff1a; 点播和直播场景中的缓冲区&#xff1a; 问题2&#xff1a; 同步方式 同步实现过程 引言 上一篇梳理了播放器的基本工作与处理流程&#xff0c;本片内容主要梳理一下其中会遇到的问题&am…

宠物行业如何进行软文营销

如今&#xff0c;宠物已经成为了人们生活中不可或缺的一部分&#xff0c;大众对于萌宠的喜爱与日俱增&#xff0c;随着“萌宠经济”升温&#xff0c;越来越多的商机开始出现&#xff0c;伴随着宠物市场竞争的日益激烈&#xff0c;宠物行业的营销光靠硬广告很难吸引受众&#xf…

【C++二叉树】进阶OJ题

【C二叉树】进阶OJ题 目录 【C二叉树】进阶OJ题1.二叉树的层序遍历II示例代码解题思路 2.二叉搜索树与双向链表示例代码解题思路 3.从前序与中序遍历序列构造二叉树示例代码解题思路 4.从中序与后序遍历序列构造二叉树示例代码解题思路 5.二叉树的前序遍历&#xff08;非递归迭…