一、什么是表膨胀
表膨胀是指在一张表的数据文件中积累的自由空间(free space)被旧数据行使用。这些空间已经被之前删除或者不再访问的数据使用。不能做表的维护以重用这些空间,导致表数据文件越来越大,所以表扫描需要更长的时间,导致业务系统效率越来越低。
二、为什么会出现表膨胀
Greenplum数据库的存储实现(MVCC-多版本并发控制)来自于Postgres。根据MVCC的原理,没有办法直接更新数据(更新操作(update)是通过先删除(delete)再插入(insert)实现的),被更新之前的行数据仍然在数据文件中,直到通过使用VACUUM命令使空间被标记为“free”。 一旦VACUUM将被删除的行数据标记为“free space”,这些空间就能够被将来的插入和更新操作使用。在更新操作后,VACCUM操作之前的这段时间,这些空间是没有标记为“free”,因此无法被重新使用,实际上这些空间为“dead space”。
三、表膨胀处理的方式
1、vacuum
vacuum table_name vacuum可以标记已被删除的行数为’free’,即把数据文件中膨胀的空间(死元组)可以被后续新数据复用。但是如果“dead space”在数据文件末尾的话,会直接释放掉空间。 缺点:vacuum 大多数情况下只会让“dead space”可以被后续新数据复用,并不能真正释放这些空间,即不会减少磁盘占用。 优点:vacuum不会加锁,会占用一定的资源,但不影响业务系统。 比如,不考虑“dead space”在数据文件末端的情况,500g的表处理完300g,物理上磁盘存量没有减少,但是这200g可以被未来的数据复用
2、vacuum full
vacuum full table_name 不论被删除的数据是否处于数据表的末端,这些数据所占用的空间都将被物理的释放并归还于操作系统。之后再有新数据插入时,将分配新的磁盘页面以供使用。 优点:可以减少磁盘占用,并且处理后,业务效率提升会更多。 缺点:运行过程中会产生排他锁,即所有有关此表的操作都会被挂起,直到vacuum full执行完毕。
3、场景选择
vacuum建议场景:vacuum可以保证磁盘存量在一个稳定的值,且开销小,所以定期进行vacuum是很有必要的。需要注意的是,由于还是会有一定的资源占用,建议还是选在一周或一天业务场景少的时段进行。 vacuum full:考虑到其开销大,且存在排他锁,所以针对一些更新删除频繁的大表进行定期的处理,可以释放磁盘存量,而且效率提升比较大。需要注意的是,处理时最好保证业务系统空闲(etl空闲)。
|