Buffer pool in myql

foreword

In fact, when we add, delete, or modify the database, we mainly perform additions, deletions, and modifications to the data in the Buffer Pool in the memory, that is, you actually mainly add, delete, or modify the data structure in the memory of the database. At the same time, it cooperates with subsequent mechanisms and operations such as redo log and disk flushing. So Buffer Pool is a memory component of the database, which caches the real data on the disk, and then our Java system performs addition, deletion and modification operations on the database, in fact, it is mainly performed on the cached data in this memory data structure .
insert image description here

Buffer Pool: data structure

Disk Data Structures: Data Pages

insert image description here
In fact, suppose we want to update a row of data. At this time, the database will find the data page where the row of data is located, and then directly load the data page where the row of data is located into the Buffer Pool from the disk file. In other words, in the Buffer Pool It stores data pages one by one, as shown in the figure below.
insert image description here

Buffer pool data structure: data page (cache page)

In fact, by default, the size of the data page stored in the disk is 16KB, that is to say, one page of data contains 16KB of content.
The data pages stored in the Buffer Pool are usually called cache pages, because after all, the Buffer Pool is a buffer pool, and the data in it is cached from the disk to the memory. In Buffer Pool, by default, the size of a cache page and the size of a data page on the disk are in one-to-one correspondence, both of which are 16KB .
insert image description here

The description information corresponding to the cache page

For each cache page, he will actually have a description information, which can generally be considered as describing the cache page.
For example, it includes the following things: the table space to which the data page belongs, the number of the data page, the address of the cache page in the Buffer Pool, and other miscellaneous things. Each cache page corresponds to a description information, which itself is also a piece of data. In the Buffer Pool, the description data of each cache page is placed at the front, and then each cache page is placed at the back.
insert image description here
The description data in the Buffer Pool is about 5% of the size of the cache page, that is, each description data is about 800 bytes in size. Then suppose you set the buffer pool size to 128MB. In fact, the real Buffer Pool The final size will exceed a little, and it may look like more than 130 MB, because it also stores the description data of each cache page.

Buffer Pool: initialization

As soon as the database is started, it will increase slightly according to the size of the Buffer Pool you set, and go to the operating system to apply for a memory area as the memory area of ​​the Buffer Pool. Then when the memory area application is completed, the database will divide the cache pages one by one and them one by one in the Buffer Pool according to the default cache page size of 16KB and the corresponding description data size of about 800 bytes. Corresponding description data . Then when the database divides the Buffer Pool, it looks like the picture we saw before, as shown in the figure below
insert image description here

It’s just that at this time, each of the cache pages in the Buffer Pool is empty, and there is nothing in it. After the database is running, when we want to perform additions, deletions, changes, and queries on the data, the data will be corresponding The pages are read from the disk file and put into the cache pages in the Buffer Pool.

Linked list in Buffer Pool

Buffer Pool: free linked list

When your database is running, you will definitely perform addition, deletion, modification and query operations continuously. At this time, you need to read data pages one by one from the disk and put them into the corresponding cache pages in the Buffer Pool. , cache the data, then you can add, delete, modify and check this data in memory later.
But at this time, when reading data pages from the disk and putting them into the cache pages in the Buffer Pool, a problem must be involved, that is, which cache pages are free? Because by default, the data pages on the disk and the cache pages are in one-to-one correspondence, both of which are 16KB, and one data page corresponds to one cache page. So we must know which cache pages in the Buffer Pool are free.

The free linked list is a two-way linked list data structure. In this free linked list, each node is the address of a description data block of a free cache page. That is to say, as long as one of your cache pages is free, then its description data The block will be put into this free linked list .
When the database is started, all cache pages may be free, because it may be an empty database at this time, and there is no data, so at this time, the description data blocks of all cache pages will be put into this free linked list .
insert image description here
The free linked list contains the description data blocks of each cache page. As long as the cache pages are free, their corresponding description data blocks will be added to the free linked list. Each node will bidirectionally link its front and back nodes to form a doubly linked list. .
The free linked list itself is actually composed of the description data blocks in the Buffer Pool. You can think that each description data block has two pointers, one is free_pre, and the other is free_next, which point to their own previous free linked list. of nodes.

