1.在从库上进行备份
当数据量不大的时候,可以使用mysqldump进行备份从库,而不会使用主库的资源。为了保证备份时数据的一致性,需要在备份时暂停主从同步。
有两种方法:
mysql> stop slave;mysql> stop slave SQL_THREAD;
第一个是停止主从同步,不会接收主库的bin-log,也不会应用relay-log。
第二种是只停止应用relay-log,但是会继续接收主库上的bin-log并转化成relay-log。这么做的好处是,如果在一个繁忙的系统中,重启同步时,从库上应用的数据可以很快的追上主库。
备份之后,开启同步线程。
shell> mysqldump --all-databases > fulldb.dump
shell> mysqladmin start-slave
还可以使用只读的方式去备份,这里暂不记录。
2.处理从库的意外停止
在从库意外停止之后,重启SQL线程之前,需要将已经执行的事务进行恢复。恢复的相关信息记录在应用元数据库中。在之前的版本中,应用元数据库只能是文件的格式,每当事务执行后,都会更新。在5.7之后,可以使用表来代替,mysql.slave_relay_log_info,去存储应用元数据。表中的数据会跟事务一起进行,意思就是说复制应用记录到元数据库中的数据总是与应用到数据库中的一致。
对于基于GTID的主从复制来说,丢失的事务可以比较主库上的GTID,与从库上已经应用的GTID。
对于基于文件位置的主从复制来说,恢复程序需要找到SQL线程应用上一个事务时的文件以及位置。
对于意外的停止,以下的设置组合是最有伸缩性的
1/当启用GTID时,设置MASTER_AUOT_POSITION=1,这会激活到源库的自动定位功能,会自动识别跟检索丢失的事务。
2/设置sync_relay_log=1,当接收到的事务写入磁盘后,会把这些relay-log中的数据写到磁盘。虽然这个增加了安全性,但是却丢失了部分性能,因为要往磁盘写数据。当sync_relay_log>1或者sync_relay_log=0时,同步操作会交给操作系统,由操作系统来决定什么时候同步。这可能导致已经提交的事务还没有写到磁盘,以后在恢复时会导致失败。sync_realy_log的默认值是10000,最小值是0,当=0时把复制的事务刷到日志中取决于操作系统,>1时,意味着每执行多少个事件就刷新到磁盘。=1是最安全的。
3/设置innodb_flush_log_at_trx_commit=1,每次提交事务后,都将内存中数据刷新到磁盘。默认就是1。这个变量与sync_relay_log同时使用,可以确保主库上的事务与relay-log中的事务总是一致的。
4/设置relay_log_info_repository=table,这个不是默认值,默认值是file。这么设置的好处是应用的事件与记录到元数据库中的数据一致。当这个变量的值为file时,恢复是不能保证的。
5/设置relay_log_recovery=on,每次启动时都会立即自动恢复relay-log。这个变量默认是OFF,在运行时不可更改,想要设置为ON,可以在启动时使用—relay-log-recovery=ON选项。但是这个选项将会忽视损坏的,不一致的relay-log。relay-log恢复程序将会新建一个relay-log文件,并且捕获应用元数据库中由SQL线程记录的应用事件的位置。
3.主从使用不同的存储引擎
主库上的表与从库上的表的存储引擎可以是不一样的。在传统的扩展方案中,在主库上使用innodb的表来保证事务,在从库上使用只读的MyIsam的表,因为不需要保证事务。
配置主从不同的存储引擎,取决于一开始如何配置从库:
1/如果使用mysqldump,可以修改dump文件中存储引擎。
2/对于新建的主从,避免主库上建表时指定存储引擎,然后从库设置一个默认存储引擎即可。
如果在一个已经运行的主从上修改从库上的存储引擎可以按以下步骤:
1/stop slave;
2/alter table tb1 engine=’myisam’;
3/start slave;
4.复制扩展方案

5.将主库上的不同数据库复制到不同从库

可以在从库上使用—replicate-do-wild-table选项。为什么不推荐使用—replicate-do-wild-db?
这取决于fromat格式,如果是statement,会考虑当前数据库的问题,可能导致不能正确复制,如果是row,那么是不存在这个问题,是可以直接用—replicate-do-wild-db进行过滤的。
在启动时,各自加上这些选项,即可达到上图的要求。
—replicate-wild-do-table=databaseA.%
—replicate-wild-do-table=databaseB.%
—replicate-wild-do-table=databaseC.%
每个从库都需要整个bin-log,但是只执行部分满足条件的事件。
如果在开启同步前需要将主库的数据同步到从库,可以使用以下方法:
1/同步到从库,然后删除不需要的库跟表
2/使用mysqldump生成独立的库的dump文件,然后到各自的从库去执行相应的dump文件
6.提高主从复制的性能
随着连接到源的副本数量的增加,负载虽然很小,但也会增加,因为每个副本都使用到源的客户端连接。每个从库都需要主库上的bin-log,因此网络的负载也会增加,成为瓶颈。如果有多个从库连接到主库,主库本身也有大量的访问请求,提高性能的一种办法:
上图所示的结构中
Source1,是主要的源库,所有的变化跟修改都被记录到数据库,这个库上的bin-log需要打开。
Source2,是次要的源库,是Source1的从库,它的主要作用就是为复制结构中的其他从库提供复制功能。Source2是唯一可以连接到Source1的库。Source2也要打开bin-log,还要设置log_slave_updates变量(默认是OFF,这个变量的作用是是否允许从库产生自己的bin-log)。
Replica1,2,3都是Source2的从库。
这个方案减少了主要源库上的客户端负载以及网络接口负载。
7.主库失败时,切换从库使其成为主库

