IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Innodb 中 rec_get_offsets 的使用注意点

淘宝JAVA中间件团队博客 2011-09-14 13:34:22 累计浏览 1,518 次
本机暂存

在Innodb中使用rec_get_offsets来获取一条rec_t的各个字段的偏移量

整个rec_get_offsets的形式为:

/******************************************************//**
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的使用要注意了,一个不当就是引起内存泄露

看一个标准用法:

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_offs_init(offsets_); 这句不能省,这个宏的目的是设置offset_的第一个数组单位的值为数值的大小,因为rec_get_offsets内部需要判断offset能不能放下所有的值,放不下的话需要向heap申请内存,怎么判断offset够不够用,就需要rec_offs_init(offsets_);来初始化大小

上面这个例子里面使用的heap是为NULL的,即外部不预先为heap申请内存,难么当offset不够用时,rec_get_offsets内部会主动在heap上申请内存了.这个时候有个注意点就是rec_get_offsets内只在heap上申请了内存并没有free,因为外面还要使用,那么不能漏的就是

if (UNIV_LIKELY_NULL(heap)) {
        mem_heap_free(heap);
    }

这一段了,一旦漏了,就很有可能出现内存泄露,而且这个泄露的触发条件还很苛刻,因为初始化的offsets_[REC_OFFS_NORMAL_SIZE]为100个,那么当你有超过96个字段的记录(因为内部要预留4个)时,就会向heap申请内存,这时没有free就会泄露了.

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. 用Hyer来进行网站的抓取 (累计阅读 158,250)
  2. MySQL数据库在实际应用一些方面的介绍 (累计阅读 36,396)
  3. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,162)
  4. Mysql监控指南 (累计阅读 21,349)
  5. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,518)
  6. 在Apache2.2.XX下安装Mod-myvhost模块 (累计阅读 13,056)
  7. 15个最好的免费开源电子商务平台 (累计阅读 12,539)
  8. 浅谈MySQL索引背后的数据结构及算法 (累计阅读 11,896)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,708)
  10. 深入浅出INNODB MVCC机制与原理 (累计阅读 9,688)