• 详述ProxySQL的路由规则 实践篇


    转载自:https://blog.csdn.net/weixin_30911809/article/details/98601663

    关于ProxySQL路由的简述

    当ProxySQL收到前端app发送的SQL语句后,它需要将这个SQL语句(或者重写后的SQL语句)发送给后端的MySQL Server,然后收到SQL语句的MySQL Server执行查询,并将查询结果返回给ProxySQL,再由ProxySQL将结果返回给客户端(如果设置了查询缓存,则先缓存查询结果)。

    ProxySQL可以实现多种方式的路由:基于ip/port、username、schema、SQL语句。其中基于SQL语句的路由是按照规则进行匹配的,匹配方式有hash高效匹配、正则匹配,还支持更复杂的链式规则匹配。

    在这里本篇只介绍基于SQL语句的路由的匹配

    mysql_query_rules表

    可以通过 show create table mysql_query_rules 语句查看定义该表的语句。

    |       COLUMN          |  TYPE   |  NULL?   | DEFAULT    |
    |-----------------------|---------|----------|------------|
    | rule_id   (pk)        | INTEGER | NOT NULL |            |
    | active                | INT     | NOT NULL | 0          |
    | username              | VARCHAR |          |            |
    | schemaname            | VARCHAR |          |            |
    | flagIN                | INT     | NOT NULL | 0          |
    | client_addr           | VARCHAR |          |            |
    | proxy_addr            | VARCHAR |          |            |
    | proxy_port            | INT     |          |            |
    | digest                | VARCHAR |          |            |
    | match_digest          | VARCHAR |          |            |
    | match_pattern         | VARCHAR |          |            |
    | negate_match_pattern  | INT     | NOT NULL | 0          |
    | re_modifiers          | VARCHAR |          | 'CASELESS' |
    | flagOUT               | INT     |          |            |
    | replace_pattern       | VARCHAR |          |            |
    | destination_hostgroup | INT     |          | NULL       |
    | cache_ttl             | INT     |          |            |
    | reconnect             | INT     |          | NULL       |
    | timeout               | INT     |          |            |
    | retries               | INT     |          |            |
    | delay                 | INT     |          |            |
    | mirror_flagOU         | INT     |          |            |
    | mirror_hostgroup      | INT     |          |            |
    | error_msg             | VARCHAR |          |            |
    | sticky_conn           | INT     |          |            |
    | multiplex             | INT     |          |            |
    | log                   | INT     |          |            |
    | apply                 | INT     | NOT NULL | 0          |
    | comment               | VARCHAR |          |            |
    

    各个字段的意义如下:

    • rule_id:规则的id。规则是按照rule_id的顺序进行处理的。
    • active:只有该字段值为1的规则才会加载到runtime数据结构,所以只有这些规则才会被查询处理模块处理。
    • username:用户名筛选,当设置为非NULL值时,只有匹配的用户建立的连接发出的查询才会被匹配。
    • schemaname:schema筛选,当设置为非NULL值时,只有当连接使用schemaname作为默认schema时,该连接发出的查询才会被匹配。(在MariaDB/MySQL中,schemaname等价于databasename)。
    • flagIN,flagOUT:这些字段允许我们创建"链式规则"(chains of rules),一个规则接一个规则。
    • apply:当匹配到该规则时,立即应用该规则。
    • client_addr:通过源地址进行匹配。
    • proxy_addr:当流入的查询是在本地某地址上时,将匹配。
    • proxy_port:当流入的查询是在本地某端口上时,将匹配。
    • digest:通过digest进行匹配,digest的值在stats_mysql_query_digest.digest中。
    • match_digest:通过正则表达式匹配digest。
    • match_pattern:通过正则表达式匹配查询语句的文本内容。
    • negate_match_pattern:设置为1时,表示未被match_digest或match_pattern匹配的才算被成功匹配。也就是说,相当于在这两个匹配动作前加了NOT操作符进行取反。
    • re_modifiers:RE正则引擎的修饰符列表,多个修饰符使用逗号分隔。指定了CASELESS后,将忽略大小写。指定了GLOBAL后,将替换全局(而不是第一个被匹配到的内容)。为了向后兼容,默认只启用了CASELESS修饰符。
    • replace_pattern:将匹配到的内容替换为此字段值。它使用的是RE2正则引擎的Replace。注意,这是可选的,当未设置该字段,查询处理器将不会重写语句,只会缓存、路由以及设置其它参数。
    • destination_hostgroup:将匹配到的查询路由到该主机组。但注意,如果用户的transaction_persistent=1(见mysql_users表),且该用户建立的连接开启了一个事务,则这个事务内的所有语句都将路由到同一主机组,无视匹配规则。
    • cache_ttl:查询结果缓存的时间长度(单位毫秒)。注意,在ProxySQL 1.1中,cache_ttl的单位是秒。
    • reconnect:目前不使用该功能。
    • timeout:被匹配或被重写的查询执行的最大超时时长(单位毫秒)。如果一个查询执行的时间太久(超过了这个值),该查询将自动被杀掉。如果未设置该值,将使用全局变量mysql-default_query_timeout的值。
    • retries:当在执行查询时探测到故障后,重新执行查询的最大次数。如果未指定,则使用全局变量mysql-query_retries_on_failure的值。
    • delay:延迟执行该查询的毫秒数。本质上是一个限流机制和QoS,使得可以将优先级让位于其它查询。这个值会写入到mysql-default_query_delay全局变量中,所以它会应用于所有的查询。将来的版本中将会提供一个更高级的限流机制。
    • mirror_flagOUT和mirror_hostgroup:mirroring相关的设置,目前mirroring正处于实验阶段,所以不解释。
    • error_msg:查询将被阻塞,然后向客户端返回error_msg指定的信息。
    • sticky_conn:当前还未实现该功能。
    • multiplex:如果设置为0,将禁用multiplexing。如果设置为1,则启用或重新启用multiplexing,除非有其它条件(如用户变量或事务)阻止启用。如果设置为2,则只对当前查询不禁用multiplexing。默认值为NULL,表示不会修改multiplexing的策略。
    • log:查询将记录日志。
    • apply:当设置为1后,当匹配到该规则后,将立即应用该规则,不会再评估其它的规则(注意:应用之后,将不会评估mysql_query_rules_fast_routing中的规则)。
    • comment:注释说明字段,例如描述规则的意义。

    常用命令

    # 查询信息状态
    select hostgroup hg,count_star cs,digest,digest_text dt from stats_mysql_query_digest;
    
    select rule_id,active,digest,match_digest,match_pattern,destination_hostgroup,apply from mysql_query_rules;
    
    # 查询规则
    select rule_id,active,match_pattern,match_digest,destination_hostgroup,apply from mysql_query_rules;
    
    # 修改规则
    update mysql_query_rules set match_digest='^select.*getSequenceNo.*' where rule_id=2;
    
    # 停止规则
    update mysql_query_rules set active=0 where rule_id=2;
    
    update mysql_query_rules set rule_id=100 where destination_hostgroup=100;
    update mysql_query_rules set rule_id=101 where destination_hostgroup=1000;
    
    # 删除规则
    delete from mysql_query_rules where rule_id=2;
    
    # 主从分组信息
    select hostgroup_id,hostname,port,status,weight from mysql_servers;
    
    # log
    select * from mysql_server_ping_log;
    select * from mysql_server_replication_lag_log;
    select * from mysql_server_read_only_log;
    
    # 写入新规则
    insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply) VALUES (2,1,'^select.*getSequenceNo',0,1);
    
    load mysql query rules to runtime;
    save mysql query rules to disk;
    

    基于SQL语句路由

    ProxySQL接收到前端发送的SQL语句后,首先分析语句,然后从mysql_query_rules表中寻找是否有匹配该语句的规则。如果先被username或ip/port类的规则匹配并应用,则按这些规则路由给后端,如果是被基于SQL语句的规则匹配,则启动正则引擎进行正则匹配,然后路由给对应的后端组,如果规则中指定了正则替换字段,则还会重写SQL语句,然后再发送给后端。

    SQL语句分类:参数化

    什么是参数化?

    select * from tbl where id=?
    

    这里将where条件语句中字段id的值进行了参数化,也就是上面的问号?。

    我们在客户端发起的SQL语句都是完整格式的语句,但是SQL优化引擎出于优化的目的需要考虑很多事情。例如,如何缓存查询结果、如何匹配查询缓存中的数据并取出,等等。将SQL语句参数化是优化引擎其中的一个行为,对于那些参数相同但参数值不同的查询语句,SQL语句认为这些是同类查询,同类查询的SQL语句不会重复去编译而增加额外的开销。

    select * from tbl where id=10;
    select * from tbl where id=20;
    

    将它们参数化后,结果如下:

    select * from tbl where id=?;
    

    通俗地讲,这里的"?"就是一个变量,任何满足这个语句类型的值都可以传递到这个变量中。

    所以,对参数化进行一个通俗的定义:对于那些参数相同、参数值不同的SQL语句,使用问号"?"去替换参数值,替换后返回的语句就是参数化的结果。

    ProxySQL也支持参数化。当前端发送SQL语句到达ProxySQL后,ProxySQL会将其参数化并分类。例如,下面是ProxySQL统计的参数化语句。

    +----+----------+------------+-------------------------------------------------------------+
    | hg | sum_time | count_star | digest_text                                                 |
    +----+----------+------------+-------------------------------------------------------------+
    | 2  | 14520738 | 50041      | SELECT c FROM sbtest1 WHERE id=?                            |
    | 1  | 3142041  | 5001       | COMMIT                                                      |
    | 1  | 2270931  | 5001       | SELECT c FROM sbtest1 WHERE id BETWEEN ? AND ?+? ORDER BY c |
    | 1  | 2021320  | 5003       | SELECT c FROM sbtest1 WHERE id BETWEEN ? AND ?+?            |
    | 1  | 1768748  | 5001       | UPDATE sbtest1 SET k=k+? WHERE id=?                         |
    | 1  | 1697175  | 5003       | SELECT SUM(K) FROM sbtest1 WHERE id BETWEEN ? AND ?+?       |
    | 1  | 1346791  | 5001       | UPDATE sbtest1 SET c=? WHERE id=?                           |
    | 1  | 1263259  | 5001       | DELETE FROM sbtest1 WHERE id=?                              |
    | 1  | 1191760  | 5001       | INSERT INTO sbtest1 (id, k, c, pad) VALUES (?, ?, ?, ?)     |
    | 1  | 875343   | 5005       | BEGIN                                                       |
    +----+----------+------------+-------------------------------------------------------------+
    

    ProxySQL的mysql_query_rules表中有三个字段,能基于参数化后的SQL语句进行三种不同方式的匹配:

    • digest:将参数化后的语句进行hash运算得到一个hash值digest,可以对这个hash值进行精确匹配。匹配效率最高。
    • match_digest:对digest值进行正则匹配。
    • match_pattern:对原始SQL语句的文本内容进行正则匹配。

    如果要进行SQL语句的重写(即正则替换),或者对参数值匹配,则必须采用match_pattern。如果可以,尽量采用digest匹配方式,因为它的效率更高。

    路由相关的几个统计表

    在ProxySQL的stats库中,包含了几个统计表。

    admin> show tables from stats;
    +--------------------------------------+
    | tables                               |
    +--------------------------------------+
    | global_variables                     |
    | stats_memory_metrics                 |
    | stats_mysql_commands_counters        |     <--已执行查询语句的统计信息
    | stats_mysql_connection_pool          |     <--连接池信息
    | stats_mysql_connection_pool_reset    |     <--重置连接池统计数据
    | stats_mysql_global                   |     <--全局统计数据
    | stats_mysql_prepared_statements_info |
    | stats_mysql_processlist              |     <--模拟show processlist的结果
    | stats_mysql_query_digest             | <--本文解释
    | stats_mysql_query_digest_reset       | <--本文解释
    | stats_mysql_query_rules              | <--本文解释
    | stats_mysql_users                    |     <--各mysql user前端和ProxySQL的连接数
    | stats_proxysql_servers_checksums     |     <--ProxySQL集群相关
    | stats_proxysql_servers_metrics       |     <--ProxySQL集群相关
    | stats_proxysql_servers_status        |     <--ProxySQL集群相关
    +--------------------------------------+
    

    stats_mysql_query_digest: 这个表对于分析SQL语句至关重要,是分析语句性能、定制路由规则指标的最主要来源。

    这个统计表中记录的就是每个参数化分类后的语句对应的统计数据,包括该类语句的执行次数、所花总时间、所花最短、最长时间,还包括语句的文本以及它的digest。

    select hostgroup hg,count_star,FROM_UNIXTIME(first_seen),sum_time,digest,digest_text from stats_mysql_query_digest order by first_seen DESC limit 5;
    

    以下是各个字段的意义:

    • hostgroup:查询将要路由到的目标主机组。如果值为-1,则表示命中了查询缓存,直接从缓存取数据返回给客户端。
    • schemaname:当前正在执行的查询所在的schema名称。
    • username:MySQL客户端连接到ProxySQL使用的用户名。
    • digest:一个十六进制的hash值,唯一地代表除了参数值部分的查询语句。
    • digest_text:参数化后的SQL语句的文本。注意,如果重写了SQL语句,则这个字段是显示的是重写后的字段。换句话说,这个字段是真正路由到后端,被后端节点执行的语句。
    • count_star:该查询(参数相同、值不同)总共被执行的次数。
    • first_seen:unix格式的timestamp时间戳,表示该查询首次被ProxySQL路由出去的时间点。
    • last_seen:unix格式的timestamp时间戳,到目前为止,上一次该查询被ProxySQL路由出去的时间点。
    • sum_time:执行该类查询所花的总时间(单位微秒)。在想要找出程序中哪部分语句消耗时间最长的语句时非常有用,此外根据这个结果还能提供一个如何提升性能的良好开端。
    • min_time, max_time:执行该类查询的时间范围。min_time表示的是目前为止执行该类查询所花的最短时间,max_time则是目前为止,执行该类查询所花的最长时间,单位都是微秒。

    注意,该表中的查询所花时长是指ProxySQL从接收到客户端查询开始,到ProxySQL准备向客户端发送查询结果的时长。因此,这些时间更像是客户端看到的发起、接收的时间间隔(尽管客户端到服务端数据传输也需要时间)。更精确一点,在执行查询之前,ProxySQL可能需要更改字符集或模式,可能当前后端不可用(当前后端执行语句失败)而找一个新的后端,可能因为所有连接都繁忙而需要等待空闲连接,这些都不应该计算到查询执行所花时间内。

    其中hostgroup、digest、digest_text、count_start、{sum,min,max}_time这几列最常用。

    admin> select hostgroup hg,count_star,sum_time,digest,digest_text from stats_mysql_query_digest;
    +----+------------+----------+--------------------+------------------------+
    | hg | count_star | sum_time | digest             | digest_text            |
    +----+------------+----------+--------------------+------------------------+
    | 10 | 4          | 2412     | 0xADB885E1F3A7A5C2 | select * from test2.t1 |
    | 10 | 6          | 4715     | 0x57497F236587B138 | select * from test1.t1 |
    +----+------------+----------+--------------------+------------------------+
    

    从中分析,两个语句都路由到了hostgroup=10的组中,第一个语句执行了4次,这4次总共花费了2412微秒(即2.4毫秒),第二个语句执行了6次,总花费4.7毫秒。还给出了这两个语句参数化后的digest值,以及参数化后的SQL文本。

    stats_mysql_query_digest_reset: 这个表的表结构和stats_mysql_query_digest是完全一样的,只不过每次从这个表中检索数据(随便检索什么,哪怕where 1=0),都会重置stats_mysql_query_digest表中已统计的数据。

    stats_mysql_query_rules
    这个表只有两个字段:

    • rule_id:对应的是规则号码。
    • hits,对应的是每个规则被命中了多少次。

    基于SQL语句路由:digest

    digest匹配规则是对digest进行精确匹配。

    例如,从stats_mysql_query_digest中获取两个对应的digest值。注意,现在它们的hostgroup_id=10。

    admin> select hostgroup hg,count_star,sum_time,digest,digest_text from stats_mysql_query_digest;
    +----+------------+----------+--------------------+------------------------+
    | hg | count_star | sum_time | digest             | digest_text            |
    +----+------------+----------+--------------------+------------------------+
    | 10 | 4          | 2412     | 0xADB885E1F3A7A5C2 | select * from test2.t1 |
    | 10 | 6          | 4715     | 0x57497F236587B138 | select * from test1.t1 |
    +----+------------+----------+--------------------+------------------------+
    

    插入两条匹配这两个digest的规则:

    insert into mysql_query_rules(rule_id,active,digest,destination_hostgroup,apply) values(1,1,"0xADB885E1F3A7A5C2",20,1),(2,1,"0x57497F236587B138",10,1);
    

    然后测试

    mysql -uroot -pP@ssword1! -h127.0.0.1 -P6033 -e "select * from test1.t1;"
    mysql -uroot -pP@ssword1! -h127.0.0.1 -P6033 -e "select * from test2.t1;"
    

    再去查看规则的路由命中情况:

    admin> select * from stats_mysql_query_rules;
    +---------+------+
    | rule_id | hits |
    +---------+------+
    | 1       | 1    |
    | 2       | 1    |
    +---------+------+
    

    查看路由的目标:

    admin> select hostgroup hg,count_star cs,digest,digest_text from stats_mysql_query_digest;
    +----+----+--------------------+------------------------+
    | hg | cs | digest             | digest_text            |
    +----+----+--------------------+------------------------+
    | 20 | 1  | 0xADB885E1F3A7A5C2 | select * from test2.t1 |
    | 10 | 1  | 0x57497F236587B138 | select * from test1.t1 |
    +----+----+--------------------+------------------------+
    

    可见,基于digest的精确匹配规则已经生效。

    基于SQL语句路由:match_digest

    match_digest是对digest做正则匹配,但注意match_pattern字段中给的规则不是hash值,而是SQL语句的文本匹配规则。

    ProxySQL支持两种正则引擎:
    1.PCRE
    2.RE2

    老版本中默认的正则引擎是RE2,现在默认的正则引擎是PCRE。可从变量mysql-query_processor_regex获知当前的正则引擎是RE2还是PCRE:

    Admin> select @@mysql-query_processor_regex;
    +-------------------------------+
    | @@mysql-query_processor_regex |
    +-------------------------------+
    | 1                             |
    +-------------------------------+
    

    其中1代表PCRE,2代表RE2。

    在mysql_query_rules表中有一个字段re_modifiers,它用于定义正则引擎的修饰符,默认已经设置caseless,表示正则匹配时忽略大小写,所以select和SELECT都能匹配。此外,还可以设置global修饰符,表示匹配全局,而非匹配第一个,这个在重写SQL语句时有用。

    (RE2引擎无法同时设置caseless和global,即使它们都设置了也不会生效。所以,将默认的正则引擎改为了PCRE)

    在进行下面的实验之前,先把mysql_query_rules表清空,并将规则的统计数据也清空。

    delete from mysql_query_rules;
    select * from stats_mysql_query_digest_reset;
     
    insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply) values (1,1,"^select .* test2.*",20,1),(2,1,"^select .* test1.*",10,1);
     
    load mysql query rules to runtime;
    save mysql query rules to disk;
    

    然后分别执行:

    mysql -uroot -pP@ssword1! -h127.0.0.1 -P6033 -e "select * from test1.t1;"
    mysql -uroot -pP@ssword1! -h127.0.0.1 -P6033 -e "select * from test2.t1;"
    

    查看规则匹配结果:

    admin> select * from stats_mysql_query_rules;
    +---------+------+
    | rule_id | hits |
    +---------+------+
    | 1       | 1    |
    | 2       | 1    |
    +---------+------+
     
    admin> select hostgroup hg,count_star cs,digest,digest_text dt from stats_mysql_query_digest;
    +----+----+--------------------+------------------------+
    | hg | cs | digest             | dt                     |
    +----+----+--------------------+------------------------+
    | 10 | 1  | 0x57497F236587B138 | select * from test1.t1 |
    | 20 | 1  | 0xADB885E1F3A7A5C2 | select * from test2.t1 |
    +----+----+--------------------+------------------------+
    

    显然,命中规则,且按照期望进行路由。

    如果想对match_digest取反,即不被正则匹配的SQL语句才命中规则,则设置mysql_query_rules表中的字段negate_match_pattern=1。同样适用于下面的match_pattern匹配方式。

    基于SQL语句路由:match_pattern

    和match_digest的匹配方式类似,但match_pattern是基于原始SQL语句进行匹配的,包括参数值。有两种情况必须使用match_pattern:

    • 重写SQL语句,即同时设置了replace_pattern字段。
    • 对参数的值进行匹配。

    如果想对match_pattern取反,即不被正则匹配的SQL语句才命中规则,则设置mysql_query_rules表中的字段negate_match_pattern=1。

    例如:

    ## 清空规则以及规则的统计数据
    delete from mysql_query_rules;
    select * from stats_mysql_query_digest_reset where 1=0;
     
    insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values(1,1,"^select .* test2.*",20,1),(2,1,"^select .* test1.*",10,1);
     
    load mysql query rules to runtime;
    save mysql query rules to disk;
    

    执行查询:

    mysql -uroot -pP@ssword1! -h127.0.0.1 -P6033 -e "select * from test1.t1;"
    mysql -uroot -pP@ssword1! -h127.0.0.1 -P6033 -e "select * from test2.t1;"
    

    然后查看匹配结果:

    admin> select * from stats_mysql_query_rules;
    +---------+------+
    | rule_id | hits |
    +---------+------+
    | 1       | 1    |
    | 2       | 1    |
    +---------+------+
     
    admin> select hostgroup hg,count_star cs,digest,digest_text dt from stats_mysql_query_digest;
    +----+----+--------------------+------------------------+
    | hg | cs | digest             | dt                     |
    +----+----+--------------------+------------------------+
    | 20 | 1  | 0xADB885E1F3A7A5C2 | select * from test2.t1 |
    | 10 | 1  | 0x57497F236587B138 | select * from test1.t1 |
    +----+----+--------------------+------------------------+
    

    再来看看匹配参数值(虽然几乎不会这样做)。这里要测试的语句如下:

    mysql -uroot -p123456 -h127.0.0.1 -P6033 -e "select * from test1.t1 where name like 'malong%';"
    mysql -uroot -p123456 -h127.0.0.1 -P6033 -e "select * from test2.t1 where name like 'xiaofang%';"
    

    现在插入两条规则,对参数"malong%"和"xiaofang"进行匹配。

    ## 清空规则以及规则的统计数据
    delete from mysql_query_rules;
    select * from stats_mysql_query_digest_reset where 1=0;
     
    insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values(1,1,"malong",20,1),(2,1,"xiaofang",10,1);
     
    load mysql query rules to runtime;
    save mysql query rules to disk;
    

    执行上面的两个查询语句,然后查看匹配结果:

    admin> select * from stats_mysql_query_rules;
    +---------+------+
    | rule_id | hits |
    +---------+------+
    | 1       | 1    |
    | 2       | 1    |
    +---------+------+
     
    admin> select hostgroup hg,count_star cs,digest,digest_text dt from stats_mysql_query_digest;
    +----+----+--------------------+------------------------------------------+
    | hg | cs | digest             | dt                                       |
    +----+----+--------------------+------------------------------------------+
    | 20 | 1  | 0x0C624EDC186F0217 | select * from test1.t1 where name like ? |
    | 10 | 1  | 0xA38442E236D915A7 | select * from test2.t1 where name like ? |
    +----+----+--------------------+------------------------------------------+
    

    已按预期进行路由。

    实用的读写分离

    一个极简单却大有用处的读、写分离功能:将默认路由组设置为写组,然后再插入下面两个select语句的规则。

    # 10为写组,20为读组
    insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply) VALUES (1,1,'^SELECT.*FOR UPDATE$',10,1),(2,1,'^SELECT',20,1);
    

    但需要注意的是,这样的规则只适用于小环境下的读写分离,对于稍复杂的环境,需要对不同语句进行开销分析,对于开销大的语句需要制定专门的路由规则。

    实践篇

    情况说明:已经知道具体的sql语句,并且要求这些sql语句走写所在组的查询(MySQL主从同步,数据时效性,个别sql语句查询走主库),且要求使用digest匹配规则

    比如SQL语句: (表前面一定要加数据库名)

    SELECT
      id, 
      open_id, 
      nick_name, 
      plate_no, 
      serial_no, 
      park_name, 
      park_code, 
      arm_code, 
      arm_name, 
      ip_addr, 
      park_log_id, 
      car_enter_id, 
      enter_time, 
      out_time, 
      charge_total_fee, 
      charge_due, 
      charge_unpaid, 
      charge_paid, 
      charge_duration, 
      charge_prepaid, 
      order_status_desc, 
      order_status, 
      version, 
      total_amt, 
      point_amt, 
      ecoupon_amt, 
      mer_disc_amt, 
      coupon_amt, 
      coupon_id, 
      platform_flag, 
      discount_param, 
      discount_type, 
      out_trade_no, 
      third_party_out_trade_no, 
      order_id, 
      pay_time, 
      total_disc_amt, 
      mer_id, 
      attach, 
      cust_id, 
      card_no, 
      bank_disc_amt, 
      payment_amt, 
      pay_type, 
      source_type, 
      bill_status, 
      car_type, 
      invoice_bill, 
      red_type, 
      red_invoice_bill, 
      coupon_use_flag, 
      create_time, 
      update_time, 
      reject_flag, 
      reject_amt, 
      medium_type, 
      real_charge, 
      out_coin_charge, 
      weixin_charge, 
      charge, 
      pay_channel, 
      transaction_id, 
      remark, 
      verify_status, 
      merchant_bill_id, 
      order_source, 
      sort_id, 
      pay_entrance, 
      trade_time, 
      third_attach, 
      payment_scenario, 
      goods_name, 
      report_status
    FROM
      park_cloud_db.park_order_info
      where car_enter_id='335401514161017511215104'  and order_status ='2' order by create_time desc;
    

    具体操作办法:

    1.获取该sql语句对应的digest值

    打开一个系统命令行窗口,执行下面的语句进行查询 (走的是proxysql配置的账号信息:user_proxysql,proxysql的端口号:6033)

    mysql -uuser_proxysql -p -h192.168.0.176 -P6033 -e "
    SELECT
      id, 
      open_id, 
      nick_name, 
      plate_no, 
      serial_no, 
      park_name, 
      park_code, 
      arm_code, 
      arm_name, 
      ip_addr, 
      park_log_id, 
      car_enter_id, 
      enter_time, 
      out_time, 
      charge_total_fee, 
      charge_due, 
      charge_unpaid, 
      charge_paid, 
      charge_duration, 
      charge_prepaid, 
      order_status_desc, 
      order_status, 
      version, 
      total_amt, 
      point_amt, 
      ecoupon_amt, 
      mer_disc_amt, 
      coupon_amt, 
      coupon_id, 
      platform_flag, 
      discount_param, 
      discount_type, 
      out_trade_no, 
      third_party_out_trade_no, 
      order_id, 
      pay_time, 
      total_disc_amt, 
      mer_id, 
      attach, 
      cust_id, 
      card_no, 
      bank_disc_amt, 
      payment_amt, 
      pay_type, 
      source_type, 
      bill_status, 
      car_type, 
      invoice_bill, 
      red_type, 
      red_invoice_bill, 
      coupon_use_flag, 
      create_time, 
      update_time, 
      reject_flag, 
      reject_amt, 
      medium_type, 
      real_charge, 
      out_coin_charge, 
      weixin_charge, 
      charge, 
      pay_channel, 
      transaction_id, 
      remark, 
      verify_status, 
      merchant_bill_id, 
      order_source, 
      sort_id, 
      pay_entrance, 
      trade_time, 
      third_attach, 
      payment_scenario, 
      goods_name, 
      report_status
    FROM 
      park_cloud_db.park_order_info
      where car_enter_id='335401514161017511215104'  and order_status ='2' order by create_time desc;"
    

    执行后输入密码进行查询。

    然后在新开一个命令行窗口,登录proxysql管理窗口:

    /usr/bin/mysql -uadmin -padmin -h 127.0.0.1 -P 6032
    

    执行如下语句进行匹配查询,获取上一步sql执行后获取的digest值

    select hostgroup hg,count_star,FROM_UNIXTIME(first_seen),sum_time,digest,digest_text from stats_mysql_query_digest order by first_seen DESC limit 5;
    

    1000是读组,根据sql语句后面的条件进行区分不同的sql语句,从而获取到digest值

    2.根据上一步获取的digest值添加近匹配规则中

    注意:mysql_query_rules表中的rule_id是有作用的,规则是按照rule_id的顺序进行处理的。

    # 查询规则,考虑把这个添加到第一个上,若已有1则可以进行修改,然后再添加
    select rule_id,active,digest,match_digest,match_pattern,destination_hostgroup,apply from mysql_query_rules;
    insert into mysql_query_rules(rule_id,active,digest,destination_hostgroup,apply) values (1,1,"0x719FE5F71C276C5A",100,1);
    
    # 同时添加多个的写法
    # insert into mysql_query_rules(rule_id,active,digest,destination_hostgroup,apply) values (80,1,"0x719FE5F71C276C5A",100,1),(81,1,"0xE8F7E13FF68362A4",100,1),(82,1,"0x2FCB0C6F738267C2",100,1),(83,1,"0x78891A8A66FA6E08",100,1),(84,1,"0x599C0D8234D854A0",100,1),(85,1,"0xC94F20CFAA43B207",100,1),(86,1,"0x9F0BEBB697D7C0BA",100,1),(87,1,"0x70A940C6A02F4FB5",100,1);
    
    load mysql query rules to runtime;
    save mysql query rules to disk;
    
    # 查询规则
    select rule_id,active,digest,match_digest,match_pattern,destination_hostgroup,apply from mysql_query_rules;
    



  • 相关阅读:
    JS 的加密库简介
    十三、行为型模式之解释器、迭代器-----《大话设计模式》
    十二、行为型模式之中介者、访问者、备忘录-----《大话设计模式》
    十一、行为型模式之模板方法、职责链、策略-----《大话设计模式》
    十、行为型模式之观察者、命令、状态-----《大话设计模式》
    十、行为型模式之观察者、命令、状态-----《大话设计模式》
    九、结构型模式之装饰、组合、外观、享元-----《大话设计模式》
    八、结构型模式之适配器、桥接、代理-----《大话设计模式》
    七、创建型模式之建造者、原型、单例-----《大话设计模式》
    六、创建型模式之工厂模式进化史-----《大话设计模式》
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/16382884.html
Copyright © 2020-2023  润新知