For the free linked list, there is only one basic node that does not belong to the Buffer Pool. It is a node with a size of 40 bytes, which stores the address of the head node of the free linked list, the address of the tail node, and the current node in the free linked list. How many nodes are there .

So how does the disk data page read the buffer pool data page?

First, we need to obtain a description data block from the free linked list, and then we can obtain the free cache page corresponding to the description data block, as shown in the figure below: Then we can read the data
insert image description here
page on the disk Go to the corresponding cache page, and at the same time write some relevant description data into the description data block of the cache page, such as the table space to which this data page belongs, and finally remove the description data block from the free list That's it, as shown in the figure below:
insert image description here
When we perform addition, deletion, modification and query, we must first check whether the data page is cached. If it is not cached, follow the above logic and find an idle cache from the free list. Page, read the data page from the disk and write it into the cache page, write the description data, and remove the description data block from the free linked list. But if the data page has been cached, it will be used directly.

cache page hash table

So in fact, the database will also have a hash table data structure, which will use the table space number + data page number as a key, and then the address of the cached page as the value . After reading a data page to the cache, a key-value pair will be written in the hash table. The key is the table space number + data page number, and the value is the address of the cache page. If you use this data next time page, it can be read directly from the hash table that it has been put into a cache page.
insert image description here
insert image description here

Buffer Pool: flush linked list

The essence of the flush linked list is to use the two pointers in the description data block of the cache page to make the description data block of the modified cache page form a two-way linked list. For any modified cache page, its description data block will be added to the flush list. Flush means that these are dirty pages, and they will be flushed to disk later, so the structure of the flush list is as follows As shown, it is almost the same as the free linked list.
insert image description here

Buffer Pool: LRU linked list

LRU is Least Recently Used, which means the least recently used. Through this LRU linked list, we can know which cache pages are the least recently used, so when you need to free up a cache page to flash to disk, can't you choose the least recently used cache page in the LRU linked list ? ?
Assuming that when we load a data page from the disk to the cache page, we put the description data block of the cache page into the head of the LRU linked list, then as long as there is a cache page with data, it will be in the LRU, and it has been loaded recently The data cache pages will be placed at the head of the LRU linked list.

As long as we load a data page from the disk to the cache page, put the description data block of the cache page into the head of the LRU list, then as long as there is a cache page with data, it will be in the LRU, and it has been loaded recently The data cache pages will be placed at the head of the LRU linked list. Therefore, when eliminating cache pages, find a cache page directly at the end of the LRU list, and then you flush the cache page at the end of the LRU list to the disk, and then load the disk data pages you need to the vacated space. Just cached pages .
insert image description here

full scan

SELECT * FROM USERS, at this time, he does not add any where condition, which will cause him to directly load all the data pages in this table from the disk to the Buffer Pool, and a large number of data pages will use the free cache pages over.
In the end, the front of the LRU linked list is full table scan data, and the hot data that was frequently accessed before has all reached the end of the queue. When the cache page is eliminated, the hot data page is eliminated .

Hot and cold separation LRU

The real LRU linked list will be split into two parts, one part is hot data and the other part is cold data. The ratio of the hot and cold data is controlled by the innodb_old_blocks_pct parameter, which defaults to 37, which means that the proportion of cold data is 37 %. The cache page that is loaded with data for the first time will be continuously moved to the head of the linked list in the cold data area.
insert image description here
MySQL set a rule, he designed an innodb_old_blocks_time parameter, the default value is 1000, which is 1000 milliseconds. Suppose you load a data page into the cache, and you still visit the cache page after 1 second, which means that you will probably visit it frequently in the future. The time limit is 1 second, so you only visit the cache after 1 second page, he will put the cache page for you at the head of the linked list in the hot data area .
insert image description here

