Innodb 中 rec_get_offsets 的使用注意点

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

整个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  "

时间: 2024-11-03 03:12:01

Innodb 中 rec_get_offsets 的使用注意点的相关文章

关于innodb中查询的定位方法

原创转载请注明出处 源码版本 5.7.14 涉及源码文件 page0cur.cc page0page.h page0page.cc rem0cmp.cc 为什么谈及定位方法,因为在innodb中,比如一个插入语句我们需要定位在哪里插入(PAGE_CUR_LE),比如一个查询语句我们需要定位到其第一个需要读取数据的位置,因此定位方法是查询的根本.而找到这个记录位置后实际上是用一个叫做page_cur_t结构体进行存储,暂且叫他cursor游标 struct page_cur_t{ const di

InnoDB中Adaptive hash index存在问题、Percona改进及一个bug

背景   Adaptive hash index  (AHI) 是InnoDB中用于加速索引查找的一个结构.InnoDB本身不支持hash索引,所有的索引检索都走B树查询.AHI可以认为是"索引的索引".当对一个页面的访问次数满足一定条件后,将这个页面的地址存在一个hash表中,下次查询可以直接访问到页面,不需要走B树查询. 问题   天下没有免费的午餐,在加速查询的同时,AHI与其他缓存结构一样,也面临维护的问题.作为一个全局结构,在更新时必然有一个全局锁操作(btr_search_

关于InnoDB中buf_page_is_corrupted的优化

函数buf_page_is_corrupted (innodb_plugin/buf/buf0buf.c)这个函数,是在InnoDB中获取page数据后,对page作校验,判断内容是否损坏. 在压力测试中发现,innodb.so最耗费cpu的就是这个buf_page_is_corrupted. Percona对这个函数作了优化.本文介绍与此有关的配置.优化原理以及进一步的优化空间.(当前版本5.1.48 innodb-plugin 1.0.9) 1.函数主流程 每个page头部的前四个字节是本p

【转】Innodb中的事务隔离级别和锁的关系

申明: 本文转自Innodb中的事务隔离级别和锁的关系,解决了我关于锁.事务隔离的一些误解和疑问.在高并发系统中,数据库对高并发的支持是非常重要的一个方面,本文主要描述高并发场景下,数据库如何保证数据一致性(同时保证良好的性能). 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过

MYSQL INNODB 中通用双向链表的实现

原创:如果有误请支持 源码在Ut0lst.h中 注意:这里我将链表中的实际的串联的数据叫做数据类比如:lock_t.mem_block_t 链表作为一种的非常重要的数据结构,在任何地方都会用到,这里简单解释一下innodb双向 链表的实现,让我们来看看innodb链表设计的魅力: 经常在某些结构体中看到 UT_LIST_BASE_NODE_T(mem_block_t) base; UT_LIST_NODE_T(mem_block_t) list;  作为最为基本的一种的数据结构innodb中实现

MYSQL innodb中的只读事物以及事物id的分配方式

原创水平有限,如果有误请指出 一.只读事物 也许有人要问一个select算不算一个事物.其实在innodb中一个innodb的select是一个事物,他有trx_t结构体,并且放到了mysql_trx_list链表中,关于 innodb事物系统一级的事都做了,但是这种事物叫做只读事物 bool read_only; /*!< true if transaction is flagged as a READ-ONLY transaction. if auto_commit && wil

InnoDB 中foreign key使用注意事项

Innodb foreign key 和 sql  standards的区别: 在 sel statement 中的inserts,deletes,updates 很多行的时候,fk 会一行一行检查. innodb 是设置 shared row_level locks 在父表或者子表上,MySQL CHECK 会立即检查是否有符合的行, 并不会推迟到事务提交的时候, 在innodb上建立fk的条件: 1.innodb允许关联到一个index或者一组 columns(第一个column 必须是in

InnoDB中dict_update_statistics调用策略及问题

背景          为了提供优化器支持,InnoDB维护了每个表的索引统计信息(index statistics).在之前的一篇文章中作过介绍.          文章里面介绍到索引统计信息有几个更新策略,并建议允许关闭动态更新.顺便提及,5.6已经提供了Persistent Statistics 选项,达到相同的目的.          在5.5版本还是必须动态更新.本文介绍在动态更新时的一个问题.   索引统计的动态更新策略          这个策略是比较简单的.每个表维护一个stat

原版MySQL中如何恢复单个InnoDB数据库表

Percona 中的 xtrabackup 真是个好工具, 简单的介绍的他的功能: 1.创建热备份(主要依靠innodb的 crash recovery 功能) 2.增量备份 3.直接对备份文件压缩打包 4.负载小 在测试最新版本2.0时,发现问题: importing  and   exporing  individual tables中这个工具对Oracle 原版的MySQL是不起作用的. 本栏目更多精彩内容:http://www.bianceng.cn/database/MySQL/ 解释