mysql5.7.26 基于GTID的主从复制环境搭建
简单工作原理:
(1)从库执行 change master to 语句,会立即将主库信息记录到master.info中
(2)从库执行 start slave语句,会立即生成IO_T和SQL_T
(3)IO_T 读取master.info文件,获取到主库信息
(4)IO_T 连接主库,主库会立即分配一个DUMP_T,进行交互
(5)IO_T 根据master.info binlog信息,向DUMP_T请求最新的binlog
(6)主库DUMP_T,经过查询,如果发现有新的,截取并反回给从库IO_T
(7)从库IO_T会收到binlog,存储在TCP/IP缓存中,在网络底层返回ACK
(8)从库IO_T会更新master.info ,重置binlog位置点信息
(9)从库IO_T会将binlog,写入到relay-log中
(10)从库SQL_T 读取Relay-log.info 文件,获取上次执行过的位置点
(11)SQL_T按照位置点往下执行relaylog日志
(12)SQL_T执行完成后,重新更新relay-log.info
(13)relaylog定期自动清理的功能。
线程:
主库:
binlog_dump_thread 二进制日志投递线程
mysql -S /data/3307/mysql.sock -e "show processlist"
从库:
IO_Thread : 从库IO线程 : 请求和接收binlog
SQL_Thread: 从库的SQL线程 : 回放日志
主从环境的基本准备
1. mysql主从服务器说明
192.168.1.219 mysql主服务器
192.168.1.17 mysql从服务器
192.168.1.151 mysql从服务器
#中间配置IP和网络及防火墙设置省略
2. 安装mysql
2.1 yum安装所需相关依赖包。
yum -y install gcc-c++
yum -y install zlib zlib-devel pcre pcre-devel
yum -y install openssl-devel
yum -y install libaio-devel.x86_64
2.2搜索关键字:MySQL5.7 linux二进制安装
参考网址:https://www.cnblogs.com/chenmh/p/5413881.htmlMySQL5.7 linux二进制安装
下载路径:
https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
2.2.1#创建mysql的数据目录,该目录在初始化数据库的候会用到
mkdir -p /data/mysql/data
mkdir -p /data/mysql/log
2.2.2#移动mysql文件到/data/mysql/mysql
tar -zxvf mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
cd /usr/local/
ln -s mysql-5.7.26-linux-glibc2.12-x86_64 mysql ## 软连接
2.2.3 #先创建mysql组
groupadd mysql
2.2.4#将MySQL用户加入mysql组
useradd -r -g mysql -s /bin/false mysql
2.2.5#修改目录权限
chown -R mysql:mysql /data/mysql/
chmod 750 /data/mysql
2.2.6#配置my.cnf
ls -l /etc/my.cnf
rpm -e mariadb-libs --nodeps
vim /etc/my.cnf #创建my.cnf文件要命名为my.cnf,另外删除/etc/下的所有my.*文件
=====================================================
/etc/my.cnf配置修改如下配置
主库配置
[root@mysqltest01 ~]# cat /etc/my.cnf
[client]
port = 3306
socket = /data/mysql/mysql.sock
[mysqld]
port = 3306
user = mysql
character-set-server = utf8mb4
default_storage_engine = innodb
log_timestamps = SYSTEM
socket = /data/mysql/mysql.sock
basedir =/usr/local/mysql
datadir = /data/mysql/data
pid-file = /data/mysql/mysql.pid
max_connections = 1000
max_connect_errors = 1000
table_open_cache = 1024
max_allowed_packet = 128M
open_files_limit = 65535
server-id=1
gtid_mode=on
enforce_gtid_consistency=on
log-slave-updates=1
log-bin=master-bin
log-bin-index = master-bin.index
relay-log = relay-log
relay-log-index = relay-log.index
binlog_format=row
log_error = /data/mysql/log/mysql-error.log
skip-name-resolve
log-slave-updates=1
relay_log_purge = 0
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /data/mysql/log/mysql-slow.log
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
==========================================
从库1配置:
[client]
port = 3306
socket = /data/mysql/mysql.sock
[mysqld]
port = 3306
user = mysql
character-set-server = utf8mb4
default_storage_engine = innodb
log_timestamps = SYSTEM
socket = /data/mysql/mysql.sock
basedir =/usr/local/mysql
datadir = /data/mysql/data
pid-file = /data/mysql/mysql.pid
max_connections = 1000
max_connect_errors = 1000
table_open_cache = 1024
max_allowed_packet = 128M
open_files_limit = 65535
server-id=2
gtid_mode=on
enforce_gtid_consistency=on
log-slave-updates=1
log-bin=master-bin
log-bin-index = master-bin.index
relay-log = relay-log
relay-log-index = relay-log.index
binlog_format=row
log_error = /data/mysql/log/mysql-error.log
skip-name-resolve
log-slave-updates=1
relay_log_purge = 0
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /data/mysql/log/mysql-slow.log
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
=========================================
从库2配置:
[client]
port = 3306
socket = /data/mysql/mysql.sock
[mysqld]
port = 3306
user = mysql
character-set-server = utf8mb4
default_storage_engine = innodb
log_timestamps = SYSTEM
socket = /data/mysql/mysql.sock
basedir =/usr/local/mysql
datadir = /data/mysql/data
pid-file = /data/mysql/mysql.pid
max_connections = 1000
max_connect_errors = 1000
table_open_cache = 1024
max_allowed_packet = 128M
open_files_limit = 65535
server-id=3
gtid_mode=on
enforce_gtid_consistency=on
log-slave-updates=1
log-bin=master-bin
log-bin-index = master-bin.index
relay-log = relay-log
relay-log-index = relay-log.index
binlog_format=row
log_error = /data/mysql/log/mysql-error.log
skip-name-resolve
log-slave-updates=1
relay_log_purge = 0
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /data/mysql/log/mysql-slow.log
============================================
2.2.7#初始化数据库
/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize --user=mysql --basedir=/data/mysql/mysql --datadir=/data/mysql/data --innodb_undo_tablespaces=3 --explicit_defaults_for_timestamp #初始化mysql
2.2.7#根据配置了my.cnf的error.log,查看初始密码
grep 'password' /data/mysql/log/mysql-error.log
2.2.8#创建ssl加密
/usr/local/mysql/bin/mysql_ssl_rsa_setup --datadir=/data/mysql/data
2.2.9#将里面的basedir和datadir改为和my.cnf一致
vi /usr/local/mysql/support-files/mysql.server
basedir=/usr/local/mysql
datadir=/data/mysql/data
2.2.10#拷贝和配置启动文件
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
2.2.11设置开机启动
chkconfig --add mysqld
chkconfig mysqld on
2.2.12配置环境变量
echo 'PATH=/usr/local/mysql/bin:$PATH'>>/etc/profile
tail -1 /etc/profile
source /etc/profile #让环境变量生效
echo $PATH #检查变量是否添加成功
##/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
2.2.13#启动mysql
service mysqld start
2.2.14#进入mysql
mysql -uroot -p #密码通过前面的2.2.7找到
2.2.15#修改初始密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
2.2.16#刷新权限
flush privileges;
2.2.17#查看路径信息
SHOW GLOBAL VARIABLES LIKE '%log%';
2.2.18日志查询
1.查找错误日志文件路径
show variables like 'log_error';
2.查找日志文件路径
show variables like 'general_log_file';
3.慢查询日志文件路径
show variables like 'slow_query_log_file';
2.2.19加入开机启动项
vim /usr/lib/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000
chmod +x /usr/lib/systemd/system/mysqld.service ##给予执行权限
systemctl daemon-reload ###重新加载
systemctl enable mysqld.service
systemctl start mysqld.service
============================================
GTID主从复制:
配置步骤:
1.检查gtid是否运行正常
启动后可以使用show global variables like '%gtid%';查看GTID状态
gtid_mode | ON
enforce_gtid_consistency | ON
注:主库从库都需要开启GTID否则在做主从复制的时候就会报错:
查看数据库的uuid
在数据目录的auto.cnf
在mysql里面使用命令查看show global variables like 'server_uuid'
2.登录主库给从库复制权限
grant replication slave on *.* to 'replication'@'192.168.1.%' identified by '1234';
flush privileges;
select host,user from mysql.user;
3.登录从库使用命令进行复制
change master to
master_host='192.168.1.219',
master_port=3306,
master_user='replication', ###用户名和密码要与在主库上建立的一致
master_password='1234',
master_auto_position = 1; ##此参数可以一直不变化
start slave; ##启动同步
show slave status\G; ##查看同步状态
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
这两个参数必须为yes否则同步没有成功
4.主从的binlog日志观察
show binlog events in 'master-bin.000001';
5.测试同步
增加数据来验证是否同步成功
create database shijiange;
use shijiange;
create table test (id int);
insert into test values (1);
update test set id = 3 where id = 1;
delete from test;
drop database shijiange;
主库的信息(master.info):
Master_Host: 10.0.0.51 主库的IP
Master_User: repl 复制用户名
Master_Port: 3307 主库的端口
Connect_Retry: 10 断连之后重试次数
Master_Log_File: mysql-bin.000001 已经获取得到binlog的文件名
Read_Master_Log_Pos: 444 已经获取得到binlog的位置号
从库的relaylog的信息(relay-log.info):
Relay_Log_File: db01-relay-bin.000002 从库已经运行过的relaylog的文件名
Relay_Log_Pos: 320 从库已经运行过的relaylog的位置点
从库复制线程工作状态:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
过滤复制相关的状态:
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
从库延时主库的时间:
Seconds_Behind_Master: 0 从库延时主库的时间(秒为单位)
从库线程报错详细信息:
Last_IO_Errno: 0 IO报错的号码
Last_IO_Error: IO报错的具体信息
Last_SQL_Errno: 0 SQL报错的号码
Last_SQL_Error: SQL线程报错的具体原因
延时从库:
SQL_Delay: 0 延时从库设定的时间
SQL_Remaining_Delay: NULL 延时操作剩余时间
GTID复制信息:
Retrieved_Gtid_Set: 接收到的GTID的个数
Executed_Gtid_Set: 执行了的GTID的个数
SQL线程故障
原因一:
读relay-log.info
读relay-log ,并执行日志
更新relay-log.info
以上文件损坏,最好是重新构建主从
原因二:
为什么一条SQL语句执行不成功?
1. 主从数据库版本差异较大
2. 主从数据库配置参数不一致(例如:sql_mode等)
3. 想要创建的对象已经存在
4. 想要删除或修改的对象不存在
5. 主键冲突
6. DML语句不符合表定义及约束时
归根结底是从库写入了。
IO线程No的状态分析:
原因一: 日志名不对
从库信息:
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 444
对比备份的位置号。
原因二:日志损坏,日志不连续