一、 软件讲解
1. 关于MogHA
MogHA 是云和恩墨基于 MogDB 同步异步流复制技术自研的一款保障数据库主备集群高可用的企业级软件系统
(适用于 MogDB 和openGauss 数据库)
MogHA 能够自主探测故障实现故障转移,虚拟IP自动漂移等特性,使得数据库的故障持续时间从分钟级降到秒级(RPO=0,RTO<30s),确保数据库集群的高可用服务。
2. 为什么数据库支持主备,还需要 MogHA
首先我们需要理解一下什么是高可用,高可用的目的是为了让数据库尽可能提供连续服务,以保证上层业务的稳定运行。数据库虽然支持主备库的部署结构,其目的是防止单点故障。但数据库并不提供故障检测以及自动化切换主备的功能,这也不属于数据库的处理范畴。所以需要有 MogHA 这样的一套高可用系统,来保证数据库服务的连续性。
3. 功能特性
自主发现数据库实例角色
自主故障转移
支持网络故障检测
支持磁盘故障检测
虚拟IP自动漂移
感知双主脑裂,自动选主
数据库进程和CPU绑定
HA自身进程高可用
支持单机并行部署多套 MogHA
支持 x86_64 和aarch64
4. 系统架构
![](https://cdn-mogdb.enmotech.com/docs-media/mogha/v23/overview-deploy-arch.png)
5. 支持的模式
(1) Lite 模式 (推荐)
Lite 模式,顾名思义即轻量级模式,该模式仅需在主库和一台同步备机器上启动MogHA 服务,此时 MogHA 服务可以保证这两台机器上数据库实例的高可用,当主库发生不可修复的问题或者网络隔离时,MogHA 可以自主地进行故障切换和虚拟IP漂移。
![](https://cdn-mogdb.enmotech.com/docs-media/mogha/v23/overview-lite-mote.png)
(2) Full 模式
Full模式相较于 lite 模式,需要在所有实例机器上运行 MogHA 服务,且所有的实例有由 MogHA 来自动管理,当出现主库故障时,会优先选择本机房同步备进行切换,如果本机房同步备也是故障的情况,会选择同城备机房的同步备进行切换。为了达到RPO=0,MogHA 不会选择异步备库进行切换,以防止数据丢失。该模式会在主备切换时,会自动修改数据库的复制连接及同步备列表配置。
举例:两地三中心【1主6备】
![](https://cdn-mogdb.enmotech.com/docs-media/mogha/v23/overview-full-mode.png)
二、 安装部署
1. 安装包下载
请前往[发布记录](https://docs.mogdb.io/zh/mogha/v2.3/release-notes)页面下载 mogha-2.3.0 对应平台的安装包
2. 安装包文件说明
![](https://cdn-mogdb.enmotech.com/docs-media/mogha/v23/installation-dir-tree.jpg)
3. 系统环境要求
(1) gsql, gs_ctl 免密执行
请确认服务器上用数据库安装用户登录时,执行 gsql 或gs_ctl 时无需输入密码。可以在数据库数据目录中,找到的 pg_hba.conf 认证文件,确认本地连接的校验方式为 trust。 检验方式:切换到 omm 用户下,执行下面的命令不需要输入密码即可查询到集群状态:
```s gs_ctl -D [PGDATA] query ```
(2) 数据库安装用户的 sudo 权限
由于 MogHA 需要自动挂虚拟IP的操作,内部需要通过 ifconfig 指令来操作网卡,MogHA 是通过数据库安装用户进行启动的,要想执行网卡操作就需要 sudo 权限,在安装期间脚本会检查 /etc/sudoers 配置中是否配置了运行用户的权限,如果存在就跳过配置,如果没有,会尝试自动的将 omm 用户添加到 /etc/sudoers 中,并赋予 ifconfig 的权限。
所以建议在部署 MogHA 服务之前,先检查一下/etc/sudoers 中是否成功配置了 运行用户的 sudo 权限。 配置方式参考:
```s
追加下列 1 行到文件末尾
omm ALL=(ALL) NOPASSWD: /usr/sbin/ifconfig ```
(3) MogHA通信端口互通
MogHA 需要一个固定的端口(默认为 8081,可配置,修改配置文件中的 agent_port)用于不同节点的 MogHA 之间通信,所以需确认要配置的端口可以在节点直接互相访问。
(4) 校对时间
使用 ntp 或 chronyd 校对主库和备库的时间。
4. 安装步骤
! 注意:安装过程请使用 root 用户进行操作,涉及到给数据库安装用户sudo权限以及注册系统服务。
将安装包拷贝到要部署 MogHA 的服务器上,存放位置建议选择/opt 或 /home/[USER] 下,以 omm 用户为例,存放目录为 /home/omm/,**为了便于演示,后面不再声明,默认使用该目录进行演示。**
(1) 解压缩安装包
```s cd /home/omm tar -zxf mogha-2.x.x.tar.gz ```
解压后会在当前目录下得到一个 mogha 的文件夹。
(2) 安装MogHA服务
进入 mogha 文件夹,执行安装脚本:sudo ./install.sh USER PGDATA [SERVICE_NAME](注意替换参数)
USER 是指数据库安装用户,在本例中指 omm 用户
PGDATA 是指数据库数据目录,本例中假设 MogDB 的数据目录为 /opt/mogdb/data
SERVICE_NAME [可选参数] 注册systemd 时的服务名,默认:mogha"
以下是安装过程示例(如果安装过程出错会终止后面的安装步骤):
```s
进入刚刚解压后的文件夹
cd /home/omm/mogha
执行安装脚本
sudo ./install.sh omm /opt/mogdb/data
安装过程,输出类似以下内容
[2021-10-30 14:29:36]: MogHA installation directory:/home/omm/mogha [2021-10-30 14:29:36]: runtime user:omm, user group:dbgrp [2021-10-30 14:29:36]: PGDATA=/opt/mogdb/data [2021-10-30 14:29:36]: LD_LIBRARY_PATH=/opt/mogdb/app/lib:/opt/mogdb/tool/lib:/opt/huawei/install/om/lib:/opt/huawei/install/om/script/gspylib/clib: [2021-10-30 14:29:36]: GAUSSHOME=/opt/mogdb/app [2021-10-30 14:29:36]: database port: 26000 [2021-10-30 14:29:36]: architecture:aarch64 [2021-10-30 14:29:36]: modify owner for installation dir... [2021-10-30 14:29:36]: generate mogha.service file... [2021-10-30 14:29:36]: copy mogha.service to /usr/lib/systemd/system/ [2021-10-30 14:29:36]: reload systemd [2021-10-30 14:29:37]: mogha service register successful [2021-10-30 14:29:37]: add sudo permissions to omm [2021-10-30 14:29:37]: add successful: NOPASSWD:/usr/sbin/ifconfig [2021-10-30 14:29:37]: not found node.conf in current directory, generate it node.conf generated,location:/home/omm/mogha/node.conf [2021-10-30 14:29:37]: MogHA install successful! Please edit /home/omm/mogha/node.conf first before start MogHA service!!! Manage MogHA service by systemctl command: Start service: sudo systemctl start mogha Stop service: sudo systemctl stop mogha Restart service:sudo systemctl restart mogha Uninstall MogHA service command: sudo ./uninstall.sh mogha ```
从安装脚本执行的输出结果可以大概看出安装的流程,安装成功的标志是看到输出的最后打印出了『**MogHA 安装成功!』**语句。其他情况,需根据实际情况,检查安装步骤哪里出错。
如果正常执行完安装脚本后,期间生成一个新文件:
node.conf: HA 配置文件(如已存在则不会生成),需要用户自行补充填写实例和机房信息
5. 完善node.conf 配置
执行完安装脚本后,不要立即启动 MogHA 服务,我们需要先完善一下配置文件再启动服务。
当第一次安装的时候,node.conf 是没有的,安装脚本会根据node.conf.tmpl 模板文件自动生成一份 node.conf, 得到该文件后,参考[配置文件](https://docs.mogdb.io/zh/mogha/v2.3/configuration-file)的介绍,完善您的机器和机房配置信息。
6. 管理 MogHA 服务
请确认您已经配置完成 node.conf 以后,就可以通过systemctl 指令来管理 MogHA 服务了。
如果执行安装脚本时指定了 SERVICE_NAME , 后续操作的服务名需替换为自定义的服务名。
(1) 启动服务
```s sudo systemctl start mogha ```
(2) 查看服务状态
```s sudo systemctl status mogha ● mogha.service - MogHA High Available Service Loaded: loaded (/usr/lib/systemd/system/mogha.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2021-11-18 22:48:51 CST; 5 days ago Docs: https://docs.mogdb.io/zh/mogha/v2.0/installation-and-depolyment Main PID: 193849 (mogha-2.2.3-dev) Tasks: 55 Memory: 1.5G CGroup: /system.slice/mogha.service ├─ 193849 /home/omm/mogha/mogha-2.3.0-aarch64 -c /home/omm/mogha/node.conf ├─ 193862 mogha: watchdog ├─ 193863 mogha: http-server └─ 193864 mogha: heartbeat ```
(3) 设置开机自启
```s sudo systemctl enable mogha ```
(4) 重启MogHA服务
```s sudo systemctl restart mogha ```
(3) 停止MogHA服务
```s sudo systemctl stop mogha ```
7. 卸载MogHA软件
进入安装目录,执行卸载脚本即可:
```s cd /home/omm/mogha sudo ./uninstall.sh ```
8. 日志文件
MogHA 会生成两个日志文件:
mogha_heartbeat.log
这个日志文件会存放在安装目录中,在本示例中为 /home/omm/mogha,这个日志主要记录HA的心跳日志,也是排查问题主要的优先检查的日志文件。
mogha_web.log
这个日志文件存放目录和心跳日志相同。这个日志主要记录 web api 接口的请求日志。
三、 配置文件
1. 配置文件
MogHA 配置文件会在执行 install.sh 脚本时根据模板(node.conf.tmpl)自动生成,配置文件名为:node.conf,如果安装目录中已存在 node.conf 文件,则会跳过自动生成。配置文件格式采用 ini 格式 规则编写
ini文件由节、键、值组成。
节 :[section]
参数(键=值) :name=value
注解 :注解使用分号(;)或井号()表示,在分号或井号后面的文字,直到该行结尾都全部为注解。
2. 参数的键和值
**所有的参数键均采用小写的蛇形命名规则定义,每个参数根据不同用途,可以接受布尔、字符串、整数这三种类型之一:**
布尔:值可以写 on, off, true, false, yes, no, 1, 0 (都是大小写不敏感的)
字符串:值即为字符串字面量,无需使用引号包裹
整数:直接填写数字,无需使用引号包裹
3. 基础配置项
db_port (整数)
数据库端口,用于 MogHA 连接数据库
db_user (字符串)
数据库用户,用于 MogHA 连接和操作管理数据库,默认使用安装时执行 install.sh 脚本指定的系统用户名
db_datadir (字符串)
数据库的数据目录
primary_info (字符串)
MogHA 主备元数据的存储路径,默认值为安装目录下 primary_info 文件,支持 json 和 二进制存储,通过 meta_file_type 配置
standby_info (字符串)
MogHA 备元数据的存储路径,默认值为安装目录下 standby_info 文件,支持 json 和 二进制存储,通过 meta_file_type 配置
meta_file_type(字符串)
元数据存储格式,默认 json,支持两种格式json(值为:json)和二进制(值为:bin)。
lite_mode (布尔)
是否为lite 模式,默认为 True。MogHA 通过该参数来区分
lite 模式:顾名思义,代表轻量级调度模式,lite 模式仅需要在主库和同步备库所在的服务器上启动 MogHA 服务。该模式下适用于1主1从部署结构或1主多从情况下仅在主和同步备部署MogHA的场景。
非lite 模式:该模式下,需要运维人员在 node.conf 配置文件中,配置所有期望管理的服务器信息。同时,需要在所有配置的实例机器上运行 MogHA 服务。该模式下,在主库故障需要切换时,会在zone1/zone2 (同城)机房内选择最优备库进行切换,且自动修改主备实例的 repliconninfo 配置信息。
切换时备库选择策略:
如果主机房(zone1)内有同步备,优先切换到同机房同步备;
如果同机房没有同步备,同城机房(zone2) 内有同步备,会切到同城的同步备;
agent_port (整数) MogHA节点之间通信端口,如果有防火墙,需要配置互通。默认:8081 http_req_timeout (整数) MogHA 节点间通信请求超时时间(单位:秒),默认:3 heartbeat_interval (整数) MogHA 心跳间隔(单位:秒),默认:3 primary_lost_timeout (整数)
备库确认主库丢失的探测超时时间(单位:秒),默认:10。
当备库无法 ping 通主库,但是可以 ping 通网关或者其他节点时,认为主库丢失(离线),当持续时间超过超时时间,备库就会发起故障切换,提升为主库。
primary_lonely_timeout (整数)
主库服务器上 MogHA 判断当前机器是否处于孤单(网络隔离)的超时时间(单位:秒),当无法ping 通任何其他机器时,认为当前机器网络故障。当持续时间超过超时时间,MogHA 会下掉虚拟IP(如果有),关闭当前实例。
double_primary_timeout (整数)
主库服务器上 MogHA 在每轮检测心跳期间,都会监控当前集群中是否存在另外一个主库实例。发现后,表示当前集群存在双主的异常情况。如果双主状态持续时间超过该超时时间,进入自主选主。
taskset (布尔)
是否为数据库实例进程设置 CPU 亲和性,默认:False。
当该字段设置为 True 时,会遵循如下规则进行CPU限制:
获取当前机器的CPU核数,假设为 N
当 N = 16 时,设置数据库进程可用 CPU 数为 N-4个
当 8 <= N <16时,设置数据库进程可用 CPU 数为 N-2 个
当 1 < N < 8 时,设置数据库进程可用 CPU 数为 N-1 个
当 N = 1时,不做限制
logger_format (字符串)
日志格式,默认:%(asctime)s %(levelname)s [%(filename)s:%(lineno)d]: %(message)s
更多字段请参考 python3 logging logrecord-attributes
log_dir (字符串)
日志存储目录,默认为安装目录
log_max_size (字符串)
单个日志文件最大字节数,接近该值时,将发生日志滚动。默认:512MB,支持的单位:KB, MB, GB (忽略大小写)
log_backup_count (整数)
日志留存的文件个数,默认:10
allow_ips (字符串)
允许外部可请求 MogHA 集群 HTTP API 的IP列表,英文逗号分割填写
handle_down_primary (布尔)
检测到主库进程宕机时,MogHA 是否需要处理(重启或切换),默认:True。
该参数是 primary_down_handle_method 参数生效的前提
handle_down_standby (布尔)
检测到备库进程宕机时,MogHA 是否需要拉起
primary_down_handle_method (字符串)
主库进程未启动时,MogHA 的处理方式,默认:restart。支持重启(值:restart)和切换(值:failover)
当该参数的值为 restart 时,需配置restart_strategy 参数使用。
restart_strategy (字符串)
重启实例进程最大尝试边界,格式为 最大次数/超时分钟 ,其中两个值均可限定尝试重启的终止。默认:10/3
假设该参数为 10/3 ,则表示最多尝试重启数据库10次或者重启超时时间为3分钟,任何一个条件先满足就终止尝试重启,进入故障切换。
uce_error_detection (布尔)
UCE(uncorrected error)故障感知功能,默认:True
UCE错误:数据库内核进程在收到系统内核的一些特定的 sigbus 信号错误时,比如内存坏块等,内核会进行优雅停止,将错误码写入数据库日志中后退出进程。而坏的内存块会被系统内核标记,以后就不会被再次分配给应用程序,所以当出现该错误时,直接重启数据库进程即可恢复服务。
uce_detect_max_lines (整数)
UCE错误检查时,从后向前读取数据库日志的行数,默认:200
debug_mode (布尔)
调试模式,开启后,MogHA 打印日志的级别将降为 DEBUG,输入更多运行日志。默认:False
4. 元数据库(可选)
默认无需配置
MogHA 保留元数据库存储的功能,便于第三方监控系统读取数据库集群状态。但MogHA 不依赖元数据库做逻辑判断,如果配置了该部分字段,MogHA 在运行期间会同步输出元数据信息到元数据库中。
5. 配置项
ha_name (字符串)
MogHA集群名,全局唯一,禁止两套HA集群共用一个名字
host (字符串)
元数据库的机器IP
port (整数)
元数据库连接端口
db (字符串)
元数据库数据库名
user (字符串)
元数据库连接用户名
password (字符串)
元数据库连接用户密码
connect_timeout (整数)
元数据库连接超时时间(单位:秒),默认:3
6. 机器配置
host1 到 host9 分别代表不同的数据库实例所在的机器。
下面以 host1 为例介绍参数字段,其他相同。
```s [host1] ip= heartbeat_ips= ``` ip (字符串)
机器的业务网卡IP
heartbeat_ips (字符串)
机器的心跳网卡,一般内网使用,该字段为选填项,作为业务网卡故障时,MogHA 节点间通信的候选网卡。
如果有多个心跳IP,以英文逗号分隔连接填写即可
7. 机房配置
zone1 到 zone3 分别代表主机房,同城备机房,异地机房。
下面以 zone1 为例介绍参数字段,其他相同。
```s [zone1] vip= hosts= ping_list= cascades= arping= ```
vip (字符串)
当前机房的虚拟IP,如果存在,MogHA 会自动将该虚拟挂载到本机房内主库所在的机器上,没有则留空。
hosts (字符串)
当前机房内的机器列表,值的内容为对应机器的节( section )名,多个机器以英文逗号分隔。
比如:zone1 中有 host1 机器和 host2 机器,则该字段配置为:hosts=host1,host2
ping_list (字符串)
当前机房内用户判断机器网络是否正常的仲裁节点,一般可配置为机房的网关地址。允许配置多个仲裁IP,以英文逗号分隔。
cascades (字符串)
当前机房内的级联备库机器列表,值得内容和 hosts 相同,没有则留空。
arping (字符串)
广播地址,用于上线虚拟IP后的广播,没有则留空。
四、常见问题
为什么启动MogHA服务后,通过 ps -ef|grep mogha 会看到四个进程?
MogHA是使用Python 语言进行开发的,由于Python的代码运行依赖于Python解释器和三方依赖包,为了减少部署时对于系统的过多要求,或者避免对于网络的依赖,MogHA 在发包的时候,采用了 Pyinstaller 工具来进行打包。由 Pyinstaller 打包后的执行文件在执行时,Pyinstaller 会启动一个清理进程,其余为我们实际的工作进程。
mogha: watchdog 进程是 MogHA 的主进程监控所有子进程存活状态。
mogha: heartbeat 进程是 MogHA 的心跳进程用于监控数据库进程及处理。
mogha: http-server 进程是用于 MogHA 节点间通信的 HTTP 服务进程。
元数据库必须配置么?
非必须。
为什么主备的 MogHA 服务都启动了,主心跳日志还报找不到备库的错误?
请确认主备数据库所在服务器已经开启防火墙相应端口,或者禁用防火墙,确认 agent_port 端口可以正常访问。
MogHA的故障检测机制是什么方式的?
对于主库实例,分为实例状态检测,网络检测和双主检测三部分。实例状态检测是通过数据库管理工具探测,支持配置自动拉起宕机的实例,可配置拉起的次数和时间;网络检测是通过和其他实例以及网关的连通性检测判断网络是否隔离,可以配置检测超时时间,判断网络故障后会自杀;双主检测是通过集群多数派确定真主,两实例时,根据元数据的时间进行判断。
对于备库实例,故障检测机制是和其他实例以及网关的连通性检测判断主库是否故障,可以配置检测超时时间。
MogHA 是怎样切换的?
主库检测到自己故障后,通过HTTP接口依据定义的切换顺序请求候选备库执行切换; 备库检测到主库故障后,依据定义的切换顺序自发的执行切换; 切换动作包含 failover 和挂载虚拟IP
主备同步复制环境中,如果无法联系到备库,主库会怎么处理以保证数据的一致性?
主备同步复制环境中,如果备库连接丢失,主库事务也会挂起,如果使用了最大可用模式,则会默认改为异步模式。 无论是同步复制还是异步复制,如果所有备库均已经故障,主库无法联系到任何一台备库,主备数据在此故障时间段就不存在一致性的说法了。但当备库恢复后,会告诉主库自己所需的起始LSN位置,获取到所有差异的WAL日志,并最终追平保持同步,主备数据仍然一致。
五、 名词表
高可用(HA:High Availability)
高可用指的是系统无中断地执行其功能的能力,代表系统的可用性程度,是进行系统设计时的准则之一。高可用性系统与构成该系统的各个组件相比可以更长时间运行。高可用性通常通过提高系统的容错能力来实现。 具体到数据库领域来说,高可用,概念上指一主一备或者一主多备情况下,当主库发生宕机,可以通过手动或者自动的主备角色切换,以降低数据库的不可服务时间,降低对于业务的影响。
主备
主备多用来用于数据库场景,比如:MogDB 主备,MySQL 主备等等。主备的概念用于有状态的应用服务。 主备即主库实例与备库实例,二者不共享数据文件,各自拥有独立的数据文件,主备之间通过数据操作日志进行数据同步,主库允许读写,而备库禁止写,但可以读,备库通过即时回放操作日志,保证数据视图延迟不会超过特定区间(通常为最新的数据事务)。
物理复制和逻辑复制
数据库存在物理复制(流复制)与逻辑复制。
物理复制指的是,复制日志为 Redo (数据块变更记录),通过物理复制,可以从实例级复制出一个与主库一模一样的实例级的从库。物理复制同步方式有同步、异步两种。其目的是保证主备之间数据文件一致,最大化保护数据。
逻辑复制传输的是逻辑操作日志,主备之间数据状态一致,但存储到磁盘上的数据文件不相同。
相比较物理复制,逻辑复制更灵活,但在特定情况下,数据不一致的可能性大于物理复制。
同步流复制,异步流复制
异步流复制指主库上提交的事务不需要等待备库接收写入 WAL 日志时便返回成功响应,如果主库宕机,主库上已提交的事务可能还没来得及发给备库,就会造成数据丢失,备库丢失数量与 WAL 复制延迟有关,延迟越大,丢失越多。 同步流复制需要在主库提交事务时等待备库接受WAL 日志后,主库收到备库发回的确认信息才返回成功响应,这样就保证了数据的完整性,但增加了事务的响应时间,因此同步流复制吞吐量比异步流复制低。
Switchover
switchover是指在主备机正常时,出于维护的需要,将备机切换为主机的行为,这样可保证切换过程中数据不丢失。
Failover
failover 是指在主机异常时,将备机切换为主机的行为。