MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

MariaDB binlog 在主从复制中的关键作用

2022-08-265.4k 阅读

MariaDB binlog 概述

binlog 基本概念

在 MariaDB 数据库中,二进制日志(binlog)是一个至关重要的组件。它记录了数据库执行的所有更改数据的语句,这些语句以二进制格式存储,包括数据定义语言(DDL)语句,如 CREATE TABLEALTER TABLE,以及数据操作语言(DML)语句,例如 INSERTUPDATEDELETE 等。与其他类型的日志(如重做日志 redo log)不同,binlog 主要用于数据备份、恢复以及主从复制。

binlog 的工作模式

MariaDB 支持三种 binlog 工作模式,分别是 STATEMENT(基于语句)、ROW(基于行)和 MIXED(混合模式)。

  1. STATEMENT 模式:在这种模式下,binlog 记录的是实际执行的 SQL 语句。例如,执行 INSERT INTO users (name, age) VALUES ('John', 30); 这样的语句,binlog 中记录的就是这条完整的 SQL 语句。这种模式的优点是日志文件相对较小,因为只记录语句,而非数据本身。然而,它存在一些潜在问题,比如对于一些不确定的函数(如 NOW()RAND() 等),在主从复制环境中可能导致主从数据不一致,因为主库和从库执行这些函数的结果可能不同。
  2. ROW 模式:基于行的模式下,binlog 记录的是数据行的实际更改。还是以上面的 INSERT 语句为例,binlog 会记录插入的具体数据行,即 ('John', 30)。这种模式可以确保主从复制的准确性,因为它不依赖于语句的执行环境。但缺点是日志文件通常会比 STATEMENT 模式大,因为需要记录每一行数据的变化。
  3. MIXED 模式:这是一种折中的模式,MariaDB 会根据 SQL 语句的特性自动选择使用 STATEMENT 模式或 ROW 模式。对于大部分语句,会使用 STATEMENT 模式记录以减少日志量;而对于可能导致主从不一致的语句(如包含不确定函数的语句),则会切换到 ROW 模式记录。

binlog 的配置与管理

要启用 binlog,需要在 MariaDB 的配置文件(通常是 my.cnfmy.ini)中进行相应配置。以下是一些关键的配置参数:

[mysqld]
log-bin=mysql-bin # 开启 binlog,并指定日志文件的前缀为 mysql-bin
server-id=1       # 每个 MariaDB 实例都需要一个唯一的 server-id,用于主从复制识别
binlog_format=ROW # 设置 binlog 模式为 ROW,也可以是 STATEMENT 或 MIXED

配置完成后,重启 MariaDB 服务使配置生效。

可以使用 SHOW BINARY LOGS; 语句查看当前数据库的 binlog 文件列表:

MariaDB [(none)]> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |      154  |
| mysql-bin.000002 |      196  |
+------------------+-----------+
2 rows in set (0.00 sec)

还可以使用 PURGE BINARY LOGS 语句来清理不再需要的 binlog 文件。例如,要删除所有早于 mysql-bin.000003 的日志文件,可以执行:

PURGE BINARY LOGS TO'mysql-bin.000003';

MariaDB 主从复制原理

主从复制架构概述

MariaDB 的主从复制是一种数据同步机制,它允许将一个 MariaDB 数据库(主库)的数据更改复制到一个或多个其他 MariaDB 数据库(从库)。这种架构在很多场景下非常有用,比如提高系统的读性能(可以将读操作分布到多个从库上),以及数据备份和容灾。

在主从复制架构中,主库负责处理所有的数据更改操作,并将这些更改记录到 binlog 中。从库则通过 I/O 线程连接到主库,获取主库的 binlog 内容,并将其写入到自己的中继日志(relay log)中。然后,从库的 SQL 线程读取中继日志,在从库上重放这些日志记录,从而实现与主库的数据同步。

主从复制的建立过程

  1. 主库配置:首先,在主库上需要进行一些配置。除了前面提到的开启 binlog 和设置 server-id 外,还需要创建一个用于从库连接的复制用户。例如:
