天天看点

Greenplum的备份实践知识与原理研究

Greenplum支持行存和列存,支持堆表和AO表。

一、行存和列存的原理:

  • 行存,以行为形式组织存储,一行是一个tuple,存在一起。当需要读取某列时,需要将这列前面的所有列都进行deform,所以访问第一列和访问最后一列的成本实际上是不一样的。
  • 列存,以列为形式组织存储,每列对应一个或一批文件。读取任一列的成本是一样的,但是如果要读取多列,需要访问多个文件,访问的列越多,开销越大。

二、堆表和AO表的原理

1、堆表,实际上就是PG的堆存储,堆表的所有变更都会产生REDO,可以实现时间点恢复。但是堆表不能实现逻辑增量备份(因为表的任意一个数据块都有可能变更,不方便通过堆存储来记录位点。)。

一个事务结束时,通过clog以及REDO来实现它的可靠性。同时支持通过REDO来构建MIRROR节点实现数据冗余。

2、AO(append only)表,看名字就知道,只追加的存储,删除更新数据时,通过另一个BITMAP文件来标记被删除的行,通过bit以及偏移对齐来判定AO表上的某一行是否被删除。

事务结束时,需要调用FSYNC,记录最后一次写入对应的数据块的偏移。(并且这个数据块即使只有一条记录,下次再发起事务又会重新追加一个数据块)同时发送对应的数据块给MIRROR实现数据冗余。

因此AO表不适合小事务,因为每次事务结束都会FSYNC,同时事务结束后这个数据块即使有空余也不会被复用。(你可以测试一下,AO表单条提交的IO放大很严重)。

虽然如此,AO表非常适合OLAP场景,批量的数据写入,高压缩比,逻辑备份支持增量备份,因此每次记录备份到的偏移量即可。加上每次备份全量的BITMAP删除标记(很小)。

三、数据库提供的备份和恢复工具

1、三种工具

主要分为以下3种,具体试用方法请参考官方文档:

  • gpbackup/gprestore

应用场景:用于并行备份或恢复

文档:http://docs.greenplum.org/6-10/admin_guide/managing/backup-gpbackup.html

  • pg_dump/pg_restore

应用场景:用于非并行备份或恢复,少量数据备份

说明:pg_dumpall在内部调用pg_dump

文档:

(1) http://www.postgres.cn/docs/9.4/app-pgdump.html

(2) http://www.postgres.cn/docs/9.4/app-pg-dumpall.html

  • copy…to…/copy…from…

应用场景:用于非并行备份或恢复,多用于导出/导入数据文件,例如csv格式等

文档:http://www.postgres.cn/docs/9.4/sql-copy.html

2、备份一个表的DDL语句与恢复

  • (1) 备份

    可以使用pg_dump导出,例如:

pg_dump  -t public.t_test -s -c -f ddl_test.sql
           

其中:

-f 把输出发往指定的文件。这里的ddl_test.sql即为输出的文件名;

-t 只转储出匹配table的表(或视图、序列、外表)。 可以使用多个-t选项匹配多个表,public.t_test即为带模式名的表名;

-s 只输出对象定义(模式),不输出数据;

-c 输出命令在输出创建数据库命令之前先清理(drop)该数据库对象。

  • (2)恢复
psql -d newdb -f ddl_test.sql
           

3、gpbackup与gprestore使用

  • (1)全量备份
gpbackup --dbname studydb --backup-dir /data/gpdb/backup  --debug
           
  • (2)恢复
gprestore --timestamp 20201210145024 --backup-dir /data/gpdb/backup --debug
           

三、AO表的增量备份原理

1、AO表的增量备份与恢复

gpbackup与gprestore可以实现对AO表的增量备份功能。在使用时要实现增量恢复,必须包含与增量备份相同的–backup-dir选项以及–leaf-partition-data和–incremental选项。即:

gpbackup --dbname studydb --backup-dir /data/gpdb/backup --leaf-partition-data --incremental --debug
           
gprestore --create-db --timestamp 20201210145024 --backup-dir /data/gpdb/backup --leaf-partition-data --debug
           

以上命令的–backup-dir与–leaf-partition-data必须都相同。

2、AO表的增量备份分析

按照如下SQL语句顺执行,注意观测SELECT modcount FROM gp_toolkit.__gp_aoseg(‘test_ao’)语句的值变化:

create table "test_ao"(
"id" int,
"name" text
) with (appendonly=true) 
distributed by ("id");

SELECT modcount FROM gp_toolkit.__gp_aoseg('test_ao')    -- 查询为空

INSERT INTO "test_ao" ("id","name") values (1,'hello');  -- 插入第1条数据

SELECT modcount FROM gp_toolkit.__gp_aoseg('test_ao');   -- 为 1

INSERT INTO "test_ao" ("id","name") values (2,'test');   -- 插入第2条数据

SELECT modcount FROM gp_toolkit.__gp_aoseg('test_ao');   -- 为 2

UPDATE "test_ao" SET "name"='xxxx' where "id"='2';       -- 更新1条记录

SELECT modcount FROM gp_toolkit.__gp_aoseg('test_ao');   -- 为 3

INSERT INTO "test_ao" ("id","name") values (3,'yyyyyy'); -- 插入第3条数据

SELECT modcount FROM gp_toolkit.__gp_aoseg('test_ao');   -- 为 4

DELETE FROM "test_ao" WHERE "id"='3';                    -- 删除1条记录

SELECT modcount FROM gp_toolkit.__gp_aoseg('test_ao');   -- 为 5
           

分析可知:

(1) 当插入或修改数据时,通过gp_toolkit.__gp_aoseg查询可发现查询的数字随操作的记录数而增加。

(2) 更新数据并非真正更改记录值,而是通过将旧数据标记为删除,再插入新的数据来实现。

(3) 删除数据也会有数据记录

四、Greenplum的垃圾空间回收

Greenplum支持行储存(HEAP储存)与列(append-only)储存,对于AO存储,虽然是appendonly,但实际上GP是支持DELETE和UPDATE的,被删除或更新的行,通过BITMAP来标记删除与修改。AO存储是块级组织,当一个块内的数据大部分都被删除或更新掉时,扫描它浪费的成本实际上是很高的。而PostgreSQL是通过HOT技术以及autovacuum来避免或减少垃圾的。但是Greenplum没有自动回收的worker进程,所以需要人为的触发。接下来就分析AO表与HEAP表的问题以及如何解答,执行空间的释放有3中方法分别是:

  • 1、执行VACUUM。(当膨胀率大于gp_appendonly_compaction_threshold参数时),为共享锁。
  • 2、执行VACUUM FULL。(不管gp_appendonly_compaction_threshold参数的设置,都会回收垃圾空间。),为DDL锁,慎用这个命令,会把CPU与IO沾满。
  • 3、执行重分布。(不管gp_appendonly_compaction_threshold参数,都会回收垃圾空间。),为DDL锁。

继续阅读