首页/新闻资讯/正文详情

MariaDB DuckDB 存储引擎数据导入内存限制完全指南:memory_limit、spill 空间与相关配置项解析

发布时间:2026/9/26 10:07:18 来源:云帆数科 栏目:资讯中心
MariaDB DuckDB 存储引擎数据导入内存限制完全指南:memory_limit、spill 空间与相关配置项解析
数据库关系型数据库【免费下载链接】serverMariaDB server is a community developed fork of MySQL server. Started by core members of the original MySQL team, MariaDB actively works with outside developers to deliver the most featureful, stable, and sanely licensed open SQL server in the industry.项目地址https://gitcode.com/gh_mirrors/server1/server点击查看免费下载导读本文围绕 MariaDB Server 内嵌 DuckDB 存储引擎storage/duckdb/在数据导入大规模COPY、INSERT ... SELECT、run_in_duckdb()过程中的内存控制问题展开。你将掌握 DuckDB 内存限制的本质——只有memory_limit别名max_memory这一实例级硬上限且它只有在配置了temp_directoryspill 空间时才能被强制执行——并学会通过write_buffer_row_group_count、preserve_insertion_order、partitioned_write_flush_threshold等设置降低导入峰值内存同时理解单一共享实例 GLOBAL 设置带来的运维约束。1. 核心结论DuckDB 没有导入专用内存预算首先必须澄清一个常见误解DuckDB 不存在任何按操作ingestion-specific划分的内存预算。对于内存密集型算子DuckDB 能做的只有两件事遵守实例级硬上限memory_limit别名max_memory前提是它能将数据 spill 到临时目录temp_directory。如果实例没有配置临时目录也没有 swap 空间DuckDB 的临时内存管理器会明确放弃限制内存将持续增长到物理资源耗尽。这一逻辑在 DuckDB 源码中写得非常直白见third_parties/duckdb/src/storage/temporary_memory_manager.cpp} else if (!has_temporary_directory) { // We cannot offload, so we cannot limit memory usage. Set reservation equal to the remaining size SetReservation(temporary_memory_state, temporary_memory_state.GetRemainingSize()); }一句话总结memory_limit只是上限的承诺temp_directory才是兑现承诺的手段。没有后者前者在导入大表时形同虚设。由此推导出两个直接后果如果共享实例没有temp_directory或系统没有 swap重负载导入期间内存上限无法被强制执行进程可能被 OOM killer 杀死memory_limit被设为-1/none/null时表示无限对应DBConfig::ParseMemoryLimit的解析逻辑config.cpp:633-637此时即便有 spill 空间也不会主动 spill。2. 影响导入内存的真实设置项全部为树内原生设置下面这些设置都是 DuckDB 源码中真实注册的配置项在src/main/config.cpp中注册在src/include/duckdb/main/settings.hpp中定义在 MariaDB 的 DuckDB 引擎中通过全局代理系统变量暴露见common/duckdb_config.h与runtime/duckdb_config.cc。2.1write_buffer_row_group_count—— 最接近导入专用内存控制的参数作用域GLOBAL默认值5官方描述The amount of row groups to buffer in bulk ingestion prior to flushing them together. Reducing this setting can reduce memory consumption.批量导入时一次性合并 flush 前缓冲的 row group 数量调小它可以降低内存消耗。定义位置settings.hpp:1609-1618这是本文所涉及参数中与批量导入内存最直接相关的一个。批量写入Appender / 批量COPY会先在一组 row group 中缓冲数据再一起 flush缓冲的 row group 越多峰值内存越高。在内存受限的环境中调小该值可以让 flush 更早发生、更频繁从而压低峰值。2.2memory_limit/max_memory—— 实例级内存天花板作用域GLOBAL别名max_memory定义位置MaxMemorySettingcustom_settings.cpp:1295-1309这是整个 DuckDB 实例唯一的硬性内存上限。注意它的强制力依赖第 1 节的条件没有 spill 空间就无法强制执行。在 MariaDB 侧duckdb_memory_limit系统变量的 ON_UPDATE 回调会把值翻译成 DuckDB 的SET GLOBAL memory_limit语句下发见runtime/duckdb_config.cc的update_memory_limit_cb当值为 0 时执行RESET GLOBAL memory_limit否则执行SET GLOBAL memory_limit 人类可读大小。2.3temp_directorymax_temp_directory_size—— spill 空间的配置与配额作用域GLOBAL定义位置custom_settings.cpp:1314-1358temp_directory、custom_settings.cpp:1606-1633max_temp_directory_size要让memory_limit真正生效必须给 DuckDB 一个可以卸载中间数据的临时目录SET GLOBAL temp_directory /var/lib/mariadb/duckdb-tmp; SET GLOBAL max_temp_directory_size 10GB; SET GLOBAL memory_limit 8GB;max_temp_directory_size控制 spill 文件可占用的最大磁盘空间避免 spill 反过来把磁盘写满。MariaDB 侧对应duckdb_temp_directory与duckdb_max_temp_directory_size代理变量runtime/duckdb_config.cc的update_max_temp_directory_size_cb同样通过SET GLOBAL max_temp_directory_size ...下发。2.4preserve_insertion_order—— 关闭顺序保证换取流式并行插入作用域GLOBAL默认值true影响机制当该值为false时查询规划器会启用并行/流式插入parallel_streaming_insert允许结果不保持插入顺序从而减少缓冲、降低内存占用。该逻辑在PlanInsert中通过parallel_streaming_insert !PreserveInsertionOrder(...)门控plan_insert.cpp:102。适用场景对插入顺序没有硬性要求的批处理导入例如先落地再在应用层排序可以接受行顺序被打乱以换取更低的内存与更高的并行度。2.5 分区写入专用partitioned_write_flush_threshold与partitioned_write_max_open_files针对COPY ... TO ... (PARTITION_BY ...)这种写出分区文件的场景还有两个细分控制设置项默认值作用源码位置partitioned_write_flush_threshold524288行提前 flush 某个线程的分区缓冲区行数达到阈值即落盘减少内存中积压的行数settings.hpp:1257-1266使用于physical_copy_to_file.cpp:287,317partitioned_write_max_open_files100同时打开的文件数越少缓冲越少调小可降低内存占用settings.hpp:1268-1277-- 示例控制分区写出时的内存占用 SET GLOBAL partitioned_write_flush_threshold 100000; SET GLOBAL partitioned_write_max_open_files 50;2.6 容易混淆streaming_buffer_size与导入无关需要特别澄清streaming_buffer_size只控制结果集流式返回给客户端时的缓冲与导入过程的内存无关见client_config.hpp:82-83。排查导入内存问题时不要在这个参数上浪费时间。3. 关键前提单一共享实例上的 GLOBAL 设置以上设置全部是GLOBAL作用域且作用于唯一的共享 DuckDB 实例——也就是run_in_duckdb()所使用的那个实例详见 security-model.md。这意味着通过run_in_duckdb()执行SET GLOBAL ...会影响每一个会话不存在按调用per-call或按租户per-tenant的内存隔离任何有权限的调用者都可以调高memory_limit甚至直接设为无限从而绕过内存限制。从仓库架构文档 shared-resources.md 可以看到所有 MariaDB 客户端线程共享由DuckdbManager单例管理的同一个duckdb::DuckDB实例单一duckdb.db文件、共享 buffer pool / 内存分配器、共享 temp/swap 目录、单一 WAL。各线程THD只是各自持有独立的duckdb::Connection与事务上下文。因此buffer pool 压力是共享的一个连接执行大扫描会驱逐另一个连接需要的页面内存与 spill 空间是全实例共享的一个导入任务的内存暴涨会直接挤压其他查询。4. 在 MariaDB 中配置的落地方式4.1 通过系统变量推荐MariaDB 侧提供了duckdb_前缀的系统变量作为 DuckDB 设置的代理定义与回调见common/duckdb_config.h、runtime/duckdb_config.cc-- 实例级 SET GLOBAL duckdb_memory_limit 8G; SET GLOBAL duckdb_temp_directory /var/lib/mariadb/duckdb-tmp; SET GLOBAL duckdb_max_temp_directory_size 10G; -- 降低导入峰值内存 SET GLOBAL duckdb_appender_allocator_flush_threshold 128M; -- 批量写入 flush 阈值对于仓库自带的 duckdb.cnf 示例默认已启用引擎插件并开启run_in_duckdb且预留了#loose-duckdb-memory-limit10G的注释示例[mysqld] plugin-maturitygamma plugin-load-addha_duckdb.so duckdb-allow-run-in-duckdbON #loose-duckdb-memory-limit10G去掉#并按需调整loose-duckdb-memory-limit即可在启动时固化内存上限。4.2 通过run_in_duckdb()直接下发 DuckDB 设置SELECT run_in_duckdb(SET GLOBAL memory_limit 8GB); SELECT run_in_duckdb(SET GLOBAL temp_directory /var/lib/mariadb/duckdb-tmp); SELECT run_in_duckdb(SET GLOBAL write_buffer_row_group_count 2); SELECT run_in_duckdb(SET GLOBAL preserve_insertion_order false);注意这些设置是 GLOBAL 且跨会话生效见第 3 节并且run_in_duckdb()本身需要duckdb_allow_run_in_duckdbON且调用者持有SUPER权限security-model.md明确说明该函数默认关闭、受SUPER门控。5. 实操建议一份低内存导入检查清单结合以上原理当导入大表时发现内存不受控增长按优先级依次检查确认 spill 空间存在temp_directory是否已设置磁盘是否有足够空间max_temp_directory_size是否合理——这是最常被忽略、也最可能导致看似无上限增长的根因对应第 1 节。确认memory_limit不是无限检查是否被设成了-1/none/null。调低write_buffer_row_group_count批量导入场景优先尝试如2或3观察峰值内存变化。如可接受乱序关闭preserve_insertion_order换取并行流式插入减少缓冲。分区写出时调低partitioned_write_flush_threshold与partitioned_write_max_open_files。注意共享性以上均为 GLOBAL 设置修改会影响所有会话在多租户或多人共享实例上调整前先评估对其他查询的影响。6. 参考与延伸阅读本文涉及的源码与文档位置均为仓库内相对路径本文主文档storage/duckdb/docs/ingestion-memory-limits.md共享实例架构storage/duckdb/docs/shared-resources.mdrun_in_duckdb()安全模型与权限门控storage/duckdb/docs/security-model.mdMariaDB 侧全局代理变量定义与 ON_UPDATE 回调common/duckdb_config.h、runtime/duckdb_config.cc引擎总览与使用场景storage/duckdb/README.md配置示例storage/duckdb/duckdb.cnfDuckDB 侧源码随仓库 vendored 在storage/duckdb/third_parties/duckdb/下src/storage/temporary_memory_manager.cpp无 temp 目录则无法限内存、src/main/config.cpp与src/main/settings/custom_settings.cpp设置定义、src/include/duckdb/main/settings.hpp默认值与描述、src/execution/physical_plan/plan_insert.cpp插入顺序与并行流式插入、src/execution/operator/persistent/physical_copy_to_file.cpp分区写出缓冲、src/include/duckdb/main/client_config.hppstreaming_buffer_size提醒所有涉及导入性能与内存的结论均以当前仓库所 vendored 的 DuckDB 版本为准不同 DuckDB 版本的默认值与行为可能存在差异升级前请以对应版本的settings.hpp定义为准。赞分享数据库关系型数据库【免费下载链接】serverMariaDB server is a community developed fork of MySQL server. Started by core members of the original MySQL team, MariaDB actively works with outside developers to deliver the most featureful, stable, and sanely licensed open SQL server in the industry.项目地址https://gitcode.com/gh_mirrors/server1/server点击查看免费下载相关推荐MariaDB DuckDB 存储引擎安全模型解析run_in_duckdb() 函数与嵌入式 DuckDB 实例的权限边界MariaDB DuckDB 存储引擎安全模型解析 run_in_duckdb 函数与嵌入式 DuckDB 实例的权限边界 本文围绕 MariaDB 服务器中数据库关系型数据库MariaDB存储引擎开发完全指南从零打造自定义数据存储方案MariaDB存储引擎开发完全指南从零打造自定义数据存储方案 还在为特定业务场景找不到合适的存储引擎而烦恼MariaDB强大的可扩展性让你可以自定义存储引擎数据库关系型数据库Presto Memory Connector 完整指南纯内存存储引擎的配置、SQL 支持与限制详解Presto Memory Connector 完整指南纯内存存储引擎的配置、SQL 支持与限制详解 导读 Memory Connector 是 Presto大数据数据库后端上一篇搞定shadcn-vue复杂组件TypeScript类型体操实战指南下一篇终极免费文件清理工具Czkawka三步定位重复文件一次释放几十G空间创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

