MySQL复制概述
⑴、MySQL数据的复制的基本介绍
目前MySQL数据库已经占去数据库市场上很大的份额,其一是由于MySQL数据的开源性和高性能,当然还有重要的一条就是免费~不过不知道还能免费多久,不容乐观的未来,但是我们还是要能熟练掌握MySQL数据的架构和安全备份等功能,毕竟现在它还算是开源界的老大吧!
MySQL数据库支持同步复制、单向、异步复制,在复制的过程中一个服务器充当主服务,而一个或多个服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
请注意当你进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
单向复制有利于健壮性、速度和系统管理:
健壮性:主服务器/从服务器设置增加了健壮性。主服务器出现问题时,你可以切换到从服务器作为备份。
速度快:通过在主服务器和从服务器之间切分处理客户查询的负荷,可以得到更好的客户响应时间。SELECT查询可以发送到从服务器以降低主服务器的查询处理负荷。但修改数据的语句仍然应发送到主服务器,以便主服务器和从服务器保持同步。如果非更新查询为主,该负载均衡策略很有效,但一般是更新查询。
系统管理:使用复制的另一个好处是可以使用一个从服务器执行备份,而不会干扰主服务器。在备份过程中主服务器可以继续处理更新。
⑵、MySQL数据复制的原理
MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。因此,要进行复制,必须在主服务器上启用二进制日志。
每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以便从服务器可以对其数据拷贝执行相同的更新。
认识到二进制日志只是一个从启用二进制日志的固定时间点开始的记录非常重要。任何设置的从服务器需要主服务器上的在主服务器上启用二进制日志时的数据库拷贝。如果启动从服务器时,其数据库与主服务器上的启动二进制日志时的状态不相同,从服务器很可能失败。
将主服务器的数据拷贝到从服务器的一个途径是使用LOAD DATA FROM MASTER语句。请注意LOAD DATA FROMMASTER目前只在所有表使用MyISAM存储引擎的主服务器上工作。并且,该语句将获得全局读锁定,因此当表正复制到从服务器上时,不可能在主服务器上进行更新。当我们执行表的无锁热备份时,则不再需要全局读锁定。
MySQL数据复制的原理图大致如下:
从上图我们可以看出MySQL数据库的复制需要启动三个线程来实现:
其中1个在主服务器上,另两个在从服务器上。当发出START SLAVE时,从服务器创建一个I/O线程,以连接主服务器并让它发送记录在其二进制日志中的语句。主服务器创建一个线程将二进制日志中的内容发送到从服务器。该线程可以识别为主服务器上SHOW PROCESSLIST的输出中的Binlog Dump线程。从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中,即中继日志。第3个线程是SQL线程,是从服务器创建用于读取中继日志并执行日志中包含的更新。
在前面的描述中,每个从服务器有3个线程。有多个从服务器的主服务器创建为每个当前连接的从服务器创建一个线程;每个从服务器有自己的I/O和SQL线程。
这样读取和执行语句被分成两个独立的任务。如果语句执行较慢则语句读取任务没有慢下来。例如,如果从服务器有一段时间没有运行了,当从服务器启动时,其I/O线程可以很快地从主服务器索取所有二进制日志内容,即使SQL线程远远滞后。如果从服务器在SQL线程执行完所有索取的语句前停止,I/O 线程至少已经索取了所有内容,以便语句的安全拷贝保存到本地从服务器的中继日志中,供从服务器下次启动时执行。这样允许清空主服务器上的二进制日志,因为不再需要等候从服务器来索取其内容。
mysql支持的复制类型:
(1):基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
一旦发现没法精确复制时, 会自动选着基于行的复制。
(2):基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
(3):混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
复制解决的问题
MySQL复制技术有以下一些特点:
(1) 数据分布 (Data distribution )
(2) 负载平衡(load balancing)
(3) 备份(Backups)
(4) 高可用性和容错行 High availability and failover
具体配置:
yum -y install mysql mysql-*
vim /etc/my.cnf
默认配置不变,加入以下内容:
log-bin=mysql-bin #开启二进制日志
server-id = 1 #server ID,必须唯一
auto_increment_offset=1 #表示自增长字段从那个数开始,他的取值范围是1 .. 65535
auto_increment_increment=2 #表示自增长字段每次递增的量,其默认值是1,取值范围是1 .. 65535
在slave上做相同配置,更改server ID 为 其它数字;再更改 auto_increment_offset=2,启动数据库
mysql中有自增长字段,在做数据库的主主同步时需要设置自增长的两个相关配置:auto_increment_offset和auto_increment_increment。
auto_increment_offset表示自增长字段从那个数开始,他的取值范围是1 .. 65535
auto_increment_increment表示自增长字段每次递增的量,其默认值是1,取值范围是1 .. 65535
在主主同步配置时,需要将两台服务器的auto_increment_increment增长量都配置为2,而要把auto_increment_offset分别配置为1和2.
这样才可以避免两台服务器同时做更新时自增长字段的值之间发生冲突
下面在master数据库中设置权限,如下:
grant replication slave on *.* to 'tongbu'@'%' identified by '123456';允许从数据库使用tongbu这个用户从任何IP和主进行同步,密码为123456 。
然后在master上执行命令查看:
接下来在slave服务器指定master IP和同步的pos点。
change master to
master_host='192.168.36.143',master_user='jfcsy',master_password='171321',master_log_file='mysql-bin.000003',master_log_pos=267;
在slave启动slave start,并执行show slave status\G查看Mysql主从状态
Slave_IO_Running: Yes
Slave_SQL_Running: Yes两个状态为YES,代表slave已经启动两个线程,一个为IO线程,一个为SQL线程。
然后在master服务器上创建一个数据库和表,命令如下:
再查看一下master的pos号是否有变化:
再去slave服务器上查看是否同步:
至此,主从同步成功;
再到master服务器上插入数据,查看slave是否同步
去slave上查看是否同步
主使用mysqladmin设置root密码,从也会同步!!!
mysql主主配置:
1、在两台服务器上各自建立一个具有复制权限的用户;让两个数据库互为主从的关系
2、修改配置文件:
把上面的连个数据库的配置文件重新配置,其配置如下
主服务器上
[mysqld]
server-id = 1
log-bin = mysql-bin
relay-log = relay-mysql
relay-log-index = relay-mysql.index
auto-increment-increment = 2 #每次跳两个数。
auto-increment-offset = 1 #从1开始。
从服务器上
[mysqld]
server-id = 2
log-bin = mysql-bin
relay-log = relay-mysql
relay-log-index = relay-mysql.index
auto-increment-increment = 2
auto-increment-offset = 2
如果此时两台服务器均为新建立,且无其它写入操作,各服务器只需记录当前自己二进制日志文件及事件位置,以之作为另外的服务器复制起始位置即可
master:查看日志文件信息:
slave:查看日志文件信息:
在各个服务器上建立账号和权限,来进行同步设置
主服务器上创建账号及权限
从服务器上创建账号及权限
在两台服务器上指定对另一台服务器为自己的主服务器
主服务器上指定:
从服务器上指定:
这里需要注意一点,从服务器创建账号及授权时可能会提示如下错误:
此问题的原因是因为之前做过主从复制,解决方法如下:
先停止slave; 再进行重置,再授权就好:
双主架构配置基本完成,下面在各自上面启动复制进程吧~并进行测试:
在两台服务器上分别创建数据库,查看同步效果:
第一台:
创建一个test1库,查看
到第二台上查看是否同步过来
再到第二台上创建一个数据库test2,到第一台上查看:
至此,主主同步完成!