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:[email protected]: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引擎的局限还是比较多的,特别在并发查询的情况下性能下降很快,不适合高并发的环境。