MySQL -- Подробное объяснение буферного пула InnoDB

MySQL

0 сомнений

  1. Что следует делать при очистке грязных страниц с соответствующими страницами данных, записанными в журнале повторов?
  2. Как InnoDB определяет, является ли страница грязной или чистой? В некоторых статьях говорится, что LSN используется для сравнения с Checkpoint, но лично я понимаю, почему бы не использовать LSN, хранящийся на странице данных, для суждения?
  3. Как удаление грязных страниц из списка LRU связано с грязной очисткой списка FLU? После удаления грязных страниц из списка LRU список FLU удаляет этот узел и добавляет его в список свободных?

1. Введение

В настоящее время механизм хранения MySQL по умолчанию — InnoDB, и разные механизмы хранения имеют разные реализации. Я не знаю, возникают ли у вас такие сомнения, когда вы изучаете базу данных MySQL: если вы непосредственно работаете с диском каждый раз, когда читаете и записываете данные, как гарантировать производительность базы данных?

Чтобы понять эти две проблемы, вы должны понимать буферный пул InnoDB.

2 Введение

MySQL InnoDB Buffer Pool, буферный пул MySQL InnoDB. В нем кэшируется большое количество данных (страниц данных), так что когда ЦП читает или записывает данные, он напрямую не имеет дело с низкоскоростным диском, а напрямую взаимодействует с буфером, таким образом решая проблему плохой производительность базы данных из-за низкой производительности диска.

3 Детали

3.1 Страница данных

В InnoDB наименьшей единицей управления данными является страница, размер которой по умолчанию составляет 16 КБ.

Для подробного ознакомления со страницей данных я рекомендую всем прочитать эту статью, которая очень хорошо написана:Структура страницы данных InnoDB.

3.2 Механизм работы буферного пула

Как упоминалось выше, основная функция буферного пула — ускорить чтение и запись.

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

Ускоренная запись означает, что когда страницу данных нужно изменить, она сначала модифицируется в пуле буферов, и в соответствующий журнал повторов записывается модификация этой страницы. Что касается фактического сброса измененной страницы на диск, то это делается потоком фонового сброса пула буферов.

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

Такая ситуация является плохим случаем, и ее следует максимально избегать, поэтому вам нужно найти способ улучшить частоту попаданий в кэш. Буферный пул innodb использует классический алгоритм LRU для устранения страниц, чтобы улучшить частоту попаданий в кэш. По сравнению с традиционным алгоритмом LRU, средняя позиция списка LRU в буферном пуле отмечена старой меткой, что можно просто понять как разделение списка LRU на две части.Страница данных, помеченная в начале списка LRU называется пулом молодых страниц данных, страница данных, помеченная в конец списка LRU, называется пулом старых страниц данных. Когда страница загружается с диска в буферный пул, она помещается на первую позицию после старого флага, то есть в старый пул (стратегия вставки в среднюю точку). Этот механизм гарантирует, что даже если имеется большое количество новых входящих страниц данных, они будут сохранены в старом пуле при выполнении однократного полного сканирования большой таблицы.Циклическая очистка выполняется в старом пуле, так что горячие страницы в молодом пуле не сбрасываются, тем самым защищая горячие страницы. Это простой механизм алгоритма LRU буферного пула.

3.3 Базовые знания

Кратко представлен механизм работы буферного пула, а затем давайте рассмотрим концепцию экземпляра буферного пула и наиболее важные связанные списки в буферном пуле. Узлы в связанном списке являются не непосредственно страницами данных, а управляющим телом страницы данных (указатель в управляющем теле указывает на настоящую страницу данных).

3.3.1 Buffer Pool Instance

Экземпляр буферного пула с размером, равнымinnodb_buffer_pool_size / innodb_buffer_pool_instances, размер innodb_buffer_pool_instances настраивается. Каждый экземпляр буферного пула имеет собственный замок, семафор, физический блок. То есть между экземплярами нет конкуренции и возможны одновременное чтение и запись. Если размер innodb_buffer_pool_size меньше 1G, будет только один экземпляр.

3.3.2 Buffer Pool Chunk

