MySQL一主一从、配置一主多从结构、数据读写分离

部署mysql主从同步

配置mysql主从

分为主数据库角色(master)、从数据库服务器角色(slave)

网站服务器连接后存储数据的服务器作为主服务器

自动同步主服务器上的数据

192.168.88.53 做master

启用binlog日志文件 指定server_id 重启服务

[root@mysql53 ~]# vim /etc/my.cnf.d/mysql-server.cnf 
[mysqld]
......
log-bin=mysql53    # 自定义binlog日志文件
server-id=53    # 主从配置 server id 不能一样
[root@mysql53 ~]# systemctl restart mysqld
[root@mysql53 ~]# mysql -e 'show master status'
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql53.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql53 ~]# ls /var/lib/mysql/mysql53.*
/var/lib/mysql/mysql53.000001  /var/lib/mysql/mysql53.index

用户授权

mysql> create user repluser@"%" identified by "123qqq...A";
mysql> grant replication slave on *.* to repluser@"%";

# 验证登录
[root@mysql54 ~]# mysql -h192.168.88.53 -urepluser -p123qqq...A
......
mysql> 

查看正在使用的binlog日志文件

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql53.000001 |      667 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

192.168.88.54 做slave

指定server_id 并重启数据库服务

[root@mysql54 ~]# vim /etc/my.cnf.d/mysql-server.cnf 
[mysqld]
......
server-id=54
[root@mysql54 ~]# systemctl restart mysqld

# 用一个已安装mysql的虚拟机克隆出来的主从机器,在从机器上执行此操作
[root@mysql54 ~]# rm -rf /var/lib/mysql/auto.cnf 
[root@mysql54 ~]# systemctl restart mysqld

指定主服务器信息

mysql> change master to master_host="192.168.88.53",master_user="repluser",master_password="123qqq...A",master_log_file="mysql53.000001",master_log_pos=667;
mysql> show slave status \G
......
Slave_IO_Running: No
Slave_SQL_Running: No
......

启动slave进程

mysql> start slave;

查看状态信息

mysql> show slave status \G

mysql> show slave status \G
......
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
......

主从验证

在master上添加数据

# -e 命令行下执行数据库命令
[root@mysql53 ~]# mysql -e 'create database bbsdb'
[root@mysql53 ~]# mysql -e 'create table bbsdb.a(id int)'
[root@mysql53 ~]# mysql -e 'insert into bbsdb.a values(110)'

在slave上查看验证

[root@mysql54 ~]# mysql -e 'show databases'
+--------------------+
| Database           |
+--------------------+
| bbsdb              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
[root@mysql54 ~]# mysql -e 'desc bbsdb.a'
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| id    | int  | YES  |     | NULL    |       |
+-------+------+------+-----+---------+-------+
[root@mysql54 ~]# mysql -e 'select * from bbsdb.a'
+------+
| id   |
+------+
|  110 |
+------+

主从同步的工作原理

Master:启用binlog日志,记录所有的数据库更新和修改操作

Slave:

Slave_IO:复制master主机 binlog日志文件里的SQL命令到本机的relay-log(中继日志文件)文件里

Slave_SQL:执行本机relay-log文件里的SQL语句,实现与Master数据一致

排错方法

Last_IO_Error: IO线程报错信息

报错的原因:通常是 change master to 的配置项不正确

解决办法:重新指定主服务器信息

stop slave;

change master to 服务器ip 用户 密码 日志文件名 偏移量;

start slave;

Last_SQL_Error: SQL线程报错信息

通常是执行relay-log文件里的sql命令时失败导致的

配置 一主多从 结构

给已有的master服务器53添加第二台slave角色的服务器55

指定server_id 并重启mysql服务

[root@mysql55 ~]# vim /etc/my.cnf.d/mysql-server.cnf 
[mysqld]
......
server-id=55
[root@mysql55 ~]# systemctl restart mysqld

要手动同步主服务器比自己多的

在master服务器执行完全备份 把备份文件拷贝给slave主机

