InnoDB 스토리지 엔진을 사용하는 테이블의 경우 스토리지 공간은 메모리와 디스크 간 교체를 위한 기본 단위로 페이지 단위로 관리됩니다. 디스크에서 메모리로 페이지를 로드하면 디스크 I/O가 수행됩니다. 디스크 I/O의 오버헤드는 전체 성능에 큰 영향을 미치며, 해당 페이지를 메모리에서 직접 읽어오면 디스크 I/O로 인한 성능 손실이 줄어들고 효율성도 많이 향상되지 않을까요? 이를 바탕으로 Buffer Pool(
Buffer Pool
)이 등장했으니 다음으로는 InnoDB의 Buffer Pool에 대해 알아보겠습니다.Buffer Pool
) 出现了,那么接下来,我们就来谈谈InnoDB中的Buffer Pool。
有人会想,既然缓冲池这么好,那我们将所有数据都存储到缓冲池中不就好了,不不不,缓冲池是操作系统分配的一片连续的内存。而内存相比于磁盘的容量小得多,并且价格昂贵。那么操作系统会给缓冲池分配多少内存呢?
当然,如果你的机器的内存容量非常大,可以在配置文件中配置启动选项参数innodb_buffer_pool_size
单位是字节,最小不能小于5MB。
缓冲池将操作系统分配的这一片连续的内存,划分成若干个大小默认为16KB的页(缓冲页)【此时还没有真正的磁盘页被缓存到Buffer Pool中】,当我们从磁盘中换入一个页到缓冲池中,如何分配位置呢?因此就需要一些控制信息来标识这些缓冲池中的缓冲页,这些控制信息都存放在一个叫控制块的内存区域中,与缓冲页一一对应。控制块的大小也是固定的。因此在这片连续的内存空间中,难免会产生内存碎片。综上,缓冲池的内部结构如下:
上面在控制块中提到了链表节点信息,那么链表节点是用来做什么的呢?是为了更好的管理缓冲池中的页。而链表就是用来链接控制块的,因为控制块与缓冲页是一一对应的。
将所有空闲的缓冲页对应的控制块链接起来,形成的链表。
解决的问题:从磁盘中换入一个页到缓冲池中,如何区分缓冲池中的哪个页是空闲的呢?而有了空闲链表之后,换入一个磁盘页到缓冲池中时,就直接从空闲链表中获取一个空闲的缓冲页,并将磁盘页中对应的信息填到缓冲页对应的控制块中,然后将该控制块从空闲链表中删除即可。
若修改了缓冲池中的缓冲页的数据,导致其与磁盘中数据不一致,该页称为脏页。将所有脏页对应的控制块链接起来形成更新链表,在将来的某个时间根据该链表将对应缓存页的数据刷新到磁盘中。
缓冲池的大小是有限的,如果缓存的页超出了缓冲池的大小,即没有空闲的缓冲页了,当有新的页要添加到缓冲池中时,采取LRU的策略将旧的缓冲页从缓冲池中移除,然后将新的页添加进来。由于LRU链表涉及的内容较多,我们接下来单独介绍。
在I/O上的优化机制,预读顾名思义,会异步地把某些页面加载到缓冲池中,预计很快就会需要这些页面,这些请求在一个范围内引入所有页面,就是所谓的 局部性原理
,目的是减少磁盘I/O。
了解预读机制之前,先回顾一下InnoDB逻辑存储单元:表空间(tablespace)→段(segment )→区(extent)→页(page)。其中特意提一下区,后面会用到:一个区就是物理位置上连续的64个页
버퍼 풀은 운영 체제에서 할당한 연속 메모리입니다. 메모리는 디스크에 비해 용량이 훨씬 작고 가격도 비쌉니다. 그렇다면 운영 체제는 버퍼 풀에 얼마나 많은 메모리를 할당합니까?
innodb_buffer_pool_size
단위는 bytes이며, 최소값은 5MB 이상일 수 없습니다.
지역성 원칙
의 목적은 디스크 I/O를 줄이는 것입니다. 🎜🎜미리 읽기 메커니즘을 이해하기 전에 InnoDB의 논리적 저장 단위인 테이블스페이스 → 세그먼트 → 익스텐트 → 페이지를 살펴보겠습니다. 나중에 사용될 영역이 구체적으로 언급됩니다. 영역은 물리적 위치에서 연속적인 64페이지
입니다. 즉, 영역의 크기는 1MB입니다.🎜🎜🎜🎜🎜사전 읽기 메커니즘은 다음 두 가지 유형으로 나눌 수 있습니다. 🎜LRU 알고리즘을 사용하여 가장 최근에 사용된 버퍼 페이지를 관리하고 쉽게 제거할 수 있도록 해당 연결 목록을 구성합니다.
페이지에 액세스한 경우[즉, 최근에 액세스한 경우]
그렇다면 InnoDB는 왜 이렇게 직관적인 LRU 알고리즘을 사용하지 않는 걸까요? 그 이유는 다음과 같습니다.
미리 읽기 실패
미리 읽기가 가능한 버퍼 풀의 페이지는 LRU 연결 목록의 선두에 배치되지만, 그 중 많은 페이지가 읽혀지지 않을 수 있습니다.
버퍼 풀 오염
자주 사용하지 않는 페이지를 버퍼 풀에 로드하면 자주 사용되는 페이지가 버퍼 풀에서 제거됩니다. 예를 들어, full table scan
위의 단점을 기반으로 최적화된 특정 방법은 기존 LRU 연결 목록을 핫 데이터 영역[젊은 영역] 및 콜드 데이터 영역[올드 영역]
간단한 구조도는 다음과 같습니다.
그림과 같이 핫 데이터 영역과 콜드 데이터 영역이 다른 영역을 차지하면 innodb_old_blocks_pct
시작 옵션을 통해 innodb_old_blocks_pct
启动选项来控制冷数据区域所占比例。
改进后的LRU如何更好的解决预读失效问题呢?
改进后的LRU如何更好的解决缓冲池污染问题呢?
先说结论,并没有很好的优化这个问题,原因如下【以全表扫描为例】:
那么到底该如何解决缓冲池污染问题呢?
innodb_old_blocks_time
콜드 데이터 영역향상된 LRU는 어떻게 미리 읽기 실패 문제를 더 잘 해결할 수 있을까요?
향상된 LRU는 어떻게 버퍼풀 오염 문제를 더 잘 해결할 수 있을까요?
먼저 결론부터 말씀드리자면 이 문제는 잘 최적화되지 않았습니다. 그 이유는 다음과 같습니다. [전체 테이블 스캔을 예로 들어]: 🎜🎜🎜처음 방문한 페이지도 선두에 배치됩니다. 콜드 데이터 영역에 속하지만 이후 방문은 핫 데이터 영역의 선두에 위치하게 되어 접근 빈도가 높은 페이지도 밀려나게 됩니다. 🎜🎜🎜그렇다면 완충풀 오염 문제를 어떻게 해결할 수 있을까요? 🎜🎜🎜버퍼 풀은 콜드 데이터 영역 시간 창 메커니즘을 도입합니다. 즉, 페이지에 대한 후속 액세스와 페이지에 대한 첫 번째 액세스 사이의 시간 간격이 지정된 창 값보다 크면 페이지가 이동됩니다. 콜드 데이터 영역에서 핫 데이터 영역으로. 창 값이 지정된 값보다 작으면 이동 작업이 수행되지 않습니다. 🎜🎜마찬가지로 창 값은innodb_old_blocks_time
매개변수 [단위 ms]를 통해 설정할 수 있으며, 기본값은 1000ms이고 1s는 전체 테이블 스캔과 같은 대부분의 작업을 필터링합니다. 예를 들어, 전체 테이블 스캔 중에 페이지에 대한 다중 액세스 사이의 시간 간격은 1초를 초과하지 않습니다. 🎜🎜🎜버퍼 풀 VS 쿼리 캐시🎜🎜🎜버퍼 풀과 쿼리 캐시는 동일한가요? →아니요 🎜🎜🎜🎜버퍼 풀은 자주 사용되는 데이터를 저장하려고 시도합니다. MySQL은 페이지를 읽을 때 먼저 페이지가 버퍼 풀에 있는지 확인하고 그렇지 않으면 직접 읽습니다. 존재하는 경우에는 페이지를 메모리나 디스크를 통해 버퍼 풀에 저장한 후 직접 읽습니다. 🎜🎜쿼리 캐시는 쿼리 결과를 미리 캐시해 두므로 다음에 실행하지 않고도 바로 결과를 얻을 수 있습니다. MySQL의 쿼리 캐시는 쿼리 계획이 아니라 해당 쿼리 결과를 캐시한다는 점에 유의해야 합니다. 적중 조건이 엄격하고 데이터 테이블이 변경되는 한 쿼리 캐시가 무효화되므로 적중률이 낮습니다. 🎜🎜🎜【관련 추천: 🎜mysql 비디오 튜토리얼🎜】🎜위 내용은 MySQL의 데이터베이스 버퍼 풀(Buffer Pool)에 대해 알아보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!