本文汇总了使用EMR Serverless StarRocks时的常见问题。
如何跨账号访问OSS?
在使用Serverless StarRocks进行数据导入或数据湖操作时,您可能需要访问不同阿里云账户下的OSS资源。默认情况下,Serverless StarRocks已配置为对当前账户下的OSS Bucket提供无密码的自动访问权限。如果您需要访问其他账户下的OSS资源,则需先取消当前的默认设置,并手动配置目标账户的访问密钥,然后提交参数以使配置生效。
禁用现有免密访问:在参数配置页签的以下文件中,删除配置项的值,保持配置项内容为空。
core-site.xml
fs.oss.credentials.provider =jindosdk.cfg
fs.oss.provider.format = fs.oss.provider.endpoint =
添加目标账号的AccessKey:在参数配置页签,单击新增配置项,在以下文件中添加下列配置信息。
core-site.xml
fs.oss.accessKeyId = 目标账号的AccessKey ID fs.oss.accessKeySecret = 目标账号的AccessKey Secretjindosdk.cfg
fs.oss.accessKeyId = 目标账号的AccessKey ID fs.oss.accessKeySecret = 目标账号的AccessKey Secret
使配置项生效:在参数配置页签,单击提交参数。
如何使用UDF和JDBC连接器驱动?
在使用UDF和JDBC驱动前,您需要从外部获取相应的JAR文件。
上传JAR文件至OSS,详情请参见上传文件。
在上传文件时,请将文件 ACL设置为公共读写,以确保上传的JAR文件具备公共读写权限。
获取JAR文件的URL。
对于每个成功上传的JAR文件,在OSS控制台上找到它对应的链接地址。请使用内部网络Endpoint的HTTP URL,格式如下:
对于JDBC驱动:
http://<YourBucketName>.oss-cn-xxxx-internal.aliyuncs.com/mysql-connector-java-*.jar。对于UDF:
http://<YourBucketName>.oss-cn-xxxx-internal.aliyuncs.com/<YourPath>/<jar_package_name>。
使用JAR文件,详情请参见Java UDF和JDBC Catalog。
如何重置实例的密码?
重置实例的密码将导致客户端与服务端连接中断,因此请务必在业务低峰期对生产环境进行此操作。
仅具备AliyunEMRStarRocksFullAccess权限的用户才能执行密码重置操作。
进入实例详情页面。
在左侧导航栏,选择。
单击目标实例的名称。
在实例详情页面,单击基础信息区域的重置密码。
在弹出的对话框中,输入新密码和确认密码,单击确定。
为什么向Paimon表写入数据时报错?
问题现象:在使用StarRocks向Paimon表写入数据时,可能会遇到以下错误信息。
(5025, 'Backend node not found. Check if any backend node is down.')问题原因:Paimon表的权限检查机制可能导致StarRocks在进行写入操作时无法正确识别后端节点。
解决方法:
升级版本(推荐方式) 如果您使用的版本低于下述版本,请您升级小版本,以更新至最新版本并获得修复。
StarRocks 3.2版本:3.2.11-1.89 及以上
StarRocks 3.3版本:3.3.8-1.88 及以上
临时解决方法 在StarRocks实例的参数配置页签中的
core-site.xml配置文件中添加以下配置项。dlf.permission.clientCheck=false
在StarRocks中创建外表时提示not a RAM user错误,该如何处理?
为什么在SQL Editor中执行包含分号的SQL时会报错?
问题现象:在SQL Editor中执行包含分号(
;)的SQL时报错,报错信息包含the most similar input is {a legal identifier}。
问题原因:因为SQL Editor默认将分号(
;)作为语句结束符。如果您的SQL语句中包含分号(;),则会导致语法解析错误。解决方法:
设置自定义分隔符。
在执行包含分号的SQL语句前,设置一个自定义分隔符,以避免语法解析错误。例如,改为
$$。delimiter $$执行包含分号的SQL语句。本文示例如下所示。
INSERT INTO sr_test VALUES (1, 'asdsd,asdsads'), (2, 'sadsad;asdsads');恢复默认分隔符。
在执行完SQL语句后,恢复默认的分隔符(
;),以便后续的SQL操作可以正常使用。delimiter ;验证结果。
执行查询语句验证数据是否正确插入。

