背景介绍
    mysql5.5之前版本,mysql主从复制比较简单
    mysql5.6:gtid,multi-thread replication

master
1 启用二进制日志
log-bin = master-bin
log-bin-index = master-bin.index

2 选择一个唯一的server id
server-id = [0~2^32]

3 创建具有复制权限的用户
replication slave,复制的从节点
replication client,联系master,获取信息的权限

slave
1 启用二进制日志
relay-log = relay-log
relay-log-index = relay-log.index

2 选择一个唯一的server id,和主不同
server-id = [0~2^32]

3 连接至主服务器复制文件
从哪里开始复制?
1)master是新的,slave从头开始复制
2)master已经运行一段时间,在master执行一次备份,记录二进制日志文件名和事件位置,在slave还原数据,连接至哪一个二进制文件的哪一个位置?

mysql> change master to master_host= ,master_port= ,master_log_file= ,master_log_pos= ,master_user= ,master_password= ;
mysql> start slave;

4 mysql复制线程
master会为每一个slave启动1个dump线程
master:dump
slave:IO_thread,SQL_thread
可单独启动
mysql> start slave IO_thread
mysql> start slave SQL_thread
mysql主从复制--mysql-5.5异步、半同步配置_style

5 半同步复制时应指定同步超时时间,一旦超时,降级为异步复制


mysql主从异步复制
    使用二进制格式安装mysql,并初始化、mtsql服务脚本复制、my.cnf配置文件复制。

导出PATH,方便使用mysql命令
# vim /etc/profile.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin

master
1 修改配置文件
# vim /etc/my.cnf
[mysqld]
datadir = /data/mysql
innodb_file_per_table = 1
log-bin=master-bin
log-bin-index=master-bin.index
server-id   = 1

启动mysql
# service mysqld start

2 授权slave复制
mysql> grant replication slave on *.* to 'replicationuser'@'192.168.8.31' identified by 'replicationuser';
mysql> flush privileges;
mysql> flush tables with read lock; # 锁住table为只读

3 查看master二进制日志文件状态,在slave上需要使用
mysql> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 |      355 |              |                  |
+-------------------+----------+--------------+------------------+
mysql> show binlog events in "master-bin.000001";
mysql主从复制--mysql-5.5异步、半同步配置_style_02


slave
1 修改配置文件
# vim /etc/my.cnf
[mysqld]
datadir = /data/mysql
innodb_file_per_table = 1

relay-log = relay-log
relay-log-index = relay-log.index
server-id   = 10

启动mysql
# service mysqld start

2 配置slave同步设置,并启动slave复制
mysql> change master to master_host='192.168.8.30',master_user='replicationuser',master_password='replicationuser',master_log_file='master-bin.000001',master_log_pos=355;
mysql> start salve;

3 查看slave的状态
mysql> show slave status\G
Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.8.30
                  Master_User: replicationuser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 438
               Relay_Log_File: relay-log.000004
                Relay_Log_Pos: 254
        Relay_Master_Log_File: master-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 438

4 在master查看slave
mysql> show slave hosts;


其他设置和说明
1 slave上不允许数据库的写操作,因此在slave上设置为用户只读模式,但此设置对具有super权限的用户无效
# vim /etc/my.cnf
[mysqld]
read-only = on

重启mysql,即生效
# service mysqld restart
重启mysqld,复制线程会自动重启
修改配置后,或者不重启,在数据库中直接修改参数也可以

查看只读模式是否生效
mysql> show global variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON    |
+---------------+-------+

2 为了保证master bin-log不在缓冲区缓存,立即同步到磁盘上,减少主从复制的延迟时间,在master设定
[mysqld] 
sync-binlog = on

重启mysql,即生效
# service mysqld restart
重启mysqld,复制线程会自动重启
修改配置后,或者不重启,在数据库中直接修改参数也可以

查看立即同步模式是否生效
mysql> show global variables like 'sync_binlog';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 0     |
+---------------+-------+

3 重启mysqld,复制线程会自动重启,存在哪些问题,如何禁止?
    当master执行了一些误操作,由于延迟原因,误操作还未同步slave;此时在slave关闭mysql,备份数据恢复到master上,启动slave的mysql,让IO_thread跳过刚才的误操作,再启动复制功能。若slave启动后,主从复制立即开始,还会同步刚才的误操作。
    不让其随mysql自动启动,防止同步误操作。

连接master 需要这两个文件master.info,relay-log.info,临时移除。slave无法连接master

在数据文件下
master.info 记录了登陆master和相关信息
relay-log.info 记录了relay-log和master-bin的相关信息 

4 从服务器的相关日志会记录在slave的错误日志中。

5 若master工作了一定时间,此时做主从的注意事项
5.1 master锁表
mysql> flush tables with read lock;
5.2 master mysql的数据库导出
# mysqldump mydb > mydb.sql
5.3 slave 创建同名数据库,并导入数据库
# mysqldump mydb < mydb.sql
5.4 此时操作和全新的数据库是相同的,注意master_log_file,master_log_pos即可

6 mysql复制过滤
在master上
# vim /etc/my.cnf
[mysqld]
binlog-do-db=db1,db2
binlog-ignore-db=db1,db2

