教你如何基于MySQL进行数据高可用[亲测有效]

教你如何基于MySQL进行数据高可用[亲测有效]数据高可用之所以是老生常谈的话题,是因它对企业数据安全起到了至关重要的保障作用,数据高可用核心功能在于如何保证在发生故障时数据不丢失。本文 作者热璞数据库首席架构师,精通数据库原理和MySQL开源数…

教你如何基于MySQL进行数据高可用

数据高可用之所以是老生常谈的话题,是因它对企业数据安全起到了至关重要的保障作用,数据高可用核心功能在于如何保证在发生故障时数据不丢失。本文 作者热璞数据库首席架构师,精通数据库原理和MySQL开源数据库,将以使用者视角,抽丝剥茧式的手把手教你如何基于MySQL进行数据高可用。强烈建议大家收藏! 以下引用作者原文

如何基于MySQL进行数据高可用

这次探讨的话题是数据高可用,首先,我们需要理清楚数据高可用的目标,数据高可用说的是,“即使发生故障,数据也不丢失”。那么就需要明确,什么叫不丢失。

先假设存在一个完美的数据库系统,我们不关心它是怎么做到的,只把它当成一个黑盒子,当承载这个数据库的服务器宕机的时候,从数据库使用者角度分析,会遇到以下三种情况:

一、过去执行的事务都已经提交完成,当前没有在执行的事务,连接中断;

二、正在执行事务,还没有发出提交操作,连接中断;

三、正在执行事务,已经发出提交操作,连接中断;

情况一、完美数据库在恢复后应该要保证过去已经提交完成的事务依旧存在,不会丢失 ;

情况二、完美数据库在恢复后应该要保证未提交的事务被正确回滚;

情况三、会出现三种分支情况,我们逐一分析:

  • 提交操作到达数据库前连接就已经中断了,这个时候,完美数据库在恢复时应该回滚事务;
  • 提交操作已经到达数据库后,连接中断,完美数据库在恢复时,应当提交这个事务;
  • 数据库已经提交完成,并且发出了提交成功的信息,但是提交成功的信息在到达使用者之前,连接中断了,这个时候,完美数据库在恢复时,也应当保证这个事务依旧已经提交了。

回到使用者视角,一个完美的数据库能够做到:

第1保证: 没有发出提交操作的事务一定被回滚; 第2保证: 已经发出提交操作并收到提交成功的事务一定存在,且已提交; 第3保证: 已经发出提交操作但没有收到提交成功的事务,要么提交了,要么回滚了 。

✎ 应用端针对“已经发出提交操作但没有收到提交成功的事务”的情形,在实际生产环境中,一定要应用程序在数据库恢复可访问后,重新检查事务是否存在,再从对应的业务角度做出相应的补偿处理。若只简单地认为这样的事务一定成功或者一定失败,都是不正确的;必须检查事务中的数据才能知道结果;只有业务的操作完全满足幂等,才能无脑重做。并且从数据库的角度,努力的上限也只是使得情况三的第二种分支的所有事务,可以全被提交,无法实现在情形三下,有确定结果 。

现在我们可以定 义,只要高可用方案,满足上述三条使用者视角下的“完美数据库保证的结果”,就可以说该高可用方案就可以实现“使用者视角等效完美数据库的不丢数据”,本文后续称之为“等效不丢”。

✎ 达到“等效不丢”不表述达到了完美数据库等同的高度,只表述从使用者的角度看,和其等效。

考虑现实情况,一个高可用方案,明显是不可能面对任意灾难都能保证不丢数据。 原因是: 假设,当彻底破坏这个方案所涉及的所有存储设备(包含内存)的时候,数据必定全部丢失。 因此除了明确什么叫数据不丢失之外,一个真实可操作的高可用方案,还需要定义清楚这个方案能够应对的灾难等级。

先讲最简单的一种,单台服务器因为硬件故障彻底损毁。我们应当怎么样做到“等效不丢”呢 ?

✎ 单台服务器故障后,如果是通过人工或自动重启,经过一定的处理使得数据库恢复运行,反而会带来更多的坑点与处理上的麻烦,我们后面再来详细分析 。

首先,很明显,我们必须排除任何单服务器的方案。我们看看MySQL最常见的、简单的主从复制。 主从复制中,从机损坏显然是安全的,主机可以完整保证“等效不丢”。如果当主机损坏时,立即切换到从机,我们来仔细分析一下,这种最基本的高可用有没有问题,有问题的话可不可以改善和解决。 首先等效不丢的 第1保证 明显是可以满足的,没有提交的事务根本就不会发往从机。

再看关键的 第2保证 :在普通的主从复制架构下,主机上成功提交的事务和复制的数据传输过程没有任何关联,不能保证从机收到所有在主机上已经提交的事务,因此无法实现第2保证。但是我们可以开启半同步复制,这样,只有从机收到了事务内容,主机才会返回提交成功,由此奠定了实现第2保证的基础(还要配合后续的等待追上复制才实现)。

✎ 敲黑板 !划重点:关于5.6的半同步复制是否会丢数据,一直是一个争论不休的问题,现在可以得到一个答案:5.6的半同步复制,满足“等效不丢”。但是5.6和after_commit方式,确实存在小问题。举例:T1线程执行了一个事务操作,发起了提交,从机网络很慢,没有及时返回ACK;这时T2线程,发起了一个事务,是可以读到T1线程的操作的,假设在从机收到事务前发生故障并切换,则T2线程可能观察到“数据丢了”;但是T1并没有收到事务提交成功的信息,未来重新判定,这个事务是没有提交成功,从T1的视角是没有问题的。那从这个例子来看,问题很明显,5.6和after_commit的方式,存在事务隔离处理上的微小缺陷。

