共享内存中的 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%。