我正在使用 PostgreSQL (8.4) 来存储由频繁插入的应用程序生成的数据(在下面描述的表结构中)。
数据库随着时间不断增长,并且由于新数据比旧数据更相关(在此特定应用程序中),删除旧行是一个合理的解决方案(基于 lowerid
或 old input_datetime
,这或多或少相同) .
为了防止与此数据库(此服务器上运行的唯一数据库)相关的问题影响系统的其余部分,我已将 PostgreSQL 数据目录放在其自己的分区上(ext3,在 Linux 系统上)。然而,当这个分区变满时,这会导致许多问题。
我正在考虑定期删除旧数据(例如DELETE FROM data_group WHERE id <= ...
通过 cron 作业)来处理这个问题。
首先,我对VACUUM
(由启用的自动真空执行)的理解是,虽然它不一定将磁盘空间归还给操作系统(就像VACUUM FULL
那样),但它仍然允许将一些新数据插入到已使用的磁盘空间(即DELETE
s 不一定会影响文件大小,但它们仍会释放 PostgreSQL 自己的数据结构中的空间)。这个对吗?(我注意到VACUUM FULL
应用程序本身存在一些问题,可能是因为它使用了锁。)
如果是这样,它似乎也SELECT pg_database_size('my_database')
反映了磁盘上使用的大小,这不一定反映可用于进一步插入的内容。有没有另一种方法来估计有多少空间可用于新插入?
此外,当为时已晚,分区被填充到 100% 时,运行此DELETE
语句会导致此错误并导致 PostgreSQL 服务崩溃:
恐慌:无法写入文件“pg_xlog/xlogtemp.7810”:设备上没有剩余空间
PostgreSQL 守护进程停止当然是一个主要问题(并且在这台机器上没有其他磁盘可以将集群移动到)。
是否有防止此类问题发生的一般策略(知道磁盘空间在给定分区内受到限制,但删除旧数据是可以接受的)?我想尽可能多地自动化这一切,而不需要root
或postgres
(或 PostgreSQL 管理员)干预。
CREATE TABLE data_group (
id SERIAL PRIMARY KEY,
name TEXT,
input_datetime TIMESTAMPTZ
);
CREATE TABLE data_item (
id SERIAL PRIMARY KEY,
group_id INTEGER NOT NULL REFERENCES data_group(id) ON DELETE CASCADE ON UPDATE CASCADE,
position INTEGER NOT NULL,
data BYTEA
);