本章介绍如何对 OceanBase 数据库进行运维,包括集群扩缩容、重启、备份、监控,租户扩缩容、性能调优等。
5.1 如何管理 OceanBase 集群
OceanBase 集群架构简述
进程简述
OceanBase 数据库是单进程软件,进程名为:observer。通常每个机器启动一个进程就是一个节点。在第 2 章部署中介绍了 OceanBase 数据库的目录架构。以下是 OceanBase 数据库和 ODP 安装后的目录。
[admin@obce02 ~]$ pwd
/home/admin
[admin@obce02 ~]$ tree -L 3 --filelimit 10 oceanbase/ obproxy/ /redo /data/
oceanbase/
├── bin
│ ├── import_time_zone_info.py
│ └── observer
├── etc
│ ├── observer.config.bin
│ ├── observer.config.bin.history
│ └── timezone_V1.log
├── lib
│ ├── libaio.so -> libaio.so.1.0.1
│ ├── libaio.so.1 -> libaio.so.1.0.1
│ ├── libaio.so.1.0.1
│ ├── libmariadb.so -> libmariadb.so.3
│ └── libmariadb.so.3
├── log [588 entries exceeds filelimit, not opening dir]
├── run
│ ├── mysql.sock
│ └── observer.pid
└── store
└── obdemo
├── clog -> /redo/obdemo/clog
├── etc2 -> /redo/obdemo/etc2
├── etc3 -> /data/obdemo/etc3
├── ilog -> /redo/obdemo/ilog
├── slog -> /redo/obdemo/slog
└── sstable -> /data/obdemo/sstable
obproxy/
/redo
└── obdemo
├── clog [160 entries exceeds filelimit, not opening dir]
├── etc2
├── ilog [17 entries exceeds filelimit, not opening dir]
└── slog
├── 5
└── 6
/data/
└── obdemo
├── etc3
└── sstable
└── block_file
21 directories, 15 filesOceanBase 数据库目录中需要关注以下几个目录:
软件安装目录
若您是使用 RPM 包手动安装 OceanBase 数据库的,默认会安装在用户 admin 的 HOME 目录下(
~/)。如果您是使用 OBD 自动部署的,RPM 将会解压缩到用户的 HOME 目录下隐藏文件夹里(~/.obd)。工作目录
本教程里进程 observer 的工作目录是
~/oceanbase,进程 obproxy 的启动目录是~/obproxy。进程 observer 和 obproxy 启动时都会在工作目录下寻找
etc子目录,读取默认配置文件。如果目录不存在则创建一个文件夹etc,同时还会创建日志目录log等。所以需要了解进程 observer 和 obproxy 的启动目录,以便进程故障时,能够快速拉起进程。此外,启动用户也需要保持一致。本教程使用的是用户 admin。使用 OBD 部署 OceanBase 数据库和 ODP 时,可以指定工作目录。
参数目录
参数文件目录默认在工作目录下的
etc目录中,此外还可以通过参数config_additional_dir设定冗余的参数目录。参数文件是二进制文件,不能直接编辑和读取,您可通过strings命令读取。日志目录
日志目录默认放在工作目录下的
log目录。如果工作目录下无log目录,将会自动生成。日志目录里有三类日志:observer.log、rootservice.log和election.log。每个日志又有一个完整的目录和一个日志级别在 WARN 级别及以上的日志。后者可以通过参数关闭。observer.log通过参数设置可以滚动生成,保留指定日志数量。当数据库访问量非常大时,进程 observer 的日志输出量也会比较大。所以这个目录在生产环境中建议可用空间不少于 100G。并且在集群的参数里还会对日志输出限流。总数据目录
总数居目录默认放在工作目录下的
store文件夹。当然进程 observer 也可以通过参数-d指定特定目录。本教程里手动部署 OceanBase 数据库的时候,建议在
store目录下设置集群名作为总数据目录,然后通过参数-d指定到具体目录(如-d ~/oceanbase/store/obdemo)。该目录下会有实际的数据文件目录(sstable)和事务日志目录(slog、ilog、clog)。通常建议数据文件目录和事务日志目录用独立的盘存放,所以该目录下的数据文件目录和事务日志目录是一个软链接。
数据文件目录
数据文件目录默认文件夹名为
sstable,目录下只有一个大文件block_file。在进程 observer 启动时初始化,初始化默认大小是磁盘可用空间的80%。block_file的大小可以通过参数控制。数据文件目录不能和事务日志目录共用一块盘存储。如果节点要重置,该目录下的内容必须清理。
事务日志目录
事务日志目录包含三个文件夹:
slog:存储静态数据写入的事务日志。clog:存储动态数据写入的事务日志。ilog:存储日志目录。
这些日志 OceanBase 数据库会自动管理,不要手动删除。这三个目录通常建议独立一块盘存储。如果节点要重置,这三个目录下的内容必须清理。
进程监听端口
下面分别介绍进程 observer 和 obproxy 的监听端口。
进程 observer 第一次启动时,需要通过参数 -p 指定连接端口,通过参数 -P 指定节点 RPC 通信端口。默认是 -p 2881 -P 2882。进程启动成功后,几秒就可以运行到监听环节。
查看方法如下:
[admin@obce02 oceanbase]$ pidof observer 56779 [admin@obce02 oceanbase]$ ps -ef | grep observer | grep -v grep admin 56779 1 99 16:26 ? 00:00:49 bin/observer [admin@obce02 oceanbase]$ [admin@obce02 oceanbase]$ netstat -ntlp | grep -i observer (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:2881 0.0.0.0:* LISTEN 56779/bin/observer tcp 0 0 0.0.0.0:2882 0.0.0.0:* LISTEN 56779/bin/observer [admin@obce02 oceanbase]$
最后一列中数字是进程 ID。 排查问题时,建议查看节点之间的 TCP 连接状态,或者查看哪个 IP 和 PORT 流量最大。
# 查看 TCP 连接
netstat -np |grep -i observer
# 查看 TCP 连接汇总
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 查看网卡 IP 流量
iftop -i eth0 -nNB
# 按 L 、T 、3 、t 、 B 、l 、 p 找出具体哪个 IP 和 PORT 流量最大 集群节点组织架构
OceanBase 集群由多个节点的进程组合而成,集群最小规模是 1 个节点,这是一个单副本集群,没有高可用能力。
在生产环境中,OceanBase 集群最小规模是三节点。会分为三个 Zone,每个 Zone 最少一个节点。实际上集群里节点组织关系如下:
| 集群 | Zone | REGION | IDC | IP |
|---|---|---|---|---|
| obdemo | zone1 | region1 | idc1 | 192.168.249.52 |
| obdemo | zone2 | region1 | idc1 | 192.168.249.49 |
| obdemo | zone3 | region1 | idc2 | 192.168.249.51 |
| obdemo | zone4 | region1 | idc2 | 192.168.249.54 |
| obdemo | zone5 | region2 | idc3 | 192.168.249.55 |
节点的 Zone 在进程启动的时候指定。节点的 region 和 idc 是和 Zone 绑定的,可以在集群初始化完成后查看和修改。 下面只是示例,并不表示一定需要修改。
alter system change zone 'zone1' region 'region1';
alter system change zone 'zone2' region 'region1';
alter system change zone 'zone3' region 'region2';
alter system modify zone zone1 idc='idc1';
alter system modify zone zone2 idc='idc2';
alter system modify zone zone3 idc='idc3';
select * from __all_zone where name in ('region','idc','status','zone_type','cluster') order by name;
+----------------------------+----------------------------+-------+-----------+-------+-----------+
| gmt_create | gmt_modified | zone | name | value | info |
+----------------------------+----------------------------+-------+-----------+-------+-----------+
| 2021-09-12 14:49:43.533839 | 2021-09-12 14:49:43.533839 | | cluster | 0 | obdemo |
| 2021-09-12 14:49:43.536334 | 2021-09-20 17:08:13.727095 | zone1 | idc | 0 | idc1 |
| 2021-09-12 14:49:43.537407 | 2021-09-20 17:08:20.052725 | zone2 | idc | 0 | idc2 |
| 2021-09-12 14:49:43.538453 | 2021-09-20 17:08:25.589423 | zone3 | idc | 0 | idc3 |
| 2021-09-12 14:49:43.536334 | 2021-09-20 17:07:44.025486 | zone1 | region | 0 | region1 |
| 2021-09-12 14:49:43.537407 | 2021-09-20 17:07:48.804019 | zone2 | region | 0 | region1 |
| 2021-09-12 14:49:43.538453 | 2021-09-20 17:07:57.702095 | zone3 | region | 0 | region2 |
| 2021-09-12 14:49:43.535302 | 2021-09-14 10:25:55.748709 | zone1 | status | 2 | ACTIVE |
| 2021-09-12 14:49:43.536334 | 2021-09-12 14:49:43.536334 | zone2 | status | 2 | ACTIVE |
| 2021-09-12 14:49:43.537407 | 2021-09-12 14:49:43.537407 | zone3 | status | 2 | ACTIVE |
| 2021-09-12 14:49:43.536334 | 2021-09-12 14:49:43.536334 | zone1 | zone_type | 0 | ReadWrite |
| 2021-09-12 14:49:43.537407 | 2021-09-12 14:49:43.537407 | zone2 | zone_type | 0 | ReadWrite |
| 2021-09-12 14:49:43.538453 | 2021-09-12 14:49:43.538453 | zone3 | zone_type | 0 | ReadWrite |
+----------------------------+----------------------------+-------+-----------+-------+-----------+
13 rows in set (0.003 sec)当集群中的所有节点都在同一机房时,region 和 idc 设置为同一个值即可。只有在三机房部署时,才需要对 region 和 idc 进行设置,以方便集群正确管理各个节点。比如说避免把一个机房的节点错划到另外一个机房的 Zone 中。
这些元数据靠 DBA 维护,集群部署时,节点只需连通性、时间延时和网络延时满足要求即可,并不要求机器一定在同一个机房。
在后期对集群做读写分离规划时,region 和 idc 对 ODP 的 SQL 路由策略有很大影响。所以,请您尽量正确设置。
如何管理 OceanBase 集群参数
OceanBase 集群支持参数定制,以适应不同的场景需求。参数的查看和修改主要在集群内部租户 sys 中进行。
参数简介
部分参数的生效范围是集群内所有实例,可以通过命令控制在哪些节点生效。少数参数是在租户范围内生效,大部分参数的变更是立即生效,极少数参数的变更需要重启节点方可生效。
参数的值、描述、生效范围、是否要重启节点等,都可以通过命令 show parameters [ like '%参数名特征%' ; 查看。 您也可以通过以下命令对参数进行修改。
alter system set 参数名 = 参数值(如果是字符串,用两个单引号引起来)[ scope = 'xxx.xxx.xxx.xxx:2882' ] ;
除了集群参数可以定制集群行为外,租户也可以定制集群行为,可通过变量(variable)进行设置。
变量跟参数是同一类概念,参数的定位和风格取自 Oracle 数据库,变量的定位和风格取自 MySQL 数据库。集群 sys 租户中同样可以设置变量值(sys 租户变量通常不用调整),不同租户的变量设置彼此独立,互不影响。
大部分变量的设置是立即生效,生效范围根据设置方法不同有实例全局层面生效和会话层面生效两种情况。极少数变量(类似 MySQL 的初始化变量)不能在租户中后期修改,只能在 sys 租户中新建业务租户的时候设置。当然也能后期在 sys 租户进行修改,但是必须充分评估修改的影响。
变量的值、描述都可以通过以下命令查看或修改。
show global | [session] variables [ like '%变量名特征%' ] ;
# 或
show global | [session] variables where variable_name in ('参数1' [, '参数2']) ;
# 您可以通过下列命令修改变量的值
set global | [session] 变量名 = 变量值(如果是字符串,用两个单引号引起来);其中,global 指全局生效,对新建会话生效,当前会话不生效。 session 或者没有限定符,都表示对当前会话生效。会话断开重连后,又会取全局层面的默认值。
部分变量还可以通过 SQL HINT 设置语句级别变量,影响范围是所修饰的语句。语句级的变量名会去掉前面的 ob_ 部分。
下面是常用的几个语句级别的变量命名映射关系。
| 全局/会话变量名 | 语句级变量名 | 描述 |
|---|---|---|
| ob_query_timeout | query_timeout | 指定语句执行超时的阈值 |
| ob_read_consistency | read_consistency | 指定读一致性级别,默认是强一致性读,可以修改为弱一致性读 |
常用集群参数作用的分类如下:
影响节点可用性的判断。如
server_permanent_offline_time和server_temporary_offline_time。影响集群日志的特点。如
enable_syslog_recycle、enable_syslog_wf、max_syslog_file_count、syslog_level和syslog_io_bandwidth_limit。影响集群冻结和合并行为。如
minor_freeze_times、major_freeze_duty_time、enable_major_freeze、freeze_trigger_percentage、micro_block_merge_verify_level、minor_merge_concurrency、merge_thread_count、zone_merge_timeout、enable_merge_by_turn、zone_merge_order、zone_merge_concurrency和enable_manual_merge。影响集群节点内存分配的行为。如
memstore_limit_percentage、memory_limit_percentage、sql_audit_memory_limit、system_memory、memory_limit。影响集群负载均衡行为。如
server_balance_cpu_mem_tolerance_percent、server_balance_disk_tolerance_percent、balancer_tolerance_percentage、data_copy_concurrency、server_data_copy_out_concurrency、server_data_copy_in_concurrency。
以上参数的作用可以在命令里查看,也可以查询官方文档。之后讲解运维、性能调优时会用到这些参数,届时将详细介绍。
参数文件
除了通过登录集群 sys 实例查看集群的参数外,您还可以通过参数文件查看。
OceanBase 集群参数文件名称为 observer.config.bin,位于进程工作目录下的 etc/ 目录下。如果您是使用 OBD 部署的 OceanBase 集群,配置文件里的 home_path 就是集群的工作目录。
您也可以通过查看进程的运行环境确定进程的工作目录。
[admin@obce02 oceanbase]$ sudo ls -lrth /proc/`pidof observer`/cwd lrwxrwxrwx 1 admin admin 0 Sep 21 13:10 /proc/56779/cwd -> /home/admin/oceanbase
进程目录下的 cwd 为指向实际工作目录的软链接。集群的参数文件是二进制文件,不能直接编辑和查看,您可使用命令 strings 进行查看。
[admin@obce02 oceanbase]$ strings /home/admin/oceanbase/etc/observer.config.bin | grep config_addition config_additional_dir=/data/obdemo/etc3;/redo/obdemo/etc2
通常集群的参数修改成功后都会持久化到参数文件内。
进程启动参数
如果参数文件设置不合理,可能会导致进程启动失败。但进程启动参数文件不能直接修改,此时您可在启动进程 observer 的时候指定启动参数。如:
cd /home/admin/oceanbase && bin/observer -o "memory_limit=50G, system_memory=10G"
这种方法适合调整少数参数,让进程启动起来。启动成功后,该参数也会持久化到进程的参数文件里。
如何管理 OceanBase 数据库内存
OceanBase 数据库的内存分配可以参考内存分配图。
下面对图中提到的内容逐个进行详细介绍。
OceanBase observer 进程启动后会从主机拿到绝大部分资源(CPU/内存/空间),具体资源大小则由集群参数控制。其中集群节点进程启动需要多少内存是由参数 memory_limit 和 memory_limit_percentage 共同控制的。
生产环境中通常不设置 memory_limit 值(默认值为 0),只设置 memory_limit_percentage 值(默认值为 80%)。这样每个节点进程获取的总内存是主机可用内存的 80% 。当主机内存扩容后(例如虚拟机),OceanBase 节点能获得的内存也相应增加。
如果设置了 memory_limit 的值,则进程获取的总内存就是指定的具体的值,该值的最小值为 8G。该参数通常在测试环境中运行 OceanBase 数据库使用,或者单机启动多个 OceanBase 进程。
注意
这两个参数可以在线调整,但调整参数时最大不能超过主机可用内存,最小不能少于 8G。通常调大是安全的,调小可能有风险。
系统内部内存
OceanBase 数据库内部租户除了 sys 租户外,还有 500 租户(租户 ID 为 500),500 租户的内存由 system_memory 配置项确定。
不同版本的 OceanBase 数据库中该参数默认值不同。生产环境中,主机有 386GB 内存以上时,这个参数默认值是 50GB。如果主机内存只有 256GB,这个参数内存会小一些,比如 30GB 左右。
在第 2 章中为了在 10GB 内存的机器上运行 OceanBase 数据库,system_memory 参数的取值范围为 3GB ~ 5GB。
该内存在内部租户 ID 500 的租户下,供业务租户某些内部操作使用。
sys 租户内存
sys 租户在集群初始化时自动创建。随着可用内存大小、版本的变化,sys 租户的资源规格会有一些细微差别。sys 租户的内存大小是由默认资源单元 sys_unit_config 的规格定义的。
select unit_config_id, name, round(max_memory/1024/1024) max_mem_MB, round(min_memory/1024/1024) min_mem_MB from __all_unit_config where unit_config_id = 1; +----------------+-----------------+------------+------------+ | unit_config_id | name | max_mem_MB | min_mem_MB | +----------------+-----------------+------------+------------+ | 1 | sys_unit_config | 1536 | 1024 | +----------------+-----------------+------------+------------+ 1 row in set (0.009 sec)
示例中 sys_unit_config 默认的内存规格最小值和最大值不一样,为了更准确的计算集群可用资源,建议把内存最小值和最大值更新为同一个值(即只能变大,不能小于默认最大值)。后续创建业务租户时,建议 CPU 和内存的最小值和最大值保持一致。
alter resource unit sys_unit_config min_memory = '1536M';
如果集群节点规模在 10 台以内,sys 租户资源通常不需要调大。
如果集群规模有几十台,需观察 sys 租户的内存和 CPU 利用率。如果出现资源瓶颈,则适当调整 sys 租户资源规格,最大时可以独占一台机器资源。sys 租户最多只能独占 3 台机器。
MemStore 内存
每个租户分得的内存,默认有一半用于存放租户的增量数据,也叫 MemStore。该内存大小通过参数 memstore_limit_percentage 控制,默认值是 50%。
当写多读少时,可以将这个参数值调高,比如在大批量导数据且没有读的时候,可以临时将参数值调整到 80%。当然该参数不能随意调整。
租户的内存除去增量数据占用的内存外,还有其他用处,比如存放静态的数据(KVCache)、SQL 执行计划缓存(PLAN CACHE)、SQL 运算的临时内存(SQLAREA)等。如果这些内存资源过少,则会报错,或者性能减慢。
说明
目前 OceanBase 数据库对内存的管理以手动分配为主,将来或许可以做到动态管理。
OceanBase 数据库的读写模型是 LSM-Tree,写操作是追加模式。
数据表是有序表格,又叫 SSTable,全称为 SORTED STRING TABLE。数据表的写操作不是在原来的数据块上修改,而是开辟新的内存记录变化的增量,原有的数据保存在 KVCache 不变,称之为基线数据。
绝大部分业务一天的数据变化量相对于数据总量来说比重很小,OceanBase 数据库的这种增量写很节省内存。所以,通常说 OceanBase 数据库的增量数据都是在内存里不落盘的,但严格来说,这种说法并不严谨,OceanBase 数据库的增量数据在内存里应该是延迟落盘。
如何对 OceanBase 集群进行合并
OceanBase 数据库每天会定时将增量数据和基线数据在内存中合并成新的数据块,然后以追加方式写回到磁盘数据文件中。这个合并操作叫 major freeze,合并的时间调度通过参数 major_freeze_duty_time 设定,默认值是 02:00,每天调度一次。
合并操作也可以手动发起。合并时会消耗一定资源,会对性能产生一些影响。不过合并的并发也可以通过参数 merge_thread_count 控制,并且通过参数 merger_warm_up_duration_time 调整合并线程启动时间。调整这两个参数可以在合并的速度和稳定性之间取一个最佳平衡。
当租户内存不是很大,或者业务写量非常大的时候,该租户的增量内存可能会写满,会出现业务写不进去,报错 NO MEMORY 的情况。这种情况是 OceanBase 运维要极力避免的。
您可运行 alter system major freeze; 命令合并集群,之后通过以下命令查看当前的合并进度。
SELECT ZONE,svr_ip,major_version,ss_store_count,merged_ss_store_count,modified_ss_store_count,merge_start_time,merge_finish_time,merge_process FROM __all_virtual_partition_sstable_image_info order by major_version desc ;
最终合并结果确认时查看合并状态。
select * from __all_zone where name in ('merge_status','all_merged_version','broadcast_version');正常情况都是 IDLE,且合并版本和广播版本保持一致。
如何对 OceanBase 集群进行限速和转储
首先,OceanBase 数据库租户可以设置一个增量内存写限速的设计,触发限速有以下两种情况:
增量内存利用率到达参数
writing_throttling_trigger_percentage设置。预估剩余增量内存持续可用时间小于或等于参数
writing_throttling_maximum_duration定义。
默认参数 writing_throttling_trigger_percentage 的值是 100%,也就是不限速。实际业务建议最大不超过 90%。
注意
当写入量非常大时,参数 writing_throttling_trigger_percentage 的值需要适当调低。
当业务写被限速的时候,业务表现为普通的 DML SQL 性能变慢(延时变大),等待事件是 mem allocation 等。限速很影响性能,所以该情况需要极力避免。
OceanBase 数据库除了 major freeze 操作可以释放内存外,minor freeze 操作也可以释放内存,该操作通常被称为转储。
转储是直接将内存中的增量数据以 SSTable 格式写到磁盘数据文件中,从而释放增量内存。转储与合并相比,对资源的占用更少,对性能的影响也很小。
转储的触发有两个机制。
手动触发
手动触发的命令是
alter system minor freeze ;。命令发生时内存中的增量块会被冻结禁止写入,新的写入会生成新的增量内存块去接受写入。自动触发
当增量内存部分的利用率达到参数
freeze_trigger_percentage指定的值(默认是70,表示70%),自动触发minor freeze操作。
转储可以有很多轮,当转储的次数达到参数 minor_freeze_times 指定的值,会自动触发合并(major freeze)操作。
转储也支持调优,通过调整转储的并发参数(minor_merge_concurrency),可以在转储的速度和稳定性之间取得一个平衡。
经验表明,当租户内存规模在 50GB 以上时,通过调整转储参数,绝大部分时候是可以避免增量内存写入限速或内存不足的错误。如果业务增量写非常大,则说明租户内存有瓶颈,则需要对内存资源扩容。
注意
如果是临时大批量导入数据,可以临时对租户内存进行扩容。等导入完毕,一轮合并结束后,就可以对租户内存进行缩容。在线扩容和缩容,也是 OceanBase 数据库最核心和实用的能力。
如何重启 OceanBase 节点和集群
(建议) OceanBase 集群合并
OceanBase 集群生产环境默认是有三个副本,任意一个副本不可用,OceanBase 数据库的内部都会发生一次故障切换。此时部分数据访问会中断,恢复时间在 30s 左右,数据能保证绝对不丢。这个故障切换过程不需要运维介入,可靠性很高。
如果是计划中的节点重启,OceanBase 集群内部也会自动发起切换,此时大部分读写感知不到切换,少数大事务会中断需要重试。
所以,整体上 OceanBase 集群计划重启可以做到业务不停机,数据库服务不中断。您只需要按机器所属的 Zone 分批次重启 OceanBase 机器。
由于 OceanBase 节点重启后会有一个恢复的过程,恢复的时间取决于从最近的基线版本到当前时间需要恢复的数据量。OceanBase 数据库可能要应用很多 clog 去恢复数据。如果需恢复的 clog 数据量实在太大,OceanBase 节点可能会直接从主副本那里拉取最新的数据。
如果条件允许,在重启节点之前,可先对整个集群发起一次合并。待合并结束后,每个节点内存中就只有最近一段时间的增量数据,那么节点重启后的恢复时间可做到最短。
发起合并操作的命令为 alter system major freeze;。合并操作详情,参考:如何对 OceanBase 集群进行合并。
如何重启 OceanBase 节点
节点停服
OceanBase 数据库并没有提供重启节点的命令,但是提供了节点停服的命令:
alter system stop server '节点ip:2882' ;
节点停服后,节点上如果有主副本,会自动切换为备副本。节点的备副本依然参与投票,但不会当选为主副本。
OceanBase 节点停服和 OceanBase 宕机性质不同,节点停服时间可以超出参数永久下线时间(
server_permanent_offline_time) 而不会导致节点真的下线。节点停服后,大概 1~2 秒后就可以观察到有主备副本切换事件。 确认 SQL 如下:
SELECT DATE_FORMAT(gmt_create, '%b%d %H:%i:%s') gmt_create_ , module, event, name1, value1, name2, value2, rs_svr_ip,name3,value3,name4,value4 FROM __all_rootservice_event_history WHERE 1 = 1 AND module IN ('leader_coordinator', 'balancer' ) ORDER BY gmt_create DESC LIMIT 20;所有分区副本的主备切换通常需要数秒。
“杀”进程
“杀”节点进程
observer命令如下:kill `pidof observer`
如果是在测试环境中,比较着急的情况下可以不用发起节点停服命令,直接强行"杀"进程。
kill -9 `pidof observer`
启动进程
启动节点进程的关键点在于上一次工作目录启动。所以建议第一次启动时就把工作目录跟安装目录保持一致,防止出错。
cd /home/admin/oceanbase && bin/observer
通常启动的时候不需要再带启动参数。但如果这次启动节点就是为了修改某个参数,则需要使用
-o带上具体的参数。示例如下:cd /home/admin/oceanbase && bin/observer -o "datafile_size=80G,clog_disk_usage_limit_percentage=96 "
进程启动后等 5~10 秒后,确认进程是否启动成功。
# 确认进程还在 ps -ef | grep observer | grep -v grep # 确认端口监听成功 netstat -ntlp | grep `pidof observer`
启动服务并确认节点服务状态
进程监听成功还不够,节点还需要一个数据恢复过程,即应用 CLOG 的过程。
如果此前对节点停服了,先把节点服务启动。
alter system start server '节点IP:2882' ;
确认节点的服务状态。
select a.zone,concat(a.svr_ip,':',a.svr_port) observer, cpu_total, (cpu_total-cpu_assigned) cpu_free, round(mem_total/1024/1024/1024) mem_total_gb, round((mem_total-mem_assigned)/1024/1024/1024) mem_free_gb, usec_to_time(b.last_offline_time) last_offline_time, usec_to_time(b.start_service_time) start_service_time, b.status, usec_to_time(b.stop_time) stop_time, b.build_version from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port) order by a.zone, a.svr_ip;
您需重点关注的内容如下:
节点状态
status:升级前没有inactive值,升级过程中会有。节点服务时间
start_service_time是否是默认值(1970-01-01 08:00:00.000000)。如果是,则表示节点还没有恢复结束。节点停止时间
stop_time是否是默认值(1970-01-01 08:00:00.000000)。如果不是,则表示节点被停服(stop server)了,需要先启动服务(start server)。
注意 节点的
start_service_time状态正常之后方可重启其他 Zone 对应的其他副本所在的机器。同一个 Zone 的多台机器可以并行重启。
如何重置 OceanBase 节点
重置 OceanBase 节点属于应急手段之一,是高危操作,仅用在如下特殊的场景:
节点磁盘损坏后修复,怀疑数据有丢失的。此时需要重做副本。
想对节点数据文件大小进行缩容,重新初始化进程
observer,相当于重做副本。
重置 OceanBase 节点的步骤如下。
停掉节点进程
因为是要重置节点,所以停进程的方法就不用像重启节点那么繁琐,可以直接杀进程。
kill -9 `pidof observer`
如果进程已经停止,则跳过这步操作。 杀进程之前,需要先知道此前的进程启动时工作目录。使用如下命令:
ll /proc/`pidof observer`/cwd lrwxrwxrwx 1 admin admin 0 Sep 25 08:18 /proc/15495/cwd -> /home/admin/oceanbase-ce
确认节点永久下线
通常情况下,节点进程异常,相当于节点掉线。掉线时间超过节点掉线时间超过参数 server_temporary_offline_time 值(默认 60s)后,状态会进入临时下线状态。此后,如果节点进程能重新正常起来,节点还是集群的成员,会自动同步落后的数据。
示例:
select a.zone,concat(a.svr_ip,':',a.svr_port) observer, usec_to_time(b.last_offline_time) last_offline_time, usec_to_time(b.start_service_time) start_service_time, b.status, usec_to_time(b.stop_time) stop_time from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port) order by a.zone, a.svr_ip;
输出:
+-------+--------------------+----------------------------+----------------------------+----------+----------------------------+ | zone | observer | last_offline_time | start_service_time | status | stop_time | +-------+--------------------+----------------------------+----------------------------+----------+----------------------------+ | zone1 | 172.20.249.52:2882 | 1970-01-01 08:00:00.000000 | 2021-09-25 08:19:06.622351 | active | 1970-01-01 08:00:00.000000 | | zone2 | 172.20.249.49:2882 | 1970-01-01 08:00:00.000000 | 2021-09-25 08:19:07.392669 | active | 1970-01-01 08:00:00.000000 | | zone3 | 172.20.249.51:2882 | 1970-01-01 08:00:00.000000 | 1970-01-01 08:00:00.000000 | inactive | 1970-01-01 08:00:00.000000 | +-------+--------------------+----------------------------+----------------------------+----------+----------------------------+ 3 rows in set (0.008 sec)
节点掉线后进入临时下线状态时,上面节点视图的 status 列会变为 inactive。同时,在 OceanBase 事件日志视图里也会有一条“临时下线”记录。
SELECT DATE_FORMAT(gmt_create, '%b%d %H:%i:%s') gmt_create_ , module, event, name1, value1, name2, value2, rs_svr_ip
FROM __all_rootservice_event_history
WHERE 1 = 1
AND module IN ('server','root_service')
and gmt_create > SUBDATE(now(),interval 1800 second)
ORDER BY gmt_create DESC
LIMIT 10;输出:
+----------------+--------------+------------------+--------+----------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+
| gmt_create_ | module | event | name1 | value1 | name2 | value2 | rs_svr_ip |
+----------------+--------------+------------------+--------+----------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+
| Sep26 12:39:32 | root_service | admin_set_config | ret | 0 | arg | {items:[{name:"rootservice_list", value:"172.20.249.52:2882:2881;172.20.249.49:2882:2881", comment:"", zone:"", server:"0.0.0.0", tenant_name:"", exec_tenant_id:1, tenant_ids:[]}], is_inner:false} | 172.20.249.52 |
| Sep26 12:39:32 | server | lease_expire | server | "172.20.249.51:2882" | | | 172.20.249.52 |
+----------------+--------------+------------------+--------+----------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+
2 rows in set (0.001 sec)节点掉线首先会有个 lease_expire 事件。节点掉线原因可以有很多,如进程宕掉、网络超时或延时过大、时间误差过大等。 此外,由于这个示例集群是三节点,所以一个节点的掉线对总控服务成员也有影响,所以参数 rootservice_list 会自动变化,踢掉了故障节点。
如果节点掉线时间超过参数 server_permanent_offline_time 值(默认是 3600s ),节点会进入永久下线状态。此时,集群会清空该节点上的数据副本,并自动在同 Zone 其他节点寻求资源补足被清空的数据副本。如果没有可用资源,则这个副本对应的分区就只剩下两个副本(或者四个副本)。此时依然是多数派副本可用,所以数据读写是正常的,但如果再次宕机集群可能不可用。
SELECT DATE_FORMAT(gmt_create, '%b%d %H:%i:%s') gmt_create_ , module, event, name1, value1, name2, value2, rs_svr_ip FROM __all_rootservice_event_history WHERE 1 = 1 AND module IN ('server','root_service') and gmt_create > SUBDATE(now(),interval 7200 second) ORDER BY gmt_create DESC LIMIT 10;输出:
+----------------+--------------+----------------------+--------+----------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+
| gmt_create_ | module | event | name1 | value1 | name2 | value2 | rs_svr_ip |
+----------------+--------------+----------------------+--------+----------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+
| Sep26 13:39:48 | server | clear_with_partition | server | "172.20.249.51:2882" | | | 172.20.249.52 |
| Sep26 13:39:22 | server | permanent_offline | server | "172.20.249.51:2882" | | | 172.20.249.52 |
| Sep26 12:39:32 | root_service | admin_set_config | ret | 0 | arg | {items:[{name:"rootservice_list", value:"172.20.249.52:2882:2881;172.20.249.49:2882:2881", comment:"", zone:"", server:"0.0.0.0", tenant_name:"", exec_tenant_id:1, tenant_ids:[]}], is_inner:false} | 172.20.249.52 |
| Sep26 12:39:32 | server | lease_expire | server | "172.20.249.51:2882" | | | 172.20.249.52 |
+----------------+--------------+----------------------+--------+----------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+
4 rows in set (0.004 sec)从上面可以看到,节点被永久下线时,会发生事件 permanent_offline,节点的数据也会随后被清空,产生事件 clear_with_partition。
从临时下线到永久下线时间可能有点长,默认 1 小时。如果您时间紧张,可以临时把这个节点的参数 server_permanent_offline_time 调小。等节点永久下线后再重新上线时,把参数再改回来。
alter system set server_permanent_offline_time='360s';
(可选)清理数据库相关文件
如果您希望重建副本,则这一步并不是必须的。如果您想借重建副本操作重新定义数据文件的大小,则可以操作此步骤。
清理的文件包括:
运行日志。包括
log目录下的observer.log、rootservice.log、election.log。数据文件。包括
sstable下的block_file文件。事务日志文件。包括目录 {
ilog、clog、slog} 下的文件。
注意
为方便再次启动节点进程,不要删除参数文件 etc 。在启动参数 -o 里指定需要修改的参数即可。
下面删除只是示例,请注意目录结构:
[admin@obce03 store]$ cd /home/admin/oceanbase-ce/store [admin@obce03 store]$ ls clog ilog slog sstable [admin@obce03 store]$ pwd /home/admin/oceanbase-ce/store [admin@obce03 store]$ /bin/rm -rf */*
启动进程
如果没有清理参数文件,则可以直接启动进程 observer,可以通过 -o 修改参数。
cd /home/admin/oceanbase-ce && bin/observer # 或 cd /home/admin/oceanbase-ce && bin/observer -o "datafile_size=100G"
启动后确认端口监听正常,节点状态正常,这个前面已经阐述,此处不再重复了。
如何为 OceanBase 集群扩容/缩容/替换机器
OceanBase 集群扩容或缩容主要是调整集群机器资源池。
扩容就是往集群里加机器,操作相对简单,复杂的是缩容。
缩容的前提是剩余的机器能容纳所有租户的资源需求。如果资源不足,通常就要先对集群里的租户进行缩容,所以集群的缩容步骤将留到介绍租户缩容时再补充。
集群机器替换则是先扩容后缩容,集群机器资源池并没有发生变化,所以操作也很简单。
集群扩容节点
OceanBase 集群的部署分为标准部署模式和非标准部署模式。
标准部署模式是有三个 Zone,每个 Zone 的机器数量相等,每个 Zone 里可以存在不同配置的机器,但是不同 Zone 之间的机器配置是对等的,机器资源总量也是对等的。
非标准部署模式则是 Zone 之间的机器配置不对等、数量也不对等。技术上这也是可以运行的,只是资源最少的机器或 Zone 会成为集群资源的瓶颈。
OceanBase 集群扩容的标准形式就是向每个 Zone 里添加同等配置的机器。非标准做法就是只向一个 Zone 里添加机器。
操作步骤如下:
环境初始化
初始化新机器环境的具体操作步骤,请参见 2.4 如何初始化服务器环境。
启动进程
observer 进程第一次启动时需要指定一些参数,具体操作步骤请参见 2.11 (高级)如何手动部署 OceanBase 集群。
cd ~/oceanbase && bin/observer -i eth0 -p 2881 -P 2882 -z zone1 -d ~/oceanbase/store/obdemo -r '172.20.249.52:2882:2881;172.20.249.49:2882:2881;172.20.249.51:2882:2881' -c 20210912 -n obdemo -o "memory_limit=8G,cache_wash_threshold=1G,__min_full_resource_pool_memory=268435456,system_memory=3G,memory_chunk_cache_size=128M,cpu_count=16,net_thread_count=4,datafile_size=50G,stack_size=1536K,config_additional_dir=/data/obdemo/etc3;/redo/obdemo/etc2" -d ~/oceanbase/store/obdemo
参数说明:
-p:连接端口。默认是 2881,可以根据实际情况修改。-P:RPC 端口,默认是 2882,可以根据实际情况修改。-r:指定 rootservice list,跟集群当前的 rootservice list 保持一致。-z:指定节点所属 Zone。-c:cluster_id。-n:指定节点所属的集群名。
添加节点
在集群 sys 租户中运行以下命令添加新节点。
ALTER SYSTEM ADD SERVER '节点IP:RPC端口' ZONE '节点所属ZONE'; # 例如: alter system add server '11.166.87.5:2882' zone 'zone1';
查看状态
添加节点之后查看节点状态,此时新节点的状态是
active。select a.zone,concat(a.svr_ip,':',a.svr_port) observer, cpu_total, (cpu_total-cpu_assigned) cpu_free, round(mem_total/1024/1024/1024) mem_total_gb, round((mem_total-mem_assigned)/1024/1024/1024) mem_free_gb, usec_to_time(b.last_offline_time) last_offline_time, usec_to_time(b.start_service_time) start_service_time, b.status, usec_to_time(b.stop_time) stop_time from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port) order by a.zone, a.svr_ip;
以上步骤全部完成之后,需按相同步骤向下一个 Zone 中继续新增机器。当三个 Zone 都扩容完毕,集群扩容操作就完成了。
不过,这里只代表着运维的工作结束。集群扩容后,新的节点不会马上被集群里的租户使用到。集群资源池扩大后,新节点的利用率是 0,约 1 分钟后,集群会发现资源利用不均衡,之后会启动负载均衡逻辑,尝试将其他租户的资源单元迁移到新的节点上。
集群缩容也会触发负载均衡。有关负载均衡的概念后文会介绍到。
为集群中的每个 Zone 添加节点后,集群整体的资源池能力新增,可用的资源也相对增加,但是租户的资源并没有增加,租户不一定能利用上新机器,所以之后还需要进行租户扩容。
集群缩容节点
OceanBase 集群的标准部署模式是有三个 Zone,每个 Zone 的机器数量都对等。集群缩容节点就是减小某个 Zone 的节点数。通常缩容节点时建议每个 Zone 都减少相同的节点,但实际操作中没有这个限制,都是按 Zone 操作。
集群缩容节点时,会触发租户资源的负载均衡。剩余的节点必须能容纳租户资源需求,否则这个节点缩容命令会报错。所以,集群节点缩容之前,需要计算集群可用资源和了解各个节点的资源池分布。
集群缩容节点命令就是将某个节点从某个 Zone 里删除,删除时需确保节点没有资源被分配出去。
示例 SQL:
alter system delete server '11.166.87.5:2882' zone 'zone1';
集群缩容节点会触发租户资源负载均衡,之后会触发数据迁移。建议关注数据迁移的进度和影响。查看集群事件日志视图。
SELECT DATE_FORMAT(gmt_create, '%b%d %H:%i:%s') gmt_create_ , module, event, name1, value1, name2, value2, rs_svr_ip FROM __all_rootservice_event_history WHERE 1 = 1 AND gmt_create > SUBDATE(now(),interval 1 hour) ORDER BY gmt_create DESC LIMIT 20;
如何给 OceanBase 集群扩容/缩容副本
三副本扩容到五副本
生产环境 OceanBase 集群通常有三个 Zone,分布在一个机房或者同城三个机房,数据也有三份(简称三副本)。当建设异地容灾机房时,可能会选择从三个 Zone 扩容到五个 Zone(即五副本)。另外一种就是机房搬迁,将集群从一个机房在线搬迁到另外一个机房。这其中都涉及到三副本扩容到五副本。
下面介绍如何从三副本扩容到五副本。
机器节点进程初始化
主要是对 zone4 和 zone5 的机器进行初始化,注意启动参数中所属的 Zone 要正确。
具体步骤请参见:2.4 如何初始化服务器环境 和 2.11 (高级)如何手动部署 OceanBase 集群。
新增 Zone
alter system add zone 'zone4'; alter system add zone 'zone5';
启动 Zone
alter system start zone zone4; alter system start zone zone5;
给新增的 Zone 添加节点
alter system add server '11.166.87.5:2882' zone 'zone4'; alter system add server '11.166.87.6:2882' zone 'zone5';
为租户在新增节点上分配资源
create resource pool test_pool_z4 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_4'); create resource pool test_pool_z5 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_5');该命令立即返回。
修改租户的 LOCALITY ,给租户增加新增的资源池
注意 每次只能给租户新增一个资源池。
alter tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3','test_pool_z4'); alter tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3','test_pool_z4','test_pool_z5');租户在新增 Zone 中补数据副本是异步进行的,租户分区数越多,数据量越大,该命令的运行时间越长。
(可选)确认复制表的副本是否扩容
复制表的 LOCALITY 可以指定在哪些 Zone 里配置复制表副本(也可以不指定),默认是整个集群范围内。如果原本指定 LOCALITY,这里需要手动添加新的 Zone(这个待验证)。
alter table BMSQL_ITEM locality='F,R{all_server}@ZONE1, F,R{all_server}@ZONE2, F,R{all_server}@ZONE3, F,R{all_server}@ZONE4,F,R{all_server}@ZONE_5';确认集群和租户副本扩容结果
select a.zone,concat(a.svr_ip,':',a.svr_port) observer, cpu_total, (cpu_total-cpu_assigned) cpu_free, round(mem_total/1024/1024/1024) mem_total_gb, round((mem_total-mem_assigned)/1024/1024/1024) mem_free_gb, usec_to_time(b.last_offline_time) last_offline_time, usec_to_time(b.start_service_time) start_service_time, b.status, usec_to_time(b.stop_time) stop_time from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port) order by a.zone, a.svr_ip; select t1.name resource_pool_name, t2.`name` unit_config_name, t2.max_cpu, t2.min_cpu, t2.max_memory/1024/1024/1024 max_mem_gb, t2.min_memory/1024/1024/1024 min_mem_gb, t3.unit_id, t3.zone, concat(t3.svr_ip,':',t3.`svr_port`) observer,t4.tenant_id, t4.tenant_name from __all_resource_pool t1 join __all_unit_config t2 on (t1.unit_config_id=t2.unit_config_id) join __all_unit t3 on (t1.`resource_pool_id` = t3.`resource_pool_id`) left join __all_tenant t4 on (t1.tenant_id=t4.tenant_id) order by t1.`resource_pool_id`, t2.`unit_config_id`, t3.unit_id; select * from __all_tenant;
五副本缩容到三副本
五副本缩容到三副本时,将上面步骤反过来执行即可。
(可选)调整复制表的 LOCALITY ,缩减副本数。
修改租户的 LOCALITY,缩减副本数。
alter tenant sys resource_pool_list = ('sys_pool','sys_pool_1'); alter tenant sys resource_pool_list = ('sys_pool'); alter tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3','test_pool_z4'); alter tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3');注意,sys 租户也需要缩减副本数。这一步命令立即返回,但是删除副本会异步进行,速度也很快,分区数可以多一些,基本上在分钟级别完成。
删除多余的资源池
drop resource pool sys_pool_1 ; drop resource pool sys_pool_2 ; drop resource pool test_pool_z4 ; drop resource pool test_pool_z5 ;
如何升级 OceanBase 集群
OceanBase 集群升级就是将集群所有节点进程 observe 的版本升级。通常小版本的升级直接替换可执行文件 observer 然后将进程重启即可。但有时候升级还会涉及到元数据的变更,这就需要参考新版本发布时具体的 RELEASE NOTE。
确认集群当前状态正常
OceanBase 集群可以在线不停服升级,具体就是按 Zone 滚动升级。升级前首先要确认集群和各个 Zone 状态都正常。避免停止某个 Zone 时出现多数派故障,数据库访问不可用问题等。
确保集群节点状态正常
select a.zone,concat(a.svr_ip,':',a.svr_port) observer, cpu_total, (cpu_total-cpu_assigned) cpu_free, round(mem_total/1024/1024/1024) mem_total_gb, round((mem_total-mem_assigned)/1024/1024/1024) mem_free_gb, usec_to_time(b.last_offline_time) last_offline_time, usec_to_time(b.start_service_time) start_service_time, b.status, usec_to_time(b.stop_time) stop_time, b.build_version from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port) order by a.zone, a.svr_ip;
您需关注的有如下几点:
节点状态
status:升级前没有inactive值,升级过程中会有。节点服务时间
start_service_time:时间是否为默认值(1970-01-01 08:00:00.000000),如果是,则表示节点异常。节点停止时间
stop_time:时间是否为默认值(1970-01-01 08:00:00.000000),如果不是,则表示节点被stop server了。节点版本
b.build_version:升级重启后会变为新版本。
观察集群最近一段时间的事件,确保无异常事件
SELECT DATE_FORMAT(gmt_create, '%b%d %H:%i:%s') gmt_create_ , module, event, name1, value1, name2, value2, rs_svr_ip FROM __all_rootservice_event_history WHERE 1 = 1 AND module IN ('server','root_service','daily_merge') and gmt_create > SUBDATE(now(),interval 1 day) ORDER BY gmt_create DESC LIMIT 100;如果有大量正常的事件影响查看,就过滤掉。 留意报错的事件是否有影响,下列异常事件一定要先解决。如:合并异常、副本创建/搬迁异常等。
(可选)发起合并(
MAJOR FREEZE)由于集群升级需要重启节点,为了减少节点重启后的恢复时间,建议升级之前发起一次合并。具体合并方法和确认方法跟 如何重启 OceanBase 节点 中方法相同。
alter system major freeze;
停止 Zone 服务
OceanBase 集群的升级,按 Zone 滚动升级。首先选中一个 Zone,将该 Zone 停服。
alter system stop zone 'zone1'; SELECT * FROM __all_zone where name in ('status','merge_status') and zone = 'zone1'; # 输出: +----------------------------+----------------------------+-------+--------------+-------+----------+ | gmt_create | gmt_modified | zone | name | value | info | +----------------------------+----------------------------+-------+--------------+-------+----------+ | 2021-09-25 08:19:05.067944 | 2021-09-29 15:44:27.162171 | zone1 | merge_status | 0 | IDLE | | 2021-09-25 08:19:05.066915 | 2021-09-29 19:36:13.108063 | zone1 | status | 1 | INACTIVE | +----------------------------+----------------------------+-------+--------------+-------+----------+ 2 rows in set (0.028 sec)查看事件日志确认
SELECT DATE_FORMAT(gmt_create, '%b%d %H:%i:%s') gmt_create_ , module, event, name1, value1, name2, value2, rs_svr_ip FROM __all_rootservice_event_history WHERE 1 = 1 AND module IN ('server','root_service','leader_coordinator') AND gmt_create > SUBDATE(now(),interval 1 hour) ORDER BY gmt_create DESC LIMIT 20;输出:
+----------------+--------------------+--------------------------+------------+----------------------+-----------+--------------------------------+---------------+ | gmt_create_ | module | event | name1 | value1 | name2 | value2 | rs_svr_ip | +----------------+--------------------+--------------------------+------------+----------------------+-----------+--------------------------------+---------------+ | Sep29 19:36:40 | root_service | full_rootservice | result | 0 | self_addr | "172.20.249.51:2882" | 172.20.249.51 | | Sep29 19:36:39 | server | load_servers | ret | 0 | has_build | 1 | 172.20.249.51 | | Sep29 19:36:39 | server | online | server | "172.20.249.52:2882" | | | 172.20.249.51 | | Sep29 19:36:39 | server | online | server | "172.20.249.49:2882" | | | 172.20.249.51 | | Sep29 19:36:39 | server | load_servers | ret | 0 | has_build | 1 | 172.20.249.51 | | Sep29 19:36:39 | root_service | finish_start_rootservice | result | 0 | self_addr | "172.20.249.51:2882" | 172.20.249.51 | | Sep29 19:36:39 | root_service | start_rootservice | self_addr | "172.20.249.51:2882" | | | 172.20.249.51 | | Sep29 19:36:39 | root_service | finish_wait_stop | cost | 350586 | | | 172.20.249.52 | | Sep29 19:36:38 | root_service | finish_stop_thread | ret | 0 | self_addr | "172.20.249.52:2882" | 172.20.249.52 | | Sep29 19:36:38 | root_service | stop_rootservice | self_addr | "172.20.249.52:2882" | | | 172.20.249.52 | | Sep29 19:36:38 | leader_coordinator | switch_leader | current_rs | "172.20.249.52:2882" | tenant_id | 1 | 172.20.249.52 | | Sep29 19:36:22 | leader_coordinator | switch_leader | current_rs | "172.20.249.52:2882" | tenant_id | 1 | 172.20.249.52 | | Sep29 19:36:13 | leader_coordinator | switch_leader | current_rs | "172.20.249.52:2882" | tenant_id | 1002 | 172.20.249.52 | | Sep29 19:36:13 | leader_coordinator | switch_leader | current_rs | "172.20.249.52:2882" | tenant_id | 1002 | 172.20.249.52 | | Sep29 19:36:13 | root_service | stop_zone | ret | 0 | sql_text | alter system stop zone 'zone1' | 172.20.249.52 | +----------------+--------------------+--------------------------+------------+----------------------+-----------+--------------------------------+---------------+ 15 rows in set (0.026 sec)
从事件日志看出,当停掉 Zone 的时候,当总控服务(Root Service)的主副本也在该 Zone 时,总控服务会发生切换(停掉老的服务,在新的节点上启动新的服务,其他 Zone 所有节点重新上线),sys 租户和业务租户都发生切换。
确认节点状态
select a.zone,concat(a.svr_ip,':',a.svr_port) observer, usec_to_time(b.last_offline_time) last_offline_time, usec_to_time(b.start_service_time) start_service_time, b.status, usec_to_time(b.stop_time) stop_time from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port) order by a.zone, a.svr_ip;
输出:
+-------+--------------------+----------------------------+----------------------------+--------+----------------------------+ | zone | observer | last_offline_time | start_service_time | status | stop_time | +-------+--------------------+----------------------------+----------------------------+--------+----------------------------+ | zone1 | 172.20.249.52:2882 | 1970-01-01 08:00:00.000000 | 2021-09-25 08:19:06.622351 | active | 1970-01-01 08:00:00.000000 | | zone2 | 172.20.249.49:2882 | 1970-01-01 08:00:00.000000 | 2021-09-25 08:19:07.392669 | active | 1970-01-01 08:00:00.000000 | | zone3 | 172.20.249.51:2882 | 1970-01-01 08:00:00.000000 | 2021-09-26 14:05:58.641570 | active | 1970-01-01 08:00:00.000000 | +-------+--------------------+----------------------------+----------------------------+--------+----------------------------+ 3 rows in set (0.017 sec)
更新节点的 OBSERVER 软件包
通常使用 RPM 包更新节点 OBSERVER 软件包。运行命令为 rpm -uvh oceanbase-xxx.rpm。此命令会自动覆盖可执行文件。但是由 LINUX 系统的设计可知,运行中的 observer 进程依然持有旧的文件句柄,所以不会释放文件。只有在 OceanBase 节点进程退出后才释放。
如果使用 OBD 管理 OceanBase 集群,软件包还需要维护到 OBD 本地仓库或远程仓库中。