Экземпляр буферного пула состоит из нескольких блоков. Блок представляет собой непрерывное пространство. Размер каждого блока по умолчанию – 128 МБ, а минимальный – 1 МБ. Это значение может быть динамически настроено в версии 8.0. Buffer Chunk — это самый нижний физический блок, который запрашивается операционной системой на этапе запуска и не освобождается до тех пор, пока база данных не будет закрыта. Блоки буфера в основном хранят страницы данных и тела управления страницами данных. Как показано ниже:

Основная цель разработки тела управления страницей данных — облегчить управление страницей данных, и в теле управления есть указатели, указывающие на страницу данных. InnoDB создает некоторую так называемую управляющую информацию для каждой страницы данных, и между телом управления страницы данных и страницей данных существует однозначное соответствие. Управляющая информация включает в себя номер табличного пространства, которому принадлежит страница, номер страницы, адрес страницы в буферном пуле и так далее. Объем памяти, занимаемый управляющей информацией, соответствующей каждой странице данных, одинаков.

Узлы нескольких связанных списков в пуле буферов, которые будут упомянуты, на самом деле являются контроллерами страниц данных.

3.3.3 Free List

При первоначальном запуске сервера MySQL необходимо завершить инициализацию Пула буферов (выделить пространство памяти Пула буферов) и разделить его на несколько пар блоков управления и страниц кэша. В это время в буферном пуле не кэшируются реальные дисковые страницы (поскольку они еще не использовались), а затем по мере выполнения программы в буферном пуле будут кэшироваться непрерывные дисковые страницы.

Поскольку все страницы данных в только что инициализированном буферном пуле свободны, каждая страница данных будет добавлена ​​в список свободных. быть увеличена.Диаграмма эффекта выглядит так:

Если вам нужно выделить новые страницы данных из базы данных, вы можете получить их непосредственно сверху. InnoDB необходимо обеспечить наличие достаточного количества узлов в свободном списке для использования пользователями, в противном случае некоторые узлы необходимо исключить из списка FLU или списка LRU.

3.3.4 LRU List

Так как назначение буферного пула — ускорить запись и чтение, необходимо найти способ повысить частоту попаданий в кэш страниц данных памяти. InnoDB управляет страницами данных в пуле буферов на основе классического алгоритма LRU. При нормальных обстоятельствах в начале списка хранятся горячие данные, т. е. так называемая молодая страница (данные, к которым в последнее время часто обращались), а в хвосте списка хранятся старые страницы (данные, к которым в последнее время не обращались). .

LRU имеет следующие стандартные алгоритмы:

  1. 3/8 информации списка используется как старый список, и эта информация представляет собой объекты, подлежащие выселению;
  2. Середина списка — это то, что мы называем точкой соединения между головой старого списка и хвостом молодого списка, что эквивалентно границе;
  3. Новые данные сначала вставляются в начало старого списка;
  4. При доступе к данным старого списка информация о странице будет перемещена в начало нового списка, чтобы стать молодой страницей;
  5. В буферном пуле InnoDB, будь то данные молодого списка или старого списка, если к ним не будут обращаться, они в конечном итоге будут перемещены в конец списка как жертва.

При нормальных обстоятельствах информация о странице будет немедленно запрошена оператором запроса и перемещена в молодой список, что означает, что она останется в пуле буферов в течение длительного времени. Сканирование таблиц (включая mysqldump или select без условий where) сбрасывает большой объем данных в пул буферов, а также сбрасывает больше информации из пула буферов, даже если эту операцию можно использовать только один раз.

В конце концов, список LRU представляет собой связанный список, и сложность времени нахождения страниц данных является O (n). Для дальнейшего улучшения производительности чтения и записи и избегайте сканирования списка LRU, на самом деле каждый экземпляр пула буфера имеет ASH HASH. SPAGE_ID и PAGE_NO могут быстро найти страницу данных, которые были прочитаны в память, а не линейно пересекающие список LRU, чтобы найти его. Для структуры данных HASH HASH, см. Архитектурную диаграмму буферного пула InnoDB в сводном модуле.

3.3.5 Flush List

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

грязные страницы: когда содержимое страницы данных памяти и страницы данных диска несовместимо, страница данных называется «грязной страницей». После записи данных памяти на диск содержимое страницы данных в памяти и на диске совпадает, что называется «чистой страницей». В памяти хранятся как грязные, так и чистые страницы.

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

