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 条评论
登录 后参与评论

相关文章

来自专栏Java架构

拜托,别再问怎么深入学习分布式架构了!总结

由于分布式系统所涉及到的领域众多,知识庞杂,很多新人在最初往往找不到头绪,不知道从何处下手来一步步学习分布式架构。

492
来自专栏CSDN技术头条

微博宕机背后,高并发有哪些常见问题?

上周,赵丽颖、冯绍峰结婚官宣造成微博宕机,那么回归技术,面对如此大的高并发流量和屡次崩溃的系统,作为程序员是否有较好的方法来应对及解决?在此,技术专家丁浪为我们...

741
来自专栏廖可知的专栏

基于Redis的低成本高可用排行榜服务构建

业务运营活动中排行榜的使用很广泛,因此在三年前组内已经将排行榜服务组件化。整个服务是基于Redis的zset数据结构实现的。

2485
来自专栏全华班

springcloud学习手册-Eureka(第一节)

导读 |Springcloud Eureka 服务治理 一、服务治理:Springcloud Eureka Eureka是springcloud Netfli...

3736
来自专栏CodingToDie

分布式事务解决方案

Spring Cloud 分布式事务管理 在微服务如火如荼的情况下,越来越多的项目开始尝试改造成微服务架构,微服务即带来了项目开发的方便性,又提高了运维难度以及...

4144
来自专栏杨建荣的学习笔记

MySQL备份恢复的自动化设计

MySQL的备份恢复是一直想要改进的地方,其中恢复是重中之重,这部分的工作要做成平台化的工作,算是有了前期的很多铺垫和延迟,最近在和同事的共同协作下,总算有了一...

1344
来自专栏SDNLAB

ONOS预热篇之开放分布式SDN操作系统(三)

关于构建ONOS(开放式网络操作系统)的项目专题,是通过性能激发创建的实验性分布式SDN控制平台,满足大型运营商网络的可扩展性、可用性需求。提出了2个版本的ON...

3465
来自专栏java架构技术

高并发场景下的缓存有哪些常见的问题?

当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。

1555
来自专栏Java架构师学习

拜托,别再问怎么深入学习分布式架构了!负载均衡分布式缓存分布式文件系统分布式RPC分布式数据库分布式消息中间件分布式session问题总结

由于分布式系统所涉及到的领域众多,知识庞杂,很多新人在最初往往找不到头绪,不知道从何处下手来一步步学习分布式架构。

502
来自专栏杨建荣的学习笔记

mysql pump和mysql dump的性能大比拼(r12笔记第90天)

昨天测试了一下mysqlpump,今天来把剩下的补充完成,算是一个小的系列。 mysqlpump 在MySQL 5.7中做逻辑备份恢复有了一个新的工具my...

3347

扫码关注云+社区