MySQL复制原理

mac2025-04-15  6

复制的基本步骤

配置一个服务器作为Master配置一个服务器作为Slave将Slave连接到Master

步骤1和2需要重启MySQL

配置Master

将服务器配置为Master,要确保服务器有一个活动的二进制日志(binary log)和唯一的服务器ID。二进制日志上保存了Master上所有的改变。服务器ID用于区分服务器,要创建二进制日志和服务器ID,需要停掉服务器,然后将log-bin、log-bin-index、server-id选项添加到my.cnf配置文件。

[mysqld] log-bin=master-bin log-bin-index=master-bin.index server-id=1

log-bin选项给出了二进制日志产生的所有文件的基本名(二进制日志包含多个文件)。 log-bin-index给出了二进制索引文件的文件名,这个索引文件保存了所有binlog文件的列表。 严格的说,不需要为log-bin选项提供值,默认值是hostname-bin。hostname的值来自pid-file选项,默认值是主机名。如果管理员后来修改了主机名,binlog文件名也会随之改变,但是索引文件扔可以获取正确的值。最好为服务器创建一个机器无关的唯一的服务器名,因为一系列binlog文件中途改名可能会很乱。 如果没有为log-bin-index赋予任何值,其默认值与binlog文件的基本名相同,索引文件名会随主机名的改变而改变。所以,如果你改变主机名然后重启服务器,将找不到索引文件,从而认为索引文件不存在,导致二进制日志为空。 每个服务器都有一个唯一的服务器ID,所以,如果一个Slave连接了Master,并且其server-id的参数值与master相同,则会产生master与slave服务器id相同的错误。 将log-bin和server-id选项添加到配置文件后重启服务器,然后添加一个复制用户,这样便完成了配置。

在Master上创建一个复制用户

create user repl_user; grant replication slave on *.* to repl_user identified by 'xxxx';

replication slave 并没有什么特别之处,只是这个用户能够从master上取得二进制日志的转储数据。完全可以给一个常规用户replication slave权限,但是最好还是将复制slave用户与其他用户区别开来。这样的话,以后如果想禁止某些slave的连接,只要删除该用户即可。

配置Slave

需要为每个Slave配置一个唯一的服务器ID,考虑使用relay-log和relay-log-index选项向my.cnf文件添加中继日志文件(relay log file)和中继日志索引文件(relay log index file)的文件名 配置Slave

[mysqld] server-id = 2 relay-log-index=slave-relay-bin.index relay-log=slave-relay-bin

和log-bin、log-bin-index选项一样,relay-log和relay-log-index选项默认值取决于hostname。 修改my.cnf后,重启Slave,使配置文件生效

连接Master和Slave

现在创建基本的复制只剩下最后一步了:将Slave指向Master,让他知道从哪里复制。为此需要知道Master的4部分信息:

主机名端口号Master上拥有Replication Slave权限的用户账号该用户的密码

配置Master时已经创建了一个拥有正确权限的用户账号和密码。主机名由操作系统确定,不能通过my.cnf配置。 启用复制

slave> CHANGE MASTER TO -> MASTER_HOST = 'master-1', -> MASTER_PORT = 3306, -> MASTER_USER='repl_user', -> MASTER_PASSWORD = 'XXXX' slave> START SLAVE;

以上,已经建立了Master和Slave之间的第一个复制。如果在Master数据库表上做一些改动,如创建新表并填充数据,将发现这些改变都会复制到Slave。

MASTER_HOST的参数值可以是主机名或者IP地址。

二进制日志简介

复制过程需要二进制日志 (binlog),他记录了服务器数据库上的所有改变。语句执行结束时,将在二进制日志的末尾写入一条记录,同时通知语句解析器语句已经执行完毕。通常只有即将执行完毕的语句才会被写入二进制日志。

二进制日志记录了什么

二进制日志的目的是记录数据库中表的更改,然后用于复制和PITR,少数审计情况也会用到。 注意二进制日志只记录包括数据库的改动,哪些不改变数据的语句不会写入二进制日志。 传统意义上说,MySQL复制记录了产生变化的SQL语句,称为基于语句的复制(statement-based replicaton)。基于语句的复制的缺点是无法保证所有语句都正确复制。5.1版本中,MySQL还提供了基于行的复制(row-based replication)。相比于基于语句的复制,基于行的复制将每一次改动记为二进制日志中的一行。基于行的复制不仅更加方便,而且有时速度更快。 考虑一个含有多表连接或WHERE条件的复杂更新,看看这两种复制有何不同。真正需要知道的是更新后每行的状态,而不是像基于语句的复制那样把所有的逻辑都记录在Slave上重新执行。相反,如果某个更新改变了10000行,你可能宁愿只记录这条语句,而不是像基于行的复制那样记录10000个单独的改动。

观察复制的动作

使用命令行客户端连接Master,然后执行一些命令获取二进制日志:

create table tb1(text TEXT); insert into tb1 values("year!replication"); select * from tb1; flush logs;

flush logs强制轮换二进制日志,从而得到一个完整的 二进制文件。使用show binlog events命令进一步查看该文件

show binlog events\G; ...........................1.row..................................... log_name:master-bin.00001 pos:4 event_type:format_desc server_id:1 end_log_pos:106 info: server ver:5.1.33,binlog ver 4 ...........................2.row..................................... log_name:master-bin.00001 pos:106 event_type:query server_id:1 end_log_pos:197 info: use 'test';create table tb1(text TEXT) ...........................3.row..................................... log_name:master-bin.00001 pos:197 event_type:query server_id:1 end_log_pos:305 info: use 'test';insert into tb1 values("year!replication") ...........................4.row..................................... log_name:master-bin.00001 pos:305 event_type:rotate server_id:1 end_log_pos:349 info: master-bin.00002;pos=4
最新回复(0)