HAWQ技术解析(十五) —— 备份恢复

一、为什么还需要备份

        HAWQ作为一个数据库管理系统,备份与恢复是其必备功能之一。HAWQ的用户数据存储在HDFS上,系统表存储在master节点主机本地。HDFS上的每个数据块缺省自带三份副本,而且一个数据块的三份副本不会存储在同一个DataNode上,因此一个DataNode节点失效不会造成数据丢失。而配置了HDFS NameNode HA与HAWQ master HA后,NameNode和master的单点故障问题也得到了解决。似乎HAWQ没有提供额外备份功能的必要。

        事实上,Hadoop集群上存储和处理的数据量通常非常大,大到要想做全备份,在时间与空间消耗上都是不可接受的。这也就是HDFS的数据块自带副本容错的主要原因。那么说到HAWQ在数据库中提供了数据备份功能,个人认为有三方面原因:一是自然地从PostgreSQL继承,本身就带备份功能;二是提供了一种少量数据迁移的简便方法,比如把一个小表从生产环境迁移到到测试环境;三是处理人为误操作引起的数据问题,例如误删除一个表时,就可以使用备份进行恢复,将数据丢失最小化。

二、备份方法

        HAWQ提供以下三个应用程序帮助用户备份数据:

  • gpfdist
  • PXF
  • pg_dump

        gpfdist与PXF是并行数据装载/卸载工具,能提供最佳性能。pg_dump是一个从PostgreSQL继承的非并行应用。除此之外,有些情况下还需要从ETL过程备份原始数据。用户可以根据自己的实际场景选择适当的备份/恢复方法。

1. gpfdist和PXF

        用户可以在HAWQ中使用gpfdist或PXF执行并行备份,将数据卸载到外部表中。备份文件可以存储在本地文件系统或HDFS上。恢复表的过程就是简单将数据从外部表装载回数据库。

(1)备份步骤

        执行以下步骤并行备份:

  1. 检查数据库大小,确认文件系统有足够的空间保存备份文件。
  2. 使用pg_dump应用程序导出源数据库的schema。
  3. 在目标数据库中,为每个需要备份的表创建一个可写的外部表。
  4. 向新创建的外部表中装载表数据。

注意:将所有表的insert语句放在一个单独的事务中,以避免因在备份期间执行任何更新操作而产生问题。

(2)恢复步骤

        执行以下步骤从备份还原:

  1. 创建一个数据库用于恢复。
  2. 从schema文件(在pg_dump过程中被创建)重建schema。
  3. 为数据库中的每个表建立一个可读的外部表。
  4. 从外部表向实际的表中导入数据。
  5. 装载完成后,运行ANALYZE命令,保证基于最新的表统计信息生成优化的查询计划。

(3)gpfdist与PXF的区别

        gpfdist与PXF的区别体现在以下方面:

  • gpfdist在本地文件系统存储备份文件,PXF将文件存储在HDFS上。
  • gpfdist只支持平面文本格式,PXF还支持如AVRO的二进制格式,以及用户自定义的格式。
  • gpfdist不支持生成压缩文件,PXF支持压缩,用户可以在Hadoop中指定使用的压缩算法,如org.apache.hadoop.io.compress.GzipCodec。
  • gpfdist和PXF都提供快速装载性能,但gpfdist要比PXF快得多。

2. pg_dump与pg_restore

        HAWQ支持PostgreSQL的备份与还原应用程序,pg_dump和pg_restore。pg_dump应用在master节点所在主机上创建一个单一的dump文件,包含所有注册segment的数据。pg_restore从pg_dump创建的备份中还原一个HAWQ数据库。大多数情况下,整库备份/还原是不切实际的,因为在master节点上没有足够的磁盘空间存储整个分布式数据库的单个备份文件。HAWQ支持这些应用的主要目的是用于从PostgreSQL向HAWQ迁移数据。下面是一些pg_dump用法的简单示例。

        为数据库mytest创建一个备份,导出数据文件格式为tar:

$ pg_dump -Ft -f mytest.tar mytest

        使用自定义格式创建一个压缩的备份,并且压缩级别为3:

$ pg_dump -Fc -Z3 -f mytest.dump mytest

        使用pg_restore从备份还原:

$ pg_restore -d new_db mytest.dump

3. 原始数据备份

        大多数情况使用gpfdist或PXF并行备份能够很好地工作。但以下两种情况不能执行并行备份与还原操作:

  • 周期性增量备份。
  • 导出大量数据到外部表,原因是此过程花费的时间太长。

        在这些情况下,用户可以使用在ETL处理期间生成原始数据的备份,并装载到HAWQ。ETL程序提供了选择在本地还是HDFS存储备份文件的灵活性。

