呕心沥血博一文--MySQL主从异步复制

目录

1、概述

2、主从时间同步

3、主从服务器mysql部署

4、配置、启动从服务

5、测试

6、总结

1、概述

mysql内建的复制功能是mysql应用的“水平扩展”的架构,是mysql高性能运用的基础,为一个服务器配置一个或多个备库来进行数据的同步(准备的说不应该说是“同步”,因为主从服务器的数据根本不可能做同步)。在这样一个分布式的架构中各个服务器间时间应该同步才是,能为后期日志的统计分析提供更为准备的信息,这样才能准确反应出某个时间点我们系统的访问情况。

主从复制是一种异步复制的模型,说成“主从同步”是不精确的,应说是“主从复制”,先有主,再有从。因mysql主从复制原理的限定,在从库上只有一个sq线程(即使在mysql5.6中支持多线程,但也是针对库级别的)来重放中继日志中的事件,这种在主服务器能并发的查询请求在从服务器就成了串行化来执行,这是一个从服务器会慢于主服务器的一个原因。

对主从服务器在硬件选择上的建议:如果在规划主从时考虑到有可能会把从服务器提升为主服务器,那主从服务器硬件配置建议完全相同,应选择核多、主频高的CPU,频率高、总容量大的内存,多块高速的SAS硬盘(或SSD)及带有BBU的RAID卡,在RAID级别上建议选择raid10或raid50;如果从库只是用来作为主库的一个副本,以便于数据的备份,那从服务器的CPU没必要与主服务一个规格,但硬盘的IO这一块还是不要太差,IO高有助于事务的重放效率,在一定程度上能缩小与主库的时间差。

2、主从时间同步

主服务器配置成一ntpd服务器,自身与外网的ntpd服务进行时间校准,而又对从服务器提供时间校准服务。在生产环境中最好不要用ntpdate来强行调整服务器的时间,这样会对让服务器的时间产生空白区,注意,ntpdate工具是调整时间,而不是像ntpd工具一样是校准时间,两者的差别是挺大的。

主服务器基础环境:

[[email protected] ~]# cat /etc/issue
CentOS release 6.4 (Final)
Kernel \r on an \m
[[email protected] ~]# uname -r
2.6.32-358.el6.x86_64
[[email protected] ~]# ifconfig | grep Bcast    #从服务器的系统与主服务器相同,只是IP地址是192.168.0.202
          inet addr:192.168.0.201  Bcast:192.168.0.255  Mask:255.255.255.0

安装配置主服务器成为ntpd时间服务器:

[[email protected] ~]# yum -y install ntp
[[email protected] ~]#  service ntpd start #启用服务后等个1-3分钟,就可用ntpq -p命令查看是否能与远程ntpd服务器连接
[[email protected] ~]#  vi /etc/ntp.conf  #配置ntp配置文件,使其成为从服务器的时间服务器
……略……
# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap   #复制上边一行并启用,把ip修改成本地地址段

#外部时间服务器不可用时,以本地时间作为时间服务
server 127.127.0.0
fudge 127.127.0.0 stratum 10
……略……
[[email protected] ~]# service ntpd restart  #重启服务
[[email protected] ~]# chkconfig --level 235 ntpd on

在从服务器上安装配置ntp:

[[email protected] ~]# yum -y install ntp
[[email protected] ~]# vim /etc/ntp.comf  #注释掉默认的时间服务器,加上本地时间服务器
……略……
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 192.168.0.201
#server 0.centos.pool.ntp.org iburst
#erver 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
……略……
[[email protected] ~]# service ntpd restart
[[email protected] ~]# chkconfig ntpd on
[[email protected] ~]#  ntpq -p  #监控时间校准的状态信息

测试时可以试着把从服务器的时间调慢几分钟,然后观察从服务器的时间是否会慢慢的赶上来。

3、主从服务器mysql部署

3.1、主服务器安装配置

[[email protected] software]# pwd
/root/software
[[email protected] software]# ls
mysql-5.6.24-linux-glibc2.5-x86_64.tar.gz
[[email protected] software]# tar xf mysql-5.6.24-linux-glibc2.5-x86_64.tar.gz -C /usr/local/
[[email protected] software]# cd /usr/local
[[email protected] local]# ln -sv mysql-5.6.24-linux-glibc2.5-x86_64 mysql
[[email protected] local]# cd mysql
[[email protected] mysql]# chown -R root.mysql ./*
[[email protected] mysql]# mkdir /mnt/mydata/dbdata  #创建数据目录
[[email protected] mysql]# chown -R mysql.mysql /mnt/mydata/dbdata
[[email protected] mysql]# scripts/mysql_install_db --user=mysql --datadir=/mnt/mydata/dbdata/  #初始化数据库,如果没有mysql用户请自行创建

