作者简介:吕文杰,瑞蓝创数据库专家
原创内容未经授权不得随意使用,转载请联系小编并注明来源
一、OCP API 概述
OCP API 支持 HTTP Basic Auth 和 AK/SK 签名 两种认证。本文档采用 HTTP Basic Auth。
|
|
|
|
|---|---|---|
| 原理 |
|
|
| 请求头 | Authorization: Basic |
Authorization: OCP-ACCESS-KEY-HMACSHA1 {AK}:{Signature} |
| 安全性 |
|
|
| 签名算法 |
|
BASE64(HMAC-SHA1(AK_SECRET, string-to-sign)) |
| 适用场景 |
|
|
| 获取方式 |
|
|
AK/SK 认证需额外请求头 Date 和签名计算,本文档为简洁起见,所有命令均采用 HTTP Basic Auth。
本文档实验环境信息如下:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
二、前置变量
source .env
.env 内容:
export OCP_HOST="http://192.168.1.71:8080"
export OCP_USER="admin"
export OCP_PASS="aaAA11__"
export CLUSTER_NAME="obcp_test"
export ZONE_NAME="zone3"
export SERVER_ID=2000006
export API_BASE="/api/v2"
export API_CLUSTERS="${API_BASE}/ob/clusters"
获取集群 ID (几乎每个操作都需要):
OCP_ID=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}" \
| jq -r --arg name "$CLUSTER_NAME" '.data.contents[] | select(.name==$name) | .id')
检查命令:
echo "OCP_ID=$OCP_ID"
验证结果: OCP_ID=2000001 ✅
三、集群操作
3.1 查询集群列表 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}" \
| jq -r '.data.contents[] | "\(.name) id=\(.id) obClusterId=\(.obClusterId) \(.status) \(.obVersion)"'
检查命令:同上
真实输出:
akmetadb id=1 obClusterId=1766993439 RUNNING 4.2.1.7
obcp id=2000002 obClusterId=1766993446 RUNNING 4.4.2.0
obcp_exam id=1000005 obClusterId=1766993444 RUNNING 4.4.2.0
obcp_test id=2000001 obClusterId=1766993445 RUNNING 4.4.2.0
3.2 停止集群 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/stop" | jq .
检查命令(循环检查,约 40 秒):
for i in $(seq 1 60); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}" | jq -r '.data.status')
echo "[$i] $S"
[ "$S" = "STOPPED" ] && echo "=== 停止成功 ===" && break
sleep 5
done
真实结果:停止耗时约 40 秒。状态变化: RUNNING -> STOPPING -> STOPPED
3.3 启动集群 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/start" | jq .
检查命令(循环检查,约 2 分钟):
for i in $(seq 1 60); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}" | jq -r '.data.status')
echo "[$i] $S"
[ "$S" = "RUNNING" ] && echo "=== 启动成功 ===" && break
sleep 5
done
真实结果:启动耗时约 2 分钟。状态变化: STOPPED -> STARTING -> RUNNING
3.4 重启集群 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" -d '{}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/restart" | jq .
检查命令(循环检查,约 6.5 分钟):
for i in $(seq 1 180); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}" | jq -r '.data.status')
echo "[$i] $S"
[ "$S" = "RUNNING" ] && echo "=== 重启成功 ===" && break
sleep 5
done
真实结果:重启耗时约 6.5 分钟。状态变化: RUNNING -> RESTARTING -> RUNNING
> 必须带 -H "Content-Type: application/json" -d '{}',否则返回 HTML。
3.5 查询集群 OBServer 列表 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq '.data.contents[] | {id, ip, port, zone: .zoneName, status}'
检查命令:同上
真实输出 (6 个):
{"id":2000001,"ip":"192.168.1.101","port":2882,"zone":"zone1","status":"RUNNING"}
{"id":2000004,"ip":"192.168.1.104","port":2882,"zone":"zone1","status":"RUNNING"}
{"id":2000002,"ip":"192.168.1.102","port":2882,"zone":"zone2","status":"RUNNING"}
{"id":2000005,"ip":"192.168.1.105","port":2882,"zone":"zone2","status":"RUNNING"}
{"id":2000003,"ip":"192.168.1.103","port":2882,"zone":"zone3","status":"RUNNING"}
{"id":2000006,"ip":"192.168.1.106","port":2882,"zone":"zone3","status":"RUNNING"}
四、Zone 操作
4.1 查看 Zone 列表 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones" \
| jq '.data.contents[] | {name, status}'
检查命令:同上
真实输出:
{"name":"zone1","status":"RUNNING"}
{"name":"zone2","status":"RUNNING"}
{"name":"zone3","status":"RUNNING"}
4.2 停止 Zone ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones/${ZONE_NAME}/stop" | jq .
检查命令(循环检查,约 1.2 分钟):
for i in $(seq 1 180); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones" \
| jq -r --arg z "$ZONE_NAME" '.data.contents[] | select(.name==$z) | .status')
echo "[$i] $ZONE_NAME: $S"
[ "$S" = "STOPPED" ] && echo "=== 停止成功 ===" && break
sleep 5
done
真实结果:停止耗时约 1.2 分钟。状态: RUNNING -> STOPPING -> STOPPED
4.3 启动 Zone ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones/${ZONE_NAME}/start" | jq .
检查命令(循环检查,约 1.5 分钟):
for i in $(seq 1 60); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones" \
| jq -r --arg z "$ZONE_NAME" '.data.contents[] | select(.name==$z) | .status')
echo "[$i] $ZONE_NAME: $S"
[ "$S" = "RUNNING" ] && echo "=== 启动成功 ===" && break
sleep 5
done
真实结果:启动耗时约 1.5 分钟。状态: STOPPED -> STARTING -> RUNNING
4.4 重启 Zone ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones/${ZONE_NAME}/restart" | jq .
检查命令(循环检查,约 2.5 分钟):
for i in $(seq 1 180); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones" \
| jq -r --arg z "$ZONE_NAME" '.data.contents[] | select(.name==$z) | .status')
echo "[$i] $ZONE_NAME: $S"
[ "$S" = "RUNNING" ] && echo "=== 重启成功 ===" && break
sleep 5
done
真实结果:重启耗时约 2.5 分钟。状态: RUNNING -> RESTARTING -> RUNNING
4.5 查询 Zone 的 OBServer 列表 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/zones/${ZONE_NAME}/servers" \
| jq '.data.contents[] | {id, ip, port, status}'
检查命令:同上
真实输出 (zone3 有 2 个):
{"id":2000003,"ip":"192.168.1.103","port":2882,"status":"RUNNING"}
{"id":2000006,"ip":"192.168.1.106","port":2882,"status":"RUNNING"}
五、仲裁服务
5.1 查询仲裁服务列表 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}/api/v2/arbitration/services" | jq .
检查命令:同上
真实结果:当前环境无仲裁服务,返回 {"successful":true,"data":{"contents":[],...}}
六、OBServer 操作
6.1 API 概览
OBServer 操作通过 3 个 API 实现:stop、start、restart。
|
|
|
|
|
|---|---|---|---|
|
|
POST /servers/{serverId}/stop |
|
|
|
|
POST /servers/{serverId}/start |
|
|
|
|
POST /servers/{serverId}/restart |
|
|
参数说明:
-
freezeServer— 操作前执行 SSTable 转储,将内存数据写入磁盘。 -
type— STOP_SERVICE 停止 OB 服务(进程仍在),STOP_PROCESS 杀死 observer 进程。 -
force— 仅重启 API 支持,直接杀进程,适用于不满足多数派场景。 -
所有操作必须带
-H "Content-Type: application/json" -d '参数',否则返回 400。
状态说明:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
通用准备命令:
OCP_ID=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}" \
| jq -r --arg name "$CLUSTER_NAME" '.data.contents[] | select(.name==$name) | .id')
通用检查命令:
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status'
6.2 停止 OBServer ✅ 已验证
API: POST /api/v2/ob/clusters/{id}/servers/{serverId}/stop
6.2.1 停止服务 (freezeServer=false, type=STOP_SERVICE)
停止 OB 服务,进程仍在。约 40 秒,6 个子任务。
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" \
-d '{"freezeServer":false,"type":"STOP_SERVICE"}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers/${SERVER_ID}/stop" | jq .
检查命令(循环检查,目标状态 SERVICE_STOPPED):
for i in $(seq 1 60); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status')
echo "[$i] $S"
[ "$S" = "SERVICE_STOPPED" ] && echo "=== 停止成功 ===" && break
sleep 5
done
6.2.2 停止进程 (freezeServer=false, type=STOP_PROCESS)
停止整个进程。约 3 分钟,8 个子任务。
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" \
-d '{"freezeServer":false,"type":"STOP_PROCESS"}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers/${SERVER_ID}/stop" | jq .
检查命令(循环检查,目标状态 PROCESS_STOPPED):
for i in $(seq 1 60); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status')
echo "[$i] $S"
[ "$S" = "PROCESS_STOPPED" ] && echo "=== 停止成功 ===" && break
sleep 5
done
6.2.3 转储+停止进程 (freezeServer=true, type=STOP_PROCESS)
先转储再停止。约 5 分钟,9 个子任务。
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" \
-d '{"freezeServer":true,"type":"STOP_PROCESS"}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers/${SERVER_ID}/stop" | jq .
检查命令(循环检查,目标状态 PROCESS_STOPPED):
for i in $(seq 1 90); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status')
echo "[$i] $S"
[ "$S" = "PROCESS_STOPPED" ] && echo "=== 停止成功 ===" && break
sleep 5
done
6.2.4 三种停止方式对比
|
|
|
|
|
|
|
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6.3 启动 OBServer ✅ 已验证
API: POST /api/v2/ob/clusters/{id}/servers/{serverId}/start
无参数,自动适配 SERVICE_STOPPED 和 PROCESS_STOPPED。11 个子任务。
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" -d '{}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers/${SERVER_ID}/start" | jq .
检查命令(循环检查,目标状态 RUNNING):
for i in $(seq 1 60); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status')
echo "[$i] $S"
[ "$S" = "RUNNING" ] && echo "=== 启动成功 ===" && break
sleep 5
done
启动耗时对比:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
启动 API 官方文档无请求参数,实际调用需带 -H "Content-Type: application/json" -d '{}',否则返回 400。
6.4 重启 OBServer ✅ 已验证
API: POST /api/v2/ob/clusters/{id}/servers/{serverId}/restart
6.4.1 优雅重启 (freezeServer=false)
约 2 分钟,13 个子任务。
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" -d '{"freezeServer":false}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers/${SERVER_ID}/restart" | jq .
检查命令(循环检查,目标状态 RUNNING):
for i in $(seq 1 60); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status')
echo "[$i] $S"
[ "$S" = "RUNNING" ] && echo "=== 重启成功 ===" && break
sleep 5
done
6.4.2 转储+重启 (freezeServer=true)
约 5 分钟,14 个子任务。
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" -d '{"freezeServer":true}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers/${SERVER_ID}/restart" | jq .
检查命令(循环检查,目标状态 RUNNING):
for i in $(seq 1 120); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status')
echo "[$i] $S"
[ "$S" = "RUNNING" ] && echo "=== 重启成功 ===" && break
sleep 5
done
6.4.3 强制重启 (freezeServer=false, force=true)
直接杀进程重启。约 15 分钟,适用于不满足多数派场景。
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" -d '{"freezeServer":false,"force":true}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers/${SERVER_ID}/restart" | jq .
检查命令(循环检查,目标状态 RUNNING):
for i in $(seq 1 180); do
S=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/servers" \
| jq -r --argjson s "$SERVER_ID" '.data.contents[] | select(.id==$s) | .status')
echo "[$i] $S"
[ "$S" = "RUNNING" ] && echo "=== 重启成功 ===" && break
sleep 5
done
6.4.4 三种重启方式对比
|
|
|
|
|
|
|
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6.5 查看任务执行步骤 ✅ 已验证
API: GET /api/v2/tasks/instances/{taskId}
所有 OBServer 操作都是异步任务,可通过任务 ID 查看子进度:
TASK_ID=
# 查看任务概览
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_BASE}/tasks/instances/${TASK_ID}" \
| jq '{id: .data.id, name: .data.name, status: .data.status, subtaskCount: (.data.subtasks | length)}'
# 查看所有 subtasks
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_BASE}/tasks/instances/${TASK_ID}" \
| jq -r '.data.subtasks[] | "\(.id) | \(.status) | \(.name)"'
输出示例:
{"id":2083159,"name":"Stop OB server","status":"RUNNING","subtaskCount":9}
2098378 | SUCCESSFUL | Freeze observer
2098381 | SUCCESSFUL | Prepare stop observer process
2098377 | RUNNING | Stop observer process
2098383 | PENDING | Wait observer inactive
Subtask 状态:READY → RUNNING → SUCCESSFUL / FAILED,PENDING 表示等待前置任务。
七、租户操作
7.1 查询租户列表 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/tenants" \
| jq -r '.data.contents[] | "\(.name) id=\(.id) obTenantId=\(.obTenantId) \(.status) \(.mode)"'
检查命令:同上
真实输出:
t2_s id=2000018 obTenantId=1022 NORMAL MYSQL
tenant2 id=2000003 obTenantId=1004 NORMAL MYSQL
tenant1 id=2000002 obTenantId=1002 NORMAL MYSQL
sys id=2000001 obTenantId=1 NORMAL MYSQL
7.2 查询租户详情 ✅ 已验证
TENANT_ID=$(curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/tenants" \
| jq -r --arg name "sys" '.data.contents[] | select(.name==$name) | .id')
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/tenants/${TENANT_ID}" \
| jq '.data | {name, id, obTenantId, status, mode, primaryZone, charset, role, locked}'
检查命令:同上
真实输出:
{"name":"sys","id":2000001,"obTenantId":1,"status":"NORMAL","mode":"MYSQL","primaryZone":"zone1,zone2,zone3","charset":"utf8mb4","role":"PRIMARY","locked":false}
7.3 修改租户 Zone 优先级 ✅ 已验证
curl -s --user "${OCP_USER}:${OCP_PASS}" -X POST \
-H "Content-Type: application/json" \
-d '{"primaryZone":"zone3,zone2,zone1"}' \
"${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/tenants/${TENANT_ID}/modifyPrimaryZone" | jq .
检查命令:
curl -s --user "${OCP_USER}:${OCP_PASS}" "${OCP_HOST}${API_CLUSTERS}/${OCP_ID}/tenants/${TENANT_ID}" \
| jq '.data.primaryZone'
primaryZone 用逗号分隔,越靠前优先级越高。区别于 zoneList 的分号分隔。
END
瑞蓝创 OceanBase OBCP V4 精英训练营
点击下方图片立即了解详情


▼ 点击「阅读原文」,了解更多产品技术文章