金融服务系统架构设计:账务一致性与合规安全的关键实践
金融服务系统架构设计:账务一致性与合规安全的关键实践

这几年要是上手过financial-services这类项目,最直接的感觉就是:这跟普通互联网产品完全不是一回事。业务规则看起来不复杂,无非是开户、转账、支付、清算这一套,但真正把系统拆开之后,你会发现每一个环节都被“资金安… · 2026/9/26 10:07:18

AI前沿 | 2026年9月26日:GPT-6 Sol 腰斩 + Luna 探底 + Claude Opus 5.5 降价 + Agent 单位经济学重构
AI前沿 | 2026年9月26日:GPT-6 Sol 腰斩 + Luna 探底 + Claude Opus 5.5 降价 + Agent 单位经济学重构

AI前沿 | 2026年9月26日:GPT-6 Sol 腰斩 Luna 探底 Claude Opus 5.5 降价 Agent 单位经济学重构 📖 首屏导读 本教程配套付费专栏:《大模型工程师修炼手记》 19.9 元(AI 编程 Agent 实战 本文同主题系统课程) 《… · 2026/9/26 10:07:18

DeepSeek Harness 插件化拆解:用 Cordis 给 Agent 框架留出第三条路
DeepSeek Harness 插件化拆解:用 Cordis 给 Agent 框架留出第三条路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:07:12

