个人博客

解决使用timescaledb的PostgreSQL内存不足问题(4.0)

01 09月
作者:西洪室|分类:技术

这边文章是zabbix社区里的问题解答,具体链接地址已经忘记了,现在将文章翻译(机器翻译+人工校验)成中文写下


PostgreSQL问题并未针对更新具有多个分区的表进行优化。
当Zabbix开始使用TimescaleDB时,1天的趋势间隔(这意味着分区的数量可能达到数百个)是最优的。
对于只有插入的表来说,这不是问题。但是,trends和trends_uint表确实每小时更新一次。这些更新可能会覆盖数以千计的条目,并导致PostgreSQL运行我们的内存和崩溃。
这个问题的自然解决方案是限制系统上用于trends和trends_uint表的分区数量。
Zabbix的新版本通过在更新的数据库设置脚本(timescaledb.sql)中设置一个大得多(1个月)的时间间隔块来实现这一点。
但是,已经将TimescaleDB配置为使用旧间隔(1天(或86400秒))的用户可能希望升级trends和trends_uint表。
快速的解决方案是运行以下程序:
SELECT set_chunk_time_interval('trends', 2628000);
SELECT set_chunk_time_interval('trends_uint', 2628000);
不幸的是,这不会影响将保留在系统中的现有数据块,直到管家将其删除(默认情况下为1年)。
大型数据库的正确升级可能需要一些时间,其中涉及将现有的历史1天数据块转换为1个月数据块:
1)将alter table trends rename to trends_old;
2)从database / postgresql / schema.sql中找到趋势创建命令,然后在psql中运行它-对于我的Zabbix版本,它看起来像以下内容(您可能略有不同):
CREATE TABLE trends (
        itemid                   bigint                                    NOT NULL,
        clock                    integer         DEFAULT '0'               NOT NULL,
        num                      integer         DEFAULT '0'               NOT NULL,
        value_min                DOUBLE PRECISION DEFAULT '0.0000'          NOT NULL,
        value_avg                DOUBLE PRECISION DEFAULT '0.0000'          NOT NULL,
        value_max                DOUBLE PRECISION DEFAULT '0.0000'          NOT NULL,
        PRIMARY KEY (itemid,clock)
);
3)将其设置为超表,每隔1个月更新一次:
SELECT create_hypertable('trends', 'clock', chunk_time_interval => 2628000, migrate_data => true);
4)移动数据:
INSERT INTO trends(itemid, clock, num, value_min, value_avg, value_max)
SELECT * FROM trends_old
ON CONFLICT DO NOTHING;
5)检查新趋势表是否包含数据,并且看起来合理:
select count(*) from trends;
6)检查系统上生成的块数:
SELECT * FROM chunk_relation_size_pretty('trends');
应该在1到12之间。(如果您运行时间量程超过一年,而运行管家的时间没有超过一年,则可能会更多)
7)  如果一切正常-删除临时表:
drop table trends_old;
对trends_uint表重复所有这些步骤
1)将alter table trends_uint rename to trends_uint_old;
CREATE TABLE trends_uint (
    itemid                   bigint                                    NOT NULL,
    clock                    integer         DEFAULT '0'               NOT NULL,
    num                      integer         DEFAULT '0'               NOT NULL,
    value_min                numeric(20)     DEFAULT '0'               NOT NULL,
    value_avg                numeric(20)     DEFAULT '0'               NOT NULL,
    value_max                numeric(20)     DEFAULT '0'               NOT NULL,
    PRIMARY KEY (itemid,clock)
);
3)将其设置为超表,每隔1个月更新一次:
SELECT create_hypertable('trends_uint', 'clock', chunk_time_interval => 2628000, migrate_data => true);
4)移动数据:
INSERT INTO trends_uint(itemid, clock, num, value_min, value_avg, value_max)
SELECT * FROM trends_uint_old
ON CONFLICT DO NOTHING;
5)检查新趋势表是否包含数据,并且看起来合理:
select count(*) from trends_uint;
6)检查系统上生成的块数:
SELECT * FROM chunk_relation_size_pretty('trends_uint');
应该在1到12之间。(如果您运行时间量程超过一年,而运行管家的时间没有超过一年,则可能会更多)
7)如果一切正常-删除临时表:
drop table trends_uint_old;
这应该足以应付大多数用例。 但是,如果问题仍然存在(对于RAM量较少的系统,如果进行非常大的更新可能会发生),最好的选择是停止对趋势表和Trends_uint表使用TimescaleDB(或分区的PostgreSQL):
运行与之前相同的命令,但没有“ create_hypertable…”行,但
确保
SELECT * FROM chunk_relation_size_pretty('trends');
不再返回块信息。


浏览279 评论0
返回
目录
返回
首页
zabbix对服务器接入IP流量监控 杂粮粥

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。