MySQL列:innodb的源代码的分析的基础数据结构

在过去的一年中的数据库相关的源代码分析。前段时间分析levelDB实施和BeansDB实现,数据库网络分析这两篇文章非常多。他们也比较深比较分析,所以没有必要重复很多劳力。MYSQL,当然主要还是数据库存储引擎,首先我还是从innodb这个最流行的开源关系数据库引擎着手来逐步分析和理解。

我一般分析源代码的时候都是从基础的数据结构和算法逐步往上分析。遇到不明确的地方,自己依照源代码又一次输入一遍并做相应的单元測试,这样便于理解。对于Innodb这种大项目,也应该如此,以后我会逐步将详细的细节和实现写到BLOG上。我分析Innodb是以MySQL-3.23为蓝本作为分析对象,然后再去比較5.6版本号的修改来做分析的。这样做有个优点就是先理解相对基础的代码easy。在有了基本概念后再去理解最新的修改。下面是我对innodb基础的数据结构和算法的理解。

1.vector

innodb的vector是个动态数组的数据结构。和c++的STL使用方法相似,值得一提的是vector的内存分配能够通过函数指针来指定是从heap内存池堆上分配内存还是用OS自带的malloc来分配内存。内存分配器的结构为:

        struct ib_alloc_t {
             ib_mem_alloc_t	mem_malloc; 				//分配器的malloc函数指针
             ib_mem_free_t	mem_release;  				//分配器的free函数指针
             ib_mem_resize_t	mem_resize;  				//分配器的又一次定义堆大小指针
             void*	 arg;     					//堆句柄,假设是系统的malloc方式,这个值为NULL
<span style="white-space:pre">	</span>};

vector内部集成了排序功能函数。其排序的算法是通过qsort(高速)来进行排序。

vector内存结构:

2.内存list

innodb的list数据结构是个标准的双向链表结构。ib_list_node_t其中有指向前一个node的prev和指向后一个

node的next,list的内存分配能够通过heap内存堆来分配,也能够通过系统的malloc来分配。

就看是採用

ib_list_create_heap来创建list爱是永ib_list_create来创建list。可是内部的ib_list_node_t的内存分配是通过

heap来分配的。

ist的内存结构:



watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVhbnJ4ZHU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

3.FIFO-queue

innodb的FIFO queue是个多线程的消息队列。能够有多个线程向queue中加入消息,可有多个线程同一时候读取queue中的消息并进行处理。queue的mutex是保证同一时候仅仅有一个线程在操作(读或者写)queue的items链表,os_event是写线程完毕后通知全部读线程能够进行queue的读事件。也就是说,仅仅有向queue写完毕一个消息。才会发送event信号给读线程。queue的消息缓冲区是採用ib_list_t来做存储的。一般写的时候写在list的最后,而读总是读取list的第一个。

queue处理提供一直读取到消息为止的方法以外,也提供最长等待读取消息的方法。这样读取线程没有必要一直等待消息。能够在等待一段时间后去处理其它的任务。其C结构定义例如以下:

struct ib_wqueue_t
{
	ib_mutex_t	mutex; /*相互排斥量*/
	ib_list_t*	items; /*用list作为queue的载体*/
	os_event_t	event; /*信号量*/
};

4.哈希表

innodb中的哈希表的基本构造和传统的哈希表的构造是相似的,不同的就是innodb的哈希表採用的是自己定义链式桶结构。而没有採用每一个桶单元用传统的list来做碰撞管理。由于这个特性。innodb中的哈希表操作採用了一系列操作宏来做操作。这样做的目的是为了能泛型的对哈希表做操作,由于在innodb中,除了操作内存中的数据以外,还会操作隐射硬盘中的数据。下面是innodb的操作宏:

HASH_INSERT                                    插入操作

HASH_DELETE                                    删除操作

HASH_GET_FIRST                               获取指定HASH key相应cell的第一个数据单元

HASH_GET_NEXT                                获取cell_node相应的下一个单元

HASH_SEARCH                                   查找相应key的值

HASH_SEARCH_ALL                            遍历整个hash table并将每一个数据单元为參数运行ASSERTION操作

HASH_DELETE_AND_COMPACT        删除操作而且优化和调整heap堆上的内存分配布局,使得heap效率更高

HASH_MIGRATE                                 将OLD_TABLE的数据单元合并到NEW_TABLE其中

这些宏在调用的时候都会指定数据的类型和Next函数名。

innodb的哈希表在多线程并发模式下也提供cell级粒度的锁,有mutex类型的锁。也有rw_lock类型的锁。

在hash_create_sync_obj_func函数调用过程中,会创建一个n_sync_obj的锁数据单元。n_sync_obj必须是2的N次方。也就是说假设n_sync_obj
= 8, 哈希表的n_cells = 19。那就至少两个cell公用一个锁。

这是其它哈希表无法比拟的。

下面是hash table的结构定义:

struct hash_table_t
{
	enum hash_table_sync_t	type;		/*hash table的同步类型*/
	ulint			n_cells;	/*hash桶个数*/
	hash_cell_t*		array;		/*hash桶数组*/
#ifndef UNIV_HOTBACKUP
	ulint			n_sync_obj;
	union{ /*同步锁*/
		ib_mutex_t*	mutexes;
		rw_lock_t*	rw_locks;
	}sync_obj;
	/*heaps的单元个数和n_sync_obj一样*/
	mem_heap_t**		heaps;
#endif
	mem_heap_t*		heap;
	ulint			magic_n;	/*校验魔法字*/
#endif
};

5.小结

Innodb还有其它的一些数据结构,比如最小堆,这些都是通用的封装,也就不做过多的描写叙述,在能够去看看innodb的源代码相关就能够。innodb在定义数据结构的时候做了特殊的处理,比如对线程并发的控制。对内存分配的控制。

