mysql 复制和原理

10.2 复制如何工作:

1.在主库上把数据更改记录到二进制日志(Binary Log)中(这些记录被称为二进制日志事件).

2.备库将主库上的日志复制到自己的中继日志(Relay Log)中

3.备库读取中继日志中的事件,将其重放到备库数据之上

第一步是在主库上记录二进制日志,在每次准备提交事务完成数据更新前,主库将数据更新的事件记录到二进制日志中。

MySQL 会按事务提交的顺序而非每条语句的执行顺序来记录二进制日志。在记录二进制日志后,主库会告诉存储引擎可

以提交事务了。

下一步 备库将主库的二进制日志复制到其本地的中继日志中。首先,备库会启动一个工作线程,称为I/O线程,

I/O 线程跟主库建立一个普通的客户端连接,然后在主库上启用一个特殊的二进制转储(binlog dump)线程

(该线程没有对应的SQL命令),这个二进制转储会读取主库上二进制日志中的事件。

它不会对事件进行轮询,如果该线程追赶上了主库,它将进入睡眠状态,直到主库发送信号量通知其有新的

事件产生时才会被唤醒,备库I/O线程会将接收到的事件记录到中继日志中。

主从步骤:

  1. 在每台服务器上创建复制账号

2.配置主库和备库

3.通知备库连接到主库并从主库复制数据

10.2.1 创建复制账号

MySQL 会赋予一些特殊的权限给复制线程,在备库运行的I/O线程会建立一个到主库的TCP/IP连接,

这意味着必须在主库创建一个账户,并赋予其合适的权限。备库I/O线程以该用户名称连接到

主库并读取其二进制日志。通过如下语句创建用户账号:

mysql>GRANT REPLICATION SLAVE,REPLICATION CLIENT ON . to repl@’192.168.0.%’ identified by ‘p4ssword’;

首先Replication操作会涉及到的两个重要权限,这里先做一下说明:
The REPLICATION CLIENT privilege enables the use of SHOW MASTER STATUS and SHOW SLAVE STATUS.
REPLICATION CLIENT 使得用户可以使用SHOW MASTER STATUS和SHOW SLAVE STATUS命令,也就是说这个权限是用于授予

账户监视Replication状况的权力。

The REPLICATION SLAVE privilege should be granted to accounts that are used by slave servers to connect

to the current server as their master. Without this privilege, the slave cannot request updates that

have been made to databases on the master server.
REPLICATION SLAVE则是一个必须而基本的权限,它直接授予slave服务器以该账户连接master后可以执行replicate操

作的权利。

10.2.2 配置主库和备库

下一步需要在主库上开启一些设置,假设主库是服务器server1,需要打开二进制日志并指定一个独一无二的服务器ID

(server ID),

在主库的my.cnf 文件中增加或修改如下内容:
log_bin = mysql-bin

s
server_id = 10

必须明确地指定一个唯一的server ID,默认服务器通常为1,

如果之前没有在MySQL的配置文件中指定log-bin选项,就需要重新启动MySQL.

为了确认二进制日志文件是否已经在主库上创建,使用SHOW MASTER STATUS命令

备库上也需要在my.cnf 中增加类似的配置,并且同意需要重启服务器:

log_bin = mysql-bin

server_id = 2

relay_log = /var/lub/mysql/mysql-relay-bin

log_slave_updates=1

read_only = 1

从技术上来说,这些选项并不总是必要的。其中一些选项我们只是显示地列出了默认值,事实上只有server_id是必需的

这里我们同意也使用了log_bin,并赋予了一个明确的名字。默认情况下,它是根据机器名来命名的,

但如果机器名变化了可能会导致问题。为了简便起见,我们将主库和备库上的log-bin设置为相同的值。

另外我们还增加了两个配置选项:

relay_log(指定中继日志的位置和命名)和log_slave_updates(允许备库将其重放的事件也记录到自身的binlog里0

后一个选项会给备库增加额外的工作,但正如后面你将会看到,我们有理由为每个备库设置该选项。

有时候只开启了二进制日志,但却没有开启log_slave_updates,可能会碰到一些奇怪的现象,

例如,当配置错误时可能会导致备库数据被修改。如果可能的话,最好使用read_only 配置选项,

该选项会阻止任何没有特权权限的线程修改数据。

10.2.3 启动复制

下一步是告诉备库如何连接到主库并重复其二进制日志,这一步不需要通过修改my.cnf来配置,

而是使用CHANGE MASTER TO 语句,该语句完全替代了my.cnf 中相应的设置,并且允许以后指向别的主库时

无须重启备库。下面开始复制的基本命令:

10.2.4 从另一个服务器开始复制

前面的设置都是假定主备库均为刚刚安装好且都是默认的数据,也就是说两台服务器上数据相同,并且知道

当前主库的binlog日志。这不是电信的案例,大多数情况下有一个已经运行了一段时间的主库,

然后用一台新安装的备库与之同步,此时这台备库还没有数据。

有几种方法来初始化备库或者从其他服务器克隆数据到备库,包括从主复制数据,从另外一台备库克隆数据,

以及使用最新的一次备份来启动备库,需要有3个条件来让主库和备库保持同步:

1.在某个时间点的主库的数据快照。

2.主库当前的二进制日志文件,和获得数据快照时在该binlog日志文件中的编译量,

我们把这两个值称为日志文件坐标(log file coordinates).通过这两个值可以确定binlog 日志的位置。

可以通过SHOW MASTER STATUS 命令来获取这些值。

  1. 从快照时间到现在的二进制日志

使用mysqldump

如果只包含InnoDB表,那么可以使用以下命令来转储主库数据并将其加载到备库,然后设置相应的二进制日志坐标:

mysqldump –single-transaction –all-databases –master-date=1

选项 –single-transaction 是的转储的数据为事务开始前的数据。如果使用的是非事务表,可以使用

–lock-all-tables 选项来获得所有表的一致性转储。

10.2.5 推荐的复制配置

有许多参数来控制复制,其中一些会对数据安全和性能产生影响。

在主库上二进制日志最重要的选项是sync_binlog:

sync_binlog=1

如果开启该选项,MySQL每次在提交事务前会将二进制日志同步到磁盘上,保证在服务器崩溃时不会丢失事件。

如果禁止该选项,服务器会少做一些工作,但二进制日志文件可能在服务器崩溃时损坏或丢失信息。

在一个不需要作为主库的备库上,该选项带来了不必要的开销,它适用于二进制日志,而非中继日志。

在备库上,我们同意推荐开启如下配置选项,为中继日志指定绝对路径:

relay_log =/path/to/logs/relay-bin

skip_slave_start

read_only

通过设置relat_log 可以避免中继日志文件基于机器名来命名,防止之前提到的可能在主库发生的问题。

skip_slave_start 选项能够阻止备库在崩溃后自动启动复制。这可以给你一些机会来修复可能发生的问题

read_only 选项可以阻止大部分用户更改非临时表,除了复制SQL线程和其他拥有超级权限的用户之外,

这也是尽量避免给正常账号授予超级权限的原因之一。

| sync_master_info | 10000 |
| sync_relay_log | 10000 |
| sync_relay_log_info | 10000 |

即使开启了所有我们建议的选项,备库仍然可能在崩溃后被中断,因为master.info和中继日志文件都不是崩溃安全的。

默认情况下甚至不会刷新到新磁盘,知道MYSQL 5.5版本才有选项来控制这种行为。

如果备库和主库的延迟很大,备库的I/O线程可能会写很多中继日志文件,SQL线程在重放完一个中继日志中的事件后

会尽快将其删除(通过relay_log_purge选项来控制)

mysql> show variables like ‘%relay_log_purge%’;
+—————–+——-+
| Variable_name | Value |
+—————–+——-+
| relay_log_purge | ON |
+—————–+——-+

10.3 复制的原理

10.3.1 基于语句的复制:

在MySQL 5.0及以前的版本只支持基于语句的复制(也称为逻辑复制),基于语句的复制模式下,主库会记录那些造成

数据更改的查询,当库读取并重放这些事件时,实际上知识把主库上执行过的SQL再执行一遍。这种方式既有好处,也有缺

点。

10.3.2 基于行的复制

MySQL 5.1 开始支持基于行的复制,这种方式会将实际数据记录在二进制日志中,跟其他数据库的实现比较相像。

它有其自身的一些优点和缺点,最大的好处是可以正确的复制每一行,一些语句可以被更加有效地复制。

10.3.4 复制文件

让我们来看看复制会使用到的一些文件,前面已经介绍了二进制日志文件,其实还有其他的文件会被用到。

不同版本在MySQL 默认情况下可能将这些文件放在不同的目录里,大多取决具体的配置选项。

可以在data目录或者包含服务器的.pid文件目录下

mysql-bin.index

当在服务器上开启二进制日志时,同时会生成一个和二进制日志同名的但以.index作为后缀的文件,

该文件用于记录磁盘上的二进制文件。这里的”index” 并不是指表的索引,而是说这个文件的每一行包含了二进制文件

的文件名。

你可能认为这个文件是多余的,可以被删除。事实上并非如此,MySQL依赖于这个文件,除非在这个文件里有记录,

否则MySQL识别不了二进制日志文件。

mysql-repkay-bin-index:

这个文件是中继日志(relay-log)的索引文件,和mysql-bin.index 的作用类似

master.info

这个文件用于保存备库连接到主库所需要的信息,格式为纯文本,此文件不能删除,否则备库在重启后无法连接到主库。

这个文件以文本的方式记录了复制的用户的密码,所以要注意此文件的权限控制。

relay-log.info

这个文件包含了当前备库复制的二进制日志和中继日志坐标(例如,备库复制在主库上的位置),

同样也不要删除这个文件,否则在备库重启后将无法获知从哪个位置开始复制,可能导致重放已经执行过的语句。

使用这些文件来记录MySQL复制和日志状态是一种非常粗糙的方式,更不幸的是,它们不是同步写的。

如果服务器断电并且文件数据没有被刷新到磁盘,在重启服务器后,文件中记录的数据可能是错误的。

以.index 作为后缀的文件也与设置expire_logs_days 存在交互,该参数定义了MySQL清理过期日志的方式,

如果文件Mysql-bin.index 在磁盘上不存在,在某些MySQL版本自动清理就会不起作用,甚至执行PURGE MASTER LOGS语句

也没有用。

10.3.5 发送复制事件到其他备库

log_slave_updates 选项可以让备库变成其他服务器的主库,在设置该选项后,MySQL会将其执行过的事件

记录到它自己的二进制日志中,这样它的备库就可以从其日志中检索并执行事件。

在这种场景下,主库将数据更新事件写入二进制日志,第一个备库提取并执行这个事件。这时候一个事件的生命周期

应该已经结束了,但由于设置了log_slave_updates,备库会将这个事件写到它自己的二进制日志中。

这样第二个备库就将事件提取到它的中级日志并执行。

这意味着作为源服务器的主库可以将其数据变化传递给没有与其直接相连的备库上。

当一个备库从主库获得的事件写入到其二进制日志中时,这个事件在备库二进制日志中的位置与其在主库二进制的位置

肯定是不相同的,可能不同的日志文件或文件内不同的位置。这意味着你不能假定所有拥有同一逻辑复制点的服务器

拥有相同的日志坐标。

10.3.6 复制过滤器

复制过滤选项允许你仅复制服务器上一部分数据,不过这可能没有想象中那么好用。有两种复制过滤方式:

在主库上过滤记录到二进制日志中的事件,以及在备库上过滤记录到中继日志的事件。

一般不从库上进行过滤:

在备库上,可以通过设置replicate_*选项,在从中继日志中读取事件时进行过滤。

你可以复制或忽略一个或多个数据库,把一个数据库重写到另外一个数据库,或使用类似LIKE的模式

复制或忽略数据库表。

原文地址:https://www.cnblogs.com/hzcya1995/p/13351573.html