KingbaseES checkpoint_timeout参数对wal日志量的影响

前言

在KingbaseESV8R6数据库中,必须先将更改写入WAL日志(老版本称为 xlog),然后才能将这些更改从内存shared_buffer 写入到磁盘。

前两天有个同事遇到一个问题,wal日志每天生成120GB,于是我们检查了参数checkpoint_timeout参数是默认的5min。然而这个参数应该根据实际的业务类型进行调整,建议调整为30-60分钟。

增加检查点之间的距离会导致WAL日志减少,相当于增加checkpoint_timeout参数,就相对减少wal日志量生成。因为当开启了full_page_writes参数(默认开启),每次检查点后的第一次写入wal日志必然发生一次全页写。所以这就大大增加了wal日志量。

检查点相关参数:
checkpoint_timeout
自动 WAL 检查点之间的最长时间,以秒计。合理的范围在 30 秒到 1 天之间。默认是 5 分钟( 5min )。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在 kingbase.conf 文件中或在服务器命令行上设置。

checkpoint_completion_target
指定检查点完成的目标,作为检查点之间总时间的一部分。默认是 0.5。 这个参数只能在 kingbase.conf 文件中或在服务器命令行上设置。

max_wal_size
在检查点之间允许重做日志增长到的最大尺寸。这是一个软限制, 在特殊的情况下重做文件尺寸可能会超过max_wal_size。如果指定值时没有单位,则以兆字节为单位。默认为 1 GB。增加这个参数 可能导致崩溃恢复所需的时间。这个参数只能在kingbase.conf或者服务器命令行中设置。

测试wal日志生成量对比

这里使用kbbench工具进行测试

[复制代码](javascript:void(0)😉

kbbench参数说明:
[kingbase2@localhost ~]$ kbbench --help
kbbench is a benchmarking tool for Kingbase.

Usage:
  kbbench [OPTION]... [DBNAME]

Initialization options:
  -i, --initialize         invokes initialization mode
  -I, --init-steps=[dtgvpf]+ (default "dtgvp")
                           run selected initialization steps
  -F, --fillfactor=NUM     set fill factor
  -n, --no-vacuum          do not run VACUUM during initialization
  -q, --quiet              quiet logging (one message each 5 seconds)
  -s, --scale=NUM          scaling factor
  --foreign-keys           create foreign key constraints between tables
  --index-tablespace=TABLESPACE
                           create indexes in the specified tablespace
  --tablespace=TABLESPACE  create tables in the specified tablespace
  --unlogged-tables        create tables as unlogged tables

Options to select what to run:
  -b, --builtin=NAME[@W]   add builtin script NAME weighted at W (default: 1)
                           (use "-b list" to list available scripts)
  -f, --file=FILENAME[@W]  add script FILENAME weighted at W (default: 1)
  -N, --skip-some-updates  skip updates of kbbench_tellers and kbbench_branches
                           (same as "-b simple-update")
  -S, --select-only        perform SELECT-only transactions
                           (same as "-b select-only")

Benchmarking options:
  -c, --client=NUM         number of concurrent database clients (default: 1)
  -C, --connect            establish new connection for each transaction
  -D, --define=VARNAME=VALUE
                           define variable for use by custom script
  -j, --jobs=NUM           number of threads (default: 1)
  -l, --log                write transaction times to log file
  -L, --latency-limit=NUM  count transactions lasting more than NUM ms as late
  -M, --protocol=simple|extended|prepared
                           protocol for submitting queries (default: simple)
  -n, --no-vacuum          do not run VACUUM before tests
  -P, --progress=NUM       show thread progress report every NUM seconds
  -r, --report-latencies   report average latency per command
  -R, --rate=NUM           target rate in transactions per second
  -s, --scale=NUM          report this scale factor in output
  -t, --transactions=NUM   number of transactions each client runs (default: 10)
  -T, --time=NUM           duration of benchmark test in seconds
  -v, --vacuum-all         vacuum all four standard tables before tests
  --aggregate-interval=NUM aggregate data over NUM seconds
  --log-prefix=PREFIX      prefix for transaction time log file
                           (default: "kbbench_log")
  --progress-timestamp     use Unix epoch timestamps for progress
  --random-seed=SEED       set random seed ("time", "rand", integer)
  --sampling-rate=NUM      fraction of transactions to log (e.g., 0.01 for 1%)

Common options:
  -d, --debug              print debugging output
  -h, --host=HOSTNAME      database server host or socket directory
  -p, --port=PORT          database server port number
  -U, --username=USERNAME  connect as specified database user
  -V, --version            output version information, then exit
  -?, --help               show this help, then exit

Report bugs to <kingbase-bugs@kingbase.com.cn>.



1)创建测试数据库kbbench :
createdb -p 2920 -U SYSTEM   kbbench ;