Так как грязные страницы не сбрасываются синхронно немедленно, мы должны создать еще один связанный список, чтобы сохранить грязные страницы. Все страницы, которые были изменены в списке LRU, должны быть добавлены в этот связанный список. Все узлы в этом связанном списке являются грязными страницами, поэтому он также называется Flush List, который обычно сокращается как FLU List.

Модификация грязной страницы здесь означает, что страница модифицируется в первый раз после ее загрузки в буферный пул, и ее нужно добавить в список FLU только при первом изменении (код основан на самая старая модификация == 0 в заголовке страницы, чтобы определить, является ли она первой модификацией), если страница будет изменена снова, она не будет помещена в список FLU, потому что она уже существует. Следует отметить, что данные грязных страниц фактически все еще находятся в списке LRU, а записи грязных страниц в списке FLU просто указывают на грязные страницы в списке LRU через указатель (То есть страница в Списке FLU должна быть в Списке LRU, и наоборот).

Страница данных может быть изменена несколько раз в разное время, и самый старый или первый измененный номер LSN, т.е. самая старая_модификация, записывается на странице данных. Разные страницы данных имеют разные old_modification,Узлы в списке FLU сортируются в соответствии с самой старой_модификацией, а хвост связанного списка является наименьшим, что является самой ранней измененной страницей данных.. Когда страницу необходимо исключить из списка FLU, она удаляется из конца связанного списка. Чтобы присоединиться к списку FLU, вам необходимо использовать защиту flush_list_mutex, чтобы можно было гарантировать порядок узлов в списке FLU.

Хотя грязные страницы существуют как в списке LRU, так и в списке FLU, список LRU используется для управления доступностью страниц в пуле буферов, а список FLU используется для управления сбросом грязных страниц обратно на диск, а эти два не влияют друг на друга.

3.3.6 Разогрев буферного пула

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

Чтобы сократить процесс прогрева, перед выключением MySQL сохраните информацию о странице в пуле буферов на диск, а при запуске MySQL загрузите данные с диска в пул буферов в соответствии с ранее сохраненной информацией.

3.3.7 Резюме

Отношения между этими тремя важными связанными списками (Free List, LRU List, FLU List) можно представить на следующем рисунке:

Отношения между Free List и LRU List представляют собой взаимную циркуляцию, и страницы заменяются туда и обратно между двумя связанными списками. Данные грязной страницы записываются в список FLUSH, то есть указатель указывает на список LRU, поэтому список FLU на рисунке обертывается списком LRU.

3.4 Механизм доступа к странице данных

Разберем процесс доступа к странице данных.

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

Однако бывает ситуация, когда свободные страницы памяти израсходованы, и нет гарантии, что должны быть свободные страницы памяти. Если Free List пуст, вам нужно как можно скорее найти способ сгенерировать свободные страницы памяти.

Сначала перейдите в список LRU, чтобы найти заменяемую страницу памяти (чистую страницу).Направление поиска должно начинаться с конца связанного списка.После того, как заменяемая страница будет найдена, она будет удалена из списка LRU, добавить в список свободных, а затем перейти к списку свободных.Найти в списке свободные страницы памяти. Первый поиск сканирует не более 100 страниц, а когда цикл переходит ко второму разу, глубина поиска составляет весь список LRU. Если страница, которую можно заменить, не найдена в списке LRU, выполняется сброс одной страницы (взятой из списка FLU), и грязная страница сбрасывается на диск перед добавлением ее в список свободных. Это механизм исключения страниц LRU в InnoDB. Почему обновляется только одна страница? Поскольку его целью является получение свободных страниц памяти как можно скорее, сброс грязных страниц является крайней мерой, поэтому сбрасывается только одна страница.

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

При выполнении оператора SQL, если необходимо очистить одну страницу, выполнение оператора SQL займет больше времени, чем ожидалось. Иногда это выглядит так, как будто база данных «трясется», что также является плохим случаем. насколько это возможно.

Благодаря механизму доступа к странице данных стало известно, что создание свободной страницы, когда свободной страницы нет, стало обязательным. Если необходимо создать свободные страницы путем сброса грязных страниц, время поиска свободных страниц будет увеличено. Поэтому в буферном пуле innodb находится большое количество заменяемых страниц, либо в Free List всегда есть свободные страницы памяти, что играет решающую роль в быстром получении свободных страниц памяти.

