Federate存储引擎也是mysql比较常用的存储引擎,使用它可以访问远程的mysql数据库上的表,这种引擎的作用类似于oracle数据库的dblink,以mysql5.5为例默认是不启用federated引擎的,可以使用INSTALL PLUGIN plugin_name SONAME 'shared_library_name'语句动态加载,下面来看看federated引擎的架构:

 

 

federated table并不保存数据只有.frm文件,真实的数据存在于远程数据库,访问federated引擎表时本地数据库接受用户SQL请求后使用msyql client c api 的mysql_real_query() 发送到远程数据库,使用 mysql_store_result()函数读取远程数据库查询结果.

     创建federated表可以使用connection和create server:

1.使用connection创建federated表:

远程库创建测试表:

mysql> use lry
Database changed
mysql> CREATE TABLE `fed_test` (
    ->   `id` int(11) DEFAULT NULL,
    ->   `name` char(20) DEFAULT NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.02 sec)

mysql> insert fed_test values (1,'aaa');
Query OK, 1 row affected (0.00 sec)

mysql> insert fed_test values (2,'bbb');
Query OK, 1 row affected (0.00 sec)

mysql> insert fed_test values (2,'ccc');
Query OK, 1 row affected (0.00 sec)

mysql>

本地库创建federate表:

connection的格式:

scheme://user_name[:password]@host_name[:port_num]/db_name/tbl_name

mysql> CREATE TABLE `fed_test` (
    ->   `id` int(11) DEFAULT NULL,
    ->   `name` char(20) DEFAULT NULL
    -> )
    -> ENGINE=FEDERATED DEFAULT CHARSET=latin1
    -> CONNECTION='mysql://test:test@172.16.16.204:3306/lry/fed_test';
Query OK, 0 rows affected (0.01 sec)

mysql>
mysql>
mysql> select * from fed_test;
+------+------+
| id   | name |
+------+------+
|    1 | aaa  |
|    2 | bbb  |
|    2 | ccc  |
+------+------+
3 rows in set (0.05 sec)

mysql>

2.使用create server创建federated表  

本地库:

mysql> CREATE SERVER fedlk
    -> FOREIGN DATA WRAPPER mysql
    -> OPTIONS (USER 'test',PASSWORD 'test', HOST '172.16.16.204', PORT 3306, DATABASE 'lry');
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> CREATE TABLE `fed_test` (
    ->   `id` int(11) DEFAULT NULL,
    ->   `name` char(20) DEFAULT NULL
    -> ) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='fedlk/fed_test';
Query OK, 0 rows affected (0.00 sec)

mysql> select * from fed_test;
+------+------+
| id   | name |
+------+------+
|    1 | aaa  |
|    2 | bbb  |
|    2 | ccc  |
+------+------+
3 rows in set (0.00 sec)
 

federate引擎的限制:

FEDERATED支持及不支持的如下:

·         在第一个版本中,远程服务器必须是一个MySQL服务器。FEDERATED对其它数据库引擎的支持可能会在将来被添加。
·         FEDERATED表指向的远程表在你通过FEDERATED表访问它之前必须存在。
·         一个FEDERATED表指向另一个FEDERATED表是可能的,但是你必须小心不要创建一个循环。
·         没有对事务的支持。
·         如果远程表已经改变,对FEDERATED引擎而言是没有办法知道的。这个的原因是因为这个表必须象数据文件一样工作,除了数据库其它任何都不会被写入。如果有任何对远程数据库的改变,本地表中数据的完整性可能会被破坏。
·         FEDERATED存储引擎支持SELECT, INSERT, UPDATE, DELETE和索引。它不支持ALTER TABLE, DROP TABLE或任何其它的数据定义语言语句。当前的实现不使用预先准备好的语句。
·         执行使用SELECT, INSERT, UPDATE和DELETE,但不用HANDLER。
·         FEDERATED表查询不能缓存。

   关于对federate表创建索引的问题,federate表是可以创建索引的,但是不能通过create index语句来创建,只能在表定义时使用key字句创建,例子:

CREATE TABLE `test` (
  `id` int(11) DEFAULT NULL,
  `name` char(20) DEFAULT NULL,
  KEY `idx_id` (`id`)
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='fedlink/test'

当然federate使用索引还需要在远程源表上创建相同的索引才行。

最后说说federed的性能,由于federate不能使用缓存,而且多了网络开销所以他的性能不理想,我用benchmark做了个简单的测试,一个10W记录的innodb表,表结构和索引情况如下:

CREATE TABLE `test` (
  `id` int(11) DEFAULT NULL,
  `name` char(20) DEFAULT NULL,
  KEY `idx_test` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

用来测试的查询语句为select * from test where id=2:

 

10个并发测试结果:

直接查询远程表TPS(after connected)=11680/s

查询本地federated表TPS(after connected)=1941/s

 

1个并发测试结果:

 直接查询远程表TPS(after connected)=1079/s

查询本地federated表TPS(after connected)=545/s

总结:federated引擎的局限还是比较多的,特别在并发查询的情况下性能下降很快,不适合高并发的环境。