首页 > 数据库 > 国内数据库 > Kingbase WAL 相关参数解析
wal 简介
change 发生时: 先将变更后的数据写入wal buffer,再将更新后的数据写入data buffer;
wal -- write ahead log,预写式日志(事务日志/redo log,重做日志);
事务日志是数据库的关键组件,在数据库系统出现故障时,在任何数据库管理系统中,都不允许数据丢失。事务日志是数据库系统中所有数据变更的行为记录,在数据库故障或者特定场景下进行恢复时,通过该日志可重现数据库的相关操作,确保数据不丢失;
change 发生时: 先将变更后的数据写入wal buffer,再将更新后的数据写入data buffer;
commit 发生时: wal buffer 刷新到磁盘;
checkpoint 发生时: 将data buffer 所有数据刷到磁盘;
wal 的中心思想时,先写入日志文件,再写数据,相当于oracle 的redo;
为减少log 日志文件的 I/O 操作,通过wal buffer 对产生的log 日志进行缓存;
日志文件是顺序写,开销小优先落盘;
保证了事务持久性和完整性,又尽量的避免了频繁 I/O 对性能的影响;
PITR,Point In Time Recovery,时间点恢复;
SR,Streaming Replication,流复制;
Wal Segment file,日志段文件,kes 把日志划分为多个日志段文件,每个日志段文件默认16M;
Log Record,日志记录,每个变更都对应一条log record,kes 读取这些 log record 进行实例恢复、增量备份、PITR、SR;
wal buffer,日志缓冲区,不管是wal segment file 的 header 还是log record都会先写入到wal buffer 中,在合适的时候再通过wal writer 进程写入到 wal segment file 中;
LSN,log segment number,日志序列号,表示 log record 记录写入到日志文件中的位置;
checkpointer,检查点进程,改后台进程周期性的执行 checkpoint,当执行checkpoint 时,该进程会把包含checkpoint 信息的 log record写入到当前的日志文件中,该 log record 记录包含了最新的redo point 的位置;
checkpoint,检查点,由checkpointer 进程执行,主要处理流程如下:获取redo point,构造包含redo point 信息的log record并写入到日志文件,刷新dirty page 到磁盘;更新redo point 等信息到 sys_control 文件中;
一、配置
wal_level = minimal , minimal, replica, or logical
决定写入 wal 的信息量多少,默认只写入从崩溃和宕机中恢复所需要的信息。 archive 补充 wal 归档所需要的日志记录, hot_standby 进一步增加在一个后备服务器上运行只读查询所需的信息。重启生效。
archive , wal 归档、物理同步;
hot_standby , archive+ 从 wal 重建运行事务的信息;
logical , hot+ 允许从 wal 抽取逻辑修改信息;
wal 信息从少到多: minimal 实例恢复、 replica 备份恢复、 logical 逻辑解码信息;
fsync = on
kes 服务器将尝试确保更新被物理的写入至磁盘,做法是发出 flync()( 在每次提交时调用 ) 系统调用或者使用多种等价方法 (wal_sync_method) 。关闭可以得到性能上的收益,但是当发生断电或系统崩溃时可能造成不可恢复的数据损坏。
在很多情况下,为不重要的事务关闭 synchronous_commit 可以提供很多关闭 fsync 的潜在性能收益,而不会有关闭 fsync 关闭的数据损坏风险 。如果要关闭这个参数,请也考虑关闭 full_page_writes 。
控制 wal_sync_method 是否将 wal 刷新到磁盘,如果 fsync 为 off ,则故障发生后可能会出现块折断
wal_sync_method = fsync , open_datasync 、 fdatasync 、 fsync 、 fsync_writethrough 、 open_sync
强制 wal 更新至磁盘的方法 。
synchronous_commit = on , on 、 remote_write 、 local 、 off
命令返回 success 前,一个事务是否需要等待 wal 写入磁盘
如果没有设置同步备库,则 on/remote_write/local 都是一样的,仅等待 wal 刷新到本地磁盘;
此参数可以局部设置,当有临时批量任务时,可以设置: set synchronous_commit to off;
当性能比完全确保事务的持久性更重要时,关闭 synchronous_commit 是个有效代替手段 。
单实例环境 :
on :表示事务提交时,等待本地 wal buffer 写入 wal 日志后向客户端返回成功;
off :提交事务时不等待 wal buffer 写入 wal 日志,即向客户端返回成功;只会造成 3 倍的 wal_writer_delay ( 默认 200ms) 的事务丢失,但数据库可以安全启动,不会发生块折断;
local : local 和 on 类似,需要等待本地 wal 写入后才向客户端返回成功;
流复制环境 :
on :本地 wal 已落盘,备库的 wal 也已落盘,有两份持久化的 wal ,但是备库还未 apply ;
remote_write :本地 wal 已落盘,备库的 wal 还在备库操作系统的缓存中,有一份持久化的 wal ;
remote_apply :本地 wal 已落盘,备库的 wal 已落盘并且已经完成重做,有两份持久化的 wal ;
local :当事务提交时,写入本地磁盘即可,不用理会是否有备库;
wal_writer_delay = 200ms
wal 写入器的 活动 轮次之间的延迟,周期性刷新 wal buffer 然后 sleep ,过长则 buffer 不足,过短则 wal 持续写入。 许多系统里,有效的休眠解析度时 10 毫秒, wal_writer_delay 设置不是 10 的倍数,将得到下一个 10 的倍数值相同的效果。
full_page_writes = on , on 、 off
kes 在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写入 wal 中, checkpoint 后,块第一次变脏要整块写入 wal 日志,以防止块折断。
操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致一个磁盘页面混合有新旧数据。在崩溃后的恢复期间,通常存储在 wal 中的行级改变数据不足以恢复这样一个页面。存储完整的页面映像可以保证页面被正确存储,但代价是增加了必须被写入 wal 的数据量(因为 wal 重放总是从一个检查点开始,所以检查点后每个页面的第一次改变时这样做就够了。因此,一种 减小全页面写开销的方法是增加检查点间隔参数值 )。
KES 以 page 为基本的存储单元 (8kb) ,但物理存储的扇区最小单元为 512bytes ,故会导致块折断问题。为了应对这种情况, kes 在写入 wal 时,会把出现变化的页整页写入到 wal 中,而不仅仅是数据。在数据库重启执行恢复的时候,在 redo point 开始回放 wal 时,如发现 Xlog record 是 FPI (full-page-image) ,则整页替换,通过这种机制解决了部分写的问题。
checkpoint 频繁时, wal FPI 会导致写放大 :
库繁忙、热块分散、 checkpoint 时间间隔短,则过多的 page 通过 full_page_write 写入 wal 中;
文件系统,例如 zfs 可以保证不会出现部分写的情况,则可以关闭 full_page_writes;
wal_buffers = -1
wal
文件持久化之前的缓冲区;
默认值
-1
表示选择
shared_buffers
的
1/32
的尺寸
(
约
3%)
,但是不小于
64kb
也不大于
WAL
段的尺寸。多个
client
同时提交事务时,缓冲区较大会更大程度的合并
I/O
提高性能。其内容每
wal_writer_delay
间隔清空,故推荐默认值。
wal_log_hints = off , off 、 on
on 时 kes 服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写入 wal 中,即使对提示为做非关键修改; 数据校验 和提示为更新也会记录记录特定提示位( hint-bit )的变化;一些特定的工具会要求设置这个参数来正常的运行。设为 on 时,检查点之后第一次页面更改(即使是对提示位进行非关键性的修改)写 FPI 到 WAL 中。
commit_delay = 0 , 0-100000 微妙 superuser
wal 刷新前,增加一个延迟。
commit 后延迟 0-100000 ms 再提交,此机制可合并其他事务实现组提交,但至少有 commit_siblings 参数个事务等待提交时候才会延迟,如果事务很稀少就不会被延迟。如果 fsync 被禁用,则不会有延迟。
commit_siblings = 5 , 1-1000 user
执行 commit_delay 延迟时要求的并发事务的最小值。
组提交的最小事务个数,事务达不到该值 commit_delay 无效。
wal_compression = off , on superuser
on 时且 full_page_writes 为 on ,压缩完整页面至 wal 中。开启此参数,会增加 wal 日志压缩及 wal 回放解压过程中一些额外的 cpu 成本开销。
wal_writer_flush_after = 1MB sighup
wal 写入器刷写wal 的大小。
wal_writer 的字节数超过该阈值时触发fsync,I/O 很好的机器不需要考虑平滑调度,设0关掉该特性。设置为0,每次wal 写入器写完wal 后(wal buffer),wal 就会被刷写(wal log),默认值1M。
二、检查点
checkpoint_timeout = 5min , 30s-1d( 天 ) sighup
自动 wal 检查点之间的最长时间,秒。
最大多长时间发生一次 checkpoint ,增加这个值会增加崩溃恢复所需的时间。
触发检查点:
(1). checkpoint_timeout ,默认 5 分钟;
checkpoint_completion_target = 0.5 , 0.0 - 1.0 sighup
指定检查点完成的目标,与 checkpoint_timeout 配合使用。
情况一:
checkpoint_completion_target=0.5
checkpoint_timeout = 5min
100G 数据(需要刷进磁盘的数据量)
1G/s
100*1024/ ( 0.5*5*60 ≈ 670M/s (数据写入速度)
情况二:
checkpoint_completion_target=0.9
checkpoint_timeout = 5min
100G 数据
1G/s
100*1024/ ( 0.9*5*60 ) ≈ 380M/s
通常来说,实际的生产环境,机器所能支撑的写入速度为 500M/s-1200M/s ,通过数据写入速度来看 “ 性能 ” 的话,在 checkpoint_completion_target 设置的越高的情况下,写入速度越低,对客户而言,体验越好,性能越高。反之,较低的值可能会引起 I/O 峰值,导致 “ 卡死 ” 的现象。
checkpoint_flush_after = 0 , 0~2M sighup
执行检查点时,只要有该大小字节写入,尝试强制 os 把这些发送至底层存储。
当 bgwriterprocess 脏数据超过配置阈值时 , 触发调用 OSsync_file_range, 告诉 osbackendflush 线程异步刷盘。 从而削减 osdirtypage 堆积。
checkpoint_warning = 30s sighup
填充检查点的间隔低于该值发送告警信息。
如果 checkpoints 的实际发生间隔小于该参数,会在 server log 中写入一条信息,可通过设置为 0 禁用。
检查点发生的太频繁,建议执行 alter system set max_wal_size = '4GB'; 增大。
max_wal_size = 1GB sighup
自动 wal 检查点使得 wal 增长到的最大尺寸,默认 1G 。
checkpoint_time 、 max_wal_size 哪个先达到条件,先触发执行检查点。
min_wal_size = 80MB sighup
只要 wal 磁盘使用率低于该值,旧的 wal 文件总数被回收,以供将来检查点使用,非删除。
最小的 wal 空间,参考值 shared_buffer 的一半以上,剩余磁盘空间低于该值时触发回收旧的 wal 文件以确保预留足够的空间以应对 wal 暴增。紧急情况下 可执行 sys_resetxlog 清理 sys_xlog 空间 。
三、归档
archive_ mode = off , on 、 off 、 always
将已完成的 wal 段发送至 archive_dest 存储。 当 wal_level 为 minimal 时, archive_mode 不能被启用 。
archive_dest = ''
归档路径
archive_timeout = 0
定时归档。
数据库 触发归档的三种情况 ( 切换日志 ) :
(1) 手动归档:
test=# select sys_switch_xlog();
sys_switch_xlog
-----------------
0/5F2988B0
(1 row)
test=#
执行 sys_switch_xlog() 后, wal 会切换到新的日志,将老的 wal 日志归档,归档到 archive_dest 。
(2)wal 日志写满后触发归档 :
wal 日志文件默认 wal_segment_size = 16M ,初始化数据库时可更改,加参数 --with-wal-segsize=64MB 。
(3) 达到 archive_timeout 阈值 :
假如 archive_timeout = 60s ,则每 60s 触发一次日志切换,同时触发日志归档。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69997973/viewspace-2767217/ ,如需转载,请注明出处,否则将追究法律责任。