【StarRocks】 排错:TableKeeper 报 `Cluster has no available capacity` / `NoAliveBackendException`

2025博客之星年度评选已开启 10w+人浏览 1.6k人参与

适用范围

本文针对两类问题的排查与修复:

  • FE 后台线程(常见为 TableKeeper)周期性报错:Cluster has no available capacity
  • 业务/后台任务报错:com.starrocks.common.NoAliveBackendException: No alive backendno alive backends

文档已对 IP/节点名/ClusterId 做脱敏,统一用占位符表示:<FE_LEADER_IP><FE_FOLLOWER_IP><BE_IP> 等。


典型日志(脱敏)

A) Cluster has no available capacity(TableKeeper 创建内部表失败)

<TS> ERROR (TableKeeper|<TID>) [RepoExecutor.executeDDL():<LINE>] execute DDL error: CREATE TABLE IF NOT EXISTS loads_history ...
com.starrocks.sql.analyzer.SemanticException: Getting analyzing error. Detail message: Cluster has no available capacity.
    at com.starrocks.system.SystemInfoService.checkClusterCapacity(SystemInfoService.java:<LINE>) ~[starrocks-fe.jar:?]
    at com.starrocks.server.LocalMetastore.createTable(LocalMetastore.java:<LINE>) ~[starrocks-fe.jar:?]
    ...

B) NoAliveBackendException / no alive backends

com.starrocks.common.NoAliveBackendException: No alive backend

或:

com.starrocks.common.DdlException: no alive backends

这些错误“到底在检查什么”(对应代码)

1) 为什么会报 Cluster has no available capacity

建表前会调用容量校验:当 FE 视角下的集群可用容量 ≤ 0 \le 0 0 时直接拒绝建表:

    public long getClusterAvailableCapacityB() {
        List<Backend> clusterBackends = getBackends();
        long capacity = 0L;
        for (Backend backend : clusterBackends) {
            // Here we do not check if backend is alive,
            // We suppose the dead backends will back to alive later.
            if (backend.isDecommissioned()) {
                capacity -= backend.getDataUsedCapacityB();
            } else {
                capacity += backend.getAvailableCapacityB();
            }
        }
        return capacity;
    }

    public void checkClusterCapacity() throws DdlException {
        if (getClusterAvailableCapacityB() <= 0L) {
            throw new DdlException("Cluster has no available capacity");
        }
    }

要点:这条校验与“能不能选到 Alive BE”不是同一件事;它只看容量汇总结果。


2) 为什么会报 no alive backends / NoAliveBackendException

在普通建表路径里,如果 Alive 的 BE 数量为 0,直接抛 no alive backends

    private void buildPartitions(Database db, OlapTable table, List<Partition> partitions) throws DdlException {
        if (partitions.isEmpty()) {
            return;
        }
        int numAliveBackends = systemInfoService.getAliveBackendNumber();
        if (numAliveBackends == 0) {
            throw new DdlException("no alive backends");
        }

在 Lake 相关任务里,如果挑不到可用 BE,会抛 NoAliveBackendException(语义一样:找不到可用的 Alive BE)。


最常见根因(按优先级)

A) 该 FE 节点看到的 BE 状态/容量信息异常(尤其“Leader 正常但某些节点报错”)

典型场景:

  • Leader 能正常建表/写入/查询
  • 只有某些节点(常见是“以为自己是 follower 的节点”)在本机日志里刷 no capacity / no alive backend

高概率原因

  • 该节点并未真正加入 FE 集群(在 Leader 上 SHOW FRONTENDS; 看不到它)
  • 或该节点 journal 未追平/处于异常恢复,导致本地视角不完整
  • 或该节点到 BE 的网络不通(Leader 能通,但该节点不通)

B) BE 心跳/端口/进程问题(导致 Alive=false 或容量不上报)

