Spec-Zone .ru
спецификации, руководства, описания, API
|
К интерфейсу администрирования mysql-прокси можно получить доступ, используя любой клиент MySQL, использующий стандартные протоколы. Можно использовать интерфейс администрирования, чтобы получить информацию о прокси-сервере в целом - стандартные соединения с прокси изолируются, чтобы работать, как будто Вы были соединены непосредственно с сервером MySQL бэкэнда.
В mysql-прокси 0.8.0 и ранее, элементарный интерфейс был встроен в прокси. В более поздних версиях это было заменено так, чтобы Вы определили сценарий администрирования, который будет использоваться, когда пользователи соединяются с интерфейсом администрирования.
Чтобы использовать интерфейс администрирования, определите имя пользователя и пароль, требуемый соединяться с
администраторской службой, используя --admin-username
и --admin-password
опции. Следует также определить сценарий Lua, который будет
использоваться в качестве интерфейса к службе администрирования при использовании admin-lua-script
опция сценария, чтобы указать на сценарий Lua.
Например, можно создать основной интерфейс к внутренним компонентам системы mysql-прокси, используя следующий сценарий, записанный Диего Мединой:
--[[ Copyright 2008, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA--]]-- admin.lua--[[ See http://www.chriscalender.com/?p=41 (Thanks to Chris Calender) See http://datacharmer.blogspot.com/2009/01/mysql-proxy-is-back.html (Thanks Giuseppe Maxia)--]]function set_error(errmsg) proxy.response = { type = proxy.MYSQLD_PACKET_ERR, errmsg = errmsg or "error" }endfunction read_query(packet) if packet:byte() ~= proxy.COM_QUERY then set_error("[admin] we only handle text-based queries (COM_QUERY)") return proxy.PROXY_SEND_RESULT end local query = packet:sub(2) local rows = { } local fields = { } -- try to match the string up to the first non-alphanum local f_s, f_e, command = string.find(packet, "^%s*(%w+)", 2) local option if f_e then -- if that match, take the next sub-string as option f_s, f_e, option = string.find(packet, "^%s+(%w+)", f_e + 1) end -- we got our commands, execute it if command == "show" and option == "querycounter" then --- -- proxy.PROXY_SEND_RESULT requires -- -- proxy.response.type to be either -- * proxy.MYSQLD_PACKET_OK or -- * proxy.MYSQLD_PACKET_ERR -- -- for proxy.MYSQLD_PACKET_OK you need a resultset -- * fields -- * rows -- -- for proxy.MYSQLD_PACKET_ERR -- * errmsg proxy.response.type = proxy.MYSQLD_PACKET_OK proxy.response.resultset = { fields = { { type = proxy.MYSQL_TYPE_LONG, name = "query_counter", }, }, rows = { { proxy.global.query_counter } } } -- we have our result, send it back return proxy.PROXY_SEND_RESULT elseif command == "show" and option == "myerror" then proxy.response.type = proxy.MYSQLD_PACKET_ERR proxy.response.errmsg = "my first error" return proxy.PROXY_SEND_RESULT elseif string.sub(packet, 2):lower() == 'select help' then return show_process_help() elseif string.sub(packet, 2):lower() == 'show proxy processlist' then return show_process_table() elseif query == "SELECT * FROM backends" then fields = { { name = "backend_ndx", type = proxy.MYSQL_TYPE_LONG }, { name = "address", type = proxy.MYSQL_TYPE_STRING }, { name = "state", type = proxy.MYSQL_TYPE_STRING }, { name = "type", type = proxy.MYSQL_TYPE_STRING }, } for i = 1, #proxy.global.backends do local b = proxy.global.backends[i] rows[#rows + 1] = { i, b.dst.name, b.state, b.type } end else set_error() return proxy.PROXY_SEND_RESULT end proxy.response = { type = proxy.MYSQLD_PACKET_OK, resultset = { fields = fields, rows = rows } } return proxy.PROXY_SEND_RESULTendfunction make_dataset (header, dataset) proxy.response.type = proxy.MYSQLD_PACKET_OK proxy.response.resultset = { fields = {}, rows = {} } for i,v in pairs (header) do table.insert(proxy.response.resultset.fields, {type = proxy.MYSQL_TYPE_STRING, name = v}) end for i,v in pairs (dataset) do table.insert(proxy.response.resultset.rows, v ) end return proxy.PROXY_SEND_RESULTendfunction show_process_table() local dataset = {} local header = { 'Id', 'IP Address', 'Time' } local rows = {} for t_i, t_v in pairs (proxy.global.process) do for s_i, s_v in pairs ( t_v ) do table.insert(rows, { t_i, s_v.ip, os.date('%c',s_v.ts) }) end end return make_dataset(header,rows)endfunction show_process_help() local dataset = {} local header = { 'command', 'description' } local rows = { {'SELECT HELP', 'This command.'}, {'SHOW PROXY PROCESSLIST', 'Show all connections and their true IP Address.'}, } return make_dataset(header,rows)endfunction dump_process_table() proxy.global.initialize_process_table() print('current contents of process table') for t_i, t_v in pairs (proxy.global.process) do print ('session id: ', t_i) for s_i, s_v in pairs ( t_v ) do print ( '\t', s_i, s_v.ip, s_v.ts ) end end print ('---END PROCESS TABLE---')end--[[ Helpwe use a simple string-match to split commands are word-boundariesmysql> show querycounteris split intocommand = "show"option = "querycounter"spaces are ignored, the case has to be as is.mysql> show myerrorreturns a error-packet--]]
Сценарий работает в комбинации с основным сценарием прокси, reporter.lua
:
--[[ Copyright 2008, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA--]]-- reporter.lua--[[ See http://www.chriscalender.com/?p=41 (Thanks to Chris Calender) See http://datacharmer.blogspot.com/2009/01/mysql-proxy-is-back.html (Thanks Giuseppe Maxia)--]]proxy.global.query_counter = proxy.global.query_counter or 0function proxy.global.initialize_process_table() if proxy.global.process == nil then proxy.global.process = {} end if proxy.global.process[proxy.connection.server.thread_id] == nil then proxy.global.process[proxy.connection.server.thread_id] = {} endendfunction read_auth_result( auth ) local state = auth.packet:byte() if state == proxy.MYSQLD_PACKET_OK then proxy.global.initialize_process_table() table.insert( proxy.global.process[proxy.connection.server.thread_id], { ip = proxy.connection.client.src.name, ts = os.time() } ) endendfunction disconnect_client() local connection_id = proxy.connection.server.thread_id if connection_id then -- client has disconnected, set this to nil proxy.global.process[connection_id] = nil endend----- read_query() can return a resultset---- You can use read_query() to return a result-set.---- @param packet the mysql-packet sent by the client---- @return-- * nothing to pass on the packet as is,-- * proxy.PROXY_SEND_QUERY to send the queries from the proxy.queries queue-- * proxy.PROXY_SEND_RESULT to send your own result-set--function read_query( packet ) -- a new query came in in this connection -- using proxy.global.* to make it available to the admin plugin proxy.global.query_counter = proxy.global.query_counter + 1end
Чтобы использовать сценарий, сохраните первый сценарий к файлу (admin.lua
в
следующем примере) и другой к reporter.lua
, тогда выполненный mysql-прокси, определяющий администраторский сценарий и
сервер MySQL бэкэнда:
shell>mysql-proxy --admin-lua-script=admin.lua --admin-password=password \ »
--admin-username=root --proxy-backend-addresses=127.0.0.1:3306 -proxy-lua-script=reporter.lua
В различном окне соединитесь с сервером MySQL через прокси:
shell> mysql --user=root --password=password
--port=4040
Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 1798669Server version: 5.0.70-log Gentoo Linux mysql-5.0.70-r1Type 'help;' or '\h' for help. Type '\c' to clear the buffer.mysql>
В другом различном окне соединитесь с администраторской службой mysql-прокси, используя указанное имя пользователя и пароль:
shell> mysql --user=root --password=password
--port=4041 --host=localhost
Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 1Server version: 5.0.99-agent-adminType 'help;' or '\h' for help. Type '\c' to clear the buffer.mysql>
Чтобы контролировать состояние прокси, попросите список текущих активных процессов:
mysql> show proxy processlist;
+---------+---------------------+--------------------------+| Id | IP Address | Time |+---------+---------------------+--------------------------+| 1798669 | 192.168.0.112:52592 | Wed Jan 20 16:58:00 2010 | +---------+---------------------+--------------------------+1 row in set (0.00 sec)mysql>
Для получения дополнительной информации по примеру см.