This article takes you to understand the InnoDB data page structure of MySQL

foreword

After learning the record structure, we should learn the structure of the data page. Earlier we briefly mentioned the concept of the page, which is the basic unit of Innodb management storage space. The default page size is 16KB. InnoDB has designed many types for different purposes. Different types of pages, such as pages that store tablespace header information, pages that store Insert Buffer information, pages that store INODE information, pages that store undo log information, and so on. And what we focus on are those pages that store the records in our table. Officially, the pages that store records are called index (INDEX) pages. Since we have not yet understood what the index is, and the pages in these tables Records are what we call data in our daily mouth, so we still call this page for storing records a data page.

1. The structure preview of the data page

insert image description here
It can be seen from the figure that the storage space of an InnoDB data page is roughly divided into seven parts, some parts occupy a certain number of bytes, and some parts occupy an uncertain number of bytes. Let's take a quick look at what these 7 sections store:

name Chinese name Size (unit: B) describe
File Header file header 38 Some general information on the page
Page Header page header 56 Some information specific to the data page
The lowest + the highest Minimum record and maximum record 26 two dummy line records
User Records User's real record uncertain The actual stored row record content
Free Space free space uncertain unused space in the page
Page Directory page directory uncertain The relative position of certain records in the page
File Trailer end of file 8 Whether the verification page is complete

2. Storage of real user records in the data page (Free Space)

Among the seven components of the page, the records we store ourselves will be stored in the User Records section according to the row format we specified. But when the page was first generated, there was no User Records section. Whenever we insert a record, we would apply for a record-sized space from the Free Space section, that is, the unused storage space, and divide it into the User Records section. When the space in the Free Space part is completely replaced by the User Records part, it means that this page is used up. If there are new records to be inserted, you need to apply for a new page. A diagram of this process is as follows:

insert image description here
In order to better manage these records in User Records, InnoDB has spent a lot of effort, where is the effort? Isn't it just to put the records in the User Records section one by one according to the specified row format? In fact, this has to start from the record header information in the record line format

3. The "record" structure of the data page derived from the record header information

Let's create a table first

mysql> create table demo5 (c1 int, c2 int, c3 varchar(10000),primary key (c1)) charset=ascii row_format=compact;

Query OK, 0 rows affected (0.04 sec)

This newly created table has three columns, c1 and c2 columns are used to store integers, c3 stores strings, but we specify c1 as the primary key, so in the specific row format, Innodb does not need to create a row_id hidden column for us up. So the schematic diagram of the row format in the table is as follows:

insert image description here
We deliberately took out the first five bytes of the record
insert image description here
and pasted the meaning of each attribute in the record header information (currently using the Compact line format):

name size (unit: bit) describe
Reserved bit 1 1 not used
Reserved 2 1 not used
delete_mask 1 Mark whether the record is deleted
min_rec_mask 1 This mark will be added to the smallest record in each non-leaf node of the B+ tree
n_owned 4 Indicates the number of records owned by the current record
heap_no 13 Indicates the position information of the current record in the record heap
record_type 3 Indicates the type of the current record, 0 indicates an ordinary record, 1 indicates a B+ tree non-leaf node record, 2 indicates the smallest record, and 3 indicates the largest record
next_record 16 Indicates the relative position of the next record

Below we insert a few pieces of data

mysql> insert into demo5 values(1,100,'aaaa'),(2,200,'bbbb'),(3,300,'cccc'),(4,400,'dddd');
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

We look at the information header of these 4 lines of records

insert image description here
Line 1: 00 00 10 00 20
Line 2: 00 00 18 00 20
Line 3: 00 00 20 00 20
Line 4:00 00 28 ff 91

Convert to binary as follows:

Line 1: 00000000 00000000 00010000 00000000 00100000
Line 2: 00000000 00000000 00011000 00000000 00100000
Line 3: 00000000 00000000 00100000 00000000 00100000
Line 4:00000000 00000000 00101000 11111111 10010001

The fourth line 11111111 10010001is a negative number, complement +1, which is -111

In order to facilitate everyone to analyze how these records are represented in the User Records section of the page, I have expressed the header information and actual column data in the records in decimal, so the schematic diagram of these records is

insert image description here

It should be noted that there are no gaps in the storage of each record in User Records. This is for the convenience of everyone to draw each record separately. Let's compare this picture to see the attributes in the record header information:

3.1 delete_mask

This attribute marks whether the current record is deleted, occupying a binary bit, 0 means not deleted, 1 is deleted

