Innodb 中 rec_get_offsets 的使用注意点
2023-03-14 22:27:19 时间
在Innodb中使用rec_get_offsets来获取一条rec_t的各个字段的偏移量
整个rec_get_offsets的形式为:
整个rec_get_offsets的形式为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/******************************************************/``/** The following function determines the offsets to each field in the record. It can reuse a previously allocated array. @return the new offsets */ UNIV_INTERN ulint* rec_get_offsets_func( /*=================*/ ``const rec_t* rec, ``/*!< in: physical record */ ``const dict_index_t* index, ``/*!< in: record descriptor */ ``ulint* offsets,``/*!< in/out: array consisting of ``offsets[0] allocated elements, ``or an array from rec_get_offsets(), ``or NULL */ ``ulint n_fields,``/*!< in: maximum number of ``initialized fields ``(ULINT_UNDEFINED if all fields) */ ``mem_heap_t** heap, ``/*!< in/out: memory heap */ ``const char``* file, ``/*!< in: file name where called */ ``ulint line); ``/*!< in: line number where called */ #define rec_get_offsets(rec,index,offsets,n,heap) ``rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__) |
参数解释:
- rec 对应的记录
- index 记录对应的索引
- offsets 用来保存偏移量结果的指针,可以是预分配好的,也可以是个NULL
- n_fields 能保存的最大的偏移量的字段数 一般可以使用ULINT_UNDEFINED来表示,没限制.ULINT_UNDEFINED 为((ulint)(-1))
- heap 内存堆.如果没有预先分配offsets ,那么返回结果将在heap上申请内存,如果heap为NULL,那么会为heap也申请内存.注意.这个地方很容易引起内存泄露
看上对offsets 和 heap的使用要注意了,一个不当就是引起内存泄露
看一个标准用法:
1
2
3
4
5
6
7
8
9
10
|
ulint offsets_[REC_OFFS_NORMAL_SIZE]; ``ulint* offsets = offsets_; ``mem_heap_t* heap = NULL; ``row_cache_chain_t* chain = NULL; ``rec_offs_init(offsets_); //TODO Someting ``if (UNIV_LIKELY_NULL(heap)) { ``mem_heap_free(heap); ``} ``return``; |
第一个需要注意的就是rec_offsinit(offsets); 这句不能省,这个宏的目的是设置offset_的第一个数组单位的值为数值的大小,因为rec_get_offsets内部需要判断offset能不能放下所有的值,放不下的话需要向heap申请内存,怎么判断offset够不够用,就需要rec_offsinit(offsets);来初始化大小
上面这个例子里面使用的heap是为NULL的,即外部不预先为heap申请内存,难么当offset不够用时,rec_get_offsets内部会主动在heap上申请内存了.这个时候有个注意点就是rec_get_offsets内只在heap上申请了内存并没有free,因为外面还要使用,那么不能漏的就是
1
2
3
|
if (UNIV_LIKELY_NULL(heap)) { ``mem_heap_free(heap); ``} |
这一段了,一旦漏了,就很有可能出现内存泄露,而且这个泄露的触发条件还很苛刻,因为初始化的offsets_[REC_OFFS_NORMAL_SIZE]为100个,那么当你有超过96个字段的记录(因为内部要预留4个)时,就会向heap申请内存,这时没有free就会泄露了.
本文来源于"阿里中间件团队播客",原文发表时间" 2011-09-10 "
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的