MySQL Replication
主从复制(也称 AB 复制)允许将来自一个MySQL数据库服务器(主服务器)的数据复制到一个或多个MySQL数据库服务器(从服务器)。
复制是异步的 从站不需要永久连接以接收来自主站的更新。
根据配置,您可以复制数据库中的所有数据库,所选数据库甚至选定的表。
MySQL中复制的优点包括:
横向扩展解决方案 - 在多个从站之间分配负载以提高性能。在此环境中,所有写入和更新都必须在主服务器上进行。但是,读取可以在一个或多个从设备上进行。该模型可以提高写入性能(因为主设备专用于更新),同时显着提高了越来越多的从设备的读取速度。
数据安全性 - 因为数据被复制到从站,并且从站可以暂停复制过程,所以可以在从站上运行备份服务而不会破坏相应的主数据。
分析 - 可以在主服务器上创建实时数据,而信息分析可以在从服务器上进行,而不会影响主服务器的性能。
远程数据分发 - 您可以使用复制为远程站点创建数据的本地副本,而无需永久访问主服务器。
前提是作为主服务器角色的数据库服务器必须开启二进制日志
主服务器上面的任何修改都会通过自己的 I/O tread(I/O 线程)保存在二进制日志Binary log里面。
从服务器上面也启动一个 I/O thread,通过配置好的用户名和密码, 连接到主服务器上面请求读取二进制日志,然后把读取到的二进制日志写到本地的一个Realy log(中继日志)里面。
从服务器上面同时开启一个 SQL thread 定时检查Realy log(这个文件也是二进制的),如果发现有更新立即把更新的内容在本机的数据库上面执行一遍。
每个从服务器都会收到主服务器二进制日志的全部内容的副本。
从服务器设备负责决定应该执行二进制日志中的哪些语句。
除非另行指定,否则主从二进制日志中的所有事件都在从站上执行。
如果需要,您可以将从服务器配置为仅处理一些特定数据库或表的事件。
重要: 您无法将主服务器配置为仅记录特定事件。
每个从站(从服务器)都会记录二进制日志坐标:
文件名
文件中它已经从主站读取和处理的位置。
由于每个从服务器都分别记录了自己当前处理二进制日志中的位置,因此可以断开从服务器的连接,重新连接然后恢复继续处理。
一主多从
如果一主多从的话,这时主库既要负责写又要负责为几个从库提供二进制日志。此时可以稍做调整,将二进制日志只给某一从,这一从再开启二进制日志并将自己的二进制日志再发给其它从。或者是干脆这个从不记录只负责将二进制日志转发给其它从,这样架构起来性能可能要好得多,而且数据之间的延时应该也稍微要好一些。工作原理图如下:
关于二进制日志
mysqld将数字扩展名附加到二进制日志基本名称以生成二进制日志文件名。每次服务器创建新日志文件时,该数字都会增加,从而创建一系列有序的文件。每次启动或刷新日志时,服务器都会在系列中创建一个新文件。服务器还会在当前日志大小达到max_binlog_size参数设置的大小后自动创建新的二进制日志文件 。二进制日志文件可能会比max_binlog_size使用大型事务时更大, 因为事务是以一个部分写入文件,而不是在文件之间分割。
为了跟踪已使用的二进制日志文件,mysqld还创建了一个二进制日志索引文件,其中包含所有使用的二进制日志文件的名称。默认情况下,它具有与二进制日志文件相同的基本名称,并带有扩展名'.index'。在mysqld运行时,您不应手动编辑此文件。
术语二进制日志文件通常表示包含数据库事件的单个编号文件。
术语二进制日志表示含编号的二进制日志文件集加上索引文件。
SUPER权限的用户可以使用SET sql_log_bin=0语句禁用其当前环境下自己的语句的二进制日志记录
配置 Replication
配置步骤:
1.在主服务器上,您必须启用二进制日志记录并配置唯一的服务器ID。需要重启服务器。
编辑主服务器的配置文件 my.cnf,添加如下内容
[mysqld]
log-bin=/var/log/mysql/mysql-bin
server-id=1
创建日志目录并赋予权限
shell> mkdir /var/log/mysql
shell> chown mysql.mysql /var/log/mysql
重启服务
shell> systemctl restart mysqld
注意:
如果省略server-id(或将其显式设置为默认值0),则主服务器拒绝来自从服务器的任何连接。 为了在使用带事务的InnoDB进行复制设置时尽可能提高持久性和一致性, 您应该在master my.cnf文件中使用以下配置项: innodb_flush_log_at_trx_commit = 1 sync_binlog = 1 确保未在复制主服务器上启用skip-networking选项。 如果已禁用网络,则从站无法与主站通信,并且复制失败。
2.应该创建一个专门用于复制数据的用户
每个从服务器需要使用MySQL 主服务器上的用户名和密码连接到主站。
例如,计划使用用户 repl 可以从任何主机上连接到 master 上进行复制操作, 并且用户 repl 仅可以使用复制的权限。
在 主服务器 上执行如下操作
mysql> CREATE USER 'repl'@'%' mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' identified by '123';
3.在从服务器上使用刚才的用户进行测试连接
shell> mysql -urepl -p'123' -hmysql-master1
下面的操作根据如下情况继续
主服务器中有数据
如果在启动复制之前有现有数据需要与从属设备同步,请保持客户端正常运行,以便锁定保持不变。这可以防止进行任何进一步的更改,以便复制到从站的数据与主站同步。
在主服务器中导出先有的数据
如果主数据库包含现有数据,则必须将此数据复制到每个从站。有多种方法可以实现:
使用mysqldump工具创建要复制的所有数据库的转储。这是推荐的方法,尤其是在使用时InnoDB。
shell> mysqldump -u用户名 -p密码 --all-databases --master-data=1 > dbdump.db
这里的用户是主服务器的用户
如果不使用 --master-data 参数,则需要手动锁定单独会话中的所有表。
2.从主服务器中使用 scp 或 rsync 等工具,把备份出来的数据传输到从服务器中。
在主服务中执行如下命令
scp dbdump.db root@mysql-slave1:/root/
这里的 mysql-slave1 需要能被主服务器解析出 IP 地址,或者说可以在主服务器中 ping 通。
3.配置从服务器,并重启
在从服务器 上编辑其配置文件 my.cnf 并添加如下内容:
// my.cnf 文件
[mysqld]
server-id=2
4.导入数据到从服务器,并配置连接到主服务器的相关信息
登录到从服务器上,执行如下操作
/*导入数据*/
mysql> source /root/fulldb.dump
在从服务器配置连接到主服务器的相关信息
mysql> CHANGE MASTER TO
MASTER_HOST='mysql-master1', -- 主服务器的主机名(也可以是 IP)
MASTER_USER='repl', -- 连接到主服务器的用户
MASTER_PASSWORD='123'; == 到主服务器的密码
5.启动从服务器的复制线程
```
mysql>startslave;
QueryOK, 0rowsaffected(0.09sec)
```