MySQL复制支持基于行的复制和基于sql的复制两种方式,这两种方式都是通过主库记录二进制日志、从库重放日志的方式来实现异步复制。
复制分为三步:
为MySQL配置复制简单分为下面三步:
假设我们有两台服务器server1(192.168.0.1)、server2(192.168.0.2)。下面我们会为这两台服务器配置一个复制。
在从库运行的I/O线程会建立一个到主库的TCP/IP连接,这意味着必须在主库创建一个用户,并赋予其合适的权限。从库I/O线程通过该用户名连接到主库,并读取二进制日志。
创建账号语句:
GRANT REPLICATION SLAVE, REPLICATION CLINT ON *.* TO "[email protected].%" IDENTIFIED BY 'p4ssword';
注意:
1. 主库和从库都需要创建该账户。
2. 因为这个账号是个特权账号,我们将它限制在本地网络。
我们将server1作为主库,server2作为从库。
首先,我们需要为server1打开二进制日志,并制定一个唯一的server_id
。在server1的my.cnf
中进行如下配置:
log-bin=mysql-bin
server_id=10
**必须明确指定一个唯一的
server_id
如果之前没有配置过log-bin
,重新配置后需要重启MySQL。我们可以通过SHOW MASTER STATUS
语句来查看:
mysql> show master status;
File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
---|---|---|---|---|
mysql-bin.000001 | 154 |
从库上也需要在my.cnf中增加配置,并重启服务器:
log_bin = mysql-bin
server_id = 2
relay_log = /var/libs/mysql/mysql-relay-bin
log_slave_update = 1
read_only = 1
relay_log
指定中继日志存在的位置及命名;log_slave_update
, 允许从库将从中继日志中重放的事件也记录到从库的二进制日志中。
现在,需要告诉从库如何连接到主库,并且重放二进制日志。
mysql> CHANGE MASTER TO MASTER_HOST='server1',
MASTER_USER='repl',
MASTER_PASSWORD='p4ssword',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;
上面的语句中将MASTER_LOG_POS参数设置为0,从二进制文件的开头读起。我们可以通过SHOW SLAVE STATUS
,查看语句执行情况:
mysql> SHOW SLAVE STATUS\G
参数 | 值 |
---|---|
Slave_IO_State | |
Master_Host | server1 |
Master_User | repl |
Master_Port | 3306 |
Connect_Retry | 60 |
Master_Log_File | mysql-bin.000001 |
Read_Master_Log_Pos | 4 |
Relay_Log_File | mysql-repay-bin.000001 |
Relay_Log_Pos | 4 |
Relay_Master_Log_File | mysql-bin.000001 |
Slave_IO_Running | No |
Slave_SQL_Running | No …omitted… |
Seconds_Behind_Master | NULL |
Slave_IO_Running
, Slave_SQL_Running
, Seconds_Behind_Master
这三项显示当前从库复制尚未运行。
注意
上面的结果中,我们可以看到日志的开头是4,而不是0.我们在执行CHANGE MASTER TO ....
语句时将MASTER_LOG_POS
参数设置为0,仅仅是标注从文件开始位置读, 然而事实上MySQL读取第一个事件是从第4位开始读的。
开始复制
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS;
参数 | 值 |
---|---|
Slave_IO_State | Waiting for master to send event |
Master_Host | server1 |
Master_User | repl |
Master_Port | 3306 |
Connect_Retry | 60 |
Master_Log_File | mysql-bin.000001 |
Read_Master_Log_Pos | 164 |
Relay_Log_File | mysql-repay-bin.000001 |
Relay_Log_Pos | 4 |
Relay_Master_Log_File | mysql-bin.000001 |
Slave_IO_Running | Yes |
Slave_SQL_Running | Yes …omitted… |
Seconds_Behind_Master | 0 |
从上面的输出我们可以看出:
1. I/O线程和SQL线程已经开始运行。 I/O线程正在等待从主库传递过来的事件,这意味I/O线程已经读取了主库所有的事件。
2. Seconds_Begind_Master的值不再是NULL。
3. 日志位置发生了改变,表明已经从主库获取和执行了一些事件。如果在主库上做一些数据更新,就会看到从库的文件或者日志位置都可能会增加。
我们还可以从线程列表看到复制线程。在主库上可以看到由从库I/O线程向主库发起的连接。
mysql> SHOW PROCESSLIST\G
参数 | 值 |
---|---|
Id | 55 |
User | repl |
Host | replica1.webcluster_1:54813 |
db | NUll |
Command | Binlog Dump |
Time | 610237 |
State | Has sent all binlog to slave;waiting for binlog to be updated |
Info | Null |
同样,我在从库也可以看到两个线程:I/O线程和SQL线程
msyql> SHOW PROCESSLIST\G
第一行
参数 | 值 |
---|---|
Id | 1 |
User | system user |
Host | |
db | NUll |
Command | Connect |
Time | 611116 |
State | Waiting for master to send event |
Info | Null |
第二行
参数 | 值 |
---|---|
Id | 2 |
User | system user |
Host | |
db | NUll |
Command | Binlog Dump |
Time | 33 |
State | Has read all relay log; waiting for the slave I/O thread to upate it |
Info | Null |