Date

MySQL Proxy got a bunch of changes in the svn-repo over the last weeks. Most of the important changes are in and we are working on making it a good 0.7.0 release.

The important changes are:

  • script cache to improve the proxy performance
  • central low-level decoding + lua wrappers
  • plugins for proxy, admin and debug
  • admin plugin is now lua based (more flexible)
  • improved test coverage
  • close a connection where we did throw a assertion before

Script Cache

In 0.7.0 we added a script-cache to only reload a script when it has changed and use a byte-cached version of it if it is unchanged.

This speeds up all script functionality quite nicely. No extra compile step as we did in 0.6.x when a connection was opened.

Plugins

We moved the proxy functionality into a plugin that can be loaded at startup as needed. We have at least 3 plugins:

  • proxy
  • admin
  • debug

where proxy is the well known proxy-plugin providing the functionality you already know.

The admin plugin is new in the way it handles your adminstrative queries against the proxy. It loads a lua script and you can use it to add your own queries if the default ones we provide are not sufficient enough.

The most simple admin lua script is:

---
-- handle the administrative commands in the admin-plugin
--
--   PROXY SHOW CONFIG
--   PROXY SET ...
--

local commands     = require("proxy.commands")
local tokenizer    = require("proxy.tokenizer")
local auto_config  = require("proxy.auto-config")
local chassis      = require("chassis")     -- for print() override

function read_query(packet)
    local cmd = commands.parse(packet)

    local r = auto_config.handle(cmd)
    if r then return r end

    -- we only handle normal queries
    if cmd.type ~= proxy.COM_QUERY then
            return
    end

    proxy.response = {
            type = proxy.MYSQLD_PACKET_ERR,
            errmsg = "query isn't understand"
    }
    return proxy.PROXY_SEND_RESULT
end

It is provided as lib/auto-admin.sql and extracts the administrative commands at runtime from the proxy's lua script (take a look at the lib/proxy/auto-config.lua script for more ideas).

Connecting to the admin-port (default is :4041) you can use:

> PROXY SHOW CONFIG;
+--------+-------------------------------+--------+---------+
| module | option                        | value  | type    |
+--------+-------------------------------+--------+---------+
| quan   | auto_explain_min_exec_time_us | 500000 | number  |
| quan   | query_cutoff                  | 160    | number  |
| quan   | analyze_queries               | true   | boolean |
| quan   | auto_explain                  | true   | boolean |
| quan   | num_worst_queries             | 2      | number  |
+--------+-------------------------------+--------+---------+
5 rows in set (0.00 sec)

> PROXY SET GLOBAL quan.analyze_queries = false;
Query OK, 0 rows affected (0.00 sec)

> PROXY SHOW CONFIG;
+--------+-------------------------------+--------+---------+
| module | option                        | value  | type    |
+--------+-------------------------------+--------+---------+
| quan   | auto_explain_min_exec_time_us | 500000 | number  |
| quan   | query_cutoff                  | 160    | number  |
| quan   | analyze_queries               | false  | boolean |
| quan   | auto_explain                  | true   | boolean |
| quan   | num_worst_queries             | 2      | number  |
+--------+-------------------------------+--------+---------+

Low-Level Codec

For the future we are working on improving our low-level encoding/decoding library to handle all MySQL packets in a low-level, fast manner. For now we provide encoders and decoders for:

  • OK, ERR, EOF return packets
  • Auth Challenge/Response packets

Next are a low-level handling of COM_* packets. No more need to decode them by hand.

Test-Coverage

By splitting all the functionality into libraries and plugins at becomes a lot more easier to test each of the pieces independently with unit-testing. For example the packet decoders have a lua-wrapper and we can use lua to test the decoders:

local proto = assert(require("mysql.proto"))
---
-- ok packet

local ok_packet = proto.to_ok_packet({ server_status = 2 })
assert(#ok_packet == 7)
local tbl = proto.from_ok_packet(ok_packet)
assert(tbl.server_status == 2)
assert(tbl.warnings == 0)

-- should fail
assert(false == pcall(
    -- wrong type
    function ()
            proto.from_ok_packet(nil)
    end
))

(taking from tests/unit/lua/mysql-proto.lua)

We also have test-cases for the different multi-host setups with fail-over and load-balancing.

The Alpha Tag

The alpha tag that will appear on 0.7.0 too isn't meaning that is unstable by itself, but that the API may change on the way to the 1.0 release. Things that are part of the core right now may get moved into a plugin, APIs that are available as part of the proxy.* namespace may move moved into a lua-module that you have to load at runtime.

Our goal is the create API that is

  • stable from 1.0
  • clean and consistent
  • fast and flexible

Let's reiterate:

Keep in mind that this is still a alpha version and things may change, get moved into other locations on the way to the 1.0 release.


Comments

Enable javascript to load comments.