MySQL中间件之ProxySQL(11):链式规则( flagIN 和 flagOUT )

返回ProxySQL系列文章:

 

1.理解链式规则

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

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

当入口值flagIN设置为0时,表示开始进入链式规则。如未显式指定规则的flagIN值,则默认都为0。

当语句匹配完当前规则后,将记下当前规则的flagOUT值,如果flagOUT值非空(NOT NULL),则为该语句打上flagOUT标记。如果该规则的apply字段值不是1,则继续向下匹配。

如果语句的flagOUT标记和下一条规则的flagIN值不同,则跳过该规则,继续向下匹配。直到匹配到flagOUT=flagIN的规则,则匹配该规则。该规则是链式规则中的另一条规则。

直到某规则的apply字段设置为1,或者已经匹配完所有规则,则最后一次被评估的规则将直接生效,不再继续向下匹配。

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

MySQL中间件之ProxySQL(11):链式规则( flagIN 和 flagOUT )

MySQL中间件之ProxySQL(11):链式规则( flagIN 和 flagOUT )

必须注意,规则是按照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 | +---------+-------+--------+---------+---------------+-----------------+------+

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyszfp.html