• mysql学习--binlog与gtid主从同步


    基础环境

    基于centOS7-MySQL8.0.35版本

    我们先准备一台主服务器两台从服务器来实现我们主从同步的诉求

    Master:192.168.75.142

    slave1:192.168.75.143

    slave:192.168.75.145

    binlog主从同步

    主库配置

    1. #我们需要在主从库中都需要添加server_id,每个库的server_id都不唯一
    2. [root@localhost ~]# tail -1 /etc/my.cnf
    3. server_id=1
    4. #重启mysql服务让配置分件生效
    5. [root@localhost ~]# systemctl restart mysqld
    6. #备份:
    7. [root@localhost ~]# mysqldump --opt -B -u root -p school school1> school.sql
    8. #授权用户:
    9. mysql> create user rep@'192.168.75.%' identified with mysql_native_password by 'Mhn@2001';
    10. mysql> grant replication slave on *.* to rep@'192.168.75.%';

    从库配置

    1. [root@localhost ~]# tail -1 /etc/my.cnf
    2. server_id=2
    3. [root@localhost ~]# systemctl restart mysqld
    4. [root@localhost ~]# tail -1 /etc/my.cnf
    5. server_id=3
    6. [root@localhost ~]# systemctl restart mysqld
    7. #还原主库备份,到从服务器家目录下:
    8. scp db.sql 192.168.75.143:/root/
    9. scp db.sql 192.168.75.145:/root/
    10. #在两台从主机上将复制的备份文件导入数据库
    11. mysql -uroot -pMysql@123 < school.sql
    12. #主库查看
    13. mysql> show master status;
    14. +------------------+----------+--------------+------------------+-------------------+
    15. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    16. +------------------+----------+--------------+------------------+-------------------+
    17. | mysql-bin.000001 | 679 | | | |
    18. +------------------+----------+--------------+------------------+-------------------+
    19. 1 row in set (0.00 sec)
    20. 从库配置
    21. change master to
    22. master_host='192.168.75.42',
    23. master_user='rep',
    24. master_password='Mhn@2001',
    25. master_log_file='mysql-bin.000001',
    26. master_log_pos=679,
    27. get_master_public_key=1;
    1. mysql> show slave status \G
    2. *************************** 1. row ***************************
    3. Slave_IO_State: Waiting for source to send event
    4. Master_Host: 192.168.75.142
    5. Master_User: rep
    6. Master_Port: 3306
    7. Connect_Retry: 60
    8. Master_Log_File: binlog.000002
    9. Read_Master_Log_Pos: 694
    10. Relay_Log_File: localhost-relay-bin.000002
    11. Relay_Log_Pos: 323
    12. Relay_Master_Log_File: binlog.000002
    13. Slave_IO_Running: Yes
    14. Slave_SQL_Running: Yes

    从这里可以查看到状态没有问题可以进行主从同步

    其他可选配置

    1. #[可选] 0(默认)表示读写(主机),1表示只读(从机)
    2. read-only=0
    3. #设置日志文件保留的时长,单位是秒
    4. binlog_expire_logs_seconds=6000
    5. #控制单个二进制日志大小。此参数的最大和默认值是1GB
    6. max_binlog_size=200M
    7. #[可选]设置不要复制的数据库
    8. binlog-ignore-db=test
    9. #[可选]设置需要复制的数据库,默认全部记录。
    10. binlog-do-db=需要复制的主数据库名字
    11. #[可选]设置binlog格式
    12. binlog_format=STATEMENT

    素材

    1. 数据库备份,数据库为school,素材如下
    2. 1.创建student和score表
    3. CREATE TABLE student (
    4. id INT(10) NOT NULL UNIQUE PRIMARY KEY ,
    5. name VARCHAR(20) NOT NULL ,
    6. sex VARCHAR(4) ,
    7. birth YEAR,
    8. department VARCHAR(20) ,
    9. address VARCHAR(50)
    10. );
    11. 创建score表。SQL代码如下:
    12. CREATE TABLE score (
    13. id INT(10) NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT ,
    14. stu_id INT(10) NOT NULL ,
    15. c_name VARCHAR(20) ,
    16. grade INT(10)
    17. );
    18. 2.为student表和score表增加记录
    19. 向student表插入记录的INSERT语句如下:
    20. INSERT INTO student VALUES( 901,'张老大', '男',1985,'计算机系', '北京市海淀区');
    21. INSERT INTO student VALUES( 902,'张老二', '男',1986,'中文系', '北京市昌平区');
    22. INSERT INTO student VALUES( 903,'张三', '女',1990,'中文系', '湖南省永州市');
    23. INSERT INTO student VALUES( 904,'李四', '男',1990,'英语系', '辽宁省阜新市');
    24. INSERT INTO student VALUES( 905,'王五', '女',1991,'英语系', '福建省厦门市');
    25. INSERT INTO student VALUES( 906,'王六', '男',1988,'计算机系', '湖南省衡阳市');
    26. 向score表插入记录的INSERT语句如下:
    27. INSERT INTO score VALUES(NULL,901, '计算机',98);
    28. INSERT INTO score VALUES(NULL,901, '英语', 80);
    29. INSERT INTO score VALUES(NULL,902, '计算机',65);
    30. INSERT INTO score VALUES(NULL,902, '中文',88);
    31. INSERT INTO score VALUES(NULL,903, '中文',95);
    32. INSERT INTO score VALUES(NULL,904, '计算机',70);
    33. INSERT INTO score VALUES(NULL,904, '英语',92);
    34. INSERT INTO score VALUES(NULL,905, '英语',94);
    35. INSERT INTO score VALUES(NULL,906, '计算机',90);
    36. INSERT INTO score VALUES(NULL,906, '英语',85);
    1. create database school;
    2. use school;
    3. CREATE TABLE `Student` (
    4. `Sno` int(10) NOT NULL COMMENT '学号', `Sname` varchar(16) NOT NULL COMMENT '姓名',
    5. `Ssex` char(2) NOT NULL COMMENT '性别', `Sage` tinyint(2) NOT NULL DEFAULT '0' COMMENT '学生年龄',
    6. `Sdept` varchar(16) DEFAULT 'NULL' COMMENT '学生所在系别', PRIMARY KEY (`Sno`)
    7. ) ;
    8. INSERT INTO `Student` VALUES (1, '陆亚', '男', 24, '计算机网络'),(2, 'tom', '男', 26, '英语'),(3, '张阳', '男', 21, '物流管理'), (4, 'alex', '女', 22, '电子商务');

    gtid主从同步

    GTID的工作原理:


    1.当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。

    2.binlog传输到slave,并存储到salve的relaylog后,读取这个GTID的这个值设置GTID——next变量,即告诉slave,下一个要执行的GTID值。

    3.sql线程从relaylog中获取GTID,然后对比slave端的binlog是否有该GTID。

    4.如果有记录说明该GTID的事务已经执行,slave会忽略。

    5.如果没有记录,slave会执行该GTID事务,并记录到该GTID到自身的binlog,在读取该事务前会检查其他session持有该GTID,确保不被重复执行。

    6.在解析过程中会判断是否有主键,如果没有就用二级索引,如果有就用全部扫描。

    主库配置

    1. 主库配置
    2. [root@localhost ~]# vim /etc/my.cnf
    3. server_id=1
    4. gtid_mode=ON #开启gtid模式
    5. enforce-gtid-consistency=ON #强制gtid一致性,开启后对特定的create table不支持
    6. log-bin=mysql-bin #开启二进制日志
    7. log-slave-updates=1 #从库binlog记录主库同步的操作日志
    8. skip-slave-start=1 #跳过slave复制线程
    9. #重启服务
    10. [root@localhost ~]# systemctl restart mysqld
    11. #查看服务状态
    12. [root@localhost ~]# systemctl status mysqld
    13. ● mysqld.service - MySQL Server
    14. Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
    15. Active: active (running) since 四 2024-02-29 11:04:01 CST; 37min ago
    16. Docs: man:mysqld(8)
    17. http://dev.mysql.com/doc/refman/en/using-systemd.html
    18. Process: 3740 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
    19. Main PID: 3770 (mysqld)
    20. Status: "Server is operational"
    21. Tasks: 40
    22. CGroup: /system.slice/mysqld.service
    23. └─3770 /usr/sbin/mysqld
    24. [root@localhost ~]# mysql -uroot -pMysql@123
    25. mysql> show variables like '%gtid%';
    26. +----------------------------------+------------------------------------------+
    27. | Variable_name | Value |
    28. +----------------------------------+------------------------------------------+
    29. | binlog_gtid_simple_recovery | ON |
    30. | enforce_gtid_consistency | ON |
    31. | gtid_executed | ff800e4d-d478-11ee-83a4-000c29b35fbd:1-8 |
    32. | gtid_executed_compression_period | 0 |
    33. | gtid_mode | ON |
    34. | gtid_next | AUTOMATIC |
    35. | gtid_owned | |
    36. | gtid_purged | |
    37. | session_track_gtids | OFF |
    38. +----------------------------------+------------------------------------------+
    39. 9 rows in set (0.01 sec)

    从库配置

    1. #slave1
    2. server_id=2
    3. gtid_mode=ON
    4. enforce-gtid-consistency=ON
    5. log-bin=mysql-bin
    6. log-slave-updates=1
    7. skip-slave-start=1
    8. mysql> show variables like '%gtid%';
    9. +----------------------------------+------------------------------------------+
    10. | Variable_name | Value |
    11. +----------------------------------+------------------------------------------+
    12. | binlog_gtid_simple_recovery | ON |
    13. | enforce_gtid_consistency | ON |
    14. | gtid_executed | ff800e4d-d478-11ee-83a4-000c29b35fbd:1-8 |
    15. | gtid_executed_compression_period | 0 |
    16. | gtid_mode | ON |
    17. | gtid_next | AUTOMATIC |
    18. | gtid_owned | |
    19. | gtid_purged | |
    20. | session_track_gtids | OFF |
    21. +----------------------------------+------------------------------------------+
    22. 9 rows in set (0.00 sec)
    23. #slave2
    24. server_id=3
    25. gtid_mode=ON
    26. enforce-gtid-consistency=ON
    27. log-bin=mysql-bin
    28. log-slave-updates=1
    29. skip-slave-start=1
    30. mysql> show variables like '%gtid%';
    31. +----------------------------------+------------------------------------------+
    32. | Variable_name | Value |
    33. +----------------------------------+------------------------------------------+
    34. | binlog_gtid_simple_recovery | ON |
    35. | enforce_gtid_consistency | ON |
    36. | gtid_executed | ff800e4d-d478-11ee-83a4-000c29b35fbd:1-8 |
    37. | gtid_executed_compression_period | 0 |
    38. | gtid_mode | ON |
    39. | gtid_next | AUTOMATIC |
    40. | gtid_owned | |
    41. | gtid_purged | |
    42. | session_track_gtids | OFF |
    43. +----------------------------------+------------------------------------------+
    44. 9 rows in set (0.00 sec)

    开启主从同步

    1. #主库
    2. mysql> stop slave;
    3. Query OK, 0 rows affected, 2 warnings (0.01 sec)
    4. mysql> create user rep@'192.168.75.%' identified with mysql_native_password by 'Mhn@2001';
    5. Query OK, 0 rows affected (0.04 sec)
    6. mysql> grant replication slave on *.* to rep@'192.168.75.%';
    7. Query OK, 0 rows affected (0.00 sec)
    1. #从库,两个都一样
    2. mysql> CHANGE MASTER TO
    3. -> MASTER_HOST = '192.168.75.142',
    4. -> MASTER_USER = 'rep',
    5. -> MASTER_PASSWORD = 'Mhn@2001',
    6. -> MASTER_AUTO_POSITION = 1;
    7. Query OK, 0 rows affected, 7 warnings (0.01 sec)
    1. #主库建立数据库
    2. mysql> create database book;
    3. Query OK, 1 row affected (0.00 sec)
    4. mysql> use book;
    5. Database changed
    6. mysql> CREATE TABLE books (name char(66),price int,pages int);
    7. '80','666');
    8. INSERT INTO books(name,price,pages) VALUES('Artificial Intelligence','166','666');Query OK, 0 rows affected (0.02 sec)
    9. mysql> INSERT INTO books(name,price,pages) VALUES('Linux','30','666');
    10. Query OK, 1 row affected (0.01 sec)
    11. mysql> INSERT INTO books(name,price,pages) VALUES('Cloud Computing','60','666');
    12. Query OK, 1 row affected (0.01 sec)
    13. mysql> INSERT INTO books(name,price,pages) VALUES('Operation System','80','666');
    14. Query OK, 1 row affected (0.00 sec)
    15. mysql> INSERT INTO books(name,price,pages) VALUES('Artificial Intelligence','166','666');
    16. Query OK, 1 row affected (0.00 sec)
    17. mysql> select * from books;
    18. +-------------------------+-------+-------+
    19. | name | price | pages |
    20. +-------------------------+-------+-------+
    21. | Linux | 30 | 666 |
    22. | Cloud Computing | 60 | 666 |
    23. | Operation System | 80 | 666 |
    24. | Artificial Intelligence | 166 | 666 |
    25. +-------------------------+-------+-------+
    26. 4 rows in set (0.00 sec)
    1. #从库的状态查看
    2. #slave1
    3. mysql> show slave status \G
    4. *************************** 1. row ***************************
    5. Slave_IO_State: Waiting for source to send event
    6. Master_Host: 192.168.75.142
    7. Master_User: rep
    8. Master_Port: 3306
    9. Connect_Retry: 60
    10. Master_Log_File: mysql-bin.000001
    11. Read_Master_Log_Pos: 680
    12. Relay_Log_File: localhost-relay-bin.000002
    13. Relay_Log_Pos: 896
    14. Relay_Master_Log_File: mysql-bin.000001
    15. Slave_IO_Running: Yes
    16. Slave_SQL_Running: Yes
    17. #slave2
    18. mysql> show slave status \G
    19. *************************** 1. row ***************************
    20. Slave_IO_State: Waiting for source to send event
    21. Master_Host: 192.168.75.142
    22. Master_User: rep
    23. Master_Port: 3306
    24. Connect_Retry: 60
    25. Master_Log_File: mysql-bin.000001
    26. Read_Master_Log_Pos: 680
    27. Relay_Log_File: localhost-relay-bin.000002
    28. Relay_Log_Pos: 896
    29. Relay_Master_Log_File: mysql-bin.000001
    30. Slave_IO_Running: Yes
    31. Slave_SQL_Running: Yes
    1. #从库查看
    2. mysql> show databases;
    3. +--------------------+
    4. | Database |
    5. +--------------------+
    6. | book |
    7. | information_schema |
    8. | mysql |
    9. | performance_schema |
    10. | sys |
    11. +--------------------+
    12. 5 rows in set (0.01 sec)
    13. mysql> use book;
    14. Reading table information for completion of table and column names
    15. You can turn off this feature to get a quicker startup with -A
    16. Database changed
    17. mysql> show tables;
    18. +----------------+
    19. | Tables_in_book |
    20. +----------------+
    21. | books |
    22. +----------------+
    23. 1 row in set (0.00 sec)
    24. mysql> select * from book.books;
    25. +-------------------------+-------+-------+
    26. | name | price | pages |
    27. +-------------------------+-------+-------+
    28. | Linux | 30 | 666 |
    29. | Cloud Computing | 60 | 666 |
    30. | Operation System | 80 | 666 |
    31. | Artificial Intelligence | 166 | 666 |
    32. +-------------------------+-------+-------+
    33. 4 rows in set (0.00 sec)

    主库

    从库1

    从库2

    可以看到最后的gtid值都一样这就说明我们配置完成。

    解决问题

    在gtid配置中如果出现 Last_IO_Error: Error connecting to source 'root@192.168.75.142:3306'. This was attempt 1/86400, with a delay of 60 seconds between attempts. Message: Host '192.168.75.143' is not allowed to connect to this MySQL server

    可以尝试更改一下主库的mysql>  create user rep@'192.168.75.%' identified with mysql_native_password by 'Mhn@2001';
    Query OK, 0 rows affected (0.04 sec)

    首先我们需要将所有的库进行stop slave;操作,然后进行操作,修改完成后再次开启就可以使用。

    在遇到问题可以使用翻译和查询日志来进行查看

    如果我们是使用一段时间mysql后才配置的gtid主从同步需要注意gtid值需要开始的位置,不能从1开始

    需要注入空事务,从而解决起始位置相同

    stop slave;
    set gtid_next='gtid值:开始位置';
    begin;commit;
    set gtid_next='AUTOMATIC';

    初始化mysql

    学习过程中因为gtid数据不同步可以进行初始化mysql

    在初始化之前必须要将mysql数据目录所有内容全部清空

    systemctl stop mysqld

    mysql --initialize --uesr=mysql

    然后重新启动mysql

    systemctl restart mysqld

    进入mysql,进入后需要刷新权限表

    FLUSH PRIVILEGES;

    最后再修改密码

    alter user root@localhost identified by 'Mysql@123';

    最后需要在配置文件中删除--skip-grant-tables

  • 相关阅读:
    Java学习——Java数组总结
    当 SQL DELETE 邂逅 Table aliases,会擦出怎样的火花
    OAuth2 的授权流程
    Pycharm连接远程服务器 导入远程包时本地显示红色解决方法
    基于51单片机pwm调光护眼台灯智能检测光强光控灯设计proteus仿真原理图PCB
    C++之std::enable_shared_from_this实例(一百九十八)
    java多线程编程:你真的了解线程中断吗?
    了解享元模式
    基于ACO蚁群算法的tsp优化问题matlab仿真
    【Flink】flink 状态恢复 because the operator is not available in the new program
  • 原文地址:https://blog.csdn.net/2202_76007104/article/details/136366292