当前位置: 首页 > article >正文

mysql高级知识之集群

一、安装

        源码编译MySQL,若需要MySQLtar包可私信我

#创建数据目录
mkdir /data/mysql -p

#安装相关依赖
yum install libtirpc-devel-0.2.4-0.16.el7.x86_64.rpm
yum install cmake gcc-c++ openssl-devel ncurses-devel.x86_64 libtirpc-devel-1.3.3-8.el9_4.x86_64.rpm rpcgen.x86_64 -y

#解压MySQL包,并进入其目录
tar zxf mysql-boost-5.7.44.tar.gz
cd mysql-5.7.44/

#进行源码安装
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql -DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock -DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_EXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci -DWITH_BOOST=/root/mysql-5.7.44/boost/boost_1_59_0/

#有几个核就j几
make -j2

#安装
make install

#拷贝启动文件
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/

#修改配置文件
vim /etc/my.cnf
[mysqld]	
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0

#设置环境变量
vim ~/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
source ~/.bash_profile

#建立mysql用户
useradd -s /sbin/nologin -M mysql

#将mysql数据目录归属于mysql用户
chown mysql.mysql -R /data/mysql/

#清空数据目录,注意非实验环境需先备份其中内容
rm -rf /data/mysql/*

#MySQL初始化,注意初始化之后会产生一个临时密码,在第一次登陆后需改密码
mysqld --user mysql --initialize

#登录MySQL,并修改root密码,第一次登录不修改密码使用不了
mysql -uroot -p'j;t/EZJ*g1y7'
alter user root@localhost identified by 'Mysql@123';

#设置MySQL开机自启动
yum install chkconfig -y
chkconfig mysqld on ###不设定启动级别,默认2345
chkconfig --list

在三台主机上安装MySQL,具体如下 

主机 主机名 角色
192.168.220.10 node1
192.168.220.20 node2
192.168.220.30 node3

 二、主从复制

1、干净数据库主从复制

步骤如下

        1)分别在主库从库设定不同的server-id以区分不同的数据库
        注:设定server-id后从机设定了read_only=1也可以写入,在设定server-id之后不让从机写入需设定super_read_only=on

        2)设定数据库开始二进制日志

        3)在主库上创建主从复制的用户,并给予权限

        4)配置从库

#主库node1--配置server-id和开启二进制日志(注,修改完配置文件需要重启数据库)
vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=1            #server-id
log-bin=mysql-bin      #二进制日志

#主库--创建用户并授权(登录数据库自己解决)
create user repl@'%' identified by 'Mysql@123';        #创建用户
grant replication slave on *.* to repl@'%';            #授权

#配置完成之后可查看master状态
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      595 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#从库node2--配置server-id和开启二进制日志(注,修改完配置文件需要重启数据库)
vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=2            #server-id
log-bin=mysql-bin      #二进制日志

#从库node2--配置主从
change master to master_host='192.168.220.10',master_user='repl',master_password='Mysql@123',master_log_file='mysql-bin.000001',master_log_pos=595;
start slave;

#可以查看slave状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.220.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 595
               Relay_Log_File: node2-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes        #看到IO线程Yes
            Slave_SQL_Running: Yes        #看到SQL线程Yes则说明主从配置成功

2、有数据的数据库主从复制

步骤如下

        1)分别在主库从库设定不同的server-id以区分不同的数据库
        注:设定server-id后从机设定了read_only=1也可以写入,在设定server-id之后不让从机写入需设定super_read_only=on

        2)设定数据库开始二进制日志

        3)在主库上创建主从复制的用户,并给予权限

        4)导出主库数据,传到从库做还原

        注:在企业搭建主从复制拉平数据时,需要先将主库锁起来

        5)配置从库

#主库node1--配置server-id和开启二进制日志(注,修改完配置文件需要重启数据库)
vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=1            #server-id
log-bin=mysql-bin      #二进制日志

#主库--创建用户并授权(登录数据库自己解决)
create user repl@'%' identified by 'Mysql@123';        #创建用户
grant replication slave on *.* to repl@'%';            #授权

#配置完成之后可查看master状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     1481 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#主库和从库之间拉平数据,主库要先锁表
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)

#验证表是否锁住
mysql> insert into db1.tb1 values('3','力迅');
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock

#导出主库数据(注:企业中不能将数据库密码显示输入)
mysqldump -uroot -p'Mysql@123' -B db1 > mysql.sql

#将sql传至新的node节点
scp /root/mysql.sql root@node3:/root

#从库node3--配置server-id和开启二进制日志(注,修改完配置文件需要重启数据库)
vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=3            #server-id
log-bin=mysql-bin      #二进制日志

#从库导入主库数据(注:需要先登录数据库)
mysql> source /root/mysql.sql

#从库node3--配置主从
change master to master_host='192.168.220.10',master_user='repl',master_password='Mysql@123',master_log_file='mysql-bin.000001',master_log_pos=595;
start slave;

#可以查看slave状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.220.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1481
               Relay_Log_File: node3-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes            #看到两个线程双Yes则配置成功

#主从搭建好之后把主库解表
mysql> unlock tables;

3、SQL_delay(延迟复制,给主库上一个保险)

        延迟复制时用来控制sql 线程的,和 i/o 线程无关
        这个延迟复制不是i/o 线程过段时间来复制, i/o 是正常工作的
        是日志已经保存在slave 端了,那个 sql 要等多久进行回放

步骤如下

        1)先停止从库SQL线程

        2)设置master_delay

        3)重新启动SQL线程 

#将node3配置为延迟复制从库
#停止SQL线程
STOP SLAVE SQL_THREAD;

#修改master_delay时间
CHANGE MASTER TO MASTER_DELAY=60;

#开启SQL线程
START SLAVE SQL_THREAD;

#在show slave status;内容里看到以下内容就配置成功
    SQL_Delay: 60

4、慢查询日志

  •  慢查询,顾名思义,执行很慢的查询
  • 当执行 SQL 超过 long_query_time 参数设定的时间阈值(默认 10s )时,就被认为是慢查询,这个 SQL语句就是需要优化的
  • 慢查询被记录在慢查询日志里
  • 慢查询日志默认是不开启的
  • 如果需要优化 SQL 语句,就可以开启这个功能,它可以让你很容易地知道哪些语句是需要优化的。
#慢查询日志默认不开启
mysql> show variables like "slow%";
+---------------------+----------------------------+
| Variable_name       | Value                      |
+---------------------+----------------------------+
| slow_launch_time    | 2                          |
| slow_query_log      | OFF                        |
| slow_query_log_file | /data/mysql/node1-slow.log |
+---------------------+----------------------------+
3 rows in set (0.00 sec)

#慢查询默认查询时间为10s
mysql> show variables like "long%";
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)

#开启慢查询日志,两种方法,一种通过命令行,一种通过修改配置参数,以下是命令行
set global slow_query_log=on

#验证慢查询日志是否开启
mysql> show variables like "slow%";
+---------------------+----------------------------+
| Variable_name       | Value                      |
+---------------------+----------------------------+
| slow_launch_time    | 2                          |
| slow_query_log      | ON                         |
| slow_query_log_file | /data/mysql/node1-slow.log |
+---------------------+----------------------------+
3 rows in set (0.00 sec)

#慢查询日志记录在slow_query_log_file所对应的位置/data/mysql/node1-slow.log里

5、并行复制

        默认情况下slave 中使用的是 sql 单线程回放 ,在master 中时多用户读写,如果使用 sql 单线程回放那么会造成组从延迟严重,开启MySQL 的多线程回放可以解决上述问题
#查看默认情况下slave的线程情况
mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  2 | root        | localhost | db1  | Query   |    0 | starting                                               | show processlist |
|  5 | system user |           | NULL | Connect | 4022 | Waiting for master to send event                       | NULL             |
|  7 | system user |           | NULL | Connect | 2911 | Slave has read all relay log; waiting for more updates | NULL             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

#将node2设定为多线程回放
slave-parallel-type=LOGICAL_CLOCK  #基于组提交
slave-parallel-workers=16          #开启的线程数量
master_info_repository=TABLE       #将master信息记录在表中,默认记录/data/mysql/master_info
relay_log_info_repository=TABLE    #将回放日志信息记录在表中,默认记录在/data/mysql目录下
relay_log_recovery=ON              #日志回放恢复功能开启

#查看修改过后slave的线程情况
mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  1 | system user |           | NULL | Connect |    5 | Waiting for master to send event                       | NULL             |
|  2 | system user |           | NULL | Connect |    5 | Slave has read all relay log; waiting for more updates | NULL             |
|  3 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
|  4 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
|  5 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
|  7 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
|  8 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
|  9 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
| 10 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
| 11 | system user |           | NULL | Connect |    5 | Waiting for an event from Coordinator                  | NULL             |
| 12 | root        | localhost | NULL | Query   |    0 | starting                                               | show processlist |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
11 rows in set (0.00 sec)

6、gtid模式

        思维引导:为什么需要gtid模式?

        在master 端的写入时多用户读写,在slave端的复制时单线程日志回放,所以slave端与master端一定会延迟, 这种延迟在 slave 端的延迟可能会不一致,当 master 挂掉后 slave 接管,一般会挑选一个和master延迟日志最接近的充当新的master,其余的slave主机重新指向新的master主机, 这时候按照之前的配置我们需要知道新的 master 上的 pos id ,但是我们无法确定新的 master slave 间差多少,于是我们就需要一个全局的日志,gtid

配置过程

  1. 在所有节点上开启gtid模式
  2. 停止所有的slave
  3. 重新配置从库change master to
  4. 启动所有slave节点
#在所有节点上开启gtid
[root@node1 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
log-bin=mysql-bin
server-id=1
gtid-mode=on                #以下两行内容,开始gtid
enforce-gtid-consistency=on

#从库操作皆以node2为例
mysql> stop slave;
mysql> change master to master_host='192.168.220.10',master_user='repl',master_password='Mysql@123',master_auto_position=1;
mysql> start slave;


#检验
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.220.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 154
               Relay_Log_File: node2-relay-bin.000002
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes            #出现双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: 154
              Relay_Log_Space: 574
              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: 7ead7e03-687d-11ef-8256-000c298c629a
             Master_Info_File: /data/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: 1            #出现这个则表示gtid模式成功开启
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

7、异步主从架构

        实际上主从同步的原理就是基于 binlog 进行数据同步的。在主从复制过程中,会基于3 个线程来操作, 一个主库线程,两个从库线程。

三个线程
  • 二进制日志转储线程( Binlog dump thread )是一个主库线程。当从库线程连接的时候, 主库可以将二进制日志发送给从库,当主库读取事件(Event )的时候,会在 Binlog 上加锁,读取完成之后,再将锁释放掉。
  • 从库 I/O 线程会连接到主库,向主库发送请求更新 Binlog 。这时从库的

http://www.kler.cn/news/289012.html

相关文章:

  • Ascend C算子开发(入门)—— 算子开发初体验
  • C++笔记---模板初阶
  • 论文速览【LLM】 —— 【ORLM】Training Large Language Models for Optimization Modeling
  • 多线程——创建
  • UDP广播、 组播通信
  • macos 使用port查询并安装python2, python3多版本, 设置默认python版本方法
  • 算法训练营|图论第8天 拓扑排序 dijkstra
  • 【笔试练习】深信服校园招聘c/c 软件开发H卷
  • 使用python导出Excel表格中的lua配置
  • 初识Linux · 有关makefile
  • 【Rust光年纪】化学计算不完全指南:Rust语言库全面解析
  • jenv 一款macos下的开源JAVA多版本环境安装管理切换工具
  • Swift concurrency 5 — async let的理解与使用
  • 聊聊随机测试和猴子测试
  • Python参数传递的艺术:解锁编程灵活性的秘密武器
  • uniapp写的一个年月日时分秒时间选择功能
  • 【数据结构初阶】——栈和队列
  • 求三元组中可能出现的最小距离
  • RabbitMQ练习(Routing)
  • 使用COAP和MQTT协议的多协议方法开发的用于机器人手术的自动医疗物联网系统
  • vue3+ts 实现模板表格文件下载~
  • pikachu文件包含漏洞靶场攻略
  • 密钥分发与公钥认证:保障网络通信的安全
  • MySQL入门学习-MySQL的连接查询
  • MySQL——事务与存储过程(二)存储过程的创建(4)光标的使用
  • 【Linux学习笔记】protobuf相关操作
  • 数仓基础(九):各大公司实时数仓实践
  • Go锁 详解
  • k8s-使用Network Policies实现网络隔离
  • (二)、软硬件全开源智能手表,可全面高精度采集生命体征数据,进行健康检测。(HealthyPi Move)