数据库Mysql主从复制

**作者:行癫**(盗版必究) ------ ## 一:环境准备 1.操作系统 Stream 9 2.数据库版本 Mysql 8.4.4 3.节点属性M-S-S ## 二:数据库安装 注意:以下操作所有节点部署 #### 1.准备仓库 ```shell [root@master ~]# yum -y install https://dev.mysql.com/get/mysql84-community-release-el9-1.noarch.rpm ``` #### 2.安装数据库 ```shell [root@master ~]# yum -y install mysql mysql-server ``` #### 3.启动数据库 ```shell [root@master ~]# systemctl start mysqld [root@master ~]# systemctl enable ``` #### 4.修改初始密码 ```shell [root@master ~]# cat /var/log/mysqld.log | grep password 2025-04-01T07:52:03.074402Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 7afbYmmmJt)) [root@master ~]# mysqladmin -u root -p'7afbYmmmJt))' password 'XingDian@123' mysqladmin: [Warning] Using a password on the command line interface can be insecure. Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety. ``` ## 三:配置主从 ### 1.创建证书 #### 1.创建目录 ```shell [root@master ~]# mkdir /etc/mysql/ssl -p ``` #### 2.创建CA证书 ```shell [root@master ssl]# openssl genrsa 2048 > ca-key.pem [root@master ssl]# openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca-cert.pem ``` #### 3.创建server证书 ``` [root@master ssl]# openssl genrsa 2048 > server-key.pem [root@master ssl]# openssl req -new -key server-key.pem -out server-req.pem [root@master ssl]# openssl x509 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem ``` #### 4.创建client证书 ``` [root@master ssl]# openssl genrsa 2048 > client-key.pem [root@master ssl]# openssl req -new -key client-key.pem -out client-req.pem [root@master ssl]# openssl x509 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 02 -out client-cert.pem ``` #### 5.证书同步 所有节点创建对应的目录 所有节点同步证书文件 ### 2.主节点 #### 1.开启GITD模式 ```shell [root@master ~]# cat /etc/my.cnf server_id=1 gtid_mode=on enforce_gtid_consistency=on binlog_checksum=none log_bin=mysql-bin log_slave_updates=on binlog_format=row require_secure_transport=ON ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/server-cert.pem ssl-key=/etc/mysql/ssl/server-key.pem [root@master ~]# systemctl restart mysqld ``` #### 2.创建用户并授权 ```shell [root@slave-1 ~]# mysql -u root -pXingDian@123 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.4.4 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> create user slave identified with 'caching_sha2_password' BY 'XingDian@123' REQUIRE SSL; Query OK, 0 rows affected (0.08 sec) 强制启用ssl传输 mysql> GRANT REPLICATION SLAVE ON *.* to 'slave'@'%'; Query OK, 0 rows affected (0.27 sec) mysql> GRANT CONNECTION_ADMIN ON *.* to 'slave'@'%'; Query OK, 0 rows affected (0.06 sec) mysql> GRANT BACKUP_ADMIN ON *.* to 'slave'@'%'; Query OK, 0 rows affected (0.10 sec) mysql> flush privileges; Query OK, 0 rows affected (0.05 sec) ``` ### 2.从节点 #### 1.开启GITD模式 ```shell [root@slave-1 ~]# cat /etc/my.cnf server_id=2 gtid_mode=on enforce_gtid_consistency=on binlog_checksum=none log_bin=mysql-bin log_slave_updates=on binlog_format=row require_secure_transport=ON ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/client-cert.pem ssl-key=/etc/mysql/ssl/client-key.pem [root@slave-1 ~]# systemctl restart mysqld ``` #### 2.连接主库 ```shell 连接数据库后输入edit,复制以下内容保存退出 CHANGE REPLICATION SOURCE TO SOURCE_HOST='master.mysql.com', SOURCE_USER='slave', SOURCE_PASSWORD='XingDian@123', SOURCE_AUTO_POSITION=1, SOURCE_SSL=1, SOURCE_SSL_CA='/etc/mysql/ssl/ca-cert.pem', SOURCE_SSL_CERT='/etc/mysql/ssl/client-cert.pem', SOURCE_SSL_KEY='/etc/mysql/ssl/client-key.pem'; ``` #### 3.启动复制 ```shell mysql> start replica; Query OK, 0 rows affected (0.38 sec) ``` #### 4.查看状态 注意观察IO线程和SQL线程,都为YES则主从复制成功 ```shell mysql> show replica status\G *************************** 1. row *************************** Replica_IO_State: Waiting for source to send event Source_Host: master.mysql.com Source_User: slave Source_Port: 3306 Connect_Retry: 60 Source_Log_File: mysql-bin.000001 Read_Source_Log_Pos: 841 Relay_Log_File: slave-1-relay-bin.000002 Relay_Log_Pos: 1050 Relay_Source_Log_File: mysql-bin.000001 Replica_IO_Running: Yes Replica_SQL_Running: 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_Source_Log_Pos: 841 Relay_Log_Space: 1255 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Source_SSL_Allowed: Yes Source_SSL_CA_File: /etc/mysql/ssl/ca-cert.pem Source_SSL_CA_Path: Source_SSL_Cert: /etc/mysql/ssl/client-cert.pem Source_SSL_Cipher: Source_SSL_Key: /etc/mysql/ssl/client-key.pem Seconds_Behind_Source: 0 Source_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Source_Server_Id: 1 Source_UUID: 50a9a869-0efa-11f0-8e51-52540047de4e Source_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates Source_Retry_Count: 10 Source_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Source_SSL_Crl: Source_SSL_Crlpath: Retrieved_Gtid_Set: 50a9a869-0efa-11f0-8e51-52540047de4e:1-3 Executed_Gtid_Set: 50a9a869-0efa-11f0-8e51-52540047de4e:1-3 Auto_Position: 1 Replicate_Rewrite_DB: Channel_Name: Source_TLS_Version: Source_public_key_path: Get_Source_public_key: 0 Network_Namespace: 1 row in set (0.00 sec) ``` #### 5.注意 Master节点查看binlog ```shell mysql> SHOW BINARY LOG STATUS\G *************************** 1. row *************************** File: mysql-bin.000001 Position: 1030 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 50a9a869-0efa-11f0-8e51-52540047de4e:1-4 1 row in set (0.00 sec) ``` 自8.0.22版本后以下命令不能使用 ```shell start slave; show slave status; start master; chang master to ``` ## 四:组复制 #### 1.MySQL 组复制的背景 ​ 创建容错系统的最常见方法是采用组件冗余,换句话说,可以删除组件,系统应该继续按预期运行,复制数据库必须处理这样一个事实,即它们需要维护和管理多台服务器,而不仅仅是一台;此外,由于服务器协同工作以创建组,因此必须处理其他一些经典的分布式系统问题,例如网络分区或脑裂场景。 ​ 因此,最终的挑战是将数据库和数据复制的逻辑与以一致且简单的方式协调多台服务器的逻辑融合在一起。换句话说,让多台服务器就系统状态和每次更改时每个服务器上的数据达成一致。这可以概括为让服务器就每个数据库状态转换达成一致,以便它们都像一个数据库一样进行,或者它们最终会收敛到相同的状态。这意味着它们需要作为一个(分布式)状态机运行。 ​ MySQL 组复制提供分布式状态机复制,服务器之间具有强大的协调性。当服务器属于同一组时,它们会自动协调。该组可以在具有自动主节点选举的单主模式下运行,其中一次只有一个服务器接受更新。或者,对于更高级的用户,该组可以部署在多主模式下,其中所有服务器都可以接受更新,即使它们是并发发出的。这种能力是以应用程序必须解决此类部署所施加的限制为代价的。 ​ 有一个内置的组成员关系服务,可以在任何给定时间点为所有服务器保持一致且可用的组视图。服务器可以离开和加入组,视图也会相应更新。有时服务器可能会意外离开组,在这种情况下,故障检测机制会检测到这种情况并通知组视图已更改。这一切都是自动的。 ​ 为了提交事务,组中的大多数必须就全局事务序列中给定事务的顺序达成一致。决定提交或中止事务由每个服务器单独完成,但所有服务器都做出相同的决定。如果存在网络分区,导致成员无法达成一致的分裂,则系统在解决此问题之前不会继续进行。因此,还有一个内置的、自动的脑裂保护机制。 ​ 所有这些都由提供的组通信系统 (GCS) 协议提供支持。它们提供故障检测机制、组成员关系服务以及安全且完全有序的消息传递。所有这些特性都是创建系统的关键,该系统可确保数据在服务器组中一致地复制。这项技术的核心是 Paxos 算法的实现。它充当组通信引擎。 总结: ​ 故障检测 ​ 故障转移 ​ 脑裂保护 #### 2.组复制和主从复制关系 ​ MySQL的**组复制(Group Replication)**并不需要建立在传统的**主从复制(Master-Slave Replication)**之上,但它确实利用了主从复制的基础架构来实现 数据同步。 ​ 在组复制中,所有节点都作为对等的主节点,彼此之间通过复制协议同步数据。因此,尽管组复制使用了与主从复制相似的机制,但它是一个独立的、高可用 的集群解决方案,不需要先配置主从复制。 ​ 综上,**组复制不依赖于主从复制的预先配置**,但它们在底层数据同步机制上有相似之处。可以直接部署组复制,而无需先设置主从复制。