CREATE USER'replication_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'%';
FLUSH PRIVILEGES;

这里创建了一个名为 replication_user 的用户,允许其从任何主机连接,并授予了 REPLICATION SLAVE 权限。

接着,需要获取主库当前的 binlog 文件名和位置。可以使用以下语句:

SHOW MASTER STATUS;

执行结果类似如下:

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      196 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

记录下 FilePosition 的值,后续从库配置时会用到。

  1. 从库配置:在从库上同样要设置 server-id,确保与主库不同。然后,使用 CHANGE MASTER TO 语句来配置主库的连接信息和复制起始位置:
CHANGE MASTER TO
    MASTER_HOST='master_host_ip',
    MASTER_USER='replication_user',
    MASTER_PASSWORD='password',
    MASTER_LOG_FILE='mysql-bin.000002',
    MASTER_LOG_POS=196;

这里 master_host_ip 是主库的 IP 地址,MASTER_LOG_FILEMASTER_LOG_POS 就是前面在主库获取的值。

配置完成后,启动从库的复制进程:

START SLAVE;

可以使用 SHOW SLAVE STATUS \G 语句来查看从库的复制状态,确保 Slave_IO_RunningSlave_SQL_Running 都为 Yes,并且 Seconds_Behind_Master 为 0 或一个较小的值,表示从库与主库同步正常。

主从复制中的数据一致性

虽然 MariaDB 的主从复制机制在大多数情况下能够保证数据的一致性,但仍然存在一些因素可能导致主从数据不一致。除了前面提到的 binlog 模式相关问题外,网络延迟、主从库硬件性能差异等也可能影响数据同步。

为了尽量减少数据不一致的风险,可以采取一些措施。例如,在主库上使用 sync_binlog=1 配置参数,确保每次事务提交时都将 binlog 同步到磁盘,这样可以保证 binlog 记录的完整性。在从库方面,可以通过合理设置 slave_parallel_workers 参数来提高从库重放中继日志的并行度,加快同步速度。

binlog 在主从复制中的关键作用

数据变更记录与传输

在 MariaDB 主从复制过程中,binlog 充当了数据变更记录的核心角色。主库上发生的每一个数据更改操作,无论是简单的 INSERT 语句还是复杂的 UPDATE 事务,都会被记录到 binlog 中。从库的 I/O 线程通过与主库建立连接,不断读取主库的 binlog 内容,并将其传输到从库。

例如,在主库上执行以下 UPDATE 语句:

UPDATE products SET price = price * 1.1 WHERE category = 'electronics';

这条语句会被记录到主库的 binlog 中。从库的 I/O 线程会感知到主库 binlog 的变化,将相关的日志记录读取并传输到从库,写入到中继日志中。

保证主从数据一致性

binlog 对于保证主从数据一致性起着决定性作用。由于 binlog 记录了主库上所有的数据更改,从库通过重放中继日志中的 binlog 记录,能够准确地在从库上重现主库的操作,从而实现数据的同步。

在基于 ROW 模式的 binlog 中,记录的数据行变化信息非常详细,从库可以精确地按照主库的更改进行数据更新。即使主库上执行的是复杂的事务操作,只要 binlog 记录完整,从库就能正确地重放事务,确保主从数据的一致性。

例如,假设主库上有一个涉及多个表的事务:

START TRANSACTION;
INSERT INTO orders (customer_id, order_date) VALUES (1, '2023 - 10 - 01');
SET @order_id = LAST_INSERT_ID();
INSERT INTO order_items (order_id, product_id, quantity) VALUES (@order_id, 101, 2);
COMMIT;

ROW 模式下,binlog 会分别记录每个表插入操作的数据行变化。从库在重放中继日志时,能够按照相同的顺序和数据内容执行这些操作,保证主从数据的一致性。

故障恢复与数据完整性

