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

news2025/1/12 20:09:15

概述

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

如果这是计划内的切换,会相对容易点。只需要在从库上使用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.coloradmin.cn/o/981273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据技术之Hadoop:使用命令操作HDFS(四)

目录 一、创建文件夹 二、查看指定目录下的内容 三、上传文件到HDFS指定目录下 四、查看HDFS文件内容 五、下载HDFS文件 六、拷贝HDFS文件 七、HDFS数据移动操作 八、HDFS数据删除操作 九、HDFS的其他命令 十、hdfs web查看目录 十一、HDFS客户端工具 11.1 下载插件…

OpenWrt系统内核设置

系统内核设置:OpenWrt也是一个 Linux 操作系统,因此它和其他Linux 操作系统一样, 可以通过一些配置文件配置。 一、/etc/sysctl.conf 配置文件 这个文件是系统启动预加载的内核配置文件,通过sysctl命令读取和设置到系统当中。这个…

openGauss学习笔记-62 openGauss 数据库管理-两地三中心跨Region容灾

文章目录 openGauss学习笔记-62 openGauss 数据库管理-两地三中心跨Region容灾62.1 基于流式复制的异地容灾解决方案62.1.1 概述62.1.2 规格与约束62.1.2.1 特性规格62.1.2.2 特性约束 62.1.3 影响容灾性能指标的GUC参数设置62.1.3.1 检查点相关参数设置的影响62.1.3.2 极致RTO…

android 车载widget小部件部分详细源码实战开发-千里马车载车机framework开发实战课程

官网参考链接:https://developer.android.google.cn/develop/ui/views/appwidgets/overview 1、什么是小部件 App widgets are miniature application views that can be embedded in other applications (such as the home screen) and receive periodic updates…

LED显示屏安全亮度参数设置方法和防护

随着LED显示屏应用领域越来越广,但其高亮度造成的光污染,常受到的人们的诟病。为了更好的避免光污染,我整理了一些关于LED显示安全亮度参数设置方法和安全防护措施。你知道LED广告牌是如何工作的吗? 设置LED显示屏的安全亮度参数和…

android上架备案公钥和md5获取工具

最近很多公司上架遇到了一个问题,就是要提供app的备案证明,现在android上架都需要备案了,但是我们的证书都是通过工具生成的,哪里知道公钥和md5那些东西呢?无论安卓备案还是ios备案都需要提供公钥和md5。 包括ios的备案…

ChatGPT Prompting开发实战(五)

一、如何编写有效的prompt 对于大语言模型来说,编写出有效的prompt能够帮助模型更好地理解用户的意图(intents),生成针对用户提问来说是有效的答案,避免用户与模型之间来来回回对话多次但是用户不能从LLM那里得到有意义的反馈。本文通过具体…

异步请求库的实际应用案例:爬取豆瓣经典电影

在日常爬虫过程中,你有没有遇到过需要爬取大量数据的情况,但是传统的同步请求方式让您等得焦头烂额? 这个问题的根源在于传统的同步请求方式。当我们使用同步请求时,程序会一直等待服务器的响应,直到数据返回后才能继续…

Jmeter性能测试手册

目录 目录 2 简介... 4JMeter与LoadRunner区别... 4环境配置... 5 3.1 安装JDK. 5 3.2 配置JDK环境变量... 9 3.3 安装并配置Maven. 13 3.4 下载JMeter 15 JMeter分类使用... 16 4.1 对于Dubbo类接口的测试.. 16 4.1.1 安装开发工具IDEA. 16 4.1.2 配置字符集格式…

leetcode_27_最小栈

