Da'sBlog

利用docker实现mysql主从同步/读写分离,附赠docker搭建mycat读写分离。

利用docker实现mysql主从同步/读写分离

为了保证数据的完整和安全,mysql设计了主从同步,一个挂掉还可以用另个。最近重构论坛,想来改成主从吧。担心失误,就先拿docker练练手。
有错误或者不理解的地方,可以联系本人邮箱sunhaokk@qq.com。

通过本文实际你会操作到。

  1. mysql的主从同步
  2. docker镜像和容器的创建
  3. docker容器间的数据传递
  4. mycat入门

以下需要大于100的智商和mysql基础docker基础,linux基础。

没有也没事,就是看着会有点吃力。

环境是centos,mycat是1.6.docker是1.12.6

下载mysql镜像。

docker pull mysql


ps:如果下载太慢,请添加腾讯源,依次执行
1
echo "OPTIONS='--registry-mirror=https://mirror.ccs.tencentyun.com'" >> /etc/sysconfig/docker
1
systemctl daemon-reload
1
service docker restart

或者直接去阿里仓库下https://dev.aliyun.com/search.html把上面的--registry-mirror=https://mirror.ccs.tencentyun.com换成你的专属源就可以

下载完输入

docker images
1
2
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/mysql latest 44a8e1a5c0b2 8 days ago 407 MB

利用mysql镜像,创建用于主从同步的两个新镜像。

我们当前所在的服务器叫宿主服务器

我们要利用docker 虚拟两个docker容器服务器,一个主服务器,一个从服务器。

创建master(主)和slave(从)两个文件夹

/usr/mysql/master
/usr/mysql/slave

在master和slave文件夹下 创建 Dockerfile 内容为

1
2
3
4
5
6
7
FROM mysql
COPY my.cnf /etc/mysql/
EXPOSE 3306
CMD ["mysqld"]

在master文件夹下 创建 my.cnf 内容为

1
2
3
4
5
[mysqld]
log-bin=mysql-bin //[必须]启用二进制日志
server-id=1//[必须]服务器唯一ID,默认是1,一般取IP最后一段,这里看情况分配

在slave文件夹下 创建 my.cnf 内容为

1
2
3
4
5
[mysqld]
log-bin=mysql-bin //[必须]启用二进制日志
server-id=2//[必须]服务器唯一ID,默认是1,一般取IP最后一段,这里看情况分配

切换到master目录下构建master/mysql镜像

docker build -t master/mysql .

(命令最后有个.,不要忘记,代表当前目录)

然后切换到slave目录下构建slave/mysql镜像

docker build -t slave/mysql .

(命令最后有个.,不要忘记,代表当前目录)

查看是否创建成功

