ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 使用blockhole存储引擎过滤复制的binlog

使用blockhole存储引擎过滤复制的binlog

原创 Linux操作系统 作者:orchidllh 时间:2007-08-08 00:00:00 0 删除 编辑

如果我们只需要将数据库中的部分表复制到从数据库上,那么可以通过replicate-do-db、replicate-do-table、replicate-ignore-db、replicate-ignore-table、replicate-wild-do-table复制选项来选择只需要复制的表或者数据库。

但是这几个参数只是将符合条件的表或者数据库的binlog apply到从数据库中,不能过滤传输的binlog的内容。如果我们需要复制的内容很少,而不需要复制的内容很多的时候,就会无谓在主从服务器之间传输很多不需要的binlog,这种情况下,我们可以通过使用blockhole存储引擎过滤需要的binlog,而又不会对主数据库造成太大的额外的压力。

blockhole,直译就是黑洞的意思,使用这个存储引擎的表,不论执行什么操作,都不会实际像表中插入记录,但是对这个表的更新操作,却可以通过binlog记录下来。


下面我们测试使用blockhole进行binlog过滤得步骤:

首先要创建一个正确的主从复制环境,最好在相同服务器上创建,这样才能达到减少网络传输的问题。

我们在test用户下面有两个表:

mysql> show tables;

+----------------+

| Tables_in_test |

+----------------+

| test_myisam |

| test_myisam1 |

+----------------+

2 rows in set (0.00 sec)

我们对这两个表的更新,都会记录到binlog中,并且都会传输到从服务器上执行。

主数据库执行:

mysql> insert into test_myisam1 values(1,'ttt'),(2,'aaa');

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

从数据库:

mysql> select * from test_myisam1;

+------+------+

| i | c |

+------+------+

| 1 | ttt |

| 2 | aaa |

+------+------+

2 rows in set (0.00 sec)

我们在从服务器上设置replicate-do-table=test.test_myisam,只复制其中的一个表,并且打开从数据库的log-slave-updates,确保从数据库的更新可以写binlog,然后重启从数据库生效。

启动后,更新两个表的记录,只有test_myisam地更新执行到从数据库中,但是传输到从数据库的binlog包括全部的更新信息。

主数据库:

mysql> insert into test_myisam1 values(1,'ttt'),(2,'aaa');

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> insert into test_myisam values(1,'ttt'),(2,'aaa');

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from test_myisam;

+------+------+

| i | c |

+------+------+

| 1 | ttt |

| 2 | aaa |

+------+------+

2 rows in set (0.00 sec)

mysql> select * from test_myisam1;

+------+------+

| i | c |

+------+------+

| 1 | ttt |

| 2 | aaa |

| 1 | ttt |

| 2 | aaa |

+------+------+

4 rows in set (0.00 sec)

从数据库:

mysql> select * from test_myisam;

+------+------+

| i | c |

+------+------+

| 1 | ttt |

| 2 | aaa |

+------+------+

2 rows in set (0.00 sec)

mysql> select * from test_myisam1;

+------+------+

| i | c |

+------+------+

| 1 | ttt |

| 2 | aaa |

+------+------+

2 rows in set (0.00 sec)

下面是传输到从数据库的binlog:

[lisa1@localhost data]$ mysqlbinlog localhost-relay-bin.000007

......

/*!C gbk *//*!*/;

SET @@session.character_set_client=28,@@session.collation_connection=28,@@session.collation_server=8/*!*/;

insert into test_myisam1 values(1,'ttt'),(2,'aaa')/*!*/;

# at 348

#070807 16:15:12 server id 1 end_log_pos 900 Query thread_id=9 exec_time=0 error_code=0

SET TIMESTAMP=1186474512/*!*/;

insert into test_myisam values(1,'ttt'),(2,'aaa')/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

下面是从数据库执行更新写的binlog:

[lisa1@localhost data]$ mysqlbinlog mysql-bin.000004

/*!40019 SET @@session.max_insert_delayed_threads=0*/;

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

DELIMITER /*!*/;

# at 4

#070807 16:15:01 server id 2 end_log_pos 98 Start: binlog v 4, server v 5.0.45-log created 070807 16:15:01 at startup

# Warning: this binlog was not closed properly. Most probably mysqld crashed writing it.

ROLLBACK/*!*/;

# at 98

#070807 16:15:12 server id 1 end_log_pos 210 Query thread_id=9 exec_time=0 error_code=0

use test/*!*/;