Why is it moved to the hot area after revisiting after 1 second?
Because of the batch loading of the table, normally it is only loaded once. If it is one of the pages, the search speed is very fast, so the second query will basically not appear in the full table scan. The time interval between the first query and the first query exceeds 1s, so that the full table scan data can be avoided from entering the hot area.

Hot data LRU movement

Next, let's take a look at a performance optimization point in the hot data area of ​​the LRU linked list, that is, in the hot data area, if you access a cache page, should you immediately move it to the head of the linked list in the hot data area? Ministry to go? If this is the case, is it not too good to move so frequently?

When the amount of concurrency is large, because of the need to add locks, there will be lock competition, and the efficiency of each move will obviously drop. Therefore, MySQL has optimized this point. If a cache page is in the hot data area and is in the first 1/4 area of ​​the hot data area (note that it is 1/4 of the hot data area, not 1/4 of the entire linked list), Then when the cache page is accessed, it is not necessary to move it to the head of the hot data area; if the cache page is in the last 3/4 area of ​​the hot data, then when the cache page is accessed, it will be moved to the hot data area. The header of the data area .

For example, suppose there are 100 cache pages in the linked list of the hot data area, then the top 25 cache pages will not be moved to the head of the linked list even if they are accessed. But for the 75 cache pages that are ranked behind, as long as they are accessed, they will move to the head of the linked list. In this way, he can reduce the movement of nodes in the linked list as much as possible

Cold data LRU flashing

First of all, the first opportunity is not to select a few cache pages at the end of the LRU cold data area to be flushed to disk when the cache pages are full, but to have a background thread that will run a scheduled task. After a period of time, some cache pages at the end of the cold data area of ​​the LRU list will be flushed to the disk, these cache pages will be cleared, and they will be added back to the free list ! So in fact, when the cached pages are not used up, some cached pages may be cleared. Let's look at the following illustration
insert image description here

Buffer pool settings

Multiple Buffer Pools optimize concurrency

MySQL has received multiple requests at the same time, he will naturally use multiple threads to process these multiple requests, and each thread will be responsible for processing one request.
insert image description here
Now multiple threads are accessing the Buffer Pool concurrently. At this time, they are all accessing some shared data structures in the memory, such as cache pages, various linked lists, etc., so is it necessary to add at this time? Lock? Yes, multi-threaded concurrent access to a Buffer Pool must be locked, and then let a thread complete a series of operations, such as loading data pages to cache pages, updating the free linked list, updating the lru linked list, and then releasing the lock, and then The next thread performs a series of operations again.

In most cases, each thread queries or updates the data in the cache page. This operation occurs in the memory, basically at the microsecond level, and very quickly, including updating linked lists such as free, flush, and lru , because he performs some pointer operations based on the linked list, the performance is also extremely high.

Therefore, we can set multiple Buffer Pools for MySQL to optimize its concurrency capabilities.
Generally speaking, the default rule of MySQL is that if the memory you allocate to Buffer Pool is less than 1GB, then at most one BufferPool will be given to you.
But if your machine has a large memory, then you will definitely allocate a larger amount of memory to the Buffer Pool, such as 8G memory, then you can set multiple Buffer Pools at the same time, such as the following MySQL server configuration.

[server]
innodb_buffer_pool_size = 8589934592
innodb_buffer_pool_instances = 4

We set the total memory of 8GB for the buffer pool, and then set that it should have 4 Buffer Pools. At this time, the size of each buffer pool is 2GB. At this time, MySQL will have 4 Buffers when it is running. Pool! Each Buffer Pool is responsible for managing a part of cache pages and description data blocks, and has its own independent free, flush, lru and other linked lists.
insert image description here

Configure the size of the Buffer Pool

Because the Buffer Pool is actually a memory component of the database, you can understand it as a piece of memory data structure, so this memory data structure must have a certain size, and it cannot be infinite. The Buffer Pool is 128MB by default, which is still a little too small. We can adjust the Buffer Pool in our actual production environment.

For example, if our database is a 16-core 32G machine, then you can allocate 2GB of memory to the Buffer Pool, and use the following configuration.

