预达到的效果:一台主mysql服务器上的数据改变了,从属服务器上的数据也自动做相同的改变
原理:从属服务器在主服务器上注册一个账户,通过这个账户,把对主服务器的增删改操作而生成的二进制日志文件发送给从属服务器,
从属服务器根据这个二进制日志来进行增删改,达到同步数据的效果。
小细节:从属服务器会指定两个线程,一个来请求和接收发送来的二进制日志;一个用来将二进制日志转换成中继日志
(先不管什么是中继日志,就是日志的一种,专门给从属服务器用的),
然后根据中继日志转换成相应的sql语句,在从服务器上执行,从而达到数据同步的效果
参数对比说明:
虚拟机
(1)用vmware的net默认配置方式安装两台centos 5.5
(2)用rpm包安装5.1.54版本的mysql
(3)通过关闭selinux和防火墙,使两台mysql能互通(telnet 192.168.80.* 3306)
主:192.168.80.135 从:192.168.80.136
主:
1. 创建账户并授予权限:
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'bak'@'192.168.80.136' IDENTIFIED BY'123456';
2.从数据库登录主数据库测试
mysql>mysql -h192.168.80.135 -ubak -p123456
配置文件设置
server_id = 1 log_bin = mysql-bin log_bin_index = mysql-bin.index sync_binlog = 1 max_binlog_size = 200M
binlog_do_db = db_1
binlog_do_db = db_2
......
binlog_ignore_db = db_x
binlog_ignore_db = db_y
......
server_id 服务器ID,不要和别的服务器冲突了,练习时主服务器一般设置为1,以区别其它服务器
log_bin 显式的指定二进制日志的文件名(其它的文章中说的‘开启’就是去掉改行前面的‘#’号,其后如果什么都不写,
二进制日志文件就默认存放在数据库存放的路径里,并以主机名为默认文件名,如果指定的文件名写后缀了,
mysql就会忽略,总的来说此选项很随意,只要去掉‘#’号就行了,)此选项的路径和文件名设置不必和从服务器保持一致,
从服务器可以没有关闭此选项
log_bin_index 上一个选项会生成一系列的文件(文件名.六位数字:e.g. hostname.000001),
这个选项将生成另一个mysql约定后缀名的文件,他记录上个选项生成的所有文件的文件名字,
也不是很重要,也不必和从服务器保持一致,此选项和上一个选项配套使用,也可以不开启
sync_binlog 设为1就是把MySql每次发生的修改和事件的日志即时同步到硬盘上
max_binlog_size 指定二进制日志的大小
binlog_do_db 指定主服务器要配分的数据库名字,注意1:开头是binlog,从服务器此项设置的开头是replicate
注意2:要同步的数据库不要写成一行(反正我没成功,不知道怎么回事),有几个写几行,前后顺序无关,无须和从服务器上这个设置一一对应
binlog_ignore_db 无需同步的数据库,设置和注意点跟上一项的一样
mysql在启动时才读取配置文件,因此修改了配置文件就得重启mysql服务 service mysql(mysqld)restart
从:
server_id = 2 relay_log = mysql-relay-bin relay_log_index = mysql-relay-bin.index max_binlog_size = 200M slave-skip-errors = 1062,1053 skip_slave_start = 1 replicate_do_db = db_1
replicate_do_db = db_2
......
replicate_ignore_db = db_x
replicate_ignore_db = db_y
relay_log 中继日志,从服务器专用的,我理解相当于缓冲,
主服务器的二进制日志-->一系列从服务器中继日志-->一个一个读取中继日志-->还原成sql语句执行-->同步
slave-skip-errors 在复制过程中忽略一些错误,让复制继续进行,在这里忽略了1062和1053号错误,
如果要忽略所有错误就设成all,一旦出错同步就停止,可以用show salve status \G来查看最后一条错误,
然后手动修改(e.g. id字段是自增的,主mysql中插入一条id=2,从中如果由于种种原因已经有了id=2,
那么就会出错而停止同步,就是上面提到的那个读中继日志的线程会停止)、
重新启动salve(change master to ....;start slave)
skip_slave_start 防止从服务器在崩溃后自动开启,以给你足够的时间修复。(也有一种说法:告诉从服务器当服务器启动时不启动从服务器线程。使用START SLAVE语句在以后启动线程。)
一些命令:(使用这些命令最好有super权限)
主:show master status ; 查看主服务器正在把信息写在哪个二进制日志文件中,以及偏移位置(我也很模糊,好像是个时间戳的标记)
show processlist;
从:show slave status \G 查看从服务器的状态,信息较多但比较容易明白,里边有读取的主服务器的二进制信息和正在使用的中继日志的信息,
上面提到的两个线程状态,最后一次错误的信息等等
stop slave; 停止监听主服务器的信息
change master to ......; 动态设置配置信息,告诉从服务器去同步那台数据库的数据,也可以固定的写在从服务器的配置文件中,
此时会默认在数据库存放的路径里生成一个master.info 的文件,每次mysql启动时读取,
因此一旦出错或需要改变某些设置,就得重启服务器,删除master.info让其重新生成
start slave; 开始监听主服务器的数据
命令的使用:
先在主服务器上使用show master status ;记录正在使用的日志文件名和偏移位置
而后在从服务器上 change master to (一堆参数,告诉从服务器连接哪个主服务器,使用哪个日志文件)
----------------------------------------
还有些参数没弄明白,随后更新
突然看到一篇很详细的文章: http://www.litvip.com/2011/06/01/291
在某些情况下,会出现从服务器更新失败,首先需要确定是否从服务器的表与主服务器的不同造成的,如果是表结构造成的,则需要修改从服务器的表和主服务器一致,然后重新运行start slave
如果不是表结构不同造成的更新失败,则需要确认手动更新是否安全,然后忽视来自主服务器的更新失败语句,跳过来来自主服务器的语句,命令为SET GLOBAL SQL_SLAVE_SKIP_COUNTER=n,其中,n=1表示来自主服务器的更新语句不使用AUTO_INCREMENT或LAST_INSERT_ID(),n=2时则反之,原因是使用AUTO_INCREMENT或LAST_INSERT_ID的语句需要从二进制日志中取得两个事件.
select master_pos_wait('mysql-bin.000004','102');
这个select 语句会阻塞直到从服务器达到指定日志文件和偏移量后,返回0,如果是-1,则表示超时推出,查询是0时,表示从服务器与主服务器已经同步(http://www.blogjava.net/dongbule/archive/2010/08/23/329714.html)
如果从服务其开启了二进制日志(以便他有朝一日也能做主服务器),从服务器并不会主动把上面提到的线程执行的sql语句行为写入到二进制中,要是这个从服务器也做了主,那么就要开启logs-slave-updates设置来让从服务器记录下所有的数据变化
配置文件中有关主从同步一些设置
http://hi.baidu.com/dc_life/item/d5e92ef7317acb40932af258
http://www.blogjava.net/dongbule/archive/2010/09/04/331050.html
如何切换主从角色和其他一些没涉及到的知识点
http://yyl-211.blog.163.com/blog/static/9348961201010173153872/