Skip to content

KingBaseES 重做日志与回滚日志

日志概述

KingBaseES 使用多种日志来确保数据的一致性和可靠性,其中最重要的是重做日志(Redo Log)和回滚日志(Undo Log)。这些日志在事务处理、崩溃恢复和数据复制中起着至关重要的作用。

重做日志(Redo Log)

重做日志的概念

重做日志是 KingBaseES 中用于记录数据库修改操作的日志,也称为 WAL(Write-Ahead Logging)日志。重做日志确保了事务的持久性和数据库的崩溃恢复能力。

WAL 机制

KingBaseES 采用 WAL(Write-Ahead Logging)机制,即先写日志后写数据。WAL 机制的核心原则是:

  1. 所有数据修改操作必须先写入重做日志,然后才能写入数据文件。
  2. 事务提交后,必须确保所有相关的重做日志都已写入磁盘。
  3. 数据文件的写入可以延迟,由后台进程(如写进程)定期刷新。

WAL 机制的优点

  1. 提高性能:减少了数据文件的 I/O 操作,因为可以批量写入数据文件。
  2. 确保持久性:即使系统崩溃,也可以通过重做日志恢复未写入数据文件的修改。
  3. 支持崩溃恢复:系统崩溃后,可以通过重做日志恢复到崩溃前的一致状态。
  4. 支持复制:可以将重做日志发送到备库,实现数据复制和高可用。

重做日志的结构

重做日志文件

KingBaseES 的重做日志以文件形式存储,默认位于数据目录的 pg_xlog/ 目录下(KingBaseES V8R6 及以上版本为 pg_wal/ 目录)。

重做日志文件的特点:

  • 每个重做日志文件的默认大小为 16MB(可配置)。
  • 重做日志文件采用循环使用的方式,当所有文件都被使用后,会覆盖最早的未使用的文件。
  • 重做日志文件的命名格式为 000000010000000000000001,其中包含时间线、逻辑日志序列号等信息。

重做日志记录

每个重做日志记录包含以下信息:

  • 事务ID:标识该修改属于哪个事务。
  • 操作类型:如插入、更新、删除等。
  • 数据位置:修改的数据页和偏移量。
  • 旧值和新值:修改前后的数据值(对于某些操作,可能只记录新值)。
  • LSN(Log Sequence Number):日志序列号,唯一标识每个日志记录的位置。

重做日志的配置

主要配置参数

参数描述默认值建议值
wal_levelWAL 日志级别replicareplica/logical
fsync是否强制将 WAL 写入磁盘onon
synchronous_commit同步提交级别onon/off/local/remote_write/remote_apply
wal_sync_methodWAL 同步方法fdatasyncfdatasync
wal_buffersWAL 缓冲区大小-1(自动调整)-1
wal_writer_delayWAL 写进程延迟(毫秒)200ms100-500ms
checkpoint_timeout检查点超时时间5min5-15min
max_wal_size最大 WAL 大小1GB1-8GB
min_wal_size最小 WAL 大小80MB80MB-512MB
wal_keep_segments保留的 WAL 段数量00-1000
max_wal_senders最大 WAL 发送进程数105-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(多版本并发控制)。

回滚日志的作用

  1. 支持事务回滚:当事务执行 ROLLBACK 或发生错误时,可以通过回滚日志恢复到事务开始前的状态。
  2. 支持 MVCC:为并发事务提供数据的旧版本,实现多版本并发控制。
  3. 支持一致性读:确保事务看到的数据是一致的,不受其他事务的影响。

回滚日志的结构

回滚日志段

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;

崩溃恢复

崩溃恢复的概念

崩溃恢复是指当数据库系统发生崩溃时,通过重做日志和回滚日志将数据库恢复到崩溃前的一致状态的过程。

崩溃恢复的过程

  1. 分析阶段:读取重做日志,确定最后一个完整的检查点位置。
  2. 重做阶段:从检查点位置开始,重新应用所有重做日志记录,将数据库恢复到崩溃前的状态。
  3. 回滚阶段:回滚所有未提交的事务,确保数据库的一致性。

崩溃恢复的配置

主要配置参数

参数描述默认值建议值
checkpoint_timeout检查点超时时间5min5-15min
max_wal_size最大 WAL 大小1GB1-8GB
min_wal_size最小 WAL 大小80MB80MB-512MB
checkpoint_completion_target检查点完成目标比例0.50.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_timeoutmax_wal_size 参数,平衡恢复时间和 I/O 负载。
  • 选择合适的同步提交级别:根据业务需求选择合适的 synchronous_commit 级别,平衡性能和可靠性。
  • 使用异步 I/O:如果操作系统支持,启用异步 I/O,提高 I/O 性能。

2. 回滚日志性能优化

  • 定期执行 VACUUM:定期执行 VACUUM 操作,清理旧的回滚日志,减少存储空间占用。
  • 合理设置 autovacuum 参数:调整 autovacuum 相关参数,确保自动清理能够及时执行。
  • 监控事务ID回绕:定期检查事务ID的使用情况,避免事务ID回绕问题。

日志版本差异

V8 与 V7 版本的差异

  1. WAL 机制优化

    • V8 版本优化了 WAL 写入机制,提高了 WAL 写入性能。
    • V8 版本新增了更多的 WAL 级别选项,如 logical 级别,支持逻辑复制。
  2. 回滚日志改进

    • V8 版本改进了回滚日志的管理,减少了回滚日志的存储空间占用。
    • V8 版本优化了回滚操作的性能,提高了事务回滚的速度。
  3. 崩溃恢复优化

    • V8 版本优化了崩溃恢复的过程,减少了恢复时间。
    • V8 版本新增了并行恢复功能,提高了恢复速度。

V8R3 与 V8R2 版本的差异

  1. WAL 性能提升

    • V8R3 版本进一步优化了 WAL 写入性能,减少了 WAL 写入的 I/O 开销。
    • V8R3 版本新增了 WAL 压缩功能,减少了 WAL 日志的存储空间占用。
  2. 回滚日志管理增强

    • V8R3 版本新增了回滚日志的监控视图,便于 DBA 监控回滚日志的使用情况。
    • V8R3 版本优化了回滚日志的清理机制,提高了清理效率。
  3. 新日志特性

    • 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 日志满的情况通常是由于归档失败或复制延迟导致的。处理方法:

  1. 检查归档状态:查看归档命令是否执行成功,归档目录是否有足够的空间。
  2. 检查复制状态:查看备库是否正常接收 WAL 日志,是否存在复制延迟。
  3. 调整 max_wal_size:如果系统负载较高,可以适当增大 max_wal_size 参数。
  4. 清理旧的 WAL 日志:如果确定旧的 WAL 日志不再需要,可以手动清理。

如何优化崩溃恢复时间?

  1. 调整检查点参数:减小 checkpoint_timeout 或增大 checkpoint_completion_target,减少恢复时需要重放的 WAL 日志量。
  2. 使用快速存储设备:将 WAL 日志存储在高性能存储设备上,提高恢复时的 I/O 速度。
  3. 启用并行恢复:在 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 需要:

  1. 理解 WAL 机制和 MVCC 的工作原理
  2. 合理配置重做日志和回滚日志的参数
  3. 定期监控日志的使用情况和性能
  4. 配置适当的归档策略,确保数据的可恢复性
  5. 优化日志的性能,提高系统的整体性能
  6. 了解崩溃恢复的过程,确保系统在崩溃后能够快速恢复

通过合理的日志管理和优化,可以提高 KingBaseES 数据库的性能、可靠性和可恢复性,确保业务的连续运行。