MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

MariaDB选择性复制的实现与应用场景

2023-11-215.4k 阅读

MariaDB 选择性复制简介

在 MariaDB 数据库环境中,复制是一种关键的技术,它允许将数据从一个数据库服务器(主服务器)复制到一个或多个其他服务器(从服务器)。选择性复制则在此基础上,提供了更灵活的方式,只复制主服务器上特定的数据库、表或者数据行,而不是全部数据。这种灵活性在很多实际应用场景中具有显著优势,例如数据隔离、数据安全以及减少资源消耗等。

选择性复制的原理

MariaDB 的复制基于二进制日志(binary log)。主服务器将数据库的更改操作记录在二进制日志中,从服务器通过读取主服务器的二进制日志来重放这些操作,从而保持与主服务器的数据同步。在选择性复制中,从服务器可以配置只读取和应用主服务器二进制日志中特定部分的记录。这通过在从服务器配置中设置过滤规则来实现,过滤规则可以基于数据库名、表名或者更复杂的条件。

实现选择性复制的步骤

配置主服务器

  1. 启用二进制日志:在主服务器的配置文件(通常是 my.cnfmy.ini)中,确保以下配置项存在并正确设置:
[mysqld]
log-bin=mysql-bin
server-id=1

这里 log-bin 开启了二进制日志功能,server-id 是服务器的唯一标识,不同服务器需设置不同的值。 2. 重启 MariaDB 服务:修改配置文件后,重启 MariaDB 服务使配置生效。

sudo systemctl restart mariadb

配置从服务器

  1. 设置服务器标识:在从服务器的配置文件中设置 server-id,确保其与主服务器不同。
[mysqld]
server-id=2
  1. 配置过滤规则:从服务器通过 replicate-do-dbreplicate-ignore-dbreplicate-do-tablereplicate-ignore-table 等选项来设置过滤规则。
  • 按数据库选择:如果只想复制 test_db 数据库,在从服务器配置文件中添加:
[mysqld]
replicate-do-db=test_db
  • 忽略特定数据库:若要忽略 ignore_db 数据库,添加:
[mysqld]
replicate-ignore-db=ignore_db
  • 按表选择:如果只想复制 test_db 数据库中的 test_table 表,添加:
[mysqld]
replicate-do-table=test_db.test_table
  • 忽略特定表:若要忽略 test_db 数据库中的 ignore_table 表,添加:
[mysqld]
replicate-ignore-table=test_db.ignore_table
  1. 重启从服务器 MariaDB 服务:使配置生效。
sudo systemctl restart mariadb

连接从服务器到主服务器

  1. 获取主服务器状态:在主服务器上执行以下命令获取二进制日志文件名和位置:
SHOW MASTER STATUS;

结果类似:

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |    12345 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

记录下 FilePosition 的值。 2. 配置从服务器连接主服务器:在从服务器上执行以下命令配置连接:

CHANGE MASTER TO
    MASTER_HOST='主服务器IP',
    MASTER_USER='复制用户',
    MASTER_PASSWORD='复制用户密码',
    MASTER_LOG_FILE='mysql-bin.000003',
    MASTER_LOG_POS=12345;

这里 MASTER_HOST 是主服务器的 IP 地址,MASTER_USERMASTER_PASSWORD 是在主服务器上预先创建的用于复制的用户及其密码。 3. 启动从服务器复制:执行以下命令启动从服务器的复制进程:

START SLAVE;
  1. 检查复制状态:使用以下命令检查从服务器的复制状态:
SHOW SLAVE STATUS \G;

重点关注 Slave_IO_RunningSlave_SQL_Running 字段,两者都应为 Yes,并且 Seconds_Behind_Master 字段的值应接近 0,表示从服务器与主服务器同步良好。

高级过滤规则

基于行数据的过滤

在某些复杂场景下,可能需要基于行数据来进行选择性复制。这可以通过 MariaDB 的 replicate-wild-do-tablereplicate-wild-ignore-table 选项结合自定义的基于行数据的过滤函数来实现。例如,假设我们有一个 employees 表,只想复制 departmentHR 的员工数据。

  1. 创建过滤函数:在主服务器上创建一个自定义函数来判断行数据是否符合过滤条件。