master binlog-ignore-db带来的问题
    不记录部分数据库的二进制日志,二进制日志不完整。当服务器崩溃时,只能恢复记录了二进制日志的数据,未记录的将不能恢复,因此不建议使用此选项。

在slave上
可以进行数据库级别的过滤,也可以进行表级别的过滤
# vim /etc/my.cnf
[mysqld]
数据库级别
replicate-do-db=
replicate-ignore-db=

表级别
replicate-do-table=
replicate-ignore-table=

在表级别使用通配
replicate-wild-do-table=mydb.tb% # 仅复制mydb中以tb开头的所有表
replicate-wild-ignore-table=mydb.tb_ # 仅复制mydb中以tb开头的、后面跟上一个字符的表

slave replicate-ignore-db带来的问题
    使用此选项,虽不记录指定slave数据库的二进制日志,但是中继日志是完整的,因此会占有slave的带宽资源。

    综上,如果必须对表进行过滤,建议在slave上进行。


半同步主从复制

1 master 添加模块
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> set global rpl_semi_sync_master_enabled = 1;
mysql> show variables like 'rpl%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_recovery_rank                  | 0     |
| rpl_semi_sync_master_enabled       | ON   |
| rpl_semi_sync_master_timeout       | 10000 | # 异步复制超时时间,单位ms
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    | # 是否必须等待slave上线
+------------------------------------+-------+

2 slave 添加模块
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> set global rpl_semi_sync_slave_enabled = 1;
mysql> show variables like 'rpl%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_recovery_rank               | 0     |
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

3 若此时主从同步是开启的,设置不会立即生效,需重启slave io_thread
3.1 master状态查看
mysql> show global status like 'rpl%';
+--------------------------------------------+-------------+
| Variable_name                              | Value       |
+--------------------------------------------+-------------+
| Rpl_semi_sync_master_clients               | 0           |
| Rpl_semi_sync_master_net_avg_wait_time     | 0           |
| Rpl_semi_sync_master_net_wait_time         | 0           |
| Rpl_semi_sync_master_net_waits             | 0           |
| Rpl_semi_sync_master_no_times              | 0           |
| Rpl_semi_sync_master_no_tx                 | 0           |
| Rpl_semi_sync_master_status                | ON          |
| Rpl_semi_sync_master_timefunc_failures     | 0           |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0           |
| Rpl_semi_sync_master_tx_wait_time          | 0           |
| Rpl_semi_sync_master_tx_waits              | 0           |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0           |
| Rpl_semi_sync_master_wait_sessions         | 0           |
| Rpl_semi_sync_master_yes_tx                | 0           |
| Rpl_status                                 | AUTH_MASTER |
+--------------------------------------------+-------------+

3.2 slave状态查看
mysql> show global status like 'rpl%';
+----------------------------+-------------+
| Variable_name              | Value       |
+----------------------------+-------------+
| Rpl_semi_sync_slave_status | OFF         |
| Rpl_status                 | AUTH_MASTER |
+----------------------------+-------------+

4 只重启io_thread即可
mysql> stop slave io_thread;
mysql> start slave io_thread;

4.1 master状态查看
mysql> show global status like 'rpl%';
+--------------------------------------------+-------------+
| Variable_name                              | Value       |
+--------------------------------------------+-------------+
| Rpl_semi_sync_master_clients               | 1           |
+--------------------------------------------+-------------+
4.2 slave状态查看
mysql> show global status like 'rpl%';
+----------------------------+-------------+
| Variable_name              | Value       |
+----------------------------+-------------+
| Rpl_semi_sync_slave_status | ON          |
| Rpl_status                 | AUTH_MASTER |
+----------------------------+-------------+

5 测试
    当半同步超时后(10000ms)一次后,会降级为异步复制。
在slave停止io_thread
mysql> stop slave io_thread;
    在master进行写操作时,会卡住100000ms,之后降级为异步复制,恢复速度;

6 为了使参数永久生效,在Master和Slave的my.cnf中编辑: 
# On Master 
[mysqld] 
rpl_semi_sync_master_enabled=1 
rpl_semi_sync_master_timeout=1000 # 1 second 
 
# On Slave 
[mysqld] 
rpl_semi_sync_slave_enabled=1  

7 mysql主从机制比较脆弱,若需重启master,需先要停止slave复制,即stop slave。


监控和监控主从复制工具
percona-toolkit(mattkit-tools)
# yum localinstall -y percona-toolkit-2.2.18-1.noarch.rpm --nogpgcheck

安装之后会出现一大堆pt命令
pt-slave-delay:使slave比master慢一些时间
pt-table-checksum:通过单向加密比较主从的数据是否一致

rhel使用的是光盘中的rpm库,无法解决percona的依赖
yum localinstall时出现如下提示
 You could try using --skip-broken to work around the problem
 You could try running: package-cleanup --problems
                        package-cleanup --dupes
                        rpm -Va --nofiles --nodigest
The program package-cleanup is found in the yum-utils package


mysql ssl 简要说明
授权时,增加ssl选项,强制使用ssl;若无此选项,不受限制,即使启用了ssl功能,复制时使用和不使用ssl都可以
mysql> grant replication slave on *.* to 'replicationuser'@'192.168.8.31' identified by 'replicationuser' require ssl;

ssl需要的内容
mysql> show global variables like '%ssl%';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+









附件列表