返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html

1.理解链式规则

在mysql_query_rules表中,有两个特殊字段"flagIN"和"flagOUT",它们分别用来定义规则的入口和出口,从而实现链式规则(chains of rules)。

链式规则的实现方式如下:

  1. 当入口值flagIN设置为0时,表示开始进入链式规则。如未显式指定规则的flagIN值,则默认都为0。
  2. 当语句匹配完当前规则后,将记下当前规则的flagOUT值,如果flagOUT值非空(NOT NULL),则为该语句打上flagOUT标记。如果该规则的apply字段值不是1,则继续向下匹配。
  3. 如果语句的flagOUT标记和下一条规则的flagIN值不同,则跳过该规则,继续向下匹配。直到匹配到flagOUT=flagIN的规则,则匹配该规则。该规则是链式规则中的另一条规则。
  4. 直到某规则的apply字段设置为1,或者已经匹配完所有规则,则最后一次被评估的规则将直接生效,不再继续向下匹配。

通过下面两张图,应该很容易理解链式规则的生效方式。

必须注意,规则是按照rule_id的大小顺序进行的。且并非只有apply=1时才会应用规则,当无规则可匹配,或者某规则的flagIN和flagOUT值相同,都会应用最后一次被评估的规则

以下几个示例,可以解释生效规则:

# rule_id=3 生效
+---------+-------+--------+---------+
| rule_id | apply | flagIN | flagOUT |
+---------+-------+--------+---------+
| 1 | 0 | 0 | 23 |
| 2 | 0 | 23 | 23 |
| 3 | 0 | 23 | NULL |
+---------+-------+--------+---------+ # rule_id=2 生效
+---------+-------+--------+---------+
| rule_id | apply | flagIN | flagOUT |
+---------+-------+--------+---------+
| 1 | 0 | 0 | 23 |
| 2 | 0 | 23 | 23 |
| 3 | 0 | 24 | NULL |
+---------+-------+--------+---------+ # rule_id=2 生效,因为匹配完rule_id=2后,还打着flagOUT=23标记
+---------+-------+--------+---------+
| rule_id | apply | flagIN | flagOUT |
+---------+-------+--------+---------+
| 1 | 0 | 0 | 23 |
| 2 | 0 | 23 | NULL |
| 3 | 1 | 24 | NULL |
+---------+-------+--------+---------+ # rule_id=3 生效,因为匹配完rule_id=2后,还打着flagOUT=23标记
+---------+-------+--------+---------+
| rule_id | apply | flagIN | flagOUT |
+---------+-------+--------+---------+
| 1 | 0 | 0 | 23 |
| 2 | 0 | 23 | NULL |
| 3 | 1 | 23 | NULL |
+---------+-------+--------+---------+

2.链式规则示例

有了普通规则匹配方式,为什么还要设计链式规则呢?虽然ProxySQL通过正则表达式实现了很灵活的规则匹配模式,但需求总是千变万化的,有时候仅通过一条正则匹配规则和替换规则很难实现比较复杂的要求,例如sharding时。

链式规则除了常用的多次替换,还可巧用于多次匹配

本文简单演示一下链式规则,不具有实际意义,只为后面ProxySQL实现sharding的文章做基础知识铺垫。

2个测试库,共4张表test{1,2}.t{1,2}。

mysql> select * from test1.t1;
+------------------+
| name |
+------------------+
| test1_t1_malong1 |
| test1_t1_malong2 |
| test1_t1_malong3 |
+------------------+ mysql> select * from test1.t2;
+------------------+
| name |
+------------------+
| test1_t2_malong1 |
| test1_t2_malong2 |
| test1_t2_malong3 |
+------------------+ mysql> select * from test2.t1;
+--------------------+
| name |
+--------------------+
| test2_t1_xiaofang1 |
| test2_t1_xiaofang2 |
| test2_t1_xiaofang3 |
+--------------------+ mysql> select * from test2.t2;
+--------------------+
| name |
+--------------------+
| test2_t2_xiaofang1 |
| test2_t2_xiaofang2 |
| test2_t2_xiaofang3 |
+--------------------+

现在借用链式规则,一步一步地将对test1.t1表的查询路由到test2.t2表的查询。再次声明,此处示例毫无实际意义,仅为演示链式规则的基本用法。

大致链式匹配的过程为:

test1.t1 --> test1.t2 --> test2.t1 --> test2.t2

以下是具体插入的规则:

delete from mysql_query_rules;
select * from stats_mysql_query_digest_reset where 1=0; insert into mysql_query_rules
(rule_id,active,apply,flagIN,flagOUT,match_pattern,replace_pattern) values
(1,1,0,0,23,"test1\.t1","test1.t2"); insert into mysql_query_rules
(rule_id,active,apply,flagIN,flagOUT,match_pattern,replace_pattern) values
(2,1,0,23,24,"test1\.t2","test2.t1"); insert into mysql_query_rules
(rule_id,active,apply,flagIN,flagOUT,match_pattern,replace_pattern,destination_hostgroup) values
(3,1,1,24,NULL,"test2\.t1","test2.t2",30); load mysql query rules to runtime;
save mysql query rules to disk; admin> select rule_id,
apply,
flagIN,
flagOUT,
match_pattern,
replace_pattern,
destination_hostgroup DH
from mysql_query_rules;
+---------+-------+--------+---------+---------------+-----------------+------+
| rule_id | apply | flagIN | flagOUT | match_pattern | replace_pattern | DH |
+---------+-------+--------+---------+---------------+-----------------+------+
| 1 | 0 | 0 | 23 | test1\.t1 | test1.t2 | NULL |
| 2 | 0 | 23 | 24 | test1\.t2 | test2.t1 | NULL |
| 3 | 1 | 24 | NULL | test2\.t1 | test2.t2 | 30 |
+---------+-------+--------+---------+---------------+-----------------+------+

