E.39. ptrack

E.39.1. 配置
E.39.2. 公开SQL API
E.39.3. 限制
E.39.4. 架构

E.39.1.  配置

唯一可配置的选项是`ptrack.map_size`(以MB为单位)。默认值为“-1”,这意味着“ptrack”已关闭。为了减少误报数量,建议将“ptrack.map_size”设置为预期“LTDATA”大小的“1/1000”(即1 TB数据库为“1000”)。

要禁用“ptrack”并清理所有剩余的服务文件,请将“ptrack.map_size”设置为“0”。

E.39.2.  公开SQL API

  • ptrack_version() — 返回ptrack版本字符串。

  • ptrack_init_lsn() — 返回上次ptrack映射初始化的LSN。

  • ptrack_get_pagemapset(start_lsn pg_lsn) — 返回一组更改的数据文件,其中包含自指定`start_lsn`以来更改的块及其位图的数量。

  • ptrack_get_change_stat(start_lsn pg_lsn) — 返回自指定`start_lsn`以来的变化统计数据(文件数、页数和大小(MB))。

Usage example:

postgres=# SELECT ptrack_version();
 ptrack_version 
----------------
 2.2
(1 row)

postgres=# SELECT ptrack_init_lsn();
 ptrack_init_lsn 
-----------------
 0/1814408
(1 row)

postgres=# SELECT * FROM ptrack_get_pagemapset('0/185C8C0');
        path         | pagecount |                pagemap                 
---------------------+-----------+----------------------------------------
 base/16384/1255     |         3 | \x001000000005000000000000
 base/16384/2674     |         3 | \x0000000900010000000000000000
 base/16384/2691     |         1 | \x00004000000000000000000000
 base/16384/2608     |         1 | \x000000000000000400000000000000000000
 base/16384/2690     |         1 | \x000400000000000000000000
(5 rows)

postgres=# SELECT * FROM ptrack_get_change_stat('0/285C8C8');
 files | pages |        size, MB        
-------+-------+------------------------
    20 |    25 | 0.19531250000000000000
(1 row)

E.39.3.  限制

  1. 您只能在“wal_level>=”replica“”的情况下安全地使用“ptrack”。否则,如果发生崩溃恢复,您可能会失去对某些更改的跟踪,因为 如果WAL_level最小,某些命令根本不会写入WAL,但我们只在检查点时间持久刷新“ptrack”地图。

  2. 目前,您无法在运行时调整“ptrack”映射的大小,只能在postmaster启动时调整。此外,您将丢失所有跟踪的更改,因此建议在维护窗口中这样做,并在执行此操作时进行完整备份。

  3. 您最多需要`ptrack.map_size*3`的额外磁盘空间,因为`ptrack`使用了两个额外的临时文件来实现持久性。

E.39.4.  架构

我们在`ptrack`中使用一个共享哈希表,该哈希表使用`mmap`从磁盘上的文件映射到内存中。由于映射的固定大小,可能会出现误报(当某些块被标记为已更改而未实际修改时),但不会出现误报结果。然而,通过设置足够高的“ptrack.map_size”,可以完全消除这些误报。

所有的读/写都是使用`uint64`条目上的原子操作进行的,因此在正常的PostgreSQL操作中,映射是完全无锁的。因为我们不使用锁进行读/写访问,也无法控制`mmap`驱逐回磁盘,`ptrack`会保留自上次检查点以来的映射(`ptrack.map`),并使用最多2个额外的临时文件:

  • 工作副本`ptrack.map.mmap`用于在其上执行`mmap`);

  • 临时文件ptrack.map.tmp,用于在检查点期间持久替换ptrack.map。

在检查点结束时,映射以原子方式逐块写入磁盘,涉及CRC32校验和计算,在崩溃恢复或重启后的下一次完整映射重新读取时进行检查。

为了在`ptrack_get_pagemapset()`中收集已修改块的整个变更集,我们遍历整个`LTDATA`(`base/**/*`、`global/*`、` lt_tblspc/*/*`),并使用map验证每个关系的每个块是否自指定的LSN以来都被修改过。