为什么Serverless StarRocks在导入数据或访问外表时失败?
问题现象:在使用Serverless StarRocks进行数据导入或访问外部表时,如果目标地址为公网地址,可能会遇到导入失败或连接失败的问题。
原因分析:Serverless StarRocks实例默认运行在专有网络(VPC)环境中,该环境可能不具备直接访问公网的能力。因此,当需要访问公网资源(如导入数据或查询外部表)时,若未配置公网访问能力,请求将无法成功。
解决方法:您可以通过在VPC中部署公网NAT网关并启用SNAT功能,使Serverless StarRocks实例能够通过该网关访问公网资源。更多信息,请参见使用公网NAT网关SNAT功能访问互联网。
如何避免StarRocks实例中的CLB/SLB因连接空闲超时而关闭客户端连接?
问题现象:在StarRocks实例中,当FE节点数大于1时,可以通过开通SLB(Server Load Balancer)实现负载均衡,详情请参见管理网关。当StarRocks实例开启SLB后,若SQL查询执行时间超过900秒,客户端与SLB之间的连接会被强制断开,导致查询结果无法返回。
问题原因:SLB的TCP连接存在一个最大空闲超时时间(900 秒)。如果客户端与SLB之间的连接在900秒内没有数据传输(例如,执行长时间运行的SQL查询),SLB会主动关闭该连接。这会导致客户端在等待StarRocks响应时出现连接中断的问题。
解决方法:通过设置客户端的TCP Keepalive参数以维持客户端和SLB之间的连接,避免连接空闲超时关闭。
全局内核参数设置(系统级)
通过修改操作系统的内核参数,为所有TCP连接启用并配置合理的TCP Keepalive参数,以检测网络连接的存活状态。以下是需要设置的参数及其具体含义。
参数
含义
建议值
Linux系统:
net.ipv4.tcp_keepalive_timeFreeBSD/macOS:
net.inet.tcp.keepidle
连接空闲多久后发送第一个Keepalive探测包(单位:秒)。
600秒
Linux系统:
net.ipv4.tcp_keepalive_intvlFreeBSD/macOS:
net.inet.tcp.keepintvl
Keepalive探测包的重传间隔(单位:秒)。
60秒
Linux系统:
net.ipv4.tcp_keepalive_probesFreeBSD/macOS:
net.inet.tcp.keepcnt
探测包连续发送失败的次数,达到此值后断开连接。
5次
Linux系统
临时生效
# 设置全局Keepalive参数(需要root权限) sudo sysctl -w net.ipv4.tcp_keepalive_time=600 # 对应keepidle(600秒) sudo sysctl -w net.ipv4.tcp_keepalive_intvl=60 # 对应keepintvl(60秒) sudo sysctl -w net.ipv4.tcp_keepalive_probes=5 # 对应keepcount(5次)永久生效
将以下内容添加到
/etc/sysctl.conf,并执行sysctl -p生效。echo "net.ipv4.tcp_keepalive_time = 600" >> /etc/sysctl.conf echo "net.ipv4.tcp_keepalive_intvl = 60" >> /etc/sysctl.conf echo "net.ipv4.tcp_keepalive_probes = 5" >> /etc/sysctl.conf
FreeBSD/macOS系统
临时生效
# 设置全局Keepalive参数(需要root权限) sudo sysctl -w net.inet.tcp.keepidle=600 sudo sysctl -w net.inet.tcp.keepintvl=60 sudo sysctl -w net.inet.tcp.keepcnt=5永久生效
将以下内容添加到
/etc/sysctl.conf。echo "net.inet.tcp.keepidle = 600" >> /etc/sysctl.conf echo "net.inet.tcp.keepintvl = 60" >> /etc/sysctl.conf echo "net.inet.tcp.keepcnt = 5" >> /etc/sysctl.conf
编程语言适配(应用级)
通过语言特定的API设置单个连接的TCP Keepalive参数。
Java
Java标准库对TCP Keepalive的支持有限,但可以通过反射或底层Socket选项实现。
说明以下代码依赖于系统(如Linux/FreeBSD)对 tcp_keepidle等选项的支持。此外,部分方法(如反射)可能因JVM版本差异而失效,建议在实际使用前进行兼容性测试。
import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketOption; import java.nio.channels.SocketChannel; public class TcpKeepaliveExample { public static void main(String[ ] args) { try (Socket socket = new Socket()) { // 1. 启用 Keepalive socket.setKeepAlive(true); // 2. 设置 Keepalive 参数(需通过底层 Socket 选项) SocketChannel channel = socket.getChannel(); if (channel != null) { // 设置 Keepidle(空闲时间) channel.setOption(StandardSocketOptions.SO_KEEPALIVE, true); // 必须先启用 Keepalive setSocketOptionInt(socket, "tcp_keepidle", 600); // 需要系统支持 // 设置 Keepintvl(重传间隔) setSocketOptionInt(socket, "tcp_keepintvl", 60); // 设置 Keepcount(失败次数) setSocketOptionInt(socket, "tcp_keepcnt", 5); // 注意:参数名可能因系统而异 } // 连接到服务器 socket.connect(new InetSocketAddress("example.com", 80)); // ... 其他操作 ... } catch (IOException e) { e.printStackTrace(); } } // 通过反射设置系统特定的 Socket 选项(如 Linux/FreeBSD) private static void setSocketOptionInt(Socket socket, String optionName, int value) { try { Class<?> clazz = Class.forName("java.net.Socket$SocketOptions"); Object options = clazz.getDeclaredMethod("options").invoke(socket); Class<?> optionsClass = options.getClass(); optionsClass.getDeclaredMethod("setOption", String.class, int.class) .invoke(options, optionName, value); } catch (Exception e) { throw new RuntimeException("Failed to set socket option " + optionName, e); } } }Python
Python的
socket模块支持直接配置TCP Keepalive参数。说明不同操作系统可能使用不同的参数名称(例如,macOS可能需用
TCP_KEEPALIVE代替TCP_KEEPIDLE),且部分参数可能需要root权限才能进行设置。import socket def create_keepalive_socket(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 1. 启用 Keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 2. 设置 Keepalive 参数(Linux/FreeBSD) # Keepidle: 600秒 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) # Keepintvl: 60秒 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 60) # Keepcount: 5次 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5) return sock # 使用示例 sock = create_keepalive_socket() sock.connect(("example.com", 80)) # ... 其他操作 ... sock.close()Golang
Golang的
net包提供了基础的Keepalive配置,但需通过底层的syscall包设置详细参数。说明不同操作系统可能使用不同的参数名称,且部分参数可能需要root权限才能进行设置。
package main import ( "fmt" "net" "syscall" ) func main() { // 创建 TCP 连接 conn, err := net.Dial("tcp", "example.com:80") if err != nil { panic(err) } defer conn.Close() // 获取底层文件描述符 fd := conn.(*net.TCPConn).SyscallConn() // 设置 Keepalive 参数 fd.Control(func(fdPtr *net.FileDesc) { fd := fdPtr.File // 启用 Keepalive err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPALIVE, 1) if err != nil { panic(err) } // 设置 Keepidle(空闲时间) err = syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, syscall.TCP_KEEPIDLE, 600) if err != nil { panic(err) } // 设置 Keepintvl(重传间隔) err = syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, syscall.TCP_KEEPINTVL, 60) if err != nil { panic(err) } // 设置 Keepcount(失败次数) err = syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, syscall.TCP_KEEPCNT, 5) if err != nil { panic(err) } }) // ... 其他操作 ... }
StarRocks备份数据报错Unexpected exception: Table '' is not a OLAP table
问题现象:在使用StarRocks进行数据快照备份时,遇到以下报错信息。
Unexpected exception: Table '<table_name>' is not a OLAP table原因分析:
实例为存算分离模式
StarRocks存算分离实例不支持数据备份和恢复功能,仅存算一体实例支持此功能。
表引擎类型不兼容
StarRocks的备份功能仅支持OLAP引擎的表。如果表的引擎类型不是OLAP,则会触发该报错。
解决方法:
查看实例类型。
在StarRocks的实例列表中,查看实例类型。如果实例为存算分离版,则不支持数据备份和恢复功能。建议您使用存算一体实例以启用备份和恢复功能。更多信息,请参见备份与恢复(Beta)。
检查表引擎类型。
检查目标表的DDL定义,确认是否设置了
ENGINE=OLAP。SHOW CREATE TABLE <table_name>;如果表的引擎不是OLAP,请根据业务需求重新创建表,并确保指定
ENGINE=OLAP。
主键模型导入报错:msg:Cancelled, msg: Primary-key index exceeds the limit
问题现象:
在主键模型写入数据时,报错如下:
msg: Cancelled, msg: Primary-key index exceeds the limit. tablet_id: 2506733, consumption: 33176971421, limit: 32116807950. Memory stats of top five tablets: 3656508(4465M) 3656496(4464M) 3656544(4464M) 3656520(4462M) 3656532(4461M): be: backend-0.backend.xxx.svc.cluster.local.xxx排查思路:
分析当前 BE 节点内存使用情况,确认是否存在资源瓶颈。
判断集群类型(存算一体 or 存算分离),并检查对应配置项。
详细排查步骤:
分析内存使用
报错的根本原因是:主键索引内存消耗超过了 BE 节点的内存上限(limit)。
查看 BE 节点的
mem_limit配置(可通过SHOW FRONTENDS或SHOW BACKENDS获取),评估其可用内存容量。
解决方案
解法一:启用持久化索引(推荐)
存算一体:将
enable_persistent_index设置为true。存算分离:将
persistent_index_type设置为cloud_native。
解法二:合理分区设计
对主键表进行合理的分区(如按时间、地域等维度),避免全表写入。
分区后,每次写入仅影响部分分区,主键索引只需加载对应分区的数据,从而降低单次写入的内存压力。
导入任务报错:[E1008]Reached timeout=xxx ms
问题现象:
业务 Flink 任务向 StarRocks 导入数据时,报错:
Message: [E1008] Reached timeout=7500ms @x.x.x.x:8060。业务通过
INSERT INTO方式导入数据时,报错:java.sql.SQLException: [E1008] Reached timeout=7500ms @10.106.7.182:8060。
排查思路:
若报错中的超时值 不等于 30000ms(即默认的
rpc_connect_timeout_ms),需确认是否手动调整过 BE 节点的rpc_connect_timeout_ms参数(默认值为 30000ms);对于
INSERT INTO类型的导入任务,需确认是否设置了query_timeout参数(例如query_timeout = 15)。当前 StarRocks 的内部逻辑会将 RPC 超时阈值设为query_timeout的一半(单位:ms),因此若query_timeout=15,则对应超时为 7500ms。
详细排查步骤:
如确认修改了 BE 的
rpc_connect_timeout_ms参数。建议恢复为默认值(30000ms),避免因过短的连接超时引发误判。报错中
Reached timeout=7500ms通常表明 BE 节点的 brpc 线程负载较高,导致 RPC 请求处理延迟,进而触发超时。通过分析目标表的数据分布情况:
SHOW TABLET FROM 目标数据库.目标表 ORDER BY RowCount DESC;以确认业务表的Tablet数据分布是否合理。例如,单个Tablet的数据量若远超最佳实践推荐范围(1GB ~ 10GB),将导致部分BE节点的负载过高,从而影响写入性能。解决方案:
解法一(推荐):
优化表的分桶策略,重新选择合适的 高基数(High Cardinality)字段 作为DISTRIBUTED BY HASH(...)的分桶键,使数据在 Tablet 间均匀分布。解法二(临时缓解):
在 BE 节点 CPU 和 I/O 负载未达瓶颈 的前提下,可适当调优以下参数:增大
brpc_num_threads:默认值为 BE CPU 核数,可尝试调整为 2 倍或 4 倍(不建议超过 4 倍,以免线程竞争加剧);增大
flush_thread_num_per_store:默认值为 2,可调整为 4,以提升数据刷盘并发能力。
导入任务报“Error:NULL value in non-nullable column 'xxx'”错误
问题现象:向 StarRocks 表导入数据时,出现如下错误:
Error: NULL value in non-nullable column 'xxx'。问题原因:向定义为
NOT NULL的列写入了NULL值,违反了表结构约束,导致导入任务失败。解决方法:
方案一:修复上游数据
在数据写入 StarRocks 前,过滤或填充
NULL值,确保符合目标表约束。方案二:调整表结构
若业务逻辑确实允许该字段为空,建议修改表结构,移除
NOT NULL约束。
Flink connector数据导入报because of too many versions, current/limit: 1009/1000错误
问题现象:
通过 Flink Connector 向 StarRocks 表持续写入数据,出现如下报错:
because of too many versions, current/limit: 1009/1000。问题原因:在 StarRocks 的主键模型(Primary Key Model)或更新模型(Unique Key with Merge-on-Write)中,每次数据导入都会生成一个新版本。为防止元数据膨胀并保证查询性能,系统默认限制每个分区最多保留 1000 个版本。
解决方法:
检查分区 Compaction Score。
执行以下 SQL,查看目标表各分区的 Compaction 压力:
SELECT TABLE_NAME, PARTITION_NAME, AvgCS AS avg_compaction_score, MaxCS AS max_compaction_score FROM information_schema.partitions_meta WHERE TABLE_NAME = 'your_table_name';报错分区的
MaxCS(最大 Compaction Score)远高于 100,说明存在大量待合并的小版本,Compaction 未能及时完成。手动触发 Compaction。
执行
ALTER TABLE your_db.your_table COMPACT PARTITION your_partition_name;优化 Flink 写入参数。
调大Flink侧的sink参数,包括
sink.buffer-flush.max-bytes、sink.buffer-flush.max-rows及sink.buffer-flush.interval-ms,以减少导入频次,从而避免生成过多的小版本。
External Catalog方式查询报Failed to get status for file xxx错误
问题现象:
查询外部数据湖(如Paimon、Iceberg 等)中的表时,查询报错:
(1064, 'Failed to get status for file: oss://data-lakehouse-oss-normal/dataware.db/dwd_annotation2_user/metadata/00097-10647858-814a-499e-b300-51c570ee7ee0.metadata.json')。OSS API 返回错误信息:<Error> <Code>AccessDenied</Code> <Message>You have no right to access this object because of bucket acl.</Message> <RequestId>68EC744EB6CD8C3539FAB32A</RequestId> <HostId>data-lakehouse-oss-normal.oss-cn-shenzhen-internal.aliyuncs.com</HostId> <EC>0003-00000001</EC> <RecommendDoc>https://api.aliyun.com/troubleshoot?q=0003-00000001</RecommendDoc> </Error>问题原因:StarRocks 通过 External Catalog 功能查询外部数据湖(如 Hive、Iceberg、Hudi 等)中的表,底层依赖对对象存储(如阿里云 OSS)的访问能力。若权限或配置不当,将导致元数据或数据文件读取失败。
解决方法:
首先验证 AccessKey 有效性:确认所配置的
accessKeyId/accessKeySecret能正常访问目标 OSS Bucket。如果
accessKeyId/accessKeySecret配置正确,请确认是否存在跨账号访问OSS Bucket的情况。对于跨账号访问OSS Bucket,需对以下配置进行修改,详细操作请参见如何跨账号访问OSS?。
如何查看cn、be节点硬盘上持久化索引占用硬盘的大小?
在启用持久化索引(enable_persistent_index = true 或 persistent_index_type = 'cloud_native')后,主键索引会落盘存储。可通过 information_schema.be_tablets 表查询其磁盘使用量。
-- 查询表的索引大小信息,按索引大小降序排列
SELECT
tables_config.TABLE_NAME,
t1.TABLE_ID,
t1.index_sum_mb
FROM (
-- 计算每个表的索引总大小(MB)
SELECT
TABLE_ID,
SUM(INDEX_DISK)/1024/1024 AS index_sum_mb
FROM information_schema.be_tablets
GROUP BY TABLE_ID
) t1
JOIN tables_config ON tables_config.TABLE_ID = t1.TABLE_ID
ORDER BY index_sum_mb DESC
-- 可选:添加LIMIT子句限制返回结果数量,避免数据量过大
-- LIMIT 100
;如何查看表正在写入的事务以及不同txn写入批次对应的tablet?
追踪正在进行或最近完成的导入任务,定位具体写入的 Tablet 分布。
SELECT
txn_table.*,
tc.table_name
FROM (
SELECT
bt.TABLET_ID,
bt.COMMIT_TIME,
bt.PUBLISH_TIME,
bt.TABLE_ID
FROM information_schema.be_txns bt
JOIN information_schema.be_tablets btt
ON bt.TABLET_ID = btt.TABLET_ID
) AS txn_table
JOIN information_schema.tables_config tc
ON txn_table.TABLE_ID = tc.TABLE_ID;分析某时间段内 CPU / 内存负载突增原因?
通过审计日志(Audit Log)定位高资源消耗的查询。
SELECT
queryId,
timestamp,
ROUND(memCostBytes / 1024 / 1024 / 1024, 2) AS memCostGB,
cpuCostNs
FROM _starrocks_audit_db_.starrocks_audit_tbl
WHERE timestamp BETWEEN '2025-xx-xx hh:mm:ss' AND '2025-xx-xx hh:mm:ss'
ORDER BY cpuCostNs DESC, memCostGB DESC
LIMIT 20;分析某时间段内 I/O 负载突增原因
I/O 峰值通常由大范围扫描(如全表扫描、未命中分区/索引)引起。
SELECT
queryId,
timestamp,
ROUND(scanBytes / 1024 / 1024 / 1024, 2) AS scanTotalGB
FROM _starrocks_audit_db_.starrocks_audit_tbl
WHERE timestamp BETWEEN '2025-xx-xx hh:mm:ss' AND '2025-xx-xx hh:mm:ss'
ORDER BY scanTotalGB DESC
LIMIT 20;