MySQL FEDERATED 存储引擎详解
1. 什么是 FEDERATED 存储引擎
FEDERATED 是 MySQL 的一个特殊存储引擎 ,它允许你访问远程 MySQL 服务器 上的表数据,而无需使用复制(Replication)或集群(Cluster)技术。本地创建一个 FEDERATED 表,它实际上是一个指向远程表的链接。
2. 工作原理
本地 MySQL 服务器 远程 MySQL 服务器
┌─────────────────┐ ┌─────────────────┐
│ FEDERATED 表 │─────>│ 实际数据表 │
│ (只存结构) │ │ (存储真实数据) │
└─────────────────┘ └─────────────────┘
↓ ↓
元数据 数据存储
(无数据) (真实数据)
核心机制:
-
本地不存储任何数据,只保存表结构
-
所有查询操作通过 MySQL Client API 发送到远程服务器
-
每次查询都是实时的,直接获取远程数据
-
支持 INSERT、UPDATE、DELETE 等操作
3. 使用场景
✅ 适合的场景:
-
数据整合:需要跨多个 MySQL 实例查询数据
-
分布式查询:避免数据迁移,实时访问远程数据
-
数据同步中间方案:作为 ETL 的临时方案
-
报表系统:汇总多个数据源的数据
-
遗留系统集成:访问旧系统数据而不影响原有架构
❌ 不适合的场景:
-
高性能要求的应用
-
频繁大量数据操作
-
网络不稳定的环境
-
需要事务一致性的关键业务
4. 使用方法
步骤 1:启用 FEDERATED 引擎
sql
-- 检查是否启用
SHOW ENGINES;
-- 如果未启用,在 my.cnf/my.ini 中添加
[mysqld]
federated
-- 或者动态加载(如果已编译)
INSTALL PLUGIN federated SONAME 'ha_federated.so';
步骤 2:创建远程表(在远程服务器)
sql
-- 在远程服务器 (例如:192.168.1.100:3306)
CREATE DATABASE remote_db;
USE remote_db;
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
email VARCHAR(100),
created_at DATETIME
) ENGINE=InnoDB;
步骤 3:创建本地 FEDERATED 表
方法一:使用 CONNECTION 参数
sql
USE local_db;
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
email VARCHAR(100),
created_at DATETIME
) ENGINE=FEDERATED
CONNECTION='mysql://username:password@192.168.1.100:3306/remote_db/users';
方法二:使用 DATA DIRECTORY 和 INDEX DIRECTORY(旧版本)
sql
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
email VARCHAR(100),
created_at DATETIME
) ENGINE=FEDERATED
DATA DIRECTORY='mysql://user:pass@host:port/db/table';
步骤 4:使用示例
sql
-- 查询远程数据(和本地表一样使用)
SELECT * FROM users WHERE username = 'john';
-- 插入数据(实际插入到远程)
INSERT INTO users (username, email) VALUES ('alice', 'alice@example.com');
-- 更新操作
UPDATE users SET email = 'new@example.com' WHERE id = 1;
-- 删除操作
DELETE FROM users WHERE id = 1;
-- JOIN 本地表和 FEDERATED 表
SELECT l.*, f.*
FROM local_table l
INNER JOIN users f ON l.user_id = f.id;
5. 配置选项
sql
# my.cnf / my.ini
[mysqld]
# 启用 FEDERATED
federated
# 可选配置
federated_max_connections=100 # 最大连接数
read_buffer_size=256K # 读缓冲区
read_rnd_buffer_size=256K # 随机读缓冲区
6. 优缺点分析
✅ 优点:
-
实时性:直接访问远程最新数据
-
透明性:对应用层透明,像使用本地表一样
-
灵活性:支持跨库、跨服务器查询
-
无需复制:不需要配置主从复制
-
节省空间:本地不存储数据
❌ 缺点:
-
性能问题:每次查询都需要网络往返
-
单点故障:远程服务器宕机则无法访问
-
不支持索引下推:所有过滤在本地进行
-
事务限制:不支持分布式事务
-
调试困难:问题排查复杂
7. 废弃原因
FEDERATED 存储引擎在 MySQL 8.0 中被标记为弃用(Deprecated),主要原因:
-
维护成本高:代码复杂,维护团队少
-
性能瓶颈:网络延迟导致性能差
-
功能限制多:
-
不支持 ALTER TABLE
-
不支持索引优化
-
不支持批量操作优化
-
不支持子查询优化
-
稳定性问题:容易出现连接中断、数据不一致
-
更好的替代方案:
-
MySQL Replication:主从复制更可靠
-
MySQL Cluster:集群方案更强大
-
MySQL Fabric:高可用方案
-
ETL 工具:定期同步数据
-
应用层解决:微服务 API 调用
8. 替代方案示例
方案一:使用视图 + 复制
sql
-- 在主库
CREATE VIEW all_users AS
SELECT * FROM db1.users
UNION ALL
SELECT * FROM db2.users;
-- 通过复制到从库,从库查询视图
方案二:应用层聚合
sql
// Java 示例
@Service
public class UserService {
@Autowired
private UserRepository localRepo;
@Autowired
@Qualifier("remoteUserRepository")
private UserRepository remoteRepo;
public List<User> getAllUsers() {
List<User> all = new ArrayList<>();
all.addAll(localRepo.findAll());
all.addAll(remoteRepo.findAll());
return all;
}
}
方案三:使用 ETL 工具
sql
# 使用 DataX 同步
{
"job": {
"content": [{
"reader": {
"name": "mysqlreader",
"parameter": {
"connection": [{
"table": ["users"],
"jdbcUrl": ["jdbc:mysql://remote:3306/db"]
}]
}
},
"writer": {
"name": "mysqlwriter",
"parameter": {
"connection": [{
"table": ["users"],
"jdbcUrl": "jdbc:mysql://local:3306/db"
}]
}
}
}]
}
}
9. 总结建议
如果是新项目,建议使用其他方案替代 FEDERATED。如果是现有系统在使用,建议制定迁移计划,逐步替换为更可靠的方案。