MySQL复制

MySQL复制

MySQL复制支持基于行的复制和基于sql的复制两种方式,这两种方式都是通过主库记录二进制日志、从库重放日志的方式来实现异步复制。

1.复制如何工作

复制分为三步:

  1. 主库以事物为顺序记录二进制日志。
  2. 从库同步主库二进制日志,复制到自己的中继日志(Relay Log)。
  3. 从库重放日志。

2.配置复制

为MySQL配置复制简单分为下面三步:

  1. 创建复制账号。
  2. 配置主库和从库。
  3. 通知从库连接到主库并从主库复制。

假设我们有两台服务器server1(192.168.0.1)、server2(192.168.0.2)。下面我们会为这两台服务器配置一个复制。

2.1创建复制账号

在从库运行的I/O线程会建立一个到主库的TCP/IP连接,这意味着必须在主库创建一个用户,并赋予其合适的权限。从库I/O线程通过该用户名连接到主库,并读取二进制日志。
创建账号语句:

GRANT REPLICATION SLAVE, REPLICATION CLINT ON *.* TO "[email protected].%" IDENTIFIED BY 'p4ssword';

注意:
1. 主库和从库都需要创建该账户。
2. 因为这个账号是个特权账号,我们将它限制在本地网络。

2.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, 允许从库将从中继日志中重放的事件也记录到从库的二进制日志中。

2.3启动复制

现在,需要告诉从库如何连接到主库,并且重放二进制日志。

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

你可能感兴趣的:(mysql)