PostgreSQL码农集散地

为什么高并发数据写入吞吐无法达到磁盘极限

文中参考文档在github需点击阅读原文打开, 同时推荐2个学习环境: 

1、懒人Docker镜像, 已打包200+插件:《最好的PostgreSQL学习镜像》

2、有web浏览器就能用的云起实验室: 《免费体验PolarDB开源数据库》
3、PolarDB开源数据库内核、最佳实践等学习图谱:  https://www.aliyun.com/database/openpolardb/activity 
关注公众号, 持续发布PostgreSQL、PolarDB、DuckDB等相关文章. 

为什么高并发数据写入吞吐无法达到磁盘极限?

https://www.bilibili.com/video/BV1mr4y167xb/

当高并发写入时, 为什么数据写入吞吐无法达到磁盘极限? 例如磁盘的写入性能是4GB/s, 但是我们不管怎么写入, 都达不到4GB/s. 这是啥原因呢?

社区版本:
抛开其他的问题, 主要妨碍数据库写入吞吐达到磁盘极限的是几个重大锁

  • 申请 WAL片段的串行排他锁

  • 高并发小事务的ProcArrayEndTrans、GetSnapshotData开销

  • 每次数据文件空间不足时, 一次只扩展1个block, 因此大批量数据写入时, 数据库要频繁扩展数据块

    • 数据文件扩展 串行排他锁

    • 索引构建和页扩展 串行排他锁

  • 扩展数据块带来的结果就是数据文件长度的变化, 需要修改inode. 因此文件系统层面: inode 锁

极限测试法(我曾经测试过nvme ssd, 写入速度基本可以达到我那块SSD的物理极限, 3.6 GB/s):

  • 采用unlogged table , 直接避免写WAL(只有当事务结束时才需要写wal)

  • 无索引(同时无pk, uk约束) (避免索引构建和页分裂负担)

  • 多表并行导入(避免单表扩展数据文件的锁冲突瓶颈)

  • 使用大block size, 减少单表扩展数据文件冲突次数

    • 完全避免扩展block. (清空数据并保留datafile, 并完成垃圾回收, 确保block内空间全部可用)

  • 采用 COPY 协议. copy to tbl ... 简化数据库入库的逻辑路径.

问题:
在极限测试法中真正有意义(对业务透明)的优化只有“使用大block size”, 但是由于目前PG的一个实例只能选择一种block size规格, 如果选择大的block size, 会导致某些需要小block size的表可能性能变差并浪费更多shared buffer. (例如偏TP的业务) , 同时也浪费带宽(例如只需要取一个page里的几条记录可能只有100多字节但是也要读整个大的block上来, 浪费存储带宽).

高速写入的业务场景, 例如IOT, 时序, feedlog(金融类、互联网用户行为类、游戏行业玩家行为类等等)类比较苦恼.

PolarDB:
支持一次扩展多个数据块, 通过参数polar_bulk_extend_size控制.
- 减少数据文件、索引页扩展导致的大量数据写入的扩展文件排他锁导致的性能瓶颈. 数据大批量写入性能更佳.

参考:

  • 《PostgreSQL 单表并行bulkload的extend file lock 冲突问题解决 - 数据块预分配》

  • 《parallel blocking|waiting by slow BLOCK extend relation , ExclusiveLock on extension of relation》

  • 《PostgreSQL bulk COPY load Bottleneck by extend lock waiting》

  • 《DB吐槽大会,第28期 - PG 每次只扩展1个block》

本期问题1:
妨碍PostgreSQL社区版本数据库写入吞吐达到磁盘极限的几个重大锁是?

  • a. 写入数据时的表级别排他锁

  • b. 申请 WAL片段的串行排他锁

  • c. 数据文件扩展串行排他锁

  • d. 写入数据时的行级别排他锁

  • e. 索引构建和页扩展串行排他锁

答案:

  • bce

解释:

  • 参考本文内容

本期问题2:
以下哪些方法对测试数据导入达到磁盘极限有帮助?

  • a. 使用insert

  • b. 使用copy

  • c. 使用upsert

  • d. 使用更大的block size

  • e. 使用更小的block size

  • f. 使用索引

  • g. 不使用索引和pk uk约束

  • h. 使用unlogged table

  • i. 并行导入多个表

答案:

  • bdghi

解释:

  • 参考本文内容

本期问题3:
PolarDB的什么特性对高速写入的业务场景, 例如IOT, 时序, feedlog类业务有很大的性能提升?

  • a. polar_bulk_extend_size, 预分配数据块

  • b. 存储计算分离功能

  • c. 跨机并行优化器

  • d. wal 管道技术

答案:

  • a

解释:

  • 参考本文内容

欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.  

近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:

Image

文章中的参考文档请点击阅读原文获得.