PostgreSQL 表数据膨胀之痛

数据库 PostgreSQL
对于很多企业级客户来说,流行的开源数据库总会存在这样那样的一些“毛病”。虽然开源社区总会不断地进行改进,而这些问题往往都很难以根本解决。

表数据更新场景: 用例

下面我们在 PostgreSQL 的数据库中,创建一个表,插入一些数据,并对表数据进行更新操作,查看表占用的存储空间在更新前后是否会发生变化。

CREATE TABLE t_large (id integer, name text);
CREATE INDEX large_idx ON t_large (id);

INSERT INTO t_large (id, name)
    SELECT i, 'xxx' FROM generate_series(1, 1000000) AS s(i);

SELECT pg_size_pretty(pg_table_size('t_large'));
 pg_size_pretty
----------------
 35 MB

UPDATE t_large SET id = id + 1;
UPDATE t_large SET name = 'yyy';

SELECT pg_size_pretty(pg_table_size('t_large’));
 pg_size_pretty
----------------
 104 MB

表数据更新场景: 内部原理

下面是我们在 PostgreSQL 中进行表更新时,单个页面内数据记录发生的变化:

1. 单条数据会有多个版本。

2. 每个事务都有一个事务 ID,它有点像数据库系统的运行时间。

3. 每行都有两个默认的隐藏属性 xmin 和 xmax,这两个属性分别保存了创建和更改它们的事务 ID。

表数据更新场景: 思考

问题影响

1. 数据更新需要占用原来 2 倍的磁盘空间。

2. 增加了垃圾数据清理和空间回收的工作量。

3. 基于索引扫描和全表扫描的查询性能都会受到影响。

应对方案

1. 调整垃圾清理的调度策略,如触发条件、清理节奏、并行度。

2. 调整表结构,将经常更新的列移动到单独的表中。

3. 合并更新,将多次更新合并成单次更新。

Redrock Postgres 的解决方案

Redrock Postgres 引入了撤消日志,修改元组时会标记删除索引记录,实现了就地更新。另外,在执行删除或非就地更新的事务提交后,会立即重用空间。因而在更新表数据后,并不会占用更多的存储空间。

下面我们在 Redrock Postgres 的数据库中,创建和上面相同的表,并插入同样的数据,对表数据进行更新操作,查看表占用的存储空间在更新前后是否会发生变化。

CREATE TABLE t_large (id integer, name text);
CREATE INDEX large_idx ON t_large (id);

INSERT INTO t_large (id, name)
  SELECT i, 'xxx' FROM generate_series(1, 1000000) AS s(i);

SELECT pg_size_pretty(pg_table_size('t_large'));
 pg_size_pretty
----------------
 19 MB

UPDATE t_large SET id = id + 1;
UPDATE t_large SET name = 'yyy';

SELECT pg_size_pretty(pg_table_size('t_large'));
 pg_size_pretty
----------------
 19 MB

从上面的测试结果来看,在我们对表t_large进行全表更新完后,该表占用的存储空间没有发生变化。

责任编辑:武晓燕 来源: 红石PG
相关推荐

2024-10-16 10:26:10

2014-04-08 09:49:27

PostgreSQL双缓冲

2013-06-04 09:46:17

联调开发团队

2013-03-26 11:20:05

创业创业者创业失败

2017-11-01 22:34:03

数据中心供电系统UPS

2022-12-26 08:07:03

MySQL批量数据

2021-08-03 07:40:46

Synchronize锁膨胀性能

2018-08-06 06:57:49

物联网IOT物联网设备

2014-09-22 15:33:54

2009-07-22 15:47:05

软件质量管理

2022-10-30 15:16:16

DML语句元组

2020-12-25 10:40:42

MySQL数据分析数据库

2020-06-09 10:15:38

Javasynchronize代码

2021-05-17 12:12:49

数据库架构分离

2018-11-13 14:41:35

溯源区块链商场

2018-08-06 15:41:49

2024-03-04 09:29:57

PostgreSQL数据库RDBMS

2011-08-23 10:54:16

PostgreSQL表空间用户

2017-08-30 16:59:54

PostgreSQL分区表

2013-04-03 09:35:02

应用集成云集成集成服务
点赞
收藏

51CTO技术栈公众号