1. federated存储引擎概述
1.1 概念说明
federated存储引擎是可以访问远程的数据库而不使用cluster或replication技术,类似于oracle的dblink,使用federated存储引擎的表只在本地存储表结构文件,在远程端存储表结构文件和数据文件,本地和远程是通过mysql的API进行访问的。
federated的两个部分:
远程服务器:数据中的表结构文件存储在数据字典中。远程的表的类型可以是mysql服务器支持的任何类型,包括MyISAM或InnoDB存储类型。
本地服务器:和远程服务器的表结构文件是对应的,本地服务器上没有数据文件,表定义包含指向远程表的连接字符串。
1.2 federated存储引擎原理
1.2.1 federated存储引擎运行机制
在federated本地服务器上的表上执行查询语句时,通常是在本地进行增删改查的操作信息发送到远程服务器执行再返回给本地,并且从本地服务器返回匹配的行。
1.2.2 federated原理
a. client发出引用federated存储引擎的sql语句请求,存储引擎将遍历federated表中的每一列,并构造引用远程表的SQL语句;
b. 该语句通过mysql的API接口发送到远程服务器;
c. 远程服务器处理sql语句,并将结果返回给本地服务器,本地服务器检索sql语句的影响行数;
d. 如果该sql产生结果集,会将每一列转换为federated存储引擎格式,并将结果返回给客户端;
1.2.3 federated存储引擎架构
a. 本地服务器存储表的结构文件.frmfile ;
b. 远程服务器存储表的.frm文件和数据文件;
c. 增删改查都是通过mysql api接口连接符来访问运行的;
d. 远程数据库支持mysql的MyISAM存储引擎和innoDB.
1.3 创建federated表
- 开启federated引擎
[root@db02 support-files]# grep -A 5 "^fed" /data/mysql80/mysql80.cnf
federated
gtid-mode=on
enforce-gtid-consistency=on
master-info-repository=TABLE
relay-log-info-repository=TABLE
binlog-checksum=none
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | YES | Federated MySQL storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
- 创建远程用户
mysql> create user remote_user@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges to test^C remote_user@'%';
mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> grant all on test.* to remote_user@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> create user remote_user@'localhost' identified by '123';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on test.* to remote_user@'localhost';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host from mysql.user;
+------------------+---------------+
| user | host |
+------------------+---------------+
| remote_user | % |
| repl | 192.168.214.% |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| remote_user | localhost |
| root | localhost |
+------------------+---------------+
7 rows in set (0.00 sec)
- 测试使用远程连接用户连接
[root@db02 support-files]# mysql -uremote_user -h192.168.214.129 -P3380 -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.19 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
- 在远程服务器上创建表
CREATE TABLE test_table (
id INT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(32) NOT NULL DEFAULT '',
other INT(20) NOT NULL DEFAULT '0',
PRIMARY KEY (id),
INDEX name (name),
INDEX other_key (other)
)
ENGINE=MyISAM
DEFAULT CHARSET=utf8mb4;
- 使用connection创建本地连接表
mysql> create table local_fed(
id int not null auto_increment,
name varchar(32) not null default '',
other int not null default '0',
primary key(id)
)
engine=federated
default charset=utf8mb4
connection='mysql://remote_user:123@192.168.214.129:3380/test/test_table';
Query OK, 0 rows affected (0.01 sec)
注意:connection字符串包含连接到远程服务器的所有信息,该服务器包含将用于物理存储的数据表。
连接字符串格式如下:
schema://user_name[:password]@host_name[:port_num]/db_name/tb1_name
解释说明:
schema:公认的连接协议,此时仅mysql作为该值;
user_name:连接的用户名,用户必须在远程服务器上创建;
password:用户名密码;
host_name:远程服务器的主机名或ip地址;
port_num:远程服务器的端口号,默认是3306
db_name:远程表的数据库名称;
tb1_name:远程表的名称,可以和本地表的名称不匹配;
- 使用create server创建federated表
create server格式为:
create server server_name
foreign data wrapper wrapper_name
options (user '',password '',host '',port '',database '');
CREATE SERVER fedlink
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'remote_user', password '123',HOST '192.168.214.129', PORT 9306, DATABASE 'test');
验证格式:
mysql> select * from mysql.servers\G
*************************** 1. row ***************************
Server_name: fedlink
Host: 192.168.214.129
Db: test
Username: remote_user
Password: 123
Port: 3380
Socket:
Wrapper: mysql
Owner:
1 row in set (0.01 sec)
创建和connection 字符串相连的连接:
connection='mysql://remote_user:123@192.168.214.129:3380/test/local_fed';
- 创建federated使用此连接表
CREATE TABLE test_table (
id INT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(32) NOT NULL DEFAULT '',
other INT(20) NOT NULL DEFAULT '0',
PRIMARY KEY (id),
INDEX name (name),
INDEX other_key (other)
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8mb4
CONNECTION='fedlink/test_table';
// fedlink是上述的server_name
connection://fedlink/test_table
connecton://server_name/本地表的表名
1.4 federated存储引擎注意事项
a. federated存储引擎可以复制到其他从属服务器,但是必须确保从服务器使用connection字符串连接到远程服务器;
b. 远程服务器必须是mysql服务器;
c. 在访问federated表中定义的远程数据库的表前,远程必须存在该表;
d. federated表不支持索引,加为对表数据的访问是远程处理的,所以实际的使用是索引的远程表,这意味着对于不能使用任何索引回而需要全表扫描的查询,服务器将从远程中获取所有行,并对其进行筛选。因此,无法使用索引的查询会导致性能下降,另外,由于返回的行必须存储在内存中,因此会托慢整个服务器。
目前,select count(),select from limit M,N等语句的执行效率低,但是按主键或索引查询就很快
select id from test.table where id>1 and id<100;
e. 不支持alter table 和任意DDL语句;
f. federated接受众insert … on duplicate key update语句,如果发生重复键冲突,该语句将失败并显示错误;
g. federated执行批量插入数据,以便将多行批量发送到远程表,从而提高性能,如果远程表是事务性的,则可以使远程存储引擎在发生错误时正确的执行语句回滚,不过有两方面限制:
-
插入数据量的大小不能超过服务器之间的最大数据包的大小,如果超过,则会分为多个数据包,并且可能发生回滚;
-
不会进行批量处理insert …on duplicate key update.
h. drop table 只会删除本地的虚拟表,不会删除远程表;
i. truncate命令会清理远程的数据表;
j. 如果虚拟表中字段未建立索引,而实体表中建立了索引,在此情况下,性能也相当差,如果要在虚拟表的索引建立,性能则恢复正常。create user fed_user@‘localhost’ identified by ‘123’;create user fed_user@‘localhost’ identified by ‘123’;
K. 不支持用户定义的分区