+ All Categories
Home > Documents > Advanced Lua Scripting - MySQL Proxy

Advanced Lua Scripting - MySQL Proxy

Date post: 13-Nov-2014
Category:
Upload: mikhail-miguel
View: 2,433 times
Download: 9 times
Share this document with a friend
54
MySQL Proxy Advanced Lua scripting Giuseppe Maxia, MySQL Community Team Lead, Sun Microsystems Database Group This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.
Transcript
Page 1: Advanced Lua Scripting - MySQL Proxy

MySQL ProxyAdvanced Lua scripting

Giuseppe Maxia, MySQL Community Team Lead, Sun MicrosystemsDatabase Group

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

Page 2: Advanced Lua Scripting - MySQL Proxy

basic principles

Page 3: Advanced Lua Scripting - MySQL Proxy

basic principles

PROXY CORE

connection hook

read query hook

read result hook

function

Lua script

function

functionfunctionfunction

Page 4: Advanced Lua Scripting - MySQL Proxy

Proxy - Lua overview

connect_server

Lua script

read_auth

read_auth_result

read_handshake

read_query

read_query_result

disconnect_client

global context

session contextsession

contextsession contextsession

contextsession contextsession

contextsession context

Page 5: Advanced Lua Scripting - MySQL Proxy

Using Lua Files/usr/local/sbin/mysql-proxy \ --proxy-lua-script=/path/name.lua

IMPORTANT!THE SCRIPT DOES NOT START UNTIL THE FIRST

CLIENT CONNECTION

Page 6: Advanced Lua Scripting - MySQL Proxy

intercepting

function read_query(packet) if packet:byte() == proxy.COM_QUERY then local query = packet:sub(2) print("Hello world! Seen query: " .. query ) endend

Page 7: Advanced Lua Scripting - MySQL Proxy

injecting queries

Page 8: Advanced Lua Scripting - MySQL Proxy

injecting queries

Page 9: Advanced Lua Scripting - MySQL Proxy

injecting queries

function read_query(packet) -- ... proxy.queries:append(2, query1 ) proxy.queries:append(1, packet ) proxy.queries:append(3, query2 )

return proxy.PROXY_SEND_QUERY

end

Page 10: Advanced Lua Scripting - MySQL Proxy

injecting queries

function read_query_result(inj) if inj.id == 1 then return -- default result else -- do something

return proxy.PROXY_IGNORE_RESULTend

Page 11: Advanced Lua Scripting - MySQL Proxy

working with results

• return the original result

• return a fake result

• return an error

• alter the original result

• return something different (affected/retrieved)

Page 12: Advanced Lua Scripting - MySQL Proxy

debugging

•Put a Proxy in between

•use a sensible script to see what's going on (e.g. tutorial-packets.lua or tutorial-states.lua)

Page 13: Advanced Lua Scripting - MySQL Proxy

debugging

server

client

proxy

diagnosticstext

Page 14: Advanced Lua Scripting - MySQL Proxy

debugging scripts

server

client

proxy

diagnosticstext

proxy

diagnosticstext

Page 15: Advanced Lua Scripting - MySQL Proxy

chained proxy: double features

server

proxy

pivot tablesproxy

loopsclient

Page 16: Advanced Lua Scripting - MySQL Proxy

testing

server

client

proxy

fake packetse.g.

connectors

Page 17: Advanced Lua Scripting - MySQL Proxy

MySQL Proxy recipes

Page 18: Advanced Lua Scripting - MySQL Proxy

cookbook: returning a simple dataset

Page 19: Advanced Lua Scripting - MySQL Proxy

cookbook: returning a simple datasetfunction simple_dataset (header, message)proxy.response.type = proxy.MYSQLD_PACKET_OKproxy.response.resultset = { fields = { {type = proxy.MYSQL_TYPE_STRING, name = header} }, rows = { { message} }}return proxy.PROXY_SEND_RESULTend

Page 20: Advanced Lua Scripting - MySQL Proxy

cookbook: returning a full dataset

Page 21: Advanced Lua Scripting - MySQL Proxy

cookbook: returning a full datasetfunction 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_RESULTend

Page 22: Advanced Lua Scripting - MySQL Proxy

cookbook: returning a full dataset

return make_dataset( {'command', 'description' }, -- the header { -- the rows {'FOO', 'removes the database'}, {'BAR', 'drops all tables'}, {'FOOBAR', 'makes the server explode'}, })

Page 23: Advanced Lua Scripting - MySQL Proxy

cookbook: returning an error

Page 24: Advanced Lua Scripting - MySQL Proxy

cookbook: returning an error

function error_result (msg, code,state) proxy.response = { type = proxy.MYSQLD_PACKET_ERR, errmsg = msg, errcode = code, sqlstate = state, } return proxy.PROXY_SEND_RESULTend

Page 25: Advanced Lua Scripting - MySQL Proxy

cookbook: returning a non dataset result

ok. you changed 42 lines

Page 26: Advanced Lua Scripting - MySQL Proxy

cookbook: returning a non dataset result

function affected_rows (rows,id) proxy.response = { type = proxy.MYSQLD_PACKET_OK, affected_rows = rows, insert_id = id, } return proxy.PROXY_SEND_RESULTend

Page 27: Advanced Lua Scripting - MySQL Proxy

cookbook: debug messages

got that query, blah, blah

proxy terminal screen

Page 28: Advanced Lua Scripting - MySQL Proxy