因mysql 5.6中的my.cnf文件太过简单,所以复制mysql 5.5中的配置文件再作一些修改:

[[email protected] mysql]# cp /opt/lamp/mysql55/support-files/my-large.cnf /etc/my.cnf
修改my.cnf配置文件
[[email protected] mysql]# vim /etc/my.cnf
……
#thread_concurrency = 8 #注释此选项,在5.6中已被放弃
#指定数据目录
datadir = /mnt/mydata/dbdata  
#基于Innodb的表让表使用单独的表空间
innodb_file_per_table = 1  
#启用慢查询日志
slow_query_log = 1
#如果查询时间长于“long_query_time”设定的值,那就把此查询查询到“slow_query_log_file”文件中
long_query_time = 1
slow_query_log_file = /var/log/mysql/master-slow.log
#定义错误日志文件
log_error = /var/log/mysql/master.error
……
#定义二进制日志文件
log-bin=/var/log/mysql/mysql-bin
#每一次事件提交就使日志同步到磁盘,默认“sync_binlog=0”,表示让系统自己来flush使在内存的日志刷到磁盘,设置为“1”是一种安全的设置,因为当系统crash时你最多丢失一个事件,但相反会增加系统的IO,即使这样也建议设置成“1”
sync_binlog = 1
……
#在5.6中已建议把二进制日志的格式修改成“row”
binlog_format=row
……
#设置服务器ID号
server-id       = 100
[[email protected] mysql]# cp support-files/mysql.server /etc/rc.d/init.d/mysqld56  #复制启动脚本
[[email protected] mysql]# service mysqld56 start
[[email protected] mysql]# ls /var/log/mysql
master.error  master-slow.log  mysql-bin.000001  mysql-bin.index
[[email protected] mysql]# vim /etc/profile.d/mysql56.sh  #导出二进制文件路径
export PATH=/usr/local/mysql/bin:$PATH
[[email protected] mysql]# source /etc/profile.d/mysql56.sh
[[email protected] ~]# mysql  #数据库连接测试
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 5.6.24-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.

mysql>

3.2、从服务器安装配置

从服务器的安装方法与主服务器一样,只是在my.cnf配置文件有些不同:

[[email protected] mysql]# vim /etc/my.cnf
……
#thread_concurrency = 2

datadir = /mnt/mydata/dbdata
innodb_file_per_table = 1
log_error = /var/log/mysql/slave.error
#relay_log
relay_log = /var/log/mysql/mysql-relay-bin
sync_relay_log = 1 
#设置让sql thread读取中继日志中的语句并在本地运用时记录到本地的二进制日志,当然从服务器要打开“log-bin”启用二进制日志,如果此从服务器还可以作为其他从服务器的主服务器,应启用“log_slave_updates = 1”
log_slave_updates = 1
#在从服务器的数据中会多出两个文件,一个是master.info和relay-log.info,master.info文件记录了当前从服务器请求主服务器的二进制文件名与偏移量等信息,而relay.info文件记录了从服务器当前所使用的中继日志文件名与偏移量等信息,如果主服务器比较繁忙,文件中记录的偏移量这样的信息是时刻在变化的,可惜的是这些数据不是时时写入磁盘的,是先写进内存,再同步到磁盘,这样可能会对数据带来不一致的问题。在新版本中引入了下边两个变量来控制此行为,表示当每一次事件后就让数据更新到磁盘,也就是更新master.info和relay-log.info两个文件,这样尽可能让数据及时刷新到磁盘,让数据持久化,当然相应增加了系统的IO,但为了数据的安全就是值得的。
sync_master_info = 1
sync_relay_log_info =1
#security
#设置从库为只读模式,但具有supper权限的用户不受此限制
read_only = 1
#跳过当mysqld启用时自动启用slave线程
skip_slave_start
……
log-bin=/var/log/mysql/mysql-bin
sync_binlog = 1
……
server-id       = 200
[[email protected] mysql]# service mysqld56 start
Starting MySQL.. SUCCESS!
[[email protected] mysql]# ls /var/log/mysql  #中继日志还没有生成,因从服务器线程没有启动
mysql-bin.000001  mysql-bin.index  slave.error
[[email protected] mysql]# ls /mnt/mydata/dbdata/ #master.info和relay-log.info两个文件没有生成,因为从服务线程没有启动
auto.cnf  ibdata1  ib_logfile0  ib_logfile1  mysql  performance_schema  slave.pid  test
[[email protected] mysql]# mysql  #测试
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.24-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.

mysql>

4、配置、启动从服务

上边已把主从服务器各自的my.cnf配置文件已设置完毕,要想启动mysql的主从复制功能,现在还差一个从从服务器到主服务器的连接帐户,再启用从服务器上的复制线程即可。

4.1、在主服务器上创建拥有复制权限的帐户

[[email protected] ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 191
Server version: 5.6.24-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.

mysql> GRANT replication slave,replication client ON *.* TO ‘repuser‘@‘192.168.0.%‘ IDENTIFIED BY ‘111111‘;
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW MASTER STATUS;  #记录下当前主服务器所使用的二进制文件及position
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      430 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

4.2、从服务器连接主服务器、启动复制线程

[[email protected] mysql]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.24-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.
mysql> CHANGE MASTER TO
    -> MASTER_HOST=‘192.168.0.201‘,
    -> MASTER_USER=‘repuser‘,
    -> MASTER_PASSWORD=‘111111‘,
    -> MASTER_LOG_FILE=‘mysql-bin.000001‘,
    -> MASTER_LOG_POS=0;    #这里的偏移量我指定为“0”,零表示从开二进制日志的开头开始进行复制
mysql> SHOW SLAVE STATUS\G #查看slave的状态信息,IO thread和sql thread线程都还没有启动
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 192.168.0.201
                  Master_User: repuser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No
……
mysql> START SLAVE;  #启动复制线程
mysql> SHOW SLAVE STATUS\G  #两个线程已启动
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.201
                  Master_User: repuser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 430
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 593
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
mysql> SHOW GRANTS FOR ‘repuser‘@‘192.168.0.%‘; #这个复制所用的帐户已经从主服务器复制到了从服务器
+--------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected]%                                                                                                                   |
+--------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO ‘repuser‘@‘192.168.0.%‘ IDENTIFIED BY PASSWORD ‘*FD571203974BA9AFE270FE62151AE967ECA5E0AA‘ |
+--------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

5、测试

在主服务器上创建、修改数据:

mysql> CREATE DATABASE mydb1;
Query OK, 1 row affected (0.00 sec)

mysql> USE mydb1;
Database changed
mysql> CREATE TABLE tb1 (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,name CHAR(20) NOT NULL,age TINYINT UNSIGNED);
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tb1 (name,age) VALUES (‘tom‘,12),(‘jem‘,23);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

在从服务器上查看在主服务器的修改:

[[email protected] mysql]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.24-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.

mysql> SELECT * FROM mydb1.tb1;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | tom  |   12 |
|  2 | jem  |   23 |
+----+------+------+
2 rows in set (0.00 sec)

测试证明:在主服务器上的修改已复制到了从服务器上。

6、总结

mysql的主从复制已搭建完毕,但这种复制并不能替代数据库的备份。由于从服务器是单进程模型(mysql 5.6的多线程也只能是库级别的),所以在一个比较繁忙的mysql系统上,从服务器可能会落后主服务器,这是mysql主从复制架构原生带来的特性,并不能真正做到主从的同步,所以在后期的维护工作中我们要用到一些监控工具来及时发现从服务器是否真正落后主服务器。在博文的最开始已提到在这种分布式的架构中时间同步的重要性,在用“show slave status\G”查看从服务器状态时有一个变量“Seconds_Behind_Master”这个值就是反应从服务器落后主服务器的时间,详细一点就是说明从服务器的SQL thread处理中继日志中的事件时,会把主服务器上日志中的timestamp与从服务器运行sql thread时的时间进行相关运算,这个差值就是“Seconds_Behind_Master”的值,所以主从服务器间的同步显得格外的重要。

“Seconds_Behind_Master”的值为0也不代表主服务器与从服务器已经同步,只能说sql thread已把relay log中的事件执行完了,因为主服务器的bin log不会实时的同步到从服务器上,从服务器上的relay log总会落后于主服务器的bin log,所以“Seconds_Behind_Master”这个值不具有真正意义上的参考价值。要监控主从是否一致,可以用percona-tools工具集中的pt-heartbeat工具。

