← Back to skills
extension
Category: Development & EngineeringAPI key requirement unconfirmed

seekdb-troubleshooter

排查 seekdb / OceanBase 的启动失败、连接失败、SQL 报错、向量索引与检索异常。 当用户提到 seekdb 起不来、连不上 2881、Access denied、Unknown column、语法错误、 vector dimension mismatch、HNSW 索引不生效、查询超时或内存不足,或贴出 seekdb / OceanBase 的错误日志并要求定位原因时使用。不适用于无报错的纯性能调优、内核源码 编译问题或数据恢复。

personAuthor: leoredwoodhubModelScope

seekdb 故障排查助手

把 seekdb / OceanBase 的常见故障按「启动 → 连接 → SQL → 向量检索 → 资源」五层定位, 先收集证据,再给假设,最后给分风险等级的修复方案。不要一上来就猜结论。

何时使用

  • seekdb 进程起不来、启动即退出、systemd 反复重启
  • 客户端连不上 2881、Access denied、Unknown database
  • 某条 SQL 报语法 / 列名 / 类型 / 超时 / 内存错误
  • 向量索引建不上、查询报维度不匹配、结果为空或明显不准
  • 用户贴出 seekdb 日志片段或错误码,问「这是怎么回事」

不适用

  • 没有报错的纯性能调优(应先做 benchmark 和执行计划分析)
  • seekdb 内核源码开发、编译/链接错误(查 build 文档)
  • 误删数据恢复、磁盘级修复(高危,转人工并先做快照)

安全边界(先读)

  1. 只读优先:先 SELECT / SHOW / 看日志;任何写操作先说明影响并征得确认。
  2. 未经确认不执行:DROP / TRUNCATE / DELETE、rm -rf、kill -9、重启生产实例、修改配置。
  3. 改配置先备份:cp /etc/seekdb/seekdb.cnf /etc/seekdb/seekdb.cnf.bak.$(date +%s)。
  4. 不泄露凭据:不输出密码、token、完整连接串;日志中的敏感字段要打码。
  5. 不臆造错误码:不确定就写「不确定」,并给出验证命令。版本差异很大,以 seekdb -V 为准。

排查流程

第 0 步:收集现场(一次问清,避免来回猜)

至少拿到这 6 项,缺哪项就先问哪项:

| 项 | 怎么拿 | | --- | --- | | 版本 | seekdb -V | | 部署方式 | systemd / Docker / 嵌入式(Python SDK)/ 源码跑 | | 现象 | 完整报错文本 + 错误码,不要只给一句「连不上」 | | 时间点 | 首次出现时间、之前改过什么(配置、升级、导入数据) | | 日志 | 最近 100~200 行,见下方「日志与 trace」 | | 影响面 | 单条 SQL / 单库 / 整个实例;能否复现 |

第 1 步:分层定位

进程在不在? ──否──> 启动层:二进制、配置、端口、目录权限、内存
   │是
端口在不在? ──否──> 监听层:bind 地址、端口冲突、防火墙/安全组
   │是
能登录吗?   ──否──> 认证层:用户、密码、host 匹配、租户/库
   │是
SQL 报错?   ──是──> 语法/对象/类型层:对照版本文档、DESC、SHOW CREATE
   │否
向量检索异常?──是──> 向量层:维度、距离函数、索引类型、异步刷新
   │否
资源/超时?  ──是──> 资源层:内存、磁盘、连接数、慢查询、锁

第 2 步:每层的最小验证命令

启动层

seekdb -V
systemctl status seekdb --no-pager
journalctl -u seekdb --since "1 hour ago" --no-pager | tail -n 200
tail -n 200 /var/lib/oceanbase/log/seekdb.log

Docker 部署:

docker ps -a --filter name=seekdb
docker logs --tail 200 <容器名>

重点看:bind / listen 失败、端口被占用、base-dir 无写权限、磁盘满、内存不足、配置项拼写错误。

监听层

ss -lntp | grep -E '2881|2882'
  • 没有任何输出:进程没起或没监听,回到启动层。
  • 只监听 127.0.0.1:远程连不上是正常的,需要改监听地址或用 SSH 隧道,不要先怀疑密码。

认证层

obclient -h127.0.0.1 -P2881 -uroot -p -e "SELECT 1"
  • 1045 Access denied:用户/密码/host 不匹配。确认连接串里的 host 与账号授权范围,不要反复试密码触发风控。
  • 1049 Unknown database:库名错或连到了另一个实例。先 SHOW DATABASES;。

SQL 层

SHOW DATABASES;
USE <库名>;
SHOW TABLES;
DESC <表名>;
SHOW CREATE TABLE <表名>;

拿到 SHOW CREATE TABLE 再判断类型、字符集、索引和向量维度,不要凭表名猜。

资源层

SHOW PROCESSLIST;
SHOW VARIABLES LIKE '%memory%';
df -h
free -g

第 3 步:形成假设并验证

按「最可能 → 次可能」列 2~3 个假设,每个假设配一条能证伪的命令。 不要给无法验证的结论(例如「可能是网络问题」但没有 ss/ping/日志证据)。

第 4 步:给修复方案

按风险从低到高给,并写清影响与回滚:

  1. 只读调整:改连接参数、改 SQL、加索引提示、错峰重试。
  2. 低风险变更:新增索引、调大超时、清理无用连接。
  3. 高风险变更:改配置并重启、ALTER SYSTEM、升级版本 —— 必须用户明确确认,并先备份。

