3

CentOS7环境下数据库运维---主从复制、读写分离 - ChAnAn

 1 year ago
source link: https://www.cnblogs.com/sre-chan/p/17255202.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

1.理解MySQL主从复制原理

主服务器开启binlog日志,从库生成log dump线程,将binlog日志传给从库I/O线程,从库生成俩个线程,一个是I/O线程,一个是SQL线程,I/O线程去请主库的binlog日志,并将binlog日志中的文件写入relay log中,sql线程会读取relay log 中的内容,并解析成具体的操作,来实现主从一致,达到最终数据一致的目的。

2.完成MySQL主从复制(一主两从)

环境准备:

主机名 IP地址 端口号
node01 192.168.11.110 3306
node02 192.168.11.111 3306
node03 192.168.11.112 3306

数据库准备:

create database company;
use company
CREATE TABLE `emp`  (
  `empno` int(4) NOT NULL,
  `ename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `job` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `mgr` int(4) NULL DEFAULT NULL,
  `hiredate` date NOT NULL,
  `sai` int(255) NOT NULL,
  `comm` int(255) NULL DEFAULT NULL,
  `deptno` int(2) NOT NULL,
  PRIMARY KEY (`empno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `emp` VALUES (1001, '甘宁', '文员', 1013, '2000-12-17', 8000, NULL, 20);
INSERT INTO `emp` VALUES (1002, '黛绮丝', '销售员', 1006, '2001-02-20', 16000, 3000, 30);
INSERT INTO `emp` VALUES (1003, '殷天正', '销售员', 1006, '2001-02-22', 12500, 5000, 30);
INSERT INTO `emp` VALUES (1004, '刘备', '经理', 1009, '2001-04-02', 29750, NULL, 20);
INSERT INTO `emp` VALUES (1005, '谢逊', '销售员', 1006, '2001-09-28', 12500, 14000, 30);
INSERT INTO `emp` VALUES (1006, '关羽', '经理', 1009, '2001-05-01', 28500, NULL, 30);
INSERT INTO `emp` VALUES (1007, '张飞', '经理', 1009, '2001-09-01', 24500, NULL, 10);
INSERT INTO `emp` VALUES (1008, '诸葛亮', '分析师', 1004, '2007-04-19', 30000, NULL, 20);
INSERT INTO `emp` VALUES (1009, '曾阿牛', '董事长', NULL, '2001-11-17', 50000, NULL, 10);
INSERT INTO `emp` VALUES (1010, '韦一笑', '销售员', 1006, '2001-09-08', 15000, 0, 30);
INSERT INTO `emp` VALUES (1011, '周泰', '文员', 1006, '2007-05-23', 11000, NULL, 20);
INSERT INTO `emp` VALUES (1012, '程普', '文员', 1006, '2001-12-03', 9500, NULL, 30);
INSERT INTO `emp` VALUES (1013, '庞统', '分析师', 1004, '2001-12-03', 30000, NULL, 20);
INSERT INTO `emp` VALUES (1014, '黄盖', '文员', 1007, '2002-01-23', 13000, NULL, 10);
INSERT INTO `emp` VALUES (1015, '张三', '保洁员', 1001, '2013-05-01', 80000, 50000, 50);

方式一:基于三台服务器实现主从复制

主库配置:

1、在mysqld标签下添加server_id并开启bin_log日志

[root@node01 ~]# cat /etc/my.cnf
[mysqld]
log_bin=mysql_bin
server_id=1

2、重启数据库服务

[root@node01 ~]# systemctl restart mysqld.service

3、授权同步账号和密码

mysql> grant replication slave on *.* to 'rep'@'192.168.11.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)

4、查看授权信息

mysql> show grants for 'rep'@'192.168.11.%';
+--------------------------------------------------------+
| Grants for [email protected].%                            |
+--------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'rep'@'192.168.11.%' |
+--------------------------------------------------------+
1 row in set (0.00 sec)

5、对表操作

# 锁表设置为只读
# 为后边备份准备,注意生产环境要提前申请停机时间,停服
mysql> flush tables with read lock;

# 超过时间不操作会自动解锁,查看超时时间
mysql> show variables like '%timeout%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| have_statement_timeout      | YES      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 60       |
| wait_timeout                | 28800    |
+-----------------------------+----------+
13 rows in set (0.01 sec)

# 查看主库状态
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 |    11824 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

6、备份数据库数据

# 创建备份目录
[root@node01 ~]# mkdir /server/backup -p

[root@node01 ~]# mysqldump -uroot -p -A -B | gzip > /server/backup/mysql_bak.$(date +%F).sql.gz
Enter password:
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

8、主库备份数据传送到从库

# 在从库上常见备份目录
[root@node02 ~]# mkdir /server/backup -p

# scp传送
[root@node01 ~]# scp /server/backup/mysql_bak.2023-03-25.sql.gz  192.168.11.111:/server/backup/
[root@node01 ~]# scp /server/backup/mysql_bak.2023-03-25.sql.gz  192.168.11.112:/server/backup/

从库配置:

1、关闭bin_log参数,设置server-id

[root@node02 ~]# cat /etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
server_id=2

2、重启数据库服务

[root@node02 ~]# systemctl restart mysqld.service

3、还原从主库传输过来的数据文件

[root@node02 ~]# cd /server/backup/
[root@node02 backup]# gzip -d mysql_bak.2023-03-25.sql.gz
[root@node02 backup]# mysql -uroot -p < mysql_bak.2023-03-25.sql
Enter password:

4、检查数据完整性

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| company            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use company;
mysql> select * from company;
# 数据完整,恢复完成

5、配置主从同步

# 查看主库的binlog和pos位置点
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 |    11824 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 从库上配置
mysql> change master to
    -> master_host='192.168.11.110',
    -> master_user='rep',
    -> master_password='123456',
    -> master_log_file='mysql_bin.000001',
    -> master_log_pos=11824;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

6、启动从库同步并检查状态

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.11.110
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000001
          Read_Master_Log_Pos: 11824
               Relay_Log_File: node02-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql_bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
# 看目前最后俩行是否为YES,俩个线程都为YES才OK

1、主库创建一个数据库

mysql> create database test_master;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| company            |
| mysql              |
| performance_schema |
| sys                |
| test_master        |
+--------------------+
6 rows in set (0.00 sec)

2、从库检查

[root@node02 backup]# mysql -uroot  -p -e 'show databases;'
Enter password:
+--------------------+
| Database           |
+--------------------+
| information_schema |
| company            |
| mysql              |
| performance_schema |
| sys                |
| test_master        |
+--------------------+

第二台从库一样的配置,除了server_id不同

方式二:基于docker实现主从复制

环境准备:

主机名 IP地址 端口
mysql01 192.168.11.10 3306
mysql02 192.168.11.10 3307
msyql03 192.168.11.10 3308

安装docker环境:

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# Step 4: 更新并安装Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
sudo service docker start

# 注意:
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将[docker-ce-test]下方的enabled=0修改为enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]

