zoukankan      html  css  js  c++  java
  • mycat读写分离与主从切换

    1, 分库分表的优缺点、以及为什么分表方式无法成为主流?

    分表:在台server上,长处是易维护,相似表分区。缺点是在一台dbserver上。无法分担IO、负载集中。


    分库:在多台server上,长处是分担IO、负载均衡,缺点是较不易维护、数据统计以及jion操作有些难度。

    数据库切分的目的是为了分担IO、负载均衡,分表无法达到最佳的要求。所以无法成为主流。


    2, 准备主库

    tar -xvf mysql-5.6.12.tar.gz
    cd mysql-5.6.12
    
    time cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql56m1 -DMYSQL_DATADIR=/home/data/mysql56m1/data -DWITH_INNOBASE_STORAGE_ENGINE=1 -DMYSQL_UNIX_ADDR==/usr/local/mysql56m1/mysql.sock -DMYSQL_USER=mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
    
    time make
    time make install 
    
     chown -R mysql /home/data/
     chgrp -R mysql /home/data/
     chown -R mysql /usr/local/mysql
    
     chown -R mysql /usr/local/mysql56m1
     chgrp -R mysql /usr/local/mysql
    
     chgrp -R mysql /usr/local/mysql56m1/
     mkdir -p /home/data/mysql56m1/binlog/
     chown -R mysql.mysql /home/data/mysql56m1/binlog/
     mkdir -p /home/data/mysql5610/binlog/
     chown -R mysql.mysql /home/data/
    
    cd /usr/local/mysql56m1
    time scripts/mysql_install_db  --user=mysql --basedir=/usr/local/mysql56m1 --datadir=/home/data/mysql56m1/data --defaults-file=/usr/local/mysql56m1/my.cnf
    
    cp support-files/mysql.server /etc/init.d/mysql56m1
    chmod 700 /etc/init.d/mysql56m1
    echo "export PATH=$PATH:/usr/local/mysql56m1/bin">>/etc/profile 
    source /etc/profile
    chkconfig --add mysql56m1
    
    service mysql56m1 start

    3。 准备备库

    tar -xvf mysql-5.6.12.tar.gz
    cd mysql-5.6.12
    
    time cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql56s1 -DMYSQL_DATADIR=/home/data/mysql56s1/data -DWITH_INNOBASE_STORAGE_ENGINE=1 -DMYSQL_UNIX_ADDR==/usr/local/mysql56s1/mysql.sock -DMYSQL_USER=mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
    
    time make
    time make install 
    
    
     chown -R mysql /home/data/
     chgrp -R mysql /home/data/
     chown -R mysql /usr/local/mysql
    
     chown -R mysql /usr/local/mysql56s1
     chgrp -R mysql /usr/local/mysql
    
     chgrp -R mysql /usr/local/mysql56s1/
     mkdir -p /home/data/mysql56s1/binlog/
     chown -R mysql.mysql /home/data/mysql56s1/binlog/
     mkdir -p /home/data/mysql5610/binlog/
     chown -R mysql.mysql /home/data/
    
    
    cd /usr/local/mysql56s1
    time scripts/mysql_install_db  --user=mysql --basedir=/usr/local/mysql56s1 --datadir=/home/data/mysql56s1/data --defaults-file=/usr/local/mysql56s1/my.cnf
    
    cp support-files/mysql.server /etc/init.d/mysql56s1
    chmod 700 /etc/init.d/mysql56s1
    echo "export PATH=$PATH:/usr/local/mysql56s1/bin">>/etc/profile 
    source /etc/profile
    chkconfig --add mysql56s1
    service mysql56s1 start

    4, 搭建主从环境

    在一台server。主3317端口,从3327端口。
    主库备库上,加入复制帐号:

    GRANT REPLICATION SLAVE ON . TO ‘repl’@’10.254.%’ IDENTIFIED BY ‘mycatms’;

    在备库上3327端口上设置复制:

    stop slave;
    reset slave;
    change master to master_user='repl', master_password='mycatms', master_host='127.0.0.1',master_port=3317, master_log_file='mysql-bin.000003',master_log_pos=840;
    start slave;
    show slave statusG;

    主库:3317端口
    这里写图片描写叙述

    从库:3327端口

    这里写图片描写叙述

    数据同步測试:
    这里写图片描写叙述


    5。 数据同步測试:

    配置schema.xml:
    然后改动mycat的schema.xml:
    balance为1:让所有的readHost及备用的writeHost參与select的负载均衡。


    switchType为2:基于MySQL主从同步的状态决定是否切换。


    heartbeat:主从切换的心跳语句必须为show slave status。
    这里写图片描写叙述

    5.0 数据录入:

    mysql> explain create table company(id int not null primary key,name varchar(100));
    +-----------+---------------------------------------------------------------------+
    | DATA_NODE | SQL                                                                 |
    +-----------+---------------------------------------------------------------------+
    | dn1       | create table company(id int not null primary key,name varchar(100)) |
    | dn2       | create table company(id int not null primary key,name varchar(100)) |
    | dn3       | create table company(id int not null primary key,name varchar(100)) |
    +-----------+---------------------------------------------------------------------+
    3 rows in set (0.00 sec)
    
    mysql> create table company(id int not null primary key,name varchar(100));
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> explain  insert into company(id,name) values(1,'alibaba');
    +-----------+--------------------------------------------------+
    | DATA_NODE | SQL                                              |
    +-----------+--------------------------------------------------+
    | dn1       | insert into company(id,name) values(1,'alibaba') |
    | dn2       | insert into company(id,name) values(1,'alibaba') |
    | dn3       | insert into company(id,name) values(1,'alibaba') |
    +-----------+--------------------------------------------------+
    3 rows in set (0.10 sec)
    
    mysql>  insert into company(id,name) values(1,'alibaba');
    Query OK, 1 row affected (0.00 sec)
    
    mysql>

    5.1主库验证:

    [root@wgq_idc_squid_1_11 logs]# /usr/local/mysql56m1/bin/mysql -uroot -p -P3317 --socket=/usr/local/mysql56m1/mysql.sock -e "select @@port;select * from db1.company";
    Enter password: 
    +--------+
    | @@port |
    +--------+
    |   3317 |
    +--------+
    +----+---------+
    | id | name    |
    +----+---------+
    |  1 | alibaba |
    +----+---------+
    [root@wgq_idc_squid_1_11 logs]#

    5.2从库验证:

    [root@wgq_idc_squid_1_11 logs]# /usr/local/mysql56s1/bin/mysql -uroot -p -P3327 --socket=/usr/local/mysql56s1/mysql.sock -e "select @@port;select * from db1.company";
    Enter password: 
    +--------+
    | @@port |
    +--------+
    |   3327 |
    +--------+
    +----+---------+
    | id | name    |
    +----+---------+
    |  1 | alibaba |
    +----+---------+
    [root@wgq_idc_squid_1_11 logs]#

    这里写图片描写叙述


    6,读写分离模式

    6.1然后改动mycat的schema.xml:

    balance为1:让所有的readHost及备用的writeHost參与select的负载均衡。


    switchType为2:基于MySQL主从同步的状态决定是否切换。
    heartbeat:主从切换的心跳语句必须为show slave status。


    这里写图片描写叙述
    有配置读节点:
    这里写图片描写叙述

    6.2 打开debug模式

    [root@wgq_idc_squid_1_11 conf]# vim log4j.xml
    <level value="info" /> 变成  <level value="debug" />

    6.3 运行查询读操作

    在mycat窗体上运行select操作:

    mysql> explain select * from company where id=1;
    +-----------+----------------------------------------------+
    | DATA_NODE | SQL                                          |
    +-----------+----------------------------------------------+
    | dn3       | SELECT * FROM company WHERE id = 1 LIMIT 100 |
    +-----------+----------------------------------------------+
    1 row in set (0.14 sec)
    
    mysql> select * from company where id=1;
    +----+---------+
    | id | name    |
    +----+---------+
    |  1 | alibaba |
    +----+---------+
    1 row in set (0.01 sec)
    
    mysql>

    后台日志显示出仅仅在3327上运行:

    01/18 01:35:01.536  DEBUG [$_NIOREACTOR-3-RW] (PhysicalDBPool.java:452) -select read source hostS2 for dataHost:wgq_idc_mon_1_11
    01/18 01:35:01.537  DEBUG [$_NIOREACTOR-3-RW] (MySQLConnection.java:445) -con need syn ,total syn cmd 2 commands SET names latin1;SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;schema change:false con:MySQLConnection [id=14, lastTime=1453052101537, user=root, schema=db1, old shema=db1, borrowed=true, fromSlaveDB=false, threadId=3326, charset=latin1, txIsolation=0, autocommit=true, attachment=dn1{SELECT *
    FROM company
    WHERE id = 1
    LIMIT 100}, respHandler=SingleNodeHandler [node=dn1{SELECT *
    FROM company
    WHERE id = 1
    LIMIT 100}, packetId=0], host=127.0.0.1, port=3327, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
    01/18 01:35:01.546  DEBUG [$_NIOREACTOR-2-RW] (NonBlockingSession.java:229) -release connection MySQLConnection [id=14, lastTime=1453052101529, user=root, schema=db1, old shema=db1, borrowed=true, fromSlaveDB=false, threadId=3326, charset=latin1, txIsolation=3, autocommit=true, attachment=dn1{SELECT *
    FROM company
    WHERE id = 1
    LIMIT 100}, respHandler=SingleNodeHandler [node=dn1{SELECT *
    FROM company
    WHERE id = 1
    LIMIT 100}, packetId=5], host=127.0.0.1, port=3327, statusSync=org.opencloudb.mysql.nio.MySQLConnection$StatusSync@7fb43f0f, writeQueue=0, modifiedSQLExecuted=false]
    01/18 01:35:01.547  DEBUG [$_NIOREACTOR-2-RW] (PhysicalDatasource.java:403) -release channel MySQLConnection [id=14, lastTime=1453052101529, user=root, schema=db1, old shema=db1, borrowed=true, fromSlaveDB=false, threadId=3326, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=127.0.0.1, port=3327, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
    ^C

    这里写图片描写叙述

    6.4 运行写操作

    Mycat窗体写操作:
    这里写图片描写叙述

    后台log显示写操作在3317上:
    这里写图片描写叙述

    01/18 01:39:54.550  DEBUG [$_NIOREACTOR-3-RW] (NonBlockingSession.java:229) -release connection MySQLConnection [id=7, lastTime=1453052394535, user=root, schema=db3, old shema=db3, borrowed=true, fromSlaveDB=false, threadId=163, charset=latin1, txIsolation=3, autocommit=true, attachment=dn3{insert into company values(3,'baidu')}, respHandler=org.opencloudb.mysql.nio.handler.MultiNodeQueryHandler@42bed1e7, host=127.0.0.1, port=3317, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
    01/18 01:39:54.550  DEBUG [$_NIOREACTOR-3-RW] (PhysicalDatasource.java:403) -release channel MySQLConnection [id=7, lastTime=1453052394535, user=root, schema=db3, old shema=db3, borrowed=true, fromSlaveDB=false, threadId=163, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=127.0.0.1, port=3317, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
    01/18 01:39:54.550  DEBUG [$_NIOREACTOR-3-RW] (MultiNodeQueryHandler.java:171) -received ok response ,executeResponse:true from MySQLConnection [id=3, lastTime=1453052394535, user=root, schema=db2, old shema=db2, borrowed=true, fromSlaveDB=false, threadId=162, charset=latin1, txIsolation=3, autocommit=true, attachment=dn2{insert into company values(3,'baidu')}, respHandler=org.opencloudb.mysql.nio.handler.MultiNodeQueryHandler@42bed1e7, host=127.0.0.1, port=3317, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
    01/18 01:39:54.551  DEBUG [$_NIOREACTOR-3-RW] (NonBlockingSession.java:229) -release connection MySQLConnection [id=3, lastTime=1453052394535, user=root, schema=db2, old shema=db2, borrowed=true, fromSlaveDB=false, threadId=162, charset=latin1, txIsolation=3, autocommit=true, attachment=dn2{insert into company values(3,'baidu')}, respHandler=org.opencloudb.mysql.nio.handler.MultiNodeQueryHandler@42bed1e7, host=127.0.0.1, port=3317, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
    01/18 01:39:54.551  DEBUG [$_NIOREACTOR-3-RW] (PhysicalDatasource.java:403) -release channel MySQLConnection [id=3, lastTime=1453052394535, user=root, schema=db2, old shema=db2, borrowed=true, fromSlaveDB=false, threadId=162, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=127.0.0.1, port=3317, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]

    Check下主从数据是否都已经写入了:
    主库3317端口:
    这里写图片描写叙述
    从裤3327端口:
    这里写图片描写叙述


    7,主从切换測试

    7.1 mycat托管配置例如以下

         <dataHost name="wgq_idc_mon_1_11" maxCon="1000" minCon="10" balance="1"
                    writeType="0" dbType="mysql" dbDriver="native" switchType="2"  slaveThreshold="100">
                    <heartbeat>show slave status</heartbeat>
                    <!-- can have multi write hosts -->
                    <writeHost host="hostM1" url="127.0.0.1:3317" user="root" password="">
                            <readHost host="hostR1" url="127.0.0.1:3327" user="root" password=""/>
                    </writeHost>
                    <writeHost host="hostS2" url="127.0.0.1:3327" user="root" password="" />
            </dataHost>

    7.2 关闭主库。写操作切换到从裤3327端口

    关闭主库
    这里写图片描写叙述

    [root@wgq_idc_squid_1_11 conf]# service mysql56m1 stop
    Shutting down MySQL....                                    [确定]
    [root@wgq_idc_squid_1_11 conf]#

    Mycat后台报错:

    01/18 01:50:01.037   INFO [Timer0] (PhysicalDatasource.java:373) -not ilde connection in pool,create new connection for hostM1 of schema db1
    01/18 01:50:01.038   INFO [$_NIOConnector] (AbstractConnection.java:458) -close connection,reason:java.net.ConnectException: 拒绝连接 ,MySQLConnection [id=0, lastTime=1453053001035, user=root, schema=db1, old shema=db1, borrowed=false, fromSlaveDB=false, threadId=0, charset=utf8, txIsolation=0, autocommit=true, attachment=null, respHandler=null, host=127.0.0.1, port=3317, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
    01/18 01:50:01.038   INFO [$_NIOConnector] (SQLJob.java:111) -can't get connection for sql :show slave status
    01/18 01:50:01.038   WARN [$_NIOREACTOR-1-RW] (MySQLDetector.java:139) -found MySQL master/slave Replication err !!! DBHostConfig [hostName=hostR1, url=127.0.0.1:3327]error reconnecting to master 'repl@127.0.0.1:3317' - retry-time: 60  retries: 1
    0

    看到主从失效,由于主down了。

    由于我们通过mycat配置了主从切换模式,如今3317端口主库down了,那么写库应该自己主动切换到从裤3327上面,假设在mycat上面写入。就应该写到3327端口的从库了,验证例如以下:
    (1)在mycat窗体录入数据:
    这里写图片描写叙述
    (2)在3327端口从裤验证数据:
    这里写图片描写叙述

    看到3327端口的数据有新录入的4,meituan的数据。

    表明验证成功。
    (3) dnindex属性文件里writeHost已经变成了第二个了,例如以下所看到的:
    这里写图片描写叙述

    7.3 再启动原来的主库3317端口,在mycat上做写操作,后台mysql写库还是原来的从库3327端口:

    这个时候就会报错,主从连接失败,原因是从库3327会再又一次从主库3317同步所有的数据,可是从库已经有了,所以就会报错,例如以下所看到的:
    这里写图片描写叙述

    我採用

    stop slave;
     set global sql_slave_skip_counter=1;
     start slave;
     show slave statusG;

    一个个忽略过后。就正常了。没有报错:
    这里写图片描写叙述

    可是这个时候假设再在mycat窗体上录入数据。debug分析面。还是会写入到3327里面去:
    这里写图片描写叙述

    后台debug日志:
    这里写图片描写叙述

    OK,至此。mycat主从切换成功。

  • 相关阅读:
    CI框架源码研读(整体架构)
    PHP微信公众号后台开发(Yii2实现)
    PHP后台支付的开发:微信支付和支付宝支付
    linux安装netcat 运行udp服务器
    运行swoole_server方法
    bind (ERROR 502): bind(0.0.0.0:9501) failed. Error: Address already in use [98] (端口被占用)
    随机生成红包算法
    获取分类算法
    PHP中的关系判断和注释
    php中自运算++ 或-- 的总结
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7274610.html
Copyright © 2011-2022 走看看