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

2023-11-08

概述

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

如果这是计划内的切换,会相对容易点。只需要在从库上使用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选项。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql(十)mysql主从复制--主库切换 的相关文章

  • 如何修改现有表以添加时区

    我有一个包含 500 多个表的大型应用程序 我必须将应用程序转换为时区感知 当前应用程序使用new java util Date GETDATE 与服务器的时区 即没有任何时区支持 我已将这项任务分为几个步骤 以便于开发 我确定的第一个步骤
  • Mysql 时间匹配连接

    我有两个表cpuinfo和jobinfo 我想使用这两种数据创建报告 tabes CREATE TABLE cpuinfo id int 11 NOT NULL AUTO INCREMENT usagetime datetime DEFAU
  • 显示标准化数据

    跟进问题 添加 2 个不同表的总和 https stackoverflow com questions 39717541 adding sum from 2 different tables 我创建了3个表 members videos v
  • 仅当值发生更改时如何插入数据库?

    我需要更新 替换 MySQL 数据库中的字段 但前提是它们已更改 该表包含 ID 文本字段和更改日期 用户根据更改日期通过 ID 查询数据 即 如果该日期早于用户上次查询数据的时间 则他不想要它 仅当文本字段与具有相同 ID 的现有文本字段
  • 不允许在 php 中连接到此 MariaDB 服务器

    我尝试在 php 中连接远程服务器数据库 但出现以下错误 Host xx xxx xx xx is not allowed to connect to this MariaDB server in 我的连接代码是这样的 servername
  • MySQL 通过 current_timestamp 选择上个月的数据

    直到今天 当我使用 MySQL 并需要对日期 时间执行操作时 我使用带有 unix 时间戳的 int 列 没有出现任何问题 但今天在阅读了一些指南后 我决定默认使用 current timestamp 测试时间戳列 所以我感兴趣如何按列选择
  • 在 MySQL 中对整数字段运行带引号的数字(字符串)查询时会发生哪些复杂情况

    在 SQL 中 不应引用整数 因为如果引用 它将是一个字符串 但我很好奇如果我这样做会出现什么问题 并发症 例如 SELECT FROM table WHERE id 1 正确的 vs SELECT FROM table WHERE id
  • 合并两个 MYSQL SELECT 查询[重复]

    这个问题在这里已经有答案了 可能的重复 如何将两个 Post Category 表 MYSQL SELECT 查询合并为一个 https stackoverflow com questions 12972130 how to combine
  • PHP MYSQL文件内容转义问题

    我正在尝试使用 php 将 pdf 文件上传到 mysql 数据库中 除了文件内容之外 一切都很好 无论我如何尝试转义特殊字符 查询总是失败 主要是 未知命令 n 我使用过addslashes mysql real escape strin
  • 每月获取记录,但如果该月没有记录,则为零

    如果我有以下 SQL 表 Tests id type receiveDate 1 Blood 2012 01 18 2 Blood 2012 01 20 3 Blood 2012 01 18 4 Blood 2012 03 01 5 Blo
  • 非常大的字段会对 MySQL 数据库产生负面影响吗?

    我目前正在使用 Django 构建一个网站 并希望托管用户生物样式页面 该页面可能长达几 KB 这些字段不一定需要搜索 但在查找用户名时确实需要提供 将这些数据存储在数据库中会产生负面影响吗 如果我使用带有数据库链接的静态文本文件 我的服务
  • 让登录更安全

    我已使用此代码进行管理员登录 仅当用户输入正确的用户名和密码时才应打开loginhome php 但后来我意识到这根本不安全 任何人都可以直接访问 mywebsite loginhome php 而无需登录 注销后 可以使用后退按钮打开 l
  • PHP MySQL 使用选项/选择 HTML 表单标签进行多重搜索查询

    我正在尝试使用两个搜索字段设置基本的 MySQL LIKE 搜索 我不想拥有它 所以它有多个可选搜索字段 例如if isset POST city isset POST name 我不知道如何用 HTML 来做到这一点
  • Mysql用in语句限制

    我正在写一个查询 SELECT user bookmarks id as user bookmark id bookmark id user bookmarks user id bookmark url bookmark website b
  • 删除行导致锁超时

    当我尝试从表中删除行时 我不断收到这些错误 这里的特殊情况是我可能同时运行5个进程 该表本身是一个 Innodb 表 约有 450 万行 我的 WHERE 子句中使用的列没有索引 其他指数按预期运行 这是在事务中完成的 首先删除记录 然后插
  • posts_search 中的自定义查询

    如何使用此查询作为我的自定义搜索查询 add filter posts search my search is perfect 20 2 function my search is perfect search wp query sWord
  • MySQL 与日语字符

    我试图弄清楚如何创建一个表 以便我可以在其中插入日语名字 现在我有 Type InnoDB Encoding UTF 8 Unicode utf8 Collation utf8 general ci 但是 当我插入字符时 它显示为 当我使用
  • 从Django中具有外键关系的两个表中检索数据? [复制]

    这个问题在这里已经有答案了 This is my models py file from django db import models class Author models Model first name models CharFie
  • 快速将列的副本添加到 MySQL 表

    我需要一种快速的方法来复制表中的 DATETIME 列并为其指定一个新名称 我的表中有一个名为 myDate 的列 名为 myResults 我需要一个查询来在名为 newDate 的表中创建一个新列 该列的数据与 myDate 列完全相同
  • Android Studio 无法识别 Mac/Linux 上的 OnePlus2

    我的 Android Studio 1 3 2 无法识别我的手机 一加二号 我有 Mac OS x Yosemite 10 10 5 和最新的 Android SDK 更新1 我的Mac上安装的文件传输软件 Android File Tra

