一个MySQL不能响应更多请求时,我们可以考虑主从复制,写都到主服务器,读都到从服务器上,这样可以增加并发响应能力,关于前端的读写分离先不讨论,我们先来构建一个MySQL的主从同步架构吧!

实验环境:RHEL5.8  SELinux已经关闭,MySQL5.5.28tar包初始化安装(非编译)
规划:
  1. master 172.16.1.18  hostname:master.laoguang.me 
  2. slave 172.16.1.19   hostname:slave.laoguang.me 
一.配置主服务器
1.1 主服务器安装mysql,见http://laoguang.blog.51cto.com/6013350/1039208
1.2 修改/etc/my.cnf
  1. [mysqld] 
  2. server-id       = 1    ##此id必须全局唯一 
  3. sync_binlog = 1        ##为了减少延迟,让二进制日志同步写到磁盘,性能会有所降低 
  4. #log-bin = 1           ## 二进制日志默认是开启的,如果你的没开启,请启用这个 
  5. log-bin = mysql-bin 
  6. innodb_flush_log_at_trx_commit=1 ##事务日志立刻刷写到磁盘 
1.3 启动mysqld
  1. service mysqld start 
1.4 创建一最少权限账号,仅用于同步
  1. create user 'backup'@'172.16.1.19' identified by 'redhat'; 
  2. revoke all privileges,grant option from 'backup'@'172.16.1.19'; 
  3. grant replication client,replication slave on *.* to 'backup'@'172.16.1.19'; 
二.从服务器设置
2.1 安装mysql 
2.2 修改/etc/my.cnf
  1. [mysqld] 
  2. server-id = 2           ##id必须全局唯一 
  3. relay-log = mysql-relay ##开启中继日志,不指定目录默认在数据目录下        
  4. relay-log-index = mysql-relay.index  ##中继日志索引 
  5. read-only = 1           ##从服务器一般用户只读 
  6. #replicate_do_db = 'db_name' ##只同步某db_name库 
  7. #rpplicate_ignore_db = 'db_name' ##不同步db_name库 
  8. #replicate_do_table = 'tb_name' ##只同步tb_name表 
  9. #replicate_ignore_table = 'tb_name' ##不同步tb_name表 
  10. #replicate_wild_do_table = 'name%' ##通配同步,如只同步name开头的 
  11. #replicate_wild_ignore_table = '_name' ##通配不同步,不同步第一个字符是任意字符后面跟的是name的表或库 
2.3 启动Mysqld
  1. service mysqld start 
三.从服务器连接主服务器
  1. mysql> change master to master_host='172.16.1.18'
  2.     -> master_user='backup'
  3.     -> master_password='redhat'
  4.     -> master_log_file='mysql-bin.000001'
  5. mysql> start slave   
  6. mysql> show slave status\G; 
如果显示Slave_IO_Running: Yes  Slave_SQL_Running: Yes Last_IO_Errno: 0 表示启动成功
这时在你的数据目录(我的为/data/mydata)中会生成中继日志与中继索引,还有连接主的信息文件master.info
四.在主服务器上建立一个库,查看能否同步到从库上
  1. mysql> create database testsycn; ##主库上建立  
  2. mysql> show databases;           ##从库上查看,如果有证明建立成功 
