如何设置MySQL同步Replication.docx
- 文档编号:5900863
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:18
- 大小:25.49KB
如何设置MySQL同步Replication.docx
《如何设置MySQL同步Replication.docx》由会员分享,可在线阅读,更多相关《如何设置MySQL同步Replication.docx(18页珍藏版)》请在冰点文库上搜索。
如何设置MySQL同步Replication
∙MySQL提供了数据库的同步功能,这对我们实现数据库的冗灾、备份、恢复、负载均衡等都是有极大帮助的。
本文描述了常见的同步设置方法。
一、准备服务器
由于MySQL不同版本之间的(二进制日志)binlog格式可能会不一样,因此最好的搭配组合是Master的MySQL版本和Slave的版本相同或者更低,Master的版本肯定不能高于Slave版本。
本文中,我们假设主服务器(以下简称Master)和从服务器(以下简称Slave)的版本都是5.0.15,操作系统是LinuxUbuntu5.0.x。
假设同步Master的主机名为:
rep1,Slave主机名为:
rep2,2个MySQL的basedir目录都是/usr/local/mysql,datadir都是:
/usr/local/mysql/data。
二、设置同步服务器
1、设置同步Master
每个同步服务器都必须设定一个唯一的编号,否则同步就不能正常运行了。
接下来开始修改f,增加以下几行:
server-id=1
log-bin
set-variable=binlog-ignore-db=mysql
然后在Master上增加一个账号专门用于同步,如下:
mysql>GRANTREPLICATIONSLAVEON*.*TOrep@rep2IDENTIFIEDBY'rep';
如果想要在Slave上有权限执行"LOADTABLEFROMMASTER"或"LOADDATAFROMMASTER"语句的话,必须授予全局的FILE和SELECT权限:
mysql>GRANTFILE,SELECT,REPLICATIONSLAVEON*.*TOrep@rep2IDENTIFIEDBY'rep';
第三行表示不记录数据库mysql的更新日志,这就避免了Master上的权限设置等被同步到Slave上,如果对这方面没有限制,就可以不设置这个参数。
接下来备份Master上的数据,首先执行如下SQL语句:
mysql>FLUSHTABLESWITHREADLOCK;
不要退出这个终端,否则这个锁就不生效了;接着导出数据,可以直接打包压缩数据文件,也可以使用mysqldump工具来做,推荐前者的方法,这样更为快捷简便。
root$cd/usr/local/mysql
root$tarzcfdata.tar.gz./data(在这里也可能是"var"等其它实际存放数据文件的目录,根据实情而定)
然后将这些数据拷贝到Slave服务器上,解开,设置好正确的权限及属主等;之后,执行"UNLOCKTABLES"语句来释放锁。
2、设置Slave
修改f,增加如下几行:
server-id=2
master-host=rep1#主服务器名
master-user=rep#同步账户名,默认是test
master-password=rep#同步帐户密码,默认是空
master-port=3306#主服务器的TCP/IP端口号,默认是3306
set-variable=replicate-ignore-db=mysql#略过同步的数据库名,如果有多个,请设置多次
set-variable=replicate-do-db=yejr#想要同步的数据库名,如果有多个,请设置多次
接下来在Slave上检验一下是否能正确连接到Master上,并且具备相应的权限。
root$mysql-hrep1-urep-prep
mysql>SHOWGRANTS;
+------------------------------------------------------------------------------+
|Grantsforrep@rep2|
+------------------------------------------------------------------------------+
|GRANTSELECT,FILE,REPLICATIONSLAVEON*.*TO'rep'@'rep2'IDENTIFIEDBY
PASSWORD'*9FF2C222F44C7BBA5CC7E3BE8573AA4E1776278C'|
+------------------------------------------------------------------------------+
现在,可以启动Slave了。
启动成功后,登录Slave,查看一下同步状态:
mysql-hlocalhost-uroot
mysql>SHOWSLAVESTATUS\G
***************************1.row***************************
Slave_IO_State:
Waitingformastertosendevent
Master_Host:
rep1
Master_User:
rep
Master_Port:
3306
Connect_Retry:
60
Master_Log_File:
binlog.000001
Read_Master_Log_Pos:
98
Relay_Log_File:
relay.000003
Relay_Log_Pos:
232
Relay_Master_Log_File:
binlog.000001
Slave_IO_Running:
Yes
Slave_SQL_Running:
Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno:
0
Last_Error:
Skip_Counter:
0
Exec_Master_Log_Pos:
98
Relay_Log_Space:
232
Until_Condition:
None
Until_Log_File:
Until_Log_Pos:
0
Master_SSL_Allowed:
No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master:
0
1rowinset(0.00sec)
可以看到,Slave_IO_Running和Slave_SQL_Running两列的值都为"Yes",这表明Slave的I/O和SQL线程都在正常运行。
至此,同步设定成功。
三、同步设定FAQ
问:
master还在运行中,如何在不停止它的情况下配置slave?
答:
需要设计几个选项参数。
如果已经有了master的备份并且记录了数据快照二进制日志文件名以及偏移位置(运行SHOWMASTERSTATUS查看结果),执行以下步骤:
1.确定slave指定了一个唯一的服务器编号。
2.在slave上执行如下语句,把一些选项值改成实际值:
3.mysql>CHANGEMASTERTO
4.->MASTER_HOST='master_host_name',
5.->MASTER_USER='master_user_name',
6.->MASTER_PASSWORD='master_pass',
7.->MASTER_LOG_FILE='recorded_log_file_name',
->MASTER_LOG_POS=recorded_log_position;
8.在slave上执行STARTSLAVE语句。
如果事先没有备份master的数据,可以用以下方法快速创建一个备份。
以下所有的操作都是在master上。
9.提交语句:
10.mysql>FLUSHTABLESWITHREADLOCK;
11.确保这个锁一直存在,执行以下命令(或者其他类似的):
12.shell>tarzcf/tmp/backup.tar.gz/var/lib/mysql
13.执行以下语句,记录下输出的结果,后面要用到:
14.mysql>SHOWMASTERSTATUS;
15.释放锁:
mysql>UNLOCKTABLES;
上述步骤的另一个办法是创建master的SQL转储文件。
只需在master上执行mysqldump--master-data命令,然后将导出来的SQL转储文件载入slave。
不过,这么做会制作二进制数据快照的方式慢一点。
无论使用上述两种方法的哪种,最后都能创建master的数据快照然后记录二进制日志文件名以及偏移位置。
可以在好几的其他的slave上使用同一个备份的二进制数据快照。
得到master的快照后,只要master的二进制日志完好无损,接着就能开始设置slave了。
两个决定是否需要等待较长时间的限制是:
在master上磁盘空间保存二进制日志,以及slave从master抓取更新事件。
也可以使用LOADDATAFROMMASTER。
这个语句可以很方便地在slave上取得数据快照并且能立刻调整二进制日志文件名以及偏移位置。
在将来,我们推荐用LOADDATAFROMMASTER来设置slave。
警告,它只能用于MyISAM表,并且可能会保持一个较长时间的读锁。
由于它还没达到所期望的高效率,因此如果数据表很大,最好还是在执行完FLUSHTABLESWITHREADLOCK后直接制作二进制数据快照。
问:
是否slave总是需要连接到master?
答:
不,非必需。
slave可以好几小时甚至几天关闭或者不连接master,然后重连再取得更新操作日志。
例如,可以在拨号链接上设置一个mater/slave关系,拨号可能只是零星的不定期的连接。
这种做法隐含的是,在任何指定的时间里,除非使用特殊的度量标准,否则slave不能保证总是能和master保持同步。
在未来,有个选项可以阻止master,除非至少有一个slave在同步中。
问:
怎么知道比master晚了多少?
也就是说,怎么知道slave最后同步的时间?
答:
如果slave是4.1.1或者更高,只需查看SHOWSLAVESTATUS结果中的Seconds_Behind_Master字段。
对于老版本,可以用以下办法。
如果在slave上执行SHOWPROCESSLIST语句结果显示SQL线程(对MySQL3.23则是slave线程)正在运行,这就意味着该线程至少从master读取一个更新操作事件。
详情请看"6.3ReplicationImplementationDetails"。
当SQL线程执行一个master上读取的更新操作事件时,它把自己的时间改成事件的时间(这也就是TIMESTAMP也要同步的原因)。
在
SHOWPROCESSLIST结果中的Time字段中,slave的SQL线程显示的秒数就是最后一次同步的时间戳和slave本机的实际时间相差秒数。
可以根据这个值来判断最后同步的时间。
注意,如果slave已经从master断开好几个小时了,然后重新连接,就能看到slave的
SHOWPROCESSLIST结果中的SQL线程的Time字段的值类似3600。
这是因为slave正在执行一个小时前的语句。
问:
如何强制master在slave赶上全部更新之前阻止更新操作?
答:
执行以下步骤:
16.在master上,执行以下语句:
17.mysql>FLUSHTABLESWITHREADLOCK;
mysql>SHOWMASTERSTATUS;
记录下结果中的日志文件名以及偏移位置,它们是同步的坐标值。
18.在slave上,提交以下语句,MASTER_POS_WAIT()函数的参数的值就是前面取得的同步坐标值:
19.mysql>SELECTMASTER_POS_WAIT('log_name',log_offset);
SELECT语句会阻止更新,直到slave同步到了上述日志文件及位置。
在这个时候,slave就和master保持同步了,并且这个语句就会返回。
20.在master上,执行以下语句允许master重新处理更新操作:
mysql>UNLOCKTABLES;
问:
设置一个双向复制时要注意什么问题?
答:
MySQL同步目前还不支持任何在master和slave上的分布式(跨服务器)更新锁协议以保证操作的原子性。
也就是说,存在这样的可能性:
客户端A在并存的master1上做了一个更新,同时,在它同步到并存master2上之前,客户端B在master2上可能也做了一个和客户端A在master1上不同的更新操作。
因此,当客户端A所做的更新同步到master2时,它将产生和master1上不同的数据表,尽管master2上的更新操作也全都同步到master1上去。
这意味着除非能确保所有的更新都能以任何顺序安全地执行,否则不要使用双向同步,或者除非注意在客户端程序中的不知原因的无序更新操作。
同时也要意识到在所关心的更新问题上,双向同步实际上并不能很大地改善性能(甚至没有)。
两个服务器都需要执行同样数量的更新操作,在一台服务器上也是。
唯一区别的是,可能这样做会减少一些锁争夺,因为来自其他服务器的更新操作都会被串行地放到slave线程中。
甚至这种好处还可以作为网络延迟的补偿。
问:
我如何利用同步来提高系统性能?
答:
需要安装一个服务器作为master并且把所有的写操作直接放在这上面。
然后配置多个廉价的使用机架磁盘的slave,把读操作分配给master和slave。
还可以在启动slave时使用--skip-innodb,--skip-bdb,--low-priority-updates,和--delay-key-write=ALL选项来提高slave端的性能。
这种情况下,slave会使用非事务的MyISAM表来代替InnoDB和BDB表,已取得更快速度。
问:
如何准备客户端应用程序的代码来适应同步应用?
答:
如果代码中负责存取数据库的部分已经被合理地抽象化/模块化了,将它们转化成适用运行于同步环境中将会很平滑和简单。
只需要修改数据库存取实现部分,把所有的写操作放到master上,把所有的读操作放到master或者slave上。
如果你的代码还没达到这个层次的抽象化,那么这将成为整理代码的机会和动机。
可以使用类似以下函数创建封装类库或者模块:
osafe_writer_connect()
osafe_reader_connect()
osafe_reader_statement()
osafe_writer_statement()
每个函数名的safe_表示它们会处理所有的错误情况。
可以使用其他函数名。
重要的是,要为读连接、写连接、读、写定义好统一的接口。
然后将客户端代码转换成使用封装的类库。
已开始可能是很痛苦且麻烦的,不过在将来长期运行中就能得到回报了。
所有使用上述方法的应用程序都会在master/slave配置中有优势,即使包含多个slave。
这些代码将很容易维护,一些额外的麻烦也会很少。
自豪需要修改一个或者两个函数;例如,想要记录每个语句执行了多长时间,或者在上千个语句中哪个出现错误了。
如果已经写了很多代码,你可能想要自动转换它们,那么可以使用MySQL发布的replace工具,或者自己写转换脚本。
理想地,你的代码已经使用了统一的编程风格。
如果不是,最好重写它们,或者可以遍历检查一下,手工规范化一下代码风格。
问:
MySQL同步何时且有多少能提高系统性能?
答:
MySQL同步对于频繁读但不频繁写的系统很有好处。
理论上来讲,使用单一master/多slave的配置,就可以通过这个方法来衡量系统:
增加更多的slave直到用完所有的网络带宽或者master的更新操作增长到了不能再处理的点了。
想要知道增加多少个slave之后得到的性能才能平稳,以及能提高多少性能,就需要知道查询模式,并且根据经验对典型的master和slave做读(每秒读或max_reads)和写(max_write)基准测试得到它们之间的关系。
下例展示了一个理想系统取得的性能的简单计算方法。
设定系统负载由10%写和90%读组成,我们已经通过基准测试确定max_reads是1200-2*max_writes。
换句话说,系统可以达到每秒做没有写的1200次读操作,写操作平均是读操作的2倍慢,它们之间的关系是线性的。
让我们假设master和每个slave都有同样的容量,有一个master和N个slave。
每个服务器(master或slave):
reads=1200-2*writes
reads=9*writes/(N+1)(读是分开的,但是所有写是在所有的服务器上的)
9*writes/(N+1)+2*writes=1200
writes=1200/(2+9/(N+1))
最后的等式说明了N个slave的最大写数量,给它每分钟的最高读频率1200和1次写9次读的机率。
分析结论比率如下:
o如果N=0(意味着没有同步),系统大致可以处理每秒1200/11=109次写。
o如果N=1,增加到每秒184次写。
o如果N=8,增加到每秒400次写。
o如果N=17,增加到每秒480次写。
o最终,随着N接近无穷大(我们的预算为负无穷大),则可以达到几乎每秒600次写,大约提高系统吞吐量5.5倍。
尽管如此,当有8台服务器时,已经提高了4倍了。
注意,上面的计算是假设了网络带宽无穷大,并且忽略了一些系统中比较大的因素。
在很多情况下,当系统增加N个同步slave之后,是无法精确计算出上述预计结果的。
不过,先看看下列问题将有助于你知道是否有和有多少系统性能上的改善:
o系统读/写得比率是多少?
o减少读操作后一个服务器能增加处理多少写操作?
o你的网络带宽足够给多少slave使用?
问:
如何利用同步提供冗余/高可用性?
答:
使用当前已经可用的特性,可以配置一个master和一个(或多个)slave,并且写一个脚本监控master是否运行着。
然后通知应用程序和slave在发现错误时修改master。
一些建议如下:
o使用CHANGEMASTERTO语句告诉slave修改master。
o一个让应用程序定位master所在主机的办法就是给master使用动态DNS。
例如bind就可以用`nsupdate`来动态更新DNS。
o使用--log-bin选项,不使用
--log-slave-updates选项来启动slave。
这样就能让slave运行STOPSLAVE;RESETMASTER语句后随时准备变成master,并且在其他slave上运行
CHANGEMASTERTO。
例如,有以下配置方案:
oWC
o\
ov
oWC---->M
o/|\
o/|\
ovvv
oS1S2S3
M表示masetr,S表示slave,WC表示提交读写操作的客户端;只提交读操作的客户端没有表示出来,因为它们无需切换。
S1,S2,S3都是使用
--log-bin选项,不用--log-slave-updates选项运行的slave。
由于除非指定--log-slave-updates参数,否则从master读到的更新操作都不会记录到二进制日志中,因此每个slave上的二进制日志都是空的。
如果因为某些原因M不能用了,可以指定一个slave作为master。
例如,如果指定S1,则所有的WC都要重定向到S1上,S2和S3都需要从S1上同步。
确定所有的slave都已经处理完各自的中继日志了。
在每个slave上,提交STOPSLAVEIO_THREAD语句,然后检查SHOWPROCESSLIST的结果直到看到Hasreadallrelaylog了。
当所有的slave都这样子之后,就可以按照新的方案设置了。
在slaveS1上提交
STOPSLAVE和RESETMASTER语句将其提升为master。
在其他slaveS2和S3上,提交STOPSLAVE和CHANGEMASTER
TOMASTER_HOST='S1'('S1'代表S1的真实主机名)语句修改master。
把S2,S3如何连接到S1的参数(用户,密码,端口等)都附加到CHANGEMASTER后面。
在
CHANGEMASTER中无需指定S1的二进制日志文件名和偏移位置:
因为CHANGEMASTER默认就是第一个二进制日志和偏移位置4。
最后,在S2和S3上提交STARTSLAVE语句。
然后让所有的WC都把他们的语句重定向到S1上。
从这个时候开始,从所有的WC发送到S1上的更新语句都会写到S1的二进制日志中,它们包含了从M死掉之后发送到S1的全部更新语句。
配置结果如下:
WC
/
|
WC|M(unavailable)
\|
\|
vv
S1<--S2S3
^|
+-------+
当M又起来了之后,只需在M上提交和在S2和S3上的一样的CHANGEMASTER语句,将它变成一个slave并且读取自从它死掉之后的全部WC提交的更新操作。
想要把M重新变成master(例如因为它的性能更好),就执行类似上面的操作,把S1当作失效了,把M提升为新的master。
在这个步骤中,别忘了在把S2和S3修改成为M的slave之前在M上运行RESETMASTER语句。
否则的话,它们会从M开始失效的那个时刻开始读取WC提交的更新操作日志。
现在我们就运行着一个完整的自动选择master的MySQL同步系统,不过在它准备好之前,需要创建自己的监控工具。
6.10同步疑难解答
如果按照上述步骤设定好同步之后,它不能正常工作的话,首先检查以下内容:
o查看一下错入日志信息。
不少用户都在这方面做得不够好以至于浪费时间。
omaster是否在记录二进制日志?
用SHO
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 如何 设置 MySQL 同步 Replication