Несколько слов о MySQL-proxy

В этой статье я расскажу о MySQL-proxy, специальном прокси-сервере, предназначенном для работы с сервером баз данных MySQL. В отличие от других статей на эту тему, я сделаю некоторые дополнения, касательно работы MySQL-proxy в CentOS 5.x и расскажу о некоторых ограничениях данного инструмента


Автор: Виктор Вислобоков
Лицензия: CC-BY-NC-ND


О возможностях MySQL-proxy

Итак. MySQL-proxy это прокси-сервер, который работает между клиентом сервера MySQL и самим сервером. При этом клиент даже не догадывается, что работает с прокси-сервером, а не с самим сервером MySQL. Вы можете разместить, например, MySQL-proxy на локальном сервере, а сам сервер MySQL на каком-либо другом сервере, а клиент тем не менее будет работать только с локальным сервером, не подозревая об этом. Более того, вы можете в качестве MySQL-сервера указать ещё один MySQL-прокси и это будет работать!

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

  1. Реализация механизма failover. Вы можете указать прокси-серверу более чем один сервер MySQL и в случае если прокси-сервер не получит ответ от первого MySQL-сервера в силу его отказа, для подключения будет использован следующий сервер по указанному списку.
  2. Балансировка нагрузки. Вы можете добиться того, что прокси-сервер будет распределять запросы к MySQL-серверу по нескольким серверам из заданного списка. При этом вы сами можете управлять тем, как это распределение будет осуществляться.
  3. Фильтрация клиентов. Вы можете установить свои собственные условия на работу определённых клиентов, например, запретить работу одних клиентов или организовать подмену одного имени пользователя другим.
  4. Корректировка или преобразование запросов. Вы можете взять исходный запрос, который передаётся от клиента к серверу и сделать с ним практически всё что угодно: откорректировать, заменить своим собственным, отбросить, дополнить.
  5. Корректировка результатов запроса. Вы можете взять ответ MySQL-севрера на запрос и сделать с ним что угодно: изменить, дополнить.
  6. Фильтрация запросов. Вы можете вернуть клиенту результат его запроса минуя обращение к серверу, например если по каким-либо критериям решите, что данный запрос выполнять не нужно.
  7. Протоколирование запросов и/или результатов запросов. Поскольку вы имеете полный доступ как к самому запросу, так и к результатам его выполнения, вы можете протоколировать и то и другое, а также подсчитывать время выполнения запросов.
  8. На любой стадии работы вы можете вызывать внешние программы и действовать в зависимости от полученного после их работы результата.

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

Ограничения MySQL-proxy

Важным замечением, которое сразу же накладывает определённые ограничения на работу схемы

клиент <-> прокси <-> сервер
является работа только по TCP/IP. Т.е. MySQL-proxy не умеет работать через файл сокета.

Ещё одним ограничением, о котором следует упомянуть является работа только с веткой MySQL 5.0.x и выше. Вполне возможно, что MySQL-proxy будет работать и с MySQL 4.1.x, но на официальном сайте MySQL написано, что таковое тестирование не производилось и цель совместимости с MySQL 4.1.x разработчиками не преследовалась!

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

Установка MySQL-proxy

Желающие посмотреть доступные сборки и получить наисвежайшие исходники могут посетить страницу загрузки MySQL-proxy и посмотреть там.

Желающим установить MySQL-proxy на CentOS 5.x могу сразу сказать, что там им ничего не обломится, а предлагаю перейти в конец статьи и либо взять готовые и собранные мной RPM-пакеты, либо там же взять SRPM-пакеты lua и mysql-proxy и собрать их самим. Пакет lua взять из дистрибутива Fedora 10, потому что в CentOS нужной версии нет, а mysql-proxy взять именно версии 0.6.1, потому что 0.7.x у меня не собралась, но если соберёте - честь вам и хвала и не забудьте прислать мне :)

После установки, советую привести в соответствие с вашими условиями конфигурационный файл /etc/sysconfig/mysql-proxy, читайте о настройках ниже.

Настройка MySQL-proxy

Вся настройка MySQL-proxy осуществляется с помощью ключей командной строки. Никаких конфигурационных файлов не предусмотрено. Мы не будем останавливаться на ключах помощи, вы их посмотрите сами (-?, --help и т.д.) Остальные ключи следующие:

--admin-address=host:port
Адрес MySQL-proxy для административных целей (читайте ниже). По умолчанию значение ":4041".
--proxy-address=host:port
Адрес MySQL-proxy для входящих соединений. Именно этот адрес нужно использовать для подключание клиентов. По умолчанию значение ":4040"
--proxy-read-only-backend-addresses=host:port
Адрес подчинённого MySQL сервера, работающего в режиме только для чтения. По умолчанию не задан.
--proxy-backend-addresses=host:port
Адрес MySQL севрера, которому будут передаваться все запросы от клиента. По умолчанию значение "127.0.0.1:3306". Данные ключ может быть указан несколько раз с разными значениями.
--proxy-skip-profiling
Выключение профилирования запросов. По умолчанию включено
--proxy-fix-bug-25371
Исправляет баг #25371 (mysqld > 5.1.12) для старых версий libmysql
--proxy-lua-script=файл
Указывает скрипт на языке lua, для использования его в MySQL-proxy
--no-proxy
Не запускать прокси-сервер
--daemon
Запускает MySQL-proxy в режиме демона (в фоновом режиме)
--pid-file=файл
Указывает местоположения pid-файла (файла содержащего ID процесса) MySQL-proxy