一个主从复制服务器构建起来了,如果你的主服务器已经运行很长一段时间了,这样简单的同步是不行的,一是因为可能会流量大 二是因为主服务器的二进制日志已经不完全都在了,所以我们要先完整备份一下主服务器,然后在从服务器上恢复并指定完整备份时的主服务器的二进制日志位置,也就是change master 时添加一项 master_log_pos=n,n代表的是完整备份时主服务器处于的二进制日志位置,其它的与上述一致。
五.基于google的补丁semisync实现半同步主从复制
mysql默认主从复制是异步的,异步是指主服务器的负责把二进制日志进程dumpthread接收到从服务器进程iothread的同步请求时,将二进制日志放到tcp的发送序列上就返回完成信号。异步模式可能导致从服务器延迟太多,假如主服务器挂点,从服务器由于延迟多导致数据不完整。半同步模式是指主服务器的二进制日志已经由dumpthread发送给从服务器的iothread,并且iothread把它存入中继日志中,从服务器的sqlthread把该日志记录应用到数据库,这时发送给主服务器一个信号,主服务器进程收到信号后才返回完成信号,有同学问了这不是同步模式吗,怎么叫半同步了?这是因为
当从服务器有多台时,有一台服务器返回信号,主服务器就认为复制完成。
5.1 主服务器设置:加载semisync补丁
  1. mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; ##加载这个补丁 
  2. mysql> show variables like '%semi%';   ##查看新增补丁后的新系统变量,由此可知模块功能没有启用 
  3. +------------------------------------+-------+ 
  4. | Variable_name                      | Value | 
  5. +------------------------------------+-------+ 
  6. | rpl_semi_sync_master_enabled       | OFF   | 
  7. | rpl_semi_sync_master_timeout       | 10000 | 
  8. | rpl_semi_sync_master_trace_level   | 32    | 
  9. | rpl_semi_sync_master_wait_no_slave | ON    | 
  10. +------------------------------------+-------+ 
  11. mysql> set global rpl_semi_sync_master_enabled=on
  12. ---------------不是很华丽的分隔---------------
  13. 如果想长期有效写入/etc/my.cnf
  14. [mysqld]
  15. rpl_semi_sync_master_enabled=1 ##启用模块
  16. rpl_semi_sync_master_timeout=10000##主库等待半同步复制信息返回的超时间隔,单位毫秒,超过间隔降级为异步模式
  17. rpl_semi_sync_master_wait_no_slave=On ##联系不上从服务器也会等待timeout,默认开启可不写
  18. ---------------不是很华丽的分隔---------------

  1. mysql> show status like '%semi%';     ##查看状态 
  2. +--------------------------------------------+-------+ 
  3. | Variable_name                              | Value | 
  4. +--------------------------------------------+-------+ 
  5. | Rpl_semi_sync_master_clients               | 0     | 
  6. | Rpl_semi_sync_master_net_avg_wait_time     | 0     | 
  7. | Rpl_semi_sync_master_net_wait_time         | 0     | 
  8. | Rpl_semi_sync_master_net_waits             | 0     | 
  9. | Rpl_semi_sync_master_no_times              | 0     | 
  10. | Rpl_semi_sync_master_no_tx                 | 0     | 
  11. | Rpl_semi_sync_master_status                | ON    | 
  12. | Rpl_semi_sync_master_timefunc_failures     | 0     | 
  13. | Rpl_semi_sync_master_tx_avg_wait_time      | 0     | 
  14. | Rpl_semi_sync_master_tx_wait_time          | 0     | 
  15. | Rpl_semi_sync_master_tx_waits              | 0     | 
  16. | Rpl_semi_sync_master_wait_pos_backtraverse | 0     | 
  17. | Rpl_semi_sync_master_wait_sessions         | 0     | 
  18. | Rpl_semi_sync_master_yes_tx                | 0     | 
  19. +--------------------------------------------+-------+ 
具体参数请google一下,
Rpl_semi_sync_master_clients 指的是客户端数量
如果想卸载semisync模块uninstall plugin rpl_semi_sync_master;即可
5.2 从服务器设置:
  1. mysql> install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so'; ##加载补丁 
  2. mysql> show variables like '%semi%'; ##由图可知同样也需开启 
  3. +---------------------------------+-------+ 
  4. | Variable_name                   | Value | 
  5. +---------------------------------+-------+ 
  6. | rpl_semi_sync_slave_enabled     | OFF   | 
  7. | rpl_semi_sync_slave_trace_level | 32    | 
  8. +---------------------------------+-------+ 
  9. mysql> set global rpl_semi_sync_slave_enabled=1; ##如果长期有效写入配置文件 
  10. ---------------不是很华丽的分隔--------------- 
  11. [mysqld] 
  12. rpl_semi_sync_slave_enabled=1 
  13. ---------------不是很华丽的分隔--------------- 
重新连接主服务器
  1. mysql> stop slave; 
  2. mysql> start slave; 
5.3 查看连接状况,并测试
主服务器中查看从服务器数量
  1. mysql> show status like '%semi%'; 
  2.  
  3. Rpl_semi_sync_master_clients | 1 
如上参数为1代表半同步正常。
建立一数据库测试
  1. mysql> create database free; 
从服务器查看
  1. mysql> show databases; 
如果有free库表示设置正常。
 
到此主从构建完成。