1
2
3
4
5
[root@VM_118_220_centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
slave/mysql latest 8c496048d7ba About an hour ago 407 MB
master/mysql latest 7be30b0b631b 2 hours ago 407 MB
docker.io/mysql latest 44a8e1a5c0b2 8 days ago 407 MB

用镜像创建容器

1
2
3
docker run -p 3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=mysql -d master/mysql
docker run -p 3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=mysql -d slave/mysql

从这里开始,建议打开两个终端窗口,方便操作。

master终端执行
1
2
3
docker exec -it mysql-master bash
mysql -uroot -p

输入密码mysql进入到mysql环境

slave终端执行
1
2
3
docker exec -it mysql-slave bash
mysql -uroot -p

输入密码mysql进入到mysql环境

mysql主从配置

mysql配置

在主容器mysql中输入以下命令:

1
2
3
mysql>GRANT REPLICATION SLAVE ON *.* TO 'user'@'192.168.99.100' IDENTIFIED BY 'mysql';(指定ip)或者
mysql>GRANT REPLICATION SLAVE ON *.* to 'user'@'%' identified by 'mysql';(所有ip)

然后查看主容器数据库状态:

1
2
3
4
5
6
7
8
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 1338 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

记录File 的值和Position的值。

下面要用到,到这里为止,主库千万不要再做任何操作,防止状态改变。

然后我们配置一下从库

查看master/mysql的对外端口号

1
2
3
4
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d1e3b87d499 slave/mysql "docker-entrypoint.sh" 2 hours ago Up 2 hours 0.0.0.0:32769->3306/tcp mysql-slave
980e5ea48152 master/mysql "docker-entrypoint.sh" 2 hours ago Up 2 hours 0.0.0.0:32768->3306/tcp mysql-master

0.0.0.0:32768->3306/tcp其中32768为master的端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql>change master to
master_host='x.x.x.x',
master_user='user',
master_log_file='mysql-bin.000003',
master_log_pos=1201,
master_port=32768,
master_password='mysql';
Query OK, 0 rows affected, 2 warnings (0.03 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

master_host=’x.x.x.x’ //这里填master主机ip

master_log_file=’mysql-bin.000003’, //这里填写File 的值

master_log_pos=1338,//这里填写Position的值。

mysql> start slave;//启动从服务器复制功能

如果不小心配置错,输入mysql> stop slave;然后重新录入一遍

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql>change master to
master_host='x.x.x.x',
master_user='user',
master_log_file='mysql-bin.000003',
master_log_pos=1201,
master_port=32768,
master_password='mysql';

就可以了

检查主从连接状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: x.x.x.x
Master_User: user
Master_Port: 32768
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 1338
Relay_Log_File: 8d1e3b87d499-relay-bin.000002
Relay_Log_Pos: 1221
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1338
Relay_Log_Space: 1435
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: cd327a00-5e18-11e7-98f7-0242ac110006
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)

这两个必须是Yes 为No 或者connect说明没有连接上

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

测试主从连接

注意设置主从后,操作只能在master终端上,slave上的操作不会同步到master上。

登陆master终端,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mysql> create database sunhao;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sunhao |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> use sunhao
Database changed
mysql> create table sunhao(id int(3),name char(10));
Query OK, 0 rows affected (0.04 sec)
mysql> insert into sunhao values(1,'xiaoshuai');
Query OK, 1 row affected (0.01 sec)
mysql> select * from sunhao;
+------+-----------+
| id | name |
+------+-----------+
| 1 | xiaoshuai |
+------+-----------+
1 row in set (0.00 sec)

登陆slave服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sunhao |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> use sunhao
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from sunhao;
+------+-----------+
| id | name |
+------+-----------+
| 1 | xiaoshuai |
+------+-----------+

如果主服务器已经存在应用数据,则在进行主从复制时,需要单独复制处理(注意此操作,如果对从服务器单独录入的数据,会被覆盖掉。):

这里我们做一次完整的测试

(1)在主服务器数据库插入新的数据,并进行锁表操作,不让数据再进行写入动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> insert into sunhao values(2,'xiaoshuai');
Query OK, 1 row affected (0.01 sec)
mysql> select * from sunhao;
+------+-----------+
| id | name |
+------+-----------+
| 1 | xiaoshuai |
| 2 | xiaoshuai |
+------+-----------+
2 rows in set (0.00 sec)
mysql> FLUSH TABLES WITH READ LOCK;
mysql> show full processlist;
`

(2)退出mysql,用mysqldump备份数据文件到/var/lib,然后顺便多余的用tar打包一下玩。哈哈。

1
2
3
4
5
6
7
8
mysql> exit
Bye
root@980e5ea48152:/var/lib/mysql# mysqldump -u root -p sunhao > /var/lib/sunhao.dump
Enter password:
root@980e5ea48152:/var/lib# tar -zcvf ./sunhao.dump .tar ./sunhao.dump

(3)打开宿主服务器,复制mysql主服务器文件sunhao.dump.tar。到宿主服务器

1
2
3
4
5
6
7
8
9
10
11
12
[root]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d1e3b87d499 slave/mysql "docker-entrypoint.sh" 4 hours ago Up 4 hours 0.0.0.0:32769->3306/tcp mysql-slave
980e5ea48152 master/mysql "docker-entrypoint.sh" 4 hours ago Up 4 hours 0.0.0.0:32768->3306/tcp mysql-master
mkdir -p /var/mydata
docker cp 980e:/var/lib/sunhao.dump.tar /var/mydata/
cd /var/mydata
[root@VM_128_230_centos mydata]# ls
sunhao.dump.tar

解释:docker cp 980e:/var/lib/sunhao.dump.tar /var/mydata/

980e是980e5ea48152的缩写。保证不重复简写就可以

980e:/var/lib/sunhao.dump.tar 意思就是选中的容器下面你的文件下的sunhao.dump.tar文件

/var/mydata/ 目标文件

(4)在宿主主机上输入

[root]# docker cp /var/mydata/sunhao.dump.tar 8d1e3b87d49936414c0e91ffdc60a054e7f4ef8b15baee295350565519abba0e:/var/lib/

(5)在从服务器上输入

1
2
root@8d1e3b87d499:/# cd /var/lib/
root@8d1e3b87d499:/var/lib# tar -zcvf sunhao.dump.tar

(6)在从服务器上输入

1
2
3
tar -zxvpf /var/lib/mysqlbak.sql.tar
mysql -uroot -pmysql sunhao < /var/lib/sunhao.dump;

如果写入成功,这个时候就可以用select查询到数据。

(2)取消主服务器数据库锁定
mysql> UNLOCK TABLES;

docker搭建mycat读写分离

制作mycat容器,并运行

首先在本地新建个文件夹/usr/mycat。然后去mycat官网下载最新版本,这里我下载的是1.6版本。安装完解压到这里。

http://dl.mycat.io/
[http://dl.mycat.io/1.6-RELEASE/](http://dl.mycat.io/1.6-RELEASE/ "http://dl.mycat.io/1.6-RELEASE/")

编写Dockerfile,内容为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 来源镜像,因为mycat依赖java,所以这里直接选的java环境。
FROM java
RUN mkdir -p /var/local/mycat/
# Add复制Mycat到容器
ADD mycat/ /var/local/mycat/
ENTRYPOINT ["/var/local/mycat/bin/mycat","console","&"]
# 对外端口
EXPOSE 8066 9066
# 启动控制台
CMD ["/var/local/mycat/bin/mycat","console","&"]

先别急着构建镜像,我们先修改下mycat的配置文件。

[root@centos mycat]# ll
total 15324
-rw-r--r-- 1 root root      357 Jul  5 15:26 Dockerfile
-rw-r--r-- 1 root root 15662280 Jul  3 15:07 Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
drwxr-xr-x 7 root root     4096 Jul  5 15:27 mycat

在我用的1.6版本。mycat对外端口是注释掉的。我们要打开下。我们编辑/usr/mycat/mycat/conf/server.xml.找到第32-35行。去掉注释符号。

<!--
    <property name="serverPort">8066</property> <property name="managerPort">9066</property> 
    <property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property> 
    <property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->

我们往下看 有这么几句。这里分别默认两个用户。 name为root的管理员,可以进行读写。和普通用户只能进行读。我们也可以手动创建修改,另外password是密码 schemas是用户所能操作的库。 在这里我什么都没有改。下面都是默认。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<user name="root">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>

我们编辑/usr/mycat/mycat/conf/schema.xml,这个是我们配置分片和逻辑库表,规则的地方,数据节点,和数据源。其中schema是我们所操作的逻辑库。默认为TESTDB。下面分别是各个逻辑表。在这里直接默认。我只是为了区分dh和db两个字的区别,把db1-3改了data1-3你们可以不用管。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- auto sharding by id (long) -->
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<!-- global table is auto cloned to all defined data nodes ,so can join
with any table whose sharding node is in the same data node -->
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<!-- random sharding using mod sharind rule -->
<table name="hotnews" primaryKey="ID" autoIncrement="true" dataNode="dn1,dn2,dn3"
rule="mod-long" />
<!-- <table name="dual" primaryKey="ID" dataNode="dnx,dnoracle2" type="global"
needAddLimit="false"/> <table name="worker" primaryKey="ID" dataNode="jdbc_dn1,jdbc_dn2,jdbc_dn3"
rule="mod-long" /> -->
<table name="employee" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id"
parentKey="id">
<childTable name="order_items" joinKey="order_id"
parentKey="id" />
</childTable>
<childTable name="customer_addr" primaryKey="ID" joinKey="customer_id"
parentKey="id" />
</table>
<!-- <table name="oc_call" primaryKey="ID" dataNode="dn1$0-743" rule="latest-month-calldate"
/> -->
</schema>

修改37-45行 /usr/mycat/mycat/conf/wrapper.conf。设置java虚拟机内存。

1
2
3
4
5
# Initial Java Heap Size (in MB)
wrapper.java.initmemory=3
# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=64

在schema.xml往下修改。43-55行。数据源地址dataHost。这些就是我们的数据源,mycat把逻辑表的数据,读写都来源于我们配置地址。其中

writeHost写入源。设置多个,默认也只用第一个。readHost是读服务器。heartbeat是我们检测数据库是否正常运行的。

在这里 mycat 有两种配置方式。

分别是两个writeHost和一个writeHost一个readHost

第一种如果写入失败,还是可读。

第二种如果写入失败,不可读。

我们采用安全稳妥的方式。一个writeHost一个readHost

我的配置为

<dataHost name="localhost1" maxCon="1000" minCon="20" 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="115.159.124.18:32768" user="root"    password="mysql">
        <!-- can have multi read hosts -->
        <readHost host="hostS1" url="115.159.124.18:32769" user="root"    password="mysql" />

    </writeHost>

</dataHost>

hostM1和hostS1分别对应我们创建的两个docker容器的对外端口。

修改/usr/mycat/mycat/conf/log4j2.xml 这个是配置日志文件的,我们打开debug方便我们学习。修改第25行info为debug

1
2
3
4
5
6
<asyncRoot level="debug" includeLocation="true">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile"/>
</asyncRoot>

构建镜像

1
docker build -t sunhao/mycat:1.6 . 别忘了最后面的圆点

运行创建容器

1
docker run --name sunhaomycat -d -p 8066:8066 -p 9066:9066 sunhao/mycat:1.6

就那么简单。我们的mycat已经搭建成功了。测试下吧打开4个终端

1个宿主,1个mysql主,1个mysql从,1个用来看mycat日志。

宿主环境操作

在宿主终端上,安装mysql。并且连接我们的mycat。

1
2
3
4
5
6
7
8
9
10
[root@VM_128_230_centos mycat]# mysql -uroot -p123456 -h115.159.124.18 -P8066
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server (OpenCloundDB)
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>

完美,Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server 出现这,说明mycat运行了。

进行简单的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Database changed
MySQL [TESTDB]> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.00 sec)
MySQL [TESTDB]> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| company |
| customer |
| customer_addr |
| employee |
| goods |
| hotnews |
| orders |
| order_items |
| travelrecord |
+------------------+
9 rows in set (0.00 sec)
MySQL [TESTDB]>

测试下写入

1
2
3
4
5
6
7
8
MySQL [TESTDB]> create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int);
ERROR 1105 (HY000): Table 'travelrecord' already exists
MySQL [TESTDB]> insert into travelrecord(id,user_id,traveldate,fee,days) values(1,@@hostname,20170707,100,10);
Query OK, 1 row affected (0.01 sec)
MySQL [TESTDB]>
MySQL [TESTDB]> insert into travelrecord(id,user_id,traveldate,fee,days) values(10000001,@@hostname,20170707,100,10);
Query OK, 1 row affected (0.00 sec)

分别进入mysql主和mysql从可以看到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
MySQL [data2]> use data3
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [data3]> select * from travelrecord;
+----------+--------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+----------+--------------+------------+------+------+
| 10000001 | 980e5ea48152 | 2017-07-07 | 100 | 10 |
+----------+--------------+------------+------+------+
1 row in set (0.00 sec)
MySQL [data3]> use data1;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [data1]> select * from travelrecord;
+----+--------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+----+--------------+------------+------+------+
| 1 | 980e5ea48152 | 2017-07-07 | 100 | 10 |
+----+--------------+------------+------+------+
1 row in set (0.00 sec)
MySQL [data1]>

测试读取分离

打开一个终端,用

docker exec -it 61e74eee274d9d0f0404a572dec1d14c8b03dfd480e13d3c96fa04c534df0556  bash

进入我们的mycat容器

其中61e74为你的mycat容器

这个就是我们的日志终端

1
2
3
root@61e74eee274d:/var/local/mycat/logs# ls
2017-07 mycat.log mycat.pid wrapper.log
root@61e74eee274d:/var/local/mycat/logs# tail -f mycat.log

在宿主环境mycat下

输入

1
2
3
4
5
6
7
8
9
10
11
12
13
MySQL [TESTDB]> select * from travelrecord ;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 9
Current database: TESTDB
+----------+--------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+----------+--------------+------------+------+------+
| 1 | 980e5ea48152 | 2017-07-07 | 100 | 10 |
| 10000001 | 980e5ea48152 | 2017-07-07 | 100 | 10 |
+----------+--------------+------------+------+------+
2 rows in set (0.02 sec)

然后切回我们的日志终端,按ctrl+c中断。

然后输入cat tail 进行查看,很长在最后面找个空白的大坑(自己体会)慢慢找。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
017-07-07 06:28:16.863 DEBUG [$_NIOREACTOR-5-RW] (io.mycat.backend.datasource.PhysicalDatasource.releaseChannel(PhysicalDatasource.java:442)) - release channel MySQLConnection [id=5, lastTime=1499408896859, user=root, schema=data3, old shema=data3, borrowed=true, fromSlaveDB=false, threadId=527, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=115.159.184.18, port=32774, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
2017-07-07 06:28:16.864 DEBUG [$_NIOREACTOR-3-RW] (io.mycat.backend.datasource.PhysicalDatasource.releaseChannel(PhysicalDatasource.java:442)) - release channel MySQLConnection [id=33, lastTime=1499408896859, user=root, schema=data3, old shema=data3, borrowed=true, fromSlaveDB=true, threadId=108, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=115.159.184.18, port=32770, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
2017-07-07 06:28:24.473 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.net.FrontendConnection.query(FrontendConnection.java:288)) - ServerConnection [id=2, schema=TESTDB, host=115.159.184.18, user=root,txIsolation=3, autocommit=true, schema=TESTDB] select * from travelrecord
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.server.ServerQueryHandler.query(ServerQueryHandler.java:57)) - ServerConnection [id=2, schema=TESTDB, host=115.159.184.18, user=root,txIsolation=3, autocommit=true, schema=TESTDB]select * from travelrecord
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.cache.impl.EnchachePool.get(EnchachePool.java:71)) - SQLRouteCache hit cache ,key:TESTDBselect * from travelrecord
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.server.NonBlockingSession.execute(NonBlockingSession.java:110)) - ServerConnection [id=2, schema=TESTDB, host=115.159.184.18, user=root,txIsolation=3, autocommit=true, schema=TESTDB]select * from travelrecord, route={
1 -> dn1{SELECT *
FROM travelrecord
LIMIT 100}
2 -> dn2{SELECT *
FROM travelrecord
LIMIT 100}
3 -> dn3{SELECT *
FROM travelrecord
LIMIT 100}
} rrs
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.<init>(MultiNodeQueryHandler.java:101)) - execute mutinode query select * from travelrecord
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.<init>(MultiNodeQueryHandler.java:137)) - has data merge logic
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.execute(MultiNodeQueryHandler.java:170)) - rrs.getRunOnSlave()-null
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.execute(MultiNodeQueryHandler.java:180)) - node.getRunOnSlave()1-null
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.execute(MultiNodeQueryHandler.java:182)) - node.getRunOnSlave()2-null
2017-07-07 06:28:24.474 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBNode.getConnection(PhysicalDBNode.java:96)) - rrs.getRunOnSlave() null
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBNode.getConnection(PhysicalDBNode.java:127)) - rrs.getRunOnSlave() null
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBPool.getRWBanlanceCon(PhysicalDBPool.java:456)) - select read source hostS1 for dataHost:localhost1
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.execute(MultiNodeQueryHandler.java:180)) - node.getRunOnSlave()1-null
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.execute(MultiNodeQueryHandler.java:182)) - node.getRunOnSlave()2-null
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBNode.getConnection(PhysicalDBNode.java:96)) - rrs.getRunOnSlave() null
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBNode.getConnection(PhysicalDBNode.java:127)) - rrs.getRunOnSlave() null
就是这了我们可以看到select read source hostS1 for dataHost:localhost1来至哪个服务器
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBPool.getRWBanlanceCon(PhysicalDBPool.java:456)) - select read source hostS1 for dataHost:localhost1
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.execute(MultiNodeQueryHandler.java:180)) - node.getRunOnSlave()1-null
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.mysql.nio.handler.MultiNodeQueryHandler.execute(MultiNodeQueryHandler.java:182)) - node.getRunOnSlave()2-null
2017-07-07 06:28:24.475 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBNode.getConnection(PhysicalDBNode.java:96)) - rrs.getRunOnSlave() null
2017-07-07 06:28:24.476 DEBUG [$_NIOREACTOR-29-RW] (io.mycat.backend.datasource.PhysicalDBNode.getConnection

如果配置不小心错了,可以用docker cp 复制到镜像里,然后重启镜像

1
2
3
docker cp /usr/mycat/mycat/conf 61e74eee274d9d0f0404a572dec1d14c8b03dfd480e13d3c96fa04c534df0556:/var/local/mycat/conf
docker restart 61e74eee274d9d0f0404a572dec1d14c8b03dfd480e13d3c96fa04c534df0556

总结,如果运行中docker过会就掉了,说明配置出错,会运行有问题。请仔细检查配置。docker用来单机测试堪称完美,对于资源不足,环境变化大的。方便太多。推荐大家多做练习。

坚持原创技术分享,您的支持将鼓励我继续创作!