DELIMITER //
CREATE FUNCTION filter_employees(department VARCHAR(50)) RETURNS BOOLEAN
DETERMINISTIC
BEGIN
    RETURN department = 'HR';
END //
DELIMITER ;
  1. 配置从服务器过滤规则:在从服务器配置文件中使用 replicate-wild-do-table 并结合过滤函数。
[mysqld]
replicate-wild-do-table=test_db.employees,filter_employees(%s)

这里 %s 是占位符,会被实际的行数据中的 department 字段值替换。

动态过滤规则

有时候,过滤规则可能需要根据运行时的条件动态变化。MariaDB 提供了一些机制来实现动态过滤。例如,可以通过在主服务器上使用事件调度器,定期更新二进制日志的过滤规则。

  1. 创建事件调度器:在主服务器上创建一个事件,用于更新过滤规则。
DELIMITER //
CREATE EVENT update_filter
ON SCHEDULE EVERY 1 HOUR
DO
BEGIN
    -- 这里可以根据业务逻辑更新过滤规则
    -- 例如,根据某个配置表中的值来修改复制过滤条件
    UPDATE replication_filters SET rule = 'new_rule' WHERE some_condition;
END //
DELIMITER ;
  1. 从服务器监听规则变化:从服务器需要定期检查主服务器上的过滤规则变化,并相应地调整自己的复制行为。这可以通过编写一个脚本,定期查询主服务器上的规则表,并更新从服务器的配置文件,然后重启 MariaDB 服务来实现。

应用场景

数据隔离

在多租户应用中,不同租户的数据需要严格隔离。通过选择性复制,可以将每个租户的数据复制到独立的从服务器上,每个从服务器只复制特定租户相关的数据库或表。例如,一个 SaaS 应用,不同企业客户的数据存储在同一个主数据库中,但通过选择性复制,可以将每个企业客户的数据分别复制到不同的从服务器,供该企业客户单独使用,确保数据安全和隔离。

-- 假设主数据库中有租户1和租户2的数据,分别在tenant1_db和tenant2_db数据库中
-- 对于租户1的从服务器配置
[mysqld]
replicate-do-db=tenant1_db

-- 对于租户2的从服务器配置
[mysqld]
replicate-do-db=tenant2_db

数据安全与合规性

在一些行业,如金融、医疗等,对数据安全和合规性要求极高。某些敏感数据可能不适合在所有环境中复制。通过选择性复制,可以确保敏感数据只在符合安全和合规要求的服务器上复制。例如,医疗数据库中包含患者的敏感信息,如病历、社保号等。可以通过选择性复制,只将非敏感数据复制到开发和测试环境的从服务器,而敏感数据仅保留在生产环境的主服务器和特定的安全级别更高的从服务器上。

-- 假设医疗数据库中有patient_info表,包含敏感字段sensitive_field
-- 在开发和测试环境的从服务器配置
[mysqld]
replicate-ignore-table=medical_db.patient_info

减少资源消耗

在数据量非常大的情况下,复制全部数据可能会对从服务器的资源造成巨大压力。选择性复制可以只复制关键数据,减少从服务器的存储和计算资源消耗。例如,一个电商数据库,每天产生大量的订单数据,但分析团队可能只关注特定时间段内的热门商品订单。通过选择性复制,可以只将符合条件的订单数据复制到分析服务器,大大减轻了分析服务器的负担。

-- 假设电商数据库中有orders表,包含订单时间和商品ID字段
-- 在分析服务器的从服务器配置
[mysqld]
replicate-do-table=ecommerce_db.orders,filter_orders(%s)

-- 创建过滤函数
DELIMITER //
CREATE FUNCTION filter_orders(order_time DATETIME, product_id INT) RETURNS BOOLEAN
DETERMINISTIC
BEGIN
    RETURN order_time BETWEEN '2023 - 01 - 01' AND '2023 - 12 - 31' AND product_id IN (1, 2, 3); -- 假设1,2,3为热门商品ID
END //
DELIMITER ;

地理分布式数据管理

在全球范围内有业务的企业,可能需要在不同地理位置的数据中心之间复制数据。由于网络带宽和数据隐私等原因,不能复制全部数据。选择性复制可以根据地理位置的需求,只复制相关的数据。例如,一家跨国公司,欧洲的数据中心可能只需要复制欧洲地区客户的数据,而亚洲的数据中心只需要复制亚洲地区客户的数据。