在主从复制环境中,binlog 对于故障恢复和数据完整性的维护也至关重要。如果主库发生故障,从库可以在一定程度上继续提供服务,并且当主库恢复后,可以利用 binlog 进行数据同步,确保主库恢复到故障前的状态。

同时,如果从库出现问题,例如数据损坏或同步中断,也可以通过重新配置从库,从主库获取最新的 binlog 记录来恢复数据同步,保证数据的完整性。

例如,假设从库由于硬件故障导致部分数据丢失。在修复硬件问题后,可以重新配置从库,从主库获取 binlog 记录,重新开始同步过程。通过重放主库的 binlog,从库可以逐步恢复丢失的数据,重新与主库保持一致。

binlog 格式对主从复制的影响

  1. 基于语句(STATEMENT)格式:在 STATEMENT 格式下,binlog 记录的是 SQL 语句。虽然这种格式日志量小,但由于存在一些可能导致主从不一致的情况,在主从复制中需要特别注意。例如,对于使用了系统函数(如 CURRENT_USER()UUID())的语句,主从库执行结果可能不同。如果主库在 STATEMENT 模式下记录了包含 UUID() 函数的 INSERT 语句,从库重放时生成的 UUID 可能与主库不同,从而导致数据不一致。

  2. 基于行(ROW)格式ROW 格式记录的数据行变化能够更准确地保证主从复制的一致性。它不依赖于 SQL 语句的执行环境,而是直接记录数据的变化。但由于需要记录每一行数据的更改,日志文件相对较大,在网络传输和存储方面会有一定的开销。

  3. 混合(MIXED)格式MIXED 格式结合了 STATEMENTROW 格式的优点,根据语句的特性自动选择合适的记录方式。对于大多数普通语句,使用 STATEMENT 格式记录以减少日志量;对于可能导致主从不一致的语句,则采用 ROW 格式记录。这种格式在保证主从一致性的同时,尽量控制了日志文件的大小。

binlog 相关性能优化

调整 binlog 写入频率

binlog 的写入频率对数据库性能有一定影响。在 MariaDB 中,可以通过 sync_binlog 参数来控制 binlog 的写入策略。

  1. sync_binlog=0:表示 MariaDB 将 binlog 的写入操作交给操作系统的缓存机制,由操作系统决定何时将 binlog 刷写到磁盘。这种方式性能最高,但在系统崩溃时可能会丢失部分 binlog 记录,从而影响主从复制的准确性。
  2. sync_binlog=1:意味着每次事务提交时,MariaDB 都会将 binlog 同步到磁盘。这样可以保证 binlog 的完整性,但由于频繁的磁盘 I/O 操作,会对性能产生一定的影响。
  3. sync_binlog=N(N > 1):表示每 N 次事务提交后,才将 binlog 同步到磁盘。这种方式在性能和数据安全性之间提供了一种折中的选择。例如,设置 sync_binlog=10,则每 10 次事务提交后进行一次 binlog 的磁盘同步操作,相对 sync_binlog=1 可以减少磁盘 I/O 次数,提高性能,但在系统崩溃时可能会丢失最多 N - 1 次事务的 binlog 记录。

优化 binlog 模式选择

根据应用场景合理选择 binlog 模式也能提升性能。如果应用中大部分 SQL 语句是确定性的,不涉及不确定函数或复杂的计算,那么 STATEMENT 模式可能是一个不错的选择,因为它可以减少日志量,降低磁盘 I/O 和网络传输的压力。

然而,如果应用中包含大量的不确定性操作,如使用 RAND() 函数生成随机数,或者对数据的一致性要求非常高,那么 ROW 模式或 MIXED 模式更为合适。虽然 ROW 模式日志量较大,但能确保主从复制的准确性。MIXED 模式则在两者之间进行了平衡,根据语句特性自动选择记录方式。

例如,对于一个主要进行简单数据插入和查询的业务系统,且对主从一致性要求不是极高,可以选择 STATEMENT 模式,以减少 binlog 的生成量,提高系统性能。而对于一个涉及金融交易等对数据一致性要求极高的系统,则应优先考虑 ROW 模式或 MIXED 模式。

