主从复制(也称 AB 复制)允许将来自一个MySQL数据库服务器(主服务器)的数据复制到一个或多个MySQL数据库服务器(从服务器)。
根据配置,您可以复制数据库中的所有数据库,所选数据库甚至选定的表。
MySQL中复制的优点包括:
前提是作为主服务器角色的数据库服务器必须开启二进制日志
每个从服务器都会收到主服务器二进制日志的全部内容的副本。
从服务器设备负责决定应该执行二进制日志中的哪些语句。
除非另行指定,否则主从二进制日志中的所有事件都在从站上执行。
如果需要,您可以将从服务器配置为仅处理一些特定数据库或表的事件。
重要: 您无法将主服务器配置为仅记录特定事件。
每个从站(从服务器)都会记录二进制日志坐标:
由于每个从服务器都分别记录了自己当前处理二进制日志中的位置,因此可以断开从服务器的连接,重新连接然后恢复继续处理。
如果一主多从的话,这时主库既要负责写又要负责为几个从库提供二进制日志。此时可以稍做调整,将二进制日志只给某一从,这一从再开启二进制日志并将自己的二进制日志再发给其它从。或者是干脆这个从不记录只负责将二进制日志转发给其它从,这样架构起来性能可能要好得多,而且数据之间的延时应该也稍微要好一些。工作原理图如下:
首先需要创建MySQL多实例,这里我创建的是一主一从,如果需要多从,上面写有思路。
1、复制第一个安装的MySQL Server,直接整个文件夹复制,如下图。
在别的路径下粘贴之后,记得删除data文件夹,否则新的MySQL实例的配置文件会一直找第一个MySQL服务,然后新的MySQL实例的服务就会一直无法启动!我的主库为MySQL2,从库为MySQL3。因为我不想操作我第一个安装的MySQL服务。如下图:
2、修改配置文件my.ini:两个端口、两个dir路径、server-id和主库的二进制日志位置
关于server-id:
①mysql的同步的数据中是包含server-id的,用于标识该语句最初是从哪个server写入的,所以server-id一定不同
② 每一个同步中的slave在master上都对应一个master线程,该线程就是通过slave的server-id来标识的;每个slave在master端最多有一个master线程,如果两个slave的server-id 相同,则后一个连接成功时,前一个将被踢掉。 这里至少有这么一种考虑:
slave主动连接master之后,如果slave上面执行了slave stop;则连接断开,但是master上对应的线程并没有退出;当slave start之后,master不能再创建一个线程而保留原来的线程,那样同步就可能有问题;
③ 在mysql做主主同步时,多个主需要构成一个环状,但是同步的时候有要保证一条数据不会陷入死循环,这里就是靠server-id来实现的
[client]
port=3307
[mysql]
no-beep
default-character-set=utf8
# server_type=3
[mysqld]
# The TCP/IP Port the MySQL Server will listen on
port=3307
# 设置mysql的安装目录
basedir="C:/MySQL2"
# 设置mysql数据库的数据的存放目录,这个data目录如果不存在,需要自己手动在创建
datadir="C:/MySQL2/data/"
# Server Id.
server-id=2
#主库二进制日志的位置
log-bin=C:/MySQL2/mysql-bin.log
3、初始化:打开CMD窗口,跳转到MySQL2/bin路径下,执行命令初始化MySQL,这里初始化成功,就会自动生成data文件夹,而且CMD也会显示一个随机生成的MySQL密码,这里可以记住它,也可以在MySQL2/data/xxx.err这个err文件中查看。MySQL5.7以前的版本在安装时不需要执行这个初始化命令也可以。
mysqld --initialize --user=mysql --console
4、安装mysql:指定服务的名称MySQL2和配置文件my.ini的路径
mysqld install MySQL2 --defaults-file="C:\MySQL2\my.ini"
5、修改服务:win+r 输入regedit命令打开注册表,找到HKEY_LOCAL_MACHINE -> SYSTEM -> CurrentControlSet -> services -> MySQL2,可以看到imagePath参数值
"C:\MySQL Server 5.7\bin\mysqld" --defaults-file=C:\MySQL2\my.ini MySQL2
第一个mysqld的位置需要修改成你的新MySQL2服务的mysqld位置,如下
"C:\MySQL2\bin\mysqld" --defaults-file=C:\MySQL2\my.ini MySQL2
这里如果不修改,你的新MySQL服务也会一直无法启动!打开data文件夹下的xxx-slow.log文件
可以看到执行的还是原来的MySQL的mysqld这个配置文件
6、启动主库服务:
net start MySQL2
这时候如果启动MySQL服务失败,请先删除已安装的MySQL2服务:sc delete MySQL2(服务名称)。然后再看看上面的步骤,是哪一个配置没有按照步骤来修改。启动成功,就算是生成MySQL多实例了。这时候包括原来的MySQL Server服务,已经有两个了,端口号分别为3306、3307。然后我们就需要修改密码,这时候MySQL2的密码有3种可能:
1、密码丢失:使用工具连接mysql服务的时候账号名是root,密码就不用填。如果要新密码就先登录mysql,然后执行命令
set password=password(“新密码”);
update user set password=password('你的新密码') where user='root' and host='localhost';
MySQL5.7版本以后:输入
update mysql.user set authentication_string=PASSWORD("你的新密码") where user="root" and host="localhost";
因为MySQL新版本用于存用户密码的字段名为authentication_string而不是 password,且新密码必须使用PASSWORD("xxxx")函数进行加密。以上所有请在管理员模式下执行
7、配置从库,记为MySQL3,它的my.ini配置如下:
[client]
port=3308
[mysql]
no-beep
default-character-set=utf8
# server_type=3
[mysqld]
# The TCP/IP Port the MySQL Server will listen on
port=3308
# 设置mysql的安装目录
basedir="C:/MySQL3"
# 设置mysql数据库的数据的存放目录,这个data目录如果不存在,需要自己手动在创建
datadir="C:/MySQL3/data/"
# Server Id.
server-id=2
#从库不需要这个配置文件
#log-bin=C:/MySQL2/mysql-bin.log
然后其他安装步骤跟主库一样。
8、连接MySQL主从库:通过Navicat Premium等工具连接了MySQL2、MySQL3,3307端口的记为3307master,3308的记为3308slave,test是我用来测试主从复制功能是否正常的测试数据库。如下图:
要想主从复制,就要数据库同构,即主从数据库3307master、3308slave所有的数据库名称一致。如果你发现从库中不包含主库同名数据库,这时候就直接新建同名数据库就可以了。
关于在主库中配置binlog-do-db=dbname(要同步的数据库名字) :我并没有在主库的my.ini中配置这一项,只是手动在主从库创建了相同的数据库(即我要让它主从复制的数据库),然后MySQL也可以正确执行主从复制,它默认应该是从库全部复制(未验证)
9、设置主库:3307master主库中test数据库(第8步创建的测试库),新建查询,完成对从库的授权功能,SQL语句如下
#REPLICATION复制的权限 给 localhost(IP),@左边的是用户名,右边是密码
GRANT REPLICATION SLAVE ON *.* TO 'root'@'localhost' IDENTIFIED BY 'root'
查看主库的状态
show MASTER STATUS
10、设置从库:3308slave从库中test数据库(第8步说了这个是测试库),新建查询,完成对主库的跟从功能,SQL语句如下
配置主库的相关信息,log_file和log_pos是show master status(第9步图中标有)显示出来的
CHANGE MASTER TO
master_host='localhost',master_port=3307,master_user='root',master_password='root',
master_log_file='mysql-bin.000004',master_log_pos=5475
启动从库:
start slave
查看从库的状态
show slave status
主要看几点:slave_sql_running是否YES,slave_io_running是否YES,log_file、log_pos、master_port是否和主库对应
11、查看主库3307master目前拥有的从库
show slave hosts;
主要看显示出来的数据是否和从库对应
12、如果这时候全部正常,那说明主从复制成功了
但是,因为每个人机器环境不一样,可能主从复制仍然失败。即主库新建表更新数据之后,从库没有实时跟着更新数据。经测试,等待几分钟,从库有概率跟着更新部分数据,具体我也不知道为什么。
解决办法:电脑重启。讲道理只要重启MySQL2、MySQL3服务(主从服务)就可以了。可是经过测试,我重启电脑才解决问题。
13、切记不要在从库进行写操作,会导致slave_sql_running变成了NO,主从复制失败。原因:主库的postion变了,从库没有跟着变
解决办法:
(1)、3308slave执行以下命令
slave stop;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
slave start;
通过show slave status命令发现,slave_sql_Runing=NO,还是没有解决,这时候就需要重新连接配置从服务。
(2)、重新配置:
3308slave从库中执行:stop slave;
3307master主库中执行:show MASTER STATUS,记录postion和log-file
最后3308slave从库中执行:
CHANGE MASTER TO
master_host='localhost',master_port=3307,master_user='root',master_password='root',
master_log_file='主库的文件名',master_log_pos=主库显示的数字
再次通过show slave status;命令发现,slave_sql_Runing=YES,这时候主从复制应该成功了,但还是有概率失败,这时候请看第三步
(3)、再次配置:第一次主从复制,需要主从库达到同构状态(即所拥有的数据库和数据都一样),所以先stop slave;然后手动同步主库数据到从库。再次执行配置2,即可成功。
建议:在确保主从复制成功之后,断开从库数据库连接,这样子就不会不小心操作到了,而且从库也会自动更新数据。