MySQL的Replication是一种多个MySQL的数据库做主从同步的方案,特点是异步,广泛用在各种对MySQL有更高性能,更高可靠性要求的场合。与之对应的另一个技术是同步的MySQL Cluster,但因为比较复杂,使用者较少。

下图是MySQL官方给出了使用Replication的场景:
Mysql之replication初探_第1张图片


Replication原理
   
Mysql 的 Replication  是一个异步的复制过程,从一个MySQL节点(称之为Master)复制到另一个MySQL节点(称之Slave)。在 Master 与 Slave  之间的实现整个复制过程主要由三个线程来完成,其中两个线程(SQL 线程和 I/O 线程)在 Slave 端,另外一个线程(I/O 线程)在  Master 端。
   
要实现 MySQL 的 Replication ,首先必须打开 Master 端的 Binary Log,因为整个复制过程实际上就是 Slave 从 Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。
   
看上去MySQL的Replication原理非常简单,总结一下:
    * 每个从仅可以设置一个主。  
    * 主在执行sql之后,记录二进制log文件(bin-log)。  
    * 从连接主,并从主获取binlog,存于本地relay-log,并从上次记住的位置起执行sql,一旦遇到错误则停止同步。  
    
从这几条Replication原理来看,可以有这些推论:
    * 主从间的数据库不是实时同步,就算网络连接正常,也存在瞬间,主从数据不一致。  
    * 如果主从的网络断开,从会在网络正常后,批量同步。  
    * 如果对从进行修改数据,那么很可能从在执行主的bin-log时出现错误而停止同步,这个是很危险的操作。所以一般情况下,非常小心的修改从上的数据。  
    * 一个衍生的配置是双主,互为主从配置,只要双方的修改不冲突,可以工作良好。  
    * 如果需要多主的话,可以用环形配置,这样任意一个节点的修改都可以同步到所有节点。  




主从设置
1. MySQL主从应用场景

原理是master上数据更新时会记录一个bin-log,slave会实时同步该bin-log然后slave根据bin-log的sql语句进行相应的操作。
MySQL主从可以实时备份,保证数据高安全性
可以应用在读写分离的场景中,用以降低单台MySQL服务器的I/O
可以实现MySQL服务的HA集群
可以是1主多从,也可以是相互主从(主主)


2. 安装、配置MySQL
参考之前步骤搭建MySQL服务


3. 配置主从准备工作

在主上创建测试库:
建立测试用数据库|表
#myslq –u root –p
mysql>create database ocean;
mysql>use ocean;
mysql>create table test1(id int,sname char(8));
mysql>insert into test1 values(1,’zhangsang’);



4. 配置主(master)
vim ./my.cnf   #修改或添加:
server-id=1
log-bin=mysql-bin 
两个可选参数(2选1):
binlog-do-db=ocean        #需要同步的库【多个库之间用,分隔】
binlog-ignore-db=ocean    #忽略不同步的库
修改配置文件后,重启mysql
pid=`ps uax |grep mysql.sock |grep -v grep |awk '{print $2}'` ; kill $pid; cd /usr/local/mysql_2/bin/; ./mysqld_safe --defaults-file=../my.cnf --user=mysql &
 
Master 授权给Slave
grant replication slave on *.* to 'ocean'@'192.168.9.10' identified by 'ocean';
flush tables with read lock;  #锁住表,防止数据写入,slave配置完成后记得解锁
flush privileges;             #刷新
show master status;           #一定要记住前两列的内容,一会会用到
mysql> show master status;
+----------------------+----------+--------------+------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------------+----------+--------------+------------------+
| mysql-bin-log.000028 |      330 | mysql        |                  |
+----------------------+----------+--------------+------------------+
1 row in set (0.00 sec)


5. 设置从(slave)
vim my.cnf  #修改或增加
server-id = 2 #这个数值不能和主一样
可选参数:
replicate-do-db=ocean,ocean2 和 replicate-ignore-db=ocean,ocean2 #意义同主的那两个可选参数
service mysqld restart
拷贝主的db1库数据到从:
然后导出主的mysql库数据然后导入给slave mysql
mysqldump -uroot -p mysql > ocean.sql
在salve 中将数据导入到新创建的数据库中
mysql -uroot -p -e "create database ocean"; mysql -uroot -p  ocean < ocean.sql


mysql -uroot -p  #登陆Slave的mysql
slave stop;

change master to master_host='192.168.9.9', master_port=3306 ,master_user='ocean',
master_password='ocean', master_log_file='mysql-bin-log.000028', master_log_pos=330;
 
slave start;

Master上: mysql -uroot -p -e "unlock tables"
Slave查看从的状态:mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.9.9
                  Master_User: ocean
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin-log.000028
          Read_Master_Log_Pos: 330
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 255
        Relay_Master_Log_File: mysql-bin-log.000028
           Slave_IO_Running: Yes
         Slave_SQL_Running: Yes
              Replicate_Do_DB: ocean
          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
                 .....



6. 测试主从
在Master中ocean数据库中插入一条记录:
mysql>use ocean;
mysql>insert into test1 values(2,'lisi');
在slave中查看oceanDB是否有新纪录生成。

建议: MySQL主从机制比较脆弱,谨慎操作。如果重启master,务必要先把slave停掉,也就是说需要在slave上去执行 slave stop 命令,然后再去重启master的mysql服务,否则很有可能就会中断了。当然重启完后,还需要把slave给开启 slave start.