1.暂停复制

  1. mysql> STOP SLAVE;
  2. mysql> STOP SLAVE IO_THREAD;
  3. mysql> STOP SLAVE SQL_THREAD;
  4. mysql> START SLAVE;
  5. mysql> START SLAVE IO_THREAD;
  6. mysql> START SLAVE SQL_THREAD;

当使用stop slave停止复制时,I/O_thread会停止从主库读取bin-log,停止将他们写到relay-log。当停止SQL_thread时,停止执行从relay-log读取的事件。也可以单独的停止I/O线程或者SQL线程。例如,可以停止SQL线程然后在从库上执行备份。当要对从库进行某些管理时或者对主库进行某些管理时,但是要确保从库已经执行到某个点时,可以只暂停I/O线程。

2.跳过事务

如果只从复制因为某个事务失败停止了,确保I/O线程以及SQL线程都暂停的情况下,可以跳过该事务。
首先需要定位的是,哪个事务引起的失败,可以在performance_schema库中replication_applier_status_by_worker表中查看到。

1.使用gtid时跳过事务

如果开启了gtid的事务,可以在replication_applier_status_by_worker的last_seen_transaction字段中看到,如果想直到这个事务是什么,可以在从库上使用show relaylog events,或者在主库上使用show binlog events查看。
将失败的事务的GTID赋给GTID_NEXT,然后进行一个空事务。最后将GTID_NEXT设置为自动。当START SLAVE时,从库会自动跳过这个失败的事务,因为会检测到这个GTID已经被执行了。

SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';

如果从库开启了bin-log,不想将空事务写进bin-log,可以删除当前的bin-log

FLUSH LOGS;
PURGE BINARY LOGS TO 'binlog.000146';

2.没有使用gtid时跳过事务

CHANGE MASTER TO MASTER_LOG_FILE='source_log_name', MASTER_LOG_POS=source_log_pos;

source_log_name是跳过要执行的事务的下一个事务所在的bin-log,source_log_pos是要跳过的事务的下一个事务的位置。这个语句不可以在MASTER_AUTO_POSITION=1时执行,如果需要将MASTER_AUTO_POSITION设置为1,可以CHANGE MASTER TO 时设置为0,然后再开启为1

CHANGE MASTER TO MASTER_AUTO_POSITION=0, MASTER_LOG_FILE='binlog.000145', MASTER_LOG_POS=235;
CHANGE MASTER TO MASTER_AUTO_POSITION=1;

3.复制相关线程

1.监控主要的线程

show processlist;
在主库上执行show processlist\G;语句:主库上id为2的就是bin-log dump线程,如果主库没有这个线程说明没有从库连接到主库。

mysql> show processlist\G;
*************************** 1. row ***************************
     Id: 2
   User: repl
   Host: 192.168.20.230:37973
     db: NULL
Command: Binlog Dump GTID
   Time: 3179
  State: Master has sent all binlog to slave; waiting for more updates
   Info: NULL

在从库上执行show processlist\G;语句:从库上id为1的是SQL线程,2是I/O线程

mysql> show processlist\G;
*************************** 1. row ***************************
     Id: 1
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 3167
  State: Slave has read all relay log; waiting for more updates
   Info: NULL
*************************** 2. row ***************************
     Id: 2
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 3227
  State: Waiting for master to send event
   Info: NULL

2.监控复制应用工作线程

performance_schema库中有两张表:
replication_applier_status_by_coordinator

mysql> desc replication_applier_status_by_coordinator;
+----------------------+---------------------+------+-----+-------------------+-----------------------------+
| Field                | Type                | Null | Key | Default           | Extra                       |
+----------------------+---------------------+------+-----+-------------------+-----------------------------+
| CHANNEL_NAME         | char(64)            | NO   |     | NULL              |                             |
| THREAD_ID            | bigint(20) unsigned | YES  |     | NULL              |                             |
| SERVICE_STATE        | enum('ON','OFF')    | NO   |     | NULL              |                             |
| LAST_ERROR_NUMBER    | int(11)             | NO   |     | NULL              |                             |
| LAST_ERROR_MESSAGE   | varchar(1024)       | NO   |     | NULL              |                             |
| LAST_ERROR_TIMESTAMP | timestamp           | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+----------------------+---------------------+------+-----+-------------------+-----------------------------+
6 rows in set (0.00 sec)

replication_applier_status_by_worker

mysql> desc replication_applier_status_by_worker;
+-----------------------+---------------------+------+-----+-------------------+-----------------------------+
| Field                 | Type                | Null | Key | Default           | Extra                       |
+-----------------------+---------------------+------+-----+-------------------+-----------------------------+
| CHANNEL_NAME          | char(64)            | NO   |     | NULL              |                             |
| WORKER_ID             | bigint(20) unsigned | NO   |     | NULL              |                             |
| THREAD_ID             | bigint(20) unsigned | YES  |     | NULL              |                             |
| SERVICE_STATE         | enum('ON','OFF')    | NO   |     | NULL              |                             |
| LAST_SEEN_TRANSACTION | char(57)            | NO   |     | NULL              |                             |
| LAST_ERROR_NUMBER     | int(11)             | NO   |     | NULL              |                             |
| LAST_ERROR_MESSAGE    | varchar(1024)       | NO   |     | NULL              |                             |
| LAST_ERROR_TIMESTAMP  | timestamp           | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-----------------------+---------------------+------+-----+-------------------+-----------------------------+
8 rows in set (0.00 sec)

4.relay-log与复制元数据信息库

1.relay-log

