外观
KingBaseES 重做日志与回滚日志
日志概述
KingBaseES 使用多种日志来确保数据的一致性和可靠性,其中最重要的是重做日志(Redo Log)和回滚日志(Undo Log)。这些日志在事务处理、崩溃恢复和数据复制中起着至关重要的作用。
重做日志(Redo Log)
重做日志的概念
重做日志是 KingBaseES 中用于记录数据库修改操作的日志,也称为 WAL(Write-Ahead Logging)日志。重做日志确保了事务的持久性和数据库的崩溃恢复能力。
WAL 机制
KingBaseES 采用 WAL(Write-Ahead Logging)机制,即先写日志后写数据。WAL 机制的核心原则是:
- 所有数据修改操作必须先写入重做日志,然后才能写入数据文件。
- 事务提交后,必须确保所有相关的重做日志都已写入磁盘。
- 数据文件的写入可以延迟,由后台进程(如写进程)定期刷新。
WAL 机制的优点
- 提高性能:减少了数据文件的 I/O 操作,因为可以批量写入数据文件。
- 确保持久性:即使系统崩溃,也可以通过重做日志恢复未写入数据文件的修改。
- 支持崩溃恢复:系统崩溃后,可以通过重做日志恢复到崩溃前的一致状态。
- 支持复制:可以将重做日志发送到备库,实现数据复制和高可用。
重做日志的结构
重做日志文件
KingBaseES 的重做日志以文件形式存储,默认位于数据目录的 pg_xlog/ 目录下(KingBaseES V8R6 及以上版本为 pg_wal/ 目录)。
重做日志文件的特点:
- 每个重做日志文件的默认大小为 16MB(可配置)。
- 重做日志文件采用循环使用的方式,当所有文件都被使用后,会覆盖最早的未使用的文件。
- 重做日志文件的命名格式为
000000010000000000000001,其中包含时间线、逻辑日志序列号等信息。
重做日志记录
每个重做日志记录包含以下信息:
- 事务ID:标识该修改属于哪个事务。
- 操作类型:如插入、更新、删除等。
- 数据位置:修改的数据页和偏移量。
- 旧值和新值:修改前后的数据值(对于某些操作,可能只记录新值)。
- LSN(Log Sequence Number):日志序列号,唯一标识每个日志记录的位置。
重做日志的配置
主要配置参数
| 参数 | 描述 | 默认值 | 建议值 |
|---|---|---|---|
wal_level | WAL 日志级别 | replica | replica/logical |
fsync | 是否强制将 WAL 写入磁盘 | on | on |
synchronous_commit | 同步提交级别 | on | on/off/local/remote_write/remote_apply |
wal_sync_method | WAL 同步方法 | fdatasync | fdatasync |
wal_buffers | WAL 缓冲区大小 | -1(自动调整) | -1 |
wal_writer_delay | WAL 写进程延迟(毫秒) | 200ms | 100-500ms |
checkpoint_timeout | 检查点超时时间 | 5min | 5-15min |
max_wal_size | 最大 WAL 大小 | 1GB | 1-8GB |
min_wal_size | 最小 WAL 大小 | 80MB | 80MB-512MB |
wal_keep_segments | 保留的 WAL 段数量 | 0 | 0-1000 |
max_wal_senders | 最大 WAL 发送进程数 | 10 | 5-32 |
修改配置示例
sql
-- 修改 WAL 级别
ALTER SYSTEM SET wal_level = 'logical';
-- 修改检查点超时时间
ALTER SYSTEM SET checkpoint_timeout = '10min';
-- 修改最大 WAL 大小
ALTER SYSTEM SET max_wal_size = '4GB';
-- 重新加载配置
SELECT sys_reload_conf();重做日志的管理
查看重做日志状态
sql
-- 查看 WAL 日志的使用情况
SELECT
pg_walfile_name(pg_current_wal_lsn()) AS current_wal_file,
pg_walfile_name_offset(pg_current_wal_lsn()) AS current_wal_position,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), pg_wal_lsn_make(0, 0))) AS total_wal_size;
-- 查看检查点信息
SELECT
checkpoint_lsn,
checkpoint_time,
oldest_xmin,
oldest_active_xid,
oldest_prepared_xid,
wal_segment_size
FROM
pg_control_checkpoint();
-- 查看 WAL 写进程的状态
SELECT
pid,
usename,
application_name,
client_addr,
state,
wait_event_type,
wait_event
FROM
sys_stat_activity
WHERE
backend_type = 'walwriter';归档重做日志
归档重做日志是指将已完成的重做日志文件复制到指定的归档目录,用于 Point-In-Time Recovery(PITR)和长期备份。
配置归档模式
sql
-- 设置归档模式
ALTER SYSTEM SET archive_mode = on;
-- 设置归档命令
ALTER SYSTEM SET archive_command = 'cp %p /archive/path/%f';
-- 重新加载配置并重启数据库
SELECT sys_reload_conf();
-- 需要重启数据库使 archive_mode 生效
sys_ctl -D $KINGBASE_DATA restart查看归档状态
sql
-- 查看归档状态
SELECT
archived_count,
failed_count,
last_archived_wal,
last_archived_time,
last_failed_wal,
last_failed_time
FROM
pg_stat_archiver;清理重做日志
重做日志文件会自动循环使用,当 max_wal_size 达到阈值时,会触发检查点并清理旧的重做日志文件。
回滚日志(Undo Log)
回滚日志的概念
回滚日志是 KingBaseES 中用于记录事务修改前的数据值的日志,用于支持事务回滚和 MVCC(多版本并发控制)。
回滚日志的作用
- 支持事务回滚:当事务执行 ROLLBACK 或发生错误时,可以通过回滚日志恢复到事务开始前的状态。
- 支持 MVCC:为并发事务提供数据的旧版本,实现多版本并发控制。
- 支持一致性读:确保事务看到的数据是一致的,不受其他事务的影响。
回滚日志的结构
回滚日志段
KingBaseES 的回滚日志存储在 pg_clog/ 目录下(KingBaseES V8R6 及以上版本为 pg_xact/ 目录),以段文件形式存储。
回滚日志记录
每个回滚日志记录包含以下信息:
- 事务ID:标识该回滚记录属于哪个事务。
- 数据位置:修改的数据页和偏移量。
- 旧值:修改前的数据值。
- 事务状态:如活动、已提交、已回滚等。
回滚日志的管理
查看回滚日志状态
sql
-- 查看事务状态
SELECT
txid_current() AS current_transaction_id,
txid_current_snapshot() AS current_snapshot;
-- 查看事务提交日志统计信息
SELECT
name,
setting,
unit,
short_desc
FROM
sys_settings
WHERE
name LIKE '%clog%' OR name LIKE '%xact%';清理回滚日志
回滚日志会通过 VACUUM 操作自动清理,当事务ID超过 oldest_xmin 时,对应的回滚日志会被标记为可清理。
sql
-- 手动执行 VACUUM,清理回滚日志
VACUUM VERBOSE;
-- 查看 oldest_xmin
SELECT
datname,
age(datfrozenxid) AS frozen_age,
age(datalastvacuum) AS last_vacuum_age,
age(datalastanalyze) AS last_analyze_age
FROM
sys_database;崩溃恢复
崩溃恢复的概念
崩溃恢复是指当数据库系统发生崩溃时,通过重做日志和回滚日志将数据库恢复到崩溃前的一致状态的过程。
崩溃恢复的过程
- 分析阶段:读取重做日志,确定最后一个完整的检查点位置。
- 重做阶段:从检查点位置开始,重新应用所有重做日志记录,将数据库恢复到崩溃前的状态。
- 回滚阶段:回滚所有未提交的事务,确保数据库的一致性。
崩溃恢复的配置
主要配置参数
| 参数 | 描述 | 默认值 | 建议值 |
|---|---|---|---|
checkpoint_timeout | 检查点超时时间 | 5min | 5-15min |
max_wal_size | 最大 WAL 大小 | 1GB | 1-8GB |
min_wal_size | 最小 WAL 大小 | 80MB | 80MB-512MB |
checkpoint_completion_target | 检查点完成目标比例 | 0.5 | 0.5-0.9 |
崩溃恢复的监控
sql
-- 查看崩溃恢复状态
SELECT
recovery_start_time,
recovery_end_time,
current_lsn,
last_lsn,
received_lsn,
replayed_lsn,
replay_lag,
last_replay_time
FROM
pg_stat_wal_receiver;日志性能优化
1. 重做日志性能优化
- 使用快速存储设备:将重做日志存储在高性能存储设备(如 SSD)上,减少 I/O 延迟。
- 合理配置 WAL 缓冲区:根据系统负载调整
wal_buffers参数,减少 WAL 写入次数。 - 调整检查点参数:根据系统负载调整
checkpoint_timeout和max_wal_size参数,平衡恢复时间和 I/O 负载。 - 选择合适的同步提交级别:根据业务需求选择合适的
synchronous_commit级别,平衡性能和可靠性。 - 使用异步 I/O:如果操作系统支持,启用异步 I/O,提高 I/O 性能。
2. 回滚日志性能优化
- 定期执行 VACUUM:定期执行 VACUUM 操作,清理旧的回滚日志,减少存储空间占用。
- 合理设置 autovacuum 参数:调整 autovacuum 相关参数,确保自动清理能够及时执行。
- 监控事务ID回绕:定期检查事务ID的使用情况,避免事务ID回绕问题。
日志版本差异
V8 与 V7 版本的差异
WAL 机制优化:
- V8 版本优化了 WAL 写入机制,提高了 WAL 写入性能。
- V8 版本新增了更多的 WAL 级别选项,如 logical 级别,支持逻辑复制。
回滚日志改进:
- V8 版本改进了回滚日志的管理,减少了回滚日志的存储空间占用。
- V8 版本优化了回滚操作的性能,提高了事务回滚的速度。
崩溃恢复优化:
- V8 版本优化了崩溃恢复的过程,减少了恢复时间。
- V8 版本新增了并行恢复功能,提高了恢复速度。
V8R3 与 V8R2 版本的差异
WAL 性能提升:
- V8R3 版本进一步优化了 WAL 写入性能,减少了 WAL 写入的 I/O 开销。
- V8R3 版本新增了 WAL 压缩功能,减少了 WAL 日志的存储空间占用。
回滚日志管理增强:
- V8R3 版本新增了回滚日志的监控视图,便于 DBA 监控回滚日志的使用情况。
- V8R3 版本优化了回滚日志的清理机制,提高了清理效率。
新日志特性:
- V8R3 版本新增了增量检查点功能,减少了检查点的 I/O 峰值。
- V8R3 版本新增了 WAL 归档的校验和功能,提高了归档数据的可靠性。
常见问题(FAQ)
如何查看当前的 WAL 位置?
sql
-- 查看当前的 WAL 位置
SELECT pg_current_wal_lsn();
-- 查看当前 WAL 文件
SELECT pg_walfile_name(pg_current_wal_lsn());
-- 查看当前 WAL 文件的偏移量
SELECT pg_walfile_name_offset(pg_current_wal_lsn());如何调整 WAL 日志的大小?
WAL 日志文件的大小在数据库初始化时确定,无法直接修改。如果需要调整 WAL 日志文件的大小,需要重新初始化数据库:
bash
# 停止数据库
sys_ctl -D $KINGBASE_DATA stop
# 备份数据目录
cp -r $KINGBASE_DATA $KINGBASE_DATA.backup
# 重新初始化数据库,指定 WAL 日志文件大小
initdb -D $KINGBASE_DATA --wal-segsize=64
# 恢复数据(需要使用备份和 PITR)如何处理 WAL 日志满的情况?
WAL 日志满的情况通常是由于归档失败或复制延迟导致的。处理方法:
- 检查归档状态:查看归档命令是否执行成功,归档目录是否有足够的空间。
- 检查复制状态:查看备库是否正常接收 WAL 日志,是否存在复制延迟。
- 调整 max_wal_size:如果系统负载较高,可以适当增大
max_wal_size参数。 - 清理旧的 WAL 日志:如果确定旧的 WAL 日志不再需要,可以手动清理。
如何优化崩溃恢复时间?
- 调整检查点参数:减小
checkpoint_timeout或增大checkpoint_completion_target,减少恢复时需要重放的 WAL 日志量。 - 使用快速存储设备:将 WAL 日志存储在高性能存储设备上,提高恢复时的 I/O 速度。
- 启用并行恢复:在 KingBaseES V8 及以上版本,启用并行恢复功能,提高恢复速度。
如何监控 WAL 写入性能?
sql
-- 查看 WAL 写入统计信息
SELECT
name,
sum(calls) AS total_calls,
sum(total_time) AS total_time_ms,
avg(total_time) AS avg_time_ms
FROM
sys_stat_statements
WHERE
query LIKE '%WAL%' OR query LIKE '%XLOG%'
GROUP BY
name
ORDER BY
total_time DESC;
-- 查看 WAL 写入延迟
SELECT
extract(epoch FROM (commit_timestamp - xact_start)) AS commit_delay_seconds
FROM
sys_stat_activity
WHERE
state = 'idle' AND xact_start IS NOT NULL AND commit_timestamp IS NOT NULL
ORDER BY
commit_delay_seconds DESC;总结
重做日志和回滚日志是 KingBaseES 确保数据一致性和可靠性的重要机制。理解这些日志的工作原理、配置和管理对于 DBA 进行性能调优、故障恢复和系统管理至关重要。
在实际生产环境中,DBA 需要:
- 理解 WAL 机制和 MVCC 的工作原理
- 合理配置重做日志和回滚日志的参数
- 定期监控日志的使用情况和性能
- 配置适当的归档策略,确保数据的可恢复性
- 优化日志的性能,提高系统的整体性能
- 了解崩溃恢复的过程,确保系统在崩溃后能够快速恢复
通过合理的日志管理和优化,可以提高 KingBaseES 数据库的性能、可靠性和可恢复性,确保业务的连续运行。
