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再次查看是否有误。