4. 备份方法对比

        表1汇总了上面讨论的四种备份方法的区别。

gpfdist

PXF

pg_dump

原始数据备份

并行执行

Yes

Yes

No

No

增量备份

No

No

No

Yes

备份文件存储位置

本地文件系统

HDFS

本地文件系统

本地文件系统, HDFS

备份文件格式

Text,CSV

Text,CSV,自定义格式

Text,Tar,自定义格式

依赖原始数据的格式

压缩

No

Yes

只支持自定义格式

可选

可伸缩性

性能

装载快速, 卸载快速

装载快速, 卸载一般

快(只拷贝文件)

表1

5. 估计空间需求

        在备份数据库前,需要确认有足够的空间存储备份文件。下面说明如何获取数据库大小和估算备份文件所需空间。

(1)使用hawq_toolkit查询需要备份的数据库大小。

gpadmin=# SELECT sodddatsize FROM hawq_toolkit.hawq_size_of_database WHERE sodddatname='db1';
 sodddatsize 
-------------
    16063436
(1 row)

        如果数据库中的表是压缩的,此查询显示压缩后的数据库大小。

(2)估算备份文件总大小

  • 如果数据库表和备份文件都是压缩的,可以使用sodddatsize作为估算值。
  • 如果数据库表是压缩的,备份文件是非压缩的,需要用sodddatsize乘以压缩率。尽管压缩率依赖于压缩算法,但一般可以使用经验值如300%进行估算。
  • 如果备份文件是压缩的,数据库表是非压缩的,需要用sodddatsize除以压缩率。

(3)得出空间需求

  • 如果使用PXF与HDFS,所需空间为:备份文件大小 * 复制因子。
  • 如果使用gpfdist,每个gpfdist实例的所需空间为:备份文件大小 / gpfdist实例个数。这是因为表数据将最终分布到所有gpfdist实例。

三、备份与恢复示例

1. gpfdist示例

        gpfdist是HAWQ的并行文件分发程序。hawq load应用程序操作gpfdist可读外部表,将外部表文件并行分发给HAWQ处理。当gpfdist用于可写外部表时,它并行接收HAWQ segment的输出流并写出到一个文件中。

        为了使用gpfdist,在要还原备份文件的主机上启动gpfdist服务器程序。可以在同一个主机或不同主机上启动多个gpfdist实例。每个gpfdist实例需要指定一个对应目录,gpfdist从该目录向可读外部表提供文件,或者创建可写外部表的输出文件。例如,如果用户有一台有两块磁盘的专门用于备份的机器,则可以启动两个gpfdist实例,每个实例使用使用一块磁盘,如图1所示:

图1

        也可以在每个segment主机上运行gpfdist实例,如图2所示。在备份期间,表数据将最终分布于所有在CREATE EXTERNAL TABLE定义的LOCATION子句中指定的gpfdist实例。

图2

(1)使用gpfdist备份

        使用gpfdist备份mytest数据库:

1.创建备份位置,并启动gpfdist实例。在hdp4上启动一个gpfdist实例,端口号为8081,外部数据目录是/home/gpadmin/mytest_20170223。

gpfdist -d /home/gpadmin/mytest_20170223 -p 8081 &

# 如果碰到“cannot open shared object file: No such file or directory”类似的错误,需要先安装响应的依赖包,如:

gpfdist: error while loading shared libraries: libapr-1.so.0: cannot open shared object file: No such file or directory yum install apr 
gpfdist: error while loading shared libraries: libyaml-0.so.2: cannot open shared object file: No such file or directory yum install libyaml

2.保存mytest数据库的schema。在HAWQ master节点所在主机,使用pg_dump应用程序,将mytest数据库的schema保存到文件mytest.schema。将schema文件拷贝到备份目录,用于以后还原数据库schema。

pg_dump --schema-only -f mytest.schema mytest 
scp mytest.schema hdp4:/home/gpadmin/mytest_20170223

3.为数据库中的每个表创建一个可写的外部表。在LOCATION子句中指定gpfdist实例。本例使用CSV文本格式,但也可以选择其它固定分隔符的文本格式。

psql mytest 
mytest=# create writable external table wext_base_table (like base_table) 
mytest=# location('gpfdist://hdp4:8081/base_table.csv') format 'csv';
 mytest=# create writable external table wext_t (like t) 
mytest=# location('gpfdist://hdp4:8081/t.csv') format 'csv';

4.向外部表卸载数据。所有外部表的数据插入在一个事务中进行。