SET TIMESTAMP=1186474512/*!*/;

SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;

SET @@session.sql_mode=0/*!*/;

/*!C gbk *//*!*/;

SET @@session.character_set_client=28,@@session.collation_connection=28,@@session.collation_server=8/*!*/;

insert into test_myisam values(1,'ttt'),(2,'aaa')/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

从两个binlog可以看出,已经有效的过滤了binlog的内容,只保留了我们关心的test_myisam表的更新信息。

最后,我们把从数据库上test_myisam表的存储引擎修改成blockhole的,这样对从数据库的访问压力降低到最小,只是简单的进行binlog的过滤。

从数据库:

mysql> alter table test_myisam engine=blackhole;

Query OK, 2 rows affected (0.03 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from test_myisam;

Empty set (0.00 sec)

然后在主数据库上进行更新操作:

mysql> insert into test_myisam values(3,'bbb'),(4,'ccc');

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from test_myisam;

+------+------+

| i | c |

+------+------+

| 1 | ttt |

| 2 | aaa |

| 3 | bbb |

| 4 | ccc |

+------+------+

4 rows in set (0.00 sec)

从数据库:

mysql> select * from test_myisam;

Empty set (0.00 sec)

检查从数据库写的binlog:

[lisa1@localhost data]$ mysqlbinlog mysql-bin.000004

......

SET @@session.character_set_client=28,@@session.collation_connection=28,@@session.collation_server=8/*!*/;

insert into test_myisam values(1,'ttt'),(2,'aaa')/*!*/;

# at 210

#070807 16:17:09 server id 2 end_log_pos 313 Query thread_id=4 exec_time=0 error_code=0

SET TIMESTAMP=1186474629/*!*/;

/*!C latin1 *//*!*/;

SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;

alter table test_myisam engine=blackhole/*!*/;

# at 313

#070807 16:17:41 server id 1 end_log_pos 425 Query thread_id=9 exec_time=0 error_code=0

SET TIMESTAMP=1186474661/*!*/;

/*!C gbk *//*!*/;

SET @@session.character_set_client=28,@@session.collation_connection=28,@@session.collation_server=8/*!*/;

insert into test_myisam values(3,'bbb'),(4,'ccc')/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

可以发现,更新操作虽然没有实际写到从数据库的表中,但是更新的操作正确记录在binlog中。

注意事项:

由于blockhole表中并没有实际的记录,所以,对blockhole表的insert触发器可以触发,但是update和delete触发器都不会触发。

这样,如果在主数据库上的表有update和delete触发器,就不能使用blockhole存储引擎进行binlog过滤,因为触发器的操作并没有写在binlog中,

而是需要通过主表的更新来触发从数据库的触发器的,如果从数据库的触发器不能触发,那么数据就不同步了。

mysql> CREATE TABLE IF NOT EXISTS test_father ( id smallint(5) unsigned NOT NULL AUTO_INCREMENT, note varchar(10) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB;

Query OK, 0 rows affected (0.10 sec)

mysql> create table test_sun(id int AUTO_INCREMENT,note varchar(20),PRIMARY KEY (id));

Query OK, 0 rows affected (0.05 sec)

mysql> DELIMITER $$

mysql> CREATE TRIGGER ins_test_father_bef

-> BEFORE INSERT ON test_father FOR EACH ROW BEGIN

-> INSERT INTO test_sun (note) VALUES (new.note);

-> END;

-> $$

Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> insert into test_father values(1,'abcd');

Query OK, 1 row affected (0.11 sec)

mysql> select * from test_sun;

+----+------+

| id | note |

+----+------+

| 1 | abcd |

+----+------+

1 row in set (0.00 sec)

察看传输到从数据库的binlog:

[lisa1@localhost data]$ mysqlbinlog localhost-relay-bin.000013

......

#070807 17:07:25 server id 1 end_log_pos 103 Query thread_id=9 exec_time=0 error_code=0

SET TIMESTAMP=1186477645/*!*/;

insert into test_father values(1,'abcd')/*!*/;

# at 784

#070807 17:07:25 server id 1 end_log_pos 3946 Xid = 82

COMMIT/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

其他blockhole的可能用途可以用来对比是否打开binlog对数据库性能的影响程度,或者测试数据库和存储引擎不相关的性能瓶颈。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/51862/viewspace-180655/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 重整旗鼓
请登录后发表评论 登录
全部评论

注册时间:2008-02-21

  • 博文量
    180
  • 访问量
    882774