1、运行三个容器,mysql01 mysql02 mysql03

# 重启docker服务
[root@template ~]# systemctl restart docker.service

# 拉取镜像
[root@template ~]# docker run --name mysql01 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 --lower_case_table_names=1
[root@template ~]# docker run --name mysql02 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 --lower_case_table_names=1
[root@template ~]# docker run --name mysql03 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 --lower_case_table_names=1

2、修改配置文件

将容器里面的配置文件复制出来,主要修改服务器的配置;在root目录下创建一个/server/backup的目录存放从Docker容器里面复制过来的配置文件。进入目录:cd /server/backup

因为在docker中vi命令都没有

# 创建备份目录
[root@template ~]# mkdir /server/backup -p

# 使用docker cp将文件传到宿主机
[root@template ~]# cd /server/backup/

# 进入容器查看mysql文件
[root@template backup]# docker exec -it  mysql01 bash
bash-4.2# mysql -uroot -p
Enter password:

# 从Docker容器里面复制过来的配置文件,配置文件路径不一样
[root@template ~]# docker cp mysql01:/etc/my.cnf  mysql01.cnf
[root@template ~]# docker cp mysql02:/etc/my.cnf  mysql02.cnf
Successfully copied 3.072kB to /root/mysql02.cnf
[root@template ~]# docker cp mysql03:/etc/my.cnf  mysql03.cnf
Successfully copied 3.072kB to /root/mysql03.cnf
[root@template ~]# ll
total 16
-rw-------. 1 root root 1425 Mar  3 18:52 anaconda-ks.cfg
-rw-r--r--. 1 root root 1159 Mar 22 04:51 mysql01.cnf
-rw-r--r--. 1 root root 1159 Mar 22 04:51 mysql02.cnf
-rw-r--r--. 1 root root 1159 Mar 22 04:51 mysql03.cnf

3、主库的mysql01.cnf

[root@template ~]# vim mysql01.cnf
[mysqld]
server_id=1
log_bin=mysql01.bin
# 添加server_id 和 开启日志

4、从库修改server_id即可

[root@template ~]# vim mysql02.cnf
server_id=2
[root@template ~]# vim mysql03.cnf
server_id=3

5、修改完成后,将 mysql01.cnf mysql02.cnf mysql03.cnf 三个文件传入容器中

[root@template ~]# docker cp mysql01.cnf mysql01:/etc/my.cnf
Successfully copied 3.072kB to mysql01:/etc/my.cnf
[root@template ~]# docker cp mysql02.cnf mysql02:/etc/my.cnf
Successfully copied 3.072kB to mysql02:/etc/my.cnf
[root@template ~]# docker cp mysql03.cnf mysql03:/etc/my.cnf
Successfully copied 3.072kB to mysql03:/etc/my.cnf

6、重启数据库

[root@template ~]# docker restart mysql01  mysql02 mysql03

7、测试连接

[root@node03 ~]# mysql -uroot -p123456 -h 192.168.11.10 -P 3306
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 2
Server version: 5.7.41-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, 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> \q
Bye
[root@node03 ~]# mysql -uroot -p123456 -h 192.168.11.10 -P 3307
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 2
Server version: 5.7.41 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, 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> \q
Bye
[root@node03 ~]# mysql -uroot -p123456 -h 192.168.11.10 -P 3308
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 2
Server version: 5.7.41 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, 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>