Deleted records are not immediately removed from the disk, because rearranging other records on the disk after removing them requires performance consumption, so it is just a deletion mark, and all deleted records will form a so-called garbage Linked list, the space occupied by the records in this linked list is called the so-called reusable space. If new records are inserted into the table later, the storage space occupied by these deleted records may be overwritten. Setting the delete_mask bit to 1 and adding the deleted record to the garbage list are two stages

3.2 min_rec_mask

This mark will be added to the smallest record in each non-leaf node of the B+ tree. A value of 1 means that the record is the smallest record in the non-leaf nodes of the B+ tree; a value of 0 means that the record is not the smallest record in the non-leaf nodes of the B+ tree

3.3 n_owned

Indicates the number of records owned by the current record, we will introduce it in detail later

3.4 heap_no

This property indicates the position of the current record on this page. MySQL automatically adds two records to each page. Since these two records are not inserted by ourselves, they are sometimes called pseudo records or virtual records. One of these two pseudo-records represents the smallest record and the other represents the largest record.

Records can also be compared in size. For a complete record, comparing the size of the record is comparing the size of the primary key. But no matter how many records we insert into the page, InnoDB stipulates that the two pseudo-records they define are the minimum record and the maximum record. The structure of these two records is very simple, both of which are composed of 5-byte record header information and a fixed part of 8-byte size.

insert image description here
insert image description here
Let's look at the file header now, which are as follows:

Max Records: 05 00 0b 00 00
Min Records:01 00 02 00 1c

Convert to binary as follows:

Max Records: 00000101 00000000 00011011 00000000 00000000
Min Records:00000001 00000000 00000010 00000000 00011100

Since these two records are not defined by us, they are not stored in the User Records section of the page. They are placed separately in the Infimum + Supremum section mentioned above

insert image description here

In the figure, other information is not shown but it does not mean that they do not exist, but it is simplified for the convenience of everyone to understand. The heap_no values ​​of the smallest record and the largest record are 0 and 1 respectively, that is to say, their positions are at the front

3.5 record_type

This attribute indicates the type of the current record. There are 4 types of records in total. 0 indicates ordinary records, 1 indicates B+ tree non-leaf node records, 2 indicates the smallest record, and 3 indicates the largest record. We can also see from the figure that the records we insert ourselves are ordinary records, and their record_type values ​​are all 0, while the record_type values ​​of the minimum record and the maximum record are 2 and 3 respectively. As for the case of record_type being 1, we will It will be emphasized when talking about indexing.

3.7 next_record

This information is very important and represents the address offset from the real data of the current record to the real data of the next record. For example, the next_record value of the first record is 32, which means that 32 bytes backward from the address of the real data of the first record is the real data of the next record. If you are familiar with data structures, you will immediately understand that this is actually a linked list, and you can find its next record through a record. But one thing to pay attention to is that the next record does not refer to the next record in the order of our insertion, but the next record in the order of the primary key value from small to large. And it is stipulated that the next record of the Infimum record (that is, the smallest record) is the user record with the smallest primary key value on this page, and the next record of the user record with the largest primary key value on this page is the Supreme record (that is, the largest record) , in order to more vividly express the role played by this next_record, we use arrows to replace the address offset in next_record:

insert image description here

As can be seen from the figure, our records form a singly linked list in ascending order of the primary key. The next_record value of the largest record is 0, which means that there is no next record for the largest record, and it is the last node in the singly linked list. If a record is deleted from it, the linked list will also change accordingly. For example, we delete the second record:

mysql> delete from demo5 where c1 =2;
Query OK, 1 row affected (0.02 sec)

After deleting the second record, let's take a look at the four-line record of the demo5.ibd file and the maximum and minimum record header information

insert image description here

Line 1 : 00 00 10 00 40
Line 2 : 20 00 18 00 00
Line 3: 00 00 20 00 20
Line 4:00 00 28 ff 91

Max Records : 04 00 0b 00 00
Min Records:01 00 02 00 1c

Compared with the previous ones, we found that the first line, the second line, and the maximum record have changed, and the conversion of the base system will not be demonstrated here.

0x40=64
0x20=0010 0000
0x04=0000 0100

The schematic is:

insert image description here

As can be seen from the figure, these changes mainly occurred before and after deleting the second record:

  • The second record is not removed from the storage space, but the delete_mask value of this record is set to 1.
  • The next_record value of the second record becomes 0, which means that there is no next record for this record.
  • The next_record value of the first record becomes 64, pointing to the third record.
  • The n_owned value of the largest record has changed from 5 to 4. We will explain this change in detail later.

