一. 主从复制的原理
主要通过主从节点上的三个线程来完成复制,简单的模型如下:
主服务器:
dump thread:主要用来响应从服务器的IO thread的请求,从将二进制日志中的内容响应给从服务器的IO thread
IO thread:是从服务器请求主服务器的二进制日志中语句的线程,并且将其记录到relaylog中
SQL thread:从relaylog中读取语句,并执行的线程
为了提高服务器的性能,mysql的复制是异步的,但这也就使mysql的复制具有滞后
工作过程:
1. master记录二进制日志。
2. slave将master的binary log拷贝到它自己的中继日志。
3. SQL的slave thread处理该过程的最后一步。
二. 主从复制的具体配置
简要的步骤:
主服务器:
1.创建具有复制权限的用户账号
2.设置server-id
3.启用二进制日志
从服务器:
1.启动中继日志(可选择关闭二进制日志)
2.设置server-id
3.启动复制进程
注意:主从服务器的server-id必须不同,从服务器可以选择从主服务器二进制日志中的某个位置开始复制
首先在主从服务器端安装好mysql,这里就不做说明了。
主服务器端:
1. 在配置文件/etc/my.cnf中启用二进制日志,并设置server-id
log-bin=mysql-bin server-id = 1
2.进入mysql交互模式,添加具有复制权限的用户账号
mysql> grant replication slave,replication client on *.* to repluser@'192.168.0.%' identified by 'repluser'; mysql> flush privileges;
这里创建账户时,由于从服务器要远程访问,则IP要是从服务器的网段
3.查看当前二进制文件所处的位置
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 357 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
从服务器:
1.在配置文件中开启中继日志,设置server-id
#log-bin=mysql-bin //禁用二进制日志 relay-log=mysql-relay //启用中继日志 server-id = 11 //设置server-id,与主服务器上的不同
2. 启动从服务器,并指定主服务器的相关参数
mysql> CHANGE MASTER TO MASTER_HOST='192.168.0.22',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=357,MASTER_USER='repluser',MASTER_PASSWORD='repluser'; mysql> start slave
3. 查看数据库数据目录中的文件,应该会出现中继日志
[root@slave ~]# ls /mydata/data/ ibdata1 master.info mysql-bin.index mysql-relay.index slave.err ib_logfile0 mysql mysql-relay.000001 performance_schema slave.pid ib_logfile1 mysql-bin.000001 mysql-relay.000002 relay-log.info test
验证:
在主服务器上新增数据库student,新建表class,插入一行数据
mysql> create database student; Query OK, 1 row affected (0.02 sec) mysql> use student Database changed mysql> create table class(id tinyint unsigned primary key, name char(20) not null); Query OK, 0 rows affected (0.11 sec) mysql> insert into class value(1,'class 1'); Query OK, 1 row affected (0.05 sec)
在从服务器可以看到这个数据库
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | student | | test | +--------------------+ 5 rows in set (0.02 sec) mysql> use student Database changed mysql> select * from class; +----+---------+ | id | name | +----+---------+ | 1 | class 1 | +----+---------+ 1 row in set (0.00 sec)
三. 半同步复制
为了提高服务器的性能,mysql的主从复制是异步的,这会导致从服务器的数据可能滞后于主服务器,造成数据不一致。
在一主多从的场景中,主服务器可以使用半同步的方式,只等待一台从服务器复制完成并返回成功信息后才停止等待过程,但是在超时后会自动降级为异步模式。
要使用半同步模式,主从服务器都要安装插件
在主从复制的基础上,做以下配置
# On Master mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1; mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000; # On Slave mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1; mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
如果需要开机时,自动能够实现半同步则需要在Master和Slave的my.cnf中编辑:
# On Master [mysqld] rpl_semi_sync_master_enabled=1 rpl_semi_sync_master_timeout=1000 # On Slave [mysqld] rpl_semi_sync_slave_enabled=1
如果要加载取消插件
mysql> UNINSTALL PLUGIN rpl_semi_sync_master;
查看从服务器上semi_sync是否开启
mysql> show variables like "%semi%"; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 2 rows in set (0.01 sec)
在主服务器上查看
mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%'; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | 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 | +--------------------------------------------+-------+ 14 rows in set (0.02 sec)
master_clietns的值为1,说明半同步已经设置成功。
以上就是最基本的主从复制的配置方法,当随着时间的推移,主服务器上的二进制文件会越来越大,当新增一台从服务器时,如果要从头开始复制就太耗时了。此时可以先做一次备份,记录二进制文件的位置,然后在从服务器上还原,在从记录的二进制文件位置处开始进行主从复制。当然,备份还原可以是物理备份,mysqldump,xtrabackup,这些都可以。下面以mysqldump为例,做简要的说明
1 首先锁定数据库的表,为了防止在操作过程中数据不一致的问题
mysql> flush tables with read lock;
2 检查当前记录的二进制日志及其所处位置
mysql> show master status;
3 通过mysqldump创建数据库备份
mysqldump --all-databases -hlocalhost -p >back.sql
4 对数据库进行解锁
mysql> unlock tables;
5 把back.sql还原到从服务器上,执行
mysql -hlocalhost -p
6 这是就可进行主从复制了,复制的位置从第2步得到的位置开始。