mytest=# begin; 
mytest=# insert into wext_base_table select * from base_table;
 mytest=# insert into wext_t select * from t; 
mytest=# commit;

5.(可选)停止gpfdist服务,为其它进程释放端口。下面的命令查找gpfdist进程号并杀掉该进程。

ps -efww|grep gpfdist|grep -v grep|cut -c 9-15|xargs kill -9

(2)从gpfdist备份还原

1.如果gpfdist没运行则启动gpfdist实例。下面的命令在hdp4上启动一个gpfdist实例。

gpfdist -d /home/gpadmin/mytest_20170223 -p 8081 &

2.创建一个新的数据库mytest2,并将mytest的schema还原到新库中。

[gpadmin@hdp3 ~]$ createdb mytest2
 [gpadmin@hdp3 ~]$ scp hdp4:/home/gpadmin/mytest_20170223/mytest.schema . 
[gpadmin@hdp3 ~]$ psql -f mytest.schema -d mytest2

3.为每个表创建可读的外部表。

[gpadmin@hdp3 ~]$ psql mytest2 
mytest2=# create external table rext_base_table (like base_table) location('gpfdist://hdp4:8081/base_table.csv') format 'csv'; 
mytest2=# create external table rext_t (like t) location('gpfdist://hdp4:8081/t.csv') format 'csv'; 
注意:这里的location子句与前面备份时创建的可写外部表相同。

4.从外部表倒回数据。

mytest2=# insert into base_table select * from rext_base_table; 
mytest2=# insert into t select * from rext_t;

5.装载数据后运行ANALYZE命令生成表的统计信息。 

mytest2=# analyze base_table; 
mytest2=# analyze t;

(3)gpfdist排错

  • 确认HAWQ集群节点对gpfdist可访问。gpfdist在运行时要被segment实例访问。因此,必须确保HAWQ segment主机可以通过网络访问gpfdist。由于gpfdist程序是一个web服务器,可以从HAWQ集群的每个主机(master或segment节点)运行类似下面的命令测试连接:
$ wget http://gpfdist_hostname:port/filenam
  • 确认CREATE EXTERNAL TABLE定义中提供了gpfdist的正确的主机名、端口号和文件名。指定的文件名和路径应该对应gpfdist提供的文件(启动gpfdist程序时使用的目录路径)。

2. PXF示例

        HAWQ Extension Framework (PXF)是一个允许HAWQ查询外部系统数据的扩展框架。

(1)使用PXF备份

        使用PXF备份mytest数据库:

1.在HDFS上建立一个用作备份的文件夹。

[root@hdp3 ~]# su - hdfs 
[hdfs@hdp3 ~]$ hdfs dfs -mkdir -p /backup/mytest-2017-02-23 
[hdfs@hdp3 ~]$ hdfs dfs -chown -R gpadmin:gpadmin /backup

2.使用pg_dump导出数据库schema,并将schema文件存储到备份文件夹中。

[gpadmin@hdp3 ~]$ pg_dump --schema-only -f mytest.schema mytest
 [gpadmin@hdp3 ~]$ hdfs dfs -copyFromLocal mytest.schema /backup/mytest-2017-02-23

3.为数据库的数据库中每个表创建一个可写的外部表。

[gpadmin@hdp3 ~]$ psql 
mytest mytest=# create writable external table wext_base_table (like base_table) 
mytest=# location('pxf://hdp1:51200/backup/mytest-2017-02-23/base_table?Profile=HdfsTextSimple&COMPRESSION_CODEC=org.apache.hadoop.io.compress.SnappyCodec') 
mytest=# format 'text';  mytest=# create writable external table wext_t (like t) 
mytest=# location('pxf://hdp1:51200/backup/mytest-2017-02-23/t?Profile=HdfsTextSimple&COMPRESSION_CODEC=org.apache.hadoop.io.compress.SnappyCodec') 
mytest=# format 'text';  
这里,所有base_table表的备份文件存储在/backup/mytest-2017-02-23/base_table文件夹中,所有t表的备份文件存储在/backup/mytest-2017-02-23/t文件夹中。外部数据文件使用snappy压缩保存到磁盘。

 4.向外部表卸载数据。