8、在3306作为主库

[root@template backup]# docker exec -it mysql01 bash
bash-4.2# mysql -uroot -p123456

9、创建一个rep用户

mysql> create user 'rep'@'%' identified by '123456';
Query OK, 0 rows affected (0.02 sec)

10、添加权限

mysql> grant replication slave on *.* to 'rep'@'%';
Query OK, 0 rows affected (0.00 sec)

11、刷新权限表

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

12、测试用rep登录

bash-4.2# mysql -urep -p123456

13、进入从库做配置

# 查看主库上的信息,注意用户,要用root用户,开始用的rep错误信息如下:
mysql> show master status;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation
# 查看主库上的信息
mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql01.000001 |      745 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


[root@template ~]# docker exec -it mysql02 bash
[root@template ~]# docker exec -it mysql03 bash

bash-4.2# mysql -uroot -p123456
mysql> change master to
    -> master_host="192.168.11.10",
    -> master_user="rep",
    -> master_password="123456",
    -> master_log_file="mysql01.000001",
    -> master_log_pos=745;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

14、开启slave并且查看俩个线程状态

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.11.10
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql01.000001
          Read_Master_Log_Pos: 745
               Relay_Log_File: cb6044d1b02b-relay-bin.000002
                Relay_Log_Pos: 318
        Relay_Master_Log_File: mysql01.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

15、可以用客户端连接测试,实验完成!!!

3.基于MySQL一主两从配置,完成MySQL读写分离配置

在docker环境上完成!!!

1、使用MYCAT2安装JDK,因为MYCAT是基于JDK1.8开发的

[root@template ~]# yum install -y jdk-8u261-linux-x64.rpm
[root@template ~]# java -version
java version "1.8.0_261"

2、下载压缩包和jar包

#创建/data/tools目录
[root@template ~]# mkdir -p /data/tools
[root@template ~]# cd /data/tools/
[root@template ~]# wget -c http://dl.mycat.org.cn/2.0/install-template/mycat2-install-template-1.21.zip
[root@template ~]# wget -c http://dl.mycat.org.cn/2.0/1.21-release/mycat2-1.21-release-jar-with-dependencies.jar

3、安装MyCAT2

[root@template tools]# ll
total 149484
-rw-r--r--. 1 root root 151819628 May  9  2022 mycat2-1.21-release-jar-with-dependencies.jar
-rw-r--r--. 1 root root   1246974 May  9  2022 mycat2-install-template-1.21.zip

4、安装unzip

[root@template tools]# yum install -y unzip

5、解压到指定目录

[root@template tools]# unzip mycat2-install-template-1.21.zip -d /data/

6、修改权限

[root@template ~] cd /data/mycat/lib/
[root@template bin]# chmod +x *
[root@template bin]# cp /data/tools/mycat2-1.21-release-jar-with-dependencies.jar ./

7、查看mycat目录结构

[root@template bin]# ll /data/mycat/
total 8
drwxr-xr-x. 2 root root 4096 Mar 25 22:56 bin
drwxr-xr-x. 9 root root  275 Mar  5  2021 conf
drwxr-xr-x. 2 root root 4096 Mar  5  2021 lib
drwxr-xr-x. 2 root root    6 Mar  5  2021 logs

8、启动mycat

./mycat start 启动
./mycat console 前台运行
./mycat install 添加到系统自动启动
./mycat remove 取消随系统自动启动
./mycat restart 重启
./mycat pause 暂停
./mycat status 查看启动状态

9、出现以下信息表示启动成功

[root@template bin]# ./mycat start
Starting mycat2...
[root@template bin]# cat /data/mycat/logs/wrapper.log
STATUS | wrapper  | 2023/03/25 22:59:23 | --> Wrapper Started as Daemon
STATUS | wrapper  | 2023/03/25 22:59:23 | Launching a JVM...
INFO   | jvm 1    | 2023/03/25 22:59:23 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO   | jvm 1    | 2023/03/25 22:59:23 |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
INFO   | jvm 1    | 2023/03/25 22:59:23 |
INFO   | jvm 1    | 2023/03/25 22:59:23 | WrapperSimpleApp: Unable to locate the class io.mycat.MycatCore: java.lang.ClassNotFoundException: io.mycat.MycatCore
INFO   | jvm 1    | 2023/03/25 22:59:23 |
INFO   | jvm 1    | 2023/03/25 22:59:23 | WrapperSimpleApp Usage:
INFO   | jvm 1    | 2023/03/25 22:59:23 |   java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class} [app_arguments]
INFO   | jvm 1    | 2023/03/25 22:59:23 |
INFO   | jvm 1    | 2023/03/25 22:59:23 | Where:
INFO   | jvm 1    | 2023/03/25 22:59:23 |   app_class:      The fully qualified class name of the application to run.
INFO   | jvm 1    | 2023/03/25 22:59:23 |   app_arguments

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK