Архитектура MySQL очень отличается от архитектур иных серверов баз данных, что делает эту СУБД полезной для одних целей, но одновременно неудачным выбором для других. MySQL неидеальна, но достаточно гибка для того, чтобы хорошо работать в очень требовательных средах, например в веб-приложениях. В то же время MySQL позволяет применять встраиваемые приложения, хранилища данных, индексирование содержимого, программное обеспечение для доставки, высоконадежные системы с резервированием, обработку транзакций в реальном времени (OLTP) и многое другое.
Для того чтобы максимально эффективно использовать MySQL, нужно разобраться в ее устройстве. Гибкость системы проявляется во многом. Например, вы можете настроить ее для работы на различном оборудовании и поддержки разных типов данных. Однако самой необычной и важной особенностью MySQL является такая архитектура подсистемы хранения, в которой обработка запросов и другие серверные задачи отделены от хранения и извлечения данных. Подобное разделение задач позволяет выбирать способ хранения данных, а также настраивать производительность, ключевые характеристики и др.
В текущей главе сделан краткий обзор архитектуры сервера MySQL, рассматриваются основные различия между подсистемами хранения и говорится о том, почему эти различия важны. В конце главы мы рассмотрим исторический контекст и перечислим эталонные тесты производительности (бенчмарки). Попытаемся объяснить MySQL на примерах и максимально упрощая детали. Этот обзор будет полезен как для новичков в работе с сервером баз данных, так и для читателей, которые являются экспертами в работе с подобными системами.
Логическая архитектура MySQL
Чтобы хорошо понимать работу сервера, нужно иметь представление о взаимодействии его компонентов. На рис. 1. представлен логический вид архитектуры MySQL.
Рис. 1. Логический вид архитектуры сервера MySQL
На верхнем уровне располагаются службы, не являющиеся уникальными компонентами MySQL. Они необходимы большинству сетевых клиент-серверных инструментов или серверов: для обслуживания соединений, аутентификации, обеспечения безопасности и т. п.
Второй уровень намного интереснее. Здесь находится большая часть «мозгов» MySQL: код для обработки, анализа, оптимизации и кэширования запросов, а также все встроенные функции (например, функции даты/времени, математические и функции шифрования). Здесь также расположены все инструменты, используемые в подсистемах хранения, например хранимые процедуры, триггеры и представления.
Третий уровень содержит подсистемы хранения данных. Они отвечают за хранение всех данных в MySQL и их извлечение. Подобно различным файловым системам, доступным для GNU/Linux, каждая подсистема хранения данных имеет как сильные, так и слабые стороны. Сервер взаимодействует с ними через API подсистемы хранения данных. Этот интерфейс скрывает различия между такими подсистемами и делает их практически прозрачными на уровне запросов. API содержит пару десятков низкоуровневых функций, выполняющих операции типа «начать транзакцию» или «извлечь строку с таким первичным ключом». Подсистемы хранения не анализируют Запросы SQL и не взаимодействуют друг с другом, они просто отвечают на исходящие от сервера запросы.
Управление соединениями и их безопасность
Для каждого клиентского соединения внутри серверного процесса выделяется отдельный поток. Запросы соединения выполняются только внутри этого потока, который, в свою очередь, выполняется одним ядром или процессором. Сервер кэширует потоки, поэтому их не нужно создавать или уничтожать для каждого нового соединения.
Когда клиенты (приложения) подключаются к серверу MySQL, он должен их аутентифицировать. Аутентификация выполняется на основе имени пользователя, адреса хоста, с которого происходит соединение, и пароля. При соединении по протоколу Secure Sockets Layer (SSL
) можно использовать сертификаты Х.509. После того как клиент подключился, сервер проверяет наличие необходимых привилегий для каждого запроса (например, может ли клиент использовать команду SELECT
применительно к таблице Country базы данных world).
Оптимизация и выполнение
MySQL анализирует запросы для создания внутренней структуры (дерева разбора), а затем выполняет оптимизации. Это могут быть переписывание запроса, определение порядка чтения таблиц, выбор используемых индексов и т. п. Через специальные ключевые слова в запросе вы можете передать оптимизатору подсказки и тем самым повлиять на процесс принятия решения. Или обратиться к серверу за объяснением различных аспектов оптимизации. Это позволит вам понять, какие решения принимает сервер, и даст ориентир для изменения запросов, схем и настроек, чтобы добиться максимальной эффективности работы.
Оптимизатору неважно, в какой подсистеме хранения данных находится конкретная таблица, но подсистема хранения данных влияет на то, как сервер оптимизирует запрос. Оптимизатор опрашивает подсистему хранения данных о некоторых ее возможностях, затратах на выполнение определенных операций и статистике по содержащимся в таблицах данным. Например, отдельные подсистемы хранения поддерживают типы индексов, которые могут быть полезны для выполнения определенных запросов.
Прежде чем анализировать запрос, сервер обращается к кэшу запросов, в котором могут храниться только команды SELECT
вместе с наборами результатов. Если поступает запрос, идентичный уже имеющемуся в кэше, серверу не нужно выполнять анализ, оптимизацию или сам запрос — он может просто отправить в ответ сохраненный набор результатов.