目录
介绍
一主一从
原理
准备
配置主从复制
验证主从复制
一主一从读写分离
安装MyCat
schema.xml配置
server.xml配置
测试
介绍
读写分离,简单地说是把对数据库的读和写操作分开,以对应不同的数据库服务器。主数据库提供写操作,从数据库提供读操作,这样能有效地减轻单台数据库的压力。
通过MyCat即可轻易实现上述功能,不仅可以支持MySQL,也可以支持Oracle和SQL Server。
一主一从
原理
MySQL的主从复制,是基于二进制日志(binlog)实现的。
准备
安装服务 | 主机 | MySQL版本 | 角色 | 用户名 | 密码 |
---|---|---|---|---|---|
MyCat,MySQL | 192.168.226.100 | MySQL : 8.0.39 | master | root | 1234 |
MySQL | 192.168.226.101 | MySQL : 8.0.39 | slave | root | 1234 |
两台主机关闭防火墙和selinux,进行时间同步并安装mysql,设置root密码为1234
#!/bin/bash
echo "=====系统环境初始化脚本====="
sleep 3
echo "——>>> 关闭防火墙与SELinux <<<——"
sleep 3
systemctl stop firewalld
systemctl disable firewalld &> /dev/null
setenforce 0
sed -i '/SELINUX/{s/enforcing/disabled/}' /etc/selinux/config
echo "——>>> 创建阿里仓库 <<<——"
sleep 3
rm -rf /etc/yum.repos.d/*
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum -y install wget
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
echo "——>>> 设置时区并同步时间 <<<——"
sleep 3
timedatectl set-timezone Asia/Shanghai
yum -y install chrony
systemctl start chronyd
systemctl enable chronyd
reboot
sudo yum remove mysql-server -y && sudo yum autoremove -y
sudo yum remove *mysql* -y
sudo rm -rf /var/lib/mysql/
sudo rm -rf /etc/mysql/
yum install -y yum-utils > /dev/null
yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm > /dev/null
yum-config-manager --enable mysql80-community > /dev/null
yum-config-manager --disable mysql57-community > /dev/null
yum install -y mysql-server
systemctl start mysqld && systemctl enable mysqld
mysqladmin -p"`awk '/temporary password/{p=$NF}END{print p}' /var/log/mysqld.log`" password 'TianPFh@123'
mysql -p'TianPFh@123' -e "UNINSTALL COMPONENT 'file://component_validate_password'"
mysqladmin -p'TianPFh@123' password '1234'
配置主从复制
配置master,对192.168.226.100主机操作,配置/etc/my.cnf 在该配置文件末尾追加下述配置项
server-id = 1 # 服务器唯一标识,每个服务器在复制环境中应有唯一的ID,用于标识不同的复制实例
log-bin = mysql-bin # 启用二进制日志,指定二进制日志文件的基名,MySQL会在此基名后添加数字和扩展名来创建日志文件
binlog-format = ROW # 设置二进制日志格式为ROW,记录每一行数据的变化,有助于减少数据不一致的风险,也便于从库的并行复制
重新启动MySQL服务
systemctl restart mysqld
登录mysql创建用于主从复制的远程用户并授权
[root@master ~]# mysql -uroot -p1234 # 使用root用户登录MySQL,密码是1234
mysql: [Warning] Using a password on the command line interface can be insecure. # 警告:在命令行界面使用密码可能不安全
Welcome to the MySQL monitor. Commands end with ; or \g. # 欢迎信息,命令以;或\g结束
Your MySQL connection id is 8 # MySQL连接ID为8
Server version: 8.0.39 MySQL Community Server - GPL # 服务器版本信息
Copyright (c) 2000, 2024, Oracle and/or its affiliates. # 版权信息
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. # Oracle是Oracle公司及其附属公司的注册商标
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. # 输入'help;'或'\h'获取帮助,输入'\c'清除当前输入的命令
mysql> create user 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'admin'; # 创建用户'itit',允许从任何主机访问,并设置密码为'123456'
Query OK, 0 rows affected (0.01 sec) # 命令执行成功,没有行受到影响
mysql> grant all on *.* to 'root'@'%'; # 授予用户'itit'从任何主机进行复制的权限
Query OK, 0 rows affected (0.00 sec) # 命令执行成功,没有行受到影响
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status; # 显示主服务器状态,包括二进制日志文件名和位置
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 824 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec) # 输出结果,显示当前使用的二进制日志文件和位置
mysql> exit # 退出MySQL命令行
Bye # MySQL命令行退出信息
配置slave,对192.168.226.101主机操作,修改配置文件 /etc/my.cnf 在该配置文件末尾追加下述配置项
# 从库的唯一标识,与主库和其他从库不同
server-id = 2
# 设置二进制日志格式为ROW,有助于减少数据不一致的风险
binlog-format = ROW
# 设置从库为只读模式,防止在从库上直接写入数据导致的数据不一致
read-only = 1
重新启动MySQL服务
systemctl restart mysqld
登录从库MySQL,配置从库以连接到主库
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.226.100',
SOURCE_USER='root',
SOURCE_PASSWORD='admin',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=824;
并创建一个远程用户并授权
create user 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'admin';
grant all on *.* to 'root'@'%';
FLUSH PRIVILEGES;
启动复制进程
START REPLICA;
查看复制状态
SHOW REPLICA STATUS\G;
验证主从复制
登录master的mysql,执行下述sql语句,然后回到slave上查看是否同步上了。
-- 在master执行sql
CREATE DATABASE IF NOT EXISTS itceshi;
-- 登录slave查看
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| itceshi |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
一主一从读写分离
安装MyCat
详细步骤参考该博文,这里不在赘述安装步骤。
MySQ分库分表与MyCat安装配置-CSDN博客
schema.xml配置
MyCat控制后台数据库的读写分离和负载均衡由schema.xml文件datahost标签的balance属性控 制。将下述配置替换原文件里的内容即可。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="ITCESHI_RW" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1"></schema>
<dataNode name="dn1" dataHost="dhost1" database="itceshi" />
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.226.100:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="admin">
<readHost host="slave" url="jdbc:mysql://192.168.226.101:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="admin" />
</writeHost>
</dataHost>
</mycat:schema>
writeHost代表的是写操作对应的数据库,readHost代表的是读操作对应的数据库。 所以我们要想 实现读写分离,就得配置writeHost关联的是主库,readHost关联的是从库。
而仅仅配置好了writeHost以及readHost还不能完成读写分离,还需要配置一个非常重要的负责均衡 的参数 balance,取值有4种,具体含义如下:
参数 | 值 | 含义 |
---|---|---|
读写分离机制 | 0 | 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上 |
读写分离机制 | 1 | 全部的readHost与备用的writeHost都参与select语句的负载均衡(主要针对于双主双从模式) |
读写分离机制 | 2 | 所有的读写操作都随机在writeHost, readHost上分发 |
读写分离机制 | 3 | 所有的读请求随机分发到writeHost对应的readHost上执行, writeHost不负担读压力 |
所以,在一主一从模式的读写分离中,balance配置1或3都是可以完成读写分离的。
server.xml配置
配置mycat的root用户可以访问 ITCHESHI_RW逻辑库。(只需要修改下述模块位置的代码即可)
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">ITCESHI_RW</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">123456</property>
<property name="schemas">ITCESHI_RW</property>
<property name="readOnly">true</property>
</user>
启动MyCat
# 先停止再启动
/usr/local/mycat/bin/mycat stop
/usr/local/mycat/bin/mycat start
登录mycat查看库
[root@master ~]# mysql -h 192.168.226.100 -P 8066 -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.6.29-mycat-1.6.7.3-release-20210913163959 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+------------+
| DATABASE |
+------------+
| ITCESHI_RW |
+------------+
1 row in set (0.01 sec)
测试
在master主机中,登陆mycat执行语句
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
description TEXT
);
INSERT INTO products (name, price, description) VALUES
('Laptop', 999.99, 'High-performance laptop with SSD and 16GB RAM'),
('Smartphone', 599.50, 'Latest model with dual cameras and AI features'),
('Tablet', 349.00, 'Lightweight tablet for entertainment and productivity');
在slave主机的mysql中查看是否同步了刚在mycat中写入的语句。
[root@slave ~]# mysql -p1234
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 91
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| itceshi |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> show tables;
+-------------------+
| Tables_in_itceshi |
+-------------------+
| products |
+-------------------+
1 row in set (0.00 sec)
mysql> select * from products;
+----+------------+--------+-------------------------------------------------------+
| id | name | price | description |
+----+------------+--------+-------------------------------------------------------+
| 1 | Laptop | 999.99 | High-performance laptop with SSD and 16GB RAM |
| 2 | Smartphone | 599.50 | Latest model with dual cameras and AI features |
| 3 | Tablet | 349.00 | Lightweight tablet for entertainment and productivity |
+----+------------+--------+-------------------------------------------------------+
3 rows in set (0.00 sec)
可以看到同步写入成功了,现在接着在slave主机的mysql中,修改或者插入一条数据,查看master会不会同步,正常情况slave写入,master不会同步。
UPDATE products
SET name = 'Lightweight Tablet'
WHERE name = 'Tablet' AND price = 349.00 AND description = 'Lightweight tablet for entertainment and productivity';
INSERT INTO products (name, price, description) VALUES
('Headphones', 79.99, 'Wireless headphones with noise-cancelling feature');
mysql> select * from products;
+----+--------------------+--------+-------------------------------------------------------+
| id | name | price | description |
+----+--------------------+--------+-------------------------------------------------------+
| 1 | Laptop | 999.99 | High-performance laptop with SSD and 16GB RAM |
| 2 | Smartphone | 599.50 | Latest model with dual cameras and AI features |
| 3 | Lightweight Tablet | 349.00 | Lightweight tablet for entertainment and productivity |
| 4 | Headphones | 79.99 | Wireless headphones with noise-cancelling feature |
+----+--------------------+--------+-------------------------------------------------------+
4 rows in set (0.00 sec)
现在到master主机中的mysql中查看:
mysql> select * from products;
+----+------------+--------+-------------------------------------------------------+
| id | name | price | description |
+----+------------+--------+-------------------------------------------------------+
| 1 | Laptop | 999.99 | High-performance laptop with SSD and 16GB RAM |
| 2 | Smartphone | 599.50 | Latest model with dual cameras and AI features |
| 3 | Tablet | 349.00 | Lightweight tablet for entertainment and productivity |
+----+------------+--------+-------------------------------------------------------+
3 rows in set (0.00 sec)
这里可以看到,slave中写入不会同步到master,从而验证了一主一从的读写分离配置完成了。