Postgresql作为世界上最先进的HTAP数据库,以其超高在线事务处理及分析性能和强大的功能被广泛应用与各行各业中。但其实它也并不完美,说到postgres,不得不提那个让人一直头疼的问题,也是数据库使用者锁诟病最多的地方:vacuum。那么为什么会有vacuum这个东西呢?它是做什么用的呢?
我们先来聊聊postgresql的mvcc机制,我们知道,postgresql是没有undo表空间的,它通过数据的多版本来实现mvcc,一条数据的delete并不会释放数据占用空间,同理update是通过delete+insert的方式实现,通过这种方式减少了锁的使用,提高了并发性能。但是这种设计天然带来一个问题:旧数据的清理,如果清理不及时就会造成数据膨胀,这也是在频繁更新的oltp系统中数据膨胀问题的原因。
这里面其实还有一个问题,postgresql从设计之初事务号就是32位。但是32位的事务id最大只有49亿,49亿的事务号在如今的生产系统中几乎会很快耗尽,而事务号耗尽后从头开始循环使用,这里为了保证数据不丢失,需要对旧的事务号进行清理,这个清理过程会使得整个数据库无法处理新的请求,这就是网上经常所说pg的“冻结炸弹”。其实真正的清理并不是达到49亿就开始的,因为事务号是循环的,所以当达到事务号一半的时候数据库就会出现冻结炸弹。这个冻结的问题是pg永远绕不过去的痛。其实pg经过这么多年的社区发展,到今天pg12版本依然是32位的事务id,这个设计有人说是为了使得事务的回滚更快,能够更快