1 、半同步复制如果退化,则不能保证“等效不丢”。 2 、半同步复制的场景,不应该使用relay_log_recovery,启用这个参数后,在一些场景会删除relaylog,这将明显破坏半同步复制的有效运行; 3 、 我们刚才讨论的半同步复制,完全没有涉及到 sync_binlog、innodb_flush_log_at_trx_commit参数的配置值,因为这个时候, 数据的高可用依赖的是“持久化到网络”而非“持久化到磁盘”,数据是否刷到磁盘,跟数据的高可用完全无关,我们只关注,数据是否安全到达了另一台服务器。并且,我们这次举例的最简单场景,属于主机或者从机完全损坏,数据是否刷到磁盘,反正都是全部没了,不影响高可用的效果,不刷盘,数据库还能跑得更欢乐一些。

第3保证 也是可以满足的,从机的复制机制能够保证单个事务的完整执行,实现要么有要么没有的结果。但是此时我们可以发现一个藏得比较深但很常见的异常问题:复制的SQL线程应用数据是有延迟的,切换后,从机可能还在不断追赶复制;从应用程序的角度看,则是出现:看到第3保证场景的不知道成功还是失败的事务的操作一开始丢失了,但是过了一会儿又神秘出现了(第2保证场景的情形,同样可能看到这样的情况),这样显然是无法接受的。

MySQL主从复制IO线程延迟和SQL线程延迟有长有短,但是毫秒、微秒级的延迟,始终是存在的,不能通过假设复制或者要求复制没有延迟的方式去逃避这个问题。这个问题的解决实际上是可以通过等待复制追上,然后再开放从机的访问来解决的。一般高可用方案也都考虑到了这一点。

✎ 从机收到的relaylog,可能存在末尾不是一个完整的事务的现象,因此追复制过程,也需要一些很特别的处理过程,才能做到完美。很少有高可用方案,正确处理了这种情况。

小结 : 经过这篇文章的探讨,使用半同步复制,配合良好完善的切换处理,可以在半同步复制没有退化,单一服务器无法恢复的损毁中(不含MySQL BUG 、服务器后续可以恢复运行与访问、MySQL实例hang、以及误判断切换等场景),保证数据在“等效不丢”这个概念下的数据高可用。

更多复杂场景,请期待后续讲解。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/8558.html

(0)
上一篇 2023-02-26
下一篇 2023-02-26

相关推荐

  • 【Redis】集群教程(Windows)[通俗易懂]

    【Redis】集群教程(Windows)[通俗易懂]Redis配置集群教程,介绍Redis集群数据分片,节点通讯,然后准备环境,搭建集群,测试集群使用

    2023-02-15
    147
  • mysql数据库常用命令总结_mysql数据库基础知识

    mysql数据库常用命令总结_mysql数据库基础知识数据库连接 链接数据库:代表连接数据库管理系 统 <!一个应用程序可以对应一个数据库,一个数据库管理系统可以管理多个数据库> <!表是用来存储数据的> 连

    2023-06-13
    139
  • Python的pymysql用法

    Python的pymysql用法
    使用pip安装pymysql 的方法 pip install pymysql 连接数据库 conn = pymysql.connect(host=”127….

    2023-04-17
    162
  • Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了「建议收藏」

    Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了「建议收藏」Redis中几个“看似”高大上的概念,经常有人提到,某些好事者喜欢死扣概念,实战没多少,嘴巴里冒出来的全是高大上的名词,个人一向鄙视概念党,呵呵,尼玛! 其实这几个概念:缓存穿透/缓存击穿/缓存雪崩,

    2022-12-26
    151
  • 提高效率的时间模块Python编程技巧

    提高效率的时间模块Python编程技巧计算机编程领域中,时间处理一直是一个很重要的任务。在Python编程中,提高时间处理的效率和精度是非常必要的,也是非常具有挑战性的。Python的时间模块是一个非常强大的工具,提供了许多函数和类,可以轻松地处理日期和时间的各种操作。这篇文章将分享一些提高时间模块Python编程效率的技巧,希望能够帮助读者提高编程效率,减少开发时间。

    2024-02-22
    100
  • Python函数定义的例子:计算两个数字的乘积

    Python函数定义的例子:计算两个数字的乘积在Python编程中,函数是一个非常常用的概念。函数可以将一段代码封装起来,使得重复使用变得更加简单,减少了出错的可能性。在本文中,我们将演示如何定义一个简单的Python函数,用于计算两个数字的乘积。

    2024-03-23
    87
  • MySQL简单实现多字段模糊查询【转】「终于解决」

    MySQL简单实现多字段模糊查询【转】「终于解决」我所做的商城项目前些时提了新需求,要求前台搜索商品除了能通过商品名称搜索到以外,还可以通过别个信息搜索,比如:商品编号、详情内容描述等等,类似于全文搜索了。我首先想到的就是lucene,但是对代码这样

    2023-02-15
    140
  • Python正则表达式:强大的文本匹配工具

    Python正则表达式:强大的文本匹配工具正则表达式是一种处理字符串的方法。在文本处理中,经常需要对字符串进行操作,例如字符串的匹配、替换以及删除等操作。Python中的正则表达式库re提供了一套强大的工具,能够对文本进行全面的匹配和操作。

    2024-02-23
    113

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注