GreenPlum中的Segment Mirror镜像模式及故障恢复

2023-12-26 11:24:06 浏览数 (1)

1.Segment Mirror

当Greenplum数据库高可用性被启用时,有两种类型的Segment:主Segment和镜像Segment,每个主Segment都有一个对应的镜像Segment。主Segment从Master接收请求来对该Segment的数据库做更改并且接着把那些更改复制到对应的镜像。如果主Segment变成不可用,数据库请求会被转移到镜像Segment。

Segment镜像采用了一种物理文件复制方案–主Segment上的数据文件I/O会被复制到镜像Segment,这样镜像的文件与主Segment的文件一模一样。Greenplum数据库中的数据被表示为元组,它们被打包成块。数据库表被存储在由一个或者更多块组成的磁盘文件中。对于元组的一个更改会改变其所在的块,该块接着会被写入到主Segment上的磁盘并且被通过网络复制到镜像Segment,镜像会在其文件副本中更新相应的块。

如果主Segment失效,文件复制进程会停止并且镜像Segment自动地开始作为活动的Segment实例。当前活动的镜像Segment的系统状态会变成Change Tracking,这表示在主Segment不可用期间由该镜像维护系统表以及所有被更新块的改变日志。当失效的主Segment被修复并且准备好重新回到线上后,管理员可以发起一次恢复处理并且系统进入到Resynchronization状态。恢复处理会将记录下来的更改应用到已被修复的主Segment。当恢复处理完成后,系统状态会变成Synchronized。

在主Segment状态为活动时,如果镜像Segment失效或者变成不可访问,主Segment的系统状态会变成Change Tracking,并且它会跟踪更改,当镜像被恢复时将更改应用到镜像Segment。

可以以不同的配置把镜像Segment放置在集群中的主机上,只要求同一个Segment的主实例和镜像实例在不同的主机上。每台主机必须有相同数量的主Segment和镜像Segment。

  • 默认的镜像配置是 group mirror,在这种配置下,每台主机的主Segment的镜像Segment被放置在其他的一台主机上。如果单个主机失效,其 standby 主机上的活动主Segment的数量会翻倍。
  • 另外有一种spread mirror方式,其把每台主机的镜像散布在多台主机上,这样如果任何一台主机失效,其他主机都不会有超过一个镜像被提升为活动主Segment,只有当主机数量大于每台主机上的Segment数量时才能使用spread mirror。

2.Master 镜像概述

可以在单独的主机或者同一台主机上部署Master实例的一个备份或者镜像。当主Master变得无法使用时,备份Master或者standby Master会作为一个温备提供服务。可在主Master在线时从中创建一个standby Master。

在取一个主Master实例的事务快照时,主Master会继续为用户提供服务。在取事务快照以及在standby Master上部署事务快照时,对主Master的更改也会被记录。在该快照被部署在standby Master上之后,那些更新会被部署以同步standby Master和主Master。

一旦主Master和standby Master被同步好,standby Master会通过walsender和walreceiver复制进程保持与主Master的同步。walreceiver是standby Master进程。walsender进程是主Master进程。这两个进程使用基于预写式日志(WAL)的流复制来保持主Master和standby Master同步。在WAL日志中,所有的修改都在被应用之前先写入到日志来确保任何进程内操作的数据完整性。

WAL日志对Segment镜像还不可用。

由于Master不保存用户数据,只有系统目录表被在主Master和standby Master之间同步。当这些表被更新时,更改会被自动地复制到standby Master来让它保持与主Master的同步。

如果主Master失效,复制进程会停止并且管理员可以激活standby Master。在激活standby Master的过程中,复制好的日志可以重构主Master在最后一个成功提交事务时的状态。被激活的standby Master接下来就像Greenplum数据库的Master一样工作,在standby Master初始化时指定的端口上接受连接。

3.检测失效的segment

在Greenplum数据库的Master主机上,Postgres的postmaster进程会派生一个故障探测进程ftsprobe。它有时也被称作FTS(容错服务器)进程。如果FTS失败,postmaster进程会重启它。

FTS运行在一个循环中,每两次循环之间有一个睡眠间隔。在每一次循环时,FTS会通过向Segment数据库建立一个TCP套接字连接来探测每一个主Segment数据库,连接时使用注册在gp_segment_configuration表中的主机名和端口。如果连接成功,Segment会执行一些简单的检查并且回报给FTS。这些检查包括在关键的Segment目录上执行一次stat系统调用以及检查Segment实例的内部故障。如果没有检测到问题,一个正面反馈会被发送给FTS并且不会为该Segment数据库采取行动。