mysql> show master status;    # 查看binlog日志文件 偏移量
mysql> show databases;        # 查看比slave多的库
[root@mysql53 ~]# mysqldump -B bbsdb > /root/bbsdb.sql    # 完全备份
[root@mysql53 ~]# scp /root/bbsdb.sql root@192.168.88.55:/root

在slave服务器执行 备份文件 恢复数据

[root@mysql55 ~]# mysql < /root/bbsdb.sql 
[root@mysql55 ~]# mysql
mysql> show databases;

指定主服务器信息

change master to 服务器的ip 用户 密码 日志文件名 偏移量

mysql> change master to master_host="192.168.88.53",master_user="repluser",master_password="123qqq...A",master_log_file="mysql53.000002",master_log_pos=156;
mysql> show slave status \G
......
Slave_IO_Running: No
Slave_SQL_Running: No
......

注意:日志名和偏移量 要写 在mysql53主机执行完全备份之前查看到的日志名和偏移量

启动slave

mysql> start slave;

查看状态信息

mysql> show slave status \G
......
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
......

主从验证

在master上添加数据

mysql> insert into bbsdb.a values(114),(119),(122);
mysql> select * from bbsdb.a;
+------+
| id   |
+------+
|  110 |
|  114 |
|  119 |
|  122 |
+------+
4 rows in set (0.00 sec)

在slave上查看验证

# 55
mysql> select * from bbsdb.a;
+------+
| id   |
+------+
|  110 |
|  114 |
|  119 |
|  122 |
+------+
4 rows in set (0.00 sec)


# 54
mysql> select * from bbsdb.a;
+------+
| id   |
+------+
|  110 |
|  114 |
|  119 |
|  122 |
+------+
4 rows in set (0.00 sec)

部署mysql数据读写分离结构

56 master数据库服务器

57 slave数据库服务器

58 读写分离服务器

相关理论

把客户端访问数据库服务的查询访问select、写访问insert 分别给不同的数据库服务器处理

功能:减轻单台数据库服务器的并发访问压力

如何实现数据的读写分离

人肉分离 select-------->57

insert-------->56

搭建读写分离服务实现

能够实现数据读写分离服务的软件(中间件)有哪些

mysql-proxy mycat和mycat2

环境准备

配置mysql主从结构

56 master数据库服务器

57 slave数据库服务器

配置器mycat服务器

58

准备软件

安装软件

# 安装jdk
[root@myscat58 ~]# yum -y install java-1.8.0-openjdk.x86_64
[root@myscat58 ~]# java -version
# 安装解压命令
[root@myscat58 ~]# which unzip || yum -y install unzip
# 安装mycat
[root@myscat58 ~]# unzip mycat2-install-template-1.21.zip 
[root@myscat58 ~]# mv mycat /usr/local/
# 安装依赖
[root@myscat58 ~]# cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
# 修改权限
[root@myscat58 ~]# chmod -R 777 /usr/local/mycat/

修改配置

设置客户端连接mycat服务时使用的用户名和密码

[root@myscat58 ~]# vim /usr/local/mycat/conf/users/root.user.json
{^M
        "dialect":"mysql",^M
        "ip":null,^M
        "password":"654321",^M
        "transactionType":"proxy",^M
        "username":"mycat"^M
}

设置mycat服务启动时连接的数据库服务器

