共享内存中的 2PC 改进状态文件

来自 PostgreSQL Wiki
跳转到导航跳转到搜索



2PC 改进:共享内存中的状态文件

此功能于 2009 年 8 月初的 Commitfest 中针对 PostgreSQL 9.0 提出。此修补程序未得到应用,因为性能改进被认为不够大,不足以冒着对代码执行行为更改的风险。

一般情况

描述

  • 在 Postgresql 8.4 中,所有 2PC 事务的状态文件都写入磁盘,然后在提交开始时将其删除。没有必要将所有这些状态文件保留在磁盘上,因为通常它们对于恢复目的来说是必要的。
  • 它们在检查点引起兴趣,检查点用于从 2PC 状态文件和 X 日志恢复数据库。
  • 此功能已引入,例如在准备状态将状态文件置于共享内存,并在提交阶段将其从中删除。
  • 通常在准备阶段和提交阶段之间没有很长时间,所以状态文件在共享内存上准时保留。

这也通过减少刷新到磁盘的数据量来加速 2PC 进度。

  • 通过名为 state_file_max_space 的参数来控制共享内存。

在初始化步骤中,分配大小为 max_prepared_transactions*state_file_max_space 的共享内存块,然后将其细分为多个大小相等的 state_file_max_space 块。

然后,每个块用于一个状态文件。

在检查点,只有已准备但未提交的事务的状态文件会刷新到磁盘,因为只有它们与 X 日志结合是恢复检查点所必需的。

修改的文件

  • src/backend/access/transam/twophase.c,实现的主要部分
    • 新参数 state_file_max_space 设置为默认值 0
    • 在共享内存中创建空间以存储状态文件
    • 在 EndPrepare 中收集记录后的状态文件管理
      • 数据量小于 state_file_max_space 所决定限制的状态文件将数据发送至共享内存
      • 数据量较大的文件将直接发送至磁盘
    • 在提交状态时,共享内存中的状态文件将从共享内存删除,该区块被清理并在下次使用
    • 检查点管理
      • 在已准备好的事务中,检查还未提交的事务中有哪项将状态文件置于共享内存中。若是如此,则将此状态文件刷新到磁盘
      • 控制非常严格,以确保将空文件发送至磁盘。例如,在刷新状态文件时共享内存将被重新初始化
  • src/backend/utils/misc/guc.c,管理新的参数 state_file_max_space
  • src/include/access/twophase.h,不是一个大问题,只新增了 guc 参数和函数 FlushStateFile
  • src/backend/storage/ipc/ipci.c,对状态文件的共享内存进行额外的初始化
  • src/backend/utils/misc/postgresql.conf.sample,添加参数 state_file_max_space,以便用户能够控制用于改进的 2PC 的共享内存

评估说明

模拟方法

为了查看改进的 2PC 的效果,所有测试均在配备了 8 个 RAID 0 配置磁盘的电池供电磁盘阵列上使用 pgbench 脚本和两个事务完成,它们的状态文件大小为 600B 和 712B。随后,通过改变事务和连接的数量,可以得到很多不同的结果。模拟已经重复 5 次,以确保可以得到稳定的结果。另外,在两种极端情况中,规模因子值已设置为 1 或 100 也进行了模拟。

使用的事务

  • 600B 的状态文件
\set nbranches :scale
\set ntellers 10 * :scale
\set naccounts 100000 * :scale
\setrandom aid 1 :naccounts
\setrandom bid 1 :nbranches
\setrandom tid 1 :ntellers
\setrandom delta -5000 5000
\setrandom txidrnd 0 100000
BEGIN;
UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid;
SELECT abalance FROM accounts WHERE aid = :aid;
UPDATE tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
UPDATE branches SET bbalance = bbalance + :delta WHERE bid = :bid
PREPARE TRANSACTION 'T:txidrnd';
COMMIT PREPARED 'T:txidrnd';
  • 712B 的状态文件
\set nbranches :scale
\set ntellers 10 * :scale
\set naccounts 100000 * :scale
\setrandom aid 1 :naccounts
\setrandom bid 1 :nbranches
\setrandom tid 1 :ntellers
\setrandom delta -5000 5000
\setrandom txidrnd 0 100000
BEGIN;
UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid;SELECT abalance FROM accounts WHERE aid = :aid;
SELECT bbalance FROM branches WHERE bid = :bid;
SELECT tbalance FROM tellers WHERE tid = :tid;
UPDATE tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
UPDATE branches SET bbalance = bbalance + :delta WHERE bid = :bid;
PREPARE TRANSACTION 'T:txidrnd';
COMMIT PREPARED 'T:txidrnd';


主要结果

结果分为两类:纯结果和归一化结果。纯结果的单位是 TX/s,归一化结果没有单位,但可以有效地查看状态文件 shmem 的 2PC 使用情况、磁盘状态文件上的 2PC 使用情况与没有 2PC 的情况之间的差异。为了评估改进的 2PC 的效果,对于一组值(连接、事务),可以使用下面的简单公式:<math>\frac{x_{Case}-x_{2PC Disk}}{x_{No 2PC}-x_{2PC Disk}}=y_{Normalized Rate}</math>

使用此公式,“没有 2PC”情况的 Tps 率为 1,且“共享内存上的状态文件使用 2PC 的情况”的 Tps 率为 0

这里列出了两个表,针对两个不同的规模因子值,并只显示归一化结果。规模因子为 100 时,归一化结果

连接 事务 600B,2PC 共享内存 600B,2PC 磁盘 600B,无 2PC 712B,2PC 共享内存 712B,2PC 磁盘 712B 无 2PC
2 10000 0.078663793 0 1 0.079652997 0 1
5 10000 0.105263158 0 1 0.08438061 0 1
10 10000 0.096105528 0 1 0.071661238 0 1
25 10000 0.106321839 0 1 0.128461538 0 1
35 10000 0.138996139 0 1 0.12106136 0 1
50 10000 0.130278527 0 1 0.140726934 0 1
60 10000 0.133937563 0 1 0.151709402 0 1
70 10000 0.17218543 0 1 0.149132948 0 1
80 10000 0.1775 0 1 0.177865613 0 1
90 10000 0.179806362 0 1 0.152327221 0 1
100 10000 0.182242991 0 1 0.152647975 0 1


  • 100 时的缩放比例,结果已标准化
连接 事务 600B,2PC 共享内存 600B,2PC 磁盘 600B,无 2PC 712B,2PC 共享内存 712B,2PC 磁盘 712B 无 2PC
2 10000 0.031791908 0 1 0.004266212 0 1
5 10000 0.018481848 0 1 0.038587312 0 1
10 10000 0.049115914 0 1 0.076610169 0 1
25 10000 0.06954612 0 1 0.061172472 0 1
35 10000 0.077677841 0 1 0.058464223 0 1
50 10000 0.059885932 0 1 0.089613035 0 1
60 10000 0.071888412 0 1 0.069977427 0 1
70 10000 0.094007051 0 1 0.035714286 0 1
80 10000 0.078838174 0 1 0.056358382 0 1

简要分析后得出,此功能在高竞争性环境中会将事务流提高 15%-18%。但在有限竞争性环境中,性能会降低多达 10%。