relay-log与bin-log类似,由描述数据库变化的事件组成,也有一个index文件,包含了所有的relay-log文件。
relay-log与bin-log的格式是一样的,并且也可以用mysqlbinlog来查看里面的内容。
默认情况下,relay-log的名称的格式是:hostname-relay-bin.nnnnnn,hostname-relay-bin.index用来记录这些relay-log。如果使用了hostname的relay-log,运行时修改主机名会导致主从复制错误。如果以后的主机名可能要修改,那么在一开始的时候,可以显示的设置relay_log和relay_log_index系统变量。但是如果在运行时遭遇了这种情况,可以重建一个relay-log的索引文件,然后将之前的relay-log写入到新的索引文件。

shell> cat new_relay_log_name.index >> old_relay_log_name.index
shell> mv old_relay_log_name.index new_relay_log_name.index

产生relay-log的情况:
1/每次I/O线程启动时
2/当日志刷新时,例如flush logs;
3/当前relay-log文件过大时,max_relay_log_size大于0时,超过这个值将产生新的日志,当这个时为0时,超过max_binlog_size时将产生新的日志。
待从库将所有事件应用到数据库中之后,SQL线程会自动删除relay-log文件。除此之外,没有明确的机制来删除relay-log。但是flush logs将会影响到SQL线程何时删除relay-log文件。

2.replication metedata Repositories

复制元数据库有两种,一种是连接元数据库,一种是应用元数据库。
连接元数据库中包含I/O线程连接到主库并从主库传输过来的bin-log文件中检索事务,还包括连接配置,连接账号,连接的安全加密配置信息。
应用元数据库中包含SQL线程需要从realy-log文件读取后去应用的信息。这个库中的元数据会记录哪个文件的哪个位置的事务已经应用到从库。还包括应用事务的配置,例如worker线程的个数。

默认情况下,这两个库是存放在数据库目录下的master.info 跟relay-log.info。可以设置—master-info-file启动选项,relay_log_info_file系统变量。要指定这两个库存进表中,可以将变量设置为master_info_file=table,relay_log_info_repository=table。

mysql> show variables like '%master_info_repository%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| master_info_repository | FILE  |
+------------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like '%relay%repository%';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| relay_log_info_repository | FILE  |
+---------------------------+-------+
1 row in set (0.00 sec)

如果元数据库的存储方式是表,连接元数据库的表是mysql.slave_master_info,应用元数据库的表是mysql.slave_relay_log_info
reset slave 会清空复制元数据库中的数据。
当备份从库的数据用来创建新的从库时,要备份这两张表,或者备份数据目录下的master.info跟relay-log.info文件。

5.复制过滤

1.数据库级别

—replicate-do-db=db_name
这是个命令行选项,它会告诉SQL线程,根据binlog-format的值的不同,可以指定哪个库复制到从库。如果有多个库,需要使用多次这个选项,不可以一次使用多个库。
当是statement时,对于指定的db_name只有在更改数据之前使用use语句才会被应用到从库
假设启动数据库时使用了这个选项 —replicate-do-db=sales,然后执行了以下语句:

USE prices;
UPDATE sales.january SET amount=amount+1000;

这个update语句将不会被复制到从库,因为默认数据库时prices,而不是sales。
如果binlog-format是row时,这个语句将会被应用到从库。

假设启动数据库时使用了这个选项 —replicate-do-db=db1,然后执行了以下语句:

USE db1;
UPDATE db1.table1, db2.table2 SET db1.table1.col1 = 10, db2.table2.col2 = 20;

USE db4;
UPDATE db1.table1, db2.table2 SET db1.table1.col1 = 10, db2.table2.col2 = 20;

第一条语句,当使用statement时,两个表都会更新,当使用row时,只有table1会更新。
第二条语句,当使用statement时,两个都不会更新,当使用row时,只有table1会更新。

—replicate-ignore-db=db_name
这是个命令行选项,它会告诉SQL线程,复制的时候,根据format的值忽略指定的库应用剩下的库。
当使用statement时,只有使用了use语句的库才会被忽略应用。
当使用row时,将不管当前库是什么,直接跳过该库。

—binlog-do-db=db_name
于replicate-do-db一致,只不过是在主库上启动时使用

—binlog-ignore-db=db_name
与replicate-ignore-db一致,只不过是在主库上启动时使用

只有DML语句才能用row的格式记录,DDL语句总是使用statement格式记录,即使format是row。这就意味着,在创建表时,只有使用了use,才能将DDL语句应用到从库。
无论是主库还是从库都是先判断format格式,然后在看是否有do_db,然后再看ignore_db,后面再看表级别的过滤。

2.表级别

—replicate-do-table=db_name.tbl_name
创建一个复制过滤器,告诉SQL线程要应用那个表。如果指定多张表,在启动时使用多次该选项。这个选项只会影响到那些应用到表的数据,不会影响存储过程。

—replicate-ignore-table=db_name.tbl_name
创建一个复制过滤器,告诉SQL线程要忽略的表。如果指定多张表,在启动时使用多次该选项。这个选项只会影响到那些应用到表的数据,不会影响存储过程。

—replicate-wild-do-table=db_name.tbl_name
这个跟—replicate-do-table的区别就是可以使用通配符%与_。
例如—replicate-wild-do-table=foo%.bar%,意思就是将那些foo开头的库中,以bar开头的表应用到从库。
如果表或者库的名称中包含这些通配符,可以使用反斜杠进行逃逸。
例如—replicate-wild-do-table=my_own\%db,
如果在命令行中使用通配符,需要两个反斜杠,—replicate-wild-do-table=my\_own\%db