前言
- 因最近服务器运营商时常出现流量问题,导致公司网站服务异常,为了解决这个问题,打算做一下异地容灾。
方案
- 说是说异地容灾,其实就是将网站服务部署在不同机房服务器上。当机房 A 的服务异常后,可以快速切换到机房 B 所在服务继续给用户提供服务。
MySQL 的主从
- 要实现这个,我们需要将数据库做到主从同步,确切的说是主主互备,而非主从。因为对于主从的架构,在机房 A 异常,机房 B 提供服务时,机房 A 的数据库没法和机房 B 实现同步。目前的方案是手动使其读取机房 B 的 MySQL 服务的 binlog
主从部署
- 加上 A 是主(master),B 是从(slave)
建立 slave 的 MySQL 账户
- B 要想同步 A 的数据,需以 slave 的身份去获取其 binlog,所以,需要在 A 上有一个账户
repl
(你可以用你喜欢的字符串作为用户名)。我们手动建立该 MySQL 用户:
grant replication slave on *.* to 'repl'@'198.74.198.198' identified by '123passwd';
flush privileges;
-
198.74.198.198
是 A 的服务器 ip,123passwd
是repl
用户的密码。flush privileges;
是让授权生效。
确保 A 到 B 是连通的,B 到 A 也是连通的
- 这里提供一种方法,就是在 B 服务器上使用
repl
用户名通过 MySQL 客户端连接 A 的 MySQL 服务:
mysql -h 198.74.198.198 -u repl -p 123passwd
- 其中
198.74.198.198
表示远程数据库服务器所在 ip - 如果能不能连接上,可以根据报错信息,去谷歌搜索报错原因,然后解决。
查看主数据库当前状态
- 要想从 A 上同步数据到 B,我们需要确定从哪个点开始同步。因此查看一下 A(主)的数据状态,使用命令
show master status
:
mysql> show master status;
+------------------+-----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+-----------+--------------+------------------+-------------------+
| mysql-bin.000005 | 397747713 | | | |
+------------------+-----------+--------------+------------------+-------------------+
配置 slave
- 知道从哪个点开始同步之后,我们就可以将这一点告诉 B:
change master to master_host='198.74.198.198',master_port=3306,master_user='repl',master_password='123passwd',master_log_file='mysql-bin.000005',master_log_pos=397747713;
开始同步
- 此时,我们在 B 上,用 MySQL 客户端连接上本地的 MySQL 服务,直行命令,让其开始同步:
start slave;
查看同步状态
- 你让它同步,它不一定能正常执行你的命令,此时我们需要查看同步状态:
show slave status\G;
- 它会给你一些提示:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 154.223.189.198
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 397747713
Relay_Log_File: host-172-16-7-145-relay-bin.000002
Relay_Log_Pos: 12488
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 397759918
Relay_Log_Space: 12673
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: xxxxxxx
Master_Info_File: /www/server/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
1 row in set (0.00 sec)
- 一大堆内容,但我们只需确认其中的两项为
yes
即可
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
- 当两项都为 yes,表示同步正常执行了。
QA
- The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).
解决:更改server-id
参数
2.Last_SQL_Error: Error 'xxx doesn't exist' on query ...
解决:将主服务器上的数据库重新导入到从服务器上,数据库结构即可。只需保证库和表存在。
3.通过命令连接远程数据库服务,查看是否可以连接 ssh -v -p3306 xxx.xxx.xxx.xxx
4.尝试使用当前服务上的MySQL客户端连接远程MySQL服务 mysql -h xxx.xxx.xxx.xxx -u username -p somepassword
,其中 xxx.xxx.xxx.xxx
表示远程数据库服务器所在 ip
参考资料
- https://blog.csdn.net/csdnhsh/article/details/92224317
- https://www.cnblogs.com/ygqygq2/p/6045279.html