ProxySQL(11):链式规则( flagIN 和 flagOUT )
文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9350631.html
理解链式规则
在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,或者已经匹配完所有规则,则最后一次被评估的规则将直接生效,不再继续向下匹配。
通过下面两张图,应该很容易理解链式规则的生效方式。


必须注意,规则是按照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 |
+---------+-------+--------+---------+
链式规则示例
有了普通规则匹配方式,为什么还要设计链式规则呢?虽然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=2和rule_id=3这两个规则的flagIN都是非0值,而每个SQL语句初始时只进入flagIN=0的规则。
此外还需注意,当某语句未按照我们的期望途经所有的链式规则,则可能会根据destination_hostgroup字段的值直接路由出去,即使没有指定该字段值,还有用户的默认路由目标组,或者基于端口的路由目标。所以,在写链式规则时,应当尽可能地针对某一类型的语句进行完完整整的定制,保证这类语句能途经我们所期望的所有规则。
ProxySQL(11):链式规则( flagIN 和 flagOUT )的更多相关文章
- MySQL中间件之ProxySQL(11):链式规则( flagIN 和 flagOUT )
返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.理解链式规则 在mysql_query_rules表中,有两个特殊 ...
- (原创)c++11中 function/lamda的链式调用
关于链式调用,比较典型的例子是c#中的linq,不过c#中的linq还只是一些特定函数的链式调用.c++中的链式调用更少见因为实现起来比较复杂.c++11支持了lamda和function,在一些延迟 ...
- PHP设计模式:类自动载入、PSR-0规范、链式操作、11种面向对象设计模式实现和使用、OOP的基本原则和自动加载配置
一.类自动载入 SPL函数 (standard php librarys) 类自动载入,尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_registe ...
- Objective-C 链式语法的实现
对于 Objective-C 的语法,喜欢的人会觉得它是如此的优雅,代码可读性强,接近自然语言,开发者在调用大多数方法时不需要去查看注释或文档,通常只凭借方法名就可以大致知道这个方法的作用,可以理解为 ...
- Java链式方法 连贯接口(fluent interface)
有两种情况可运用链式方法: 第一种 除最后一个方法外,每个方法都返回一个对象 object2 = object1.method1(); object3 = object2.method2(); ob ...
- zzuli 2131 Can Win dinic+链式前向星(难点:抽象出网络模型+建边)
2131: Can Win Time Limit: 1 Sec Memory Limit: 128 MB Submit: 431 Solved: 50 SubmitStatusWeb Board ...
- (数据科学学习手札107)在Python中利用funct实现链式风格编程
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 链式编程是一种非常高效的组织代码的方式,典型如p ...
- C#用链式方法表达循环嵌套
情节故事得有情节,不喜欢情节的朋友可看第1版代码,然后直接跳至“三.想要链式写法” 一.起缘 故事缘于一位朋友的一道题: 朋友四人玩LOL游戏.第一局,分别选择位置:中单,上单,ADC,辅助:第二局新 ...
- 由表单验证说起,关于在C#中尝试链式编程的实践
在web开发中必不可少的会遇到表单验证的问题,为避免数据在写入到数据库时出现异常,一般比较安全的做法是前端会先做一次验证,通过后把数据提交到后端再验证一次,因为仅仅靠前端验证是不安全的,有太多的htt ...
随机推荐
- Java实现ATM架构设计
云ATM架构设计 说明 https://www.processon.com/view/link/62ca68ee5653bb74ddcdd582 点击连接可查看项目流程图,帮助小伙伴们开发 启动程序( ...
- NC20566 [SCOI2010]游戏
题目链接 题目 题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属 ...
- Netty源码解读(四)-读写数据
读写Channel(READ)的创建和注册 在NioEventLoop#run中提到,当有IO事件时,会调用processSelectedKeys方法来处理. 当客户端连接服务端,会触发服务端的ACC ...
- 操作表查询&操作表创建&操作表删除&操作表修改
2.操作表 C(create):创建 语法: create table 表明( 列名1 数据类型1, 列名2 数据烈性2, .... 列名n 数据类型n ); create table Student ...
- 关于静态 RMQ 问题
目录 1. 普通做法 2. Four Russian 算法 3. 随机数据的一种做法 4. 有关转 LCA 的做法 1.1. RMQ 转 LCA 再转 ±1RMQ(RMQ 标准算法) 1.2. 一个优 ...
- 什么是双网口以太网IO模块
MXXXE系列远程IO模块工业级设计,适用于工业物联网和自动化控制系统,MxxxE工业以太网远程 I/O 配备 2 个mac层数据交换芯片的以太网端口,允许数据通过可扩展的菊花链以太网远程 I/O 阵 ...
- doc或docx(word)或image类型文件批量转PDF脚本
doc或docx(word)或image类型文件批量转PDF脚本 1.实际生产环境中遇到文件展示只能适配PDF版本的文件,奈何一万个文件有七千个都是word或者image类型的,由此搞个脚本批量转换下 ...
- leetcode之二叉树
专题:二叉树遍历 987. 二叉树的垂序遍历 给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列. 对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row ...
- JavaScript的入门
书写的三种方式 1. 书写在script标签里面(一般会用到的) 2.书写在js文件里面(推荐)定义一个js文件(xxx.js) 3. 书写对应的事件属性里面(比较少用) 初体验 1. 目前js的代码 ...
- 大数据Hadoop入门教程 | (一)概论
数据是什么 数据是指对客观事件进行记录并可以鉴别的符号,是对客观事物的性质.状态以及相互关系等进行记载的物理符号或这些物理符号的组合,它是可识别的.抽象的符号. 它不仅指狭义上的数字,还可以是具有一定 ...