查询test1.t1表,测试结果。

[root@xuexi ~]# mysql -uroot -pP@ssword1! -h127.0.0.1 -P6033 -e "select * from test1.t1;"
+--------------------+
| name |
+--------------------+
| test2_t2_xiaofang1 | <-- 查询返回结果为test2.t2内容
| test2_t2_xiaofang2 |
| test2_t2_xiaofang3 |
+--------------------+ admin> select * from stats_mysql_query_rules;
+---------+------+
| rule_id | hits |
+---------+------+
| 1 | 1 | <-- 3条规则全都命中
| 2 | 1 |
| 3 | 1 |
+---------+------+ admin> select hostgroup,digest_text from stats_mysql_query_digest;
+-----------+----------------------------------+
| hostgroup | digest_text |
+-----------+----------------------------------+
| 30 | select * from test2.t2 | <-- 路由目标hg=30
+-----------+----------------------------------+

显然,已经按照预想中的方式进行匹配、替换、路由。

一个问题:如果查询的是test1.t2表或test2.t1表,会进行链式匹配吗?

答案是不会,因为rule_id=2rule_id=3这两个规则的flagIN都是非0值,而每个SQL语句初始时只进入flagIN=0的规则。

此外还需注意,当某语句未按照我们的期望途经所有的链式规则,则可能会根据destination_hostgroup字段的值直接路由出去,即使没有指定该字段值,还有用户的默认路由目标组,或者基于端口的路由目标。所以,在写链式规则时,应当尽可能地针对某一类型的语句进行完完整整的定制,保证这类语句能途经我们所期望的所有规则。

MySQL中间件之ProxySQL(11):链式规则( flagIN 和 flagOUT )的更多相关文章

  1. ProxySQL(11):链式规则( flagIN 和 flagOUT )

    文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9350631.html 理解链式规则 在mysql_query_rules表中,有两个特殊字段"fl ...

  2. MySQL中间件之ProxySQL(7):详述ProxySQL的路由规则

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.关于ProxySQL路由的简述 当ProxySQL收到前端app发 ...

  3. MySQL中间件之ProxySQL(9):ProxySQL的查询缓存功能

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html ProxySQL支持查询缓存的功能,可以将后端返回的结果集缓存在自己的 ...

  4. MySQL中间件之ProxySQL(1):简介和安装

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.ProxySQL简介 之前的文章里,介绍了一个MySQL的中间件: ...

  5. MySQL中间件之ProxySQL(10):读写分离方法论

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.不同类型的读写分离 数据库中间件最基本的功能就是实现读写分离,Pr ...

  6. MySQL中间件之ProxySQL(6):管理后端节点

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.配置后端节点前的说明 为了让ProxySQL能够找到后端的MySQ ...

  7. MySQL中间件之ProxySQL(8):SQL语句的重写规则

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.为什么要重写SQL语句 ProxySQL在收到前端发送来的SQL语 ...

  8. MySQL中间件之ProxySQL(14):ProxySQL+PXC

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.ProxySQL+PXC 本文演示ProxySQL代理PXC(Pe ...

  9. MySQL中间件之ProxySQL(5):线程、线程池、连接池

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.ProxySQL的线程 ProxySQL由多个模块组成,是一个多线 ...

随机推荐

  1. 编程感悟-建立好代码sop

    1.最近学django和python,发现很多的函数记不住,这时候我百度了一下,发现记不住是程序员的正常情况, 这下心安理得多了,记好笔记和咱的sop吧,会很快. 社会是不是也这样,好多东西也记不住, ...

  2. python之路(十)-正则表达式

    re模块用于对python的正则表达式的操作. 字符: . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配 ...

  3. Linux目录/usr结构说明

    在 linux 文件结构中,有一个很神奇的目录 -- /usr. 讨论中,大部分观点认为: usr 是 unix system resources 的缩写: usr 是 user 的缩写: usr 是 ...

  4. Metasploit漏洞的利用

  5. window系统中 mongodb创建用户名和密码

    use admindb.createUser({user:"root",pwd:"root",roles:[{"role":"us ...

  6. 《python语言程序设计》_第二章编程题

    2.1 程序: Celsius=eval(input("Enter a degree in Celsius:"))#输入摄氏度的值Celsiusfahrenheit =(9/5)* ...

  7. js获取复选框值

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. Android中弹出dialog后无法捕捉back键

    一.需求 在Android开发过程中,弹出dialog后无法捕捉back键,点击back按键无响应. 二.解决方案 原因:弹出dialog后,activity失去焦点,dialog获得当前焦点. 解决 ...

  9. linux系统下安装redis以及java调用redis

    关系型数据库:MySQL  Oracle 非关系型数据库:Redis 去掉主外键等关系数据库的关系性特性 1)安装redis编译的c环境,yum install gcc-c++ 2)将redis-2. ...

  10. JSON Web Token(JWT)原理和用法介绍

    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案.今天给大家介绍一下JWT的原理和用法. 官网地址:https://jwt.io/ 一.跨域身份验证 Internet服务无法与 ...