常见表现:

  • SHOW BACKENDS 中某些 BE Alive=false
  • ErrMsgConnection refused / timeout / Invalid method name: 'heartbeat'
  • 端口字段为 -1 或容量字段异常

C) 容量确实为 0(磁盘满/路径不可用)

表现:

  • AvailCapacity 接近 0
  • 或 BE storage_root_path 配置/权限/挂载异常,导致容量上报异常

排查步骤(最短路径,强烈推荐照做)

第 1 步:在 Leader 上确认“集群真实状态”

SHOW FRONTENDS;
SHOW BACKENDS\G

判断:

  • 如果 SHOW FRONTENDS 只有 1 行(仅 Leader):说明你以为的 follower 很可能没入集群,它本机报错不代表集群
  • 如果 SHOW BACKENDS\G 里至少 1 台 BE Alive=trueAvailCapacity 很大:集群实际有容量;报错节点多半是“视角异常/不一致”。

第 2 步:在“报错的 FE 机器”确认它是否真的在同一个集群

在报错 FE 节点本机连它自己执行:

SHOW FRONTENDS;

对比 Leader 的输出:

  • 如果该节点的 ClusterId/成员列表与 Leader 不一致:它实际上在跑“另一个 FE 集群”(或加入失败)。

第 3 步:检查报错 FE → BE 网络连通性(非常高频)

在报错 FE 节点上执行(把 <BE_IP> 替换为任一 Alive 的 BE):

nc -zv <BE_IP> 9050   # heartbeat_service_port
nc -zv <BE_IP> 8060   # brpc_port
nc -zv <BE_IP> 8040   # webserver_port

任何一个端口不通,都可能导致:

  • BE 心跳失败(Alive=false)
  • BE 端口/容量无法刷新
  • 后台任务误判 no capacity / no alive backend

修复步骤(按根因对应处理)

修复 1:报错节点没真正加入 FE 集群(最常见,“Leader 正常但它一直报错”)

  1. 在 Leader 上添加 follower:
ALTER SYSTEM ADD FOLLOWER "<FE_FOLLOWER_IP>:9010";
  1. 在该 follower 机器上(推荐“干净加入”避免元数据不一致):
./bin/stop_fe.sh
mv meta meta_bak_$(date +%Y%m%d_%H%M%S)
./bin/start_fe.sh --helper <FE_LEADER_IP>:9010 --daemon
  1. 回到 Leader 验证:
SHOW FRONTENDS;

修复 2:BE 心跳端口登记错误(典型:把 9060 当成心跳)

现象:Invalid method name: 'heartbeat',且 HeartbeatPort 显示为 9060。

做法:在 FE 上删除错误登记、用 9050 重新添加:

ALTER SYSTEM DROP BACKEND "<BE_IP>:9060";
ALTER SYSTEM ADD BACKEND "<BE_IP>:9050";

修复 3:BE 端口拒绝连接 / BE 未监听(Connection refused

在 BE 机器上:

ss -lntp | egrep ':9050|:9060|:8040|:8060' || netstat -tlnp | egrep ':9050|:9060|:8040|:8060'
./bin/stop_be.sh
./bin/start_be.sh --daemon
tail -200 be/log/be.INFO | grep -i "error\|exception\|fail"

修复 4:容量确实不足(磁盘满/路径问题)

在 BE 机器上:

  • 检查 storage_root_path 配置是否正确
  • 检查磁盘空间 df -h
  • 检查目录权限(BE 用户可写)

验证(修复后 1~2 分钟内应达成)

SHOW BACKENDS\G
SHOW FRONTENDS;

期望:

  • 期望数量的 FE 全部在列,且 Alive=true
  • 至少 1 台 BE Alive=true,并且 AvailCapacity/TotalCapacity 正常
  • TableKeeper 日志不再周期性刷 Cluster has no available capacity

备注:TableKeeper 属于周期任务,修复后可能还会再打印 1-2 次历史错误,然后停止。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roman_日积跬步-终至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值