mytest=# begin;
mytest=# insert into wext_base_table select * from base_table; 
mytest=# insert into wext_t select * from t; 
mytest=# commit;  
外部表使用snappy压缩时可能遇到如下错误: 
mytest=# insert into wext_t select * from t; 
ERROR:  remote component error (500) from '172.16.1.125:51200':  type  Exception report   message   native snappy  library not available: this version of libhadoop was built without snappy support.    description   The server  encountered an internal error that prevented it from fulfilling this request.    exception    java.lang.RuntimeException: native snappy library not available: this version of libhadoop was built without  snappy support. (libchurl.c:897)  (seg0 hdp4:40000 pid=8565) (dispatcher.c:1801)  
使用下面的方法解决该问题(参考https://issues.apache.org/jira/browse/HAWQ-951): 
# 创建目录和软连接 
mkdir -p /usr/lib/hadoop/lib && cd /usr/lib/hadoop/lib && ln -s /usr/hdp/current/hadoop-client/lib/native native 
# 添加pxf-public-classpath属性 
登录ambari,在Services -> PXF -> Configs -> Advanced pxf-public-classpath中添加一行:/usr/hdp/current/hadoop-client/lib/snappy*.jar

5.(可选)改变备份文件夹的HDFS文件复制因子。缺省HDFS每个数据块复制三份以提供可靠性。根据需要,可以为备份文件降低这个数,以下命令将复制因子设置为2:

su - pxf

-bash-4.1$ hdfs dfs -setrep 2 /backup/mytest-2017-02-23

注意:这只改变已经存在的文件的备份因子,新文件仍然使用缺省的备份因子。

(2)从PXF备份还原

1.创建一个新的数据库并还原schema。

[gpadmin@hdp3 ~]$ createdb mytest3 
[gpadmin@hdp3 ~]$ hdfs dfs -copyToLocal /backup/mytest-2017-02-23/mytest.schema . 
[gpadmin@hdp3 ~]$ psql -f mytest.schema -d mytest3

2.为每个需要还原的表创建一个可读外部表。

[gpadmin@hdp3 ~]$ psql mytest3
 mytest3=# create external table rext_base_table (like base_table) 
mytest3=# location('pxf://hdp1:51200/backup/mytest-2017-02-23/base_table?Profile=HdfsTextSimple') mytest3=# format 'text';  
mytest3=# create external table rext_t (like t) 
mytest3=# location('pxf://hdp1:51200/backup/mytest-2017-02-23/t?Profile=HdfsTextSimple') 
mytest3=# format 'text';  
除了不需要指定COMPRESSION_CODEC,location子句与前面创建可写外部表的相同。PXF会自动检测压缩算法。

3.从外部表装载数据。

mytest3=# insert into base_table select * from rext_base_table; 
mytest3=# insert into t select * from rext_t;

4.导入数据后运行ANALYZE。

mytest3=# analyze base_table; 
mytest3=# analyze t;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏pangguoming

Windows下RabbitMQ安装及入门

1.Windows下安装RabbitMQ需要以下几个步骤    (1):下载erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的,...

3347
来自专栏Laoqi's Linux运维专列

df,du,磁盘分区

df命令 df命令是用来报告磁盘文件系统的使用量 #df -h           @根据磁盘的大小适当的用适当的单位去表示 Kb,Mb,Gb,Tb #df -...

3057
来自专栏吴柯的运维笔记

如何部署缓存数据库Redis ?

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings)...

2937
来自专栏用户画像

2.5.5 作业和进程的关系

进程是系统资源的使用者,系统的资源的大部分都是以进程为单位分配的。而用户使用计算机是为了实现一串相关的任务,通常把用户要求计算机完成的这一串任务成为作业。

691
来自专栏菩提树下的杨过

ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表

zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机...

5056
来自专栏爱撒谎的男孩

MyBatis入门程序

1 创建项目DAY07-MyBatis-Sample,生成web.xml,在web.xml中配置(2项),添加spring-webmvc依赖,复制Spring配...

4727
来自专栏上善若水

S004Define a SELinux domain for Service

这是因为Service ro_isn没有在SELinux的监控之下,这种情况会提示你定义一个SELinux。

923
来自专栏用户2442861的专栏

windows下mongodb安装与使用整理

3.创建文件夹d:\mongodb\data\db、d:\mongodb\data\log,分别用来安装db和日志文件,在log文件夹下创建一个日志文件Mong...

592
来自专栏数据之美

通过hiveserver远程服务构建hive web查询分析工具

(1)hive 三种启动方式及用途,本文主要关注通过hiveserver(可jdbc连接)的方式启动  1, hive  命令行模式,直接输入/hive/...

1705
来自专栏数据之美

Python RPC 远程调用脚本之 RPyC 实践

最近有个监控需求,需要远程执行集群每个节点上的脚本,并获取脚本执行结果,为了安全起见不需要账号密码登陆节点主机,要求只需要调用远程脚本模块的方法就能实现。 总结...

2686

扫码关注云+社区