nnodb_buffer_pool_size = 2147483648

We can first check the size of our innodb_buffer_pool_size and execute the following SQL, which can be found to be 134217728 [134217728 /1024 / 1024 =128M]

show global variables like ‘innodb_buffer_pool_size’;

set size

SET GLOBAL innodb_buffer_pool_size= 32423423

How much should the total memory of the Buffer pool be set?

A more reasonable and healthy ratio is suggested, which is to set about 50%~60% of your machine memory for the buffer pool. For example, if you have a 32GB machine, then set a 20GB memory for the buffer, and leave the rest for the OS and others. It is more reasonable for people to use it. Assuming that your machine has 128GB of memory, then the buffer pool can be set to about 80GB, which is probably such a rule.

How many buffer pools should be set?

Then after determining the total size of the buffer pool, you have to consider how many buffer pools to set and the size of the chunks. At this point, remember that
there is a key formula:
total buffer pool size = chunk size x chunk size Number x buffer pool number

Summarize

First of all, the memory space requested by the buffer pool must be a multiple of the page size (default 16KB). In other words, although the buffer pool is a large memory area, it is managed according to a fixed page size when used. As shown in the figure:
insert image description here
the buffer pool has a free linked list, which stores unused memory page space. When all the pages in the free linked list have been allocated, when space is requested again, the used pages need to be eliminated according to the LRU (Latest Recently Used) algorithm.

Generally speaking, the buffer pool in the database is managed through the LRU (Latest Recent Used least recently used) algorithm. That is, the most frequently used pages are at the front of the LRU list, and the least used pages are at the end of the LRU list. When the buffer pool cannot store the newly read page, it will first release the tail page from the LRU linked list.
In the InnoDB storage engine, it also uses the LRU algorithm to manage the buffer pool. The slight difference is that the InnoDB storage engine has made some optimizations to the traditional LRU algorithm. In the storage engine of InnoDB, the midpoint position is also added to the LRU linked list. Although the newly read page is the latest accessed page, it is not directly put into the head of the LRU linked list, but placed into the LRU linked list. midpoint position. This algorithm is called midpoint insertion strategy under the InnoDB storage engine. In the default configuration, the position is at 3/8 of the length of the LRU linked list, as shown in the figure.
insert image description here
Then why not use the simple LRU algorithm to directly put the read page into the head of the LRU linked list? This is because if the read page is directly put into the head of the LRU, some SOL operations may cause Pages in the buffer pool are flushed from the LRU linked list, thus affecting the efficiency of the buffer pool. Common such operations are index or data scan operations. This type of operation needs to access many pages in the table, or even all pages, and these pages are usually only needed in this query operation, and are not active hot data. If the page is placed at the head of the LRU linked list, it is very likely that the required hot data page will be removed from the LRU linked list, and when the page needs to be read next time, the InnoDB storage engine needs to access the disk again, resulting in a decrease in database performance decline.

Pages in the buffer pool not only need to be read, but also need to be modified. The modified page must occur in the LRU linked list. When the page in the LRU linked list is modified, the page is called a dirty page (dirty page), that is, the page data in the buffer pool and the page data on the disk are inconsistent. At this time, the database will flush the dirty pages back to disk through the checkpoint mechanism. The pages in the flush list are dirty pages. It should be noted that dirty pages exist in both the LRU linked list and the flush linked list. The LRU linked list is used to manage the availability of pages in the buffer pool, and the flush linked list uses dry management to flush pages back to disk, and the two do not affect each other. Shows the relationship between the free linked list, LRU linked list, and flush linked list:
insert image description here

Article source: https://www.saoniuhuo.com/article/detail-484156.html
Summary: https://blog.csdn.net/lijuncheng963375877/article/details/124011204
Other article recommendations: https://zhuanlan.zhihu .com/p/408119486
Video link: https://www.bilibili.com/video/BV1Pv411h7Ep

Guess you like

Origin blog.csdn.net/yzx3105/article/details/130736132