主从架构

什么是主从架构

主从架构也称为“水平扩展”架构,英文单词表示 “Master/Slave” 通过为服务器(主库)配置一个或多个备库(从库)的方式来进行数据同步,也就是 复制。

为什么要使用主从架构复制功能不仅有利于构建高性能的应用,同时也是高可用性、可扩展性、灾难修复、备份以及数据仓库等工作的基础。

我的直接目的是为了实现 读写分离。

复制

复制方式

目前存在两种复制方式:基于行的复制

基于语句的复制(逻辑复制)

无论哪种方式,他们都是通过在主库上记录二进制日志、在备库重放日志的方式来实现异步的数据复制。既然是异步,那么主从之间的数据自然会存在延迟。

复制原理

三个步骤:在主库上把数据更改记录到二进制日志中

二进制日志——Binary Log,这些记录被称为二进制日志事件。在每次准备提交事务完成数据更新前主库将数据更新的事件记录到二进制日志中。MySQL 会按事务提交的顺序而非每条语句的执行顺序记录二进制日志。在记录二进制日之后,主库会告诉存储引擎可以提交事务了。

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

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

配置复制

三个步骤:在每台服务器上创建复制账号

配置主库和备库

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

环境

主库:win7 64位,一个

备库:与主库同一台机器,一个

MySQL: 5.6

创建复制账号

由于主库与备库是同一台机器,所以,我把这个账号限制在本地网络——localhost或者127.0.0.1。在主库和备库都执行以下命令:1mysql> grant replication salve,replication client on *.* to rep@'localhost' identified by 'rep123';

配置主库

主要配置 my.ini:

[mysqld]server_id = 11

主服务机标识,整数值([1,32]),并不能与从服务器的值相同

log-bin = mysql-bin

指定二进制日志文件,二进制日志文件以mysql-bin为前缀,并在mysql/data/下

重启 MySQL,查看 mysql/data/ 下,是否生成了以mysql-bin为前缀的文件,或者使用如下命令:1mysql> show master statusG;

注意:navicat 不支持 G 语法,至少我的没有。

ERROR:在错误日志(mysql/data/,以.err结尾)中,发现有如下警告:1

2

3InnoDB: Cannot open table mysql/slave_master_info from the internal data dictionary of InnoDB

InnoDB: Cannot open table mysql/slave_worker_info from the internal data dictionary of InnoDB

InnoDB: Cannot open table mysql/slave_relay_log_info from the internal data dictionary of InnoDB

我找到上述三张表,但是打开报错:该表不存在。

原因:所涉及的表已经损坏。

解决方法:删除已损坏的表,还包括 innodb_index_stats、innodb_table_stats(如果不删,还会报同样的错)

删除 MySQL/data/mysql/ 下的以上述五张表表名为前缀、以 .ibd 为后缀的文件

运行 MySQL/share/mysql_system_tables.sql

生成系统表的 SQL 文件,将重新生成已删掉的额五张表

配置备库

主要配置 my.ini:

[mysqld]server_id = 22

主服务机标识,整数值([1,32]),并不能与主服务器的值相同

relay-bin = mysql-relay-bin

指定中继日志件,中继日志文件以mysql-relay-bin为前缀,并在mysql/data/下

注意:据说不要在 my.ini 中配置 master-port、master-host等,这是老配置,已经被废弃。

启动复制

此步骤是将备库连接到主库,并重放其二进制日志。开始复制的基本命令如下:1

2

3

4

5

6mysql> change master to

-> master_host='127.0.0.1',

-> master_user='rep',

-> master_password='rep123',

-> master_log_file='mysql-bin.000001',

-> master_log_pos=0;

master_host 表示 主库所在服务器的 IP,因为是本地单机建立主从架构,所以 master_host 设置为 127.0.0.1。

接下来要检查复制是否正确执行,执行如下命令:1mysql> show slave statusG;

ERROR:大意是说主从两个 MySQL 的 server_id 相同。12016-12-02 17:19:07 5520 [ERROR] Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it). Error_code: 1593

在 cmd 下查看 备库 的server_id:1mysql>show variables like 'server_id';

果然和主库的一样,明明在 备库的 my.ini 中已经配置了不同的 server_id 值,为什么查到的还是和主库一样呢?

在 navicat 下查看 备库 的 server_id,则和 主库不同,这就更加奇怪了。

原因:我突然想起当时解压第一个 MySQL 的时候 配置过 环境变量,而 MySQL2 则没有配置,这样一来,在 cmd 下查询的 MySQL2 的信息是属于 MySQL。参考 《MySQL-主从架构前传——单机配置多个MySQL实例》

解决方法:将“磁盘符:MySQL2bin;”加入环境变量的 Path 中

使用 navicat

navicat 不支持 G 语法

从头开始执行步骤。

开始复制:1mysql> start slave;

查看错误日志,如果没有错,则说明成功了,否则,根据错误提示寻找问题,或者从头每一步认真重做,做一步检查一次错误日志,缩小错误范围。

使用如下检查命令:1show slave statusG;

正确判断依据:Slave_IO_Running: Yes

Slave_SQL_Running: Yes

````