MySQL 主从复制(Master-Slave Replication)是一种常见的数据库架构,广泛用于提高数据库的可扩展性、读写分离以及数据备份和容灾恢复。主从复制架构中,一个 MySQL 实例作为主库(Master),负责处理所有的写操作,而一个或多个从库(Slave)从主库复制数据,并负责处理读操作。
- 主库(Master):主库负责处理数据库的所有写操作(如 INSERT、UPDATE 和 DELETE),并将这些修改记录到二进制日志(binlog)中。主库的主要任务是记录所有数据变更并与从库同步。
- 从库(Slave):从库会从主库读取 binlog 文件,并重放日志中的操作,从而使从库中的数据与主库保持同步。一个主库可以有多个从库,从库主要用于处理读操作,减轻主库的压力。
MySQL 主从复制的基本流程如下:
- 主库生成 binlog:当主库发生写操作时,MySQL 会将这些操作记录到二进制日志(binlog)中。binlog 包含了所有对数据库的修改操作,如 INSERT、UPDATE 和 DELETE。
- 从库读取 binlog:从库通过 I/O 线程向主库请求 binlog 文件,并将这些日志保存到从库本地的中继日志(relay log)中。
- 从库执行中继日志:从库的 SQL 线程从中继日志中读取操作,并在从库中重放这些操作,从而使从库的数据与主库同步。
- I/O 线程:从库启动一个 I/O 线程,用来从主库读取 binlog 日志,并将其保存到中继日志中。
- SQL 线程:从库启动一个 SQL 线程,用来读取中继日志并在从库中重放这些日志操作,以保持与主库同步。
MySQL 主从复制有几种不同的模式:
- 异步复制(Asynchronous Replication):在异步复制中,主库在执行完写操作后立即返回给客户端,不等待从库完成同步。主库只负责将变更记录到 binlog 中,异步复制的好处是写操作的性能较好,但可能存在主库发生故障时从库数据落后的风险。
- 半同步复制(Semi-Synchronous Replication):在半同步复制中,主库执行写操作后,在返回客户端之前,至少要等一个从库确认接收到 binlog 日志。这样可以减少主从数据不一致的风险,但性能较异步复制稍低。
- 全同步复制(Synchronous Replication):在全同步复制中,主库执行写操作后,必须等所有的从库都确认接收到 binlog,才会向客户端返回结果。这种复制方式提供了最高的数据一致性,但性能较差,适用于对数据一致性要求极高的场景。
应用场景
- 读写分离:主库负责写操作,从库负责读操作。通过将读操作分散到多个从库,可以减轻主库的压力,提升整体数据库的性能。尤其适用于读多写少的场景,例如新闻网站、博客平台等。
- 高可用性:当主库出现故障时,可以快速将某个从库提升为主库,继续提供服务。这可以减少系统的宕机时间,提升数据库的高可用性。
- 数据备份:从库可以用于备份数据库数据,而不会影响主库的性能。通过在从库上执行备份操作,可以确保主库不受影响的情况下进行数据备份。
- 异地容灾:主从复制可以用于在不同的地理位置部署数据库。主库位于一个数据中心,从库可以部署在其他数据中心,形成异地容灾机制,当发生灾难时,异地从库可以立即接管数据服务。
- 数据分析:从库可以用于复杂的分析查询操作,避免对主库写入造成影响。
优点
- 读写分离:通过分离读写操作,提升数据库的整体性能。
- 高可用性:从库可以用于灾难恢复,提升系统的容错能力。
- 数据备份:从库可以用于无影响的备份操作。
- 部署简单:主从复制的配置相对简单,维护成本较低。
- 读性能提升:通过添加从库,扩展系统的读能力。
缺点
- 数据延迟:由于从库从主库复制数据的过程存在一定延迟,从库数据可能不是实时更新的。
- 单点故障风险:如果主库宕机,所有写操作都会中断,必须手动将某个从库提升为主库。
- 写性能瓶颈:写操作仍然集中在主库上,写性能无法扩展。
- 手动故障切换:虽然从库可以用来提升高可用性,但需要手动将从库提升为主库。
在 MySQL 的主从复制架构中,数据的存储主要是在磁盘中,而不是完全在内存中。虽然 MySQL 会使用内存进行缓存和提高查询性能,但核心数据和事务日志等关键信息都会存储在磁盘上,以确保数据的持久性和高可用性。
尽管数据主要存储在磁盘中,但 MySQL 会使用内存缓存来加速数据的访问。内存的使用情况包括以下几种:
- MySQL 的 InnoDB 存储引擎有一个非常重要的内存区域,叫做缓冲池(Buffer Pool)。它用于缓存磁盘上的数据页和索引,以加速读写操作。当数据库从磁盘上读取数据时,它会将这些数据页缓存到内存中,以便下次访问时更快。
- 在主节点中,当有读写操作时,数据会首先从内存中的缓冲池读取或写入,但最终的数据仍会同步到磁盘上。缓冲池主要用于减少磁盘 I/O 操作的频率。
- 同样的,从节点在应用主节点的更新日志时,也会将数据首先加载到内存的缓冲池中,提高查询速度。
MySQL 的查询缓存可以将常见的查询结果保存在内存中,以便在后续请求中直接返回缓存的结果而不需要重新访问磁盘。不过,查询缓存在高并发写入的情况下效率较低,因此在现代版本中已经被逐渐淘汰和弃用。
主从复制架构中的每个节点都依赖磁盘来存储以下关键数据:
- 表和索引数据:主从节点都会将数据表和索引文件存储在磁盘上。
- 二进制日志和中继日志:主节点的二进制日志、从节点的中继日志都保存在磁盘上,这些日志用于数据的复制和同步。
- 事务日志:用于保障数据的持久性和事务恢复的 Redo 和 Undo 日志也会存储在磁盘上。
在 MySQL 主从复制架构中,内存和磁盘是协同工作的:
- 内存用于缓存和加速访问:MySQL 会利用内存(如 InnoDB 缓冲池)来缓存常用的数据和索引页,以减少磁盘 I/O,提高查询性能。
- 磁盘用于持久存储和容灾:所有的数据和日志都会最终存储在磁盘上,以确保在发生故障时可以进行恢复,确保数据的一致性和持久性。