• mysql主从架构


    mysql主从架构是一套非常基础的高可用架构,主要依赖复制技术来实现。

    1.复制原理

    mysql复制功能主要使用三个线程实现:

    1.Binary log dump thread(二进制日志转储线程):当副本连接时发送二进制日志

    2.Replication I/O receiver thread(复制 I/O 接收器线程): I/O(接收器)线程,连接到源服务器要求它发送其二进制日志中记录的更新,复制源服务器发送的二进制日志保存到中继日志(relay log

    3.Replication SQL applier thread (复制 SQL 应用程序线程):复制中继日志并执行其中包含的记录

     

    1. 主库执行DDL、DML更新binlog
    2. 二进制日志转储线程检测到binlog更新主动发送binlog给从库
    3. 从库I/O线程接收到binlog后写入到relaylog中
    4. 从库SQL线程检测到relaylog更新,复制relaylog到SQL线程并执行SQL。 

     

    2.配置主从

    1.主库建立唯一的服务器 ID 

    mysql> SET GLOBAL server_id = 2; 

    持久化修改:

    在/etc/my.cnf添加server-id = 2

     

    查看server_id变量 

    mysql> show global variables like 'server_id'; 

    2.主库开启二进制日志

    查看二进制日志是否开启

    mysql> SHOW VARIABLES LIKE 'log_bin';

    除了使用mysqld命令启动mysql二进制日志是默认不开启的,其他情况都是二进制日志默认是开启的

    如果不开启,需要修改/etc/my.cnf配置文件

    在[mysqld]添加

    log_bin=ON

    重启mysql 

    3.创建复制用户

    mysql> CREATE USER 'repl'@'%' IDENTIFIED BY '123456';

    mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

    查看用户

    mysql> select Host,User from mysql.user; 

    4.获取主库二进制日志坐标 

    先锁表,阻止InnoDB进行Commit操作,待副本复制好后可以释放锁,保证主库和从库的数据一致性(会话退出也会自动释放锁)

     mysql> FLUSH TABLES WITH READ LOCK;

    确定当前二进制日志文件名和位置 

     mysql> SHOW MASTER STATUS\G

     

    5.对主库进行快照

    可以选择物理备份、逻辑备份等方法。。。

    我这里用的是docker,我直接对主库容器进行镜像,再用这个镜像开启容器作为mysql从库

    查看容器

    创建镜像

    docker commit 10d74d587551 mysql8-slave 

    查看镜像

     释放主库的read lock

    mysql> UNLOCK TABLES;

     6.启动从库

    docker run --name=mysql8-slave10  --restart on-failure -p 3310:3306 -d mysql8-slave:latest

    连接上从库服务器

    docker exec -it mysql8-slave10 bash 

    修改从库的server_id

     SET GLOBAL server_id = 21;

    持久化修改:

    在/etc/my.cnf添加server-id = 21 

     

    从库如果不需要binlog可以关闭该功能,毕竟开启需要消耗资源

    如果这个从库是用作备份或者故障恢复等需要用到binlog可以开启binlog

     关闭从库binlog

    在/etc/my.cnf添加

    [mysqld]
    # 关闭二进制日志
    skip-log-bin

     7.在从库设置主库复制信息

    MySQL 8.0.23之前使用这种格式:

    mysql> CHANGE MASTER TO

    -> MASTER_HOST='source_host_name',

    -> MASTER_USER='replication_user_name',

    -> MASTER_PASSWORD='replication_password',

    -> MASTER_LOG_FILE='recorded_log_file_name',

    -> MASTER_LOG_POS=recorded_log_position;

    MySQL 8.0.23之后使用这种格式:

    mysql> CHANGE REPLICATION SOURCE TO

    -> SOURCE_HOST='source_host_name',

    -> SOURCE_USER='replication_user_name',

    -> SOURCE_PASSWORD='replication_password',

    -> SOURCE_LOG_FILE='recorded_log_file_name',

    -> SOURCE_LOG_POS=recorded_log_position

     我连接的是本机的3309端口

    CHANGE REPLICATION SOURCE TO SOURCE_HOST='10.0.12.12',SOURCE_USER='repl',SOURCE_PASSWORD='123456',master_port=3309,SOURCE_LOG_FILE='mysql-bin.000001',SOURCE_LOG_POS=1284;

     8.从库启动slave

    mysql> start slave;

    查看slave状态

    mysql> SHOW SLAVE STATUS\G 

    我第一次启动发现启动失败

    报错:

    Last_IO_Error: Error connecting to source 'repl@10.0.12.12:3309'. This was attempt 1/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.

    意思是连接失败 ,需要caching_sha2_password安全连接

    从MySQL 8.0 中, 默认身份验证插件caching_sha2_password

    解决办法:

    重新设置主库复制信息,加上了主库公钥的位置获取公钥:

    CHANGE REPLICATION SOURCE TO SOURCE_HOST='10.0.12.12',SOURCE_USER='repl',SOURCE_PASSWORD='123456',master_port=3309,SOURCE_LOG_FILE='mysql-bin.000001',SOURCE_LOG_POS=1284,Master_public_key_path='/var/lib/mysql/public_key.pem',Get_master_public_key=1;

     

    再次启动又出现错误:

     Last_IO_Error: Fatal error: The replica I/O thread stops because source and replica have equal MySQL server UUIDs; these UUIDs must be different for replication to work.

     意思是主库和从库的MySQL服务器UUID相同了

    解决办法:

    删除从库的UUID,重启从库重新生成UUID

     rm -rf /var/lib/mysql/auto.cnf 

     

     这两个为yes表示启动成功

     

    9.测试

    主库操作 

    1. mysql> create database mytest;
    2. Query OK, 1 row affected (0.02 sec)
    3. mysql> show databases;
    4. +--------------------+
    5. | Database |
    6. +--------------------+
    7. | information_schema |
    8. | mysql |
    9. | mytest |
    10. | performance_schema |
    11. | sys |
    12. | test888 |
    13. +--------------------+
    14. 6 rows in set (0.03 sec)

    从库同步 

    1. mysql> show databases;
    2. +--------------------+
    3. | Database |
    4. +--------------------+
    5. | information_schema |
    6. | mysql |
    7. | mytest |
    8. | performance_schema |
    9. | sys |
    10. | test888 |
    11. +--------------------+
    12. 6 rows in set (0.00 sec)

    3.主从数据一致性

    主从架构是对主库DDL、DML操作会同步到从库,但是对从库 DDL、DML操作不会同步到主库,这就会造成主从数据不一致了。

    如果从库存在一条在主库没有的数据,那么主库插入相同的数据同步到从库时会报错。 

     怎么解决?

    1.跳过错误继续同步

     如果这些不同步数据对业务没有影响可以选择跳过错误

    (1)在主库锁表

    FLUSH TABLES WITH READ LOCK;

    (2) 停掉从库slave

    stop slave;

    (3)从库设置跳过命令 

    set global sql_slave_skip_counter = 1;  # 跳过一次 

    (4)从库启动slave 

    start slave;

    (5)主库释放锁 

     UNLOCK TABLES;

     

    2.重做主从架构

    重新保持主库一致性

    (1)主库锁表

     FLUSH TABLES WITH READ LOCK;

    (2)逻辑备份主库 

    mysqldump -uroot -p123456 --all-databases -A >> all.sql 

    (3)把主库数据全部导入从库中

    mysql -uroot -p123456 < all.sql 

    (4)主库释放锁 

    UNLOCK TABLES;

     

     4.主从延迟

    查看是否有延迟

     mysql> show slave status\G

     

    Seconds_Behind_Master为0表示没有延迟,数值越高表示延迟越高。 

     

     

     

  • 相关阅读:
    【吴恩达机器学习-笔记整理】OCR,滑动窗口,数据扩增,上限分析,计算机视觉
    ESXI 7 :创建统信V20_1050d服务器系统虚拟机
    [AIGC] 深入理解Flink中的窗口、水位线和定时器
    浅谈Kube-OVN
    java 多excel下载 打成zip压缩包 程序中创建文件 响应到浏览器
    jquery动画效果
    漫游计算机系统
    图神经网络-GraphSage
    微服务概览
    云和恩墨大讲堂 x openGauss Meetup x 鲲鹏生态孵化营(上海站)圆满落幕
  • 原文地址:https://blog.csdn.net/weixin_51262054/article/details/134221678