Therefore, no matter how we add, delete, or modify records in the page, InnoDB will always maintain a single-linked list of records, and each node in the linked list is connected in order of primary key value from small to large

Do you think the next_record pointer is a bit strange, why should it point to the position between the record header information and the real data? Why not just point to the beginning of the entire record, that is, the beginning of the additional information recorded?

Because this position is just right, reading to the left is the record header information, and reading to the right is the real data. MySQL's InnoDB record structure We also said that the information in the variable-length field length list and the NULL value list is stored in reverse order, so that the distance between the front-positioned fields in the record and their corresponding field length information in the memory is closer , which may improve the cache hit ratio.

Let's look at another interesting thing, because the record with the primary key value of 2 was deleted by us, but the storage space was not recovered. If we insert this record into the table again, what will happen?

mysql> insert into demo5 VALUES(2, 200, 'bbbb');
Query OK, 1 row affected (0.01 sec)

Let's look directly at the data file

insert image description here
Is it exactly the same as the beginning, as shown in the picture

insert image description hereInnoDB does not apply for new storage space for the insertion of new records, but directly reuses the storage space of the original deleted records.

Tips
1. When there are multiple deleted records in the data page, the next_record attribute of these records will form a garbage list with these deleted records, so that this part of the storage space can be reused later. If a line of record is deleted above and then inserted back intact, the original storage space will be reused.
2. There is another situation that will not be reused: after deleting the original record, when the storage space occupied by the real data of the newly inserted record is larger than the storage space of the original record, the original space will not be reused and will be added to the garbage list. Newly inserted records will apply for new space from Free Space and combine with existing records to form a new linked list.

Four, Page Directory (page directory)

Now that we understand that the records in the page are concatenated into a singly linked list according to the primary key value from small to large, what should we do if we want to find a certain record in the page according to the primary key value? For example, a query like this:

select * from where c1=3;

The stupidest way: start from the Infimum record (the smallest record), and look all the way back along the linked list, and you will always find it. You can also be opportunistic when looking for it, because the values ​​​​of each record in the linked list are arranged in ascending order, so when the primary key value of the record represented by a node in the linked list is greater than the primary key value you want to find, you The search can be stopped, because the primary key values ​​​​of the nodes behind the node are incremented sequentially.

But can InnoDB use such a stupid method? Of course, it is necessary to design a faster search method, so I almost found inspiration from the catalog of the book.

When we usually want to find a certain content from a book, we usually look at the table of contents first, find the page number of the book corresponding to the content we need to find, and then go to the corresponding page number to view the content. InnoDB also made a similar directory for our records, and their production process is as follows:

  • Divide all normal records (including the largest and smallest records, excluding records marked as deleted) into several groups.
  • The n_owned attribute in the header information of the last record in each group (that is, the largest record in the group) indicates how many records the record owns, that is, how many records there are in the group.
  • The address offset of the last record of each group is extracted separately and stored in sequence 靠近页的尾部的地方. This place is the so-called Page Directory, that is, the page directory. These address offsets in the page directory are called slots (English name: Slot), so this page directory is composed of slots.

It should be noted that the Page Directory is stored in reverse order, and each slot occupies 2 bytes

insert image description here
From this figure, we need to pay attention to the following points:

  • Now there are two slots in the page directory section, which means that our records are divided into two groups. The value in slot 1 is 112, which represents the address offset of the largest record (that is, counting from byte 0 of the page , counting 112 bytes); the value in slot 0 is 99, representing the address offset of the minimum record.

  • Note the n_owned attribute in the min and max record headers

    • The n_owned value of the smallest record is 1, which means that there is only one record in the group ending with the smallest record, which is the smallest record itself.

    • The n_owned value of the largest record is 5, which means that there are only 5 records in the group ending with the largest record, including the largest record itself and the 4 records we inserted ourselves.

Address offsets like 99 and 112 are not intuitive. We replace the numbers with arrows, which is easier for us to understand, so the modified schematic diagram is like this:

insert image description here
Regardless of the arrangement of the records on the storage device for the time being, just look at the relationship between these records and the page directory logically:

insert image description here
InnoDB has regulations on the number of records in each group: the group with the smallest record can only have 1 record, the group with the largest record can only have between the records, and the remaining 1~8group The range of the number of records can only be 4~8between. So the grouping is done according to the following steps:

  • Initially, there are only two records in a data page, the minimum record and the maximum record, and they belong to two groups.

  • After inserting a record, it will find the slot whose primary key value is larger than the primary key value of this record and the difference is the smallest from the page directory, and then add 1 to the n_owned value of the record corresponding to the slot, indicating that this group has added another One record until the number of records in the group equals 8.

  • When the number of records in a group is equal to 8 and then a record is inserted, the records in the group will be split into two groups, with 4 records in one group and 5 records in the other. This process will add a new slot in the page directory to record the offset of the largest record in the newly added group.

Since there are too few records in the table now demo5, it is impossible to demonstrate the process of speeding up the search after adding the page directory, so demo5add some more records to the table

insert into demo5 values(5, 500, 'eeee');
insert into demo5 values(6, 600, 'ffff');
insert into demo5 values(7, 700, 'gggg');
insert into demo5 values(8, 800, 'hhhh');
insert into demo5 values(9, 900, 'iiii');
insert into demo5 values(10, 1000, 'jjjj');
insert into demo5 values(11, 1100, 'kkkk');
insert into demo5 values(12, 1200, 'llll');
insert into demo5 values(13, 1300, 'mmmm');
insert into demo5 values(14, 1400, 'nnnn');
insert into demo5 values(15, 1500, 'oooo');
insert into demo5 values(16, 1600, 'pppp');

Now there are a total of 18 records in the page (including the minimum and maximum records), and these records are divided into 5 groups, as shown in the figure:

insert image description here
Because it takes too much space to draw all the information of 16 records in one picture, it is dazzling, so only the n_owned and next_record attributes in the user record header information are kept, and the arrows between each record are omitted. I No painting does not mean no! Now see how to find records from this page directory. Because the primary key values ​​​​of the records represented by each slot are sorted from small to large, we can use the so-called dichotomy for fast search. The numbers of the 5 slots are: 0, 1, 2, 3, 4, so the lowest slot in the initial case is low=0, and the highest slot is high=4. For example, if we want to find records with a primary key value of 6, the process is as follows:

  • Calculate the position of the middle slot: (0+4)/2=2, so look at slot 2, the primary key value of the corresponding record is 8, and because 8 > 6, set high=2, and low remains unchanged.
  • Recalculate the position of the middle slot: (0+2)/2=1, so check that the primary key value corresponding to slot 1 is 4, and because 4 < 6, set low=1, and high remains unchanged.
  • Because the value of high - low is 1, it is determined that the record with a primary key value of 6 is in the group corresponding to slot 2. At this moment, we need to find the record with the smallest primary key value in slot 2, and then traverse the slots along the one-way linked list 2 records. But as we said before, the record corresponding to each slot is the record with the largest primary key value in the group. Here, the record corresponding to slot 2 is the record with the primary key value of 8. How to locate the smallest record in a group? Don’t forget that the slots are next to each other. We can easily get the record corresponding to slot 1 (the primary key value is 4), and the next record of this record is the record with the smallest primary key value in slot 2. The record has a primary key value of 5. So we can start from this record with a primary key value of 5, and traverse the records in slot 2 until we find the record with a primary key value of 6. Since the number of records contained in a group can only be 1~8, the cost of traversing the records in a group is very small.

So the process of finding the record of the specified primary key value in a data page is divided into two steps:

  • Determine the slot where the record is located by dichotomy, and find the record with the smallest primary key value in the group where the slot is located.

  • Traverse each record in the group where the slot is located through the next_record attribute of the record

We use the hexdump command to parse the data file:

root@mysql2 testdb]# hexdump -C demo5.ibd > demo5.txt

insert image description here

Five, Page Header (page header)

In order to get the status information of the records stored in a data page, InnoDB, such as how many records have been stored in this page, what is the address of the first record, how many slots are stored in the page directory, etc., are specially stored in the page A part called Page Header is defined, which is the second part of the page structure. This part occupies a fixed 56 bytes and is dedicated to storing various status information.

insert image description here

See the table below for the meaning of each byte:

name Size (unit: B) describe
page_n_dir_slots 2 Number of slots for the page directory
page_heap_top 2 The minimum address of the unused space, that is to say, free space after this address
page_n_heap 2 Number of records on this page (including min and max records and records marked for deletion)
page_free 2 The address of the first record that has been marked as deleted (each deleted record will also form a singly linked list through next_record, and the records in this singly linked list can be reused)
page_garbage 2 The number of bytes occupied by deleted records
page_last_insert 2 The position of the last inserted record
page_direction 2 direction of record insertion
page_n_direction 2 The number of records inserted consecutively in one direction
page_n_recs 2 Number of records on the page (excluding minimum and maximum records and records marked for deletion)
page_max_trx_id 8 Modify the maximum transaction id of the current page, which is only defined in the secondary index
page_level 2 The level of the current page in the b+ tree
page_index_id 8 Index id, indicating which index the current page belongs to
page_btr_seg_leaf 10 The header information of the b+ tree leaf segment is only defined on the root page of the b+ tree
page_btr_seg_top 10 The header information of the non-leaf segment of the b+ tree is only defined on the root page of the b+ tree

Through the introduction of the previous article, everyone must be clear about the meaning of page_n_dir_slots, page_last_insert and page_n_recs.

If you are not sure, I suggest you go back and take a good look. Don't worry about the rest of the status information.

Let's first look at the meaning of page_direction and page_n_direction:

5.1 page_direction

If the primary key value of a newly inserted record is greater than the primary key value of the previous record, we say that the insertion direction of this record is to the right, and vice versa. The state used to indicate the insertion direction of the last record is page_direction

0x02 Right
0x01 Left
0x05 Unordered

5.2 page_n_direction

Assuming that the direction of inserting new records several times in a row is the same, InnoDB will record the number of records inserted in the same direction, and this number is represented by the state of page_n_direction. Of course, if the insertion direction of the last record is changed, the value of this status will be cleared and counted again.

Let's look at the data file above and it corresponds to 0x000f, which is 15.

As for the attributes we didn't mention, I didn't mention them because we don't need to know them now. Don't worry, when we have finished learning the content behind, you can look back and everything is so clear.

Tip:
When it comes to some things that are clear when we look back after we learn them, I can't help but think of Jobs' speech at Stanford University: "You can't connect the dots looking forward; you can only connect them looking backwards . So you have to trust that the dots will somehow connect in your future. You have to trust in something - your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.” The above paragraph was written on a whim, to the effect that you insist on doing the things you like. When you are doing it, you may not be able to figure out what impact these things will have on your future life, but when you When I walked back and forth and looked back, everything was so clear, as if it was meant to be.

Six, File Header (file header)

Page Header is a variety of status information specially recorded for data pages, such as how many records and how many slots there are in the page. The File Header we describe now is common to all types of pages, that is to say, different types of pages will use the File Header as the first component, which describes some information that is common to various pages, such as this What is the page number, who is its previous page, and who is the next page... This part occupies a fixed 38 bytes and is composed of the following contents:

insert image description here

See the table below for the meaning of each byte:

name Size (unit: B) describe
fil_page_space_or_chksum 4 Page checksum (checksum value)
fil_page_offset 4 page number
file_page_prev 4 page number of the previous page
fil_page_next 4 Page number of the next page
fil_page_lsn 8 页面被最后修改时对应的日志序列位置(英文名是:log sequence number)
fil_page_type 2 该页的类型
fil_page_file_flush_lsn 8 仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的lsn值
fil_page_arch_log_no_or_space_id 4 页属于哪个表空间

对照着这个表格,我们看几个目前比较重要的部分:

6.1 fil_page_space_or_chksum

这个代表当前页面的校验和(checksum)。啥是个校验和?就是对于一个很长很长的字节串来说,我们会通过某种算法来计算一个比较短的值来代表这个很长的字节串,这个比较短的值就称为校验和。这样在比较两个很长的字节串之前先比较这两个长字节串的校验和,如果校验和都不一样两个长字节串肯定是不同的,所以省去了直接比较两个比较长的字节串的时间损耗。

6.2 fil_page_offset

每一个页都有一个单独的页号,就跟你的身份证号码一样,InnoDB通过页号来可以唯一定位一个页。

6.3 fil_page_type

这个代表当前页的类型,我们前边说过,InnoDB为了不同的目的而把页分为不同的类型,我们上边介绍的其实都是存储记录的数据页,其实还有很多别的类型的页,具体如下表:

类型名称 十六进制 描述
fil_page_type_allocated 0x0000 最新分配,还没使用
fil_page_undo_log 0x0002 undo日志页
fil_page_inode 0x0003 段信息节点
fil_page_ibuf_free_list 0x0004 insert buffer空闲列表
fil_page_ibuf_bitmap 0x0005 insert buffer位图
fil_page_type_sys 0x0006 系统页
fil_page_type_trx_sys 0x0007 事务系统数据
fil_page_type_fsp_hdr 0x0008 表空间头部信息
fil_page_type_xdes 0x0009 扩展描述页
fil_page_type_blob 0x000a 溢出页
fil_page_index 0x45bf 索引页,也就是我们所说的数据页