cookbook: debug messageslocal DEBUG = os.getenv('DEBUG') or 0DEBUG = DEBUG + 0

function read_query (packet ) if packet:byte() ~= proxy.COM_QUERY then return end print_debug(packet:sub(2),1) print_debug('inside read_query', 2)end

function print_debug(msg, level) level = level or 1 if DEBUG >= level then print (msg) endend

Page 29: Advanced Lua Scripting - MySQL Proxy

cookbook: verbose level at run timelocal DEBUG = os.getenv('DEBUG') or 0DEBUG = DEBUG + 0

function read_query (packet ) if packet:byte() ~= proxy.COM_QUERY then return end local vlevel=query:match('^VERBOSE=(%d)$') if vlevel then DEBUG = vlevel+0 return simple_dataset('verbose',vlevel) endend

Page 30: Advanced Lua Scripting - MySQL Proxy

cookbook: keep info inside a session

my variable value

proxy script

my variable valuemy variable value

Page 31: Advanced Lua Scripting - MySQL Proxy

cookbook: keep info inside a session

nothing to do :) Proxy scripts have session scope by defaultlocal tot_q = 0

function read_query (packet ) if packet:byte() ~= proxy.COM_QUERY then return end tot_q = tot_q + 1 print('queries ' .. tot_q)end

Page 32: Advanced Lua Scripting - MySQL Proxy

cookbook: share info among sessions

my variable value

proxy script

Page 33: Advanced Lua Scripting - MySQL Proxy

cookbook: share info among sessions

proxy.global.tot_q = proxy.global.tot_q or 0

function read_query (packet ) if packet:byte() ~= proxy.COM_QUERY then return end proxy.global.tot_q = proxy.global.tot_q + 1 print('queries ' .. proxy.global.tot_q)end

Page 34: Advanced Lua Scripting - MySQL Proxy

read_query and read_query_resultclient

MySQL Proxy

SERVER

query

functionread_query

function

read_query_result

query

result

result

if a query is passed directly to the server, its result is NOT evaluated by read_query_result

Page 35: Advanced Lua Scripting - MySQL Proxy

read_query and read_query_resultclient

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

query

result

result

only if a query is added to the query queue, its result is evaluated by read_query_result

queryquery

Page 36: Advanced Lua Scripting - MySQL Proxy

multiple query execution - basic rule

Even if the proxy sends multiple queries to the server, it can return ONLY ONE RESULT to the client

Page 37: Advanced Lua Scripting - MySQL Proxy

Multiple query execution

simple queue queue management interactive play cumulative results

Page 38: Advanced Lua Scripting - MySQL Proxy

Multiple query execution - simple queue

client sends one query Proxy adds 1 or more queries to the queue The Proxy processes each result

• if the result is for the client, it is passed along• if the result is for internal calculation, it is discarded

The client receives one result only

Page 39: Advanced Lua Scripting - MySQL Proxy

multiple query execution - 1client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

query 3

result 1

query 2

query 1

result 1

OK

Page 40: Advanced Lua Scripting - MySQL Proxy

multiple query execution - 2client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

query 3

result 2

query 2

result 2

OK

Page 41: Advanced Lua Scripting - MySQL Proxy

multiple query execution - 3client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

query 3

result 3

result 3

OK

Page 42: Advanced Lua Scripting - MySQL Proxy

Multiple query execution - queue management

the client sends one query the proxy adds N queries the proxy processes each result

• if no error, the result is passed or discarded as needed

• if error:✦ clears the query queue✦ an appropriate result is passed to the client

The client receives one result

Page 43: Advanced Lua Scripting - MySQL Proxy

queue management - 1client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

query 3

result 1

query 2

query 1

result 1

NOT OK

Page 44: Advanced Lua Scripting - MySQL Proxy

queue management - 2client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

reset

Page 45: Advanced Lua Scripting - MySQL Proxy

queue management - 3client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

errorresult

Page 46: Advanced Lua Scripting - MySQL Proxy

Multiple query execution - interactive play

The client sends a query the query is sent through the query queue the proxy uses the result to create a new query the proxy inserts the new query to the queue the first result is discarded the next result is passed to the client the client receives only one result

Page 47: Advanced Lua Scripting - MySQL Proxy

interactive execution - step 1client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

result 1

query 1

result 1

query 2

creates

OK

Page 48: Advanced Lua Scripting - MySQL Proxy

interactive execution - step 2client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queuequery 2

result 1

Page 49: Advanced Lua Scripting - MySQL Proxy

interactive execution - step 3client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

result 2

query 2

result 2

OK

Page 50: Advanced Lua Scripting - MySQL Proxy

Multiple query execution cumulative result

The client sends a query the proxy adds N queries to the queue (e.g. loop) each result is added to a cumulative the client receives only one (big) result

Page 51: Advanced Lua Scripting - MySQL Proxy

cumulative result - 1client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

result

query 3

query 2

query 1

result 1

result 1

result 1

Page 52: Advanced Lua Scripting - MySQL Proxy

cumulative result - 2client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

result

query 3

query 2

result 1

result 2

result 2

result 2

Page 53: Advanced Lua Scripting - MySQL Proxy

cumulative result - 3client

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

result

query 3

result 1

result 3

result 3

result 2

result 3

Page 54: Advanced Lua Scripting - MySQL Proxy

Q&A

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Let's talk!


Recommended