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

发布时间:2026/11/3 9:48:56
【StarRocks】 排错:TableKeeper 报 `Cluster has no available capacity` / `NoAliveBackendException`

文章目录

    • 适用范围
    • 典型日志(脱敏)
      • A) `Cluster has no available capacity`(TableKeeper 创建内部表失败)
      • B) `NoAliveBackendException` / `no alive backends`
    • 这些错误“到底在检查什么”(对应代码)
      • 1) 为什么会报 `Cluster has no available capacity`
      • 2) 为什么会报 `no alive backends` / `NoAliveBackendException`
    • 最常见根因(按优先级)
      • A) 该 FE 节点看到的 BE 状态/容量信息异常(尤其“Leader 正常但某些节点报错”)
      • B) BE 心跳/端口/进程问题(导致 Alive=false 或容量不上报)
      • C) 容量确实为 0(磁盘满/路径不可用)
    • 排查步骤(最短路径,强烈推荐照做)
      • 第 1 步:在 **Leader** 上确认“集群真实状态”
      • 第 2 步:在“报错的 FE 机器”确认它是否真的在同一个集群
      • 第 3 步:检查报错 FE → BE 网络连通性(非常高频)
    • 修复步骤(按根因对应处理)
      • 修复 1:报错节点没真正加入 FE 集群(最常见,“Leader 正常但它一直报错”)
      • 修复 2:BE 心跳端口登记错误(典型:把 9060 当成心跳)
      • 修复 3:BE 端口拒绝连接 / BE 未监听(`Connection refused`)
      • 修复 4:容量确实不足(磁盘满/路径问题)
    • 验证(修复后 1~2 分钟内应达成)

适用范围

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

  • FE 后台线程(常见为TableKeeper)周期性报错:Cluster has no available capacity
  • 业务/后台任务报错:com.starrocks.common.NoAliveBackendException: No alive backend或no 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中某些 BEAlive=false
  • ErrMsg为Connection refused/timeout/Invalid method name: 'heartbeat'
  • 端口字段为-1或容量字段异常

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

表现:

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

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

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

SHOWFRONTENDS;SHOWBACKENDS\G

判断:

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

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

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

SHOWFRONTENDS;

对比 Leader 的输出:

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

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

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

nc-zv<BE_IP>9050# heartbeat_service_portnc-zv<BE_IP>8060# brpc_portnc-zv<BE_IP>8040# webserver_port

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

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

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

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

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

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

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

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

ALTERSYSTEMDROPBACKEND"<BE_IP>:9060";ALTERSYSTEMADDBACKEND"<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--daemontail-200be/log/be.INFO|grep-i"error\|exception\|fail"

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

在 BE 机器上:

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

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

SHOWBACKENDS\GSHOWFRONTENDS;

期望:

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

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