好的,没问题。我们直接进入正题。
MySQL复制过滤:利用binlog_do_db与binlog_ignore_db实现精确复制
大家好,今天我们要深入探讨MySQL复制中的一个关键概念:复制过滤,特别是如何利用binlog_do_db
和binlog_ignore_db
来实现精确的数据库复制。在复杂的生产环境中,我们通常不需要复制所有数据库或者数据库中的所有表。复制过滤允许我们只复制我们需要的数据,这可以显著降低网络带宽占用,减少Slave服务器的存储压力,并且提高复制效率。
复制过滤的必要性
在开始深入技术细节之前,先来理解一下为什么需要复制过滤。以下是一些常见的场景:
-
数据隔离: 某些数据可能包含敏感信息,出于安全或合规性考虑,我们不希望这些数据被复制到其他服务器。
-
降低资源消耗: 只复制需要的数据库可以减少网络带宽,磁盘空间和Slave服务器的CPU资源消耗。
-
简化维护: 如果Slave服务器只需要关注特定数据库,维护和管理工作会大大简化。
-
测试环境: 我们可能只需要复制生产环境的部分数据到测试环境进行测试,而不是完整的数据副本。
复制过滤的类型
MySQL提供了多种复制过滤机制,主要可以分为以下几类:
- 基于数据库的过滤: 使用
binlog_do_db
和binlog_ignore_db
参数,这是我们今天要重点讨论的内容。 - 基于表的过滤: 使用
replicate_do_table
和replicate_ignore_table
参数。 - 基于通配符的过滤: 使用
replicate_wild_do_table
和replicate_wild_ignore_table
参数。
今天我们主要关注基于数据库的过滤,其他的过滤方式以后有机会再详细讨论。
binlog_do_db
和 binlog_ignore_db
binlog_do_db
和 binlog_ignore_db
是 Master 服务器上的配置,用于控制哪些数据库的更改会被记录到二进制日志(binary log)中。 重要的是要理解 这些参数只影响 Master 服务器写入二进制日志的行为,并不直接影响 Slave 服务器的复制行为。 Slave服务器的复制行为由replicate_do_db
和replicate_ignore_db
等参数控制,我们稍后会讨论。
-
binlog_do_db
: 指定需要写入二进制日志的数据库列表。 只有列出的数据库的更改才会被记录。 -
binlog_ignore_db
: 指定不需要写入二进制日志的数据库列表。 列出的数据库的更改不会被记录。
注意: 如果同时设置了 binlog_do_db
和 binlog_ignore_db
, 那么 binlog_ignore_db
优先于 binlog_do_db
。
配置 binlog_do_db
和 binlog_ignore_db
可以通过以下方式配置这两个参数:
-
配置文件 (my.cnf/my.ini): 这是推荐的方式,因为配置会在服务器重启后仍然生效。
[mysqld] binlog_do_db = db1,db2 binlog_ignore_db = db3
-
命令行: 这种方式只在当前会话有效,服务器重启后配置会丢失。
SET GLOBAL binlog_do_db = 'db1,db2'; SET GLOBAL binlog_ignore_db = 'db3';
注意: 修改全局参数需要
SUPER
权限。
示例 1: 使用 binlog_do_db
假设我们有两个数据库 users
和 products
, 我们只想复制 users
数据库的更改。
-
配置 Master 服务器的
my.cnf
:[mysqld] log_bin = mysql-bin # 启用二进制日志 server-id = 1 binlog_do_db = users
-
重启 Master 服务器:
sudo systemctl restart mysqld
或者
sudo service mysql restart
-
验证配置:
SHOW GLOBAL VARIABLES LIKE 'binlog_do_db';
应该看到
Value
为users
。
现在,只有对 users
数据库的更改才会被记录到二进制日志中。
示例 2: 使用 binlog_ignore_db
假设我们有三个数据库 users
, products
和 logs
, 我们不想复制 logs
数据库的更改。
-
配置 Master 服务器的
my.cnf
:[mysqld] log_bin = mysql-bin # 启用二进制日志 server-id = 1 binlog_ignore_db = logs
-
重启 Master 服务器:
sudo systemctl restart mysqld
-
验证配置:
SHOW GLOBAL VARIABLES LIKE 'binlog_ignore_db';
应该看到
Value
为logs
。
现在,对 logs
数据库的更改不会被记录到二进制日志中。
示例 3: 同时使用 binlog_do_db
和 binlog_ignore_db
假设我们有三个数据库 users
, products
和 logs
。 我们只想复制 users
和 products
数据库,但是 products
数据库中有一个表 products.temp_table
,我们不想复制这个表。 这种情况比较复杂,binlog_do_db
和 binlog_ignore_db
无法直接实现。 我们需要结合其他复制过滤参数,例如 replicate_ignore_table
,在 Slave 服务器上进行配置。 这里为了演示 binlog_do_db
和 binlog_ignore_db
的优先级,我们先假设只复制 users
和 products
,并忽略 logs
。
-
配置 Master 服务器的
my.cnf
:[mysqld] log_bin = mysql-bin # 启用二进制日志 server-id = 1 binlog_do_db = users,products binlog_ignore_db = logs
-
重启 Master 服务器:
sudo systemctl restart mysqld
-
验证配置:
SHOW GLOBAL VARIABLES LIKE 'binlog_do_db'; SHOW GLOBAL VARIABLES LIKE 'binlog_ignore_db';
应该看到
Value
分别为users,products
和logs
。
由于 binlog_ignore_db
优先于 binlog_do_db
, 因此 logs
数据库的更改不会被记录到二进制日志中,即使它没有在 binlog_do_db
列表中。
Slave服务器上的复制过滤
仅仅在 Master 服务器上配置 binlog_do_db
和 binlog_ignore_db
是不够的。 Slave 服务器也需要配置复制过滤参数,才能实现精确复制。
Slave 服务器上常用的复制过滤参数包括:
replicate_do_db
: 指定 Slave 服务器需要复制的数据库列表。replicate_ignore_db
: 指定 Slave 服务器不需要复制的数据库列表。replicate_do_table
: 指定 Slave 服务器需要复制的表列表。replicate_ignore_table
: 指定 Slave 服务器不需要复制的表列表。replicate_wild_do_table
: 使用通配符指定 Slave 服务器需要复制的表列表。replicate_wild_ignore_table
: 使用通配符指定 Slave 服务器不需要复制的表列表。
注意: Slave 服务器的复制过滤参数只影响 Slave 服务器的行为,与 Master 服务器无关。
replicate_do_db
和 replicate_ignore_db
这两个参数的功能与 binlog_do_db
和 binlog_ignore_db
类似,但是作用对象不同。 replicate_do_db
和 replicate_ignore_db
控制的是 Slave 服务器从 Master 服务器接收到的二进制日志中,哪些数据库的更改会被应用到 Slave 服务器上。
-
replicate_do_db
: 指定 Slave 服务器需要复制的数据库列表。只有列出的数据库的更改才会被应用到 Slave 服务器。 -
replicate_ignore_db
: 指定 Slave 服务器不需要复制的数据库列表。列出的数据库的更改不会被应用到 Slave 服务器。
注意: 如果同时设置了 replicate_do_db
和 replicate_ignore_db
, 那么 replicate_ignore_db
优先于 replicate_do_db
。
配置 replicate_do_db
和 replicate_ignore_db
可以通过以下方式配置这两个参数:
-
配置文件 (my.cnf/my.ini): 这是推荐的方式,因为配置会在服务器重启后仍然生效。
[mysqld] replicate_do_db = db1,db2 replicate_ignore_db = db3
-
命令行: 这种方式只在当前会话有效,服务器重启后配置会丢失。
SET GLOBAL replicate_do_db = 'db1,db2'; SET GLOBAL replicate_ignore_db = 'db3';
注意: 修改全局参数需要
SUPER
或REPLICATION SLAVE ADMIN
权限。
示例 4: Master/Slave 复制过滤的完整配置
假设我们有三个数据库 users
, products
和 logs
。 我们只想在 Slave 服务器上复制 users
数据库。
-
配置 Master 服务器的
my.cnf
:[mysqld] log_bin = mysql-bin # 启用二进制日志 server-id = 1 binlog_do_db = users
-
重启 Master 服务器:
sudo systemctl restart mysqld
-
配置 Slave 服务器的
my.cnf
:[mysqld] server-id = 2 replicate_do_db = users
-
重启 Slave 服务器:
sudo systemctl restart mysqld
-
启动 Slave 复制线程:
START SLAVE;
现在,只有对 users
数据库的更改才会被记录到 Master 服务器的二进制日志中, 并且只有 users
数据库的更改才会被应用到 Slave 服务器上。
示例 5: binlog_ignore_db
和 replicate_ignore_db
的配合使用
假设我们有三个数据库 users
, products
和 logs
。 我们不想复制 logs
数据库。
-
配置 Master 服务器的
my.cnf
:[mysqld] log_bin = mysql-bin # 启用二进制日志 server-id = 1 binlog_ignore_db = logs
-
重启 Master 服务器:
sudo systemctl restart mysqld
-
配置 Slave 服务器的
my.cnf
:[mysqld] server-id = 2 replicate_ignore_db = logs
-
重启 Slave 服务器:
sudo systemctl restart mysqld
-
启动 Slave 复制线程:
START SLAVE;
现在,对 logs
数据库的更改不会被记录到 Master 服务器的二进制日志中, 并且 logs
数据库的更改也不会被应用到 Slave 服务器上。
复制过滤的优先级
当同时使用多种复制过滤参数时,理解它们的优先级非常重要。
| 参数类型 | 参数名 | 优先级 | 说明
of course, and the rest of the world.
| 参数类型 | 参数名 | 优先级 | 说明