MySQL内建的复制功能是构建基于MySQL的大规模、高性能应用的基础,这类应用使用所谓的“水平扩展”的架构,为服务器配置一个或多个备库的方式来进行数据同步。
复制解决的基本问题时让一台服务器的数据与其它服务器保存同步。
MySQL支持两种复制方式,基于行的复制和基于语句的复制(逻辑复制)。
这两种方式都是通过在主库上记录二进制日志,在备库重放日志的方式来实现异步的数据复制。
复制既不是备份也不能取代备份!!
复制有三个步骤:
① 在主库上把数据更改记录到二进制日志(Binary Log)中(这些记录被称为二进制日志事件)
② 备库将主库上的日志复制到自己的中继日志(Relay Log)中。
③ 备库读取中继日志中的事件,将其重放到备库数据之上。
配置复制
1.在每台服务器上创建复制账号(主备都创建)
MySQL会赋予一些特殊的权限给复制线程。在备库运行的I/O线程会建立一个到主库的TCP/IP连接,这意味着必须在主库创建一个用户,并赋予其合适的权限。备库I/O线程以该用户名连接到主库并读取其二进制日志。
mysql> grant replication slave,replication client on *.* to repl@'192.168.20.%' identified by 'p4ssword';
2.配置主库和备库
主库:
如果my.cnf中之前没有log-bin 选项,就需要重新启动MySQL
[mysql@centos7min1 mysql57]$ vi my.cnf
[client]
port = 3306
socket = /opt/mysql57/socket/mysqld-T-prod-3306.sock
default_character_set=utf8
[mysqld]
user = mysql
port = 3306
socket = /opt/mysql57/socket/mysqld-T-prod-3306.sock
datadir = /opt/mysql57/data
basedir = /opt/mysql57/
server_id = 10 ## 1-10
log_bin = /opt/mysql57/mylog/mysql-bin-T-prod-3306 #二进制日志
sync_binlog=1 #提交事务将二进制日志同步至磁盘,防止出错丢失事件
tmpdir = /opt/mysql57/tmp
[mysqld_safe]
pid_file = /opt/mysql57/pid/mysql-T-prod-3306.pid
log_error = /opt/mysql57/log/mysql-T-prod-3306.err
[mysql@centos7min1 mysql57]$ ./support-files/mysql.server restart
mysql> show master status;
+------------------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-T-prod-3306.000004 | 154 | | | |
+------------------------------+----------+
192.168.0.92 MySQL主服务配置信息:
备库:
备库上也需要在my.cnf中增加类似的配置,并且同样需要重启服务器
[yang@centos7min2 mysql]$ cat my.cnf
[client]
port=39306
socket=/opt/mysql5/mysql/socket/mysqld-T-prod-39306.sock
default_character_set=utf8
# Here follows entries for some specific programs
# The MySQL server
[mysqld]
user=mysql
port=39306
socket=/opt/mysql5/mysql/socket/mysqld-T-prod-39306.sock
datadir=/opt/mysql5/mysql/data
basedir=/opt/mysql5/mysql
server_id=9
log_bin=/opt/mysql5/mysql/mylog/mysql-bin-T-prod-39306
relay_log=/opt/mysql5/mysql/mylog/relay-log-T-prod-39306 #中继日志
log_slave_updates=1 #允许备库将重放的事件也记录到自身的二进制日志中
read_only=1 #如果备库没有写操作就可设置该参数
tmpdir=/opt/mysql5/mysql/tmp
[mysqld_safe]
pid_file=/opt/mysql5/mysql/pid/mysql-T-prod-39306.pid
log_error=/opt/mysql5/mysql/log/mysql-T-prod-39306.err
[yang@centos7min2 mysql]$ ./support-files/mysql.server restart
192.168.0.93 MySQL从服务配置信息:
3.通知备库连接到主库并从主库复制数据
启动复制
这一步不要通过修改my.cnf来配置,而是使用 change master to语句,该语句完全替代了my.cnf中相应的设置,并且允许以后指向别的主库时无须重启备库。
备库:
mysql> change master to master_host='192.168.20.71',
-> master_user='repl',
-> master_password='p4ssword',
-> master_log_file='mysql-bin-T-prod-3306.000004',
-> master_log_pos=0;
Query OK, 0 rows affected, 2 warnings (0.04 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.20.71
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-T-prod-3306.000004
Read_Master_Log_Pos: 4
Relay_Log_File: relay-log-T-prod-39306.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin-T-prod-3306.000004
Slave_IO_Running: No
Slave_SQL_Running: No
mysql> start slave; | (stop slave )
Query OK, 0 rows affected (0.02 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.20.71
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-T-prod-3306.000004
Read_Master_Log_Pos: 154
Relay_Log_File: relay-log-T-prod-39306.000002
Relay_Log_Pos: 391
Relay_Master_Log_File: mysql-bin-T-prod-3306.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
从线程列表中看到复制线程,在主库上可以看到由备库I/O线程向主库发起的连接。
mysql> show processlist\G
*************************** 2. row ***************************
Id: 4
User: repl
Host: 192.168.20.72:34388
db: NULL
Command: Binlog Dump
Time: 151
State: Master has sent all binlog to slave; waiting for more updates
Info: NULL
同样,在备库也可以看到两个线程,一个是I/O线程,一个是SQL线程。
*************************** 1. row ***************************
Id: 3
User: system user
Host:
db: NULL
Command: Connect
Time: 659
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 4
User: system user
Host:
db: NULL
Command: Connect
Time: 654
State: Slave has read all relay log; waiting for more updates
Info: NULL
主库的操作能同步备库,但备库的操作不能同回主库。
取消主备复制:
备库 my.cnf
##server_id=9
##log_bin=/opt/mysql5/mysql/mylog/mysql-bin-T-prod-39306 ---master取消
show master status
##relay_log=/opt/mysql5/mysql/mylog/relay-log-T-prod-39306 ---slave取消
##log_slave_updates=1
##read_only=1
show slave status
彻底取消主从复制:
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> reset slave all;
Query OK, 0 rows affected (0.06 sec)
mysql> show slave status\G
Empty set (0.00 sec)
MYSQL主 my.cnf
MYSQL 从 my.cnf