作者简介:
Hans-Jürgen Schönig从90年代开始接触PostgreSQL,目前是CYBERTEC的CTO以及技术领导。CYBERTEC是PostgreSQL领域的技术领导者之一并且从2000年开始服务于多个国家。
译者简介:
陶进,数据库技术和理论爱好者,熟悉pg和gp以及其他大数据相关并行处理框架,现就职于广联达数据中台部门。
校对者简介:
崔鹏,任职于海能达通信股份有限公司,数据库开发高级工程师,致力于postgresql数据库在专网通信领域、公共安全领域的应用与推广。
在PostgreSQL中,自从早期的MVCC模型被设计出来以后, 表膨胀成为主要的忧虑。CYBERTEC曾通过一系列博客来详细讨论这件事情。什么是 表膨胀? 表膨胀是表或者索引的记录条数没有增加,但是占用的物理空间大小在持续增长。如果要支持事务,记录在被修改时显然不能直接覆盖掉原纪录,因为用户正在修改时可能会有其他用户在读取原纪录,或者事务需要回滚。 对于PostgreSQL的MVCC来说,膨胀是必然的事情。但是,PostgreSQL当前存储数据以及处理事务的机制并不是数据库在事务和并发方面唯一的方案。我们可以看看其他方案: 在MS SQL中,你可以找到一个称作tempdb的东西,而在Oracle和MySQL中,旧版本的纪录放在redo lo g中。你可能知道PostgreSQL在执行Update的时候复制一条新的记录并且将它存储在原表中。Firebird同样将记录的多个旧的版本串联起来。 这里主要想表达两点: Ø 处理旧的记录很难(Getting rid of old rows is hard) Ø 没有一种方案不是经过各方面权衡之后的结果(No solution is without tradeoffs) 如何处理旧的记录是一个实实在在的问题。在PostgreSQL中通常通过vacuum删除旧的记录。但是,在某些场景下,vacuum不会一直执行,或者磁盘空间因为其他原因一直增长(比如,长事务)CYBERTEC的博客曾经大量的讨论过这些场景。 “没有一种方案不是经过各方面权衡之后的结果”表达了存储系统重要的一面。不存在一个完美的存储引擎——只存在于服务于某些特定的负载场景(workloads)的存储引擎。对于PostgreSQL也同样:当前的表结构适用于非常多的应用场景(workloads).但是某些“短板”也会让我们回到最开始的主题: 表膨胀。在执行UPDATE非常多的负载下, 表膨胀比其他情况下更容易产生,很难去控制表的大小。如果开发人员或者管理员没有预先了解PostgreSQL的工作机制这种状况非常容易发生。