Greenplum恢复系统知多少

30dec898-3855-4aba-b335-26a2fb67c0eb.jpg

了解更多Greenplum相关内容,欢迎访问Greenplum中文社区网站

《深入浅出Greenplum内核》系列直播已经顺利完结啦!全部十场的视频内容可以前往Greenplum中文社区B站频道观看相关视频,相关PPT均已上传Greenplum中文社区网站(cn.greenplum.org)的下载页面,欢迎获取!现在让我们来回顾一下完结场活动《揭秘Greenplum恢复(Recovery)系统》的精华内容。

 

揭秘Greenplum恢复(Recovery)系统

视频如和文字部分有出入,请以文字为准

 

今天我们将给大家详细解析Greenplum恢复系统。恢复系统对于一个数据库系统是必不可少的一部分。本文将围绕4个部分进行讲述,本文内容如非特殊声明,均基于Greenplum 6。

 

  • 恢复系统概述
  • 预写式日志简介
  • 单节点系统恢复
  • 分布式系统恢复

 

首先我们会对恢复系统相关概念和预写式日志进行介绍,接着会介绍单点式的恢复系统,Greenplum在这一点上与PostgreSQL很接近,但由于Greenplum是个分布式数据库系统,因此在例如两阶段恢复等地方和PostgreSQL会有不同之处。最后我们会介绍分布式系统恢复,Greenplum作为分布式数据库系统,除了单个节点的恢复,也需要保证整个集群的一致性,本文将着重介绍这一部分。

 

一、系统恢复概述

 

在现实生活中,数据库系统可能会遇到各种各样的故障。常见的故障大致可以被分为三类:

 

  1. 硬件故障。例如异常断电、磁盘访问出现故障,网卡出问题等,此时,就需要针对具体情况进行恢复。

  2. 统故障。即软件故障,这里和数据库没有太大关系,原因有多种,有可能是内核崩溃,依赖库bug等情况导致的。这一块也不是我们今天重点要介绍的内容。

  3. Postgres进程异常退出。例如OOM,bug,保护性PANIC等。这将是本文着重介绍的故障类型。在遇到这种故障时,如果是除postmaster之外的单点进程退出,整个单点Postgres会进行重启。

 

PostgreSQL和Greenplum的恢复系统都是基于WAL,即预写式日志。所谓预写式日志是指事务提交先写日志,事务引起的数据修改通常可以滞后,Greenplum的segment上事务提交时日志同步到从节点后才认为成功。一些表数据的页面修改可以稍后完成,从而保证了较好的性能。

 

在单节点上,恢复系统通常是从Checkpoint日志中redo值所代表的的位置开始重放日志。通常情况下会读取最新的checkpoint中的日志,但在某些情况下会需要读取上次的checkpoint中的日志。

 

Greenplum作为一个分布式数据库系统,需要分布式事务管理器和分布式恢复,而Master节点充当了这两个角色,保证整个集群的数据全局一致性。在数据恢复系统中某些场景下,需要进行人工干预:例如一些产品bug中,startup进程出现异常等情况,但这种场景较少见。如果出现需要人工干预的场景,商业用户可以寻求原厂的支持。

 

二、预写式日志简介

 

首先我们来看一个简单Insert的预写式日志的例子。

 

postgres=# insert into t1 select generate_series(1,10);INSERT 0 10

 

上面的Insert语句中,写入了十个tuple,被分布到各个节点上,这是一个典型的两阶段事务。我们以某一个Primary为例,以完成时间顺序看这个两阶段事务日志写入情况(下为pg_xlogdump解析日志输出结果)。

 

  • 第一个Primary节点(其余 Primary节点类似)

rmgr: Heap        len (rec/tot):     31/    63, tx:        721, lsn: 0/0C0F02A0, prev 0/0C0F0238, bkp: 0000, desc: insert: rel 1663/12812/16391; tid 0/6rmgr: Heap        len (rec/tot):     31/    63, tx:        721, lsn: 0/0C0F02E0, prev 0/0C0F02A0, bkp: 0000, desc: insert: rel 1663/12812/16391; tid 0/7rmgr: Heap        len (rec/tot):     31/    63, tx:        721, lsn: 0/0C0F0320, prev 0/0C0F02E0, bkp: 0000, desc: insert: rel 1663/12812/16391; tid 0/8rmgr: Heap        len (rec/tot):     31/    63, tx:        721, lsn: 0/0C0F0360, prev 0/0C0F0320, bkp: 0000, desc: insert: rel 1663/12812/16391; tid 0/9rmgr: Heap        len (rec/tot):     31/    63, tx:        721, lsn: 0/0C0F03A0, prev 0/0C0F0360, bkp: 0000, desc: insert: rel 1663/12812/16391; tid 0/10rmgr: Transaction len (rec/tot):    376/   408, tx:        721, lsn: 0/0C0F03E0, prev 0/0C0F03A0, bkp: 0000, desc: prepare

 

  • Master节点

rmgr: Transaction len (rec/tot):     84/   116, tx:          0, lsn: 0/0C0FC9C8, prev 0/0C0FC988, bkp: 0000, desc: distributed commit 2021-01-12 16:29:12.085955 CST gid = 4129264608-0000032766 gid = 1610432654-0000000012, gxid = 12

 

  • 第一个Primary节点(其余priamry节点类似)

rmgr: Transaction len (rec/tot):     72/   104, tx:          0, lsn: 0/0C0F0578, prev 0/0C0F03E0, bkp: 0000, desc: commit prepared 721: 2021-01-12 16:29:12.086621 CST gid = 139787424-0000000000 gid = 1610432654-0000000012 gxid = 12

 

  • Master 节点

rmgr: Transaction len (rec/tot):     28/    60, tx:          0, lsn: 0/0C0FCA40, prev 0/0C0FC9C8, bkp: 0000, desc: distributed forget  gid = 1610432654-0000000012, gxid = 12

 

两阶段事务的参与者prepare后,协调器会发commit prepare给所有的节点。Master的节点接收到所有节点的prepare信息后,如果其中一个节点prepare不成功,就会给所有的节点发prepare回滚的指令。如果所有的节点prepare成功,Master会在本地写一个distributed commit日志,所有的primary节点才会发起两阶段提交,因此在上面的例子中,我们会看到 Primary节点上会有一个commit prepared的日志。最后master节点上会写一个distributed forget的日志

 

虽然整个流程较为简单,但有很多细节需要考量。这里我们可以思考三个问题:

 

问题1:为什么master先做distributed commit再发起segment上两阶段提交?

问题2

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值