1. 主从复制原理:一般来说主从复制即一个主服务器多个从服务器,分为同步复制和异步复制,实际一般复制中都为异步复制。

2. 复制的基本过程:


1)slave端上面的IO进程连接master,并请求从指定的二进制日志文件的位置(或最新开始的日志)之后的内容;


2)master端接收到来自slave的IO线程后,通过负责复制的IO线程根据请求信息来读取指定日志(bin-log日志)之后的日志信息,返回给salve的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置;


3)slave的IO线程接收到信息后,将接收到的日志内容依次添加到relay-log文件的末端,并将读取到的master端的bin-log的文件名和位置记录到master-info文件中,以便在下次读取的时候能够清楚的告诉master需要从哪块进行复制;


4)slave的sql进程检测到relay-log中增加了新的内容,会解析relay-log的内容成为master端真实执行时候的那些可执行的内容,并在自身执行。


MySQL主从复制的环境: 

 master:192.168.10.155 

 slave:192.168.10.177   192.168.10.188 

 mysql位源码安装的 5.5.22 


 1. 配置master服务器 


 1)编辑master的my.cnf配置文件,设置如下参数: 

 server-id = 1 

 log-bin=mysql-bin 

 binlog_format=mixed(bin日志格式=混合的) 

 log-slave-updates=true 


 2)在master端启动mysql, 

 mysql -uroot -p123456 


 3) 创建一个有复制权限的slave用户进行远程连接salve服务器 

 grant replication slave on *.* to 'slave'@'192.168.10.%' identified by '123456'; 

replication 复制
4) flush privileges; 刷新授权
 

 5)show master status; 

 里面的file对应的mysql-bin.000048(二进制文件,前面的mysql可以进行修改,跟主机名一致)和Position(偏移量)对应的值是slave与master的同步点。 


 2. 配置slave服务器: 


 1)修改slave的mysql配置文件,重启服务。 

 server-id = 2 

 relay-log=relay-log-bin 

 relay-log-index=slave-relay-bin.index 


2)登录mysql,配置同步。
 change master to master_host='192.168.10.200',master_user='slave',master_password='123456',master_log_file='mysql-bin.000051',master_log_pos=107; 

启动从的slave状态:start slave;
3)查看slave的状态:
 show slave status\G; 

 当Slave_IO_Running: Yes,,Slave_SQL_Running: Yes出现连个yes,即说明是正确的。 

 对于Slave_IO_Running: connecting错误的排查: 

 1)网络不通(也可能是防火墙原因) 

 2)授权用户的密码不对 

 3)POS不对,或者bin-log文件不对(可在master上通过 show master status\G;查看) 



 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 



 另外几个常见问题: 

 mysql无法启动:先看错误日志文件中提示的错误,依据错误找原因;查看配置文件中数据目录等配置是否正确;检查MySQL相关目录属主和属组是否正确;查看是否有之前未被正确关闭的mysqld进程仍在运行。 

 mysql无法连接:先看mysqld进程是否正确启动了;再看提供的连接串是否争取无误 


 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 



 若服务器有多台从服务器,需要做主从切换,可以把从服务器进行stop slave,然后修改对应的my.cnf配置文件,把配置文件改成主的配置文件,其他从服务器更改change master即可。 


 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

 如果主服务器已经存在应用数据,则在进行主从复制时,需要做以下处理: 

 (1)主数据库进行锁表操作,不让数据再进行写入动作 

 mysql> FLUSH TABLES WITH READ LOCK; 

 (2)查看主数据库状态 

 mysql> show master status; 

 (3)记录下 FILE 及 Position 的值。 

 将主服务器的数据文件(整个/usr/local/mysql/data目录)复制到从服务器,建议通过tar归档压缩后再传到从服务器解压。 

 (4)取消主数据库锁定 

 mysql> UNLOCK TABLES; 


 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 



 MySQL读写分离可以采用:如果MySQL的读写分离不采用中间件的话,是使用mysql-proxy进行调度的,(mysql-proxy的读写分离是通过rw-splitting.lua脚本实现的,因此需要先安装lua,lua 的获取方式从http://www.lua.org/download.html下载源码包 

 从rpm.pbone.net搜索相关的rpm包 

 download.fedora.redhat.com/pub/fedora/epel/5/i386/lua-5.1.4-4.el5.i386.rpm 

 download.fedora.redhat.com/pub/fedora/epel/5/x86_64/lua-5.1.4-4.el5.x86_64.rpm 

 建议使用源码安装)。 

 mysql-proxy获取网址:http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/ 



 可以参考博客:http://jayluns.iteye.com/blog/2275690 

 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 



 MySQL读写分离的环境: 

 master:192.168.10.155 

 slave:192.168.10.177   192.168.10.188 

 amoeba:192.168.10.200 



 amoeba需要在java环境下运行,并且Java环境最好是jdk1.5或者jdk1.6(因为amoeba框架是基于JavaSE1.5开发的) 



 下载Java的官网:http://www.oracle.com/technetwork/java/javase/downloads/index.html 



 安装Java环境: 
  

 chmod 755 jdk-6u25-linux-i586.bin 

 ./jdk-6u25-linux-i586.bin 

 mv jdk1.6.0_25/ /usr/local/jdk 



 编辑/etc/profile文件: 

 export JAVA_HOME=/usr/local/jdk 

 export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin 

 export AMOEBA_HOME=/usr/local/amoeba 

 export PATH=$PATH:$AMOEBA_HOME/bin 



 让文件profile重启生效:source /etc/profile 



 查看java版本:java -version 



 安装amoeba中间件: 

 mkdir /usr/local/amoeba 

 tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C  /usr/local/amoeba/ 

 chmod -R 755 /usr/local/amoeba/ 

 /usr/local/amoeba/bin/amoeba 

 显示amoeba start|stop及安装成功。 



 在master,slave上给开放权限给amoeba访问。 

 grant all on *.* 'test'@'192.168.10.%' identified by '123456'; 



 amoeba的主要两个配置文件/usr/local/amoeba/conf下的 

 dbServers.xml  #定义连接数据库信息  

 amoeba.xml     #定义读写分离节点管理信息 



 修改amoeba.xml文件的 

 <property name="user">amoeba</property> (30) 

 <property name="password">123456</property> (32) 

 (这块的用户密码是测试时在客户端上通过amoeba代理访问mysql时使用) 



 <property name="defaultPool">master</property> 

 <property name="writePool">master</property> 

 <property name="readPool">slaves</property> 



 修改dbServer.xml文件: 

 <!-- mysql schema --> 

 <property name="schema">test</property> 

 <!-- mysql user  

 <property name="user">root</property> 

 --> 


 <!--  mysql password 

 <property name="password">password</property> 

 --> 


