赞
踩
基于centOS7-MySQL8.0.35版本
我们先准备一台主服务器两台从服务器来实现我们主从同步的诉求
Master:192.168.75.142
slave1:192.168.75.143
slave:192.168.75.145
- #我们需要在主从库中都需要添加server_id,每个库的server_id都不唯一
- [root@localhost ~]# tail -1 /etc/my.cnf
- server_id=1
- #重启mysql服务让配置分件生效
- [root@localhost ~]# systemctl restart mysqld
- #备份:
- [root@localhost ~]# mysqldump --opt -B -u root -p school school1> school.sql
- #授权用户:
- mysql> create user rep@'192.168.75.%' identified with mysql_native_password by 'Mhn@2001';
- mysql> grant replication slave on *.* to rep@'192.168.75.%';
- [root@localhost ~]# tail -1 /etc/my.cnf
- server_id=2
- [root@localhost ~]# systemctl restart mysqld
-
- [root@localhost ~]# tail -1 /etc/my.cnf
- server_id=3
- [root@localhost ~]# systemctl restart mysqld
-
- #还原主库备份,到从服务器家目录下:
- scp db.sql 192.168.75.143:/root/
- scp db.sql 192.168.75.145:/root/
-
- #在两台从主机上将复制的备份文件导入数据库
- mysql -uroot -pMysql@123 < school.sql
-
- #主库查看
- mysql> show master status;
- +------------------+----------+--------------+------------------+-------------------+
- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
- +------------------+----------+--------------+------------------+-------------------+
- | mysql-bin.000001 | 679 | | | |
- +------------------+----------+--------------+------------------+-------------------+
- 1 row in set (0.00 sec)
-
- 从库配置
- change master to
- master_host='192.168.75.42',
- master_user='rep',
- master_password='Mhn@2001',
- master_log_file='mysql-bin.000001',
- master_log_pos=679,
- get_master_public_key=1;
- mysql> show slave status \G
- *************************** 1. row ***************************
- Slave_IO_State: Waiting for source to send event
- Master_Host: 192.168.75.142
- Master_User: rep
- Master_Port: 3306
- Connect_Retry: 60
- Master_Log_File: binlog.000002
- Read_Master_Log_Pos: 694
- Relay_Log_File: localhost-relay-bin.000002
- Relay_Log_Pos: 323
- Relay_Master_Log_File: binlog.000002
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
从这里可以查看到状态没有问题可以进行主从同步
- #[可选] 0(默认)表示读写(主机),1表示只读(从机)
- read-only=0
- #设置日志文件保留的时长,单位是秒
- binlog_expire_logs_seconds=6000
- #控制单个二进制日志大小。此参数的最大和默认值是1GB
- max_binlog_size=200M
- #[可选]设置不要复制的数据库
- binlog-ignore-db=test
- #[可选]设置需要复制的数据库,默认全部记录。
- binlog-do-db=需要复制的主数据库名字
- #[可选]设置binlog格式
- binlog_format=STATEMENT
- 数据库备份,数据库为school,素材如下
-
- 1.创建student和score表
-
- CREATE TABLE student (
- id INT(10) NOT NULL UNIQUE PRIMARY KEY ,
- name VARCHAR(20) NOT NULL ,
- sex VARCHAR(4) ,
- birth YEAR,
- department VARCHAR(20) ,
- address VARCHAR(50)
- );
-
- 创建score表。SQL代码如下:
-
- CREATE TABLE score (
- id INT(10) NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT ,
- stu_id INT(10) NOT NULL ,
- c_name VARCHAR(20) ,
- grade INT(10)
- );
-
- 2.为student表和score表增加记录
-
- 向student表插入记录的INSERT语句如下:
-
- INSERT INTO student VALUES( 901,'张老大', '男',1985,'计算机系', '北京市海淀区');
- INSERT INTO student VALUES( 902,'张老二', '男',1986,'中文系', '北京市昌平区');
- INSERT INTO student VALUES( 903,'张三', '女',1990,'中文系', '湖南省永州市');
- INSERT INTO student VALUES( 904,'李四', '男',1990,'英语系', '辽宁省阜新市');
- INSERT INTO student VALUES( 905,'王五', '女',1991,'英语系', '福建省厦门市');
- INSERT INTO student VALUES( 906,'王六', '男',1988,'计算机系', '湖南省衡阳市');
-
- 向score表插入记录的INSERT语句如下:
- INSERT INTO score VALUES(NULL,901, '计算机',98);
- INSERT INTO score VALUES(NULL,901, '英语', 80);
- INSERT INTO score VALUES(NULL,902, '计算机',65);
- INSERT INTO score VALUES(NULL,902, '中文',88);
- INSERT INTO score VALUES(NULL,903, '中文',95);
- INSERT INTO score VALUES(NULL,904, '计算机',70);
- INSERT INTO score VALUES(NULL,904, '英语',92);
- INSERT INTO score VALUES(NULL,905, '英语',94);
- INSERT INTO score VALUES(NULL,906, '计算机',90);
- INSERT INTO score VALUES(NULL,906, '英语',85);
- create database school;
- use school;
- CREATE TABLE `Student` (
- `Sno` int(10) NOT NULL COMMENT '学号', `Sname` varchar(16) NOT NULL COMMENT '姓名',
- `Ssex` char(2) NOT NULL COMMENT '性别', `Sage` tinyint(2) NOT NULL DEFAULT '0' COMMENT '学生年龄',
- `Sdept` varchar(16) DEFAULT 'NULL' COMMENT '学生所在系别', PRIMARY KEY (`Sno`)
- ) ;
- INSERT INTO `Student` VALUES (1, '陆亚', '男', 24, '计算机网络'),(2, 'tom', '男', 26, '英语'),(3, '张阳', '男', 21, '物流管理'), (4, 'alex', '女', 22, '电子商务');
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.在解析过程中会判断是否有主键,如果没有就用二级索引,如果有就用全部扫描。
- 主库配置
- [root@localhost ~]# vim /etc/my.cnf
- server_id=1
- gtid_mode=ON #开启gtid模式
- enforce-gtid-consistency=ON #强制gtid一致性,开启后对特定的create table不支持
- log-bin=mysql-bin #开启二进制日志
- log-slave-updates=1 #从库binlog记录主库同步的操作日志
- skip-slave-start=1 #跳过slave复制线程
-
- #重启服务
- [root@localhost ~]# systemctl restart mysqld
- #查看服务状态
- [root@localhost ~]# systemctl status mysqld
- ● mysqld.service - MySQL Server
- Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
- Active: active (running) since 四 2024-02-29 11:04:01 CST; 37min ago
- Docs: man:mysqld(8)
- http://dev.mysql.com/doc/refman/en/using-systemd.html
- Process: 3740 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
- Main PID: 3770 (mysqld)
- Status: "Server is operational"
- Tasks: 40
- CGroup: /system.slice/mysqld.service
- └─3770 /usr/sbin/mysqld
-
- [root@localhost ~]# mysql -uroot -pMysql@123
- mysql> show variables like '%gtid%';
- +----------------------------------+------------------------------------------+
- | Variable_name | Value |
- +----------------------------------+------------------------------------------+
- | binlog_gtid_simple_recovery | ON |
- | enforce_gtid_consistency | ON |
- | gtid_executed | ff800e4d-d478-11ee-83a4-000c29b35fbd:1-8 |
- | gtid_executed_compression_period | 0 |
- | gtid_mode | ON |
- | gtid_next | AUTOMATIC |
- | gtid_owned | |
- | gtid_purged | |
- | session_track_gtids | OFF |
- +----------------------------------+------------------------------------------+
- 9 rows in set (0.01 sec)
-
- #slave1
- server_id=2
- gtid_mode=ON
- enforce-gtid-consistency=ON
- log-bin=mysql-bin
- log-slave-updates=1
- skip-slave-start=1
- mysql> show variables like '%gtid%';
- +----------------------------------+------------------------------------------+
- | Variable_name | Value |
- +----------------------------------+------------------------------------------+
- | binlog_gtid_simple_recovery | ON |
- | enforce_gtid_consistency | ON |
- | gtid_executed | ff800e4d-d478-11ee-83a4-000c29b35fbd:1-8 |
- | gtid_executed_compression_period | 0 |
- | gtid_mode | ON |
- | gtid_next | AUTOMATIC |
- | gtid_owned | |
- | gtid_purged | |
- | session_track_gtids | OFF |
- +----------------------------------+------------------------------------------+
- 9 rows in set (0.00 sec)
-
-
- #slave2
- server_id=3
- gtid_mode=ON
- enforce-gtid-consistency=ON
- log-bin=mysql-bin
- log-slave-updates=1
- skip-slave-start=1
- mysql> show variables like '%gtid%';
- +----------------------------------+------------------------------------------+
- | Variable_name | Value |
- +----------------------------------+------------------------------------------+
- | binlog_gtid_simple_recovery | ON |
- | enforce_gtid_consistency | ON |
- | gtid_executed | ff800e4d-d478-11ee-83a4-000c29b35fbd:1-8 |
- | gtid_executed_compression_period | 0 |
- | gtid_mode | ON |
- | gtid_next | AUTOMATIC |
- | gtid_owned | |
- | gtid_purged | |
- | session_track_gtids | OFF |
- +----------------------------------+------------------------------------------+
- 9 rows in set (0.00 sec)
- #主库
- mysql> stop slave;
- Query OK, 0 rows affected, 2 warnings (0.01 sec)
-
- mysql> create user rep@'192.168.75.%' identified with mysql_native_password by 'Mhn@2001';
- Query OK, 0 rows affected (0.04 sec)
-
- mysql> grant replication slave on *.* to rep@'192.168.75.%';
- Query OK, 0 rows affected (0.00 sec)
- #从库,两个都一样
- mysql> CHANGE MASTER TO
- -> MASTER_HOST = '192.168.75.142',
- -> MASTER_USER = 'rep',
- -> MASTER_PASSWORD = 'Mhn@2001',
- -> MASTER_AUTO_POSITION = 1;
- Query OK, 0 rows affected, 7 warnings (0.01 sec)
- #主库建立数据库
- mysql> create database book;
- Query OK, 1 row affected (0.00 sec)
-
- mysql> use book;
- Database changed
- mysql> CREATE TABLE books (name char(66),price int,pages int);
- '80','666');
- INSERT INTO books(name,price,pages) VALUES('Artificial Intelligence','166','666');Query OK, 0 rows affected (0.02 sec)
-
- mysql> INSERT INTO books(name,price,pages) VALUES('Linux','30','666');
- Query OK, 1 row affected (0.01 sec)
-
- mysql> INSERT INTO books(name,price,pages) VALUES('Cloud Computing','60','666');
- Query OK, 1 row affected (0.01 sec)
-
- mysql> INSERT INTO books(name,price,pages) VALUES('Operation System','80','666');
- Query OK, 1 row affected (0.00 sec)
-
- mysql> INSERT INTO books(name,price,pages) VALUES('Artificial Intelligence','166','666');
- Query OK, 1 row affected (0.00 sec)
-
- mysql> select * from books;
- +-------------------------+-------+-------+
- | name | price | pages |
- +-------------------------+-------+-------+
- | Linux | 30 | 666 |
- | Cloud Computing | 60 | 666 |
- | Operation System | 80 | 666 |
- | Artificial Intelligence | 166 | 666 |
- +-------------------------+-------+-------+
- 4 rows in set (0.00 sec)
- #从库的状态查看
- #slave1
- mysql> show slave status \G
- *************************** 1. row ***************************
- Slave_IO_State: Waiting for source to send event
- Master_Host: 192.168.75.142
- Master_User: rep
- Master_Port: 3306
- Connect_Retry: 60
- Master_Log_File: mysql-bin.000001
- Read_Master_Log_Pos: 680
- Relay_Log_File: localhost-relay-bin.000002
- Relay_Log_Pos: 896
- Relay_Master_Log_File: mysql-bin.000001
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- #slave2
- mysql> show slave status \G
- *************************** 1. row ***************************
- Slave_IO_State: Waiting for source to send event
- Master_Host: 192.168.75.142
- Master_User: rep
- Master_Port: 3306
- Connect_Retry: 60
- Master_Log_File: mysql-bin.000001
- Read_Master_Log_Pos: 680
- Relay_Log_File: localhost-relay-bin.000002
- Relay_Log_Pos: 896
- Relay_Master_Log_File: mysql-bin.000001
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- #从库查看
- mysql> show databases;
- +--------------------+
- | Database |
- +--------------------+
- | book |
- | information_schema |
- | mysql |
- | performance_schema |
- | sys |
- +--------------------+
- 5 rows in set (0.01 sec)
-
- mysql> use book;
- Reading table information for completion of table and column names
- You can turn off this feature to get a quicker startup with -A
-
- Database changed
- mysql> show tables;
- +----------------+
- | Tables_in_book |
- +----------------+
- | books |
- +----------------+
- 1 row in set (0.00 sec)
-
- mysql> select * from book.books;
- +-------------------------+-------+-------+
- | name | price | pages |
- +-------------------------+-------+-------+
- | Linux | 30 | 666 |
- | Cloud Computing | 60 | 666 |
- | Operation System | 80 | 666 |
- | Artificial Intelligence | 166 | 666 |
- +-------------------------+-------+-------+
- 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';
学习过程中因为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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。