MariaDB binlog与数据库高可用架构
MariaDB binlog 基础
binlog 是什么
MariaDB 的二进制日志(binlog)记录了数据库执行的所有更改操作,这些操作以二进制格式存储。它主要用于数据备份、恢复以及主从复制。与 InnoDB 的重做日志(redo log)不同,binlog 是逻辑日志,记录的是数据库层面的修改操作,比如执行的 SQL 语句,而 redo log 是物理日志,记录的是 InnoDB 存储引擎层面的数据页修改。
binlog 的作用
- 数据备份与恢复:通过定期备份数据库以及相应的 binlog,可以在数据库出现故障时,先恢复到最近一次备份的状态,然后通过重放 binlog 中的记录,将数据库恢复到故障发生前的状态。例如,假设每周日进行一次全量备份,每天进行 binlog 备份。如果在周三数据库出现故障,就可以先恢复周日的全量备份,再应用周一到周三的 binlog 备份,使数据库恢复到故障前的状态。
- 主从复制:在主从复制架构中,主库将 binlog 发送给从库,从库通过重放 binlog 来保持与主库的数据一致性。主库每执行一个事务,就会将该事务对应的 binlog 写入日志文件,并通知从库有新的 binlog 可用。从库通过 I/O 线程将主库的 binlog 下载到本地,再由 SQL 线程重放这些 binlog 记录,从而实现数据的同步。
binlog 的格式
MariaDB 支持三种 binlog 格式:Statement(基于语句)、Row(基于行)和 Mixed(混合模式)。
- Statement 格式:这种格式下,binlog 记录的是执行的 SQL 语句。例如,如果执行
UPDATE users SET age = age + 1 WHERE city = 'New York';
,binlog 中就会记录这条 SQL 语句。这种格式的优点是日志文件较小,因为只记录语句本身。缺点是在某些情况下可能导致主从数据不一致,比如使用了函数NOW()
,在主库和从库执行时返回的时间可能不同,因为函数的执行时间点不同。 - Row 格式:Row 格式下,binlog 记录的是数据行的实际修改内容。以上面的
UPDATE
语句为例,binlog 会记录哪些行的age
字段发生了变化,以及变化前后的值。这种格式可以保证主从数据的一致性,但缺点是日志文件较大,因为要记录每一行数据的变化。 - Mixed 格式:Mixed 格式结合了 Statement 和 Row 格式的优点。默认情况下,使用 Statement 格式记录 binlog,如果遇到可能导致主从数据不一致的语句(如包含不确定函数的语句),则自动切换为 Row 格式记录。这样可以在保证数据一致性的同时,尽量减少日志文件的大小。
配置 binlog
在 MariaDB 中,配置 binlog 主要通过修改配置文件(通常是 /etc/my.cnf
或 /etc/mysql/my.cnf
)来实现。以下是一些常用的配置参数:
[mysqld]
log-bin=/var/lib/mysql/mysql-bin.log # binlog 文件的路径和前缀
server-id=1 # 服务器唯一标识,主从复制中各服务器的 server-id 必须不同
binlog_format=mixed # binlog 格式,可选 statement、row 或 mixed
expire_logs_days=7 # binlog 文件的过期天数,过期后自动删除
修改完配置文件后,需要重启 MariaDB 服务使配置生效:
sudo systemctl restart mariadb
可以通过以下命令查看当前 binlog 的配置情况:
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';
SHOW VARIABLES LIKE'server_id';
binlog 的写入机制
MariaDB 使用双写缓冲机制来写入 binlog。当一个事务提交时,先将 binlog 写入内存中的 binlog cache,然后根据配置的 sync_binlog
参数决定是否将 binlog cache 中的数据刷新到磁盘。sync_binlog
的取值有 0、1 和 N(N > 1):
sync_binlog=0
:表示 MariaDB 不主动将 binlog cache 中的数据刷盘,而是由操作系统决定何时刷盘。这种方式性能最高,但在系统崩溃时可能会丢失部分 binlog 数据。sync_binlog=1
:表示每次事务提交时,都将 binlog cache 中的数据同步到磁盘。这种方式可以保证数据的完整性,但性能相对较低,因为每次提交都要进行磁盘 I/O 操作。sync_binlog=N
:表示每 N 次事务提交后,将 binlog cache 中的数据同步到磁盘。这种方式在性能和数据完整性之间取得了一定的平衡。
MariaDB 高可用架构中的 binlog
主从复制架构
- 主从复制原理:在主从复制架构中,主库将 binlog 发送给从库,从库通过重放 binlog 来同步数据。主库在执行事务并写入 binlog 后,会生成一个 binlog event,从库的 I/O 线程连接到主库,获取这些 binlog event 并写入本地的中继日志(relay log)。然后,从库的 SQL 线程读取中继日志,重放其中的 binlog event,从而使从库的数据与主库保持一致。
- 配置主从复制:
- 主库配置:
- 确保开启 binlog,配置
log-bin
和server-id
参数,如前文所述。 - 授予从库复制权限:
- 确保开启 binlog,配置
- 主库配置:
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'slave_ip' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
- 记录 `SHOW MASTER STATUS` 命令输出的 `File` 和 `Position` 值,这是从库连接主库时需要使用的信息。
- **从库配置**:
- 配置 `server-id`,确保与主库不同。
- 连接主库:
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='replication_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='master_binlog_file',
MASTER_LOG_POS=master_binlog_position;
START SLAVE;
SHOW SLAVE STATUS \G;
- 检查 `SHOW SLAVE STATUS` 的输出,确保 `Slave_IO_Running` 和 `Slave_SQL_Running` 都为 `Yes`,并且 `Seconds_Behind_Master` 为 0 或较小的值,表示主从复制正常运行。
双活/多活架构
- 双活架构原理:双活架构通常是指两个数据库节点都处于活动状态,同时对外提供服务。这种架构下,两个节点之间需要进行数据同步,binlog 在其中起着关键作用。每个节点既是主库,也是从库。当一个节点接收到写操作时,将其写入 binlog 并发送给另一个节点,另一个节点通过重放 binlog 来同步数据。
- 多活架构原理:多活架构是双活架构的扩展,有多个数据库节点同时对外提供服务。节点之间通过 binlog 进行数据同步,形成一个复杂的同步网络。在多活架构中,需要解决数据冲突的问题,例如两个节点同时对同一数据进行修改。常见的解决方法包括使用分布式锁、时间戳比较等。
- 基于 binlog 的双活/多活架构实现:以双活架构为例,假设两个节点分别为 Node A 和 Node B。
- Node A 配置:
- 配置
log-bin
和server-id
。 - 授予 Node B 复制权限。
- 配置
auto_increment_offset=1
和auto_increment_increment=2
,确保两个节点的自增 ID 不会冲突。
- 配置
- Node B 配置:
- 配置
log-bin
和server-id
,确保与 Node A 不同。 - 授予 Node A 复制权限。
- 配置
auto_increment_offset=2
和auto_increment_increment=2
。
- 配置
- 双向复制配置:在 Node A 上配置指向 Node B 的从库,在 Node B 上配置指向 Node A 的从库,按照主从复制的配置步骤进行,形成双向复制。
- Node A 配置:
故障切换与 binlog
- 手动故障切换:在主从复制架构中,如果主库出现故障,需要手动将从库提升为主库。在提升从库之前,需要确保从库已经同步了主库的所有 binlog。可以通过
SHOW SLAVE STATUS
命令查看从库的同步状态。当确认从库已经同步完成后,在从库上执行以下命令:
STOP SLAVE;
RESET MASTER;
然后,将应用程序的数据库连接切换到新的主库。同时,需要重新配置其他从库,使其连接到新的主库。 2. 自动故障切换:为了实现自动故障切换,可以使用一些工具,如 MHA(Master High Availability)。MHA 可以监控主库的状态,当主库出现故障时,自动将从库提升为主库,并通知应用程序更新数据库连接。MHA 的工作原理是通过监控主库和从库的心跳,当检测到主库故障时,选择一个同步最完整的从库,通过重放 binlog 确保其数据与主库一致,然后将其提升为主库。以下是使用 MHA 实现自动故障切换的基本步骤: - 安装 MHA 软件:在所有节点上安装 MHA 的管理节点和节点监控软件包。 - 配置 MHA:在管理节点上配置 MHA 的配置文件,指定主库和从库的地址、用户名、密码等信息。 - 启动 MHA:在管理节点上启动 MHA 服务,MHA 开始监控主从库的状态。 - 故障模拟与验证:手动停止主库服务,观察 MHA 是否能够自动将从库提升为主库,并验证应用程序是否能够正常连接到新的主库。
binlog 相关的性能优化
binlog 对性能的影响
- I/O 性能影响:binlog 的写入操作会涉及磁盘 I/O,特别是在
sync_binlog=1
的情况下,每次事务提交都要进行磁盘同步操作,这会严重影响数据库的写入性能。如果磁盘 I/O 性能瓶颈,可能导致事务提交时间延长,从而影响整个系统的吞吐量。 - CPU 性能影响:生成 binlog event 和重放 binlog 都需要消耗 CPU 资源。在高并发写入场景下,binlog 的生成和处理可能成为 CPU 的负担,导致系统性能下降。
优化 binlog 性能的方法
- 调整 sync_binlog 参数:根据应用对数据一致性和性能的要求,合理调整
sync_binlog
参数。如果应用对数据一致性要求不是非常严格,可以将sync_binlog
设置为大于 1 的值,例如sync_binlog=10
,表示每 10 次事务提交后进行一次磁盘同步,这样可以减少磁盘 I/O 次数,提高写入性能。但如果应用对数据一致性要求极高,如金融行业的应用,建议保持sync_binlog=1
。 - 优化 binlog 格式:根据业务场景选择合适的 binlog 格式。如果业务以简单的增删改查为主,且对主从一致性要求不是特别高,可以选择 Statement 格式,以减少 binlog 文件大小。如果业务涉及复杂的函数操作或可能导致主从数据不一致的操作,应选择 Row 格式或 Mixed 格式。
- 优化磁盘 I/O:可以通过使用高速磁盘(如 SSD)、配置磁盘阵列(如 RAID 0、RAID 10)等方式提高磁盘 I/O 性能。另外,合理调整数据库服务器的内存参数,增加 binlog cache 的大小,也可以减少磁盘 I/O 次数。例如,通过
binlog_cache_size
参数调整 binlog cache 的大小,默认值为 32K,可以根据业务情况适当增大。 - 并行复制优化:从 MariaDB 10.0 版本开始支持并行复制。在主从复制架构中,可以通过配置
slave_parallel_workers
参数开启并行复制,让从库的多个线程并行重放 binlog,提高从库的同步速度。例如,将slave_parallel_workers
设置为 4,表示从库使用 4 个线程并行重放 binlog。同时,需要注意的是,并行复制需要 binlog 格式为 Row 或 Mixed,并且主库上的事务之间尽量相互独立,以避免并行复制时的冲突。
binlog 性能监控
- 使用 SHOW STATUS 命令:可以通过
SHOW STATUS
命令查看与 binlog 相关的状态变量,例如:
SHOW STATUS LIKE 'Binlog_bytes_written'; // 查看 binlog 写入的字节数
SHOW STATUS LIKE 'Binlog_stmt_cache_disk_use'; // 查看使用磁盘的 binlog 语句缓存数量
SHOW STATUS LIKE 'Binlog_stmt_cache_use'; // 查看使用的 binlog 语句缓存数量
通过监控这些状态变量,可以了解 binlog 的写入情况、缓存使用情况等,从而发现性能问题。
2. 使用性能分析工具:MariaDB 自带的 pt - query - digest
工具可以分析 binlog 中的 SQL 语句执行时间、频率等信息,帮助找出性能瓶颈。例如,可以使用以下命令分析 binlog 文件:
pt - query - digest /var/lib/mysql/mysql - bin.000001
该命令会输出 binlog 中 SQL 语句的详细分析报告,包括执行次数、平均执行时间、总执行时间等信息,根据这些信息可以对性能不佳的 SQL 语句进行优化。
binlog 的管理与维护
binlog 文件管理
- 查看 binlog 文件列表:可以使用
SHOW BINARY LOGS
命令查看当前数据库的 binlog 文件列表:
SHOW BINARY LOGS;
该命令会列出所有的 binlog 文件及其大小、创建时间等信息。
2. 删除 binlog 文件:可以使用 PURGE BINARY LOGS
命令删除 binlog 文件。例如,要删除所有早于指定 binlog 文件的日志,可以使用以下命令:
PURGE BINARY LOGS TO'mysql - bin.000005';
要删除所有过期的 binlog 文件(根据 expire_logs_days
配置),可以使用以下命令:
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;
- 手动切换 binlog 文件:可以使用
FLUSH LOGS
命令手动切换 binlog 文件。执行该命令后,MariaDB 会关闭当前的 binlog 文件,并创建一个新的 binlog 文件。
FLUSH LOGS;
binlog 备份与恢复
- binlog 备份:为了实现数据的恢复,需要定期备份 binlog 文件。可以使用
mysqlbinlog
工具将 binlog 文件备份到其他存储介质。例如,以下命令将当前的 binlog 文件备份到/backup/binlog/mysql - bin.000001.bak
:
mysqlbinlog /var/lib/mysql/mysql - bin.000001 > /backup/binlog/mysql - bin.000001.bak
也可以使用脚本定期备份 binlog 文件,并根据 expire_logs_days
配置删除过期的备份文件。
2. 基于 binlog 的恢复:在数据库出现故障时,先恢复到最近一次的全量备份,然后应用 binlog 备份来恢复到故障前的状态。假设已经恢复了全量备份,并且有 binlog 备份文件 /backup/binlog/mysql - bin.000001.bak
到 /backup/binlog/mysql - bin.000003.bak
,可以使用以下命令应用 binlog 备份:
mysqlbinlog /backup/binlog/mysql - bin.000001.bak /backup/binlog/mysql - bin.000002.bak /backup/binlog/mysql - bin.000003.bak | mysql - u root - p
在应用 binlog 备份时,需要确保数据库处于恢复状态,并且数据库版本与备份时的版本兼容。
binlog 安全管理
- 权限管理:严格控制对 binlog 的访问权限。只有具有
REPLICATION SLAVE
权限的用户才能读取 binlog 用于主从复制。对于其他用户,应限制其对 binlog 文件的访问,避免敏感数据泄露。可以通过GRANT
和REVOKE
命令来管理用户权限。 - 加密传输:在主从复制过程中,如果网络环境不安全,可以考虑对 binlog 的传输进行加密。MariaDB 支持通过 SSL/TLS 加密连接进行主从复制。在主库和从库的配置文件中添加 SSL 相关配置,如
ssl - ca
、ssl - cert
和ssl - key
等参数,然后在从库连接主库时指定使用 SSL 连接:
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='replication_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='master_binlog_file',
MASTER_LOG_POS=master_binlog_position,
MASTER_SSL=1,
MASTER_SSL_CA='/path/to/ca.pem',
MASTER_SSL_CERT='/path/to/client - cert.pem',
MASTER_SSL_KEY='/path/to/client - key.pem';
START SLAVE;
这样可以确保 binlog 在传输过程中的数据安全。
综上所述,MariaDB 的 binlog 在数据库高可用架构中起着至关重要的作用。通过深入理解 binlog 的原理、配置、在高可用架构中的应用以及性能优化、管理维护等方面的知识,可以构建出稳定、高效、安全的数据库系统。无论是主从复制、双活/多活架构,还是故障切换、数据备份恢复等场景,binlog 都是实现数据一致性和高可用性的关键因素。同时,合理的性能优化和安全管理措施可以进一步提升数据库系统的整体性能和安全性。