当前位置: 首页 > 后端技术 > PHP

MySQL复制——性能和可伸缩性的基石一:概述及其原理

时间:2023-03-30 02:43:44 PHP

1.复制概述MySQL内置的复制功能是基于MySQL构建大规模、高性能应用程序的基础。复制解决的基本问题是使一个服务器的数据与其他服务器保持同步。下面我们将从复制的概述和原理、复制的配置、常见问题及解决方案来学习MySQL的复制功能。1.1Replication解决的问题以下是replication的一个常见用途:数据分发。Mysql的复制通常不会对带宽造成很大的压力,但是5.1版本引入的基于行的复制会比传统的基于语句的复制方式造成更大的带宽压力。您可以随意停止和开始复制,将数据备份分布在不同的地理位置,比如不同的数据中心。此外,即使在不稳定的网络环境中,远程复制也能正常工作。但是如果你想在未来保持低复制延迟,最好有一个稳定的、低延迟的连接。负载均衡。通过Mysql复制,可以将读操作分布到多台服务器上,优化读密集型应用,实现简单。基本的负载均衡可以通过简单的代码修改来实现。对于小规模的应用,可以简单地使用DNSround-robin(将一个机器名指向多个IP地址)。备份。加载是对备份的有意义的技术补充。高可用性和故障转移。负载可以帮助应用程序避免Mysql单点故障,使用复制的设计良好的系统可以显着减少停机时间。mysql升级测试。这是一种比较普遍的做法。在更新Mysql版本之前,使用待更新的版本作为备份数据库,保证更新后的版本不会对系统造成影响。1.2复制是如何工作的?在详细介绍如何设置复制之前,让我们看一下MySQL实际上是如何进行数据复制的。一般来说,复制有三个步骤:将数据变化写入主库上的二进制日志(BinaryLog)(这些记录被称为二进制日志事件)。备库将主库上的日志复制到自己的中继日志(RelayLog)中。备用数据库读取中继日志中的事件并将其更改同步到备用数据库。以上是对复制的简单介绍,下图描述了复制的细节:整体复制流程:在主库上记录二进制日志。在每个准备提交的事务完成数据更新之前,主库将数据更新事件记录在二进制日志中。Mysql按照事务提交的顺序记录二进制日志,而不是按照每条语句的执行顺序。主库记录二进制日志后,会告诉存储引擎事务可以提交了。备用数据库将主数据库的二进制日志复制到其本地中继日志。首先,备用数据库将启动一个工作线程,称为I/O线程。I/O线程会与主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转储(binlogdump)线程。二进制转储线程从主二进制日志中读取事件。它不轮询时间。如果该线程“追上”主库,则进入休眠状态,直到主库发送信号量通知它有新的事件更新,备库I/O线程将接收到的事件记录到in中继日志。备库启动SQL线程,执行最后一步。该线程从中继日志中读取事件并在备库上执行以更新备库数据。当SQL线程追上I/O线程时,中继日志通常已经在系统缓存中,因此中继日志的开销很低。SQL线程执行的事件也可以通过配置项写入到自己的二进制日志中,这对于备库的配置非常有用。这种复制架构将获取事件与重放事件分离,允许这两个进程异步进行。也就是说,I/O线程可以独立于SQL线程工作。但是,这种架构也限制了复制过程。最重要的一点是,在主库上并发运行的查询只能在备库上串行执行,因为只有一个SQL线程来重放relaylog。事件。不过值得欣慰的是,5.7版本已经支持从库并行复制。对于基于二进制日志的并行复制,在日志内容中加入last_committed和sequence_number,分别表示事务提交的时间和最后事务提交的编号。如果交易有相同的时间,则意味着这些交易在一个组中,可以并行回放。2.复制原理我们已经了解了复制的一些基本概念。接下来,我们将对复制有更深入的了解,看看它是如何工作的,有哪些优缺点。2.1基于语句的复制Mysql5.0及更早版本只支持基于语句的复制(也称为逻辑复制)。在基于语句的复制模式下,主数据库会记录引起数据变化的SQL语句。当备库读取并重放这些事件时,实际上只是把主库执行过的SQL再执行一遍。这种方法既有优点也有缺点。优点是实现简单。理论上,只要简单的记录并执行SQL语句,就可以保持主备同步。二进制日志记录对带宽没有太大影响。二进制日志中的事件更紧凑,占用的带宽更少。但实际上,基于语句的方法可能并不像看起来那么方便,其缺点是主数据库上的数据可能取决于执行的语句之外的其他因素。将基于语句的复制与在主数据库上使用CURRENT_USER()函数的语句、存储过程和触发器一起使用时,可能会出现问题。2.2基于行的复制Mysql5.1开始支持基于行的复制。这样实际的数据就记录在了二进制日志中。同样,它也有自己的优点和缺点。它的优点是可以更准确地复制数据,缺点是可能会造成更大的开销。比如一张salary表有10000个用户,我们把每个用户的salary+1000相加,那么需要复制10000行的内容进行行复制,产生的开销比较大,而语句复制只是一个语句就可以了。由于没有一种模式是适用于所有情况的,Mysql启用了复制模式的动态切换。默认情况下,使用基于语句的复制,但是如果您发现无法正确复制语句,请切换到基于行的复制。也可以根据需要设置会话级变量binlog_format来控制二进制日志格式。2.3复制文件的解释在复制过程中会用到一些文件。上面已经介绍了二进制日志文件和中继日志文件,除此之外,还会用到其他文件。mysql-bin.index:当服务器开启二进制日志时,会同时生成一个与二进制日志同名但后缀为.index的文件。该文件用于记录磁盘上的二进制日志文件。这里的索引不是表的索引,而是这个文件的每一行都包含二进制文件的文件名。Mysql依靠这个文件来识别二进制日志文件。mysql-relay-bin-index:中继日志的索引文件,类似于mysql-bin.index。master.info:保存备库连接主库所需的信息文件。格式为纯文本(一行一个值),不同Mysql版本记录的信息可能不同。这个文件不能删除,否则备库重启后无法连接到主库。该文件以文本形式记录了复制用户的密码,因此要注意该文件的权限控制。relay-log.info:记录当前备库复制的二进制日志和中继日志位置文件。使用这些文件是一种非常粗略的记录MySQL复制和日志状态的方法。更不幸的是,它们不是同步编写的。如果服务器掉电,文件数据没有刷入磁盘,重启服务器后,文件中记录的数据可能是错误的。幸运的是,这些问题在5.5版本中得到了改善。2.4向其他备库发送复制事件log_slave_update选项允许备库对其他服务器的主库进行编程。设置该选项后,Mysql会在自己的二进制日志中记录自己执行过的事件。这样它的备用数据库就可以从它的日志中检索和执行事件。下图说明了这个过程:在这个场景中,主数据库向二进制日志写入一个数据更新事件,第一个备数据库提取并执行这个事件。这个时候,一个事件的生命周期应该已经结束了。但是因为设置了log_slave_updates,备库会将这个事件写入自己的二进制日志。这样第二个备用数据库可以从第一个备用数据库提取事件到它的中继日志中并执行它们。这意味着作为源服务器的主数据库可以将其数据更改传递给未与其直接连接的备用数据库。默认情况下,该选项是打开的,这样连接到备用数据库时不需要重新启动服务器。当第一个备库将自治库获取的事件写入其他二进制日志时,这个事件在备库二进制日志中的位置几乎肯定与主库二进制日志中的位置不同,并且可能是在不同的日志文件或文件中的不同位置。这意味着您不能假设具有相同逻辑复制点的所有服务器都具有相同的日志坐标。总结复制功能是MySQL高扩展性的基础,常见的读写分离使用复制。复制使用三个线程。master的log线程将event写入binlog,slave的IO线程获取binlog并写入relaylog,SQL线程重放relaylog日志。有基于语句的复制和基于行的复制。参考:高性能MySQL-版本3;