知识库

检查点和日志修剪交互

概述

检查点(Checkpointing)是将页面缓存(page cache)中所有待处理的页面更新刷新到存储文件的过程。这对于确保在恢复期间需要重放的事务数量保持在合理范围内是必要的,主要目的是减少在非正常关闭后的恢复时间。无论是否存在检查点,数据库操作都是安全的,因为所有未确认已持久化到存储的事务都会在数据库下次启动时进行重放。然而,这取决于这些事务包含的变更集是否存在,相关信息保存在事务日志中。如果未应用事务的列表过长(即检查点之间的间隔过大),会导致事务日志堆积,因为它们对于恢复是必需的。检查点会在事务日志中引入一个特殊的“检查点”条目,标记发生检查点的最后一个事务。这用于确定哪些事务日志不再需要,因为它们包含的所有事务都已安全地持久化到存储文件中。

删除恢复不再需要的事务日志的过程称为清理(pruning)。从上述描述可以明显看出,清理依赖于检查点,因为检查点决定了哪些日志可以被清理,换句话说,决定了何时可以进行清理。如果未发生检查点,则可清理事务日志文件的集合就不会发生变化。这种依赖关系通过每当检查点发生时触发清理(如下所述,可能包含也可能不包含对其存在性的检查)来体现。这种关系是不变的,适用于后续讨论的全部内容。

触发检查点(和清理)事件

作为清理驱动事件的检查点,可以通过几种不同的方式触发。

最简单的方法称为“定期(periodic)”,默认每15分钟检查一次是否有待刷新的变更(即尚未进行检查点的事务)。如果有,则执行检查点并随后触发日志清理。请注意,如果不执行检查点,则意味着不会发生清理。这是默认行为,也是社区版中唯一可用的选项。

在企业版中,还有两种额外的检查点策略。最简单的是“持续(continuous)”,顾名思义,它会不断检查是否可以进行检查点(即自上次成功检查点以来是否有任何事务提交),如果是,则执行它。与定期策略一样,清理在检查点完成后立即触发。

第三种也是最后一种检查点策略是“体积(volumetric)”。它每10秒检查一次是否有可用于清理的日志,如果有,它会触发检查点并随后清理日志。该策略似乎颠倒了检查点和清理之间的控制关系,但实际上它只是更改了必须发生检查点的标准。它不像前两种策略那样依赖时间触发,而是依赖清理检查。与其他两种策略一样,清理仍将在检查点发生后进行。然而,由于检查取决于是否存在可清理的事务日志文件,因此该策略取决于下一节中描述的清理配置。

要使用的策略由设置 dbms.checkpoint 控制,默认为“periodic”。

日志和指标

以下详细说明了检查点事件发生时在 logs\debug.log 中出现的预期消息

基于 dbms.checkpoint.interval.time 的检查点

2019-08-28 12:55:05.174+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for time threshold" @ txId: 49 checkpoint started...
2019-08-28 12:55:05.253+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for time threshold" @ txId: 49 checkpoint completed in 79ms

基于 dbms.checkpoint.interval.tx 的检查点

2019-08-28 13:08:51.603+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for tx count threshold" @ txId: 118 checkpoint started...
2019-08-28 13:08:51.669+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for tx count threshold" @ txId: 118 checkpoint completed in 66ms

当 dbms.checkpoint=continuous 时的检查点

2019-08-28 13:17:21.927+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for continuous threshold" @ txId: 171 checkpoint started...
2019-08-28 13:17:21.941+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for continuous threshold" @ txId: 171 checkpoint completed in 13ms

数据库关闭导致的检查点

2019-08-28 12:35:56.272+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Database shutdown" @ txId: 47 checkpoint started...
2019-08-28 12:35:56.306+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Database shutdown" @ txId: 47 checkpoint completed in 34ms

由 Neo4j 3.5.6 引入的 call dbms.checkpoint(); 导致的检查点

2019-08-28 12:31:56.463+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Call to dbms.checkpoint() procedure" @ txId: 47 checkpoint started...
2019-08-28 12:31:56.490+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Call to dbms.checkpoint() procedure" @ txId: 47 checkpoint completed in 27ms

备份运行导致的检查点

2019-08-28 12:33:30.489+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Full backup" @ txId: 47 checkpoint started...
2019-08-28 12:33:30.509+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Full backup" @ txId: 47 checkpoint completed in 20ms

检查点指标 也可用,并详细说明于 metrics/ 以及以下文件中

neo4j.check_point.check_point_duration.csv
neo4j.check_point.total_time.csv
neo4j.check_point.events.csv

控制事务日志清理

事务日志清理配置主要涉及指定应保留的事务日志数量。保留超过恢复所需的绝对最小数量的主要原因源于集群部署和在线备份的需求。由于数据库更新是通过事务日志在集群成员和备份客户端之间进行通信的,因此保留超过必要的最少量,可以只传输增量变更(以事务的形式)而不是整个存储文件,这可以节省大量时间和网络带宽。这适用于 HA 部署、备份以及因果集群(Causal Clusters)中的只读副本。然而,在因果集群的核心成员(Core members)的情况下,重要的不是事务日志,而是 Raft 日志内容。这种情况将在单独的知识库文章中介绍。

清理操作后留下的事务日志数量由设置 dbms.tx_log.rotation.retention_policy 控制,它可以采用多种值。格式为 <数值> <度量单位>

<度量单位> 可以是 "files"、"size"、"txs"、"entries"、"hours" 或 "days"。

  • "files" 确定清理后保留的事务日志文件的最小数量。这意味着一旦执行检查点,将删除部分日志文件,以确保至少保留指定数量的文件——例如值 "5 files" 将保留至少 5 个事务日志文件。

  • "size" 的行为类似,但它计算的是总文件大小而不是文件数量。例如,"500M size" 将保留至少 500M 的文件。

  • "txs""entries" 是同义词。它们的行为与上述类似,但它们计算的是文件中存在的事务数量,与文件数量或大小无关。"100 txs" 将在每次操作后保留至少 100 个事务的日志。

  • "hours""days" 衡量的是时间而不是大小或事务计数,但在其他方面行为类似。将值设置为 "20 hours" 将确保日志中至少存在 20 小时的事务。

© . This site is unofficial and not affiliated with Neo4j, Inc.