mdb存储引擎实现
来源:互联网 发布:艾琳和后羿的伤害数据 编辑:程序博客网 时间:2024/06/01 10:50
存储引擎整体结构
Memory pool
如图所示,mdb存储引擎针对一块大的内存进行操作,内存引擎实现的原理如下:
初始化
- 首先分配一块大的内存,然后初始mem_pool对象,为mem_pool_impl对象中相关page的元数据赋值,如page_size、total_pages、meta_pages、free_pages、current_page等。
- 初始化mem_cache对象,初始化cache_info元数据对象,初始化cache_info中max_slab_id、base_size、factor相关成员。
- 初始化mem_cache对象中slab_manager对象数组,slab_manager数组大小为cache_info对象中max_slab_id,每个slab_manager还包括一个partial_pages的数组,数组的大小为该slab管理的page中item数决定,计算方式为: ( item数+(10-1)/10 )。
内存分配
- 分配指定大小的内存时,会为其在slab_manager数组中选择一个合适的slab(管理的长度大于指定的内存大小的最小的slab)。
for (size_t i = 0; i < slab_managers.size(); ++i){ if (slab_managers[i]->slab_size >= size) { mgr = slab_managers[i]; break; }}
通过获取的slab分配内存,内存分配的顺序为首先判断是否有partial_pages_no,如果有则直接从部分可用的page中分配item,如果没有部分可用的page,则直接判断是否有全空闲的page,如果有,则从全空闲的page中分配item,如果上述两种情况都没有,则从mem_pool中分配并初始化一块空闲的page,分配item,并且将该page连接到该slab对应的部分可用的page中。
说明:
在通过slab成功分配了item后,会将item连接到hashtable的链表中,具体的连接方式我们在后面的hashtable一节中详细描述,通过hashtable管理分配后的item的好处是提高查找的效率,减少相应操作的时间。删除记录操作时,实际是调用存储引擎的删除item的接口,同分配内存一样,也是根据item的大小,确定对应管理该内存的slab,删除的主要操作包括:
1)将该item从hashtable的链表中删除。
2)获取该item所在页,根据该页当前的状态是全满还是部分满,更新释放该item后的page状态,对于部分空闲的page,还需要根据空闲的item数重新将该page连接到对应的部分空闲队列上。
Hashtable:
这里主要介绍hashtable对应链表中的插入及删除操作,hashtable中每一个bucket的类型为uint64_t数据类型,对应item的id。
item初始化:
for(int i = 0; i < per_slab; ++i){ item->next = item->prev = 0; item->item_id = ITEM_ID(slab_size, i, index, slab_id); item->h_next = ITEM_ID(slab_size, i + 1, index, slab_id); item = reinterpret_cast<mdb_item *>((char*)item + slab_siz);}
item相关主要操作:
#define ITEM_KEY(it) (&((it)->data[0]))#define ITEM_DATA(it) (&((it)->data[0]) + (it)->key_len)#define ITEM_AREA(it) (((it)->data[0]&0xff)|(((it)->data[1]<<8)&0xff00))#define KEY_AREA(key) ((key[0]&0xff)|((key[1]<<8)&0xff00))#define ITEM_ID(_slab_size,_offset,_page_id,_slab_id) \ ({ \ (((uint64_t)_slab_id) << 52 \ |((uint64_t)_page_id)<<36 \ |((uint64_t)_offset) << 20 \ |((uint64_t)_slab_size));})#define ITEM_ADDR(base,item_id,page_size) \ ({assert(item_id != 0); \ reinterpret_cast<mdb_item *>(base \ + PAGE_ID(item_id) * page_size \ + SLAB_SIZE(item_id) * PAGE_OFFSET(item_id) + sizeof(mem_cache::page_info));})#define id_to_item(id) \ ITEM_ADDR(this_mem_pool->get_pool_addr(),id,mdb_param::page_size )
item插入hashtable:
插入时,先将item映射到某一个bucket上,然后将该bucket上的itemid赋值给item->next,然后将item的itemid赋值给该bucket的第一过程就是一个链表第一个元素的入过程,时间复杂度为o(1)。
int idx = get_bucket_index(item);item->h_next = hashtable[idx];hashtable[idx] = item->item_id;
hashtable中删除item:
删除时,先通过find函数遍历链表,根据遍历查找的结果,判断要删除的节点是否存在、是链首还是非链首位置,根据对应的结果从链表中删除item节点。
int idx = get_bucket_index(item);uint64_t pos = hashtable[idx];mdb_item *prev = 0;mdb_item *pprev = 0;prev = __find(pos, ITEM_KEY(item), item->key_len, &pprev);if(prev == 0) // not found{ return false;}if(pprev){ pprev->h_next = prev->h_next;}else{ hashtable[idx] = prev->h_next;}prev->h_next = 0;
- mdb存储引擎实现
- innodb存储引擎实现
- EJB3.0 MDB实现
- MYSQL存储引擎实现----分块管理
- Mysql Merge存储引擎实现分表
- InnoDB存储引擎行锁的实现
- Mongodb Wiredtiger存储引擎实现原理
- Mongodb Wiredtiger存储引擎实现原理
- MongoDB Wiredtiger存储引擎实现原理
- InnoDB存储引擎MVCC实现原理
- 利用MRG_MyISAM存储引擎实现分表
- 解析MongoDB存储引擎WiredTiger:事务实现
- MDB的简单替代实现
- php innodb存储引擎实现分区存储数据
- MDB
- MDB
- 存储引擎
- 存储引擎
- 路径规划
- 设置StatusBarStyle:Light无效
- Spring cloud系列十三 服务网关Zuul
- Mongodb大数据语法大全
- 深入分析ADO.NET中的DataSet对象
- mdb存储引擎实现
- Redis安装和自启动配置
- [SDOI2008]仪仗队
- c++new and delete
- CommonJS/AMD和EcmaScript规范简析
- VS编译——C/C++遍历库目录得到附加依赖项列表
- MONGODB大数据运维管理
- Ubuntu14.04安装redis和简单配置
- 并发编程之理解多线程假死现象的原因