MySQL-Proxy

1,421 views

Published on

sourcode research

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,421
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
27
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

MySQL-Proxy

  1. 1. MySQL-Proxy--使用和源码分析 www.hoterran.info
  2. 2. use ● 依赖 ○ libevent ○ glib ○ lua,必须支持dlopen ● 重要参数 ○ --plugins=<name> ○ --event-threads ○ --proxy-backend-addresses ○ --proxy-read-only-backend-addresses ○ --proxy-lua-script ● 例子 ○ 启动bin/mysql-proxy --proxy-read-only-backend-addresses=10.250.7.14:3306 --proxy-backend-addresses=10.250.7.15:3306 --proxy-lua-script=tutorial-basic.lua ○ 连接mysql -h 127.0.0.1 -ptest -P4040 -u test
  3. 3. plugin● 支持多种plugins,内置有proxy(必须加载),admin等模块. ○ 模块是so共享库,以dl_open形式打开 ■ $INSTALL/lib/mysql-proxy/plugins/libproxy.so ■ $INSTALL/lib/mysql-proxy/plugins/libadmin.so● 模块必须遵循的规范 ○ 必须有plugin_init函数,填充chassis_plugin中init, apply_config函数
  4. 4. arch 1. 根据events-threads启动多线程. 2. 加载proxy模块,调用plugin_init函数(admin模块类似) 3. 调用proxy模块的apply_config启动监听(4040端口) 4. 主线程与子线程通过一个pipe交互,主线程开始监听 5. 子线程盯着pipe fd看主线程是否发送数据. 6. 主线程发现有新连接,主线程把任务(fd,event)写入一个队 列. 7. 往pipe写一个字符,子线程(惊群)从pipe fd的epoll_wait返 回. 8. 子线程从队列里抢夺该任务. 9. 抢到任务的子线程把pipe fd的数据读掉,对这个fd开始 epoll_wait.10. 仅有该子线程与这个fd保持交互.
  5. 5. arch1. 子线程在与client,mysql交互的过程中会调用proxy模块的几个函数 (proxy_connect_server等6个函数).2. 如果存在lua脚本还会有调用proxy_lua_connect_server3. proxy_lua_connect_server会创建一个lua_State,并把mysql server的信息 写入一张叫proxy的lua表里,并载入lua脚本(cachedscripts)到一个 REGISTRYINDEX里,方便后面的连接使用.4. 同时写入还有mysql的一些宏方便lua进行解析packet5. proxy_lua_connect_server还会判断lua脚本是否有connect_server函数,由 它来选择需要连接mysql服务器.6. 接下来就是状态机....
  6. 6. proxy plugin● 状态机函数(plugin.c 里proxy_*)●
  7. 7. proxy plugin● lua_scripts的作用 ○ 对client与MySQL的交互设置hook,可以添加额外的很多功 能,这也是MySQL-Proxy最吸引的功能● Proxy 与lua的交互 ■ 修改lua-scripts会影响到下一次的连接 ■ client第一次连接才会载入 ■ 如果没有lua-scripts则跳过
  8. 8. proxy plugin● proxy table●
  9. 9. proxy plugin● connect_server ○ 各种模式的负载均衡 ○ 读写控制 ○ 白名单,黑名单 ○ 必须设置proxy.connection.backends_ndx保证c代码可以 连接数据库.
  10. 10. proxy plugin● read_handshake ○● read_auth ○ 用户映射 ■ 把proxy用户转换成mysql的用户 ■ 处理密码和重包协议 ■ 需要$INSTALL/lib/mysql-proxy/lua/mysql.so● read_auth_result ○ 记录连接 ○ 连接池
  11. 11. proxy plugin● read_query ○ 对某类sql的汇总统计 ○ 记录sql语句的类型和明文的sql语句 ○ 否定部分特殊的sql(sql注入,避免select *) ○ 可以添加额外的sql(queries) ○ 可以自己定制proxy.response,添加一些额外的命令参数,例 如show mysql-proxy等命令.
  12. 12. proxy plugin● read_query_result ○ 记录结果集 ○ 避免过大的结果集 ○ 移走不想展示的结果集 ○ Qos控制结果集返回的时间 ○ 定制proxy.response包,模拟MySQL的返回结果 ○ 从injection获取sql执行时间和返回结果集的时间
  13. 13. admin plugin ● 启动bin/mysql-proxy --plugins=admin --plugins=proxy --admin-password=test --admin-username=test --admin-lua-script=admin.lua --proxy-backend-addresses=10.250.7.15:3306 --proxy-backend-addresses=10.250.7.14:3306 --proxy-lua-script=tutorial-basic.lua ● client ○ mysql -h 127.0.0.1 -utest -ptest -P4040 ● admin ○ mysql -h 127.0.0.1 -utest -ptest -P4041mysql> select * from backends;+-------------+------------------+---------+------+------+-------------------+| backend_ndx | address | state | type | uuid | connected_clients |+-------------+------------------+---------+------+------+-------------------+| 1 | 10.250.7.15:3306 | up | rw | NULL | 1|| 2 | 10.250.7.14:3306 | unknown | rw | NULL | 0|+-------------+------------------+---------+------+------+-------------------+
  14. 14. dir ● 目录说明,$INSTALL为MySQL-Proxy安装后的目录,$SOURCE为源代码 目录 ● MySQL-Proxy主体的目录 ○ $SOURCE/src ○ $INSTALL/bin,$INSTALL/lib ● admin,proxy模块的目录 ○ $SOURCE/plugins ○ $INSTALL/lib/mysql-proxy/plugins ● lua-scripts,包括负载均衡,用户映射,解析sql等 ○ $SOURCE/lib/(example), $SOURCE/lib/proxy(lib) ○ $INSTALL/lib/mysql-proxy/lua/proxy/(lib) ● lua-scripts调用c的模块(密码,包重新组装,词法解析) ○ $SOURCE/lib ○ $INSTALL/lib/mysql-proxy/lua/
  15. 15. 代码之旅从src/mysql-cli.c开始

×