监控与分析 binlog 性能

为了优化 binlog 在主从复制中的性能,需要对其进行监控和分析。可以使用 MariaDB 提供的一些工具和视图来获取相关信息。

  1. SHOW STATUS:通过 SHOW STATUS 语句可以查看与 binlog 相关的状态变量,例如 Binlog_cache_disk_useBinlog_cache_useBinlog_cache_disk_use 表示使用临时文件来缓存 binlog 的次数,如果这个值较高,说明 binlog 缓存可能设置过小,需要调整相关参数。Binlog_cache_use 则表示使用 binlog 缓存的次数。
SHOW STATUS LIKE 'Binlog_cache%';
  1. Performance Schema:MariaDB 的 Performance Schema 提供了更详细的性能监控信息。可以通过查询 performance_schema.events_statements_summary_by_digest 表来分析不同 SQL 语句对 binlog 生成的影响,找出可能导致 binlog 量过大的语句,进行优化。
SELECT DIGEST_TEXT, SUM_TIMER_WAIT, SUM_ROWS_AFFECTED
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC;

通过这些监控和分析手段,可以及时发现 binlog 相关的性能问题,并采取相应的优化措施,确保主从复制环境的高效运行。

实际案例分析

案例背景

假设有一个电商平台,随着业务的增长,读请求量大幅增加。为了提高系统的读性能,决定采用 MariaDB 主从复制架构,将读操作分布到多个从库上。主库负责处理所有的写操作,并将数据变更记录到 binlog 中,从库通过复制主库的 binlog 来保持数据同步。

配置过程

  1. 主库配置:在主库的 my.cnf 文件中进行如下配置:
[mysqld]
log-bin=mysql-bin
server-id=1
binlog_format=ROW
sync_binlog=1

重启 MariaDB 服务后,创建复制用户:

CREATE USER'replication_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'%';
FLUSH PRIVILEGES;

然后获取主库当前的 binlog 文件名和位置:

SHOW MASTER STATUS;
  1. 从库配置:在从库的 my.cnf 文件中设置:
[mysqld]
server-id=2

重启 MariaDB 服务后,使用 CHANGE MASTER TO 语句配置主库连接信息和复制起始位置:

CHANGE MASTER TO
    MASTER_HOST='master_host_ip',
    MASTER_USER='replication_user',
    MASTER_PASSWORD='password',
    MASTER_LOG_FILE='mysql-bin.000002',
    MASTER_LOG_POS=196;

启动从库的复制进程:

START SLAVE;

通过 SHOW SLAVE STATUS \G 确认从库复制状态正常。

遇到的问题及解决

在运行过程中,发现从库偶尔会出现数据同步延迟的情况。通过查看 SHOW SLAVE STATUS \G 中的 Seconds_Behind_Master 值,发现该值有时会逐渐增大。

经过分析,发现是由于主库上有一些复杂的事务操作,导致 binlog 生成量较大,而从库的 slave_parallel_workers 参数设置过小,无法及时重放中继日志。

解决方法是适当增大从库的 slave_parallel_workers 参数值,根据从库的硬件性能,将其从默认的 0 调整为 4。同时,对主库上的复杂事务进行优化,尽量拆分成多个较小的事务,减少单个事务对 binlog 的影响。调整后,从库的数据同步延迟问题得到了明显改善,Seconds_Behind_Master 值保持在较小范围内。

总结与启示

通过这个实际案例可以看出,binlog 在 MariaDB 主从复制中起着关键作用。合理的 binlog 配置、模式选择以及对主从复制过程的监控和优化,对于保证数据一致性和系统性能至关重要。在实际应用中,需要根据业务特点和系统需求,灵活调整相关参数,以确保主从复制架构的稳定和高效运行。同时,遇到问题时要善于利用 MariaDB 提供的工具和视图进行分析,找出问题根源并及时解决。