Если вы ставили MySQL-proxy в CentOS из пакета, как было описано в разделе Установка MySQL-proxy, то вы можете снова вернуться к файлу /etc/sysconfig/mysql-proxy и отредактировать его в соответствии с пояснениями по ключам. Остальным предлогается самостоятельно подготовить shell-скрипт для запуска MySQL-proxy.

Административный интерфейс MySQL-proxy

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

Вы можете получить информацию о текущих открытых соединениях MySQL-proxy командой:

mysql> select * from proxy_connections;
+------+--------+-------+------+
| id   | type   | state | db   |
+------+--------+-------+------+
|    0 | server | 0     |      | 
|    1 | proxy  | 0     |      | 
|    2 | server | 10    |      | 
+------+--------+-------+------+
3 rows in set (0.00 sec)

или запросить текущую конфигурацию MySQL-proxy командой:

mysql> select * from proxy_config;
+----------------------------+----------------------+
| option                     | value                |
+----------------------------+----------------------+
| admin.address              | :4041                | 
| proxy.address              | :4040                | 
| proxy.lua_script           | mc.lua               | 
| proxy.backend_addresses[0] | mysql:3306           | 
| proxy.fix_bug_25371        | 0                    | 
| proxy.profiling            | 1                    | 
+----------------------------+----------------------+
6 rows in set (0.01 sec)

Как работает MySQL-proxy

Для реализации вышеописанных возможностей на языке lua для работы выделенн ряд предопределённых функций, каждая их которых запускается в определённое время. Ниже все они перечислены в порядке их выполнения:

connect_server()
Эта функция вызывается в момент установления клиентом соединения с MySQL-proxy сервером. В ней вы можете использовать свои правила для выбора подключения к одному из серверов MySQL, указанных в командной строке. Если никаких правил не задано, то для выбора MySQL-сервера используется алгоритм round-robin.
read_handshake()
Эта функция вызывается, когда MySQL-севрер при подключении к нему возвращает начальную информацию. Вы можете использовать эту информацию для каких-либо дополнительных проверок или условий перед тем как будет запущена авторизация.
read_auth()
Эта функция вызывается когда от клиента к MySQL-серверу передаётся пакет авторизации (имя пользователя, пароль, база данных по умолчанию).
read_auth_result()
Эта функция вызывается когда сервер возвращает пакет авторизации клиенту, чтобы дать ответ о том была ли авторизация пройдена успешно или нет.
read_query()
Эта функция вызывается каждый раз, когда клиент посылает запрос MySQL-серверу. Вы можете использовать её для исправлений и других действий с оригинальным запросом.
read_query_result()
Эта функция вызывается каждый раз, когда MySQL-сервер возвращает результаты запроса клиенту. Вы можете использовать её для различных манипуляций с результатами запроса.

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

Итак, чтобы реализовать все те вкусности, о которых говорилось ранее, необходимо написать собственный lua-скрипт и указать его при запуске MySQL-proxy. Начать писать свои скрипты лучше всего с примеров, которые идут в комплекте к MySQL-proxy. Если вы ставили MySQL-proxy в CentOS из пакета, как было описано в разделе Установка MySQL-proxy, то вы можете найти их в каталоге /usr/share/mysql-proxy.

Заключение

Дополнительную информацию о MySQL-proxy вы можете найти на официальном сайте

ВложениеРазмер
mysql-proxy-0.6.1-3.i386.rpm89.51 kb
mysql-proxy-0.6.1-3.src_.rpm497.32 kb
lua-5.1.4-1.i386.rpm364.63 kb
lua-5.1.4-1.fc10.src_.rpm536.61 kb

Кеширование

С его помощю получится кешировать запросы?

вопросы

Немного не понятно с какими параметрами соединятся, чтобы выполнить запросы:

select * from proxy_connections;
select * from proxy_config;

И еще интересно было бы почитать решение при настройке серверов БД master-master. При падение master1, как при помощи MySQL-proxy переключить мастера на master2, ну и соответственно когда master1 оживает, то вернуть все на круги своя.
Спасибо.

1. С параметрами подключения

1. С параметрами подключения к АДМИНИСТРАТИВНОМУ интерфейсу - читайте ключи командной строки в тексте.
2. Нет такого решения. В статье по-моему довольно ясно описан алгоритм работы: принимается решение о том какой сервер юзать с помощью lua-скрипта, если такового нет, то первый из заданного списка. Если он не ответил - второй и т.д. Балансировку нагрузки опять-таки средствами означенного lua-скрипта.