Буферный пул (буферный пул), на этот раз я полностью понимаю! ! !

Java задняя часть Архитектура

Многоуровневая архитектура системы приложений, чтобы ускорить доступ к данным, наиболее часто используемые данные будут помещены втайник(кэш), чтобы каждый раз не обращаться к базе данных.

операционная система, будетбуферный пул(буферный пул), чтобы избежать доступа к диску каждый раз, чтобы ускорить доступ к данным.

В качестве системы хранения MySQL также имеетбуферный пул(буферный пул), чтобы избежать дискового ввода-вывода для каждого запроса данных.

Сегодня поговорим о буферном пуле InnoDB.

Что кэширует буферный пул InnoDB? Какая польза?

Кэшируйте данные таблицы и данные индекса, загружайте данные на диск в пул буферов, избегайте дискового ввода-вывода при каждом доступе и ускоряйте доступ.

быстро, чтоПочему бы не поместить все данные в пул буферов?

У всего есть две стороны, помимо волатильности данных, противоположностью быстрого доступа является малая емкость хранилища:

(1) доступ к кешу быстрый, но его емкость мала.База данных хранит 200 ГБ данных, а объем кеша может быть только 64 ГБ;

(2) Доступ к памяти быстрый, но емкость маленькая.Купите диск для ноутбука с 2T, а память может быть только 16G;

Следовательно, только самые «горячие» данные могут быть размещены в «ближайшем» месте, чтобы минимизировать обращение к диску.

Как управлять пулами буферов и устранять их, чтобы максимизировать производительность?

Прежде чем углубляться в детали, давайте введем понятие «предварительное чтение».

Что такое предварительное чтение?

Чтение и запись диска не читаются по требованию, а читаются постранично, за раз считывается как минимум одна страница данных (обычно 4 КБ). сохранено. , Повышение эффективности.

Почему предварительное чтение работает?

Доступ к данным обычно следует принципу "централизованного чтения и записи". Когда используются некоторые данные, скорее всего, будут использоваться соседние данные. Это так называемый "принцип локальности", который указывает на то, что ранняя загрузка эффективна и действительно может уменьшить дисковый ввод-вывод.

Чтение по страницам (4K), какое отношение это имеет к дизайну пула буферов InnoDB?

(1) Доступ к диску может повысить производительность за счет постраничного чтения, поэтому буферный пул обычно кэширует данные постранично;

(2) Механизм предварительного чтения показывает нам, что мы можем заранее добавить некоторые страницы, к которым «может быть доступ», в пул буферов, чтобы избежать будущих операций ввода-вывода на диск;

Какой алгоритм использует InnoDB для управления этими буферными страницами?

Проще всего придумать LRU (наименее недавно использовавшийся).

Голос за кадром: memcache, ОС будет использовать LRU для управления заменой страниц, но игровой процесс MySQL отличается.

Как традиционный LRU выполняет управление страницами буфера?

Самый распространенный способ игры — поместить страницу в буферный пул во главе LRU как самый последний доступный элемент, который будет удален самое позднее. Здесь есть два случая:

(1)Страница уже находится в пуле буферов, то выполняется только действие «перемещения» в голову LRU, и никакие страницы не удаляются;

(2)Страница не в буферном пуле, в дополнение к действию «помещения» заголовка LRU, но также и действию «удаления» последней страницы LRU;

Как показано на рисунке выше, если длина LRU пула буферов управления равна 10, буферизуются страницы с номерами 1, 3, 5..., 40, 7.

Предположим, что следующие данные, к которым нужно получить доступ, находятся на странице с номером страницы 4:

(1) Страница с номером 4 изначально находится в пуле буферов;

(2) Поместите страницу с номером 4 в заголовок LRU, и ни одна страница не будет удалена;

Голос за кадром: Чтобы уменьшить перемещение данных, LRU обычно реализуется со связанным списком.

Предположим, что следующие данные, к которым нужно получить доступ, находятся на странице с номером страницы 50:

(1) Страница с номером страницы 50 изначально не находилась в пуле буферов;

(2) Поместите страницу с номером страницы 50 в заголовок LRU и удалите страницу с номером страницы 7 в конце;

Традиционный алгоритм буферного пула LRU очень интуитивно понятен, и используется много программного обеспечения, такого как ОС и кэш памяти.Почему MySQL такой претенциозный и не может использоваться напрямую?

Здесь есть две проблемы:

(1) Предварительное чтение не удается;

(2) загрязнение буферного бассейна;

Что такое аннулирование чтения вперед?

Из-за упреждающего чтения страница заранее помещается в пул буферов, но MySQL не считывает данные со страницы в конце, что называется сбоем упреждающего чтения.

Как оптимизировать ошибку опережающего чтения?

Чтобы оптимизировать сбой опережающего чтения, идея такова:

(1) Пусть страницы, которым не удалось упреждающее чтение, остаются в буферном пуле LRU как можно меньше времени;

(2) Позволить фактически прочитанным страницам переместиться в начало LRU буферного пула;

Чтобы гарантировать, что горячие данные, которые фактически считываются, остаются в буферном пуле как можно дольше.

Конкретный метод:

(1) Разделите LRU на две части:

  • Новое поколение (новый подсписок)
  • Старое поколение (старый подсписок)

(2) Новое и старое поколения соединяются в конце, то есть хвост нового поколения соединяется с головой старого поколения;

(3) Когда новая страница (например, предварительно прочитанная страница) добавляется в пул буферов, она добавляется только в заголовок старого поколения:

  • Если данные действительно прочитаны (предварительное чтение прошло успешно), они будут добавлены в голову нового поколения
  • Если данные не читаются, они будут удалены из пула буферов раньше, чем «горячие страницы данных» в молодом поколении.

