在现在生产中,一台数据库已经完成不能满足需求,这个时候我们就需要构建MySQL集群来搭接系统,mysql提供主从复制,来进行读写分离和数据备份。这一篇博客,主要是想说明一下,如何实现两台服务器上的 MySQL 数据实时同步,互为主备。
一、在Linux下安装MySql
首先去MySQL官网去下载你需要的安装包,我下载的是mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz,并将这个放在/usr/local目录下,执行如下命令
tar -zxvf /usr/local/mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz
然后将获得文件夹进行重命名:
mv mysql-5.7.20-linux-glibc2.5-x86_64(旧的文件名) mysql(新的文件名)
然后进入mysql文件,如果mysql文件夹下没有data目录,我们就需要创建data目录:在/usr/local/mysql目录下:执行命令
mkdir data
接着创建mysql用户组:
创建用户组:groupadd mysql
创建用户:useradd -r -g mysql mysql
改变mysql目录权限:
chown -R mysql.mysql /usr/local/mysql/
在目录/usr/local/mysql 下,接下来初始化数据库:
./mysqld --initialize --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --lc_messages_dir=/usr/local/mysql/share --lc_messages=en_US
有的时候初始化,会有一些错误,可以参考这篇博客解决mysql初始化错误。
接下来配置my.cnf文件:
vi /etc/my.cnf
然后再在文件里加入,下面配置
[mysqld]
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data/
然后就可以使用service启动:
重启服务:service mysql restart
停止服务:service mysql stop
启动服务:service mysql start
查看服务:service mysql status
第一次可以设置免密码登录,在/etc/my.cnf下,加入下面这个命令:
skip-grant-tables
然后我们可以在/usr/local/mysql/bin 目录下启动MySQL
./mysql -u root -p 输入临时密码
启动成功,安装完成!
二、MySQL双主机数据备份
首先我们需要两台服务,我这里直接在VMware下载了两台虚拟机,地址分别为134.98.1.45和134.98.1.47,首先要保证两台机子,可以互相ping同。
然后在45这个机器上,配置/etc/my.cnf文件:
server_id=10
log-bin=master_01 //开启二进制日志,作用是另一个服务器可以
binlog-do-db=test_db //同步的库
binlog-do-db=my_test //同步的库
在47这个机器上,也需要配置/etc/my.cnf文件:
server_id=20
log-bin=master_02 //开启二进制日志,作用是另一个服务器可以
binlog-do-db=test_db //同步的库
binlog-do-db=my_test //同步的库
配置完成后,重启一下mysql,命令是:service mysql restart
添加的参数分别为:
server_ id 为当前 mysql 服务的识别 ID,必须唯一。
log - bin 开启二进制日志,每次数据操作都会将操作日志记录在里面,以便从服务可以通过日志确定执行了什么操作。
bin - do - db 需要同步的数据库,如果有多个数据库需要同步,写多行。 binlog - do - db = db1,db2,db3... 这种写法是错误的,不会达到预期效果
在45机器进入 mysql后执行下列命令:
GRANT FILE ON *.* TO 'copyuser'@'134.98.1.47' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'copyuser'@'134.98.1.47' IDENTIFIED BY '123456';
flush privileges;
在47机器上进入mysql后执行下列命令:
GRANT FILE ON *.* TO 'copyuser'@'134.98.1.45' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'copyuser'@'134.98.1.45' IDENTIFIED BY '123456';
flush privileges;
然后在45这个机器的mysql中执行 show master status;
同样在47这个机器上执行同样的命令:
分别记一下file和position对应的值,
然后在45这个机器上执行:
mysql>CHANGE MASTER TO
MASTER_HOST='134.98.1.47', //所要同步的服务器ip
MASTER_USER='copyuser', //同步服务器的mysql用户名
MASTER_PASSWORD='123456', //同步服务器的mysql密码,与上面创建时的密码要匹配
MASTER_PORT=3306,
MASTER_LOG_FILE='master_02.000005', //对应134.98.1.47的file名
MASTER_LOG_POS=154, //对应134.98.1.47的position
MASTER_CONNECT_RETRY=10;
同样在47这个机器上执行:
mysql>CHANGE MASTER TO
MASTER_HOST='134.98.1.45', //所要同步的服务器ip
MASTER_USER='copyuser', //同步服务器的mysql用户名
MASTER_PASSWORD='123456', //同步服务器的mysql密码,与上面创建时的密码要匹配
MASTER_PORT=3306,
MASTER_LOG_FILE='master_01.000006', //对应134.98.1.45的file名
MASTER_LOG_POS=154, //对应134.98.1.45的position
MASTER_CONNECT_RETRY=10;
注:若 slave 开启状态无法执行以上命令,需要首先执行 stop slave;关闭 slave,执行完上述命令后执行 start slave;命令开启 slave。
然后分别再两台机器上执行show slave status\G:
Slave_IO_Running:
指的就是从服务器上负责读取主服务器的线程工作状态。 从服务器用这个专门的线程链接到主服务器上,并把日志拷贝回来。
Slave_SQL_Running:
指的就是专门执行 sql 的线程。它负责把复制回来的 Relaylog 执行到自己的数据库中。 这两个参数必须都为Yes 才表明复制在正常工作。
当我在45的数据库删除数据的时候:
我在47的数据库查看数据:
备份成功!
三、错误解决方法:
1.如果两个进程都是no,可能的问题是:出现这个现象的原因主要就是两边数据库数据存在不同之处,也就是同步时没有相同的初态,所以在同步之前要保证需要同步的数据库的数据是一致的!
2.如果一个是connecting:
出现的问题可能是:
1.网络不通 保证两台机器可以互ping机器ip,无丢包率正常访问才行。
2.密码不对 MySQL重新授权远程用户登陆账号,密码不正确导致。
3.pos不正确 主服务器,登陆数据库重新查看起始偏移量show master status。
4.ID问题 ID的问题,在安装完mysql数据库的时候默认他们的server-id=1 但是在做主从同步的时候需要将ID号码设置不一样才行,查看数据库配置文件cat /etc/my.cnf,文件写的不同,排除
5.防火墙策略 查看防火墙策略,是否放通双方的服务端口 iptables -nL,最后发现 防火墙策略写了多端口防火墙策略的端口不生效,解决防火墙策略单独开放端口。
我当时出现这个问题就是因为防火墙没有关闭,所以一直是Connecting。