MySQL主从布署
零、引入
作为一个架构师,连MySQL主从布署、读写分离都不懂是说不过去的。
呃,在写这篇文章之前,我的确是没做过这方面的东西。一直都在做系统分析及实现,所以有数据库直连即可,一直以为到部署之后运营一段时间再作调整。
其实并不是这样,往往底层的设计决定实现的方式。就这个MySQL主从吧,也有着读写分离的意味,写一个数据库,读可以是多个数据库。所以上层使用JPA、Hibernate这类的ORM框架就无法很好的工作——因为它个都认为读写是同一个数据库。
所以,有时还是要从下往上看,这是架构师的基本能力。
一、准备
1. 准备虚拟主机
安装两台虚拟主机,IP信息如下:
192.168.122.20 mysql-primary # 主库
192.168.122.21 mysql-secondary # 从库
2. 安装MySQL
我是在Ubuntu 18.04 server上安装MySQL的,奇怪的是从Ubuntu 18.04开始,MySQL的安装有所不同,所以这里就说明一下:
# 安装
$ sudo apt install mysql-server
# 初始配置服务器
$ sudo mysql_secure_installation
# 登录服务器测试一下 - 注意,必须是sudo,否则就算输入的密码是正确的也连不上去。
$ sudo mysql -u root -p
3. 配置/etc/hosts
这里配置这个主要是方便认知,如果用IP进行配置的话,一串串数字真的很容易出错,于是就编辑/etc/hosts,以方便认知服务器:
192.168.122.20 mysql-primary
192.168.122.21 mysql-secondary
二、配置主服务器
1. 先登上MySQL服务器
$ sudo mysql -u root -p
2. 准备用户
# 添加用户同步的用户,并赋予访问所有功能的权限
mysql> CREATE USER repl;
mysql> GRANT ALL ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl_password';
# 为root用户添加远程访问数据库的能力,方便测试数据(这一步并不是必须的)
mysql> GRANT ALL ON *.* TO 'root'@'%';
3. 配置服务器
编辑mysql配置文件,在Ubuntu中,文件路径为:/etc/mysql/mysql.conf.d/mysqld.cnf
:
# 在[mysqld]下面增加下面代码
# 数据主唯一标识,一般为本机IP最后一个数字,这里是20
server-id=20
# 开启binlog
log-bin=master-bin
log-bin-index=master-bin.index
# 找到 bind-address = 127.0.0.1,将其改成以下代码,使服务器可以接受远程访问:
bind-address = 0.0.0.0
4. 测试服务器配置
重启服务器:
$ sudo service mysql restart
登录服务器:
$ mysql -u root -h mysql-primary -p
$ mysql -u repl -h mysql-primary -p
查看binlog是否已工作:
mysql> SHOW MASTER STATUS;
# 一般情况下会出现下面的输出:
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 | 1285 | | |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
三、配置从服务器
1. 先登上MySQL服务器
$ sudo mysql -u root -p
2. 准备用户
# 为root用户添加远程访问数据库的能力,方便测试数据(这一步并不是必须的)
mysql> GRANT ALL ON *.* TO 'root'@'%';
3. 配置服务器
编辑mysql配置文件,在Ubuntu中,文件路径为:/etc/mysql/mysql.conf.d/mysqld.cnf
:
# 在[mysqld]下面增加下面代码
# 数据主唯一标识,一般为本机IP最后一个数字,这里是21
server-id=21
# 找到 bind-address = 127.0.0.1,将其改成以下代码,使服务器可以接受远程访问:
bind-address = 0.0.0.0
重启服务器
$ sudo service mysql restart
连上MySQL,配置从服务器并启用:
mysql> CHANGE MASTER TO master_host='mysql-primary',
master_port=3306,
master_user='repl',
master_password='repl_password',
master_log_file='master-bin.000001',
master_log_pos=0;
mysql> start slave;
master_log_file 是主服务器上执行
SHOW MASTER STATUS
获取的主MySQL的binlog信息。
查看slave是否已工作:
mysql> SHOW SLAVE STATUS\G;
# 输出类似以下情形:
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: mysql-primary
Master_User: root
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 922
Relay_Log_File: mysql-secondary-relay-bin.000002
Relay_Log_Pos: 1089
Relay_Master_Log_File: master-bin.000002
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: 922
Relay_Log_Space: 1306
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: 20
Master_UUID: 8f9360b6-4fc7-11e8-bf34-525400c8c952
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
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
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
四、测试
配置好了,那就测试一下:
- 主服务器添加数据库,查看从服务器是否也添加了。
- 主服务器添加数据表,并添加数据,查看从服务器是否已同步。
- 主服务器删除库或者表,查看从服务器的情况是否也同样同步。
五、结语
这里配置好了主从,但是并没有做高可用,嗯,下一个攻击点,MySQL高可用。