StarRocks关于ConcurrentModificationException 问题的解决
背景
本文基于 StarRocks 3.1.7
目前在基于Starrocks做一些数据分析的操作(主要是做一些简单的查询),同事遇到了一些并发的问题:
ontent:2024-11-27 07:04:34,048 WARN (starrocks-mysql-nio-pool-214933|3593819) [StmtExecutor.execute():643] execute Exception, sql SELECT distinct(id) FROM `db`.`table` WHERE col1='xxx' AND col2='xxx'
java.util.ConcurrentModificationException: nullat java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719) ~[?:?]at java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:746) ~[?:?]at com.starrocks.sql.optimizer.statistics.StatisticsCalcUtils.deltaRows(StatisticsCalcUtils.java:176) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.statistics.StatisticsCalcUtils.getTableRowCount(StatisticsCalcUtils.java:114) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.statistics.StatisticsCalculator.computeOlapScanNode(StatisticsCalculator.java:257) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.statistics.StatisticsCalculator.visitLogicalOlapScan(StatisticsCalculator.java:225) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.statistics.StatisticsCalculator.visitLogicalOlapScan(StatisticsCalculator.java:161) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.operator.logical.LogicalOlapScanOperator.accept(LogicalOlapScanOperator.java:149) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.statistics.StatisticsCalculator.estimatorStats(StatisticsCalculator.java:177) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.task.DeriveStatsTask.execute(DeriveStatsTask.java:57) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.task.SeriallyTaskScheduler.executeTasks(SeriallyTaskScheduler.java:69) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.Optimizer.memoOptimize(Optimizer.java:595) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.Optimizer.optimizeByCost(Optimizer.java:201) ~[starrocks-fe.jar:?]at com.starrocks.sql.optimizer.Optimizer.optimize(Optimizer.java:134) ~[starrocks-fe.jar:?]at com.starrocks.sql.StatementPlanner.createQueryPlan(StatementPlanner.java:146) ~[starrocks-fe.jar:?]at com.starrocks.sql.StatementPlanner.planQuery(StatementPlanner.java:121) ~[starrocks-fe.jar:?]at com.starrocks.sql.StatementPlanner.plan(StatementPlanner.java:92) ~[starrocks-fe.jar:?]at com.starrocks.sql.StatementPlanner.plan(StatementPlanner.java:61) ~[starrocks-fe.jar:?]at com.starrocks.qe.StmtExecutor.execute(StmtExecutor.java:456) ~[starrocks-fe.jar:?]at com.starrocks.qe.ConnectProcessor.handleQuery(ConnectProcessor.java:392) ~[starrocks-fe.jar:?]at com.starrocks.qe.ConnectProcessor.dispatch(ConnectProcessor.java:506) ~[starrocks-fe.jar:?]at com.starrocks.qe.ConnectProcessor.processOnce(ConnectProcessor.java:782) ~[starrocks-fe.jar:?]at com.starrocks.mysql.nio.ReadListener.lambda$handleEvent$0(ReadListener.java:69) ~[starrocks-fe.jar:?]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[?:?]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[?:?]at java.lang.Thread.run(Thread.java:829) ~[?:?]
涉及到的表如下:
CREATE TABLE `table` (`id` bigint(20) NOT NULL ,`create_date` datetime NOT NULL ,`col1` varchar(64) NOT NULL ,`col2` varchar(20) NOT NULL
) ENGINE = OLAP PRIMARY KEY(`create_date`, `id`
) COMMENT ""
PARTITION BY date_trunc('month', create_date) DISTRIBUTED BY HASH(`id`) PROPERTIES ("replication_num" = "3", "in_memory" = "false", "enable_persistent_index" = "true", "replicated_storage" = "true", "partition_live_number" = "18", "compression" = "LZ4");
结论
StarRocks 对分区带有TTL的表,会后台启动线程轮询的去删除分区,轮询的间隔受到 dynamic_partition_check_interval_seconds 控制,
然而在查询的时候, Starrocks会做语法解析,以及基于CBO的优化,在这期间会统计涉及到的表的分区信息统计,而此时恰好遇到了后台线程的分区删除,导致了ConcurrentModificationException 并发异常。
目前可以参考这个issue ConcurrentModificationException when query during drop partition,以及 增大 dynamic_partition_check_interval_seconds(目前是10分钟) 这个参数来降低这种冲突的概率。
分析
这里主要涉及到两个部分:
一个部分是查询部分(主要是StmtExecutor.execute),一个是后台清理分区部分(DynamicPartitionScheduler)
查询部分
每个SQL查询都会经过 StmtExecutor.execute方法,进而生成物理执行计划,而在生成物理执行计划的阶段,会经过Optimizer 阶段,这个阶段由于默认情况下是基于CBO的优化,所以会统计涉及的表所扫描的数据量,最终会走到 StatisticsCalcUtils.deltaRows方法:
private static long deltaRows(Table table, long totalRowCount) {long tblRowCount = 0L;for (Partition partition : table.getPartitions()) {long partitionRowCount;TableStatistic tableStatistic = GlobalStateMgr.getCurrentStatisticStorage().getTableStatistic(table.getId(), partition.getId());if (tableStatistic.equals(TableStatistic.unknown())) {partitionRowCount = partition.getRowCount();} else {partitionRowCount = tableStatistic.getRowCount();}tblRowCount += partitionRowCount;}if (tblRowCount < totalRowCount) {return Math.max(1, (totalRowCount - tblRowCount) / table.getPartitions().size());} else {return 0;}}
这里会对 table.getPartitions 进行 迭代,也就是OlapTable的 idToPartition.valus 进行迭代, 注意 idToPartition 是HashMap类型的,
总体的流程如下:
StmtExecutor.execute||\/
StatementPlanner.plan||\/
StatementPlanner.planQuery||\/
StatementPlanner.createQueryPlan||\/
Optimizer.optimize||\/
Optimizer.optimizeByCost||\/
Optimizer.memoOptimize||\/
SeriallyTaskScheduler.executeTasks||\/
DeriveStatsTask.execute||\/
StatisticsCalculator.estimatorStats||\/
StatisticsCalculator.computeOlapScanNode||\/
StatisticsCalcUtils.getTableRowCount||\/
StatisticsCalcUtils.deltaRows
后台清理部分
对于这种带有TTL的分区表来说,会有 DynamicPartitionScheduler 这个后台线程进行分区的删除。具体代码见:
protected void runAfterCatalogReady() {if (!initialize) {// check Dynamic Partition tables only when FE startinitDynamicPartitionTable();}setInterval(Config.dynamic_partition_check_interval_seconds * 1000L);if (Config.dynamic_partition_enable) {executeDynamicPartition();}executePartitionTimeToLive();}
其中删除分区的频率就是由 Config.dynamic_partition_check_interval_seconds 也就是dynamic_partition_check_interval_seconds来决定的,
其中executeDynamicPartition方法就是执行分区删除,具体数据流如下 :
executeDynamicPartition||\/
executeDynamicPartitionForTable||\/
getDropPartitionClause||\/
GlobalStateMgr.getCurrentState().dropPartition(db, olapTable, dropPartitionClause);||\/
olapTable.dropPartition(db.getId(), partitionName, clause.isForceDrop());||\/
idToPartition.remove(partition.getId());
其中 在 executeDynamicPartitionForTable 中 RangePartitionInfo rangePartitionInfo = (RangePartitionInfo) olapTable.getPartitionInfo(); 会根据PartitionInfo的信息来进行判断,只有 RangePartitionInfo类型支持partition TTL删除,也就是Expression partitioning (recommended) 和Dynamic partitioning支持.
在最后的idToPartition.remove(partition.getId())中就会删除正在进行查询迭代的idToPartition.values,就是导致并发问题
相关文章:
StarRocks关于ConcurrentModificationException 问题的解决
背景 本文基于 StarRocks 3.1.7 目前在基于Starrocks做一些数据分析的操作(主要是做一些简单的查询),同事遇到了一些并发的问题: ontent:2024-11-27 07:04:34,048 WARN (starrocks-mysql-nio-pool-214933|3593819) [StmtExecutor.execute():643] execute Exceptio…...
网络安全防护指南:筑牢网络安全防线(5/10)
一、网络安全的基本概念 (一)网络的定义 网络是指由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息收集、存储、传输、交换、处理的系统。在当今数字化时代,网络已经成为人们生活和工作中不可或缺的一部分。它连接了世…...
替代FTP最佳跨网文件传输解决方案——FileLink
在传统的企业文件传输中,FTP(文件传输协议)曾因其便捷性和高效性被广泛应用。然而,其固有的安全漏洞、对大文件传输支持的局限性、易受网络攻击等问题,已逐渐暴露出FTP在现代企业环境下的不足。针对这一问题࿰…...
Cesium在vue2中的引入和注意事项
在Vue2中,可以使用npm包管理工具来安装Cesium,并通过import语句将其引入到项目中。下面是在Vue2中引入Cesium的步骤和注意事项: 步骤: 首先,打开终端并进入Vue项目的根目录。 运行以下命令来安装Cesium: …...
CentOS 9 配置静态IP
文章目录 1_问题原因2_nmcli 配置静态IP3_使用配置文件固定IP4_重启后存在的问题5_nmcli 补充 1_问题原因 CentOS 7 于 2014年6月发布,基于 RHEL 7,并在 2024年6月30日 结束维护。 CentOS 9 作为目前的最新版本,今天闲来闲来无事下载下来后…...
深入解析 Webhook:从原理到实践的全面指南
1. 引言 1.1 什么是 Webhook? Webhook 是一种基于 HTTP 回调的轻量级通信机制,它允许一个系统实时向另一个系统发送数据。当特定事件发生时,Webhook 会主动向指定的 URL 发送 HTTP 请求,通常携带事件相关的数据。这种被动接收通…...
基于springboot+vue实现的创新创业学分管理系统 (源码+L文+ppt)4-111
4 系统总体设计 4.1系统功能结构设计图 根据需求说明设计系统各功能模块。采用模块化设计方法实现一个复杂结构进行简化,分成一个个小的容易解决的板块,然后再将小的板块继续分化成功能单一的更小模块。模块化设计方法使测试调试、维护更容易ÿ…...
如何高效地架构一个Java项目
引言 Java是企业级应用开发的主流语言之一,而我们作为使用Java语言的程序员,职称有初级、中级、高级、资深、经理、架构,但我们往往只是慢慢通过经验的积累迭代了自己的等级,如果没有保持学习的习惯,大多数程序员会停留…...
Scala的模式匹配(8)
package hfdobject Test35_1 { //需求:现在有一个数组Array(1,2,3,4)。我希望能定义三个变量,他们的值分别是数组中的第1,2,3个元素的值 def main(args: Array[String]): Unit {val arr Array(1,2,3,4,5)//第一个元素的值:arr(0…...
nodejs30: CSS 剪辑路径clip-path导致伪元素不可见问题及解决方法
相关问题 应用圆角裁剪时无法显示::after 取消clip-path设置: 完整问题代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, i…...
Git分布式版本控制工具 Git基本概念、Git工作流程、Git常用命令、Git远程仓库、IDEA操作Git
目录 1.Git基本概念 1.1 概述 1.1.1 开发中的实际场景 1.1.2 版本控制器的方式 1.1.2.1 集中式版本控制工具(SVN) 1.1.2.2 分布式版本控制工具(Git) 2.概述git工作流程 3.Git常用命令 3.1 Git环境配置 3.1.1 下载与安装 3.1.2 基本配置 3.1.3 为常用指令配置别名&…...
十,[极客大挑战 2019]Secret File1
点击进入靶场 查看源代码 有个显眼的紫色文件夹,点击 点击secret看看 既然这样,那就回去查看源代码吧 好像没什么用 抓个包 得到一个文件名 404 如果包含"../"、"tp"、"input"或"data",则输出"…...
Android 获取数字键盘和输入类型
在Android中,获取数字键盘可以通过为EditText设置输入类型为number或numberPassword来实现。以下是一个简单的例子: <!-- 在XML布局文件中 --> <EditText android:id"id/editTextNumber" android:layout_width"match_parent…...
8. 一分钟读懂“代理模式”
8.1 模式介绍 代理模式是一种结构型设计模式,它通过提供一个代理对象来替代对另一个对象(真实对象)的访问。代理对象与真实对象实现相同的接口,并通过代理类对真实对象的访问进行控制,可以在调用前后执行附加操作&…...
【实战攻略】如何从零开始快速实现深度学习新想法?——四步走战略
标题 【实战攻略】如何从零开始快速实现深度学习新想法?——四步走战略 【核心结论】 通过四步走战略,即找到baseline论文、深入baseline代码、搭建自己的pipeline、融入核心算法,新手也能快速实现深度学习新想法。 【通俗解释࿰…...
Creating Server TCP listening socket *:6379: bind: No error
启动redis报错:Creating Server TCP listening socket *:6379: bind: No error 解决方案: 1、直接在命令行中输入 redis-cli.exe 2、输入shutdown,关闭 3、输exit,退出 4、重新输入 redis-server.exe redis.windows.conf&…...
Go热加载工具air-使用说明-win11问题解决指南
写web程序 每次都要ctrlc 然后go run .非常但疼 用一下这个热加载工具air Live reload for Go apps 贴个github地址:https://github.com/air-verse/air 1. go版本1.23先install一下 go install github.com/air-verse/airlatest下载完发现输入air windows还是报…...
华为HarmonyOS 让应用快速拥有账号能力 -- 2 获取用户头像昵称
场景介绍 如应用需要完善用户头像昵称信息,可使用Account Kit提供的头像昵称授权能力,用户允许应用获取头像昵称后,可快速完成个人信息填写。以下只针对Account kit提供的头像昵称授权能力进行介绍,若要获取头像还可通过场景化控…...
oracle表迁移至postgre
第一步: 导出表结构 进入脚本 第二步: 删除spool相关和prompt相关(不需要表空间的情况下) 类似以下语句 第三步: 修改数据类型 VARCHAR2 --> VARCHAR VARCHAR2(200 CHAR) --> VARCHAR(200) NUMBER(10,2) --> numeric(10,2…...
【PlantUML系列】类图(一)
目录 一、类 二、接口 三、抽象类 四、泛型类 五、类之间的关系 六、添加注释 七、包图 八、皮肤参数 一、类 使用class关键字定义类,类名后跟大括号,声明类的属性和方法。 属性:格式为{visibility} attributeName : AttributeType…...
前端测试的学习阶段,由基础到进阶的过程认识.....
前言:突然想起刚入行的学习感悟,一个知识点不懂的背后,是整个知识体系的欠缺, 那会从后端转入前端(非科班)有时候一个报错不知道从何找起,一、单元测试 【已经案例和知识相结合,可看…...
PID控制在自动循迹小车中的实战应用与参数整定指南
PID控制在自动循迹小车中的实战应用与参数整定指南 当你在实验室里第一次看到自己设计的自动循迹小车歪歪扭扭地沿着黑线前进时,那种既兴奋又挫败的感觉一定记忆犹新。为什么理论上完美的PID算法,在实际应用中却总是出现超调、振荡或者响应迟缓ÿ…...
如何三步搞定iOS微信聊天记录完整导出:隐私保护与数据备份终极指南
如何三步搞定iOS微信聊天记录完整导出:隐私保护与数据备份终极指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 还在为无法永久保存重要微信对话而烦恼吗&…...
新手入门福音:用快马AI生成你的第一个Python版游戏账号管理工具
作为一个刚接触Python编程的新手,最近想尝试开发一个简单的游戏账号管理工具。这个需求其实挺常见的,比如我平时玩多个游戏,账号密码经常记混,如果能有个小工具统一管理就方便多了。在朋友的推荐下,我尝试用InsCode(快…...
GitHub新手避坑指南:从SSH Key到Personal Token,搞定本地项目上传(含大文件失败解决方案)
GitHub新手避坑指南:从SSH Key到Personal Token,搞定本地项目上传(含大文件失败解决方案) 第一次用GitHub上传项目就像玩扫雷游戏——表面风平浪静,实际暗藏玄机。上周帮实习生小李排查上传失败问题时,发现…...
新能源车BMS低压管理避坑指南:如何解决上下电时序中的典型问题
新能源车BMS低压管理避坑指南:如何解决上下电时序中的典型问题 在新能源汽车的电池管理系统(BMS)开发中,低压上下电时序控制是确保系统稳定运行的关键环节。许多开发团队在实际项目中都会遇到信号冲突、时序错乱、异常处理机制不完…...
Claude Code 源码泄露深度剖析,Anthropic AI 编程助手的架构全解密
2026年3月31日,整个AI开发圈被一条消息炸开了锅。安全研究员Chaofan Shou(推特账号Fried_rice)在Anthropic官方发布的npm包中,意外发现了一个暴露的.map文件,正是这个看似不起眼的文件,直接泄露了Claude Co…...
Win11更新后Wifi图标消失?别急着重装系统,先试试这个官方驱动修复法
Win11更新后Wifi图标消失?三步精准定位官方驱动修复方案 刚更新完Windows 11系统,正准备继续手头的工作,突然发现任务栏右下角的Wifi图标不翼而飞。尝试重启电脑、重置网络设置,甚至检查了各种服务状态,问题依旧存在。…...
智慧农业 水稻害虫检测数据集 基于深度学习结合 深度学习模型(YOLOv11) 和 图形用户界面(GUI) 两部分来实现。 PyQt5
智慧化农业-水稻害虫目标检测数据集,3156张,yolo和voc两种标注方式 10类,标注数量: Asiatic Rice Borer: 亚洲稻螟 (716) Brown Plant Hopper: 褐飞虱 (577) Paddy Stem Maggot: 稻茎虫 (104) Rice Gall Midge: 稻瘿蚊 (223) Rice…...
基于Dify的智能问答系统:从意图识别到规范化回复的全流程设计
1. 从零开始理解Dify智能问答系统 第一次接触Dify时,我完全被它的可视化编排能力惊艳到了。这个平台就像搭积木一样,让不懂代码的产品经理也能设计出复杂的AI应用。举个实际例子,去年我们团队要做一个游泳健身领域的问答助手,传统…...