时间: 2024-10-06 12:13:26

呕心沥血博一文--MySQL主从异步复制的相关文章

MySQL主从延迟复制实践及生产故障案例恢复实践

1.1 MySQL主从延迟复制介绍 从MySQL5.6开始支持了主从延迟复制,这个功能主要解决的问题是,当主库有逻辑的数据删除或错误更新后,所有的从库都会进行错误的更新,从而导致所有的数据库数据异常,即使有定时的备份数据可以用于数据恢复,特别是数据库数据量很大时,恢复时间会很长,再恢复期间数据库数据被删或错误数据影响正常的访问体验. 而延迟复制就可以较好的解决这个问题.例如,可以设定某一个从库和主库的更新延迟1小时,这样主库数据出问题以后,1个小时以内发现,可以对这个从库进行无害恢复处理,使之依

mysql 主从的复制的原理及操作步骤

数据库读法约定: 主库: master 从库: slave mysql 主从同步的原理: #主从是异步模式,且是由从库找主库进行同步: 1.主库开启IO线程:    开启binlog: #binlog记录用户的增删改 从库开启IO线程:    开启SQL线程: 2.主库授权从库同步的帐号密码: 3.备份主库数据且导入从库: 4.在从库change master to 导入用于同步主库的ip.port.user.等信息. CHANGE MASTER TO          MASTER_HOST=

mysql主从数据库复制

Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的.复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器.主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环.这些日志可以记录发送到从服务器的更新.当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置.从服务器接收从那时起发生的

MariaDB主从异步复制详解

一 异步复制(Asynchronous replication) 1.MariaDB本身支持单向的.异步的复制.异步复制意味着在把数据从一台机器拷贝到另一台机器时有一个延时,最重要的是这意味着当应用系统的事务提交已经确认时数据并不能在同一时刻拷贝,应用到从机.通常这个延时是由网络带宽.资源可用性和系统负载决定的.然而,使用正确的组件并且调优,复制能做到接近瞬时完成. 2.MariaDB默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这

mysql主从服务器复制原理

在实际企业应用环境当中,单台mysql数据库是不足以满足日后业务需求的.譬如服务器发生故障,没有备份服务器来提供服务的话,业务就得停止.介于这种情况,我们来学习一下mysql主从复制. 将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的.复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器.主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环.这些日志可以记录发送到从服

mysql主从服务器复制操作

master主机ip:192.168.1.19  用户名sunzy 密码123456slave主机ip:192.168.1.20 1.配置master1)接下来对master进行配置,包括打开二进制日志,指定唯一的servr ID.例如,在配置文件加入如下值:    [mysql]    log-bin=mysql-bin   #二进制变更日值,[必须]启用二进制日志    server-id=1    #为主服务master的ID值2)重启master服务,运行SHOW MASTER STAT

MySQL主从延时复制

MySQL的主从复制是实现MySQL大规模集群的基础,其在日常生产环境中被广泛的被应用,而在MySQL5.6开始对MySQL的底层代码不断的重构完善后在MySQL的主从复制取得极大的进步,且在5.7版本引入主从多线程复制(http://blog.51cto.com/jim123/1961241),而在5.6版本开始MySQL的主从复制就支持slave上延时复制master而不需要借助第三方工具实现,主从复制延时可以在master误删除数据后在slave中延时一定时间后快速找回误删除数据,至于设置

MySQL主从同步(复制)的配置

1.主从复制的原理: *Master,记录数据更改操作 - 启用binlog记录模式 - 允许Slave读取binlog日志 *Slave运行2个同步线程 - Slave_IO:负责连接Master,复制其binlog日志文件到本机的relay-log文件 - Slave_SQL:执行本机relay-log文件里的SQL语句,重现Master的数据操作 2.基本构建思路: 1)初始化现有库:将主库导入从库,确保数据一致性 2)配置Master,主服务器:调整运行参数,授权一个同步用户 3)配置S

mysql主从双机复制备份

由于从机不知道为什么配置了环境变量也不能在从机的mysql文件夹下敲mysql命令,所以以下操作都在Navicat下完成,如果使用mysql命令也是可以的 1.检查主从服务器之间是否互通,如果单一的主从复制不是主主复制,只需要主通从即可,(也可以用Navicat进行数据库连接进行测试,从机能连上主机就可以主从复制) 2.在主库新增一个权限用户grant replication slave on *.* to 'replicate'@'%' identified by '123456'; %指的是