随机推荐

  • 从源头理解Batch Normalization (顺带搞懂为什么做参数初始化)

    一 BN LN等一系列Normalization方法的动机 因为一个网络中某层的参数的梯度 最终是由训练样本中这层输入的各个feature的具体数值决定的 如果feature的数值变化范围过大 比如不同特征的含义就导致了取值范围不在一个数量
  • 标签传递算法:java版

    标签传递算法 java版 标签传递算法 java版 java labelpropagation 本地测试 数据集 LPAlgorithm loadJSON vertexAdjMap和vertexInAdjMap的区别在哪里 根据每个节点的权
  • 【计算机视觉

    文章目录 一 前言 二 简介 三 相关方法 3 1 实时目标检测器 3 2 端到端目标检测器 3 3 目标检测的多尺度特征 四 检测器端到端速度 4 1 分析NMS 4 2 端到端速度基准 五 The Real time DETR 5 1
  • 我的世界虚拟服务器联机,我的世界模拟城市联机教程-的世界怎么联机

    我的世界联机分为服务器联机和本地WIFI联机两种 首先我们先说下服务器联机方法 一 打开游戏后 点击Play进入游戏列表 再点击右上角的Edit 然后点击External 然后将会进入添加服务器的界面 第一行 ServerName 那里填写
  • 安卓默认启动的活动界面

    是在AndroidManifest 的activity 的标签中 加入 的活动是默认启动的
  • ENVI5.3安装

    一 下载地址 BT下载地址 链接 https pan baidu com s 1Z1l0qXQjSaEf3VQj9 qcAw 提取码 4il4 压缩包下载 链接 https pan baidu com s 1EbdO0uDiBdbFFdQx
  • java中定义score方法_elasticsearch 自定义 script score JavaAPI查询详解

    一 自定义score的应用场景 先打个比方 比如新产品上架了 我想让最新上架的产品搜索时候 排在前面 怎么办呢 很简单按时间排序 嗯这种方法很好实现 但下面又有个需求 比如我要求排序中上架时间的比重为40 自营产品为20 促销产品的比重为4
  • git branch管理常用命令

    本文转载至 http www 2cto com os 201307 229235 html git branch管理常用命令 查看本地分支 plain git branch dev master 代表当前位于dev分支 查看远程分支 pla
  • python netcdf4读取nc格式的气象数据

    一 nc格式数据介绍 NetCDF全称为network Common Data Format 中文译法为 网络通用数据格式 netcdf文件开始的目的是用于存储气象科学中的数据 现在已经成为许多数据采集软件的生成文件的格式 从数学上来说 n
  • PROJ4是什么?

    GIS Geographic Information System 地理信息系统 领域中最常提及 的一个概念是坐标系统 当我们提及一个地理位置的时候 与之伴随而产生的是该位置必定在一个空间参考下 当我们使用GPS设备获取到某个位置的经纬度的
  • Linux常用配置及硬件检测命令

    一些比较常见的linux命令 主要用于检测服务器的配置和硬件信息 包括 操作系统 CPU 内存 硬盘分区 系统时间 负载 网络相关 进程 用户 开关机 启动等方面 适用于主流操作系统 常见的centos ubuntu debian等 操作系
  • python selenium 三种等待方式详解

    引言 当你觉得你的定位没有问题 但是却直接报了元素不可见 那你就可以考虑是不是因为程序运行太快或者页面加载太慢造成了元素还没出来就已经报错了 试着程序调试程序运行速度 等待元素可见再继续运行程序 1 强制等待 sleep 优点 简单明了 需
  • 【国家参考文献标准GB/T 7714—2015】

    GB T 7714 2015 2 1 参考文献著录方法几种主要类型的参考文献 专著 专著中的析出文献 连续出版物 连续出版物中的析出文献 专利文献 电子文献等 的著录项目与格式要求如下 2 1 1 专著 图书 M 指以单行本或多卷册形式 在
  • 游戏开发unity编辑器扩展知识系列:获取选中文件的路径

    参考 Unity 编辑器下获取选择文件路径
  • Python中如何输出换行?

    Python中如何输出换行 在Python中 输出换行可以使用的方法有两种 分别是用转义符号或使用print 接下来我们通过这篇文章为大家详细的讲解一下 方法1 用转义符号 str3 老男孩教育 n str4 帮助有志向的年轻人通过努力学习
  • Threejs + vue 学习- VR 看房

    知识点 参考链接 threejs github 图片下载 https gitee com congyingcy threejs learning tree master three public imgs 直接跳转 代码下载 直接跳转 立方
  • maven自定义Archetype

    1 创建模板项目 如下 2 模板项目的pom xml中添加archetype插件
  • 光纤验收测试标准、参数及常用设备

    在光纤工程项目中必须执行一系列的测试以确保其完整性 一根光缆从出厂到工程安装完毕 需要进行机械测试 几何测试 光测及传输测试 前3个测试一般在工厂进行 传输测试则是光缆布线系统工程验收的必要步骤 综合布线工程电气测试包括电缆系统电气性能测试
  • ChatGPT追祖寻宗:GPT-1论文要点解读

    论文地址 Improving Language Understanding by Generative Pre Training 最近一直忙着打比赛 好久没更文了 这两天突然想再回顾一下GPT 1和GPT 2的论文 于是花时间又整理了一下
  • mysql(十)mysql主从复制--主库切换

    概述 可能为了更迭升级服务器 或者主库出现问题 又或者只是希望重新分配容量 此时需要切换主库 如果这是计划内的切换 会相对容易点 只需要在从库上使用CHANGE MASTER TO命令 并设置合适的值 大多数的值都是可选的 至少要指定需要改