[root@myscat58 ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json 
{^M
        "dbType":"mysql",^M
        "idleTimeout":60000,^M
        "initSqls":[],^M
        "initSqlsGetConnection":true,^M
        "instanceType":"READ_WRITE",^M
        "maxCon":1000,^M
        "maxConnectTimeout":3000,^M
        "maxRetryCount":5,^M
        "minCon":1,^M
        "name":"prototypeDs",^M
        "password":"123456",^M
        "type":"JDBC",^M
        "url":"jdbc:mysql://localhost:3306/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",^M
        "user":"hmy",^M
        "weight":0^M
}

根据配置在本机运行mysql服务并创建hmy用户

[root@myscat58 ~]# yum -y install mysql-server mysql
[root@myscat58 ~]# systemctl start mysqld
[root@myscat58 ~]# mysql
mysql> create user hmy@"localhost" identified by '123456';
mysql> grant all on *.* to hmy@"localhost";
[root@myscat58 ~]# mysql -hlocalhost -uhmy -p123456

启动mycat服务

[root@myscat58 ~]# ls /usr/local/mycat/logs/
[root@myscat58 ~]# /usr/local/mycat/bin/mycat start
Starting mycat2...
[root@myscat58 ~]# ls /usr/local/mycat/logs/
mycat.pid  wrapper.log
[root@myscat58 ~]# ss -ntulp | grep 8066
tcp   LISTEN 0      128                     *:8066             *:*    users:(("java",pid=22649,fd=71))  
[root@myscat58 ~]#

连接mycat服务

[root@myscat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
mysql> show databases;
+--------------------+
| `Database`         |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.16 sec)

连接mycat服务配置读写分离

MySQL主从结构 + MyCat2

主从结构 + mycat 软件实现 数据的读写分离

添加数据源(定义数据库服务器的ip地址)

# 连接mycat服务
[root@myscat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
# 添加mysql56数据库服务器
mysql> /*+ mycat:createdatasource{
    -> "name":"whost56", "url":"jdbc:mysql://192.168.88.56:3306","user":"hmy","password":"123456"}*/;
Query OK, 0 rows affected (0.30 sec)
# 添加mysql57数据库服务器
mysql> /*+ mycat:createdatasource{
    -> "name":"whost57", "url":"jdbc:mysql://192.168.88.57:3306","user":"hmy","password":"123456"}*/;
Query OK, 0 rows affected (0.07 sec)
# 查看数据源
/*+mycat:showDataSources{}*/ \G
# 添加的数据源以文件的形式保存在安装目录下
[root@myscat58 ~]# ls /usr/local/mycat/conf/datasources/
prototypeDs.datasource.json  whost56.datasource.json  whost57.datasource.json

在数据库服务器上添加hmy用户

[root@mysql56 ~]# mysql
mysql> create user hmy@"%" identified by '123456';
mysql> grant all on *.* to hmy@"%";

# 测试
[root@myscat58 ~]# mysql -h192.168.88.56 -uhmy -p123456
mysql>

[root@myscat58 ~]# mysql -h192.168.88.57 -uhmy -p123456
mysql>

创建集群 把56和57组成工作组

[root@myscat58 ~]#mysql -h127.0.0.1 -P8066 -umycat -p654321
# 创建集群
mysql> /*!mycat:createcluster{ "name":"rwcluster", "masters":["whost56"], "replicas":["whost57"] }*/;
# 查看集群信息
mysql> /*+ mycat:showClusters{}*/ \G*************************** 1. row ***************************
             NAME: rwcluster
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: whost56
          READ_DS: whost56,whost57
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
2 rows in set (0.00 sec)

# 创建的集群以文件的形式保存在目录下
[root@myscat58 ~]# ls /usr/local/mycat/conf/clusters/
prototype.cluster.json  rwcluster.cluster.json

指定数据库服务器的角色

master角色机器负责写

slave角色机器负责访问

# 修改master角色主机仅负责写访问
[root@myscat58 ~]# vim /usr/local/mycat/conf/datasources/whost56.datasource.json
{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"WRITE",    # 仅负责写访问
        "logAbandoned":true,
        "maxCon":1000,
        "maxConnectTimeout":30000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"whost56",
        "password":"123456",
        "queryTimeout":0,
        "removeAbandoned":false,
        "removeAbandonedTimeoutSecond":180,
        "type":"JDBC",
        "url":"jdbc:mysql://192.168.88.56:3306?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true",
        "user":"hmy",
        "weight":0
}
# 修改slave角色主机仅负责读访问
[root@myscat58 ~]# vim /usr/local/mycat/conf/datasources/whost57.datasource.json 
{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ",    # 仅负责读访问
        "logAbandoned":true,
        "maxCon":1000,
        "maxConnectTimeout":30000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"whost57",
        "password":"123456",
        "queryTimeout":0,
        "removeAbandoned":false,
        "removeAbandonedTimeoutSecond":180,
        "type":"JDBC",
        "url":"jdbc:mysql://192.168.88.57:3306?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true",
        "user":"hmy",
        "weight":0
}

定义集群出来读访问的策略

集群处理查询访问的方式

[root@myscat58 ~]# vim /usr/local/mycat/conf/clusters/rwcluster.cluster.json 
{
        "clusterType":"MASTER_SLAVE",
        "heartbeat":{
                "heartbeatTimeout":1000,
                "maxRetryCount":3,
                "minSwitchTimeInterval":300,
                "showLog":false,
                "slaveThreshold":0.0
        },
        "masters":[
                "whost56"
        ],
        "maxCon":2000,
        "name":"rwcluster",
        "readBalanceType":"BALANCE_ALL_READ",
        "replicas":[
                "whost57"
        ],
        "switchType":"SWITCH"
}

创建网站存储数据使用的库 并定义 库存储数据使用rwcluster

[root@myscat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
mysql> create database testdb;
# 指定testdb库存储数据使用的集群
[root@myscat58 ~]# vim /usr/local/mycat/conf/schemas/testdb.schema.json 
{
        "customTables":{},
        "globalTables":{},
        "normalProcedures":{},
        "normalTables":{},
        "schemaName":"testdb",
        "targetName":"rwcluster",    # 添加此行,之前创建的集群名rwcluster
        "shardingTables":{},
        "views":{}
}
[root@myscat58 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...
[root@myscat58 ~]# ss -ntulp | grep 8066
tcp   LISTEN 0      128                     *:8066             *:*    users:(("java",pid=23325,fd=72))  
[root@myscat58 ~]# 

测试配置

# 连接mycat服务建表插入记录
[root@client ~]# mysql -h192.168.88.58 -P8066 -umycat -p654321
mysql> create table user(name char(10),passwd char(6));
mysql> insert into user values("A","123");
mysql> select * from user;
+------+--------+
| name | passwd |
+------+--------+
| A    | 123    |
+------+--------+
1 row in set (0.01 sec)

[root@mysql56 ~]# mysql -e 'select * from testdb.user'
+------+--------+
| name | passwd |
+------+--------+
| A    | 123    |
+------+--------+

[root@mysql57 ~]# mysql -e 'select * from testdb.user'
+------+--------+
| name | passwd |
+------+--------+
| A    | 123    |
+------+--------+

# 测试读写分离
# 在从服务器本机插入记录,数据仅在从服务器有,主服务器没有
[root@client ~]# mysql -h192.168.88.58 -P8066 -umycat -p654321 -e 'insert into testdb.user values("B","678")'
[root@mysql57 ~]# mysql -e 'insert into testdb.user values("mysql57","57")'
[root@client ~]# mysql -h192.168.88.58 -P8066 -umycat -p654321 -e 'select * from testdb.user'
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------+--------+
| name    | passwd |
+---------+--------+
| A       | 123    |
| B       | 678    |
| mysql57 | 57     |
+---------+--------+
# 主服务器数据不变,日志偏移量不不变
[root@mysql56 ~]# mysql -e 'select * from testdb.user'
+------+--------+
| name | passwd |
+------+--------+
| A    | 123    |
| B    | 678    |
+------+--------+
[root@mysql56 ~]# mysql -e 'show master status'
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000001 |     2538 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat服务读/写数据
[root@client ~]# mysql -h192.168.88.58 -P8066 -umycat -p654321 -e 'insert into testdb.user values("bbb","222")'
# 在主服务器查看数据和日志偏移量
[root@mysql56 ~]# mysql -e 'show master status'
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000001 |     2828 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
相关推荐
拭心12 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王14 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡14 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道14 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库15 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道16 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe16 小时前
Android Hook - 动态加载so库
android
居居飒17 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He20 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗20 小时前
Android笔试面试题AI答之Android基础(1)
android