2)初始化测试数据:
kbbench -i -s 10 -p 2920 -U SYSTEM   kbbench
重点:主要用到两个参数,‐i:初始化模式,‐s 插入的倍数,默认是1,即插入100000条,这里设置10,即插入100万条记录

[kingbase2@localhost sys_wal]$ kbbench -i -s 10 -p 2920 -U SYSTEM   kbbench
dropping old tables...
creating tables...
generating data...
100000 of 1000000 tuples (10%) done (elapsed 0.07 s, remaining 0.63 s)

200000 of 1000000 tuples (20%) done (elapsed 0.18 s, remaining 0.70 s)
300000 of 1000000 tuples (30%) done (elapsed 0.29 s, remaining 0.67 s)
400000 of 1000000 tuples (40%) done (elapsed 0.39 s, remaining 0.59 s)
500000 of 1000000 tuples (50%) done (elapsed 0.49 s, remaining 0.49 s)
600000 of 1000000 tuples (60%) done (elapsed 0.60 s, remaining 0.40 s)
700000 of 1000000 tuples (70%) done (elapsed 0.71 s, remaining 0.30 s)
800000 of 1000000 tuples (80%) done (elapsed 0.82 s, remaining 0.21 s)
900000 of 1000000 tuples (90%) done (elapsed 1.01 s, remaining 0.11 s)
1000000 of 1000000 tuples (100%) done (elapsed 1.12 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done.



开始测试:
kbbench -c 4 -j 4 -T 100 -r -p 2920 -U SYSTEM   kbbench;
-c 总连接数,创建多少个连接到数据库,一般数据库接受连接数默认为100,其中需要预留
3个左右的连接。
-j 进程数量,每个进程创建n个连接,那么就存在如下关系:-c = -j *n,建议为服务
器的CPU核数。
-T 测试持续时间,指定了-T就不能指定-t,每个连接执行的事物数量。即,要么指定测试多
长时间,要么指定测试多少个事物。
-r 显示每一步操作的平均时间。
-f 指定测试脚本,不指定则使用默认脚本。这里使用的默认脚本。


[kingbase2@localhost ~]$ kbbench -c 4 -j 4 -t100 -r -p 2920 -U SYSTEM   kbbench;
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 4
number of threads: 4
duration: 100 s
number of transactions actually processed: 104125
latency average = 3.842 ms
tps = 1041.164501 (including connections establishing)
tps = 1041.374809 (excluding connections establishing)
statement latencies in milliseconds:
         0.001  \set aid random(1, 100000 * :scale)
         0.000  \set bid random(1, 1 * :scale)
         0.000  \set tid random(1, 10 * :scale)
         0.000  \set delta random(-5000, 5000)
         0.241  BEGIN;
         0.173  UPDATE kbbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
         0.406  SELECT abalance FROM kbbench_accounts WHERE aid = :aid;
         0.867  UPDATE kbbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
         1.453  UPDATE kbbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
         0.160  INSERT INTO kbbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
         0.538  END;



kbbench=# select pg_size_pretty(sum(size)) from pg_ls_waldir();
 pg_size_pretty
----------------
 160 MB
(1 row)

调整检查点时间为30s,再次进行测试
alter system set checkpoint_timeout='1min'

TEST=# select sys_reload_conf();
 sys_reload_conf
-----------------
 t
(1 row)

TEST=# show checkpoint_timeout ;
 checkpoint_timeout
--------------------
 1min
(1 row)


TEST=# drop database kbbench;
DROP DATABASE
再次执行一次以上的测试步骤
createdb -p 2920 -U SYSTEM   kbbench ;

kbbench -i -s 10 -p 2920 -U SYSTEM   kbbench

kbbench -c 4 -j 4 -T 100 -r -p 2920 -U SYSTEM   kbbench;

wal日志量增长3倍左右,因为检查点发生的更频繁,导致检查点发生后第一次写入的wal日志是full page,也就是写入了8K,无形中增加了wal日志量。

TEST=#  select pg_size_pretty(sum(size)) from pg_ls_waldir();
 pg_size_pretty
----------------
 462 MB
(1 row)

[复制代码](javascript:void(0)😉

总结:

增加检查点间隔可以避免生成大量wal日志。而且检查点频繁发生会使脏块写入更频繁,这时候如果业务很繁忙,wal日志实际上也会发生大量磁盘写,综合分析,很容易造成磁盘IO繁忙,严重会影响业务正常运行,甚至造成一些数据库等待事件。所以我们需要根据业务系统类型,例如OLAP或OLTP,合理设置检查点时间。
另一方面,需要注意增加检查点时间间隔虽然对数据库性能有帮助,但是由于需要保留更多wal日志,所以当发生实例崩溃时,事务前滚回滚的时间也会加长,那么也将增加数据库恢复时间。

posted @ 2023-02-28 10:02  KINGBASE研究院  阅读(124)  评论(0编辑  收藏  举报