Greeplum 系列(六) 备份与恢复
http://www.dbdream.com.cn/category/greenplum/
先介绍几个命令查看 Greenplum 集群状态:
# 1. 查看所有 gp 节点状态
select * from gp_segment_configuration;
# 2. 查看 gp 正在执行那些 sql
select * from * from pg_stat_activity;
# 3. 查看 gp 节点状态,4.3之前是 gpstate -m
gpstate -s;
一、 Segment 节点恢复
1.1 备份原理
在 Greenplum4.X 版本中,主备之间的同步是基于文件级复制做的,在这种情况下,如果系统中有一个节点挂掉了,那么系统仍然可以继续运行,等到失败节点恢复的时侯,再根据主备之间的文件差异来同步数据。
在正常情况下, Primary Segment 中发生的变更都会体现数据文件的变化,同步进程监控到此变化,就会记录文件的同步状态,并且将文件变化数据块发送到 Mirror 节点中。除非 Primary 发生故障,否则 Mirror 会一直处于非活动状态,如图 6-1 所示。
当 Mirror 失败时, Primary 会记录下此阶段所有发生变更的文件数据块,等到 Mirror 节点恢复后开始同步。当 Primary 失败时, Mirror 节点会自动唤醒代替 Primary,此时两者的角色会发生变,系统状态会变为修改跟踪(Change Tracking)模式。待 Primary 恢复后,Primary 变成 Mirror 节点,并将这段时间的所有文件同步恢复。
1.2 失败节点恢复
在 Greenplum 中,提供了 gprecoverseg 脚本用于对失败的 Segment 节点进行恢复。 有增量恢复和全量恢复两种方式,所谓的全量恢复就是把失败的 Segment 节点的数据目录全部删除,再从其它节点完整的拷贝一份新的数据过来,而增量恢复只会拷贝新增的数据。
gprecoverseg 脚本会检查 Primary 与 Mirror 之间的文件差异,操作会导致整个数据库卡住,无法执行命令,如果文件比较多,这一步会耗时比较久文件差异比完之后, gprecoverseg 脚本就退出了,但这个时候,数据还没有完全同步成功,数据会在后台进行同步,同步状态会被修改成 Resynchronizing,同步完成后同步状态为 Synchronized。在同步的过程中,可以通过 gestate -m 命令査看同步的进度。
(1) 恢复所有失效的节点(增量恢复)
gprecoverseg
(2) 还原所有的 Segment 角色
首先,执行这一步之前必须确认所有的 Segment 都是 Synchronized 状态的:
# 查询结果为 0 时说明所有的节点都处于同步状态
select count(1) from gp_segment_configuration where status='d' or mode<>'s';
等待数据全部同步気成之后,运行恢复命令:
gprecoverseg -r
当然,重启数据库(gpstop -afr)也可以达到同样的效果。
(3) 全量恢复
有时候 Segment 被破坏,可能导致增量同步失败,这个时候只能采用全量同步。在进行全量同步的时候,应该使用 gprecoverseg 先将能增量恢复的节点先恢复了,然后再开始全量恢复,减少全量恢复的数据量。
gprecoverseg -F
Greenplum4.3 可以用 gpstate -s 查看节点状态,之前的版本用 gpstate -m。
二、 Greenplum Master 备份策略
(1) 添加 Standby Master
# 如果 $MASTER_DATA_DIRECTORY 节点已经存在(如 Master 节点恢复正常),要先删除该文件空间
gpinitstandby -s smdw
在 gpinitstandby 初始化的过程中, Greenplum 会先用 gpstop -a 停止数据库,然后使用 utility 模式启动 Master,在数据字典(gp_segment_configuration)中增加 Standby Maste r的配置,关闭 Master。接着将攵件系统中的数据从 Master 上复制到 Standby Master 上,最后重新启动数据库即可。
(2) 删除 Standby Master
gpinitstandby -r
(3) 同步 Standby Master
gpinitstandby -n
(4) 激活 Standby Master
先模拟 Master 挂掉的情况,也可以直接将 Master 关机
gpstop -m
激活 Standby Master
gpactivatestandby -d $MASTER_DATA_DIRECTORY
注意:在执行 gpactivatestandby 命令之前要在 .bashrc 中添加如下配置:
source /usr/local/greenplum-db/greenplum_path.sh
export MASTER_DATA_DIRECTORY=/data/master/gpseg-1
export PGPORT=543
(5) 重新激活 Master
执行 gpactivatestandby 后,查看 gp_segment_configuration 发布 mdw 节点已经不存在了,所以要重新激活 Master 要重复 1-4 步。
三、数据备份与恢复
3.1 备份
3.1.2 并行备份(gp_dump)
GP 同时备份 Master 和所有活动的 Segment 实例,备份消耗的时间与系统中实例的数量没有关系。在 Master 主机上备份所有 DDL 文件和 GP 相关的数据字典表,每个 Segment 备份各自的数据。所有备份文件组成一个完整的备份集合,通过唯一 14 位数字的时间戳来识别。
gp_dump dbname;
gp_dump 命令将在数据目录(如 /data/master/gpseg-1)生成如下的备份文件:
-- 在 Master 主机上
gp_catalog_1_<dbid>_<timestamp> -- 数据字典表
gp_cdatabase_1_<dbid>_<timestamp> -- 创建数据库 SQL 语句
gp_dump_1_<dbid>_<timestamp> -- 创建 schema SQL 语句
gp_dump_1_<dbid>_<timestamp>_post_data -- 创建 Table SQL 语句
-- 在 Segment 主机上
gp_dump_0_ <dbid>_<timestamp> -- 用户数据文件
gp_dump_status_0_ <dbid>_<timestamp> -- 日志文件
3.1.2 并行备份(gpcrondump)
gpcrondump -x dbname -- -x 指定数据库
在 Master 和 Segment 的数据目录创建备份文件:
-- Segment 数据的备份使用 gzip 压缩格式
<data_directory>/db_dumps/YYYYMMDD
使用 CRON 调度备份操作,定义一个调用 gpcrondump 的 crontab 条目。
-- 例如,在午夜1点备份 dbname 数据库
0 1 0 * * * gpadmin source $GPHOME/greenplum_path.sh;
gpcrondump –x dbname –c –g –G –a –q >> gp_dbnamedump.log;
-- 创建一个名为 mail_contacts 的文件放置在 GP SUPERUSER 的根目录。
vi /home/gpadmin/mail_contacts
-- mail_contacts 放入邮件地址
dba@company.com
3.1.3 非并行备份(pg_dump)
GP 依然支持常规的 PostgreSQL 备份命令 pg_dump 和 pg_dumpall,备份将在 Master 主机上创建一个包含所有 Segment 数据的大的备份文件。因此, 不适合于全部数据备份,适用于小部分数据的迁移或备份。
[gpadmin@mdw ~]$ pg_dump dbname > dbname.sql; -- 导出 SQL 脚本文件
pg_dump –Ft –gp-syntax dbname > dbname.tar; -- 导出包含分布键信息的 tar 文件
pg_dump –Fc dbname > dbname.dump; -- 导出到定制格式的归档文件
pg_dump –t tb_cp_02 dbname > tb_cp_02_dbname.sql; -- 导出单个表
pg_dump –t '"MixedTableName"' dbname > tab_dbname.sql; -- 导出混合大小写名称的表
pg_dumpall > all.dump; -- 集群备份
3.2 恢复
在决定使用恢复程序时,需确定以下几个问题:
-
备份文件在哪里?
如果备份文件位于 gp_dump 生成的原始位置,可以简单的通过 gp_restore 命令恢复;如果备份文件已经移除 GP 集群,使用 gpdbrestore 来恢复。 gp_restore、gpdbrestore 恢复的前提是 greenplum 仍正常运行。
-
是否需要恢复整个系统,还是只恢复数据?
如果 GP 仍在运行并仅需要恢复数据,使用 gp_restore 或 gpdbrestore 命令来恢复;如果丢失了整个集群或者需要从备份来重建整个集群,使用 gpinitsystem 命令
-
是否恢复的系统与备份时的系统具有相同数量的 Instance?
如果相同,使用 gp_restore 或 gpdbrestore 命令来恢复; 如果是在不同集群间迁移,必须使用非并行恢复。
3.2.1 并行恢复(gp_restore)(?????)
通过 gp_dump 产生的时间戳来辨识备份集合,恢复数据库对象和数据到分布式数据库中,每个 Segment 并行恢复各自的数据。被恢复的 GP 系统必须与备份的系统同构,否则只能使用串行恢复。
如果在备份时使用了参数:-s(仅模式),-a(仅数据),--gp-c(压缩),--gp-d(修改备份文件目录),那么在恢复时也要指定这些参数。
恢复数据库
createdb dbname;
-- 在Master主机,运行gp_restore命令(--gp-k 指定备份操作时间戳标识符,-d 指定恢复的数据库)
gp_restore –-gp-k=20131231001327 –d dbname;
gp_restore 命令将执行如下操作
(1) 在 Master 主机上
- 运行由 gp_dump 生成的 gp_dump_1_
_ 文件中 SQL DDL 命令,重建数据库的模式和对象; - 在 Master 数据目录生成日志文件,日志文件的名称为:gp_restore_status_1_
_ - gp_restore 在每个需要恢复的 Instance 上启动一个名为 gp_restore_agent 的程序,gp_restore_agent 进程在 Segment 主机上运行并向 Master 主机上的 gp_restore 进程报告状态
(2) 在 Segment 主机上
- 每个 Instance 使用 gp_dump 生成的 gp_dump_1
文件来恢复用户数据 - 每个 Instance 生成一个日志文件,名字为:gp_restore_status_1_
_
2.2 并行恢复(gpdbrestore)(?????)
gpdbrestore 命令是对 gp_restore 命令的包装,提供更灵活的选项,使用 gpcrondump 备份生成的备份文件来进行恢复。
createdb dbname -- 创建需要被恢复的数据库
-- 指定备份文件目录
gpdbrestore –b 20131231
-- 在 Master 主机上执行 gpdbrestore 命令(-R 指定备份文件所在的主机名和路径)
gpdbrestore –R archive_host:/gpdb/backups/archive/20131231
3.2.3 非并行恢复(pg_restore)
使用由 pg_dump 或 pg_dumpall 创建的备份文件来恢复,使用非并行恢复可以实现异构系统恢复。
-- 使用 pg_restore 或 psql 进行恢复
pg_restore –d dbname dbname.dump;
psql -d dbname –f tb_cp_02_dbname.sql;
3.2.4 非并行恢复异构系统
确保具备了全部的备份文件,包括 Master 和每一个 Segment 的文件,所有的文件具有相同的时间戳标识符
-- 1. 创建需要恢复的数据库
createdb dbname;
-- 2. 装载 Master 备份文件以恢复数据库对象
psql -d dbname -f /data/backups/gp_dump_1_1_20131231001327;
-- 3. 装载每个 Segment 的备份文件以恢复数据
psql –d dbname -f /data/backups/gp_dump_0_2_20131231001327;
psql –d dbname -f /data/backups/gp_dump_0_3_20131231001327;
-- 4. 恢复 Table 相关的对象,比如索引、触发器、主键约束等
psql –d dbname -f /data/backups/gp_dump_1_1_20131231001327_post_data;
来自《Greenplum企业应用实战》12 章 P287。
每天用心记录一点点。内容也许不重要,但习惯很重要!