这样做的目的是为了统一的管理。

innodb的代码是C的。但支持C++。里面并没有使用STL这样的传统的数据结构和算法,非常大程度上是适合性的问题。

据说MYSQL 5.7開始大量使用boost 和STL。

个人感觉STL还勉强。使用boost有点感觉阔步前进。

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-08-12 12:25:46

MySQL列:innodb的源代码的分析的基础数据结构的相关文章

MySQL系列:innodb引擎分析之基础数据结构

近一年来一直在分析关于数据库相关的源码,前段时间分析了levelDB的实现和BeansDB的实现,这两个数据库网络上分析的文章很多,也都比较分析的比较深,所以也就没有太多必要重复劳动.最近开始关注关系数据库和MYSQL,当然主要还是数据库存储引擎,首先我还是从innodb这个最流行的开源关系数据库引擎着手来逐步分析和理解.我一般分析源码的时候都是从基础的数据结构和算法逐步往上分析,遇到不明白的地方,自己按照源码重新输入一遍并做对应的单元测试,这样便于理解.对于Innodb这样的大项目,也应该如此

MySQL的innoDB存储引擎的运作方式,数据结构等

先上InnoDB架构图: 自上而下依次为内存区结构,后台线程,操作系统,磁盘存储,日志文件等. 其中内存由缓冲池,额外缓冲池,日志缓冲池组成.其中缓冲池中结构如下: 在磁盘存储文件中,MyISAM存储引擎采用元数据,数据,索引三分的文件存储方法,而InnoDB采用元数据,数据(=索引)方式存储,这个主要由于InnoDB采用B+树结构实现.所以我们在架构图中看到存储的table1包含Primary key& data.其结构如下图 关于InnoDB的这种存储结构以及其对索引的影响,详见:MySQL

MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析

文/何登成 导读:   来自网易研究院的MySQL内核技术研究人何登成,把MySQL数据库InnoDB存储引擎的多版本控制(简称:MVCC)实现原理,做了深入的研究与详细的文字图表分析,方便大家理解InnoDB存储引擎实现的多版本控制技术(简称:MVCC). 基本知识 假设对于多版本控制(MVCC)的基础知识,有所了解.MySQL数据库InnoDB存储引擎为了实现多版本的一致性读,采用的是基于回滚段的协议. 行结构 MySQL数据库InnoDB存储引擎表数据的组织方式为主键聚簇索引.由于采用索引

mysql innodb的锁机制分析

线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作.经过DBA的分析,是某一张表的insert操作和delete操作发生了死锁.简单介绍下数据库的情况(因为涉及到真实数据,这里做了模拟,不影响具体的分析和分析的结果.)假设存在如下2张表: Order 表的数据如下: Customer表的数据如下: Order和Customer 在实体关系上存在一个关联,即order实体拥有一个指向customer实体的指针.在数据库设计的时候,order表的customer_id没有被设

剖析Mysql的InnoDB索引

摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇以介绍InnoDB为主.少量涉及MyISAM作为对照. 这篇文章是我在学习过程中总结完毕的.内容主要来自书本和博客(參考文献会给出).过程中增加了一些自己的理解.描写叙述不准确的地方烦请指出. 1 各种树形结构 本来不打算从二叉搜索树開始,由于网上已经有太多相关文章,可是考虑到清晰的图示对理解问题

MySQL 温故而知新--Innodb存储引擎中的锁

近期碰到非常多锁问题.所以攻克了后,细致再去阅读了关于锁的书籍,整理例如以下:1,锁的种类 Innodb存储引擎实现了例如以下2种标准的行级锁: ? 共享锁(S lock),同意事务读取一行数据. ?  排它锁(X lock).同意事务删除或者更新一行数据. 当一个事务获取了行r的共享锁.那么另外一个事务也能够马上获取行r的共享锁,由于读取并未改变行r的数据.这样的情况就是锁兼容. 可是假设有事务想获得行r的排它锁,则它必须等待事务释放行r上的共享锁-这样的情况就是锁不兼容.二者兼容性例如以下表

MySQL的InnoDB索引原理详解

摘要 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇以介绍InnoDB为主,少量涉及MyISAM作为对比. 这篇文章是我在学习过程中总结完成的,内容主要来自书本和博客(参考文献会给出),过程中加入了一些自己的理解,描述不准确的地方烦请指出. 1 各种树形结构 本来不打算从二叉搜索树开始,因为网上已经有太多相关文章,但是考虑到清晰的图示对理解问题有很大

MySQL的InnoDB索引原理详解 (转)

摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇以介绍InnoDB为主,少量涉及MyISAM作为对比. 这篇文章是我在学习过程中总结完成的,内容主要来自书本和博客(参考文献会给出),过程中加入了一些自己的理解,描述不准确的地方烦请指出. 1 各种树形结构 本来不打算从二叉搜索树开始,因为网上已经有太多相关文章,但是考虑到清晰的图示对理解问题有很

列式数据库的简单分析

转自:列式数据库的简单分析 这些天看数据仓库的内容,发现一个新内容——列式存储.曾经有想过把数据库行列转置作成索引,不过没有深想,没想到列式数据库已经开始发展起来了.首先看下WIKI上对列式数据库的解释: 列式数据库是以列相关存储架构进行数据存储的数据库,主要适合与批量数据处理和即席查询.相对应的是行式数据库,数据以行相关的存储体系架构进行空间分配,主要适合与小批量的数据处理,常用于联机事务型数据处理.数据库以行.列的二维表的形式存储数据,但是却以一维字符串的方式存储,例如以下的一个表:EmpI