OceanBase 装完之后,很多人第一个念头就是赶紧建表、导数据,但我要劝你先冷静一下:比起急着写 DDL,你更应该先学会查看集群基本信息。这就跟买车一样,仪表盘还没看懂就踩油门上路,迟早要出事。这篇是“零基础 OceanBase 数据库入门”系列的第二篇,主题就一个——装完 OceanBase 之后,怎么用几条 SQL 和命令,把集群里的节点、Zone、租户、资源分布一次摸清楚。
这篇文章适合刚装完 OceanBase(不管是单机版还是三节点)还搞不清该看哪个视图的人,也适合那些正准备做数据库课程设计、写实验报告、或者准备 kca 考试的同学。你可以把它当成一份速查手册,命令直接抄,字段含义直接看,踩坑点也帮你提前标好了。
1. 看集群之前,先弄懂 OceanBase 里“集群”到底指什么
1.1 集群、Zone、Server、租户的逻辑关系
很多人一上来就敲 SQL,结果连查询结果都看不懂,问题出在概念没理清。OceanBase 的集群体系可以拆成四层:集群(Cluster)、Zone、Server(也就是 observer 进程)、租户(Tenant)。
集群是整个数据库实例的总称,对外表现为一个完整的数据库;一个集群里可以有多个 Zone,Zone 是逻辑上的容灾单元,你可以把它理解成“机房里的一个区域”或者“机架上的一个分组”。每个 Zone 下面分布着若干台机器,每台机器上跑着一个 observer 进程,这就是 Server。最后是租户,OceanBase 天生是多租户架构,业务数据都放在租户里,租户又分为 MySQL 模式和 Oracle 模式。
这里有个新手最容易绕晕的点:单机版也会有多个 Zone。比如你用 OBD 在一台服务器上部署一个“1-1-1”的架构,实际上是在一台物理机上模拟了三个逻辑 Zone,每个 Zone 里一个 observer。这种部署在容灾上没有任何意义(机器挂了全挂),但它能完整模拟生产环境的逻辑结构,用来学习、做实验非常合适。
1.2 为什么查集群信息必须登录 sys 租户
查集群信息,核心入口是 sys 租户。sys 是 OceanBase 内置的管理员租户,所有集群级别的元数据都保存在 sys 租户内部:哪些节点在线、哪些 Zone 是活着的、资源池怎么分配、副本怎么分布,全部得在 sys 租户下才能看到。
连接方式是root@sys,意思就是 sys 租户下的 root 用户。普通业务租户登录后,只能看到自己租户内部的数据字典和性能视图,查不到集群全局拓扑。打个比方,业务租户像小区里的住户,能看到自己家里有几间房;sys 租户像物业,能看到整个小区有几栋楼、每栋楼住了多少人、水电管网怎么走。
1.3 版本差异:4.x 请用 DBA_OB_ 开头的视图
查集群信息,网上能搜到很多旧教程,动不动就让你select * from __all_server;。这类以__all_开头的表是 OceanBase 3.x 及更早版本的内部表。注意,是内部表,不是对外承诺的稳定接口,字段随时可能调整。
从 4.x 开始,官方推荐使用oceanbase库下DBA_OB_开头的系统视图来查看集群信息。这套视图命名规整、字段清晰,是 4.x 之后对外承诺的稳定查询入口。所以你现在搜教程,只要看到__all_开头的写法,建议先留个心眼,确认一下那篇教程对应的版本。这篇博文所有示例都基于 4.x 版本,查询时统一用DBA_OB_视图。
2. 别急着敲 SQL,先用几条命令确认 observer 活着没
2.1 进程层面确认 observer
数据库是不是活着,第一层是操作系统层面。登录到部署 observer 的服务器上,执行:
ps -ef | grep observer正常情况下,你会在输出里看到类似这样的进程:
admin 12345 1 0 10:00 ? 00:00:00 /home/admin/oceanbase/bin/observer -z zone1 -P 2881 -p 2882重点看两件事:PID 存在且没有被标记为僵尸进程;启动参数里的-P和-p跟你的预期一致。其中-P 2881是 SQL 对外服务端口,-p 2882是 observer 内部 RPC 通信端口。
如果 ps 看不到 observer,先别急着查数据库,问题在进程就没起来。这时候去翻日志,后面会讲。
2.2 端口和日志
进程活着不代表端口一定能连,建议再确认一下端口监听状态:
netstat -tlnp | grep -E "2881|2882"必须看到 2881 和 2882 处于 LISTEN 状态。2881 是客户端连库的 SQL 端口,2882 是集群内部节点之间通信的端口。如果只监听了 2882,说明进程可能还在启动阶段,多等一会儿再看。
日志是排查一切问题的终点。用 OBD 默认方式部署的话,observer 日志一般在安装目录下的log文件夹里,常见路径是~/oceanbase/log/observer.log。启动阶段看日志用这个命令:
tail -n 200 ~/oceanbase/log/observer.log判断标准很简单:日志还在持续滚动输出,说明进程在干活;日志停在某个 ERROR 上不再动了,说明启动失败,把最后几十行报错看完,基本就能定位到原因(内存不足、端口被占用、目录权限不对是最常见的三类)。
2.3 向数据库发出第一条连接命令
进程和端口都正常,接下来用 obclient 连进去。连接命令:
obclient -h127.0.0.1 -P2881 -uroot@sys -p -A -c逐个参数说:-h是 observer 所在机器地址,本机就填 127.0.0.1;-P是 SQL 端口 2881;-u后面是用户名加租户名的组合,root@sys表示 sys 租户的 root;-p表示需要密码,回车后会交互式输入,不建议直接写在命令行里,避免被 shell 历史记录泄密。
这里有两个容易被忽略的小参数。-A是关闭自动补全,连接时如果元数据较多,不带-A可能会在执行补全的瞬间卡一下;-c是让客户端不要截断长字符串,查视图时有些字段值很长,不截断才能看到完整内容。
如果你机器上没装 obclient,也可以用 mysql 客户端临时连接,但要注意两点:一是要加--default-auth=mysql_native_password参数,否则新版 mysql 客户端会因为认证插件不兼容报错;二是 obclient 对 OceanBase 的兼容性最好,长期使用建议还是把 obclient 装上。
另外注意一个端口陷阱:2881 是直连 observer 的端口,如果你部署了 OBProxy,从 OBProxy 访问数据库的默认端口是 2883。用 2883 连接时,用户名写法不变,但本质是走了中间件路由,跟你直连 observer 看到的元数据是一样的。排查连接问题时,先搞清楚自己连的是哪个入口。
3. 核心实操:几条 SQL 看清集群全家桶
3.1 先看节点状态:oceanbase.DBA_OB_SERVERS
连上 sys 租户后,第一件事就是看集群里有哪些节点、各自状态如何。执行:
SELECT SVR_IP, SVR_PORT, ZONE, SQL_PORT, WITH_ROOTSERVER, STATUS, START_SERVICE_TIME, BUILD_VERSION FROM oceanbase.DBA_OB_SERVERS;这条 SQL 是查看 OceanBase 集群基本信息最核心的一条,字段含义逐个拆解:
SVR_IP和SVR_PORT:这台 observer 的 IP 和内部 RPC 端口,SVR_PORT一般显示 2882;ZONE:该节点属于哪个 Zone;SQL_PORT:客户端连这个节点的 SQL 端口,一般显示 2881;WITH_ROOTSERVER:标记该节点是否承载 RootService 相关服务。在 4.x 中 RootService 的职责已经打散到多节点,这个字段参考意义大于实际意义;STATUS:节点状态,ACTIVE表示正常对外服务,INACTIVE表示节点心跳异常或不可用;START_SERVICE_TIME:节点开始对外提供服务的时间,如果是空值,说明这个节点虽然进程起来了,但还没正式加入集群服务;BUILD_VERSION:observer 的编译版本号,确认版本时直接看这列,比到处问人靠谱。
正常的查询结果,每台节点对应一行,状态是 ACTIVE,START_SERVICE_TIME 有值。如果这个查询能出来,说明集群控制面是通的。
3.2 再看 Zone 和地域信息:oceanbase.DBA_OB_ZONES
节点看完,再看 Zone 维度。执行:
SELECT ZONE, STATUS, REGION, IDC, TYPE FROM oceanbase.DBA_OB_ZONES;ZONE是 Zone 名称;STATUS表示 Zone 是否可用(ACTIVE/INACTIVE);REGION和IDC表示这个 Zone 在哪个地域、哪个机房,多 IDC 部署时重点关注这两列;TYPE用来标识 Zone 的读写类型,常规部署一般是读写。
这里要理解 Zone 在 OceanBase 里的定位:它是容灾的基本单元,生产环境通常建议至少 3 个 Zone,分布在不同的物理机架甚至不同机房,这样任何一个 Zone 整体宕机,数据仍然有副本在其他 Zone 提供服务。
单机部署的同学看到三个 Zone 别慌,这是正常的逻辑结构,不代表你真有三套物理机器。学习阶段完全够用,但心里要明白:单机多 Zone 没有物理容灾效果。
3.3 租户、资源池、资源单元一把梭:四张表联合查询
集群拓扑看完,接下来就是租户和资源。OceanBase 的资源管理是一条链:租户申请资源,资源从资源池里划,资源池最终落实到具体节点上的资源单元。
先看有哪些租户:
SELECT TENANT_ID, TENANT_NAME, TENANT_TYPE, PRIMARY_ZONE, LOCALITY, STATUS FROM oceanbase.DBA_OB_TENANTS;TENANT_ID是租户 ID;TENANT_NAME是租户名,你看到sys租户的 ID 一般是 1;TENANT_TYPE表示租户类型,SYS是系统租户,业务租户通常是USER类型;PRIMARY_ZONE表示租户主副本优先分布在哪个 Zone;LOCALITY描述副本分布规则,比如F@zone1,F@zone2,F@zone3表示三个 Zone 里各放一个全功能副本。
再看资源池:
SELECT RESOURCE_POOL_ID, NAME, TENANT_ID, UNIT_COUNT, UNIT_CONFIG_NAME, ZONE_LIST FROM oceanbase.DBA_OB_RESOURCE_POOLS;重点看UNIT_COUNT(这个资源池在多少个节点上有单元)和ZONE_LIST(覆盖哪些 Zone)。
继续下钻到资源单元:
SELECT UNIT_ID, RESOURCE_POOL_ID, TENANT_ID, SVR_IP, ZONE, MAX_CPU, MEMORY_SIZE, STATUS FROM oceanbase.DBA_OB_UNITS;MAX_CPU是 CPU 上限,MEMORY_SIZE是内存大小,单位是字节。
最后看一眼资源规格定义:
SELECT UNIT_CONFIG_ID, NAME, MAX_CPU, MIN_CPU, MEMORY_SIZE, LOG_DISK_SIZE FROM oceanbase.DBA_OB_UNIT_CONFIGS;单独看每张表容易晕,把它们联合起来查一次,整个资源分配关系就清楚了:
SELECT t.TENANT_NAME AS tenant_name, r.NAME AS pool_name, r.ZONE_LIST AS zones, u.SVR_IP AS server_ip, u.MAX_CPU AS max_cpu, ROUND(u.MEMORY_SIZE / 1024 / 1024 / 1024, 2) AS mem_gb FROM oceanbase.DBA_OB_TENANTS t JOIN oceanbase.DBA_OB_RESOURCE_POOLS r ON t.TENANT_ID = r.TENANT_ID JOIN oceanbase.DBA_OB_UNITS u ON r.RESOURCE_POOL_ID = u.RESOURCE_POOL_ID;这条 SQL 执行完,你能看到每个租户的资源池落在哪几个 Zone、具体哪个节点的 IP、分到了多少 CPU 和内存。后面做租户扩容、缩容、迁移副本时,这个查询结果就是你做判断的底图。
3.4 顺带确认版本和集群 ID
排查问题或者跟别人对接时,版本和集群 ID 经常要确认。版本信息特别简单:
SELECT version();集群 ID 用参数查询:
SHOW PARAMETERS LIKE 'cluster_id';执行后会列出cluster_id这个参数以及对应的值。注意SHOW PARAMETERS的结果里一行的VALUE列才是真正的集群 ID。集群 ID 在多集群场景下很重要,比如做数据迁移、监控上报、多集群管理时,都是靠集群 ID 区分不同集群的。
如果你习惯用 DBeaver 这类图形化工具连接 OceanBase,用户名同样是root@sys这种“用户@租户”的写法,端口同样区分 2881(直连 observer)和 2883(走 OBProxy)。用工具看数据确实直观,但命令行这几条 SQL 还是要练熟,因为生产环境很多时候你没有图形工具可用。
4. 实操中常见报错与排查方法
4.1 连不上:ERROR 2003 / 10061
现象是提示Can't connect to MySQL server on '127.0.0.1' (10061)。这说明端口根本没通。
排查顺序固定下来:先ps -ef | grep observer看进程,再netstat -tlnp | grep -E "2881|2882"看端口,然后检查防火墙是否放行了对应端口。如果是本地学习环境,最简单的方式是先把 firewalld 停掉再测;生产环境要放行端口规则,不要简单粗暴关防火墙。
还有一种情况是用 OBProxy 连接失败,但直连 observer 成功,问题定位在 OBProxy 本身,检查 OBProxy 进程和它的 2883 端口。
4.2 权限报错:ERROR 1045 / ERROR 4012
ERROR 1045 Access denied for user 'root'@'...',说明用户名或密码不对。ERROR 4012也是 OceanBase 常见的认证失败错误码。
先检查用户名写法,-uroot@sys中间不要有空格,租户名不能写错。再看密码,OBD 部署时如果没有显式设置密码,root 用户密码一般是部署配置里指定的,或者可能为空。空密码的话,执行连接命令后直接按回车就行。
如果你忘了密码,最快的路子是去翻 OBD 部署时的配置或记录,而不是在数据库里瞎猜。生产环境密码通常会上到密钥管理或配置中心,去那里找。
4.3 查询报错:表不存在 / unknown database
连接后直接执行SELECT * FROM DBA_OB_SERVERS;报表不存在,原因是没加库名前缀。这些视图都在oceanbase库下,两种写法都对:
SELECT * FROM oceanbase.DBA_OB_SERVERS;或者先执行use oceanbase;再查。建议第一种写法,命令一条条都能独立执行,不会被当前库状态影响。
4.4 报 -4000 / something wrong 等内部错误
这种报错信息比较模糊,通常是 observer 内部没有准备好。比如节点刚启动还在初始化阶段,RootService 还没选主完成,这时候查集群视图就可能报内部错误。处理办法是等几十秒再试,同时看 observer.log 有没有 ERROR 级别的日志刷出来。
另一类情况是版本不匹配:你用 3.x 时期的内部表名去查 4.x 集群,或者反过来,都会出现奇怪的报错。记住前面说的,4.x 统一用DBA_OB_视图,能避开绝大多数兼容性问题。
| 现象 | 常见原因 | 排查方向 |
|---|---|---|
| 10061/2003 连接失败 | 进程没起、端口没监听、防火墙拦截 | ps、netstat、防火墙规则 |
| 1045/4012 认证失败 | 密码错误、用户名租户格式不对 | 核对 root@sys 写法、重置密码 |
| 表不存在 | 没加 oceanbase 库名前缀 | 用 oceanbase.DBA_OB_xxx 全名查询 |
| -4000 内部错误 | 节点未就绪、版本不匹配 | 看 observer.log、等待就绪、核对版本 |
5. 查看集群信息不只是为了看一眼
5.1 结合 OBD 命令双通道查看
如果你是用 OBD 部署的 OceanBase,除了登录数据库查 SQL 视图,OBD 自己也有一套查询入口:
obd cluster list这条命令列出 OBD 管理的所有集群。然后:
obd cluster display 集群名会展示集群里每个组件(observer、OBProxy 等)的运行状态和端口信息。我个人的建议是两条通道配合着看:OBD 展示的是进程和部署层面的状态,SQL 视图展示的是数据库内部真正的服务状态。比如有时候进程起来了,但 observer 因为某些原因没对外提供 SQL 服务,这时候 OBD 显示可能是 RUNNING,而START_SERVICE_TIME却是空的,一对比就能发现问题。
5.2 后续扩展:监控、巡检、实验报告
查看集群基本信息这个动作,往小了说是几条命令,往大了说是你后续所有运维操作的起点。做日常巡检时,把第 3 节的几条 SQL 定时跑一遍,节点状态、Zone 状态、租户资源水位就都有了。如果后面要做监控告警,也是基于这些视图去采集数据。
准备数据库课程设计、比赛答辩或者实验报告时,“查看集群基本信息”这一步几乎是必写项。建议把查询结果留存下来,配合版本号、部署时间一起写进文档,能明显增强报告的可信度和完成度。
集群迁移、数据库同步这些话题也是基于集群信息展开的,你得先知道集群里有哪些节点、版本是什么、租户分布在哪,才能规划迁移链路。这些都是后话,本篇先把看家底的本事练好。
5.3 一条实用的肌肉记忆
最后分享一个我日常排查的习惯。连接上集群之后,我从来不会乱翻视图,而是固定按这个顺序走:
obclient -h127.0.0.1 -P2881 -uroot@sys -p -A -c进去之后先查DBA_OB_SERVERS确认节点都在线,再查DBA_OB_ZONES确认 Zone 状态,最后联合查询DBA_OB_TENANTS、DBA_OB_RESOURCE_POOLS、DBA_OB_UNITS看资源分布。
这套流程走完,整个集群的状态基本就心里有数了。后面做租户创建、扩容缩容、性能排查,都是在这个基础上加东西。把这几条 SQL 存成一个.sql文件放在本地,每次要查的时候直接source执行,比现场敲快得多——这是我自己踩过几次坑之后总结出来的习惯,希望对你有用。