OceanBase 常用运维指令手册
OceanBase 常用运维指令手册
适用版本:OceanBase V4.2.x LTS / V4.3.x / V4.4.x / V4.5.x / V5.0.x(社区版 CE 与企业版命令基本一致) 约定:
#root 或 sudo,$普通用户,obclient>SQL 提示符,<xxx>为占位符。 差异标注:正文用> **版本差异**引用块标注跨版本不一致之处。 更新时间:2026-11
目录
- 版本与支持周期
- 架构与关键概念
- 下载与安装
- 集群部署(obd)
- 集群日常运维
- 连接方式与账号体系
- 租户与资源管理
- 参数管理
- 副本、日志流与合并
- 库表对象与分区
- 备份与恢复
- 数据迁移与同步
- 高可用与容灾切换
- 日志与监控
- 性能诊断
- 空间与容量管理
- 升级与扩缩容
- 高频故障速查
- 危险命令与避坑清单
- 附录:一键巡检脚本
1. 版本与支持周期
1.1 版本体系
OceanBase 的版本号是四段式:主版本.次版本.修订版本.补丁版本,例如 4.2.1.8。企业版还会带 BP 后缀(4.2.1.8 BP2)。
| 版本线 | 类型 | 状态(2026-11) | 说明 |
|---|---|---|---|
| 3.2.x | 旧 LTS | 已停止主线维护 | 存量较多,升级需跨大版本评估 |
| 4.0.x | 过渡版 | 停止维护 | — |
| 4.2.x | LTS | 维护中 | 生产存量最大的长期支持版本 |
| 4.3.x | 特性版 | 维护中 | 引入列存、向量等能力 |
| 4.4.x / 4.5.x | 特性版 | 维护中 | 共享存储、AI 场景增强 |
| 4.6.x | 特性版 | 维护中 | 被 V5.0 承接 |
| 5.0.x | 当前主线 | 最新 | 2026-08 发布 5.0.1 CE,主打并行 DDL、行列混存在线转换、AI Function |
选型提醒:OceanBase 的「LTS」与 MySQL/PG 的 LTS 含义不同——它指长期维护的稳定分支,而 4.3/4.4/4.5 这些特性版也会持续发补丁。生产环境建议固定在某个 LTS 的最新补丁版本(如 4.2.1.x 的最高位),而不是追新特性版。
1.2 版本识别
-- 数据库版本
SELECT OB_VERSION();
-- 详细版本信息(含 build 号与构建时间)
SHOW VARIABLES LIKE 'version%';
SELECT * FROM oceanbase.DBA_OB_SERVERS\G
-- 集群名与 ID
SHOW PARAMETERS LIKE 'cluster';
SHOW PARAMETERS LIKE 'cluster_id';
# 部署工具版本
obd --version
obclient --version
1.3 两种租户模式
OceanBase 最特殊的设计是一个集群可以同时跑 MySQL 模式和 Oracle 模式的租户,两者语法、系统视图、数据类型都不同。
| 维度 | MySQL 模式 | Oracle 模式 |
|---|---|---|
| 建租户参数 | ob_compatibility_mode='mysql' |
ob_compatibility_mode='oracle' |
| 默认库 | 有 information_schema、mysql |
有 SYS、SYSTEM,需 CREATE SCHEMA 或用户即 Schema |
| 大小写 | 表名大小写敏感(受 lower_case_table_names 影响) |
默认大写 |
| 系统视图 | DBA_OB_*、GV$OB_* |
DBA_OB_*、GV$OB_*(部分需 SYS 前缀) |
| 常用客户端 | obclient / MySQL 客户端 |
obclient / SQL*Plus 风格 |
| 连接串 | user@tenant#cluster |
同左 |
坑:Oracle 模式租户里,用户即 Schema,
CREATE USER会自动建同名 Schema;MySQL 模式里CREATE USER和CREATE DATABASE是两件事。迁移脚本不能混用。
2. 架构与关键概念
2.1 组件
应用
│
┌────▼─────┐
│ OBProxy │ 反向代理,路由 SQL 到正确的 OBServer(可选但生产必备)
└────┬─────┘
│
┌──────▼───────────────────────┐
│ OBServer 集群(多 Zone) │
│ ┌────────┐ ┌────────┐ ┌────┐ │
│ │ Zone1 │ │ Zone2 │ │Zone3│ │
│ │ 副本 │ │ 副本 │ │副本 │ │
│ └────────┘ └────────┘ └────┘ │
└──────────────────────────────┘
管理面:OBD(命令行)/ OCP(图形化)/ OCP Express(单机图形化)/ obshell(V4.2+ 内置)
诊断:obdiag
| 组件 | 默认端口 | 作用 |
|---|---|---|
| OBServer | 2881(SQL)/ 2882(RPC) | 数据库进程,一个节点一个 |
| OBProxy | 2883(SQL)/ 2884(Prometheus) | SQL 路由,屏蔽后端节点变化 |
| obshell | 2886 | V4.2+ 内置的运维 API 服务 |
| OCP | 8080 | 图形化运维平台(独立部署) |
| OBAgent | 8088 / 8089 | 监控采集 |
2.2 六个必须搞清楚的概念
| 概念 | 含义 | 为什么重要 |
|---|---|---|
| Zone | 故障域,通常对应一个机房或一个机架 | 副本按 Zone 分布,Zone 挂了不影响多数派 |
| Resource Unit | 资源规格(CPU/内存/日志盘/IOPS) | 租户的资源上限,创建后不能随意缩小 |
| Resource Pool | 资源池,由若干 Unit 组成,绑定 Zone 列表 | 一个 Pool 只能给一个租户用 |
| Tenant | 租户,即一个独立的「数据库实例」 | 资源隔离 + 权限隔离的基本单位 |
| LS(Log Stream) | 日志流,V4.x 的核心概念 | 每个租户至少一个 LS,承载事务日志与副本 |
| 副本类型 | 全能型 / 日志型 / 只读型 | 日志型副本不存数据只投票,用于低成本凑多数派 |
V4.x 最大的架构变化:V3.x 的「分区副本」概念被 LS(日志流) 取代。一个租户的多个分区可以共享一个 LS,副本同步以 LS 为单位。这意味着:
- 故障切换粒度从「分区」变成「LS」,切主更快;
DBA_OB_LS是排查同步问题的第一入口,不再是__all_virtual_clog_stat;- 日志型副本(L 副本)可以只参与投票不存数据,三副本成本可降到 2F+1L。
3. 下载与安装
3.1 官方入口
3.2 安装 OBD(部署工具)
# 方式一:在线安装脚本(需外网)
bash -c "$(curl -s https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/download-center/opensource/oceanbase-all-in-one/install.sh)"
# 方式二:RPM 安装(离线环境推荐)
rpm -ivh ob-deploy-4.5.0-5.el8.x86_64.rpm
obd --version
# 方式三:All-in-One 包(含 obd + oceanbase-ce + obproxy + obclient + libs)
tar xzf oceanbase-all-in-one-*.tar.gz
cd oceanbase-all-in-one/bin && ./install.sh
source ~/.oceanbase-all-in-one/bin/env.sh
# 配置本地镜像(离线包导入)
obd mirror clone /path/to/oceanbase-ce-*.rpm
obd mirror list
obd mirror list local
3.3 单机快速体验
# 一条命令拉起单节点集群(仅测试)
obd demo
# 指定资源
obd demo -c oceanbase-ce --memory_limit 16G --cpu_count 8
# 销毁
obd cluster destroy demo
obd demo默认只建 1 个 Zone、1 个副本,没有任何高可用能力。生产不能用。
3.4 Docker 方式(开发测试)
docker run -d --name ob \
-p 2881:2881 -p 2882:2882 \
-e MODE=mini \
-e OB_TENANT_PASSWORD='Root#123456' \
-v /data/ob:/root/observer/store \
oceanbase/oceanbase-ce:latest
# 首次启动约 1~2 分钟,日志出现 "boot success" 后可连
docker logs -f ob | grep -i "boot success"
# 连接
docker exec -it ob obclient -h127.0.0.1 -P2881 -uroot@sys -p'Root#123456' -Doceanbase -A
4. 集群部署(obd)
4.1 环境要求
| 项 | 要求 |
|---|---|
| 操作系统 | Anolis 8 / CentOS 7.9 / RHEL 8/9 / Ubuntu 20.04+ / 麒麟 V10 / 统信 UOS V20 |
| 内核 | ≥ 4.19 |
| CPU | 生产 ≥ 4 核,推荐 32 核 |
| 内存 | 生产 ≥ 16 GB,长期使用 ≥ 32 GB,推荐 256 GB+ |
| 磁盘 | 数据盘与日志盘必须分开,日志盘 ≥ 内存的 3 倍 |
| 文件系统 | ext4 / xfs,挂载参数 noatime,nodiratime |
| 时钟 | chronyd,偏差 < 100 ms |
| 用户 | 建议专用用户 admin,不建议 root 跑 observer |
# 关闭 THP、调整内核参数(所有节点)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
swapoff -a
cat >> /etc/security/limits.conf <<'EOF'
admin soft nofile 655360
admin hard nofile 655360
admin soft stack unlimited
admin hard stack unlimited
EOF
cat >> /etc/sysctl.conf <<'EOF'
fs.aio-max-nr = 1048576
net.core.somaxconn = 2048
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_tw_reuse = 1
vm.min_free_kbytes = 524288
vm.swappiness = 0
EOF
sysctl -p
4.2 单机集中式配置
# single.yaml —— 单机集中式(1 Zone 1 副本,无 HA)
oceanbase-ce:
servers:
- name: server1
ip: 10.0.0.11
global:
home_path: /home/admin/oceanbase
data_dir: /data/1
redo_dir: /data/log1
devname: eth0
mysql_port: 2881
rpc_port: 2882
zone: zone1
cluster_id: 1
memory_limit: 32G
system_memory: 8G
datafile_size: 100G
log_disk_size: 100G
cpu_count: 16
production_mode: false
server1:
zone: zone1
4.3 三副本分布式配置
# cluster.yaml —— 3 Zone 3 副本,生产最小形态
oceanbase-ce:
servers:
- name: server1
ip: 10.0.0.11
- name: server2
ip: 10.0.0.12
- name: server3
ip: 10.0.0.13
global:
home_path: /home/admin/oceanbase
data_dir: /data/1
redo_dir: /data/log1
devname: eth0
mysql_port: 2881
rpc_port: 2882
cluster_id: 1
memory_limit: 64G
system_memory: 16G
datafile_size: 200G
log_disk_size: 200G
cpu_count: 32
production_mode: true
enable_syslog_recycle: true
max_syslog_file_count: 20
appname: obcluster
server1:
zone: zone1
server2:
zone: zone2
server3:
zone: zone3
obproxy-ce:
servers:
- 10.0.0.21
global:
listen_port: 2883
prometheus_listen_port: 2884
rs_list: 10.0.0.11:2881;10.0.0.12:2881;10.0.0.13:2881
cluster_name: obcluster
obproxy_sys_password: ''
skip_proxy_sys_private_check: true
memory_limit的分配规则:memory_limit是 OBServer 可用的总内存,其中system_memory留给系统(建议 8~16 GB),剩余部分才是租户可分配的。如果memory_limit - system_memory小于所有租户 Unit 内存之和,建租户会直接失败。
4.4 部署与启停
# 1) 预检查
obd cluster check config cluster.yaml
# 2) 部署(只安装,不启动)
obd cluster deploy obcluster -c cluster.yaml
# 3) 启动
obd cluster start obcluster
# 4) 查看
obd cluster list
obd cluster display obcluster
# 5) 停止(-f 强制)
obd cluster stop obcluster
# 6) 重启
obd cluster restart obcluster
# 7) 重载配置(改完 config 后必须执行)
obd cluster edit-config obcluster
obd cluster reload obcluster
# 8) 销毁(不可恢复)
obd cluster destroy obcluster
# 查看部署日志(部署失败时第一时间看)
obd display-trace <trace-id>
# 重新部署某个组件
obd cluster reinstall obcluster -c oceanbase-ce --usable
# 集群重命名
obd cluster rename obcluster obcluster-new
启动顺序:OBServer → OBProxy。停止顺序:OBProxy → OBServer。
obd cluster stop会先尝试优雅停(把 Leader 切走),加-f是强制 kill,可能触发副本补全。
5. 集群日常运维
5.1 节点状态
-- 从 sys 租户执行
SELECT SVR_IP, SVR_PORT, ZONE, STATUS, WITH_ROOTSERVER, START_SERVICE_TIME, STOP_TIME, BLOCK_MIGRATE_IN_TIME
FROM oceanbase.DBA_OB_SERVERS;
-- Zone 列表
SELECT * FROM oceanbase.DBA_OB_ZONES;
-- 各节点资源使用
SELECT SVR_IP, SVR_PORT, ZONE,
ROUND(CPU_CAPACITY/100, 2) cpu_cores,
ROUND(CPU_ASSIGNED/100, 2) cpu_assigned,
ROUND(MEM_CAPACITY/1024/1024/1024, 2) mem_gb,
ROUND(MEM_ASSIGNED/1024/1024/1024, 2) mem_assigned,
ROUND(DATA_DISK_CAPACITY/1024/1024/1024, 2) data_disk_gb,
ROUND(DATA_DISK_IN_USE/1024/1024/1024, 2) data_disk_used_gb
FROM oceanbase.GV$OB_SERVERS;
STATUS 取值:ACTIVE(正常)/ INACTIVE(心跳丢失)/ DELETING(下线中)。
5.2 服务启停(节点级)
# 单节点启停(不影响其他节点)
obd cluster stop obcluster -s 10.0.0.11
obd cluster start obcluster -s 10.0.0.11
# 直接操作 observer(应急)
su - admin -c "/home/admin/oceanbase/bin/observer -r '10.0.0.11:2882:2881;10.0.0.12:2882:2881;10.0.0.13:2882:2881' -p 2881 -P 2882 -z zone1 -d /data/1 -i eth0 -l WARN -c 1 -n obcluster"
# 查看 observer 进程
ps -ef | grep observer | grep -v grep
# 查看监听端口
ss -lntp | grep -E '2881|2882|2886'
5.3 配置变更
# 交互式编辑(会重启相关组件)
obd cluster edit-config obcluster
# 只改参数不重启(推荐,用 SQL 改)
-- 系统参数(sys 租户)
ALTER SYSTEM SET memory_limit = '64G';
ALTER SYSTEM SET enable_syslog_recycle = true;
-- 租户参数
ALTER SYSTEM SET ob_query_timeout = 10000000 TENANT = tenant1;
ALTER SYSTEM SET ob_tcp_invited_nodes = '%' TENANT = ALL;
ALTER SYSTEM SET ob_tcp_invited_nodes = '%' TENANT = ALL_USER;
参数三级别:
ALTER SYSTEM SET不带TENANT改的是 sys 租户;带TENANT = xxx改指定租户;带TENANT = ALL改所有用户租户。改错范围会导致「只在 sys 生效,业务租户没变」的排查困境。
6. 连接方式与账号体系
6.1 连接串格式
OceanBase 的账号格式是它最容易出错的地方:
用户名@租户名#集群名
# 直连 OBServer(绕过 OBProxy)
obclient -h 10.0.0.11 -P 2881 -uroot@sys -p'xxx' -Doceanbase -A
# 通过 OBProxy 连接业务租户
obclient -h 10.0.0.21 -P 2883 -uapp@tenant1#obcluster -p'xxx' -Dapp_db -A
# MySQL 客户端也可以(协议兼容)
mysql -h 10.0.0.21 -P 2883 -u'app@tenant1#obcluster' -p'xxx' -Dapp_db
# 执行单条
obclient -h 10.0.0.21 -P 2883 -u'app@tenant1#obcluster' -p'xxx' -e "SELECT COUNT(*) FROM t1"
| 场景 | 用户名写法 |
|---|---|
| sys 租户 root | root@sys |
| sys 租户普通用户 | proxyro@sys |
| 业务租户 root | root@tenant1 |
| 业务租户普通用户 | app@tenant1 |
| 通过 OBProxy + 集群名 | app@tenant1#obcluster |
| Oracle 模式 | app@tenant1(用户即 Schema) |
6.2 账号管理(MySQL 模式)
-- 切到目标租户
-- 连接时用 root@tenant1,或在 sys 租户下执行:
ALTER SYSTEM SET ob_tcp_invited_nodes='%' TENANT=tenant1;
-- 建用户
CREATE USER 'app'@'%' IDENTIFIED BY 'Strong#2026';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app'@'%';
GRANT ALL PRIVILEGES ON app_db.* TO 'dba'@'%';
FLUSH PRIVILEGES;
-- 查看
SELECT User, Host FROM mysql.user;
SHOW GRANTS FOR 'app'@'%';
-- 改密
ALTER USER 'app'@'%' IDENTIFIED BY 'New#2026';
-- 锁定
ALTER USER 'app'@'%' ACCOUNT LOCK;
-- 删除
DROP USER 'app'@'%';
6.3 账号管理(Oracle 模式)
-- Oracle 模式下用户即 Schema
CREATE USER app IDENTIFIED BY "Strong#2026";
GRANT CONNECT, RESOURCE TO app;
GRANT SELECT ANY TABLE TO app;
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW TO app;
-- 查看
SELECT USERNAME, ACCOUNT_STATUS, CREATED FROM DBA_USERS;
-- 改密
ALTER USER app IDENTIFIED BY "New#2026";
-- 锁定 / 解锁
ALTER USER app ACCOUNT LOCK;
ALTER USER app ACCOUNT UNLOCK;
-- 删除(CASCADE 会连带删除对象)
DROP USER app CASCADE;
Oracle 模式的密码规则:默认要求大小写+数字+特殊字符,且不能用
IDENTIFIED BY 'xxx'单引号(要双引号)。这是从 Oracle 迁过来时最容易被卡住的一步。
6.4 会话管理
-- 当前会话
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, LEFT(INFO, 100) INFO
FROM oceanbase.GV$OB_PROCESSLIST
WHERE COMMAND <> 'Sleep'
ORDER BY TIME DESC;
-- 按租户汇总连接数
SELECT TENANT, COUNT(*) cnt FROM oceanbase.GV$OB_PROCESSLIST GROUP BY TENANT ORDER BY cnt DESC;
-- 杀会话(需要 SESSION 权限)
ALTER SYSTEM KILL SESSION 'id';
-- 或
KILL <session_id>;
7. 租户与资源管理
这是 OceanBase 运维的核心。资源 → 池 → 租户三步走,顺序不能反。
7.1 资源单元(Resource Unit)
-- 创建资源规格
CREATE RESOURCE UNIT unit_8c16g
MAX_CPU 8, MIN_CPU 8,
MEMORY_SIZE '16G',
LOG_DISK_SIZE '32G',
MAX_IOPS 10000, MIN_IOPS 10000,
IOPS_WEIGHT 1;
-- 查看
SELECT UNIT_ID, NAME, MAX_CPU, MIN_CPU,
ROUND(MEMORY_SIZE/1024/1024/1024,2) mem_gb,
ROUND(LOG_DISK_SIZE/1024/1024/1024,2) log_gb,
MAX_IOPS, MIN_IOPS
FROM oceanbase.DBA_OB_UNIT_CONFIGS;
-- 修改(只能调大或调部分参数)
ALTER RESOURCE UNIT unit_8c16g MAX_CPU 16, MEMORY_SIZE '32G';
-- 删除(需先解除引用)
DROP RESOURCE UNIT unit_8c16g;
MIN_CPU与MAX_CPU之间是弹性范围。设MIN_CPU < MAX_CPU可以做超卖,但要保证所有租户MIN_CPU之和不超过节点物理核数,否则高负载时会互相抢。
7.2 资源池(Resource Pool)
-- 创建(UNIT_NUM 表示每个 Zone 放几个 Unit)
CREATE RESOURCE POOL pool_tenant1
UNIT = 'unit_8c16g',
UNIT_NUM = 1,
ZONE_LIST = ('zone1','zone2','zone3');
-- 查看
SELECT POOL_ID, NAME, UNIT_COUNT, UNIT_CONFIG_ID, ZONE_LIST, TENANT_ID
FROM oceanbase.DBA_OB_RESOURCE_POOLS;
-- 修改 Unit 规格(在线扩容)
ALTER RESOURCE POOL pool_tenant1 UNIT = 'unit_16c32g';
-- 删除(需先无租户引用)
DROP RESOURCE POOL pool_tenant1;
| 参数 | 说明 |
|---|---|
UNIT_NUM |
每个 Zone 内的 Unit 数量。UNIT_NUM=1 + 3 Zone = 3 副本 |
ZONE_LIST |
资源池覆盖的 Zone,必须与副本分布一致 |
UNIT |
引用的 Unit 规格名 |
改规格的正确顺序:先
CREATE RESOURCE UNIT新规格 →ALTER RESOURCE POOL ... UNIT = 新规格→ 观察负载。直接ALTER RESOURCE UNIT会影响所有引用它的池。
7.3 创建租户
-- MySQL 模式租户
CREATE TENANT tenant1
RESOURCE_POOL_LIST = ('pool_tenant1'),
PRIMARY_ZONE = 'zone1;zone2;zone3',
LOCALITY = 'FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3',
SET ob_compatibility_mode = 'mysql',
ob_tcp_invited_nodes = '%',
ob_query_timeout = 10000000;
-- Oracle 模式租户(多一个参数)
CREATE TENANT tenant_ora
RESOURCE_POOL_LIST = ('pool_ora'),
PRIMARY_ZONE = 'zone1;zone2;zone3',
LOCALITY = 'FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3',
SET ob_compatibility_mode = 'oracle',
ob_tcp_invited_nodes = '%';
-- 查看
SELECT TENANT_ID, TENANT_NAME, TENANT_TYPE, COMPATIBILITY_MODE, PRIMARY_ZONE,
LOCALITY, STATUS, CREATE_TIME
FROM oceanbase.DBA_OB_TENANTS;
-- 查看租户资源使用
SELECT TENANT_ID, TENANT_NAME,
ROUND(MAX_CPU,2) max_cpu,
ROUND(MIN_CPU,2) min_cpu,
ROUND(MEMORY_SIZE/1024/1024/1024,2) mem_gb
FROM oceanbase.DBA_OB_TENANT_RESOURCES;
LOCALITY 语法要点:
| 写法 | 含义 |
|---|---|
FULL{1}@zone1 |
zone1 上 1 个全能型副本 |
FULL{2}@zone1 |
zone1 上 2 个全能型副本(同 Zone 多副本,抗单机故障) |
L{1}@zone2 |
zone2 上 1 个日志型副本(只投票不存数据) |
R{1}@zone3 |
zone3 上 1 个只读型副本(读流量分担) |
三副本最低成本方案:FULL{1}@zone1, FULL{1}@zone2, L{1}@zone3 —— 2 份数据 + 1 份日志,成本降 1/3,仍能容忍 1 个 Zone 故障。
7.4 租户日常操作
-- 改 Primary Zone(切主)
ALTER TENANT tenant1 PRIMARY_ZONE = 'zone2;zone1;zone3';
-- 改 Locality(加副本/换副本类型)
ALTER TENANT tenant1 LOCALITY = 'FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3, R{1}@zone4';
-- 改租户参数
ALTER TENANT tenant1 SET ob_tcp_invited_nodes = '%';
-- 锁定租户(禁止连接,保留数据)
ALTER TENANT tenant1 LOCK;
ALTER TENANT tenant1 UNLOCK;
-- 只读租户
ALTER TENANT tenant1 READ ONLY;
-- 删除租户(先删再回收资源池)
DROP TENANT tenant1;
DROP TENANT tenant1 FORCE; -- 有残留 LS 时强制
-- 查看租户级任务(V4.x 重要)
SELECT * FROM oceanbase.DBA_OB_TENANT_JOBS ORDER BY START_TIME DESC LIMIT 20;
# obd 也能管租户
obd cluster tenant create obcluster -n tenant2 --max-cpu 8 --min-cpu 8 --memory-size 16G --zone-list zone1,zone2,zone3
obd cluster tenant show obcluster -n tenant2
obd cluster tenant drop obcluster -n tenant2
删租户是异步的。
DROP TENANT后租户进入TENANT_STATUS='DROPPING',需要等 GC(默认 1 小时后才能真正清理)。期间资源池不能删。急着重建议DROP TENANT ... FORCE,但会跳过回收检查。
7.5 租户资源不足的处理
-- 1) 看哪个租户吃满了
SELECT TENANT_ID, TENANT_NAME, MAX_CPU, MIN_CPU,
ROUND(MEMORY_SIZE/1024/1024/1024,2) mem_gb
FROM oceanbase.DBA_OB_TENANT_RESOURCES ORDER BY MAX_CPU DESC;
-- 2) 看节点剩余可分配
SELECT SVR_IP, ZONE,
ROUND((CPU_CAPACITY-CPU_ASSIGNED)/100, 2) cpu_free,
ROUND((MEM_CAPACITY-MEM_ASSIGNED)/1024/1024/1024, 2) mem_free_gb
FROM oceanbase.GV$OB_SERVERS;
-- 3) 扩租户(在线,无需重启)
ALTER RESOURCE UNIT unit_8c16g MAX_CPU 16, MEMORY_SIZE '32G';
-- 若 Unit 已在池中,ALTER RESOURCE UNIT 会自动生效到所有引用它的租户
8. 参数管理
8.1 查看参数
-- 当前租户参数
SHOW PARAMETERS LIKE '%memory%';
SHOW PARAMETERS LIKE 'ob_query_timeout';
-- 指定租户
SHOW PARAMETERS LIKE '%timeout%' TENANT = tenant1;
-- 集群级参数(sys 租户)
SELECT * FROM oceanbase.GV$OB_PARAMETERS WHERE NAME = 'memory_limit';
-- 参数详情(含取值范围、是否可动态修改)
SELECT NAME, VALUE, DATA_TYPE, INFO, SECTION
FROM oceanbase.GV$OB_PARAMETERS
WHERE NAME IN ('memory_limit','system_memory','cpu_count','enable_syslog_recycle');
8.2 关键参数
| 参数 | 级别 | 建议 | 说明 |
|---|---|---|---|
memory_limit |
集群 | 物理内存 80% | OBServer 总内存上限 |
system_memory |
集群 | 8~16 GB | 系统预留,剩余才给租户 |
cpu_count |
集群 | 物理核数 | 超线程按物理核算 |
datafile_size |
集群 | 按数据量 1.5 倍 | 数据文件初始大小,不足会报 -4030 |
log_disk_size |
集群 | 内存的 3 倍 | 日志盘,写满会导致集群 hang |
enable_syslog_recycle |
集群 | true |
自动清理系统日志,必开 |
max_syslog_file_count |
集群 | 20~50 | 日志文件保留数 |
ob_query_timeout |
租户 | 10s~30s | 查询超时(微秒) |
ob_trx_timeout |
租户 | 100s | 事务超时(微秒) |
ob_trx_idle_timeout |
租户 | 120s | 空闲事务超时 |
ob_tcp_invited_nodes |
租户 | % 或具体网段 |
白名单,默认 127.0.0.1,新建租户连不上多半是它 |
ob_enable_sql_audit |
租户 | true |
SQL 审计,诊断必需 |
enable_perf_event |
租户 | true |
性能事件采集 |
major_freeze_duty_time |
租户 | 02:00 |
每日合并时间 |
undo_retention |
租户 | 86400(秒) | undo 保留时长,影响闪回查询 |
ob_enable_rich_vector_format |
租户 | — | V4.3+ 向量能力相关 |
-- 常用的三条即时调整
ALTER SYSTEM SET ob_query_timeout = 30000000 TENANT = tenant1; -- 30s
ALTER SYSTEM SET ob_tcp_invited_nodes = '%' TENANT = tenant1; -- 放开白名单
ALTER SYSTEM SET enable_syslog_recycle = true; -- 开日志回收
8.3 参数生效级别
| 级别 | 命令 | 生效范围 |
|---|---|---|
| 集群级 | ALTER SYSTEM SET x=v;(sys 租户) |
所有 OBServer |
| 租户级 | ALTER SYSTEM SET x=v TENANT=t; |
指定租户所有副本 |
| 会话级 | SET SESSION x=v; / SET x=v; |
当前连接 |
| 全局(租户内) | SET GLOBAL x=v; |
该租户新连接 |
排查「参数改了没生效」的顺序:
SHOW PARAMETERS LIKE 'x'看当前值 → 确认改的是哪个租户(TENANT子句)→ 确认是否需要重连(会话级参数)→SELECT * FROM GV$OB_PARAMETERS WHERE NAME='x'看各节点是否一致。
9. 副本、日志流与合并
9.1 日志流(LS)
-- 查看所有日志流(sys 租户看全集群)
SELECT LS_ID, TENANT_ID, STATUS, PRIMARY_ZONE, UNIT_GROUP_ID
FROM oceanbase.CDB_OB_LS
ORDER BY TENANT_ID, LS_ID;
-- 单个租户内查看
SELECT * FROM oceanbase.DBA_OB_LS;
-- LS 副本分布
SELECT LS_ID, SVR_IP, SVR_PORT, ZONE, REPLICA_TYPE, ROLE
FROM oceanbase.CDB_OB_LS_LOCATIONS
WHERE TENANT_ID = 1002
ORDER BY LS_ID;
-- 查看某 LS 的同步进度
SELECT * FROM oceanbase.GV$OB_LS_LOG_STAT WHERE LS_ID = 1;
REPLICA_TYPE:FULL(全能型)/ LOGONLY(日志型)/ READONLY(只读型)。
9.2 切主与负载均衡
-- 把某租户所有 Leader 切到指定 Zone
ALTER SYSTEM SWITCH ALL SERVER TO LEADER;
ALTER SYSTEM SWITCH ALL SERVER TO FOLLOWER;
-- 租户级切主
ALTER SYSTEM SWITCH ALL SERVER TO LEADER TENANT = tenant1;
-- Zone 级负载均衡(把 Leader 打散到各 Zone)
ALTER SYSTEM BALANCE ZONE 'zone1';
-- 查看 Leader 分布
SELECT ZONE, COUNT(*) leader_cnt
FROM oceanbase.CDB_OB_LS_LOCATIONS
WHERE ROLE = 'LEADER' AND TENANT_ID = 1002
GROUP BY ZONE;
切主是在线操作,业务会有秒级抖动(连接闪断 + 事务重试)。大批量切主前先确认应用有重连机制。
9.3 合并(Major Compaction)
合并是 OceanBase 把内存中的增量数据与基线数据融合的过程,直接影响查询性能和磁盘占用。
-- 查看合并状态
SELECT * FROM oceanbase.DBA_OB_MAJOR_COMPACTION\G
-- 关键字段:STATUS(IDLE / MERGING)、FROZEN_SCN、GLOBAL_BROADCAST_SCN
-- sys 租户看所有租户的合并
SELECT TENANT_ID, STATUS, FROZEN_SCN, GLOBAL_BROADCAST_SCN, START_TIME, MODIFIED_TIME
FROM oceanbase.CDB_OB_MAJOR_COMPACTION
ORDER BY TENANT_ID;
-- 手动触发合并(立即)
ALTER SYSTEM MAJOR FREEZE;
-- 租户级
ALTER SYSTEM MAJOR FREEZE TENANT = tenant1;
-- 只冻结不合并(排查用)
ALTER SYSTEM MINOR FREEZE;
-- 暂停/恢复合并(大促期间避免 IO 抖动)
ALTER SYSTEM SUSPEND MERGE;
ALTER SYSTEM RESUME MERGE;
ALTER SYSTEM SUSPEND MERGE TENANT = tenant1;
-- 查看合并进度
SELECT * FROM oceanbase.DBA_OB_ZONE_MAJOR_COMPACTION;
SELECT * FROM oceanbase.GV$OB_COMPACTION_PROGRESS;
SELECT * FROM oceanbase.GV$OB_COMPACTION_DIAGNOSE;
| 参数 | 默认 | 说明 |
|---|---|---|
major_freeze_duty_time |
02:00 |
每日定时合并 |
enable_major_freeze |
true |
关闭后只能手工合并 |
merger_check_interval |
10m |
合并调度检查间隔 |
minor_merge_concurrency |
0(自适应) | 小合并并发 |
合并失败的典型原因:磁盘不足(
-4030)、log_disk_size写满、某个副本长时间不可用。合并卡住超过 24 小时必须处理,否则增量数据堆积会导致查询变慢、内存压力升高。 处理:SELECT * FROM GV$OB_COMPACTION_DIAGNOSE看具体原因 → 补磁盘 →ALTER SYSTEM RESUME MERGE。
9.4 副本迁移
-- 添加副本(在线)
ALTER SYSTEM ADD REPLICA LS = 1001
LOCALITY = 'FULL{1}@zone4';
-- 删除副本
ALTER SYSTEM REMOVE REPLICA LS = 1001
LOCALITY = 'FULL{1}@zone4';
-- 迁移 Unit(把某个 Unit 从一台机器挪到另一台)
ALTER SYSTEM MIGRATE UNIT = 1001 DESTINATION = '10.0.0.15:2882';
-- 取消迁移
ALTER SYSTEM CANCEL MIGRATE UNIT = 1001;
-- 查看 Unit 分布
SELECT UNIT_ID, TENANT_ID, ZONE, SVR_IP, SVR_PORT, STATUS
FROM oceanbase.DBA_OB_UNITS ORDER BY TENANT_ID, UNIT_ID;
10. 库表对象与分区
10.1 基础对象(MySQL 模式)
CREATE DATABASE app_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE TABLE app_db.orders (
id BIGINT NOT NULL AUTO_INCREMENT,
order_no VARCHAR(32) NOT NULL,
user_id BIGINT NOT NULL,
amount DECIMAL(18,2) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_order_no (order_no),
KEY idx_user (user_id)
) DEFAULT CHARSET=utf8mb4;
-- 查看
SHOW CREATE TABLE app_db.orders;
SHOW TABLES FROM app_db;
DESC app_db.orders;
-- 查看表在哪些节点有副本(V4.x 重要)
SELECT TABLE_NAME, PARTITION_NAME, LS_ID, ZONE, SVR_IP, ROLE
FROM oceanbase.DBA_OB_TABLE_LOCATIONS
WHERE TABLE_NAME = 'orders';
10.2 分区表
-- Range 分区(按时间)
CREATE TABLE app_db.logs (
id BIGINT NOT NULL,
log_time DATETIME NOT NULL,
msg VARCHAR(500),
PRIMARY KEY (id, log_time)
) PARTITION BY RANGE COLUMNS(log_time) (
PARTITION p202610 VALUES LESS THAN ('2026-11-01'),
PARTITION p202611 VALUES LESS THAN ('2026-12-01'),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
-- Hash 分区(打散写入)
CREATE TABLE app_db.sessions (
id BIGINT NOT NULL,
data VARCHAR(1000),
PRIMARY KEY (id)
) PARTITION BY HASH(id) PARTITIONS 16;
-- 二级分区(先按时间,再按用户哈希)
CREATE TABLE app_db.trade (
id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
trade_time DATETIME NOT NULL,
PRIMARY KEY (id, trade_time, user_id)
) PARTITION BY RANGE COLUMNS(trade_time)
SUBPARTITION BY HASH(user_id) SUBPARTITIONS 8 (
PARTITION p202611 VALUES LESS THAN ('2026-12-01'),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
-- 分区维护
ALTER TABLE app_db.logs ADD PARTITION (PARTITION p202612 VALUES LESS THAN ('2027-01-01'));
ALTER TABLE app_db.logs DROP PARTITION p202610;
ALTER TABLE app_db.logs TRUNCATE PARTITION p202610;
分区键必须在主键里。这是 MySQL 系分区表的通病,OceanBase 也一样:
PRIMARY KEY (id, log_time)而不是只有id。漏了会直接报错。
10.3 表组(Table Group)
OceanBase 特有的优化手段:把经常 JOIN 的表放进同一个表组,让它们的分区落在同一台机器上,避免跨机 JOIN。
-- 创建表组(按分区对齐)
CREATE TABLEGROUP tg_order SHARDING = 'PARTITION';
-- 建表时绑定
CREATE TABLE app_db.orders (...) TABLEGROUP = tg_order PARTITION BY HASH(id) PARTITIONS 16;
CREATE TABLE app_db.order_items (...) TABLEGROUP = tg_order PARTITION BY HASH(order_id) PARTITIONS 16;
-- 查看
SHOW TABLEGROUPS;
SELECT * FROM oceanbase.DBA_OB_TABLEGROUPS;
V5.0 新增:支持 Zone 级表组和
SHARDING = 'SUBPARTITION'的二级分区对齐,二级分区键相同的数据会绑定到同一日志流。跨分区事务性能提升明显,但要求表组内所有表的分区类型/数量/边界完全一致。
10.4 建表时的几个约束
| 约束 | 说明 |
|---|---|
| 主键必须包含分区键 | 分区表硬性要求 |
| 自增列必须是主键或唯一键的一部分 | MySQL 模式限制 |
| 单表分区数 | 建议 ≤ 8192,过多会拖慢 DDL |
| 大对象 | LOB 字段建议单独表,避免主表膨胀 |
| 字符集 | 库级统一 utf8mb4,跨库 JOIN 时字符集不一致会退化为全表扫描 |
11. 备份与恢复
11.1 备份架构
OceanBase 的备份分三层:
基线备份(Base)—— 全量数据文件
+
增量备份(Incremental)—— 相对上次基线/增量的变化
+
日志归档(ArchiveLog)—— clog 持续归档,支撑 PITR
11.2 配置备份目的端
-- sys 租户执行
ALTER SYSTEM SET DATA_BACKUP_DEST = 'oss://bucket/obbackup?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=xxx';
ALTER SYSTEM SET LOG_ARCHIVE_DEST = 'oss://bucket/obarchive?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=xxx';
-- NFS 方式
ALTER SYSTEM SET DATA_BACKUP_DEST = 'file:///backup/ob/data';
ALTER SYSTEM SET LOG_ARCHIVE_DEST = 'file:///backup/ob/archive';
-- 确认
SHOW PARAMETERS LIKE '%backup_dest%';
SHOW PARAMETERS LIKE '%archive_dest%';
NFS 场景下,所有 OBServer 节点都要挂载同一路径且有写权限。备份是每个副本各写各的,路径不一致会导致部分副本备份失败。
11.3 执行备份
-- 1) 开启日志归档(必须先做,否则无法 PITR)
ALTER SYSTEM ARCHIVELOG;
ALTER SYSTEM NOARCHIVELOG;
-- 查看归档状态
SELECT * FROM oceanbase.DBA_OB_ARCHIVELOG\G
SELECT * FROM oceanbase.DBA_OB_ARCHIVELOG_PIECE_FILES ORDER BY START_SCN DESC LIMIT 5;
-- 2) 全量备份(集群级)
ALTER SYSTEM BACKUP DATABASE;
-- 3) 全量备份(租户级)
ALTER SYSTEM BACKUP TENANT tenant1;
-- 4) 增量备份
ALTER SYSTEM BACKUP INCREMENTAL DATABASE;
ALTER SYSTEM BACKUP INCREMENTAL TENANT tenant1;
-- 5) 查看备份任务
SELECT JOB_ID, TENANT_ID, BACKUP_TYPE, STATUS, START_TIMESTAMP, END_TIMESTAMP,
ROUND(TOTAL_BYTES/1024/1024/1024, 2) total_gb
FROM oceanbase.DBA_OB_BACKUP_JOBS ORDER BY JOB_ID DESC LIMIT 10;
-- 6) 查看备份集
SELECT BACKUP_SET_ID, TENANT_ID, BACKUP_TYPE, STATUS,
ROUND(TOTAL_BYTES/1024/1024/1024, 2) size_gb, START_TIMESTAMP, END_TIMESTAMP
FROM oceanbase.DBA_OB_BACKUP_SET_FILES ORDER BY BACKUP_SET_ID DESC LIMIT 10;
-- 7) 取消备份
ALTER SYSTEM CANCEL BACKUP;
ALTER SYSTEM CANCEL BACKUP TENANT tenant1;
11.4 恢复
-- 恢复到新租户(推荐,不影响原租户)
ALTER SYSTEM RESTORE tenant1_restore
FROM 'file:///backup/ob/data'
WITH 'pool_list=pool_restore,restore_timestamp=2026-11-05 09:30:00';
-- 查看恢复进度
SELECT * FROM oceanbase.DBA_OB_RESTORE_PROGRESS\G
SELECT * FROM oceanbase.DBA_OB_RESTORE_HISTORY ORDER BY JOB_ID DESC LIMIT 5;
-- 取消恢复
ALTER SYSTEM CANCEL RESTORE tenant1_restore;
-- 恢复完成后,新租户是只读状态,需要显式激活
ALTER SYSTEM ACTIVATE TENANT tenant1_restore;
-- 验证数据
-- 连接 tenant1_restore 后 SELECT COUNT(*)
| 参数 | 说明 |
|---|---|
pool_list |
目标资源池,需预先创建且规格不小于原租户 |
restore_timestamp |
恢复到的时间点,必须在归档范围内 |
restore_option |
高级选项,如 dest_tenant_name |
backup_set_id |
指定恢复某个备份集 |
concurrency |
恢复并发度 |
恢复的三个前提:① 有全量备份;② 归档日志连续(中间不能断);③ 目标资源池规格 ≥ 原租户。少任何一个都会失败,且报错信息不直观,必须查
DBA_OB_RESTORE_PROGRESS的ERROR_CODE。
11.5 备份策略建议
| 对象 | 频率 | 保留 | 说明 |
|---|---|---|---|
| 全量 | 每天 1 次 | 7 天 | 低峰执行,避开合并时间 |
| 增量 | 每 6 小时 | 3 天 | 基于上次基线 |
| 归档日志 | 持续 | 7 天 | PITR 依赖 |
| 异地副本 | 每天同步 | 30 天 | 对象存储跨区域复制 |
-- 清理过期备份(保留最近 7 天)
ALTER SYSTEM DELETE BACKUP BACKUP_SET_ID = 12;
-- 或按时间
ALTER SYSTEM DELETE OBSOLETE BACKUP;
12. 数据迁移与同步
12.1 OBLoader / OBDumper
# 导出(OBDumper)
./obdumper \
-h 10.0.0.21 -P 2883 -u app@tenant1#obcluster -p 'xxx' \
-D app_db --table orders \
--file-format csv --column-separator ',' \
-f /data/export
# 导入(OBLoader)
./obloader \
-h 10.0.0.21 -P 2883 -u app@tenant1#obcluster -p 'xxx' \
-D app_db --table orders \
--file-format csv --column-separator ',' \
-f /data/export
# 只导结构
./obdumper -h ... --sys-password 'xxx' -D app_db --table orders --ddl -f /data/ddl
12.2 OMS(数据迁移服务)
OMS 是图形化迁移平台,支持 MySQL / Oracle / PG / OB 之间的全量+增量迁移。
# 部署 OMS(独立机器,需 Docker)
docker run -d --name oms \
-p 8089:8089 \
-v /data/oms:/home/admin/logs \
-e OMS_DB_HOST=10.0.0.31 \
reg.docker.alibaba-inc.com/oms/oms:latest
迁移任务的关键检查点:
| 阶段 | 检查项 |
|---|---|
| 结构迁移 | 数据类型映射、字符集、分区键、自增列 |
| 全量迁移 | 行数校验、大字段完整性 |
| 增量同步 | 延迟(OMS 控制台的 Latency)、DDL 同步、冲突处理 |
| 切换 | 停写 → 追平延迟 → 校验 → 切流量 |
12.3 从 MySQL 迁入的兼容问题
| 问题 | 表现 | 处置 |
|---|---|---|
| 存储过程 | 部分语法不支持 | 改写到应用层或用 OB 的 PL 重写 |
| 触发器 | 支持但性能差 | 尽量去掉 |
ON DUPLICATE KEY UPDATE |
支持 | — |
| 外键 | 支持但性能影响大,生产建议关闭 | SET foreign_key_checks=0 |
AUTO_INCREMENT 连续性 |
不保证 | 业务不要依赖 |
FULLTEXT 索引 |
V4.x 支持有限 | 改用外部检索 |
JSON 函数 |
部分函数缺失 | 迁移前用 obdumper 的兼容性报告核对 |
13. 高可用与容灾切换
13.1 故障自动切换
OceanBase 的切主是自动的:LS 的 Leader 所在节点失联,剩余副本在 lease 超时后自动选主。
| 参数 | 默认 | 说明 |
|---|---|---|
ob_trx_timeout |
100s | 事务超时 |
ls_lease_duration |
10s(内部) | Leader 租约,影响切主速度 |
enable_auto_leader_switch |
true |
自动切主开关 |
server_permanent_offline_time |
3600s | 节点永久下线判定,超过后补副本 |
-- 查看切主情况
SELECT * FROM oceanbase.DBA_OB_SERVER_EVENT_HISTORY
WHERE EVENT_NAME LIKE '%switch%' ORDER BY TIMESTAMP DESC LIMIT 20;
-- 查看副本同步延迟
SELECT LS_ID, SVR_IP, ZONE, ROLE,
ROUND(END_SCN - START_SCN) scn_gap
FROM oceanbase.GV$OB_LS_LOG_STAT
WHERE TENANT_ID = 1002 ORDER BY scn_gap DESC;
13.2 计划内主备切换
-- 方式一:改 Primary Zone(推荐,平滑)
ALTER TENANT tenant1 PRIMARY_ZONE = 'zone2;zone1;zone3';
-- 方式二:手工切某个 LS
ALTER SYSTEM SWITCH REPLICA LS = 1001 TO 'zone2';
-- 方式三:整机维护前把 Leader 全部赶走
ALTER SYSTEM SWITCH ALL SERVER TO FOLLOWER;
-- 维护完成后恢复
ALTER SYSTEM SWITCH ALL SERVER TO LEADER;
# obd 层面:优雅停止单节点(会先把 Leader 切走)
obd cluster stop obcluster -s 10.0.0.11
13.3 两地三中心
同城 A(zone1, zone2)—— 2F,同步
同城 B(zone3) —— 1F,同步
异地 C(zone4) —— 1R 或 1L,异步
-- 建异地只读副本
ALTER TENANT tenant1 LOCALITY =
'FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3, R{1}@zone4';
-- 切换异地为可写(灾难场景)
ALTER TENANT tenant1 PRIMARY_ZONE = 'zone4';
异地副本的 RPO 不为 0。跨城异步复制意味着灾难发生时可能丢最后几秒的数据。要 RPO=0 必须全同步,但那样写入延迟由最远节点决定,通常不可接受。这是物理限制,不是产品缺陷。
13.4 仲裁服务(V4.1+)
两副本场景下(如两地两中心),可以用仲裁服务(Arbitration Service)替代第三副本,避免脑裂。
-- 部署仲裁服务后
ALTER SYSTEM ADD ARBITRATION SERVICE '10.0.0.99:2882';
-- 查看
SELECT * FROM oceanbase.DBA_OB_ARBITRATION_SERVICE;
SELECT * FROM oceanbase.DBA_OB_ARBITRATION_SERVICE_STATUS;
-- 租户启用仲裁
ALTER TENANT tenant1 ARBITRATION SERVICE '10.0.0.99:2882';
-- 移除
ALTER SYSTEM REMOVE ARBITRATION SERVICE '10.0.0.99:2882';
14. 日志与监控
14.1 日志文件
| 日志 | 路径 | 说明 |
|---|---|---|
| observer 主日志 | $HOME/admin/oceanbase/log/observer.log |
最常用,包含 ERROR/WARN |
| 选举日志 | election.log |
切主、选主问题看这个 |
| RootsService | rootservice.log |
RS 相关(DDL、负载均衡) |
| 事务日志 | transaction.log |
事务回滚、锁冲突 |
| SQL 审计 | 存表 GV$OB_SQL_AUDIT |
不落文件 |
# 实时跟踪
tail -f /home/admin/oceanbase/log/observer.log
# 找错误(带 trace id 便于串联)
grep -E '\[ERROR\]|\[WARN\]' observer.log | tail -100
# 按 trace_id 追一条 SQL 的全链路
grep '<trace_id>' observer.log
# 统计错误码 Top10
grep -oE 'ret=-\?[0-9]+' observer.log | sort | uniq -c | sort -rn | head -10
# 日志轮转配置(必须开,否则日志会吃满磁盘)
# enable_syslog_recycle=true, max_syslog_file_count=20
14.2 SQL 审计
-- 最近 1 小时最慢的 SQL
SELECT SVR_IP, TENANT_ID, TRACE_ID,
ROUND(ELAPSED_TIME/1000, 2) elapsed_ms,
ROUND(EXECUTE_TIME/1000, 2) exec_ms,
ROUND(QUEUE_TIME/1000, 2) queue_ms,
ROW_COUNT, RET_CODE,
LEFT(QUERY_SQL, 150) sql
FROM oceanbase.GV$OB_SQL_AUDIT
WHERE REQUEST_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY ELAPSED_TIME DESC LIMIT 20;
-- 按 SQL ID 聚合(找 TOP 模板)
SELECT SQL_ID, COUNT(*) cnt,
ROUND(AVG(ELAPSED_TIME)/1000, 2) avg_ms,
ROUND(MAX(ELAPSED_TIME)/1000, 2) max_ms,
SUM(RETURN_ROWS) rows_total,
LEFT(MIN(QUERY_SQL), 100) sample
FROM oceanbase.GV$OB_SQL_AUDIT
WHERE REQUEST_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY SQL_ID ORDER BY avg_ms DESC LIMIT 20;
-- 按用户统计
SELECT USER_NAME, COUNT(*) cnt, ROUND(SUM(ELAPSED_TIME)/1000000, 2) total_sec
FROM oceanbase.GV$OB_SQL_AUDIT
WHERE REQUEST_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY USER_NAME ORDER BY total_sec DESC;
14.3 监控接入
# OBAgent + Prometheus + Grafana(obd 部署时自动装)
# Grafana 地址:http://<host>:3000
# Prometheus:http://<host>:9090
# OCP Express(单机图形化,V4.2+ 内置)
# 地址:http://<host>:2886
# OCP(集群图形化,独立部署)
# 地址:http://<ocp-host>:8080
关键监控指标:
| 指标 | 阈值 | 含义 |
|---|---|---|
ob_tenant_cpu_percent |
> 80% 持续 | 租户 CPU 吃紧 |
ob_tenant_memstore_percent |
> 80% | 内存增量区压力,可能触发提前合并 |
ob_disk_usage |
> 85% | 磁盘水位告警 |
ob_clog_disk_percent |
> 80% | 日志盘水位,写满会 hang |
ob_sql_rt_p99 |
业务定 | SQL 响应时间 |
ob_merge_status |
非 IDLE 超 24h | 合并卡住 |
ob_server_status |
!= ACTIVE | 节点异常 |
15. 性能诊断
15.1 执行计划
-- 查看执行计划
EXPLAIN SELECT * FROM app_db.orders WHERE user_id = 1001;
-- 带实际执行统计(V4.x 支持)
EXPLAIN ANALYZE SELECT ...;
EXPLAIN EXTENDED ...;
-- 查看执行计划缓存
SELECT * FROM oceanbase.GV$OB_PLAN_CACHE_PLAN_STAT
WHERE SQL_ID = '<sql_id>';
SELECT * FROM oceanbase.GV$OB_PLAN_CACHE_PLAN_EXPLAIN
WHERE PLAN_ID = <plan_id> AND SVR_IP = '<ip>';
-- 清理计划缓存(改索引后必做)
ALTER SYSTEM FLUSH PLAN CACHE;
ALTER SYSTEM FLUSH PLAN CACHE TENANT = tenant1;
ALTER SYSTEM FLUSH PLAN CACHE GLOBAL;
执行计划危险信号:
| 现象 | 含义 | 处置 |
|---|---|---|
TABLE SCAN 无 INDEX |
全表扫描 | 补索引 |
EST.ROWS 与 OUTPUT ROWS 差 10 倍以上 |
统计信息不准 | 手动收集统计信息 |
DISTRIBUTED 计划跨多机 |
分区键设计不合理 | 用表组或调整分区键 |
EXCHANGE 算子占比高 |
跨机数据搬运 | 优化 JOIN 键与分区对齐 |
PHY_QUERY 里有 MATERIALIZE |
中间结果落盘 | 调大 hash_area_size 或拆查询 |
15.2 统计信息
-- 手动收集(表级)
CALL DBMS_STATS.GATHER_TABLE_STATS('app_db', 'orders');
-- 指定采样率与并行度
CALL DBMS_STATS.GATHER_TABLE_STATS('app_db', 'orders', degree => 8, granularity => 'AUTO');
-- 收集整个 Schema
CALL DBMS_STATS.GATHER_SCHEMA_STATS('app_db');
-- 查看统计信息状态
SELECT * FROM oceanbase.DBA_TAB_STATISTICS WHERE TABLE_NAME = 'orders';
SELECT * FROM oceanbase.DBA_TAB_COL_STATISTICS WHERE TABLE_NAME = 'orders';
-- 锁定统计信息(防止自动收集覆盖)
CALL DBMS_STATS.LOCK_TABLE_STATS('app_db', 'orders');
CALL DBMS_STATS.UNLOCK_TABLE_STATS('app_db', 'orders');
15.3 锁与事务
-- 当前事务
SELECT * FROM oceanbase.GV$OB_TRANSACTION_PARTICIPANTS
WHERE STATE <> 'ACTIVE' ORDER BY START_TIME LIMIT 20;
-- 锁等待(V4.x 用 __all_virtual_lock_wait_stat)
SELECT * FROM oceanbase.GV$OB_LOCK_WAIT_STAT;
-- 长事务(超过 60 秒)
SELECT TENANT_ID, SVR_IP, TX_ID, SESSION_ID,
ROUND(ELAPSED_TIME/1000000, 2) elapsed_sec,
STATE, LEFT(QUERY_SQL, 100) sql
FROM oceanbase.GV$OB_TRANSACTION_PARTICIPANTS
WHERE STATE = 'ACTIVE'
ORDER BY ELAPSED_TIME DESC LIMIT 20;
-- 找出阻塞者(V4.x)
SELECT
w.SVR_IP, w.SESSION_ID AS blocked_session,
b.SESSION_ID AS blocking_session,
w.LOCK_ID, w.WAIT_SEC
FROM oceanbase.GV$OB_LOCK_WAIT_STAT w
JOIN oceanbase.GV$OB_TRANSACTION_PARTICIPANTS b
ON w.LOCK_ID = b.TX_ID
WHERE w.WAIT_SEC > 5;
15.4 内存诊断
-- 租户内存使用
SELECT TENANT_ID, SVR_IP,
ROUND(MEMSTORE_USED/1024/1024/1024, 2) memstore_gb,
ROUND(MEMSTORE_LIMIT/1024/1024/1024, 2) memstore_limit_gb,
ROUND(MEMSTORE_USED/MEMSTORE_LIMIT*100, 1) used_pct
FROM oceanbase.GV$OB_MEMSTORE
ORDER BY used_pct DESC;
-- 内存模块分布
SELECT SVR_IP, CTX_NAME, ROUND(SUM(HOLD)/1024/1024/1024, 2) hold_gb
FROM oceanbase.GV$OB_MEMORY
GROUP BY SVR_IP, CTX_NAME ORDER BY hold_gb DESC LIMIT 20;
-- 租户内存上限
SELECT TENANT_ID, ROUND(MEMORY_SIZE/1024/1024/1024, 2) mem_limit_gb
FROM oceanbase.DBA_OB_TENANT_RESOURCES;
memstore达到 80% 会触发提前冻结(minor freeze),达到 100% 会拒绝写入并报-4013(No memory or reach tenant memory limit)。这是 OceanBase 最常见的写入失败原因,处置是加大MEMORY_SIZE或降低写入并发。
15.5 慢 SQL 治理闭环
① 抓:GV$OB_SQL_AUDIT 按 ELAPSED_TIME 排序
② 归类:按 SQL_ID 聚合,找到高频/高耗时模板
③ 看计划:EXPLAIN + GV$OB_PLAN_CACHE_PLAN_EXPLAIN
④ 判因:无索引 / 统计信息旧 / 分区裁剪失效 / 跨机 JOIN / 锁等待
⑤ 处置:加索引 → 收集统计信息 → 刷计划缓存 → 业务侧改造
⑥ 验证:同一 SQL_ID 的 p99 是否下降,观察 30 分钟
16. 空间与容量管理
16.1 容量查询
-- 租户数据量
SELECT TENANT_ID,
ROUND(SUM(DATA_SIZE)/1024/1024/1024, 2) data_gb,
ROUND(SUM(REQUIRED_SIZE)/1024/1024/1024, 2) required_gb
FROM oceanbase.CDB_OB_TABLEGROUP_PARTITIONS
GROUP BY TENANT_ID;
-- MySQL 模式:按库统计
SELECT TABLE_SCHEMA,
ROUND(SUM(DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024, 2) total_gb,
COUNT(*) tables
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','oceanbase','sys')
GROUP BY TABLE_SCHEMA ORDER BY total_gb DESC;
-- 单表 Top20
SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_ROWS,
ROUND((DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024, 2) gb
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','oceanbase','sys')
ORDER BY (DATA_LENGTH+INDEX_LENGTH) DESC LIMIT 20;
16.2 节点磁盘水位
SELECT SVR_IP, ZONE,
ROUND(DATA_DISK_CAPACITY/1024/1024/1024, 2) data_cap_gb,
ROUND(DATA_DISK_IN_USE/1024/1024/1024, 2) data_used_gb,
ROUND(DATA_DISK_IN_USE/DATA_DISK_CAPACITY*100, 1) data_pct,
ROUND(LOG_DISK_CAPACITY/1024/1024/1024, 2) log_cap_gb,
ROUND(LOG_DISK_IN_USE/1024/1024/1024, 2) log_used_gb,
ROUND(LOG_DISK_IN_USE/LOG_DISK_CAPACITY*100, 1) log_pct
FROM oceanbase.GV$OB_SERVERS
ORDER BY data_pct DESC;
| 水位 | 状态 | 处置 |
|---|---|---|
| < 80% | 正常 | — |
| 80~90% | 警告 | 清理历史分区、扩容 |
| > 90% | 严重 | 立即扩容,否则合并会失败 |
| 日志盘 > 95% | 致命 | 集群会 hang,必须立刻处理 |
16.3 清理空间
-- 1) 删历史分区(比 DELETE 快得多,且立即释放)
ALTER TABLE app_db.logs DROP PARTITION p202601;
-- 2) 删表
DROP TABLE app_db.tmp_table;
-- 3) 触发合并,让空间真正回收
ALTER SYSTEM MAJOR FREEZE;
-- 4) 确认回收(观察 GV$OB_SERVERS 的 DATA_DISK_IN_USE)
DELETE不释放空间。OceanBase 的删除是标记删除,空间要等合并后才会被复用(不是立即还给操作系统)。要快速释放磁盘,用DROP PARTITION或TRUNCATE。
16.4 扩容
-- 数据文件扩容(在线)
ALTER SYSTEM SET datafile_size = '500G';
ALTER SYSTEM SET datafile_next = '100G';
ALTER SYSTEM SET datafile_maxsize = '1T';
-- 日志盘扩容
ALTER SYSTEM SET log_disk_size = '400G';
# 加节点(扩 Zone)
obd cluster scale_out obcluster -c scale_out.yaml
# 或编辑配置后 reload
obd cluster edit-config obcluster
obd cluster reload obcluster
# scale_out.yaml
oceanbase-ce:
servers:
- name: server4
ip: 10.0.0.14
server4:
zone: zone4
17. 升级与扩缩容
17.1 升级
# 1) 检查当前版本
obd cluster display obcluster
# 2) 导入新版本镜像
obd mirror clone oceanbase-ce-4.2.5.0-*.rpm
obd mirror list local
# 3) 升级(滚动,逐个 Zone)
obd cluster upgrade obcluster -c oceanbase-ce -V 4.2.5.0
# 4) 验证
obd cluster display obcluster
obclient -h10.0.0.11 -P2881 -uroot@sys -p'xxx' -e "SELECT OB_VERSION()"
| 参数 | 说明 |
|---|---|
-V / --version |
目标版本 |
--usable |
使用本地镜像中可用的最高版本 |
-e / --exec |
只生成升级脚本不执行 |
升级路径:
3.2.x → 4.0 → 4.1 → 4.2 ✅ 需逐级
4.2.x → 4.3.x ✅ 允许
4.2.x → 5.0.x ⚠️ 需评估,建议先到 4.3
升级前必做:① 全量备份 + 归档日志;② 检查
DBA_OB_TENANT_JOBS无运行中任务;③ 确认所有租户合并完成(STATUS='IDLE');④ 预留回滚窗口(OceanBase 不支持版本回退,只能靠备份恢复)。
17.2 缩容
-- 1) 先把 Leader 从待下线节点赶走
ALTER SYSTEM SWITCH ALL SERVER TO FOLLOWER;
-- 2) 删除该节点的 Unit(会触发副本迁移)
ALTER SYSTEM DELETE SERVER '10.0.0.13:2882';
-- 3) 等待迁移完成
SELECT * FROM oceanbase.DBA_OB_SERVERS;
-- 该节点 STATUS 变成 DELETING,迁移完成后从列表消失
-- 4) 确认无 LS 副本残留
SELECT * FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE SVR_IP = '10.0.0.13';
# 5) obd 层面移除
obd cluster scale_in obcluster -c scale_in.yaml
不要直接
obd cluster destroy单节点。必须走DELETE SERVER,否则该节点上的副本会被判定为永久下线,触发全集群补副本,可能引发 IO 风暴。
17.3 租户扩缩容
-- 扩容:改 Unit 规格
ALTER RESOURCE UNIT unit_8c16g MAX_CPU 16, MEMORY_SIZE '32G';
-- 缩容:必须先确认实际使用低于目标值
SELECT TENANT_ID, ROUND(MEMORY_SIZE/1024/1024/1024,2) FROM DBA_OB_TENANT_RESOURCES;
ALTER RESOURCE UNIT unit_8c16g MAX_CPU 8, MEMORY_SIZE '16G';
-- 增加副本数(提升读能力)
ALTER TENANT tenant1 LOCALITY = 'FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3, R{1}@zone4';
18. 高频故障速查
18.1 连不上
| 现象 | 排查顺序 |
|---|---|
Access denied |
① 用户名格式 user@tenant#cluster 是否正确 → ② 密码 → ③ ob_tcp_invited_nodes 白名单 |
No such tenant |
租户名拼错,或租户在 DROPPING 状态 |
Connection refused |
OBServer 进程是否在 → ss -lntp | grep 2881 → 防火墙 |
| OBProxy 连不上 | obproxy 进程 → rs_list 配置 → 后端 OBServer 是否 ACTIVE |
| 连接闪断 | 是否在切主/合并 → 看 DBA_OB_SERVER_EVENT_HISTORY |
-- 白名单是新建租户连不上的头号原因
SHOW PARAMETERS LIKE 'ob_tcp_invited_nodes' TENANT = tenant1;
ALTER SYSTEM SET ob_tcp_invited_nodes = '%' TENANT = tenant1;
18.2 写入失败
| 错误码 | 含义 | 处置 |
|---|---|---|
-4013 |
租户内存不足 | 扩 MEMORY_SIZE,或降低写入并发 |
-4030 |
磁盘满 | 清理分区 / 扩 datafile_size |
-4012 |
超时 | 调 ob_query_timeout;查锁等待 |
-6002 |
事务未提交/已回滚 | 应用侧检查事务边界 |
-6225 |
主键冲突 | 业务逻辑问题 |
-4007 |
内存不足(系统级) | 检查 system_memory 是否被挤压 |
-- -4013 的标准排查
SELECT SVR_IP, ROUND(MEMSTORE_USED/1024/1024/1024,2) used_gb,
ROUND(MEMSTORE_LIMIT/1024/1024/1024,2) limit_gb
FROM oceanbase.GV$OB_MEMSTORE ORDER BY used_gb DESC;
18.3 合并卡住
-- 1) 看状态
SELECT * FROM oceanbase.CDB_OB_MAJOR_COMPACTION\G
-- 2) 看诊断
SELECT * FROM oceanbase.GV$OB_COMPACTION_DIAGNOSE;
-- 3) 常见原因与处置
-- 磁盘不足 → 扩 datafile_size 或删分区
-- 副本不可用 → 恢复节点
-- 合并线程被限 → 调大 merge_thread_count
-- 卡在某个分区 → 单独对该分区做 major freeze
-- 4) 恢复合并
ALTER SYSTEM RESUME MERGE;
18.4 副本同步延迟
-- 看各副本的 SCN 差距
SELECT LS_ID, SVR_IP, ZONE, ROLE,
END_SCN - START_SCN AS scn_gap
FROM oceanbase.GV$OB_LS_LOG_STAT
WHERE TENANT_ID = 1002
ORDER BY scn_gap DESC;
-- 看日志盘是否写满
SELECT SVR_IP, ROUND(LOG_DISK_IN_USE/LOG_DISK_CAPACITY*100,1) log_pct
FROM oceanbase.GV$OB_SERVERS;
| 原因 | 判断 | 处置 |
|---|---|---|
| 网络带宽不足 | scn_gap 持续增大,网卡打满 |
限流或扩带宽 |
| 日志盘满 | log_pct > 95% |
扩 log_disk_size |
| 目标节点 IO 慢 | iostat 看 %util |
换盘或迁 Unit |
| 大事务 | 有超大事务在跑 | 拆批处理 |
18.5 租户创建失败
-- 常见报错:resource pool not enough / no enough resource
-- 1) 看节点剩余
SELECT SVR_IP, ZONE,
ROUND((CPU_CAPACITY-CPU_ASSIGNED)/100,2) cpu_free,
ROUND((MEM_CAPACITY-MEM_ASSIGNED)/1024/1024/1024,2) mem_free_gb
FROM oceanbase.GV$OB_SERVERS;
-- 2) 看 Unit 是否够
SELECT * FROM oceanbase.DBA_OB_UNITS WHERE TENANT_ID IS NULL;
-- 3) 检查 memory_limit 是否被 system_memory 吃掉太多
SHOW PARAMETERS LIKE 'memory_limit';
SHOW PARAMETERS LIKE 'system_memory';
19. 危险命令与避坑清单
| # | 命令 | 风险 | 防护 |
|---|---|---|---|
| 1 | obd cluster destroy |
删集群+数据,不可恢复 | 核对集群名;生产禁用 |
| 2 | DROP TENANT ... FORCE |
跳过回收检查,可能残留 LS 导致资源泄漏 | 优先普通 DROP TENANT,等 GC |
| 3 | ALTER SYSTEM DELETE SERVER |
触发全集群副本补全,IO 风暴 | 低峰执行,先 SWITCH ALL SERVER TO FOLLOWER |
| 4 | ALTER SYSTEM SET memory_limit 调小 |
可能导致现有租户内存超限,集群起不来 | 保证 memory_limit >= Σ(Unit 内存) + system_memory |
| 5 | ALTER RESOURCE UNIT 调小 |
租户实际使用超限,直接报 -4013 |
先看 DBA_OB_TENANT_RESOURCES 实际值 |
| 6 | ALTER SYSTEM SET log_disk_size 调小 |
日志盘写满 → 集群 hang | 只能调大,不能调小 |
| 7 | TRUNCATE/DROP PARTITION |
数据不可恢复(除非有备份) | 确认分区范围;先备份 |
| 8 | ALTER SYSTEM MAJOR FREEZE 频繁触发 |
IO 抖动,合并排队 | 依赖每日定时合并即可 |
| 9 | KILL SESSION 杀大事务 |
回滚可能比等待更久 | 看 ELAPSED_TIME,超过 10 分钟再考虑 |
| 10 | 直连 OBServer 绕过 OBProxy 做运维 | 节点切换后连接失效 | 生产统一走 OBProxy 2883 |
变更前五步
- 备份:
ALTER SYSTEM BACKUP DATABASE+ 确认归档日志连续; - 确认合并状态:
CDB_OB_MAJOR_COMPACTION全部IDLE; - 确认无运行中任务:
DBA_OB_TENANT_JOBS无INPROGRESS; - 评估资源:改 Unit / memory_limit 前算一遍余量;
- 留痕:记录变更前后
GV$OB_SERVERS与DBA_OB_TENANTS快照。
20. 附录:一键巡检脚本
#!/usr/bin/env bash
# ob_health_check.sh —— 一分钟巡检
# 用法:OB_HOST=10.0.0.21 OB_PORT=2883 OB_USER='root@sys' OB_PASS='xxx' ./ob_health_check.sh
set -uo pipefail
H="${OB_HOST:?请设置 OB_HOST}"
P="${OB_PORT:-2883}"
U="${OB_USER:-root@sys}"
PW="${OB_PASS:?请设置 OB_PASS}"
Q() { obclient -h"$H" -P"$P" -u"$U" -p"$PW" -Doceanbase -A -N -e "$1" 2>/dev/null; }
echo "==================== OceanBase 巡检 $(date '+%F %T') ===================="
echo -e "\n--- 1. 版本 ---"
Q "SELECT OB_VERSION();"
echo -e "\n--- 2. 节点状态 ---"
Q "SELECT SVR_IP, ZONE, STATUS, WITH_ROOTSERVER FROM oceanbase.DBA_OB_SERVERS;" |
awk -F'\t' '{printf " %-16s %-8s %-10s %s\n", $1, $2, $3, $4}'
echo -e "\n--- 3. 租户列表 ---"
Q "SELECT TENANT_ID, TENANT_NAME, COMPATIBILITY_MODE, STATUS FROM oceanbase.DBA_OB_TENANTS;" |
awk -F'\t' '{printf " %-6s %-20s %-10s %s\n", $1, $2, $3, $4}'
echo -e "\n--- 4. 资源使用 ---"
Q "SELECT SVR_IP, ROUND((CPU_CAPACITY-CPU_ASSIGNED)/100,2) cpu_free,
ROUND((MEM_CAPACITY-MEM_ASSIGNED)/1024/1024/1024,2) mem_free_gb
FROM oceanbase.GV$OB_SERVERS;" |
awk -F'\t' '{printf " %-16s cpu_free=%-6s mem_free=%s GB\n", $1, $2, $3}'
echo -e "\n--- 5. 磁盘水位(>85% 需处理)---"
Q "SELECT SVR_IP, ZONE,
ROUND(DATA_DISK_IN_USE/DATA_DISK_CAPACITY*100,1) data_pct,
ROUND(LOG_DISK_IN_USE/LOG_DISK_CAPACITY*100,1) log_pct
FROM oceanbase.GV$OB_SERVERS;" |
awk -F'\t' '{printf " %-16s %-8s data=%-6s%% log=%s%%\n", $1, $2, $3, $4}'
echo -e "\n--- 6. 合并状态 ---"
Q "SELECT TENANT_ID, STATUS, START_TIME FROM oceanbase.CDB_OB_MAJOR_COMPACTION;" |
awk -F'\t' '{printf " tenant=%-8s status=%-10s start=%s\n", $1, $2, $3}'
echo -e "\n--- 7. 慢 SQL TOP5(近 1 小时)---"
Q "SELECT ROUND(ELAPSED_TIME/1000,2), SQL_ID, LEFT(QUERY_SQL,80)
FROM oceanbase.GV$OB_SQL_AUDIT
WHERE REQUEST_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY ELAPSED_TIME DESC LIMIT 5;" |
awk -F'\t' '{printf " %8s ms %-20s %s\n", $1, $2, $3}'
echo -e "\n--- 8. 长事务(>60s)---"
Q "SELECT SVR_IP, SESSION_ID, ROUND(ELAPSED_TIME/1000000,2), STATE
FROM oceanbase.GV$OB_TRANSACTION_PARTICIPANTS
WHERE STATE='ACTIVE' AND ELAPSED_TIME > 60000000 ORDER BY ELAPSED_TIME DESC LIMIT 10;" |
awk -F'\t' '{printf " %-16s sid=%-10s %ss %s\n", $1, $2, $3, $4}'
echo -e "\n--- 9. 备份任务(近 5 次)---"
Q "SELECT JOB_ID, TENANT_ID, BACKUP_TYPE, STATUS, START_TIMESTAMP
FROM oceanbase.DBA_OB_BACKUP_JOBS ORDER BY JOB_ID DESC LIMIT 5;" |
awk -F'\t' '{printf " job=%-6s tenant=%-6s %-12s %-12s %s\n", $1, $2, $3, $4, $5}'
echo -e "\n--- 10. observer 日志 ERROR 计数(近 500 行)---"
for f in /home/admin/oceanbase/log/observer.log; do
[ -f "$f" ] && printf " %-50s %s\n" "$f" "$(tail -500 "$f" | grep -c '\[ERROR\]')"
done
echo -e "\n==================== 巡检结束 ===================="
速查表
| 需求 | 命令 |
|---|---|
| 集群状态 | obd cluster display <name> |
| 节点 | SELECT * FROM DBA_OB_SERVERS |
| 租户 | SELECT * FROM DBA_OB_TENANTS |
| 建租户 | CREATE TENANT ... RESOURCE_POOL_LIST=(...) |
| 扩租户 | ALTER RESOURCE UNIT <unit> MEMORY_SIZE='32G' |
| 合并 | ALTER SYSTEM MAJOR FREEZE |
| 合并状态 | SELECT * FROM CDB_OB_MAJOR_COMPACTION |
| 切主 | ALTER TENANT t PRIMARY_ZONE='zone2;zone1' |
| 备份 | ALTER SYSTEM BACKUP DATABASE |
| 恢复 | ALTER SYSTEM RESTORE t2 FROM '<dest>' WITH '...' |
| 慢 SQL | GV$OB_SQL_AUDIT |
| 计划缓存 | ALTER SYSTEM FLUSH PLAN CACHE |
| 诊断 | obdiag check run / obdiag gather scene run |
# obdiag 常用(V4.x 官方诊断工具)
obdiag check run # 一键巡检
obdiag analyze log --files observer.log # 日志分析
obdiag gather scene run --scene=observer.cpu_high
obdiag gather scene run --scene=observer.memory_high
obdiag gather scene run --scene=observer.disk_full
obdiag display scene list # 查看所有场景
最后一句:OceanBase 的运维门槛不在命令数量,而在资源模型。把「Unit → Pool → Tenant」这条链和「Zone → LS → 副本」这条链想清楚,80% 的问题都能自己定位。剩下 20% 靠
GV$OB_SQL_AUDIT和observer.log。