<dbServer name="master"  parent="abstractServer">
 <factoryConfig> 

 <!-- mysql ip --> 

 <property name="ipAddress">192.168.10.155</property> 

 <property name="user">test</property> 

 <property name="password">123456</property> 

 </factoryConfig> 

 </dbServer> 



<dbServer name="slave1"  parent="abstractServer">
 <factoryConfig> 

 <!-- mysql ip --> 

 <property name="ipAddress">192.168.10.177</property> 

 <property name="user">test</property> 

 <property name="password">123456</property> 

 </factoryConfig> 

 </dbServer> 



<dbServer name="slave2"  parent="abstractServer">
 <factoryConfig> 

 <!-- mysql ip --> 

 <property name="ipAddress">192.168.10.188</property> 

 <property name="user">test</property> 

 <property name="password">123456</property> 

 </factoryConfig> 

 </dbServer> 



 <dbServer name="master" virtual="true"> 

 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> 

 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> 

 <property name="loadbalance">1</property> 

 <!-- Separated by commas,such as: server1,server2,server1 --> 

 <property name="poolNames">master</property> 

 </poolConfig> 

 </dbServer> 



 <dbServer name="slaves" virtual="true"> 

 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> 

 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> 

 <property name="loadbalance">1</property> 

 <!-- Separated by commas,such as: server1,server2,server1 --> 

 <property name="poolNames">slave1,slave2</property> 

 </poolConfig> 

 </dbServer> 



 启动amoeba软件: 

 /usr/local/amoeba/bin/amoeba & 



 查看启动端口: 

 netstat -anpt|grep java  (端口为8066) 



 进行测试: 

 在客户端安装mysql: 

 yum -y install mysql 

 通过代理访问mysql: 

 mysql -uamoeba -p123456 -h 192.168.10.200(代理服务器IP) -P8066 



 在master上创建一个表,同步到从服务器,然后关掉从服务器的slave功能,再在主从服务器上插入不同的语句。 



 在客户端进行测试读操作: 

 第一次查询出来的是192.168.10.177上的语句,第二次查询出来的是192.168.10.188上的语句。第三次查询出来又是192.168.10.177上的语句。 



 测试写操作: 

 在client主机上插入一条记录,但是在client上查询不到,只有在master上才能查到。 



 ERROR 1045 (28000): Access denied for user 'zhangsan'@'192.168.10.200' (using password: YES)



报这个错查看库里面对应的user用户以及权限,他从最相应的主机权限进行匹配。


MySQL主从复制的时候,若新添加进来一个slave,用show slave status\G查看时显示都是yes,但是进行测试时同步不了,为啥?
应该还是pos时间点不对或者是show slave status\G再次查看是否有误。