阿里云mySQl RDS数据同步到本地服务器
目标
在阿里云上有一个高可用版的mySQL RDS,现在我们想在本地保持一个实例副本以实现异地同步。
方案
原来想真接使用阿里云的DTS服务,但是要实现备份到本地,有一个限制条件,要么实现VPN方案,这需要专门的线路,租用费用比较贵,20M就得4万/年左右。用阿里云的智能接入网关的话,成本更高。
低成本的话,还可以考虑用数据订阅服务在实现,但是,这也有问题,首先,得自己开发消费订阅的数据,其次,稳定性和实时性不能保证。因为订阅推送的数据,有保留时间,超过时间的数据,订阅不会再推送,也无法找回。
所以,现在想到的是两个方案,一个是直接对RDS进行主从备份,一个是先将RDS通过DTS同步到一个ECS上的MySQL,然后对这个MySQL和一台本地的MySQL进行主从备份。从安全的角度考虑,第二种方法不需要在RDS上做配置更改,也不需要改变阿里云上的网络架构,更简洁些。所以决定用这种方法。
第一步:以ECS为主Mysql,同步到本地从Mysql
1)先在本地创建一个CentOS的虚拟机,安装与RDS相同版本的MySQL。选择比较新的版本,7.7-1908版,安装后习惯用ifconfig,可是看到不IP地址,想起来CentOS7已经没有这个命令,可用ip addr看来。但是没有看到IP地址。
既然网卡是ens192,就修改它的配置吧
vi /etc/sysconfig/network-scripts/ifcfg-ens192
//将最后一行的ONBOOT=no,修改成ONBOOT=yes,
//重启网络
service network restart
然后再用ip addr,就能看到IP地址了。然后再修改成固定IP
vi /etc/sysconfig/network-scripts/ifcfg-ens192
//先将BOOTPROTO=dhcp修改成BOOTPROTO=static,然后在最后加上三行
//IPADDR=192.168.11.56
//GATEWAY=192.168.11.1
//DNS1=202.96.209.133
service network restart
//然后安装Mysql
yum install wget
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
//上面的rpm很小,只有几K
yum -y install mysql57-community-release-el7-10.noarch.rpm
//下面这行才开始下载,大约259M
yum -y install mysql-community-server
安装成功。
//启动服务
systemctl start mysqld.service
//查看状态
systemctl status mysqld.service
//查找初始的随机密码
grep "password" /var/log/mysqld.log
//可看到下面的一行
//2019-10-22T00:14:34.008951Z 1 [Note] A temporary password is generated for root@localhost: 5x(!fz6nCX,S,说明这个临时密码是5x(!fz6nCX,S,得用它登录,然后修改密码后才能使用
//进入mysql
mysql -uroot -p
//修改密码为Newps@111
mysql> set password=password("Newps@111");
//注意这个密码是有规范要求的,这个规范可以通过下面的命令来查看
// SHOW VARIABLES LIKE 'validate_password%';
//也可以通过下面的命令来修改
//mysql> set global validate_password_policy=0;
//mysql> set global validate_password_length=1;
这就安装成功了,因为上面安装时更新了Yum的Repository,在执行yum时会自动更新,为了不让它自动更新,可将这个Repository去掉
[root@localhost ~]# yum -y remove mysql57-community-release-el7-10.noarch
其它的一些设置如下:
systemctl stop mysqld #关闭MySQL
systemctl restart mysqld #重启MySQL
systemctl status mysqld #查看MySQL运行状态
systemctl enable mysqld #设置开机启动
systemctl disable mysqld #关闭开机启动
在其它的机器上telnet 3306端口不成功是因为防火墙的原因。
[root@localhost ~]# firewall-cmd --state
running
#上面说明防火墙已打开
[root@localhost ~]# systemctl is-enabled firewalld.service;echo $?
enabled
0
#上面说明防火墙是自启动运行的
#开端口命令:firewall-cmd --zone=public --add-port=80/tcp --permanent
#重启防火墙:systemctl restart firewalld.service
#命令含义:
#--zone #作用域
#--add-port=80/tcp #添加端口,格式为:端口/通讯协议
#--permanent #永久生效,没有此参数重启后失效
firewall-cmd --zone=public --add-port=3306/tcp --permanent
systemctl restart firewalld.service
再在其它的机器上Telnet 3306端口,这时能连到,但是显示
FHost '192.168.16.37' is not allowed to connect to this MySQL server
[root@localhost ~]# mysql -uroot -p
mysql> grant all privileges on *.* to root@"%" identified by "Newps@111";
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
2)在阿里云上创建一个相同版本的Mysql,先买一个临时的ECS,1vCPU,2G内存先用着看。
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql-community-server
systemctl start mysqld.service
systemctl status mysqld.service
grep "password" /var/log/mysqld.log
mysql -uroot -p
mysql> set password=password("Newps@111");
mysql> grant all privileges on *.* to root@"%" identified by "Newps@111";
mysql> flush privileges;
安装挺顺利的,而且速度也非常快。
在本地防火墙上配置好NAT和Access权限,然后可以试着从阿里云的ECS上用mysql -uroot -p -h x.x.x.x来连接本地的Mysql试试,很快连上了。也可以在地看看客户端的状态
mysql> SELECT substring_index(host, ':',1) AS host_name,state,count(*) FROM information_schema.processlist GROUP BY state,host_name;
看得出,ECS是可以直接访问到本地的。
3)配置主从复制。本地的作为只读副本,阿里云上的作为主机。考虑到异地复制,时间同步非常重要,所以,第一步是将两台机器上设定相同的NTP客户端。
#在阿里云ECS上,作为主数据库,安装NTP服务,并且将其作为NTP的源服务,给本地的服务器使用
yum -y install ntp
systemctl start ntpd
#再用下面的命令看服务状态
systemctl status ntpd
#再在本地的服务器上
yum -y install ntp
#先试一下看ECS服务器的效果
ntpdate 139.x.x.x(ECS的公网IP)
#能看到类似22 Oct 15:12:37 ntpdate[21839]: adjust time server 139.x.x.x offset 0.008821 sec,说明能连到ECS的NTP服务器
#在ECS上设NTP服务器开机自启
systemctl enable ntpd.service
#在本地从服务器上
vi /etc/ntp.conf
#增加一行server 139.x.x.x,注释掉下面的默认的四行 Server 0.centos.pool.ntp.org iburst.....server 4.centos.pool.ntp.org
#重启NTPd
systemctl restart ntpd
#过一段时间后(10来分钟),用下面的命令看状态,能看到同步成功的信息
ntpstat
下面在ECS上的主Mysql上
vi /etc/my.cnf
#在后面加上下面的内容
server-id=101 #服务器ID,只要不重复就行
log-bin=mysql-bin
binlog_format=row
binlog-ignore-db=information_schema #binlog-ignore-db是列出不需要同步的库名
binlog-ignore-db=mysql
#然后
systemctl restart mysqld
#我以为log-bin=mysql-bin是指向log文件,所以,原来是直接指定目录
#写成log-bin=/var/log/mysql-bin,结果是启动不了,修改成只写mysql-bin就行了。
#在主Mysql上创建同步账号
mysql -uroot -p
mysql>grant replication slave,replication client on *.* to 'repl'@'%' identified by 'NewPs!123';
mysql>use mysql
mysql>select user,host from user;
mysql>show variables like '%server_id%';
在从Mysql服务器上
vi /etc/my.cnf
#只加上,binlog可以不开,除非要做主-主互相复制
server-id=102
在主Mysql,创建一个数据为Test,里面建一个表tab1,加上两行数据。
#在主Mysql上备份
[root@master ~]# mysqldump -uroot -p -all-databases > ./mysqlbak.sql
#文件拷到从Mysql上,然后
[root@local ~]# mysql -uroot -p < ./mysqlbak.sql
#登录到mysql上,能看到数据已经恢复过来了。
在主Mysql库上查看状态,获取主库日志文件名称和偏移量
在从Mysql上,设定change master to命令,参数根据上面获得的信息
#启动从库
mysql> start slave;
mysql> show slave status \G;
看到下面两个Yes,说明已经配置成功了
试着在ECS上的主Mysql表中插入一行,在本地的Mysql上能看到同步成功。
第二步:从RDS配置DTS,同步到ECS的主Mysql
这一步相对比较简单,在阿里云的控制台上,找到DTS服务,选择“数据同步”,创建一个任务,按向导,填写好相关账号,直接执行即可。
故障演练
1)先将本地的从Mysql服务器模拟断电,持续一天后,第二天开机,稍等后,同步正常。数据无丢失。
2)将ECS上的主Mysql服务器强制关机。大约1小时后,DTS服务提示失败,同步停止。半天后开机,Mysql自动启动,但是DTS服务需要手动重启。重启后,数据也正常同步,无丢失。