Какой метод используется в буферном пуле innodb для создания свободных страниц памяти и заменяемых страниц памяти? Вот о чем мы поговорим дальше — о стратегии обновления грязной страницы.

3.5 Стратегия обновления грязной страницы (список FLU)

3.5.0 Преамбула

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

существует3.4 Механизм доступа к странице данныхВ этом разделе обнаружено, что когда свободного списка недостаточно, грязные страницы в списке LRU также будут исключены.Одна страница в LRU грязная для создания свободных страниц, а список FLU грязный, чтобы гарантировать, что там достаточно свободных страниц Эти два пункта Обратите внимание на различие.

Грязные статьи:

3.5.1 Время расчесывать грязь

InnoDB сбрасывает грязные страницы в следующих четырех случаях:

  1. MySQL считает, что система простаивает;
  2. MySQL завершает работу нормально;
  3. Недостаточный список свободных мест;
  4. Журнал повторов заполнен.

Первые два мало влияют на производительность.

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

3.5.2 Грязная скорость чистки

Грязная скорость InnoDB в основном связана со следующими факторами:

  • Дисковые IOPS: как быстро InnoDB может очищать грязные страницы
  • Скорость записи журнала повторов:N = (write pos 对应的 LSN - Checkpoint 对应的 LSN),当 N 越大,刷脏速度越快
  • Доля грязных страниц в пуле буферов: значение по умолчанию 75%.

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

innodb_io_capacity: это ключевой параметр InnoDB, который используется для информирования InnoDB о емкости вашего диска (в настоящее время InnoDB не имеет возможности самостоятельно получать размер дисковых IOPS), это значение обычно рекомендуется устанавливать равным IOPS записи диска. . Когда параметр innodb_io_capacity слишком мал, InnoDB будет думать, что производительность диска низкая, что приводит к очень медленной очистке грязных страниц, даже медленнее, чем скорость генерации грязных страниц, что приведет к накоплению грязных страниц и повлияет на производительность запросов и обновлений. .

Настройка размера innodb_io_capacity:

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

innodb_max_dirty_pages_pct: Этот параметр относится к верхнему пределу коэффициента грязных страниц (значение по умолчанию — 75%). Чем ближе коэффициент грязных страниц в памяти к этому значению, тем ближе скорость загрязнения InnoDB будет к полной силе.

Блок-схема может лучше проиллюстрировать взаимосвязь между частотой грязных страниц, коэффициентом грязных страниц и скоростью записи журнала повторов:

F1 и F2 - это два значения, рассчитанные на основе коэффициента грязных страниц и скорости записи журнала повторов, описанных выше.Затем движок берет большее значение и записывает его как R, и, наконец, умножает способность, определенную innodb_io_capacity, на R%, чтобы контролировать очистка грязных страниц скорость.

3.5.3 Обновление соседних страниц

innodb_flush_neighbors: значение 1 означает непрерывную очистку грязных страниц, 0 означает очистку только своих собственных.

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

В InnoDB для управления этим поведением используется параметр innodb_flush_neighbors.При значении 1 будет работать упомянутый выше механизм «подключения».При значении 0 означает, что он не находит соседние страницы и сбрасывает свои собственные .

Оптимизация поиска «соседей» имеет большое значение в эпоху механических жестких дисков, которые могут уменьшить количество случайных операций ввода-вывода. Случайные операции ввода-вывода механических жестких дисков обычно составляют всего несколько сотен.Уменьшение случайных операций ввода-вывода означает значительное улучшение производительности системы. Если вы используете устройство с высоким IOPS, такое как SSD, рекомендуется установить значение innodb_flush_neighbors равным 0. Потому что IOPS часто не является узким местом в это время, и «только самоочистка» может выполнять необходимые операции очистки грязных страниц быстрее, уменьшая время отклика операторов SQL.

В MySQL 8.0 значение параметра innodb_flush_neighbors по умолчанию уже равно 0.

4 справочника чтения

  1. [Забавный MySQL № 10] InnoDB Buffer Pool Подробное объяснение
  2. Введение в реализацию пула памяти MySQL Innodb
  3. MySQL Engine включает буферный пул InnoDB
  4. Статья для понимания механизма хранения InnoDB