如果无法建立连接或者在超时后没有收到一个回复,则会重试。如果失败的探测次数超过配置的最大次数,FTS会探测该Segment的镜像以确保它正常,然后更新gp_segment_configuration表标记主Segment为”down”,并且设置该镜像作为主Segment运行。FTS会在gp_configuration_history中更新被执行的操作。

当只有一个活动的主Segment并且相应的镜像宕机时,该主Segment会进入到”Change Tracking Mode”。在这种模式中,对该Segment的更改会被记录,这样可以同步镜像而无需把主Segment的完整数据复制给镜像Segment。

gprecoverseg工具被用来把一个宕机的镜像恢复过来。默认情况下,gprecoverseg执行一次增量恢复,把该镜像置于resync模式中,这会开始把主Segment记录的更改在镜像上进行重放。如果不能完成增量恢复,恢复会失败并且应该重新运行 “gprecoverseg -F” 来执行完全恢复。这会导致主Segment把所有的数据都复制给镜像。

在gp_segment_configuration表中,对于每个Segment可以看到”change tracking”、”resync”或者”in-sync”三种模式,还可以看到”up”或”down”两种状态。

gp_segment_configuration表还有两个列role和preferred_role。它们的值可以是表示主Segment的 p 或者表示镜像Segment的 m 。role列显示该Segment数据库的当前角色,而preferred_role显示该Segment的原始角色。在一个平衡的系统中,所有Segment的role和preferred_role都是匹配的。当它们不匹配时,就可能有台硬件主机上活动主Segment数量造成的倾斜。为了重新平衡该集群并且让所有的Segment回到它们的首选角色,可以运行 “gprecoverseg -r” 命令。

  • gp_fts_probe_threadcount 影响FTS行为的服务器配置参数集合:
  • gp_fts_probe_interval 用于探测Segment的线程数。默认:16

多长时间开始一次新的FTS循环,以秒计。例如如果设置是60并且探测循环本身需要10秒,FTS处理会睡眠50秒。如果该设置是60并且探测循环需要75秒,FTS进程睡眠0秒。默认值是60,最大值是3600。

  • gp_fts_probe_timeout 在Master和Segment之间的探测超时时长,以秒计。默认值是20,最大值是3600。
  • gp_fts_probe_retries 尝试探测一个Segment的次数。例如如果该设置是5,在第一次尝试失败后将会有4次重试。默认值:5
  • gp_log_fts FTS的日志级别。值可能是”off”、“terse”、“verbose”或者”debug”。”verbose”设置可以被用在生产环境中为排查问题提供有用的数据。”debug”设置不应该被用在生产中。默认值:“terse”
  • gp_segment_connect_timeout 允许一个镜像做出响应的最大时间(以秒计)。默认:180 除了FTS执行的故障检查之外,如果一个主Segment无法把数据发送给其镜像,它可以把该镜像的状态改成down。主Segment把数据放在队列中,并且在经过了gp_segment_connect_timeout秒后(表示一个镜像失效)导致镜像被标记为down而且主Segment进入到变更追踪模式。

4.检测方法

使用gpstate命令查看greenplum集群状态,详细可预见gpstate参数。也可以使用 “select * from gp_segment_configuration;” 命令,检查gp_segment_configuration目录表,以获得一个失效Segment的详细信息。

为失效Segment检查日志文件

日志文件可以提供信息来帮助判断一个错误的成因。每个Master和Segment实例都在其数据目录的pg_log中有它们自己的日志文件。Master的日志文件包含了大部分信息,应该总是首先检查它。

使用gplogfilter工具来检查Greenplum数据库的日志文件以获得额外的信息。要检查Segment的日志文件,使用gpssh在Segment主机上运行gplogfilter。

恢复失效的segment

针对以下几种情况,有不同的恢复方法:

在启用了镜像的情况下恢复 1.确定可以从Master主机连接到该Segment主机。例如:

代码语言:javascript复制
$ ping failed_seg_host_address

2.排查解决妨碍Master主机连接到Segment主机的问题。例如,主机可能需要被重启或者替换。 3.在主机上线并且能连接到它后,从Master主机运行gprecoverseg工具来重新激活失效的Segment实例。例如:

代码语言:javascript复制
$ gprecoverseg

4.恢复过程会启动失效的Segment并且确定需要同步的已更改文件。该过程可能会花一些时间,请等待该过程结束。在此过程中,数据库的写活动会被禁止。 5.在gprecoverseg完成后,系统会进入到Resynchronizing模式并且开始复制更改过的文件。这个过程在后台运行,而系统处于在线状态并且能够接受数据库请求。 6.当重新同步过程完成时,系统状态是Synchronized。运行gpstate工具来验证重新同步过程的状态:

代码语言:javascript复制
$ gpstate -m

让所有Segment返回到它们的首选角色

当一个主Segment宕掉后,镜像会激活并且成为主Segment。在运行gprecoverseg之后,当前活动的Segment仍是主Segment而失效的Segment变成镜像Segment。这些Segment实例并没有回到在系统初始化时为它们指定的首选角色。这意味着,如果Segment主机上的活动Segment数量超过了让系统性能最优的数量,系统可能处于一种潜在地非平衡状态。要检查非平衡的Segment并且重新平衡系统,运行:

代码语言:javascript复制
$ gpstate -e

所有Segment都必须在线并且被完全同步以重新平衡系统。在重新平衡过程中,数据库会话保持连接,但正在进行的查询会被取消并且回滚。

1.运行 gpstate 来确保所有镜像都是Synchronized。

代码语言:javascript复制
$ gpstate -m

2.如果有任何镜像处于Resynchronizing模式,等它们完成。 3.用-r选项运行gprecoverseg,让Segment回到它们的首选角色。

代码语言:javascript复制
$ gprecoverseg -r

4.在重新平衡之后,运行gpstate 来确认所有的Segment都处于它们的首选角色。

代码语言:javascript复制
$ gpstate -e

要从双重故障中恢复

在双重故障中,主Segment和它的镜像都宕掉。如果在不同的Segment主机上同时发生硬件失效,就有可能发生这种情况。如果发生双重故障,Greenplum数据库会变得不可用。要从一次双重故障中恢复:

1.重启Greenplum数据库:

代码语言:javascript复制
$ gpstop -r

2.在系统重启后,运行gprecoverseg:

代码语言:javascript复制
$ gprecoverseg

3.在gprecoverseg完成后,使用gpstate检查镜像的状态:

代码语言:javascript复制
$ gpstate -m

4.如果仍有Segment处于Change Tracking模式,运行一次完整复制恢复:

代码语言:javascript复制
$ gprecoverseg -F

如果无法恢复一台Segment主机并且损失了一个或者多个Segment,可以从备份文件中重新创建Greenplum数据库系统。

在没有启用镜像的情况下恢复

1.确定能够从Master主机连接到该Segment主机。例如:

代码语言:javascript复制
$ ping failed_seg_host_address

2.排查解决妨碍Master主机连接到Segment主机的问题。例如,主机可能需要被重新启动。 3.在主机在线之后,验证能够连接到它并且重启Greenplum数据库。例如:

代码语言:javascript复制
$ gpstop -r

4.运行gpstate工具验证所有的Segment实例都在线:

代码语言:javascript复制
$ gpstate

当一台Segment主机不可恢复时

如果一台主机是不可操作的(例如由于硬件失效导致),就需要把那些Segment恢复到备用的硬件资源上。如果启用了镜像,可以使用gprecoverseg从Segment的镜像把它恢复到另一台主机上。例如:

代码语言:javascript复制
$ gprecoverseg -i recover_config_file

其中 recover_config_file 的格式是:

代码语言:javascript复制
filespaceOrder=[filespace1_name[:filespace2_name:...]failed_host_address:
port:fselocation [recovery_host_address:port:replication_port:fselocation
[:fselocation:...]]

其中

  • failed_host_address表示失败的节点的主机内容
  • recovery_host_address表示新增的替换节点的内容,
  • fselocation表示数据存储的具体位置,精确到 “/gpseg i”

gp_segment_configuration和pg_filespace_entry系统目录表可以帮助确定当前的Segment配置,这样才能规划镜像恢复配置。例如,运行下面的查询:

代码语言:javascript复制
=# SELECT dbid, content, hostname, address, port, 
   replication_port, fselocation as datadir 
   FROM gp_segment_configuration, pg_filespace_entry 
   WHERE dbid=fsedbid 
   ORDER BY dbid;

新恢复的Segment主机必须预装好Greenplum数据库软件并且按照现有Segment主机相同的方式配置。 例如,要恢复到不同于失效主机的另一主机上且该主机没有配置(除默认的pg_system文件空间外)额外的文件空间:

代码语言:javascript复制
filespaceOrder=sdw5-2:50002:/gpdata/gpseg2 sdw9-2:50002:53002:/gpdata/gpseg2

使用 “gprecoverseg -o filename” 选项会自动生成一个recover_config_file文件的示例,可以参考该示例,自己编写recover_config_file所需的文件。

恢复过程中可以查看恢复的状态,直到节点达到同步完成(Synchronized)的状态。恢复成功后,需要使用“gprecoverseg -r” 命令恢复primary节点和mirror节点原有的功能。

恢复失效的master

如果主Master失效,日志复制会停止。使用 “gpstate -f”命令来检查后备复制的状态。 使用gpactivatestandby来激活后备Master。在激活后备Master过程中,Greenplum数据库会重构Master主机为最后一次成功提交事务时的状态。

要激活后备Master,执行以下步骤: 1.确保为系统已经配置了一个后备Master主机。 2.从正在激活的后备Master主机运行gpactivatestandby工具。例如:

代码语言:javascript复制
$ gpactivatestandby -d /data/master/gpseg-1

其中-d指定正在激活的Master主机的数据目录。

在激活后备之后,它会变成Greenplum数据库阵列中的活动或者主Master。 注意:在激活standby master期间,原master节点不能处于启动状态,否则激活会出现失败现象。

3.在该工具结束后,运行gpstate来检查状态:

代码语言:javascript复制
$ gpstate -f

最新被激活的Master的状态应该是Active。如果配置了一个新的后备主机,它的状态是Passive。在没有配置后备Master时,该命令会显示-No entries found,该消息表示没有配置后备Master实例。

4.在切换到最新的活动Master主机后,在其上运行ANALYZE。例如:

代码语言:javascript复制
$ psql dbname -c 'ANALYZE;'

5.可选:如果运行gpactivatestandby工具时没有指定一个新的后备主机,之后可使用gpinitstandby配置一个新的后备Master。应在活动Master主机上运行gpinitstandby例如:

代码语言:javascript复制
$ gpinitstandby -s new_standby_master_hostname

在恢复后还原Master镜像

在激活一台后备Master进行恢复后,该后备Master会成为主Master。如果后备Master具有和原始Master主机相同的能力和可靠性,可以继续把该实例当作主Master。

必须初始化一个新的后备Master继续提供Master的镜像,除非在激活前一个后备Master时已经这样做了。在活动的Master主机上运行gpinitstandby来配置一个新的后备Master。

可以在原来的主机上恢复主Master和后备Master。这个过程会交换主Master主机和后备Master主机的角色,只有强烈希望在恢复场景之前的相同主机上运行Master实例时才应该执行这样的处理。 在原来的主机上恢复Master和后备实例(可选)

1.确认原来的Master主机有可靠的运行条件,确保以前的失效原因已被修复。 2.在原来的Master主机上,移动或者移除数据目录 gpseg-1。这个例子把该目录移动到 backup_gpseg-1:

代码语言:javascript复制
$ mv /data/master/gpseg-1 /data/master/backup_gpseg-1

一旦后备被成功地配置,就可以移除备份目录。

3.在原来的Master主机上初始化一个后备Master。例如,从当前的Master主机(smdw)运行这个命令:

代码语言:javascript复制
$ gpinitstandby -s mdw

4.在初始化完成后,检查后备Master(mdw)的状态,用-f 选项运行gpstate来检查状态:

代码语言:javascript复制
$ gpstate -f

状态应该是In Synch。

5.在后备Master上停止Greenplum数据库的Master实例。例如:

代码语言:javascript复制
$ gpstop -m

6.从原始的Master主机mdw运行gpactivatestandby工具,该主机当前是一个后备Master。例如:

代码语言:javascript复制
$ gpactivatestandby -d $MASTER_DATA_DIRECTORY

其中-d选项指定正在激活的主机的数据目录。

7.在该工具完成后,运行gpstate来检查状态:

代码语言:javascript复制
$ gpstate -f

验证原来的主Master状态为Active。当没有配置一个后备Master时,该命令显示-No entries found并且该消息表示没有配置一个后备Master实例。

8.在后备Master主机上,移动或者移除数据目录gpseg-1。这个例子移动该目录:

代码语言:javascript复制
$ mv /data/master/gpseg-1 /data/master/backup_gpseg-1

一旦成功地配置好后备,就可以移除备份目录。

9.在原来的Master主机运行主Greenplum数据库Master之后,可以在原来的后备Master主机上初始化一个后备Master。例如:

代码语言:javascript复制
$ gpinitstandby -s smdw

可以显示Greenplum数据库系统视图pg_stat_replication中的信息。该视图列出用于Greenplum数据库Master镜像的walsender进程的信息。例如,这个命令显示walsender进程的进程ID和状态:

代码语言:javascript复制
$ psql dbname -c 'SELECT procpid, state FROM pg_stat_replication;'

参考:《greenplum数据库文档》–管理员指南–启用高可用性

0 人点赞