作用主从复制在工作中可能会有两种形式传统AB复制基于binlog日志 pos点位实现复制MySQL5.7及以后版本新增基于GTID的主从复制相对于传统AB复制基于GTID的主从复制在两方面比较灵活g:globalT:事务配置灵活不需要关心binlog及点位直接配置自动追踪跳过异常也比较灵活简单操作就可以解决主从复制中的异常信息SQL异常基于全局事务标识符GTID复制GTglobal transaction GTID 服务器ID 事务ID官网https://dev.mysql.com/doc/refman/8.0/en/replication-gtids.html事务标识符每执行一次事务操作增、删、改系统都会给其定义一个唯一编号很长的字符串。GTID一个基于原始MySQL服务器生成的一个已经被成功执行的全局事务ID它由服务器ID以及事务ID组合而成全局事务ID不仅仅在原始服务器上唯一在所有存在主从关系的MySQL服务器上也是唯一的幂等执行同一个 GTID 在单台 MySQL 实例只会被执行一次自动跳过重复事务杜绝主从重复执行造成数据错乱。复制启动方式变更传统复制依靠MASTER_LOG_FILE MASTER_LOG_POS二进制日志文件 位置点启动同步。GTID 复制配置MASTER_AUTO_POSITION1自动获取同步起点无需手动找日志位点。从库必须开启 binlog关键区别普通传统主从从库只开 relay logbinlog 可关闭GTID 主从从库必须开启 binlog用来持久化已经执行完成的 GTID 事务号保证故障切换时事务不会重复执行。Master主库必须开启 binlogSlave从库必须开启 relay log 必须开启 binlog用于保存已执行 GTIDGTID的优势更简单的实现 failover不用以前那样在需要找位点log_file 和 log_pos。更简单的搭建主从复制。比传统的AB复制更加安全。GTID 是连续的没有空洞的保证数据的一致性零丢失。GTID工作原理GTID全局事务ID编号server_uuid 事务序号不管单独MySQL服务器还是主从集群环境中都是唯一的。从库连接主库把本机已经执行完的所有 GTID 集合gtid_executed发送给主库。主库拿到从库的 GTID 集合做集合运算主库全部 GTID − 从库已执行 GTID 待同步事务差集。校验如果主库的 binlog 已经清理掉了差集对应的事务直接报错防止数据缺失。主库自动定位到差集里第一条事务对应的 binlog 起始位置。主库从该事务开始持续把后续 binlog 推送给从库 IO 线程。从库写入 relay logSQL 线程执行事务。关键特性同一个 GTID 只会执行一次自动跳过重复事务保证幂等。举例主库已执行 GTID1~100从库已执行 GTID1~90差集91~100主库自动找到 GTID91 的位置从此处开始推送 binlog。GTID的配置与实现作用基于GTID实现主从复制重点文档https://dev.mysql.com/doc/refman/8.0/en/replication-gtids-howto.html环境说明关闭防火墙SELinux、配置IP与主机映射、时间同步、安装必备包IP主机名角色192.168.88.101mysql-node1master(主)192.168.88.102mysql-node2slave(从)环境准备① 安装必备软件如vim、wget、rsync② 配置IP、主机名③ 配置IP与主机映射 /etc/hosts④ 优化Linux系统⑤ 时间同步主从服务器都要安装一些依赖包dnf install vim wget rsync telnet net-tools -y主从服务器都要设置一下主机名hostnamectl set-hostname mysql-node1 hostnamectl set-hostname mysql-node2主机映射两个服务器都要添加vim /etc/hosts192.168.88.101 mysql-node1 node1 192.168.88.102 mysql-node2 node2优化系统一些防火墙设置sed -i -r s/SELINUX[ep].*/SELINUXdisabled/g /etc/selinux/config setenforce 0 systemctl stop firewalld /dev/null systemctl disable firewalld /dev/null iptables -F iptables -t nat -F iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT时间同步dnf -y install chrony systemctl enable chronyd --now从服务器安装MySQL脚本vim install-mysql8.sh#!/bin/bash if rpm -q libaio /dev/null; then echo libaio已安装跳过安装 else echo 开始安装依赖 dnf -y install libaio /dev/null if [ $? -ne 0 ];then echo libaio安装失败 exit 1 fi fi echo 进行解压操作 if ls -l mysql-8.0.43-linux-glibc2.28-x86_64 /dev/null; then echo 已解压跳过 else if [ -f mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz ]; then tar -xf mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz ls -l mysql-8.0.43-linux-glibc2.28-x86_64 fi fi echo 判断是否安装过MariaDB进行清理 rpm -qa | grep mariadb | xargs -r dnf remove -y if [ -f /etc/my.cnf ]; then rm -rf /etc/my.cnf fi id mysql /dev/null [ $? -ne 0 ] useradd -r -s /sbin/nologin mysql rm -rf /export/server mkdir -p /export/server cp -r mysql-8.0.43-linux-glibc2.28-x86_64 /export/server/mysql chown -R mysql:mysql /export/server/mysql echo 正在进入mysql目录对其进行初始化操作... cd /export/server/mysql bin/mysqld --initialize --usermysql --basedir/export/server/mysql --datadir/export/server/mysql/data 21 | tee /tmp/mysqld.log | grep password | awk {print $NF} /tmp/mysql_temp_password.txt bin/mysql_ssl_rsa_setup --datadir/export/server/mysql/data /dev/null cat /etc/my.cnfEOF [mysqld] port3306 basedir/export/server/mysql datadir/export/server/mysql/data socket/tmp/mysql.sock character_set_serverutf8 collation-serverutf8_unicode_ci EOF cat /etc/systemd/system/mysqld.serviceEOF [Unit] DescriptionMySQL Server Afternetwork.target [Service] Usermysql Groupmysql Typeforking # MySQL 执行命令及路径 ExecStart/export/server/mysql/bin/mysqld --daemonize --pid-file/export/server/mysql/data/mysqld.pid ExecStop/export/server/mysql/bin/mysqladmin --defaults-file/export/server/mysql/my.cnf shutdown # Ensure MySQL has sufficient time to start up TimeoutSec600 # PID 文件路径 PIDFile/export/server/mysql/data/mysqld.pid # Enable these options to auto-restart the service if it crashes Restarton-failure RestartSec5 [Install] WantedBymulti-user.target EOF echo 正在刷新后台服务然后启动mysqld... systemctl daemon-reload systemctl start mysqld systemctl enable mysqld #10.重置mysql管理员密码为123456 echo 正在重置mysql管理员密码... cd /export/server/mysql temp_passwordcat /tmp/mysql_temp_password.txt bin/mysqladmin -uroot password 123456 -p$temp_password echo export PATH$PATH:/export/server/mysql/bin /etc/profile source /etc/profile mysql -V echo MySQL8安装成功安装路径/export/server/mysql数据库初始密码123456注意执行完install-mysql8.sh安装脚本后需要在Linux命令行执行source /etc/profile初始化数据库强烈建议建议把从服务器的data删除然后重新同步如果/etc/my.cnf有传统主从的配置那么就要先删除对应的配置。初始化数据库systemctl stop mysqld rm -rf /export/server/mysql/data/* rm -rf /tmp/mysqld.log /export/server/mysql/bin/mysqld --initialize --usermysql --basedir/export/server/mysql /tmp/mysqld.log grep password /tmp/mysqld.log | awk {print $NF} mysqld --usermysql --skip-grant-tables --skip-networking mysql FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY 123456; FLUSH PRIVILEGES; EXIT; pkill mysqld systemctl start mysqld systemctl status mysqld --no-pager mysql -uroot -p123456rsync 同步 data 目录与删除 auto.cnf 文件同步# 1、停止 master服务器 上的 MySQL 服务可选 systemctl stop mysqld # 2、在 master 上执行 rsync 同步 data 目录可选 rsync -av --delete /export/server/mysql/data/ mysql-node2:/export/server/mysql/data/ # 3、在 master 或 slave 删除 auto.cnf 文件 rm -f /export/server/mysql/data/auto.cnf修改配置文件/etc/my.cnf修改mastercat /etc/my.cnfEOF [mysqld] # 基础路径 basedir/export/server/mysql datadir/export/server/mysql/data socket/tmp/mysql.sock port3306 # 日志 log-error/export/server/mysql/master.err log-bin/export/server/mysql/data/binlog server-id101 # 字符集 character_set_serverutf8mb4 collation-serverutf8mb4_unicode_ci # GTID 配置 gtid_modeON enforce_gtid_consistencyON log_slave_updatesON binlog_formatROW binlog_row_imageFULL sync_binlog1 expire_logs_days7 # 复制过滤不同步的系统库 binlog-ignore-dbinformation_schema binlog-ignore-dbmysql binlog-ignore-dbperformance_schema binlog-ignore-dbsys # InnoDB 优化 default_storage_engineInnoDB innodb_buffer_pool_size1G innodb_log_file_size256M innodb_log_buffer_size64M innodb_flush_log_at_trx_commit1 innodb_file_per_table1 # 连接配置 max_connections500 max_connect_errors1000000 table_open_cache2000 # 慢查询日志 slow_query_log1 slow_query_log_file/export/server/mysql/slow.log long_query_time1 [client] socket/tmp/mysql.sock EOF修改slavecat /etc/my.cnfEOF [mysqld] # 基础路径 basedir/export/server/mysql datadir/export/server/mysql/data socket/tmp/mysql.sock port3306 # 日志 log-error/export/server/mysql/slave.err log-bin/export/server/mysql/data/binlog relay-log/export/server/mysql/data/relaylog relay-log-index/export/server/mysql/data/relaylog.index server-id102 # 字符集 character_set_serverutf8mb4 collation-serverutf8mb4_unicode_ci # GTID 配置 gtid_modeON enforce_gtid_consistencyON log_slave_updatesON binlog_formatROW binlog_row_imageFULL sync_binlog1 expire_logs_days7 # 复制过滤不同步的系统库 replicate-wild-ignore-tablemysql.% replicate-wild-ignore-tableinformation_schema.% replicate-wild-ignore-tableperformance_schema.% replicate-wild-ignore-tablesys.% # 从库只读 read_onlyON super_read_onlyON skip-slave-start1 # 避免重启时自动启动复制线程需手动控制 # 复制优化 relay_log_recovery1 sync_relay_log0 sync_relay_log_info0 sync_master_info0 # InnoDB 优化适合从库查询压力大 default_storage_engineInnoDB innodb_buffer_pool_size1G innodb_log_file_size256M innodb_log_buffer_size64M innodb_flush_log_at_trx_commit2 # 从库可设置为 2提高复制与查询性能 innodb_file_per_table1 # 连接配置 max_connections500 max_connect_errors1000000 table_open_cache2000 # 慢查询日志从库常用于报表分析 slow_query_log1 slow_query_log_file/export/server/mysql/slow.log long_query_time1 [client] socket/tmp/mysql.sock EOF上面的从库只读等于SET GLOBAL.read_only ON;锁表也差不多flush tables with read lock;unlock tablesmaster节点/slave节点优化配置重启MySQL# master 主服务器 touch /export/server/mysql/master.err chown -Rf mysql:mysql /export/server/mysql systemctl restart mysqld systemctl status mysqld --no-pager # slave 从服务器 touch /export/server/mysql/slave.err chown -Rf mysql:mysql /export/server/mysql systemctl restart mysqld systemctl status mysqld --no-pager创建账号主服务器创建账号CREATE USER slave% IDENTIFIED WITH mysql_native_password BY 123456; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO slave%; flush privileges;启动同步从库执行操作需要调整为自己master服务器信息CHANGE REPLICATION SOURCE TO SOURCE_HOST host, SOURCE_PORT port, SOURCE_USER user, SOURCE_PASSWORD password, SOURCE_AUTO_POSITION 1;SOURCE_AUTO_POSITION 1 这告诉从服务器使用自动位置跟踪功能以便它可以自动从主服务器获取最新的二进制日志事件而无需手动指定位置。开启从库复制start replica;查看从库复制状态show slave status\G测试主从复制结果主库中加入数据create database if not exists db_itheima; show databases; use db_itheima; create table if not exists students( id int primary key, name varchar(20) ) default charsetutf8; insert into students values (10, lisa); insert into students values (11, Rose); select * from students; show databases;在从库查看数据show databases; use db_itheima; show tables; select * from students;从库中查看复制状态这张表记录了本机已经执行过的所有 GTID 事务区间select * from mysql.gtid_executed;