Например, весь LRU буферного пула показан выше:

(1) Длина всего LRU равна 10;

(2) Первые 70% — это новое поколение;

(3) Последние 30% — это старое поколение;

(4) Новое и старое поколения связаны встык;

Предположим, что новая страница с номером страницы 50 предварительно загружается и добавляется в пул буферов:

(1) 50 будут вставлены только из заголовка старого поколения, а страницы в хвосте старого поколения (также весь хвост) будут удалены;

(2) Предполагая, что страница 50 не будет фактически прочитана, т. е. произойдет сбой предварительного чтения, она будет исключена из пула буферов раньше, чем данные нового поколения;

Например, если страница 50 читается немедленно, SQL обращается к данным строки на странице:

(1) Он будет немедленно добавлен к главе нового поколения;

(2) Страницы нового поколения будут втиснуты в старое поколение, и в настоящее время никакие страницы не будут действительно устранены;

Усовершенствованный буферный пул LRU может очень хорошо решить проблему «ошибки упреждающего чтения».

Голос за кадром: Но не отказывайтесь от еды из-за того, что поперхнулись, и отменяйте стратегию предварительного чтения, опасаясь провала предварительного чтения.В большинстве случаев действует принцип локальности, а предварительное чтение эффективно. *

Усовершенствованные LRU нового и старого поколения по-прежнему не могут решить проблему загрязнения буферного бассейна.

Что такое загрязнение буферного пула MySQL?

Когда определенный оператор SQL должен сканировать большой объем данных в пакетах, это может привести к замене всех страниц в пуле буферов, что приведет к выгрузке большого количества горячих данных и резкому падению производительности MySQL. называется загрязнением буферного пула.

Например, есть пользовательская таблица с большим объемом данных, при выполнении:

select * from user where name like "%shenjian%";

Хотя результирующий набор может содержать только небольшой объем данных, этот тип лайка не может попасть в индекс, и требуется полное сканирование таблицы, что требует доступа к большому количеству страниц:

(1) Добавьте страницу в пул буферов (вставьте заголовок старого поколения);

(2) Прочитайте соответствующую строку со страницы (вставьте заголовок нового поколения);

(3) Поле имени в строке сравнивается со строкой shenjian и, если оно удовлетворяет условиям, добавляется в набор результатов;

(4)...пока не будут отсканированы все строки на всех страницах...

Таким образом, все страницы данных будут загружены в голову молодого поколения, но будут доступны только один раз, а настоящие горячие данные будут выгружены в больших количествах.

В чем проблема загрязнения буферного пула из-за сканирования такого большого объема данных?

Пул буферов MySQL добавляет механизм «временного окна пребывания старого поколения»:

(1) Предположим, что T = временное окно пребывания старого поколения;

(2) Страница, вставленная в шапку старого поколения, даже если к ней немедленно обратиться, не будет помещена сразу в шапку нового поколения;

(3) толькоудовлетворить«Посещение» и «время пребывания в старом поколении» больше Т, будет ли оно помещено в голову нового поколения;

Продолжая пример, если пакетные данные сканируются, пять страниц, таких как 51, 52, 53, 54 и 55, будут последовательно доступны.

Если нет стратегии «временного окна пребывания старого поколения», эти страницы, к которым обращаются в пакетном режиме, будут обмениваться большим объемом горячих данных.

После добавления стратегии «Окно времени ожидания старого поколения» страницы, которые много загружаются в течение короткого периода времени, не будут сразу вставлены в заголовок нового поколения, но те страницы, к которым обращаются только один раз за короткий период времени, будут быть устранены в первую очередь.

И только если он останется в старом поколении достаточно долго и время пребывания больше T, он будет вставлен в голову нового поколения.

Каким параметрам соответствуют вышеуказанные принципы в InnoDB?

Есть еще три важных параметра.

параметр:innodb_buffer_pool_size

вводить: Настройка размера пула буферов.Когда позволяет память, DBA часто рекомендует увеличить этот параметр.Чем больше данных и индексов помещается в память, тем лучше будет производительность базы данных.

параметр:innodb_old_blocks_pct

вводить: Отношение длины старого поколения к длине всей цепочки LRU, по умолчанию 37, то есть отношение длины молодого поколения к старому поколению во всей LRU равно 63:37.

Голос за кадром: Если вы установите для этого параметра значение 100, он превратится в обычный LRU.

параметр:innodb_old_blocks_time

вводить: Окно времени пребывания в старом поколении, единица измерения миллисекунды, по умолчанию 1000, то есть если выполняются оба условия "посещение" и "пребывание в старом поколении более 1 секунды", оно будет вставлено в голову нового поколения.

Суммировать

(1) Буферный пул — это своего родаОбщие механизмы сокращения доступа к диску;

(2) Буферный пул обычноКэшировать данные в единицах страниц;

(3) буферного пулаОбщий алгоритм управления — LRU., memcache, OS, InnoDB используют этот алгоритм;

(4) InnoDB оптимизирует обычные LRU:

  • Разделите буферный пул наСтарое и новое поколения, страницы, введенные в пул буферов, сначала попадают в старое поколение, а доступ к странице осуществляется перед входом в новое поколение, чтобы решить проблему сбоя упреждающего чтения.
  • страница доступна и находится в старом поколенииВремя ожидания превышает настроенный порогвойти в новое поколение, чтобы решить проблему пакетного доступа к данным и устранить большое количество горячих данных

идеи, важнее, чем вывод.

Какая проблема решена, более важно, чем решение.