Базы данных Oracle - статьи

         

Способы оптимизации


По большому счету, присутствие блокировок в программном обеспечении – это дань одномерной архитектуре и однопроцессорному мышлению. Принципиально изменить ситуацию может только изобретение новых принципов функционирования и архитектуры ЭВМ. Возможно ЭВМ, специализированных под обработку баз данных и конкретные СУБД. Идея аппаратного ускорителя для СУБД Oracle уже назрела и требует своей реализации.

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

Поскольку за каждым запросом блокировки следует ее отмена по тому же адресу, то команды запроса блокировки и ее отмены всегда существуют парами и обращаются к одному и тому же адресу. Таким образам эта пара:

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

Таким образом, узел ЦПУ - “прогнозировщик блокировок” будет динамически идентифицировать начало и конец критической секции с целью оптимизации блокирования.


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

В ОС Solaris, начиная с 7 версии, появилось понятие adaptive mutex. В этом случае процесс, прежде чем запросить блокировку, проверяет, удерживает ли ее какой-нибудь другой процесс, и если да, то первый процесс проверяет, находится ли удерживающий процесс на процессоре или нет. Если процесс, удерживающий блокировку, выполняется на процессоре, то запрашивающий процесс переходит к стандартному алгоритму – в цикле выполняет TSL. Если удерживающий процесс не находится на процессоре, то запрашивающий процесс освобождает свой процессор и переходит в состояние ожидания.

В качестве еще одной оптимизации в ОС Solaris процессу, удерживающему блокировку, дается дополнительный квант процессорного времени, чтобы он как можно быстрее освободил эту блокировку. Используются ли эти технологии в СУБД Oracle мне пока не известно.

Справедливым возражением, относительно единого и универсального параметра _spin_count будет сказать, что не все блокировки одинаково длительны. Для того чтобы правильно настроить ожидание за защелку, следует знать особенности каждой конкретной защелки, то есть разные защелки могут иметь существенно разное среднее время удержания. В связи с этим вызывает сомнение, что один единственный параметр будет достаточным для всех защелок в СУБД. На месте разработчиков Oracle я бы, вероятно, для каждой защелки (или для каждого класса защелок с похожим поведением) определил свой параметр _spin_count.


Содержание раздела