一:vacuum
- 什么是vacuum
vacuum是greenplum数据库中用来回收死亡元组占用空间的语句。
标准语句:
VACUUM [FULL] [FREEZE] [VERBOSE] [table]
VACUUM [FULL] [FREEZE] [VERBOSE] ANALYZE
[table [(column [, ...] )]]
例句:
清理当前数据库下的所有表(该操作是只要登录的数据库账户有权限的表都会进行vacuum):
VACUUM;
清理一张指定的表:
VACUUM tablename;
清理当前数据库下的所有表同时为查询优化器收集统计信息:
VACUUM ANALYZE;
- vacuum的作用
因为greenplum数据库是基于postgres,而postgres采用的是mvcc(多版本并发控制)机制来处理常用的读写冲突,用来提高数据库高并发场景下的吞吐性能。并发访问一般就读写两种操作,读与读之间肯定不会冲突,写与写之间肯定会发生冲突是用锁来解决,还有一种读写操作这个是不定的有时也会发生冲突。mvcc就是为了解决这一情况,让读写之间不会阻塞。
实现的方法,比如对一张表的数据进行update,由1更新成2。此时1这个数据不会被物理上的删除。只是被标记成已删除,成为旧版本被2这个新版本取代。在磁盘上还会保留1这个版本记录。写的时候旧版本不会被删除此时如果有读操作则会读到旧版本的数据也就是1,待update执行完成,此时再读则会变成2。由此解决了读写阻塞的问题。
有得必有失,这样的机制也导致了另一个问题,当一张表更新的版本也许所产生的旧版本也可以称之为死亡元组所占用的存储就越多。这势必会影响到我们操作这张表的执行速度,因此我们需要来清理这些无用的元组,这个操作就是vacuum。
- vacuum的使用场景和注意事项
建议对使用比较频繁的表定期使用vacuum full不建议使用vacumm,因为在实际使用中vacuum的效果可能没有那么好,甚至可以说是微乎其微的作用。但是vacuum full会对表产生独占锁,并且对io的消耗很高所以需要在业务空闲的时候执行。
4.vacuum和vacuum full的区别
vacuum:并不会实际删除表的数据,只会将死亡元组做个标记,表示此元组可复用。但是对表不会产生排他锁。
vacuum full:这个操作相当于新建了一张同名的表,把原表中最新版本的数据全部复制到新表中,原版本的表直接物理意义上的删除。这是比较简单通俗的解释,具体还会涉及到原表索引,统计信息等等。
案例分享(基于4.3版本):
vacuum full 表导致数据库hang机
一般这样的问题都是锁冲突,或者是当前版本的bug。如果是锁冲突的问题可以在pg_locks表中查到相关的信息,锁冲突的情况建议根据实际情况决定是否清理产生冲突的进程。vacuum full “系统表”的锁冲突可能会导致psql这样的命令卡住,也就是说会导致默认的数据库进不去,导致这样的错误是因为连接相应的库是需要获取共享访问锁。如果是访问别的库则不会卡住。比如当前的集群有两个库一个a库一个b库,你是在a库做的vacuum full此时如果有锁冲突,访问a库可能会卡住,但是访问b库不会。
如果担心有锁冲突做vacuum full之前可以尝试使用
lock table “tablename” in access exclusive mode nowait
命令获取访问排他锁,如果失败vacuum full相应的表就会卡住。并且在4.3的版本中lock命令可以不在事务里执行,不在事务里的lock,获取锁之后就马上释放了,不会产生别的影响。可以在生产中执行。
在执行vacuum full之前建议先做reindex。
总结:lock table pg_attribute in access exclusive mode nowait失败说明有锁冲突,这个时候再vacuum full相当于在排队状态,必须等影响的进程执行完才会执行。如果不确定vacuum full是否在执行,可以观察vacuum full表的数据块来判断表是否在收缩比如pg_attribute表的数据块是1249.
那就需要在segment节点观察1249这个文件的时间戳,如果变化了说明是在收缩的。
标签:full,greenplum,VACUUM,冲突,版本,vacuum,数据库 From: https://www.cnblogs.com/xurui96/p/17086384.html