公司原先只有一台mysql,现在业务量上来,像实现读写分离,于是在虚拟机先练习了一下
实现环境
node01 10.0.0.17 Centos7.9 jdk1.8 mycat中间件 mycat--1.6.7.3 node01 10.0.0.17 Centos7.9 jdk1.8 master mysql--5.7.29 node01 10.0.0.18 Centos7.9 jdk1.8 salve mysql--5.7.29
实现主从复制
记得serverid要不一样,从节点在配置文件中加上read-only设置,
配置文件中加bind-address = 0.0.0.0,允许外部连接
主节点
mysql> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| node01-bin.000001 | 154 |
+-------------------+-----------+
1 row in set (0.00 sec)
从节点
mysql> CHANGE MASTER TO
-> MASTER_HOST='10.0.0.17',
-> MASTER_USER='repluser',
-> MASTER_PASSWORD='123456',
-> MASTER_PORT=3306,
-> MASTER_LOG_FILE='node01-bin.000001', MASTER_LOG_POS=154;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
测试
主节点
mysql> use db1;
Database changed
mysql> CREATE TABLE stu (
-> id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-> name VARCHAR(20) NOT NULL,
-> age tinyint UNSIGNED,
-> gender ENUM('M','F') default 'M'
-> )ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into stu(name,age)values('tom',10);
Query OK, 1 row affected (0.00 sec)
从节点
mysql> show databases like '%db1%';
+------------------+
| Database (%db1%) |
+------------------+
| db1 |
+------------------+
1 row in set (0.00 sec)
mysql> select * from db1.stu;
+----+------+------+--------+
| id | name | age | gender |
+----+------+------+--------+
| 1 | tom | 10 | M |
+----+------+------+--------+
1 row in set (0.00 sec)
#在master节点上创建账号并授权,该帐号会被同步到 slave 节点
mysql> create user 'mycat'@'10.0.0.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL ON db1.* TO 'mycat'@'10.0.0.%';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
Mycat安装
使用mycat中间件搭建读写分离,那么应访问的是mycat中间件,再由mycat访问主从服务器。须jjdk环境为1.7以上,
解压文件并创建用户授权目录
[root@node01 data]# tar zxf Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz -C /usr/local/
root@node01 mycat]#useradd mycat
[root@node01 mycat]#echo "mycat:123456" | chpasswd
[root@node01 mycat]#chown -R mycat:mycat /usr/local/mycat/
[root@node01 mycat]#ll /usr/local/mycat/
total 12
drwxr-xr-x 2 mycat mycat 190 Nov 5 11:17 bin
drwxrwxrwx 2 mycat mycat 6 Jul 18 2019 catlet
drwxrwxrwx 4 mycat mycat 4096 Nov 5 11:17 conf
drwxr-xr-x 2 mycat mycat 4096 Nov 5 11:17 lib
drwxrwxrwx 2 mycat mycat 6 Sep 9 2019 logs
-rwxrwxrwx 1 mycat mycat 227 Sep 27 2019 version.txt
conf目录下存放了配置文件,其中server.xml是Mycat服务器参数调整和用户授权的配置文件,schema.xml是逻辑库、表和分片定义的配置文件,rule.xml是分片规则的配置文件。另外分片规则的一些具体参数信息单独作为一个文件,也是存放在这个目录下。配置文件修改后,需要重启Mycat或者通过9066端口reload
Linux下部署安装MySQL,默认不忽略表名大小写,需要手动到/etc/my.cnf下配置lower_case_table_names=1,使Linux环境下MySQL忽略表名大小写,否则使用MyCAT的时候会提示找不到表的错误!
修改配置文件
添加环境变量并加载
[root@node01 ~]#cat /etc/profile.d/mycat.sh
#!/bin/bash
MYCAT_HOME=/usr/local/mycat
PATH=$MYCAT_HOME/bin:$PATH
[root@node01 ~]#source /etc/profile.d/mycat.sh
配置mycat本身的用户信息server.xml文件
[root@node01 ~]#vim /usr/local/mycat/conf/server.xml
//直接拉到最后修改<user>部分,设置访问mycat的用户信息,以及其能够访问的逻辑库
<user name="mycat" defaultAccount="true"> //设置用户名。如果存在defaultAccount="true",则表示在不指定用户的情况下,默认以该用户访问mycat。
<property name="password">123456</property>
<property name="schemas">db1</property>//能够访问的逻辑库(虚拟库),逻辑库需要在同目录下的schema.xml定义
<property name="defaultSchema">db1</property> //<!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="lala" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
配置schema.xml文件
[root@node01 ~]#vim /usr/local/mycat/conf/schema.xml
<schema name="db1" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn1'>
/*name是逻辑库名;
*checkSQLschema默认为false,含义为是否去掉表名前的逻辑库名,只能去除当前定义的逻辑库名;
*sqlMaxLimit是隐式limit,如果查询没有定义limit,则自动加上limit;
*dataNode指定所属的数据节点,也就是常说的数据分片。*/
<dataNode name="dn1" dataHost="dthost" database="db1" />
//dataNote标签用于定义数据节点。name是数据节点名称;dataHost指定所属数据库实例;database指定数据库实例上的实际数据库名(要和真实数据库一样的名字)。
<dataHost name="dthost" maxCon="1000" minCon="10" balance="3"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
/*dataHost标签用于定义数据库实例。
*name数据库实例名称;
*maxCon指定每个读写实例连接池的最大连接;
*minCon指定每个读写实例连接池的最小连接,初始化连接池的大小
*balance负载均衡类型。0表示不开启读写分离,所有读操作(select查询)都发送到当前writeHost上。1表示全部的readHost和备用writeHost都参与读操作(select查询)的负载均衡。2表示读操作随机在writeHost和readHost上发布。3表示所有读操作随机分发到当前writeHost对应的readHost上执行,writeHost不用执行。
*writeType负载均衡类型。0表示所有写操作发送到配置的第一个writeHost,挂了后切换到还生存的第二个writeHost,重新启动后以切换后的为准,切换记录在配置文件dnindex.properties中。1表示所有写操作都随机发送到配置的writeHost,mycat1.5以后已经废弃。
*switchType切换类型。-1表示不自动切换。1表示自动切换,默认值。2表示基于Mysql主从同步状态决定是否切换,心跳语句为show slave status。3表示基于MySQL galary cluster的切换机制(适合集群),心跳语句为show status like 'wsrep%'。
*dbType指定后端连接的数据库类型,支持二进制的mysql协议,以及其他使用JDBC连接的数据库,例如mongodb、oracle、spark等;
*dbDriver指定后端数据库使用的驱动,可选值JDBC和native,其中native对应二进制的mysql协议,即mysql和maridb,其余都使用JDBC;
*switchType请看下发说明
*slaveThreshold slave服务器读的安全边界,如果Seconds_Behind_Master大于这个值,这台slave服务器会被临时剔除,以免被读。*/
<heartbeat>select user()</heartbeat>
//heartbeat标签用于定义心跳语句,用语句执行成功与否来判断数据库的可用性
<!-- can have multi write hosts -->
<writeHost host="node01" url="10.0.0.17:3306" user="mycat" password="123456"></writeHost>
<readHost="node02" url="10.0.0.18:3306" user="mycat" password="123456"/>
</writeHost>
</dataHost>
/*writeHost和readHost标签都指定数据库的相关配置,用于实例化后端连接池。writeHost定义写实例,readHost定义读实例。如果使用readHost标签,请使用writeHost标签将readHost标签包裹。
启动
启动测试Mycat,并设置开机自启
[root@node01 conf]#mycat start
Starting Mycat-server...
[root@node01 conf]#mycat status
Mycat-server is running (30231).
[root@node01 conf]#mysql -umycat -p123456 -P 8066
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| MYCATDB |
| db1 |
+--------------------+
3 rows in set (0.00 sec)
mysql> use db1;
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> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| stu |
+---------------+
1 row in set (0.00 sec)
测试,开启通用日志,general_log SHOW VARIABLES LIKE 'general_log_file';查看日志地址
MyCAT进行查询,
[root@node01 mysql]#mysql -umycat -p123456 -h10.0.0.17 -P8066
mysql> select * from db1.stu;
+----+-------+------+--------+
| id | name | age | gender |
+----+-------+------+--------+
| 1 | tom | 10 | M |
| 2 | jerry | 20 | F |
| 3 | lisan | 15 | F |
+----+-------+------+--------+
3 rows in set (0.03 sec)
mysql> insert into db1.stu(name,age,gender)values('liwu',16,'F');
Query OK, 1 row affected (0.00 sec)
查看slave的日志
[root@node02 mysql]#cat node02.log| grep db1
2024-11-05T10:11:28.297825Z 31 Query select * from db1.stu
查看master的日志
[root@node01 mysql]#cat node01.log| grep db1
2024-11-05T10:14:32.359028Z 84 Query insert into db1.stu(name,age,gender)values('liwu',16,'F')
成功实现读写分离