zoukankan      html  css  js  c++  java
  • Mycat 注解说明

    我们知道MySQL 数据库有自己的SQL注解(hint),比如 use index、force index、ignore index 等都是会经常用到的,Mycat 作为一个数据库中间件,最重要的是 SQL 路由,所以 Mycat 中的注解基本上都是和路由功能相关。

    主从路由注解

    该注解用于解决MySQL 数据库的主从同步延迟的问题,由于对于数据库读写分离架构的系统,其 slave 可能会存在一定的复制延迟,在一些业务上不能接受任何延迟的 select 语句就可以使用该注解,强制其在 master 执行,主从路由注解的基本原理是根据注解的值是 master 还是 slave,分别获取对应的 writeHost 或 readHost 的数据库连接,来执行 SQL 语句,示例代码如下:

    mysql> /*!mycat:db_type=slave*/select * from tb_sharding_murmur where id= 199

    通过查询日志可以发现,其 hintSQLValue 值为 slave,getRunOnSlave() 为 true,表示路由到了 salve 数据库,日志如下:

    2018-02-14 00:10:32.077 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.route.handler.HintMasterDBHandler.route(HintMasterDBHandler.java:45)) - schema.rrs(): select * from tb_sharding_murmur where id= 199, route={

    1 -> vmDB2-tempdb{select * from tb_sharding_murmur where id= 199}

    }

    2018-02-14 00:10:32.077 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.route.handler.HintMasterDBHandler.route(HintMasterDBHandler.java:48)) - hintSQLValue:::::::::slave

    2018-02-14 00:10:32.078 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.route.handler.HintMasterDBHandler.route(HintMasterDBHandler.java:85)) - rrs.getRunOnSlave():true

    修改查询语句,指定从 master 查询,示例代码如下:

    mysql> /*!mycat:db_type=master*/select * from tb_sharding_murmur where id= 199

    通过查询日志可以发现,其 hintSQLValue 值为 master,getRunOnSlave() 为 false,表示路由到了 salve 数据库,日志如下:

    2018-02-14 00:10:36.538 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.route.handler.HintMasterDBHandler.route(HintMasterDBHandler.java:45)) - schema.rrs(): select * from tb_sharding_murmur where id= 199, route={

    1 -> vmDB2-tempdb{select * from tb_sharding_murmur where id= 199}

    }

    2018-02-14 00:10:36.538 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.route.handler.HintMasterDBHandler.route(HintMasterDBHandler.java:48)) - hintSQLValue:::::::::master

    2018-02-14 00:10:36.538 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.route.handler.HintMasterDBHandler.route(HintMasterDBHandler.java:85)) - rrs.getRunOnSlave():false

    2018-02-14 00:10:36.538 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.server.NonBlockingSession.execute(NonBlockingSession.java:110)) - ServerConnection [id=1, schema=TEMPDB, host=192.168.2.109, user=mycat,txIsolation=3, autocommit=true, schema=TEMPDB]select * from tb_sharding_murmur where id= 199, route={

    1 -> vmDB2-tempdb{select * from tb_sharding_murmur where id= 199}

    } rrs

    2018-02-14 00:10:36.538 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.SingleNodeHandler.execute(SingleNodeHandler.java:166)) - rrs.getRunOnSlave() false

    SQL 注解

    SQL 注解部分是一条SQL语句,称其为注解SQL;被注解的部分也是一条SQL语句,称为原始SQL。其原理就是用解析注解SQL的路由结果,来执行被注解的SQL语句。其处理过程是先对注解中的SQL语句进行解析,得到路由结果,然后将被注解的SQL语句在该路由结果表示的数据库分片上执行,因为注解SQL仅仅用于获取路由结果,因此一般尽量使其为一条简单的select 语句,使用分片键所在字段即可。而原始的SQL语句可以是 select、delete、update、insert、call 等

    • 在指定dataNode中创建存储过程示例
      • 查询指定的SQL分配到的 dataNode,通过在 SQL 语句前增加 explain 关键字,示例如下:

        mysql> EXPLAIN select id from tb_sharding_murmur where id = 199;

        查询结果如下:

        可以看到其 dataNode 为 vmDB2-tempdb

      • 我们通过SQL注解在 vmDB2-tempdb 来创建一个存储过程,示例如下:

        mysql> set autocommit=0; /* 此处必须的,SQL注解的缺陷*/

        Query OK, 0 rows affected (0.00 sec)

        mysql> delimiter //

        mysql> /*!mycat:sql=select id from tb_sharding_murmur where id = 199*/

        -> create procedure test_sql_hint_proc()

        -> begin

        -> select 1;

        -> end;

        -> //

        Query OK, 0 rows affected (0.20 sec)

        mysql> set autocommit=1;

        Query OK, 0 rows affected (0.00 sec)d

      • 我们直连 vmDB2-tempdb 的 MySQL,查询该数据库中是否有该存储过程,示例如下:

        mysql> select name from mysql.proc where db='tempdb' and type='PROCEDURE';

        查询结果如下:

    • 使用 SQL 注解调用指定 dataNode 上的存储过程

      mysql> /*!mycat:sql=select id from tb_sharding_murmur where id = 199*/call test_sql_hint_proc();

      执行结果如下:

    • 使用SQL注解来支持 insert select 语句

      Mycat 是不支持 insert select 语句的,原因是该语句需要在所以分片上执行,显然对事物不好控制,例如,一个分片执行成功,而另一个分片执行失败,那么该如何处理,通过SQL注解就可以实现某一个分片的 insert select 语句,示例如下:

      • 创建相同表结构的表

        mysql> create table tb_sharding_murmur_cp like tb_sharding_murmur;

      • 在 mycat 中的 schema.xml 中,增加 tb_sharding_murmur_cp 的表配置,并重新加载配置

        <table name="tb_sharding_murmur_cp" dataNode="vmDB1-tempdb,vmDB2-tempdb" primaryKey="id" rule="sharding-by-murmur"/>

      • 连接 mycat 执行下面的命令

        mysql> set autocommit=0;

        Query OK, 0 rows affected (0.02 sec)

           

        mysql> /*!mycat:sql=select id from tb_sharding_murmur where id=199*/insert into tb_sharding_murmur_cp select * from tb_sharding_murmur;

        Query OK, 3276 rows affected (0.57 sec)

        Records: 3276 Duplicates: 0 Warnings: 0

           

        mysql> set autocommit=1;

        Query OK, 0 rows affected (0.00 sec)

           

           

  • 相关阅读:
    Tomcat配置JNDI
    (转)通过反编译深入理解Java String及intern
    (转)Java8内存模型-永久代(PermGen)和元空间(Metaspace)
    排序算法
    并发编程
    MySQL
    Go语言
    Go语言
    Go语言
    Go语言
  • 原文地址:https://www.cnblogs.com/li3807/p/8461886.html
Copyright © 2011-2022 走看看