为啥在 MySQL 复制中使用 GTID?

Posted

技术标签:

【中文标题】为啥在 MySQL 复制中使用 GTID?【英文标题】:Why use GTIDs in MySQL replication?为什么在 MySQL 复制中使用 GTID? 【发布时间】:2014-06-22 13:05:50 【问题描述】:

说到数据库复制,全局事务标识符有什么用?为什么我们需要防止跨服务器的并发?这种预防究竟是如何实现的?

我尝试在以下位置阅读文档 http://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html 但还是看不懂。这听起来可能很基础,但如果有人能向我解释这些概念,我将不胜感激。

【问题讨论】:

【参考方案1】:

全局事务 ID 的原因是允许 MySQL 从属知道它是否已应用给定事务,以保持主从之间的同步。如果连接断开,它也可以用于重新启动从站,以再次了解时间点。在不使用 GTID 的情况下,必须根据给定二进制事务日志文件(bin 日志)中的位置来控制复制。这比 GTID 方法更难管理。

主服务器是唯一通常写入的服务器,因此从服务器只需通过按顺序应用每个事务来重建主服务器的副本。

了解 MySQL 复制可以以 3 种模式之一运行也很重要:

Statement-based:每个 SQL 语句都记录到 binlog 并作为语句复制到从站。在某些情况下,这在从站可能是模棱两可的,导致数据不完全匹配。 (大多数情况下它可以用于普通用途)。 Row-based:在这种模式下,MySQL 将实际数据更改复制到每个表,每行都有“之前”和“之后”的图片,这是完全准确的。这可能会导致更大的 binlog,例如,如果您有批量更新查询,例如:UPDATE t1 SET c1 = 'a' WHERE c2 = 'b'。 混合:在这种模式下,MySQL 将在 binlog 中混合使用基于语句和基于行的日志记录。

我只提到复制模式,因为在您引用的文档中提到,如果您使用 GTID,推荐使用基于行的选项。

还有另一个选项称为 Master-Master 复制,您可以在其中写入两个 master(每个充当另一个的 slave),但这需要特殊配置以确保写入每个 master 的数据是唯一的。它比典型的主/从设置更难管理。

因此,防止写入从属设备是您必须从您的应用程序中确保典型复制过程正常运行的事情。从 Slave 读取是可以的,但你不应该写入它。请注意,如果您将 Slave 用于读取,则它可以在 Master 之后,因此最好对可能在 Master 之后的事物执行查询(例如直到秒或毫秒都不重要的报告)。您可以通过将您的普通应用程序用户设置为从服务器的只读用户和主服务器的读写用户来确保不写入从服务器。

【讨论】:

【参考方案2】:

为什么我们需要防止跨服务器的并发?

如果我正确理解了这个问题,那么您说的是一致性。如果是这样,答案是您需要在分布式系统中保持一致的状态。例如,如果我的银行账户信息在多个不同的服务器上复制,那么它们的余额必须完全相同。现在想象一下,我执行了多次货币交易(存款/支出),并且每次都连接到不同的服务器:并发问题会导致我的帐户余额在每台服务器上都不同,这是不可接受的。

这种预防是如何实现的?

使用主/从方法。在这些服务器中,您有一个服务器(主服务器)负责处理每个写入操作,这意味着对数据库的修改必须仅由该服务器处理。该主服务器的数据库被复制到所有其他服务器(从属服务器),这些服务器不允许修改数据库,但可以用于读取数据库(例如 SELECT 操作)。知道只有一台服务器允许修改数据库,就没有一致性问题。

全局事务标识符有什么用?

服务器之间的通信是异步的,从服务器不需要一直与主服务器连接。因此,一旦从服务器与主服务器重新连接,它可能会发现主服务器的数据库同时被修改,因此它必须更新自己的数据库。现在的问题是要知道主服务器执行的所有修改,哪些是从服务器在以前的日期已经执行的修改,哪些是尚未执行的修改。

GTID 解决了这个问题:它们唯一地标识了主服务器执行的每个事务。现在,从服务器可以识别主服务器执行的所有事务,这些事务是以前未见过的。

【讨论】:

以上是关于为啥在 MySQL 复制中使用 GTID?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的GTID复制

MySQL基于GTID的主从复制

MySQL5.7 传统复制到GTID复制

mysql集群-基于GTID的主从复制

MySQL跳过复制错误

配置MYSQL基于GTID 主从复制详细解析及步骤