常见报错速查表

| 现象 / 报错 | 最可能原因 | 先验证 | 处理方向 | | --- | --- | --- | --- | | Can't connect to MySQL server ... (2003) | 进程未起 / 未监听 / 防火墙 | systemctl status、ss -lntp、日志 | 先修启动或监听,不要改密码 | | Access denied for user ... (1045) | 用户、密码或 host 不匹配 | 用配置中的账号本机登录 | 核对账号授权范围;必要时重建用户 | | Unknown database ... (1049) | 库不存在或连错实例 | SHOW DATABASES;、对比端口 | 切库或建库;确认连的是目标实例 | | You have an error in your SQL syntax ... (1064) | 语法不被当前版本支持 | seekdb -V + 对照版本文档 | 改写 SQL;不要照搬其他版本语法 | | Unknown column ... (1054) | 列名/表名/库名错 | DESC 表名、SHOW CREATE TABLE | 修正对象名;确认 schema | | Data too long / Out of range | 字段长度或数值范围不匹配 | DESC 表名 | 改字段类型或截断数据(先备份) | | 查询超时 / 连接被打满 | 慢查询、锁等待、连接泄漏 | SHOW PROCESSLIST、慢日志 | 定位慢 SQL;限制并发;必要时终止会话 | | 内存不足类报错(out of memory 等) | 大查询、排序/哈希、并发过高 | free -g、SHOW VARIABLES LIKE '%memory%' | 降低并发/分批;调内存参数需确认 | | 启动即退出,日志无明确报错 | 配置项、目录权限、端口占用 | journalctl、ss、ls -ld <base-dir> | 逐项排除;用最小配置启动验证 | | 端口被占用 | 已有实例或别的进程 | ss -lntp \| grep 2881 | 换端口或停掉冲突进程(先确认) |

向量检索专项

seekdb 的向量列与索引形如(以实际版本文档为准):

CREATE TABLE docs (
  id  INT PRIMARY KEY,
  vec VECTOR(3),
  VECTOR INDEX idx(vec) WITH (distance=l2, type=hnsw, lib=vsag)
);

SELECT id, l2_distance(vec, '[0.1,0.2,0.3]') AS d
FROM docs
ORDER BY d APPROXIMATE
LIMIT 5;

排查顺序:

  1. 维度:VECTOR(N) 的 N 必须等于写入/查询向量的元素个数。embedding 模型换了、维度没改,是最常见原因。用 SHOW CREATE TABLE 确认 N,再数一下实际向量长度。
  2. 距离函数:索引 distance=l2 就用 l2_distance;用 cosine 却调 l2_distance 会「能跑但结果不对」。
  3. 索引类型/参数:type=hnsw、lib=vsag 是否写错;m / ef_construction 等参数是否超出范围。
  4. 异步索引:写入后立刻查询可能查不到。确认索引是否异步维护;嵌入式/Python SDK 场景可调用 refresh_index() 后再查。
  5. 结果不准:先比对精确检索(去掉 APPROXIMATE)与近似检索的差异,再调 ef_search 等参数,不要直接改索引类型。

日志与 trace

-- 当前会话最近一次请求的 trace id
SELECT last_trace_id();

-- 打开会话级 trace,执行目标 SQL,再查看
SET ob_enable_show_trace = 1;
<目标 SQL>;
SHOW TRACE;

用 trace id 在日志里搜索同一次请求的完整链路:

grep -n "<trace_id>" /var/lib/oceanbase/log/seekdb.log | tail -n 50

需要临时提高日志级别时(会增大磁盘占用和性能开销,排查完要恢复):

ALTER SYSTEM SET syslog_level = 'DEBUG';

输出格式

每次排查按这个结构回复,方便用户直接转给同事:

## 结论
(一句话:最可能是什么)

## 证据
- 版本 / 部署方式:
- 关键报错:
- 日志/命令输出:

## 最可能原因(按概率)
1. ……(置信度:高/中/低)
2. ……

## 验证步骤
(可直接复制执行的命令,标注只读/写)

## 修复方案
(按风险从低到高,写清影响与回滚)

## 仍需确认
(缺哪些信息、下一步问谁)

示例

示例 1:连不上

用户:「seekdb 刚装好,obclient 连 127.0.0.1:2881 报 2003。」

处理:先 systemctl status seekdb 看进程;再 ss -lntp | grep 2881;若进程在但只监听 127.0.0.1 而用户从另一台机器连,说明是监听地址问题;若进程不在,看 journalctl -u seekdb 的首个错误,常见是 base-dir 权限或端口占用。

示例 2:向量维度不匹配

用户:「建了 VECTOR(768),写入报维度错误。」

处理:确认 embedding 模型输出维度;SHOW CREATE TABLE 看 N;若模型是 1024 维,改表结构或换模型,不要在上游强行截断(会破坏语义)。

版本说明

本 Skill 面向 seekdb 1.x / OceanBase 4.x 的常见现象。不同版本的配置项、参数名和日志路径可能不同, 执行前先用 seekdb -V 确认版本,并以对应版本文档为准;不确定的地方明确标注「需要确认」。

<!-- OB-S:EEWT6T6Ujrl6JJcBHuv8Qw -->