class MinStack { public:MinStack() {}void push(int val) {//只要是压栈&#xff0c;先将元素保存到_elem中_elem.push(val);//如果x小于_min中栈顶的元素&#xff0c;将x再压入_min中if(_min.empty() || val < _min.top()){_min.push(val);}}void pop() {//如果——min栈…

OSPF路由协议

OSPF基本信息 OSPF&#xff08;Open Shortest Path First&#xff09;开放式最短路径优先协议是用于网际协议&#xff08;IP&#xff09;网络的链路状态路由协议。该协议使用链路状态路由算法的内部网关协议&#xff08;IGP&#xff09;&#xff0c;在单一自治系统&#xff08…

【论文通读】CLIP改进工作综述

CLIP改进工作综述 前言1. 语义分割1.1 Lseg1.2 GroupViT 2. 图像检测2.1 ViLD2.2 GLIP2.3 GLIPv2 3. 图像生成3.1 CLIPasso 4. 视频理解4.1 CLIP4Clip4.2 ActionCLIP 5. 其它领域5.1 CLIP-VIL5.2 AudioCLIP5.3 PointCLIP5.4 DepthCLIP 总结参考链接 前言 CLIP作为多模态对比学…

torch.nn中的L1Loss和MSELoss

我们打开Pytorch官网&#xff0c;找到torch.nn中的loss function&#xff0c;进去如下图所示。 L1LOSS 我们先来看看 L1LOSS 损失函数的使用。下图是官网给出的描述。 L1loss有两种方式&#xff0c;一种是将所有误差累加作为总损失&#xff0c;另一种是将所有误差累加之后求平…

java八股文面试[数据库]——一个B+树中大概能存放多少条索引记录

MySQL设计者将一个BTree的节点的大小设置为等于一个页. (这样做的目的是每个节点只需要一次I/O就可以完全载入), InnoDB的一个页的大小是16KB,所以每个节点的大小也是16KB, 并且BTree的根节点是保存在内存中的,子节点才是存储在磁盘上. 假设一个B树高为2&#xff0c;即存在一个…

Cyber RT基础入门与实践_Hello Apollo

Hello Apollo 进入云实验环境模块的模块内包的 进入云实验环境 <1> 创建本节实验工程目录&#xff0c;创建完成后&#xff0c;工程目录如下所示&#xff1a; cyber_demo |-- cyber_01 |-- demo_main | |-- BUILD | |-- main.cc |–BUILD |–cyberfile.xml |–cyber_demo.…

YOLO目标检测——火焰检测数据集+已标注xml和txt格式标签下载分享

实际项目应用&#xff1a;火灾预警系统、智能监控系统、工业安全管理、森林火灾监测以及城市规划和消防设计等应用场景中具有广泛的应用潜力&#xff0c;可以提高火灾检测的准确性和效率&#xff0c;保障人员和财产的安全。数据集说明&#xff1a;YOLO火焰目标检测数据集&#…

栈和队列经典笔试题

文章目录 栈和队列的回顾&#x1f4bb;栈&#x1fa73;队列&#x1f45f; 栈和队列经典笔试题&#x1f50b;有效的括号&#x1f3b8;用队列实现栈 &#x1f56f;用栈实现队列&#x1f52d;设计循环队列&#x1f9fc; 安静的夜晚 你在想谁吗 栈和队列的回顾&#x1f4bb; 栈&am…

在VR全景中嵌入3D模型有哪些优势?

现阶段&#xff0c;很多商企都会引入VR全景展示来宣传推广自己的产品、服务以及环境&#xff0c;但是环境展示凸显的沉浸式体验只是 VR全景一部分的价值所在&#xff0c;商企使用VR全景还有一个优势就是互动性&#xff0c;通过丰富多样的互动性&#xff0c;让用户同VR场景中的物…

Linux下systemd深入指南:如何优化Java服务管理与开机自启配置

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

网络编程day6作业

完成网络聊天室编写 ser #define ERR_MSG(msg) do{\fprintf(stderr,"__%d__",__LINE__);\perror(msg);\ }while(0) #define IP "127.0.0.1" #define PORT 6666 //创建链表 Linklistptr list_create(); Linklistptr node_buy(datatype e); int list_inser…