`

思考mysql内核之初级系列12---innodb的簇描述结构(摘自老杨)

阅读更多

在上一篇里,bingxialex聊了关于innodb的页编号。在本篇,bingxialex会讨论下簇描述结构。所谓的簇描述结构,对应的英文描述是extent,表达的意思是一些连续的页。

对应的文件为:

D:\mysql-5.1.7-beta\storage\innobase\fsp\ fsp0fsp.c

D:\mysql-5.1.7-beta\storage\innobase\include\ fsp0fsp.h

1)簇的定义

Bingxi:“alex,在共享存储空间的情况,多个innodb表存储在同一个表空间里面。对单个表而言,存储并不一定是连续的。在上一篇里面提到这样的一个例子:

a)创建表1,并插入数据

b)创建表2,并插入数据

c)1插入数据

d)2插入数据

如果我们每次分配一个页,就会存储得很凌乱。可能第n页属于t1,n+1页属于t2n+3页属于t1,n+4页属于t2,……

这样就会降低io的读写性能,因此我们可以看到在mysql中有簇的概念,这里的簇也就是指extent。簇是连续的页,数量是64页。那么我问下alex,假设T1表新分配了一个簇,某些页用完了,如何标识?

Alex:“bingxi,我也存在这个疑惑。我们用过代码来看这个问题吧。代码如下:

/* EXTENT DESCRIPTOR

=================

File extent descriptor data structure: contains bits to tell which pages in

the extent are free and which contain old tuple version to clean. */

/*-------------------------------------*/

#define XDES_ID 0 /* The identifier of the segment

to which this extent belongs */

#define XDES_FLST_NODE 8 /* The list node data structure

for the descriptors */

#define XDES_STATE (FLST_NODE_SIZE + 8)

/* contains state information

of the extent */

#define XDES_BITMAP (FLST_NODE_SIZE + 12)

/* Descriptor bitmap of the pages

in the extent */

定义里面的数字是偏移量,我们来画个图看下。

从上面我们可以知道:

XDES_ID //0

XDES_FLST_NODE //8

XDES_STATE //20

XDES_BITMAP //24

这些内容中,我们会产生两个疑问:116个字节描述64个页的使用状态,怎么描述?如果只是描述该页是否使用,1bit位就够了,也就是64bit位,即8个字节。而实际使用了16个字节,那么是不是可以认为是两个bit位来描述一个页的使用情况。2)每个簇使用40个字节,这些内容存储在什么地方?

Bingxi,你来看看。我们在本篇中,先解决第一个问题,第二个问题留到下一篇。

Bingxi:“第一个问题,可以理解。

//每个页需要两个bit位来描述

#define XDES_BITS_PER_PAGE 2 /* How many bits are there per page */

//这两个bit位中,第一个bit位标识该页是否在使用

#define XDES_FREE_BIT 0 /* Index of the bit which tells if

the page is free */

//第二个标识位目前没有使用

#define XDES_CLEAN_BIT 1 /* NOTE: currently not used!

Index of the bit which tells if

there are old versions of tuples

on the page */

每个页使用两个位,那么64个页使用的就是16个字节。我们看一下簇的初始化代码:

/**************************************************************************

Inits an extent descriptor to the free and clean state. */

UNIV_INLINE

void

xdes_init(

/*======*/

xdes_t* descr, /* in: descriptor */

mtr_t* mtr) /* in: mtr */

{

ulint i;

ut_ad(descr && mtr);

ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),

MTR_MEMO_PAGE_X_FIX));

ut_ad((XDES_SIZE - XDES_BITMAP) % 4 == 0);

//其中XDES_BITMAP的值为24

// XDES_SIZE的大小为40

//也就是簇描述结构中24字节开始的16个字节全部设置为1

for (i = XDES_BITMAP; i < XDES_SIZE; i += 4) {

mlog_write_ulint(descr + i, 0xFFFFFFFFUL, MLOG_4BYTES, mtr);

}

//设置簇的使用状态为空闲簇

xdes_set_state(descr, XDES_FREE, mtr);

}

我们接着看xdes_set_state的实现:

/**************************************************************************

Sets the state of an xdes. */

UNIV_INLINE

void

xdes_set_state(

/*===========*/

xdes_t* descr, /* in: descriptor */

ulint state, /* in: state to set */

mtr_t* mtr) /* in: mtr handle */

{

ut_ad(descr && mtr);

ut_ad(state >= XDES_FREE);

ut_ad(state <= XDES_FSEG);

ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),

MTR_MEMO_PAGE_X_FIX));

// descr是该簇的起始指针,相对该指针XDES_STATE的开始4个字节填写status的值

mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr);

}

同样的,获取状态也是类似的。我们接着看下xdes_get_n_used函数,该函数表述该簇的页已经使用了多少。

/**************************************************************************

Returns the number of used pages in a descriptor. */

UNIV_INLINE

ulint

xdes_get_n_used(

/*============*/

/* out: number of pages used */

xdes_t* descr, /* in: descriptor */

mtr_t* mtr) /* in: mtr */

{

ulint i;

ulint count = 0;

ut_ad(descr && mtr);

ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),

MTR_MEMO_PAGE_X_FIX));

//对该簇的每一页调用函数xdes_get_bit

// xdes_get_bit函数返回对应页的是否使用位

//我们从初始化函数中知道,1表示使用,0表示未使用

//因为如果函数返回的值是false,则表示该页已经使用了,将count1

for (i = 0; i < FSP_EXTENT_SIZE; i++) {

if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) {

count++;

}

}

return(count);

}

如果所有的页都使用完,那么就表示该页已经使用满。

/**************************************************************************

Returns true if extent contains no free pages. */

UNIV_INLINE

ibool

xdes_is_full(

/*=========*/

/* out: TRUE if full */

xdes_t* descr, /* in: descriptor */

mtr_t* mtr) /* in: mtr */

{

//如果该簇使用的页等于64FSP_EXTENT_SIZE),也就是表示该簇已经满了

if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) {

return(TRUE);

}

return(FALSE);

}

其它的函数类似,这里就不一一列举。作为重点,我们再看一下xdes_set_bit函数。

/**************************************************************************

Sets a descriptor bit of a page. */

UNIV_INLINE

void

xdes_set_bit(

/*=========*/

xdes_t* descr, /* in: descriptor */

ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */

ulint offset, /* in: page offset within extent:

0 ... FSP_EXTENT_SIZE - 1 */

ibool val, /* in: bit value */

mtr_t* mtr) /* in: mtr */

{

ulint index;

ulint byte_index;

ulint bit_index;

ulint descr_byte;

ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),

MTR_MEMO_PAGE_X_FIX));

ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT));

ut_ad(offset < FSP_EXTENT_SIZE);

//假设offset的值为n

// XDES_BITS_PER_PAGE为2

//index也就是相对于XDES_BITMAP的偏移bit

index = bit + XDES_BITS_PER_PAGE * offset;

//index/8对应的是相对于XDES_BITMAP的偏移字节

byte_index = index / 8;

//表示所在的位,这里面要重点关注

//字节是从低字节编码的,比如n对应的bit_index0,实际上表示的是第0位,而不是第7位。即使xxxxxxxy中的y对应的位。

//假设bit_index6,实际对应的是xyxxxxxx中的y对应的位。

bit_index = index % 8;

//获得对应的字节

descr_byte = mtr_read_ulint(descr + XDES_BITMAP + byte_index,

MLOG_1BYTE, mtr);

//设置对应的bit

descr_byte = ut_bit_set_nth(descr_byte, bit_index, val);

//重写入

mlog_write_ulint(descr + XDES_BITMAP + byte_index, descr_byte,

MLOG_1BYTE, mtr);

}

这样,我们对应簇的bit位进行设置,标识对应的页的使用情况。还有一些其他的函数,建议直接看代码。

Alex:“ok,今天就到这里吧。”

Bingxi:“ok

分享到:
评论

相关推荐

    percona-data-recovery-tool-for-innodb-0.5.tar.tar

    percona-data-recovery-tool-for-innodb-0.5.tar.tar

    MySQL内核 INNODB存储引擎-卷1-高清-完整目录-2014年5月

    MySQL内核 INNODB存储引擎-卷1-高清-完整目录-2014年5月

    MySQL高级-第07章-InnoDB数据存储结构

    MySQL是世界上最流行的关系型数据库管理系统之一,其InnoDB存储引擎是默认且最常使用的引擎,尤其在事务处理和数据安全性方面表现出色。本章节将深入探讨InnoDB数据存储结构,帮助你理解其内部机制,提升数据库管理...

    MySQL内核:InnoDB存储引擎 卷1.pdf

    卷1》由资深MySQL专家,机工畅销图书作者亲自执笔,在以往出版的两本InnoDB介绍性图书的基础之上,更深入地介绍InnoDB存储引擎的内核,例如latch、B+树索引、事务、锁等,从源代码的角度深度解析了InnoDB的体系结构...

    何登成 - 管中窥豹——MySQL(InnoDB)死锁分析之道

    何登成在其演讲中深入探讨了MySQL(InnoDB)死锁问题,尤其对于死锁的分析提出了独到的见解和方法。以下是对何登成演讲内容的知识点详细梳理: ### 为什么选择“死锁” 何登成首先分享了他选择探讨死锁话题的原因,...

    MySQL内核:InnoDB存储引擎 卷1.pdf.zip

    《MySQL内核:InnoDB存储引擎 卷1》是一本深度探讨MySQL数据库系统核心部分——InnoDB存储引擎的专业书籍。这本书以超高清的PDF格式呈现,包含详细的书签,便于读者快速定位和查阅相关内容。InnoDB作为MySQL中最常用...

    mysql内核 innodb存储引擎

    《MySQL技术内幕:InnoDB存储引擎》是国内目前唯一的一本关于InnoDB的著作,由资深MySQL专家亲自执笔,中外数据库专家联袂推荐,权威性毋庸置疑。内容深入,从源代码的角度深度解析了InnoDB的体系结构、实现原理、...

    mysql-8.2.0-winx64-debug-test.zip

    MySQL是世界上最受欢迎的开源数据库管理系统之一,主要用于存储和管理数据。这个特定的压缩包"mysql-8.2.0-winx64-debug-test.zip"包含了MySQL的8.2.0版本,专为Windows 64位操作系统设计。下面将详细讨论MySQL 8.x...

    ZeroMoreFree#mysql-note#4.InnoDB记录存储结构1

    前言mysql中有很多的引擎,不同的引擎存储数据的方式是不同的,本文以InnoDB为例进行讲解InnoDB页简介为了提高效率,InnoDB以页作为磁盘和内存之间

    undrop-for-innodb

    yum install make gcc flex bison cd /root/undrop-for-innodb-master make 会产生三个文件c_parser innochecksum_changer stream_parser

    mysql for Linux (mysql-standard-4.1.22-pc-linux-gnu-i686.tar.gz )

    MySQL是世界上最受欢迎的开源数据库系统之一,尤其在Linux操作系统中广泛应用。`mysql-standard-4.1.22-pc-linux-gnu-i686.tar.gz` 是一个针对Linux平台的MySQL服务器版本的压缩包,适用于Intel x86架构。这个特定的...

    mysql-8.0.16-winx64-debug-test.zip

    MySQL是世界上最受欢迎的开源关系型数据库管理系统之一,其8.0.16版本是一个重要的更新,提供了许多增强功能和性能优化。"mysql-8.0.16-winx64-debug-test.zip" 是一个专为Windows 64位系统设计的MySQL安装包,包含...

    mysql-8.0.28-winx64.zip + mysql80-community-release-el7-5.noarch

    MySQL是世界上最受欢迎的开源关系型数据库管理系统之一,其最新版本为8.0.28。在本案例中,我们有两个不同平台的安装包:一个是针对Windows操作系统的“mysql-8.0.28-winx64.zip”,另一个是用于Linux(特别是基于...

    MySQL技术内幕InnoDB存储引擎-读书笔记.pdf

    MySQL技术内幕InnoDB存储引擎-读书笔记.pdf

    mysql-5.7.44-linux-glibc2.12-x86-64.tar.gz

    MySQL是世界上最受欢迎的关系型数据库管理系统之一,特别是在Web应用程序中。MySQL 5.7.44是该系列的一个重要版本,提供了许多性能优化、安全增强和功能改进。在Linux环境下,MySQL通常以源码形式安装,以便更好地...

    mysql-shell-8.0.18-windows-x86-64bit.zip

    mysql-shell-8.0.18-windows-x86-64bit.zip MySQL Shell is an advanced command-line client and code ... MySQL Shell includes the AdminAPI that enables you to work with InnoDB cluster, see InnoDB Cluster.

    mysql innodb恢复数据工具.rar

    这是我从网上找到的mysql/mariadb对innodb表进行数据恢复的工具,实现从innodb的数据库文件中恢复数据,用于实现下面情况:1、直接下载了innodb数据库的文件,而不是导出其数据,想恢复数据时(需要有完整的文件,...

    MySQL体系结构及原理(innodb)图文完美解析

    ### MySQL体系结构及原理(innodb)图文完美解析 #### 宏观认识 在深入探讨MySQL的体系结构及其核心组件InnoDB之前,我们先来理解几个基础概念。 1. **MySQL简介** MySQL是一种开源的关系型数据库管理系统(RDBMS)...

    mysql57-community-release-el7-11.noarch.rpm

    MySQL是世界上最受欢迎的关系型数据库管理系统(RDBMS)之一,尤其在Web应用程序中广泛使用。本文将详细讨论“mysql57-community-release-el7-11.noarch.rpm”这个安装包,以及它在Linux环境中的应用。 标题中的...

Global site tag (gtag.js) - Google Analytics