MySQL主从又叫做Replication、AB复制。 简单讲就是A和B两台机器做主从后,在A上写数据,另外一台B也会跟着写数据,两者数据实时同步的 MySQL主从是基于binlog的,主上须开启binlog才能进行主从。 binlog就是记录的MySQL的写入操作,主要就是创建,插入,修改,删除等等操作 binlog文件是一个二进制文件,无法直接cat查看。 主从过程大致有3个步骤 1)主将更改操作记录到binlog里 2)从将主的binlog事件(sql语句)同步到从本机上并记录在relaylog里,relaylog又称为中继日志 3)从根据relaylog里面的sql语句按顺序执行 主上有一个log dump线程,用来和从的I/O线程传递binlog 从上有两个线程,其中I/O线程用来同步主的binlog并生成relaylog,另外一个SQL线程用来把relaylog里面的sql语句落地
实验环境说明:
需要准备两台虚拟机,分别都装上MySQL并且能正常运行 注意:克隆的虚拟机需要将网卡配置文件中的UUID删除掉,否则会有冲突 此次实验的环境是两台CentOS7.4系统的虚拟机 主服务器: 是之前做LNMP实验时的系统,里面已经装好了MySQL,并且MySQL也有几个库了 主机名:修改为mysql-master IP:10.1.1.28 MySQL版本:5.6.35 从服务器 最小化安装的CentOS7.4系统,全新使用二进制包安装的MySQL服务 主机名:mysql-slave IP:10.1.1.30 MySQL版本:5.6.35
1:修改/etc/my.cnf配置文件
# 在/etc/my.cnf文件内容中添加下面两行配置 server-id=1028 log_bin=abcopy
2:修改完配置文件后,启动或者重启mysqld服务
[root@mysql-master ~]> /etc/init.d/mysqld restart Shutting down MySQL.... SUCCESS! Starting MySQL. SUCCESS! # 重启后查看 datadir 目录下的文件 [root@mysql-master ~]> ls /data/mysql/ abcopy.000001 auto.cnf ib_logfile0 mysql performance_schema server-lnmp.pid abcopy.index ibdata1 ib_logfile1 mysql-master.pid server-lnmp.err zrlog # 其中 abcopy.000001 和 abcopy.index 两个文件是主从配置的关键文件 # 与abcopy.000001类似的文件后面会出现很多个,000002 000003等等。
3:备份mysql库,然后恢复为 testbase 库,用于后面的测试
# 创建备份文件存放目录 [root@mysql-master ~]> mkdir /mysqlbak # 备份mysql库 # 注意如果没有将 mysql/bin 目录加入PATH # 那么mysql命令和mysqldump命令需要使用绝对路径,或者定义一个alias [root@mysql-master ~]> mysqldump -uroot -p123456 mysql > /mysqlbak/mysql.sql # 创建一个新的库 testbase [root@mysql-master ~]> mysql -uroot -p123456 -e "create database testbase" # 将刚才备份的mysql库的文件恢复到testbase库 [root@mysql-master ~]> mysql -uroot -p123456 testbase < /mysqlbak/mysql.sql
4:创建用于同步数据的用户
# 这个用户只需要两个权限,replication 和 slave,但是需要针对所有库 [root@mysql-master ~]> mysql -uroot -p123456 mysql> grant replication slave on *.* to 'repl'@'10.1.1.30' identified by '123456'
5:锁表,备份所有需要同步的库
# 锁表是为了让数据库暂停到这一刻,只能读,不能写 # 然后进行备份,等会将备份的数据都恢复到从服务器里面 # 这样是为了让主服务器与从服务器之间的数据相同 # 锁表 [root@mysql-master ~]> mysql -uroot -p123456 -e 'flush tables with read lock' # 备份需要同步的库 # 注:mysql库是存放mysql用户数据和权限的,一般都不用同步,所以也不需要备份 # 所以这里只需要备份两个库: testbase zrlog [root@mysql-master ~]> mysqldump -uroot -p123456 -B testbase zrlog > /mysqlbak/base_bak.sql
6:查看主服务器的状态
[root@mysql-master ~]> mysql -uroot -p123456 -e 'show master status' +---------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+----------+--------------+------------------+-------------------+ | abcopy.000001 | 661858 | | | | +---------------+----------+--------------+------------------+-------------------+ # 这里需要记住两个地方,等会从服务器上会用到 # File: abcopy.000001 # Position:661858
到此主服务器已经配置完成了
1:修改/etc/my.cnf 文件
# 在 /etc/my.cnf文件内容中添加下面的这一行配置就OK了, server-id=1030 # 注:server-id 不能和主服务器相同
2:修改完后重启mysql服务
[root@mysql-slave ~]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS!
3:将主服务器备份数据库的文件拷贝到从服务器上
# 这里可以用scp命令,或者FTP等工具来拷贝文件 [root@mysql-slave ~]# scp 10.1.1.28:/mysqlbak/base_bak.sql ./ root@10.1.1.28's password: #这里输入源主机的密码 base_bak.sql 100% 681KB 81.7MB/s 00:00
4:创建对应的数据库,恢复数据
# 这边需要创建两个库,testbase 和 zrlog ,从服务器还没有设置 mysql 的 root 密码 [root@mysql-slave ~]# mysql -uroot -e 'create database testbase' [root@mysql-slave ~]# mysql -uroot -e 'create database zrlog' #恢复数据 [root@mysql-slave ~]# mysql -uroot < ./base_bak.sql #检查数据是否恢复成功 [root@mysql-slave ~]# mysql -uroot -e 'select count(*) from testbase.user' +----------+ | count(*) | +----------+ | 10 | +----------+ # 有数据,说明已经恢复成功了
5:配置从服务器参数
# 参看 Slave_IO_Running 和 Slave_SQL_Running 两个状态是否为 Yes [root@mysql-slave ~]# mysql -uroot -e 'show slave status\G' | grep Running Slave_IO_Running: Yes Slave_SQL_Running: Yes # 注:如果Slave_IO_Running为 Connecting # 需要检查主服务器防火墙是否放行msyql的端口 # 或者查看slave参数的ip、user、password等参数是否定义正确 # 还需关注 # Seconds_Behind_Master: 0 # 为主从延迟的时间 # Last_IO_Errno: 0 # IO线程错误代码 # Last_IO_Error: # IO线程错误信息 # Last_SQL_Errno: 0 # SQL线程错误代码 # Last_SQL_Error: # SQL线程错误信息
# 先查看主服务器和从服务器的库是否相同 ##主服务器的库 [root@mysql-master ~]> mysql -uroot -p123456 -e 'show databases' +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | testbase | | zrlog | +--------------------+ ##从服务器的库,与主服务器相同 [root@mysql-slave ~]# mysql -uroot -e 'show databases' +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | testbase | | zrlog | +--------------------+ # 在主服务器上创建一个库 test001 [root@mysql-master ~]> mysql -uroot -p123456 -e 'create database test001' [root@mysql-master ~]> mysql -uroot -p123456 -e 'show databases' +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test001 | #此库就是刚创建的 | testbase | | zrlog | +--------------------+ #查看从服务器是否自动创建这个库 [root@mysql-slave ~]# mysql -uroot -e 'show databases' +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test001 | #自动创建的 | testbase | | zrlog | +--------------------+ # 再删除主服务器的testbase库 [root@mysql-master ~]> mysql -uroot -p123456 -e 'drop database testbase' # 查看从服务器是否还有testbase库 [root@mysql-slave ~]# mysql -uroot -e 'show databases' +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test001 | | zrlog | +--------------------+ # 从服务器上的testbase也自动删除了。
千万不要在从服务器上做任何有关写入的操作,
在从服务器做写入操作会导致主从数据不一致,严重的需要重新做主从