6.4 fil_page_prev和fil_page_next

我们前边强调过,InnoDB都是以页为单位存放数据的,有时候我们存放某种类型的数据占用的空间非常大(比方说一张表中可以有成千上万条记录),InnoDB可能不可以一次性为这么多数据分配一个非常大的存储空间,如果分散到多个不连续的页中存储的话需要把这些页关联系起来来,fil_page_prev和fil_page_next就分别代表本页的上一个和下一个页的页号。这样通过建立一个双向链表把许许多多的页就都串联起来了,而无需这些页在物理上真正连着。需要注意的是,并不是所有类型的页都有上一个和下一个页的属性,不过我们本集中唠叨的数据页(也就是类型为fil_page_index 的页)是有这两个属性的,所以所有的数据页其实是一个双链表,就像这样:

insert image description here

七、File Trailer(文件尾部)

InnoDB存储引擎会把数据存储到磁盘上,但是磁盘速度太慢,需要以页为单位把数据加载到内存中处理,如果该页中的数据在内存中被修改了,那么在修改后的某个时间需要把数据同步到磁盘中。但是在同步了一半的时候中断电了咋办,这不是莫名尴尬么?为了检测一个页是否完整(也就是在同步的时候有没有发生只同步一半的尴尬情况),InnoDB在每个页的尾部都加了一个File Trailer部分,这个部分由8个字节组成,可以分成2个小部分:

insert image description here

  • 前4个字节代表页的校验和
    这个部分是和File Header中的校验和相对应的。每当一个页面在内存中修改了,在同步之前就要把它的校验和算出来,因为File Header在页面的前边,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的。如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trailer中的校验和代表着原先的页,二者不同则意味着同步中间出了错。

  • 后4个字节代表页面被最后修改时对应的日志序列位置(LSN)
    这个部分也是为了校验页的完整性的,只不过我们目前还没说LSN
    是个什么意思,所以大家可以先不用管这个属性。这个File Trailer与File Header类似,都是所有类型的页通用的。

总结

今天的数据页结构理论知识也很多,下面我们来做个总结:

  • InnoDB为了不同的目的而设计了不同类型的页,我们把用于存放记录的页叫做数据页

  • 一个数据页可以被大致划分为7个部分,分别是:
    -insert image description here

    • File Header,表示页的一些通用信息,占固定的38字节。

    • Page Header,表示数据页专有的一些信息,占固定的56个字节。

    • Infimum + Supremum,两个虚拟的伪记录,分别表示页中的最小和最大记录,占固定的26个字节。

    • User Records:真实存储我们插入的记录的部分,大小不固定。

    • Free Space:页中尚未使用的部分,大小不确定。

    • Page Directory:页中的某些记录相对位置,也就是各个槽在页面中的地址偏移量,大小不固定,插入的记录越多,这个部分占用的空间越多。
      File Trailer:用于检验页是否完整的部分,占用固定的8个字节

  • 每个记录的头信息中都有一个next_record属性,从而使页中的所有记录串联成一个单链表

  • InnoDB会把页中的记录划分为若干个组,每个组的最后一个记录的地址偏移量作为一个槽,存放在Page Directory中,所以在一个页中根据主键查找记录是非常快的,分为两步:

    • 通过二分法确定该记录所在的槽。
    • 通过记录的next_record属性遍历该槽所在的组中的各个记录。
  • 每个数据页的File Header部分都有上一个和下一个页的编号,所以所有的数据页会组成一个双链表。

  • 为保证从内存中同步到磁盘的页的完整性,在页的首部和尾部都会存储页中数据的校验和和页面最后修改时对应的LSN值,如果首部和尾部的校验和和LSN值校验不成功的话,就说明同步过程出现了问题。

便于大家理解,我整理了一张数据页结构图:

insert image description here
本章较上一章记录结构知识点更多,原书作者画了很多图,看完后,我是一脸懵,虽然这两章内容理论知识偏多,但是为我们后面理解索引原理打下坚实基础,所以大家一定要理解文中重要的知识点。

至此今天的学习就到此结束了,愿您成为坚不可摧的自己~~~

You can’t connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future.You have to trust in something - your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life

If my content is helpful to you, please 点赞, 评论,, 收藏creation is not easy, everyone's support is the motivation for me to persevere

insert image description here

Guess you like

Origin blog.csdn.net/liang921119/article/details/130556995