分布式锁在梯控集群调度中的高并发实践
分布式锁在梯控集群调度中的高并发实践

1. 场景与难点:机器人梯控到底在控什么去年做楼宇机器人物流调度,项目从立项到落地用了一年。电梯控制这块不算最起眼,但绝对是最磨人的。今天把核心部分,也就是基于分布式锁的梯控集群调度,拿出来详细聊一聊。这套系统… · 2026/9/26 10:49:58

MCP 与 Agent Skill 别再搞混了:从 settings.json 到 config.toml 一次理清(保姆级教程)
MCP 与 Agent Skill 别再搞混了:从 settings.json 到 config.toml 一次理清(保姆级教程)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:49:52

一句话说清 AD:默认 Computers 容器不是 OU,TaoToken 帮你把 redircmp 与 GPO 配置一次跑通
一句话说清 AD:默认 Computers 容器不是 OU,TaoToken 帮你把 redircmp 与 GPO 配置一次跑通

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:49:52

【值得收藏】AI架构选型指南:单Agent vs 多Agent,用TaoToken统一Key跑通思维链配置
【值得收藏】AI架构选型指南:单Agent vs 多Agent,用TaoToken统一Key跑通思维链配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:49:52

opencode.json 里 playwright-extension-mcp 连不上浏览器?先查这份配置骨架
opencode.json 里 playwright-extension-mcp 连不上浏览器?先查这份配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:49:52

Laya Core ML ANE 可行性研究:等价图变换与可测量的 10× 能耗目标
Laya Core ML ANE 可行性研究:等价图变换与可测量的 10× 能耗目标

【免费下载链接】laya-coreml Local Laya typed decisions on Apple Core ML and Neural Engine. Validated ports, ~5 ms short decisions on M3 Max, reproducible speed and energy benchmarks. 项目地址: https://gitcode.com/gh_mirrors/la/laya-coreml 点击查… · 2026/9/26 10:49:45

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码