MySQL 集群讲解与搭建


1. 基于binlog搭建主从复制

  1)、主从复制原理

  

       - 用户写入数据到master数据库中

    - master数据库数据写入binlog文件中,通知到slave数据库

    - slave数据库的I/O线程从master数据库binlog读取数据到slave数据库的relay log中

    - slave数据库的SQL线程重放relaylog,也就是将数据还原到库中

  2)、binlog三种模式:通过命令show variables like 'binlog_format';或select @@binlog_format;可查看binlog日志模式;也可通过命令set binlog_format=STATEMENT或ROW或MIXED设置binlog模式;命令只是临时的,重启MySQL就会失效,永久设置需要在my.cnf的[msqld]下添加binlog_format=STATEMENT或ROW或MIXED

    - statement level模式:每一条修改数据的SQL记录到master的binlog中,这样会减少binlog数据量,slave只需根据SQL命令就可以同步数据,但是这只限于简单的SQL操作,如果有依赖宿主环境和复杂函数的SQL就不能正确同步数据了,如记录宿主机机器名等;

    - row level模式:master的binlog记录每一行数据被修改的形式,slave会做同样的修改,这样可以避免statement level的缺点,但会带来数据量大的问题,如一个简单的update SQL操作,statement level就是一条SQL记录,而row level要记录下所有影响行的数据;

    - mixed模式:会结合statement level和row level优点区分对待记录日志形式。其实新版本的MySQL已经对row level模式做了一定优化,比如对表定义的修改就以statement level形式记录。

  3)、主从复制环境搭建:(如果有防火墙限制,可以先关闭防火墙)MySQL客户端可以是docker内登录或者其他连接MySQL的客户端

    a. 主服务器配置如下:

    - 开启binlog,MySQL8.0默认开启,可通过命令show variables like 'log_bin%';查看到log_bin为ON;如果默认为OFF,即关闭,需要在my.cnf的[msqld]下添加log_bin=mybinlog,mybinlog可以自定义修改,为binlog的basename;

    - 设置server_id,在my.cnf的[msqld]下添加server_id=3316,保证集群中唯一;我本地用docker环境,配置的server_id为对外暴露的端口号;

    - 在配置文件修改完log_bin和server_id后,启动镜像容器,成功后,可在数据文件下看到mybinlog.index文件,里面记录的是mybinlog文件位置,可直接使用cat命令查看,而查看binlog文件需要使用mysql工具命令:docker exec -it mysqlmaster mysqlbinlog --no-defaults --base64-output=decode-rows /var/lib/mysql/mybinlog.000001,--no-defaults参数是解决mysqlbinlog: [ERROR] unknown variable 'default-character-set=utf8mb4';

docker run --name mysqlmaster -p 3316:3306 --privileged=true -v /root/mysqlmaster/conf:/etc/mysql/conf.d -v /root/mysqlmaster/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0

    - 在mysql客户端创建一个用户,用于slave中配置连接master,同步数据,同时授予该用户备份数据权限;如果不想创建新用户可直接用root,赋予备份数据权限即可;

create user 'rep'@'%' identified by '@Rep123';
grant replication slave on *.* to 'rep'@'%';

    - 在mysql客户端执行刷新权限命令:flush privileges;

    - 在mysql客户端查看master状态,命令:show master status; ,记录file和position,要用到slave配置中;如file为mybinlog.000003,position为896

    b. 从服务器配置如下:

    - 设置server_id,在my.cnf的[msqld]下添加server_id=3326,保证集群中唯一;我本地用docker环境,配置的server_id为对外暴露的端口号;

    - 配置完后启动镜像容器

docker run --name mysqlslave -p 3326:3306 --privileged=true -v /root/mysqlslave/conf:/etc/mysql/conf.d -v /root/mysqlslave/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0

    - 将master中现有数据手动迁移到slave,如果是全新的库,可忽略此步    

    - 在mysql客户端执行如下命令,指定slave的master信息

change master to
master_host='10.0.79.61',
master_port=3316,
master_user='rep',
master_password='@Rep123',
master_log_file='mybinlog.000004',
master_log_pos=156,
MASTER_AUTO_POSITION=0;

    - 在mysql客户端启动从服务器复制功能:start slave;

    - 在mysql客户端执行命令:show slave status;查看从库是否正常,可观察Slave_IO_Running和Slave_SQL_Running值都为Yes即可

    c. 测试(本地测试通过):

    - 在主库中执行创建数据库:create database dbtest;use dbtest;

    - 创建表

CREATE TABLE `test` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `a` bigint DEFAULT NULL,
  `b` bigint DEFAULT NULL,
  `c` bigint DEFAULT NULL,
  `d` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_a_b_c` (`a`,`b`,`c`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

    - 插入数据,查看从库,同步成功。

    d. 清理binlog方式:

    - 手动清理:按照时间清理命令purge master logs before '2022-01-01 17:20:00';或按照文件索引清理purge master logs to'mybinlog.000022';

    - 自动清理,设置binlog过期时间:expire_logs_days=7,单位天

2. 基于主从复制的高可用方案,可设计如下,准备两个双主节点的数据库,也就是互相做主从复制,通过keepalive工具实现高可用

  

3. 基于MySQL-Proxy搭建读写分离

  MySQL官方不推荐用于生产,所以做赘述

4. MySQL Router搭建MySQL集群

  实际工作中用的并不多,生产上用的都是MySQL中间件,如当当的sharding-jdbc,蘑菇街的TSharding,奇虎360的Atlas,阿里的Cobar,阿里基于Cobar的MyCAT,58同城的Oceanus,谷歌的Vitess

5. 生产用的分库分表后期通过ShardingSphere进行讲解和实现


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM