MySQL 的主从复制又叫 Replication、AB 复制。至少需要两个 MySQL 服务(可以是同一台机器,也可以是不同机器之间进行)。
比如A服务器做主服务器,B服务器做从服务器,在A服务器上进行数据的更新,通过 binlog 日志记录同步到B服务器上,并重新执行同步过来的 binlog 数据,从而达到两台服务器数据一致。
MySQL 数据库的主从复制方案,与使用 scp/rsync 等命令进行的文件级别复制类似,都是数据的远程传输。只不过 MySQL 的主从复制是其自带的功能,无需借助第三方工具,而且MySQL的主从复制并不是数据库磁盘上的文件直接拷贝,而是通过逻辑的 binlog 日志复制到要同步的服务器本地,然后由本地的线程读取日志里面的 SQL 语句,重新应用到 MySQL 数据库中。
可以实时灾备,用于故障切换;
读写分离,提供查询服务,实现负载均衡;
数据热备,避免影响业务
主节点:
从节点:
测试环境
序号 | 节点类型 | 节点名称 | IP地址 |
---|---|---|---|
1 | 主节点 | CentOS01 | 192.168.67.140 |
2 | 从节点 | CentOS02 | 192.168.67.130 |
有很多种配置主从同步的方法,可以总结为如下的步骤:
1.在主服务器上,必须开启二进制日志机制和配置一个独立的ID
2.在每一个从服务器上,配置一个唯一的ID,创建一个用来专门复制主服务器数据的账号
3.在开始复制进程前,在主服务器上记录二进制文件的位置信息
4.如果在开始复制之前,数据库中已经有数据,就必须先创建一个数据快照(可以使用mysqldump导出数据库,或者直接复制数据文件)
5.配置从服务器要连接的主服务器的IP地址和登陆授权,二进制日志文件名和位置
编辑主节点的配置文件
进入MySQL数据库的配置文件my.cnf,添加如下信息
主服务器:
[mysqld]
port = 3306
server-id = 1
#要同步的数据库
binlog-do-db = cloudDB01
#要生成二进制日志文件 主服务器一定要开启
log-bin = mysql-bin
重启MySQL
创建用户,每一个从服务器都需要用到一个账户名和密码来连接主服务器,可以为每一个从服务器都创建一个账户,也可以让全部服务器使用同一个账户。下面就为同一个ip网段的所有从服务器创建一个只能进行主从同步的账户。
首先登陆mysql,然后创建一个用户名为htzw2020,密码为123456的账户,该账户可以被192.168.67网段下的所有ip地址使用,且该账户只能进行主从同步
#创建用户,并设置用户权限
mysql > grant replication slave on *.* to ‘htzw2020’@‘192.168.67.%’ identified by ‘123456’;
#刷新权限
mysql> flush privileges;
首先登陆数据库,然后刷新所有的表,同时给数据库加上一把锁,阻止对数据库进行任何的写操作
mysql > flush tables with read lock;
然后执行下面的语句获取二进制日志的信息
mysql > show master status;
File的值是当前使用的二进制日志的文件名,Position是该日志里面的位置信息(不需要纠结这个究竟代表什么),记住这两个值,会在下面配置从服务器时用到。
注意:如果之前的服务器并没有配置使用二进制日志,那么使用上面的sql语句会显示空,在锁表之后,再导出数据库里的数据(如果数据库里没有数据,可以忽略这一步)
[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases > /server/backup/mysql_bak.sql
如果数据量很大,可以在导出时就压缩为原来的大概三分之一
[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases | gzip > /server/backup/mysql_bak.sql.gz
这时可以对数据库解锁,恢复对主数据库的操作
mysql > unlock tables;
首先检查从服务器上的my.cnf文件中是否已经在[mysqld]模块下配置了server-id。注意上面的server-id的值都是可以改为其他值的(建议更改为ip地址的最后一个字段),如果没有上面的配置,首先关闭mysql服务器,然后添加上去,接着重启服务器
从服务器:
[mysqld]
port = 3306
server-id = 2
#要同步的数据库
binlog-do-db = cloudDB01
#要生成二进制日志文件(从服务器可选)
log-bin = mysql-bin
重启MySQL
如果有多个从服务器上,那么每个服务器上配置的server-id都必须不一致。从服务器上没必要配置log-bin,当然也可以配置log-bin选项,因为可以在从服务器上进行数据备份和灾难恢复,或者某一天让这个从服务器变成一个主服务器
如果主服务器导出了数据,下面就导入该文件,如果从主服务器上拿过来的是压缩文件,就先解压再导入。如果主服务器没有数据,就忽略这一步
[root@localhost ~]# mysql -uroot -p'123456' -S /data/3306/data/mysql.sock < /server/backup/mysql_bak.2020-07-01.sql
配置同步参数,登录mysql,输入如下命令
mysql> CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_PORT='master_port'
-> MASTER_USER='replication_user_name',
-> MASTER_PASSWORD='replication_password',
-> MASTER_LOG_FILE='recorded_log_file_name',
-> MASTER_LOG_POS=xxx;
mysql > start slave;
mysql > show slave status\G
下面的两个进程都显示YES则表示配置成功
mysql replication 中slave机器上有两个关键的进程,死一个都不行,一个是slave_sql_running,一个是Slave_IO_Running,一个负责与主机的io通信,一个负责自己的slave mysql进程。
shell > mysql -h master < other_data.sql
增加从服务器,本来已经至少有一个从服务器时(暂时命名为slave1),决定再添加其余的从服务器(slave2),此时就不需要像上面那样去操作主服务器,只要复制一个已经存在的从服务器就可以了
复制的控制相关命令:
查看主服务器的进程
mysql > show processlist;
mysql > show processlist;
这是一个很常见的错误,总结起来就三个原因:
排错过程:(主服务器ip:192.168.67.140,从服务器ip:192.168.67.130)
第0步就是检查错误日志,如果不能快速排错,可以按我的步骤试试:
1.首先在从服务器上执行ping程序,确定能ping通主服务器
在从服务器上执行mysq的远程连接
[root@slave204 log]# mysql -urep -p -h 192.168.67.140 -P3306
如果显示ERROR 1045 (28000): Access denied for user 'test'@'192.168.67.130' (using password: YES)
2.登陆主服务器的mysql,查看所有的用户
mysql > select user,host from mysql.user;
看看用户名是否写错,假如用户名写错了,先删除错误的用户(如用户名为[email protected].%)
mysql > drop user “[email protected].%”@”%”;
再重新创建用户
mysql > grant replication slave on *.* to ‘rep’@‘192.168.67.%’ identified by ‘123456’;
mysql > flush privileges;
案例分析
(1)查看主服务器
mysql > show master status\G
(2)在从服务器上查看
mysql > show slave status\G
问题原因在于:发现Master_Log_File没有对应
在出现Slave_IO_Running:No的机器上进行如下操作
mysql > slave stop;
mysql >CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000026', MASTER_LOG_POS=0;
mysql > slave start;
mysql > show slave status\G
到此问题解决!!
解决办法如下
mysql > stop slave;
mysql > SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql > start slave;
mysql > show slave status\G