上图所示,每个从库都开启了bin-log,且没有打开log_slave_updates,这是从库可以成为主库的两个条件。如果某个从库开启了log_slave_updates,那么它是不能直接切换成主库的。如果主库因为某些原因变得不可用,就可以选择某个从库成为新的主库,如下图所示,Replica2成为新的主库。
切换步骤:
1/在切换之前要确保每个从库的relay-log都已经应用完成,可以使用stop slave io_thread,然后检查show processlist;直到看到了Has read all relay log这个语句。
2/在replica2上执行stop slave;
3/在replica2上执行reset master;
4/在replica1,replica3上执行stop slave,并重新指定change master to语句,当执行change master to语句时,需要指定用户,密码,端口,地址,但是不需要指定bin-log文件名与位置,因为replica1上是空的,不需要指定。
5/最后在replica1,replica3上执行start slave即可。
6/当之前的主库恢复正常后,应该把它加入到新的主从结构中。
8.半同步复制
默认情况下,mysql是异步(asynchornous)复制,主库产生事件并记录到bin-log,从库请求这是bin-log。但是主库并不知道从库是否已经接收到了,或者已经接收到了但是不知道什么时候执行这些事务,也不能保证所有的事件都发送到了从库。在异步复制中,如果主库崩溃了,那些已经提交的事务,但是却没能传送到备库,那么故障切换时,就会导致数据丢失。
全同步复制中,主库需要等到所有的从库接收到日志且执行事务完成后,才能返回给客户端事务已经执行。全同步的复制可以随时进行故障切换。全同步的缺点就是完成事务的延迟高,需要等待。
半同步复制是介于异步复制与全同步复制之间,主库只需要等待其中至少一个从库(这个数量可以配置)接收且应用日志完成后,就可以返回客户端事务已执行。
与异步复制相比,半同步复制提供了数据的完整性,因为在两个地方都持有相同的数据。与全同步复制相比,半同步复制更快。
使用半同步复制需要安装插件,然后使用变量来控制,如果插件没有安装,这些变量是无法使用的。
使用半同步复制的一些前提条件:
1/安装半同步插件需要动态加载have_dynamic_loading系统变量的值需要是yes。
2/需要基本的主从复制结构
3/不能配置多个复制通道,半同步只能有一个主库
4/配置的一些语句例如install plugin,set global,stop slave,start slave需要有SUPER权限
插件必须在plugin_dir这个系统变量指定的目录下,semisync_master.so安装在主库,semisync_slave.so安装在从库
部署步骤:
1/主库安装插件:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
2/从库安装插件:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
如果在安装时,出现了以下类似的错误,需要装一个插件:
so文件可以在https://dev.mysql.com/downloads/os-linux.html获得。
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
ERROR 1126 (HY000): Can't open shared library
'/usr/local/mysql/lib/plugin/semisync_master.so'
(errno: 22 libimf.so: cannot open shared object file:
No such file or directory)
装完之后,可以用show plugins;语句来查看,也可以查询information_schema.plugins表。
3/插件装完之后,默认是关闭的,需要修改变量,可以在运行时设置,也可以写在my.cnf文件中
4/主库打开半同步复制功能,默认是0,设置为1即打开。
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000; # 1秒
rpl_semi_sync_master_timeout=N,默认是10秒,意思是主库在提交事务之前,等待从库的确认信息多少秒之后超时。
5/从库打开半同步复制功能
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
6/如果从库正在运行,需要重启I/O线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
7/将配置写进主库与从库各自的my.cnf
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 1 second
[mysqld]
rpl_semi_sync_slave_enabled=1
关于半同步复制的监控:
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
9.延迟复制
配置延迟复制,只要在change master to 语句后加上master_delay=N即可。N是秒。如果是在运行中设置,需要先关闭sql线程,设置完之后再打开。
CHANGE MASTER TO MASTER_DELAY = N;
从库接收到事务之后,SQL线程过N秒才会应用该事件。
使用延迟复制的场景:
1/为了防止主库上的用户导致的错误。例如删除一个表,可以在应用到从库之前修改事件。
2/测试系统在出现滞后时的行为。当从库上的负载很高时就会出现同步滞后的问题。
3/检查数据库多久之前的状态,而不必重新加载备份。如果是延迟一周复制,就可以看到过去几天数据库的发展。
start slave语句跟stop slave语句会立即生效,不管delay是多少,reset slave语句会导致sql_delay=0。
show slave status\G;
关于延迟复制的三个字段
SQL_Delay: 60
SQL_Remaining_Delay: 27
Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
SQL_Delay:表示延迟多少秒开始复制
SQL_Remaining_Delay:表示还有多少秒开始进行复制
Slave_SQL_Running_State:表示状态