-- 假设公司数据库中有customers表,包含客户所在地区字段region
-- 欧洲数据中心的从服务器配置
[mysqld]
replicate-do-table=company_db.customers,filter_customers(%s)

-- 创建过滤函数
DELIMITER //
CREATE FUNCTION filter_customers(region VARCHAR(50)) RETURNS BOOLEAN
DETERMINISTIC
BEGIN
    RETURN region = 'Europe';
END //
DELIMITER ;

开发与测试环境优化

在开发和测试过程中,通常不需要完整的生产数据。选择性复制可以将生产环境中的部分数据复制到开发和测试环境,既能满足开发和测试的需求,又能减少数据量,提高环境搭建和维护的效率。例如,开发团队在进行功能测试时,只需要部分典型的用户数据和订单数据。通过选择性复制,可以将这些数据复制到开发测试服务器,避免复制大量无用数据。

-- 假设生产数据库中有users和orders表
-- 在开发测试服务器的从服务器配置
[mysqld]
replicate-do-table=production_db.users
replicate-do-table=production_db.orders,filter_orders(%s)

-- 创建过滤函数
DELIMITER //
CREATE FUNCTION filter_orders(order_amount DECIMAL(10, 2)) RETURNS BOOLEAN
DETERMINISTIC
BEGIN
    RETURN order_amount BETWEEN 10 AND 100; -- 假设10到100之间的订单为典型订单
END //
DELIMITER ;

故障排除与优化

常见故障及解决方法

  1. 从服务器复制中断:从服务器的 Slave_IO_RunningSlave_SQL_Running 字段变为 No。这可能是由于网络问题、主从服务器配置错误或主服务器二进制日志损坏等原因导致。
  • 网络问题:检查主从服务器之间的网络连接,确保端口(通常是 3306)开放。可以使用 pingtelnet 命令进行测试。
  • 配置错误:仔细检查主从服务器的配置文件,确保 server-id 不同,过滤规则正确设置,并且主从服务器连接信息(如 CHANGE MASTER TO 中的参数)准确无误。
  • 二进制日志损坏:在主服务器上执行 mysqlcheck --repair --all-databases 尝试修复二进制日志。如果损坏严重,可能需要重新配置主从复制。
  1. 数据不一致:从服务器与主服务器数据不一致。这可能是由于过滤规则设置不当,或者在复制过程中有数据直接在从服务器上被修改。
  • 过滤规则问题:检查过滤规则是否符合预期,确保没有遗漏或错误配置。例如,如果按表复制,确保表结构在主从服务器上一致,否则可能导致数据不一致。
  • 从服务器数据修改:严格禁止在从服务器上直接修改数据,除非是在特定的维护场景下,并在修改后及时同步到主服务器。

性能优化

  1. 优化网络:确保主从服务器之间的网络带宽充足,减少网络延迟。可以通过优化网络拓扑、使用高速网络设备等方式提高网络性能。
  2. 调整日志设置:在主服务器上,合理设置二进制日志的刷新频率和大小。例如,适当增大 innodb_log_file_size 可以减少日志切换的频率,提高性能。
[mysqld]
innodb_log_file_size=256M
  1. 从服务器资源优化:根据从服务器的负载情况,合理分配 CPU、内存和磁盘资源。例如,增加从服务器的内存,以提高复制过程中数据处理的效率。
  2. 并行复制:MariaDB 支持并行复制,可以在从服务器上启用并行复制功能,提高复制速度。在从服务器配置文件中添加:
[mysqld]
slave_parallel_workers=4
slave_parallel_type=LOGICAL_CLOCK

这里 slave_parallel_workers 设置并行复制的线程数,slave_parallel_type 设置并行复制的类型。

总结

MariaDB 的选择性复制为数据库管理提供了强大而灵活的功能。通过合理配置和应用选择性复制,可以满足不同场景下的数据管理需求,如数据隔离、安全合规、资源优化等。在实际应用中,需要深入理解其原理和配置方法,并注意故障排除和性能优化,以确保数据库复制的高效、稳定运行。无论是多租户应用、地理分布式数据管理,还是开发测试环境优化,选择性复制都能发挥重要作用,帮助企业更好地管理和利用数据资源。