MySQL主从复制有利于数据库架构的健壮性、提升访问速度和易于维护管理。主要有主从服务器互为备份、主从服务器读写分离分担网站压力、三个应用场景
主从服务器架构的设置,可以大大的加强数据库架构的健壮性。当主服务器出现问题后,可以人工或自动的切换到从服务器上继续提供服务。类似于nfs存储通过inotify +rsync同步到备份nfs 上,只不过MySQL的同步,是其自带的工具。对非人为的硬件、服务故障,人为的执行drop、delete 无能为力。
主从服务器架构可以通过程序(PHP、Java等)或代理软件(mysql-proxy、amoeba等)对用户(客户端)的请求实现读写分离,即通过在从服务器上仅仅处理用户的Select查询请求,降低用户查询响应时间及读写同时在主服务器带来的压力。对于更新的数据(Update、Insert、Delete)仍然交给主服务器处理,确保主服务器和从服务器保持实时同步。
在MySQL实现主从同步后,企业读写分离实现方式:
中大型公司:通过PHP、Java等程序
测试环境: mysql-proxy、amoeba等代理软件
门户网站:分布式dbproxy实现读写分离、hash负载均衡、健康检查(百度、阿里都自行开发)
可以把几个不同的从服务器,根据企业业务进行拆分。如有提供查询的从服务器、有DBA备份的从服务器、还有提供内部人员访问的后台、脚本、日志分析及开发人员服务的从服务器。可以有效的减轻主服务器的压力的同时,使各个业务之间互不影响。
配置好从库复制所需的帐户(需replication slave权限)。
必须开启binlog日志,如有数据更新,则会在将数据写入数据库的同时,将更新结果也写入binlog文件中。
会生成一个I/O线程,用来接收从库I/O线程的请求,并给从库I/O线程传binlog。
必须先通过CHANGE MASTER TO命令配置Master信息:将Master的host、user、password、port、binlog文件名以及位置点进行配置,生成master.inof文件。以便从库读取,并连接上主库。
如果在备份命令中加了--master-data=1,则备份文件中会带有binglog文件名和位置点信息,在master.info文件中就不需要指定文件名以及位置点了。
开启同步的开关:start slave。此时,生成两个线程,一个I/O线程,一个SQL线程。I/O线程去请求主库的binlog,并将得到的binlog日志写到relay log(中继日志)文件中。SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致。
在Master服务器开启binlog和配置好从库复制所需的帐户,Slave服务器配置好master.info文件后,MySQL Replication的复制过程步骤如下:
(1)Slave服务器的执行start slave,开启主从复制开关,产生IO Thread和SQL Thread线程。
(2)此时,Slave服务器的IO线程会根据 master.info文件的内容请求连接Master服务器,并请求Master服务器发送指定binlog日志文件的指定位置点之后的binlog日志。
(3)Master服务器接收到Slave服务器的IO线程的请求后,Master服务器首先进行验证,验证通过后负责复制的IO线程根据Slave的IO线程请求读取指定的binlog日志文件的指定位置之后的binlog日志信息,连同本次返回日志内容后在Master服务器上的新的binlog文件名以及下一个指定更新的位置点一起发送给Slave服务器的IO线程。
(4)Slave服务器的IO线程接收到信息后,将binlog日志内容依次写入到中继日志(Relay Log)文件的最末端(MySQL-relay-bin.xxxxxx),将将新的binlog文件名和位置记录到master.info文件中,以便一下次从新的位置读取。
(5)Slave服务器的SQL线程会实时检测到本地Relay Log中新增加的日志内容,如有更新,则及时把Relay Log文件中的内容解析为在Master上执行过的SQL语句,按顺序在Slave服务器上执行。并在应用完毕后清理应用过的日志。
(6)经过上面步骤后,一般可以确保在Master和Slave上执行同样的SQL语句。在正常情况下可以保证Master和Slave上的数据完全一样。
一般情况下Slave服务器在应用复制过来的binlog日志信息时是不写入Slave端的binlog日志文件的。但如果是级联复制的话,Slave服务器还要将数据复制到下一级Slave服务器,则需要将应用的binlog日志内容写入自身的binlog文件中,以便进行复制。此时,需在第一级Slave服务器上修改my.cnf文件,启用binlog日志,并打开log_slave_update参数,则可将应用的日志内容写入binlog文件中。
(1)启动2台MySQL库(单、多实例均可)。
(2)配置my.cnf文件(配置参数后要重启生效)。主库配置bin-log和server-id参数,从库配置server-id,从库除了再做备份或的主从的主库外,一般不会开启bin-log。
(3)在主库上增加用于从库连接的帐户,并授replication slave的权限。
(4)在主库,整库锁表(窗口关闭后就失效,超时参数到了也失效)。通过showmaster status查看binlog的位置状态。
(5)在主库新开窗口进行备份,并将备份拷贝到从库。如果数据量很大且允许停机,则可以停机打包,而不用mysqldump。
(6)解锁主库:unlock tables;
(7)在从库进行还原操作。
(8)根据主库的show master status查看binlog的位置状态,在从库执行change master to语句
(9)在从库开启同步开关:start slave;
(10)在从库检查同步状态:show slave status\G; 并在主库进行更新测试。
(1)异步方式同步
(2)逻辑同步模式(binlog有三种模式:SQL、混合、rowlevel),默认是通过SQL语句执行
(3)主库通过记录binlog实现对从库的同步
(4)主库1个线程(IO线程),从库2个线程(IO和SQL)来完成
(5)从库的关键文件:master.info、relay-log、relay-info
(6)如果从库还想级联从库,需打开log-bin和log-slave-updates参数
(1)安装好要配置从库的数据库,配置好log-bin和server-id参数。
(2)无需配置主库的my.cnf文件,主库的log-bin和server-id参数默认就是配置好的。
(3)登陆主库增加用于从库连接的帐户,并授replication slave的权限。
(4)半夜使用mysqldump带--master-data=1参数全备主库,并在从库进行恢复。
(5)在从库执行change master to 语句,无需binlog文件及对应位置点。
(6)在从库开启同步开关start slave。
(7)从库show slave status\G,检查同步状态,并在主库进行更新测试。
(1)主从库服务器的配置差距不要太大。
(2)撰写方案文档和实施步骤。如可能需要停机维护,需要事先申请停机维护时间。
mysql> show processlist;
+----+------+-------------------+------+-------------+-------+-------------------
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-------------------+------+-------------+-------+------------------
| 2 | rep |192.168.1.2:13798|NULL|BinlogDump| 84015 | Masterhas sent all binlog to slave; waiting for binlog to be updated |NULL |
| 3 | root | localhost | NULL | Query | 0 | NULL | showprocesslist |
+----+------+-------------------+------+-------------+-------+------------------
mysql> show processlist;
+----+-------------+-----------+------+---------+--------+-------------------
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+------+---------+--------+-------------------
|6|system user| |NULL|Connect|172446| Waiting for masterto send event |NULL|
|7| system user| | NULL | Connect | 84468 | Slave has read all relay log; waiting for the slave I/Othread to update it | NULL |
|8| root | localhost | NULL | Query | 0 | NULL show processlist |
+----+-------------+-----------+------+---------+--------+-------------------
主库的IO线程(Command列为BinlogDump)的State列常见有以下4种状态,如果没有看见任何Binlog Dump线程,这说明在主库上的复制没有运行。目前也没有连接任何从服务器。
a、Sending binlog eventto slave
表示线程已经从二进制日志读取了一个事件并且正将它发送到从库。
b、Finished readingon binlog; switching to next binlog
表示线程已经读完二进制文件,并且正打开下一个要发送到从库的日志文件
c、Has sent allbinlog to slave;waiting for binlog to be updated
表示线程已从二进制日志读取了所有主要的更新并已发送到从库。线程正在空闲,等待主库上新的更新日志。
d、Waiting tofinalize termination
表示线程停止时发生的一个很简单的状态。
从库IO线程的State列常见有下面5种状态,该状态也出现在Slave_IO_State列,由show slave status显示。
a、Connecting tomaster
表示线程正试图连接主库。
b、Checking masterversion
表示线程检查主库版本。
c、Registering slaveon master
表示线程在主库注册
d、Requesting binlogdump
表示线程请示binlog dump。线程向主库发送一条请求,索取从请求的二进制日志文件名和位置开始的日志内容。
e、Waiting toreconnect after a failed binlog dump request
表示线程请求失败,进入睡眠状态,等待请求重连。可以通过--master-connect-retry选项指定重试的间隔。
f、Reconnectingafter a failed binlog dump request
表示线程正在请求重连主库。
g、Waiting formaster to send event
表示线程等待主库发送日志。
h、Queueing masterevent to the relay log
表示线程已读取到一个日志,正将其复制到中继日志供SQL线程来处理。
i、Waiting reconnectafter a failed master event read
表示线程读取时,由于没有连接而出现错误,线程将睡眠指定的秒数。
j、Reconnectingafter a failed master event read
表示线程正在尝试重连主库,当连上后状态将变为Waiting for master to send event。
k、Waiting for theslave SQL t