VACUUM

为什么需要VACUUM

Redshift的设计是Blocks are immutable。当进行更新操作时,会写到新的block上面;当删除行时,记录并没有从磁盘上移除,只是做了个删除标记,被删除的行依然占用磁盘空间,当进行查询时依然会被扫描到。所以,这会造成磁盘空间的浪费和查询性能的降低。

DELETE 操作:
┌─────────────────────┐
│ Row 1  ✓ 有效       │
│ Row 2  ✗ 标记删除    │  ← 只是打标记,空间没释放
│ Row 3  ✓ 有效       │
│ Row 4  ✗ 标记删除    │
│ Row 5  ✓ 有效       │
└─────────────────────┘

UPDATE 操作 = DELETE + INSERT:
原行标记删除 + 末尾插入新行

Redshift可以在后台自动执行 VACUUM操作,VACCUUM命令可以恢复空间、重新进行table sort。

当系统空闲时,Redshift会自动在后台执行VACUUM;而当系统负载过高时,会暂停操作。当表进行vacuum操作时,用户依然可以进行查询操作。

最佳实践是尽可能频繁的进行VACUUM操作,以提高查询性能。当系统负载不高(例如深夜时),或者维护窗口期,可以进行vacuum操作。

VACUUM 类型

VACUUM FULL

VACUUM FULL table_name;
操作 是否执行
回收空间
重新排序
最彻底
耗时 最长

VACUUM DELETE ONLY

VACUUM DELETE ONLY table_name;
操作 是否执行
回收空间
重新排序
适用场景 只做了 DELETE,没有 INSERT

VACUUM SORT ONLY

VACUUM SORT ONLY table_name;
操作 是否执行
回收空间
重新排序
适用场景 只做了 INSERT,没有 DELETE

VACUUM REINDEX

VACUUM REINDEX table_name;
操作 是否执行
回收空间
重新排序
重建 Interleaved 索引
适用场景 Interleaved Sort Key 表专用

类型对比:

VACUUM 类型 回收空间 排序 重建 Interleaved 耗时
FULL
DELETE ONLY
SORT ONLY
REINDEX 最长

VACUUM BOOST

-- 使用全部资源加速 VACUUM(独占模式)
VACUUM BOOST table_name;

执行VACCUM的一些最佳实践:

场景 推荐操作
大量 DELETE 后 VACUUM DELETE ONLY
大量 INSERT 后 VACUUM SORT ONLY
日常维护 VACUUM FULL(或依赖自动)
Interleaved 表维护 VACUUM REINDEX(必须手动)
大表 分批或在维护窗口执行
  • 查询svv_vacuum_progress表,可以查看VACUUM的进度
  • 推荐使用BOOST模式,该模式下会给VACCUM命令分配更多的内存/磁盘资源,加快进度。但执行的时候会阻拦delete/update操作。

Deep Copy

在大表上进行vaccum操作速度非常慢。当表大于700GB时,可以考虑使用deep copy:

deep copy示例:

create table partscopy(
 ps_partkey bigint not null,
  ps_suppkey integer not null,
  ps_availqty integer not null
) diststyle even;
insert into public.partscopy( select * from parts);
drop table parts;
alter table partscopy rename to parts;

第二种方式:

create table public.partscopy (like public.parts);
insert into public.partscopy (select * from parts);
drop table parts;
alter talbe partscopy rename to parts;