暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSQL 变成充气娃娃,怪谁?

AustinDatabases 2019-12-30
1194

周三是新年的第一天,所以周三和周五的文字调换一下,所以postgresql 高可用的文字要在周四发布,敬请见谅。


还能怪谁,谁用的怪谁呗  使用过 PostgreSQL 的对比其他的数据库,都会怕一件事,explosion.  此时的postgresql 就像一个充了气的娃娃,能将你已经预估好的数据的存储空间,完全填满,系统可能会停止运行,或者你的老板会给你在早晨 big  morning call。

当然可以谴责postgresql 的“不靠谱”,或者不如先问,是不是.......


到底是为什么会这样,(之前写过两篇文字关于vacuum可以翻翻哈),那就是MVCC,因为要结合自身,以及实现RDS数据库都有的MVCC ,在一群不大理解此事情的使用者“光顾” 后,postgresql 就变成了充气娃娃。

通过保持每行的多个版本,MVCC减少了放置在数据库行上的独占锁的数量。


我们可以来看看下面的例子,建立一个十分 清纯的表


CREATE TABLE exploded (
id SERIAL PRIMARY KEY,
x  INTEGER NOT NULL
);

然后就插入 100万条记录

INSERT INTO exploded (x) VALUES (generate_series(1,1000000));


然后我们查看这100万条记录占用了35MB 的空间



UPDATE exploded SET x = x + 1;
SELECT pg_size_pretty(pg_relation_size('exploded'));

我们可以看一下在update 后这个表变成了69MB


我们将实验继续下去, 再次update 如果按照逻辑思维,表应该继续膨胀到 100MB 左右,但实际上,没有,压根就没有变化。


到这里的捋一捋,"充气娃娃"到底什么时候充气,什么时候就不膨胀了.


先问个问题,其他的数据库为什么不会这样,例如ORACLE ,MYSQL ,事实上是这样的吗,你何曾听过POSTGRESQL 有 REDO , UNDO ,而 ORACLE ,MYSQL 都有 UNDO log 这就是不同的数据库实现 MVCC 的手法不一样,ORACLE MYSQL 是去膨胀他的UNDO LOG ,而Postgresql 是在行设计来完成部分的UNDO LOG 的功能。所以mysql 需要进行purge, postgresql 需要 vacuum.  


那到底为什么第二次不膨胀了的问题我想就很好回答了,如果你在ORACLE ,MYSQL 里面执行一个事务结束后,在执行一个事务,UNDO LOG 大部分可能性会复用空间来解决,所以POSTGRESQL 也会将不再使用的“死行”进行回收,我们也叫 vacuum. 来保证表空间不会无序大量的进行膨胀。


那问题剩下就是,怎么会导致无法vacuum(画外音,我这出事了,别讲大道理,赶紧给我解决方法) OK ,下面只说怎么和充气娃娃处


1  autovacuum 运行了吗 ?  通过查看 pg_stat_user_tables 可以看到 exploed 表 已经 autovacuum_count 两次了。



2 是否有长时间运行的语句


SELECT pid, datname, usename, state, backend_xmin,query,backend_type,query_start,client_addr

FROM pg_stat_activity

WHERE backend_xmin IS NOT NULL

ORDER BY age(backend_xmin) DESC;


3 您老人家是否开了复制槽,并且接收方已经“玩失踪了”

SELECT
slot_name, slot_type,
database
, xmin
最后修改时间:2019-12-30 09:25:53
文章转载自AustinDatabases,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论