2. - 1/17 -
Federated Table 적용 사례 1
동기화대상테이블
(=원본테이블)
트리거
한국
원본테이블_DML
DML
유형
DML
일시
순번
동기화 테이블과
동일한 구성
ToBe
지역코드
미국 유럽(네덜란드)
federated_원본테이블_dml federated_원본테이블_dml
원본테이블_dml 원본테이블이름_dml
원본테이블 원본테이블
sp_sync_원본테이블이름
(동기화 stored procedure)
sp_sync_원본테이블이름
(동기화 stored procedure)
Federated Table은
미국DB 혹은 유럽DB에서
한국DB에 있는 테이블의 내용을
읽어오는 용도로만 사용함
미국/유럽 DB에서는
한국DB에서 데이터를 가져온
마지막 “순번”이후의 데이터만
한국DB에서 읽어오도록 조건을 줘서
인덱스를 이용해 데이터를 읽도록 했음
PK
한국 <-> 미국 : 2Mbps
한국 <-> 유럽: 1Mbps
해외에서 한국에 있는 DML이력을 가져와서 해외에 반영한 후 반영여부를 한국에 update 해주는 경우 분당 약 1000건 처리
해외에서 한국에 있는 DML이력을 읽어오기만 하고 해외에 반영됐는지 여부를 한국에 update는 하지 않는 경우 분당 약 30,000건 처리
3. - 2/17 -
Federated Table 적용 사례 2
Federated Table 과 Local Table 간의 조인 (Federated Table 이 Driving Table이면서 NOT IN & UNION ALL...)
쿼리에서 Federated Table 의 데이터를 전부 Local DB 로 가져온 후 한 건씩 Nested Loop Join 하면서 과도한
메모리를 사용하게 됨
평소 DB서버의 상태
Federated Table을 이용 쿼리가 실행될 때
4. - 3/17 -
Federated Engine 이해
Remote Server에 있는 MySQL/MariaDB에 있는 테이블에 접근할 수 있게 하는 스토리지 엔진
(Oracle의 DB Link와 유사함)
Local Server에서 Remote Server에 있는 테이블을 Local Server에 있는 테이블처럼 사용할 수 있게 해준다.
MySQL에서 Federated, MariaDB에서는 FederatedX(확장된 기능의 Federated) 로 부르고 있다.
실체가 없는 브릿지 역할을 한다.
5. - 4/17 -
Federated Engine 활성화
Local Server에서 Federated 엔진이 활성화 돼 있어야 한다.
MariaDB: 별다른 옵션 없이 사용할 수 있다.(기본적으로 활성화 돼 있음)
MySQL: 환경을 설정한 후에 DB를 restart 한다.
엔진 활성화 여부 확인
vi my.cnf
[mysqld]
…
Federated
…
SHOW ENGINES;
6. - 5/17 -
Federated Table 생성 – 방법1: 테이블 생성문 안에 Remote Server 정보 포함
Remote Table
Local Table
Local Server에 만든 Federated Table은 Local에 있는 다른 일반 테이블처럼 사용이 가능하다.
SHOW CREATE TABLE 구문을 이용하면 테이블 생성에 사용된 username, password, host 등 모든 정보가
노출된다.
↑
username
↑
password
↑
host
↑
port
↑
schema
↑
tablename
create table remoteschema.t1
(
id int unsigned not null auto_increment primary key
,c1 int
,c2 varchar(100)
)
engine=innodb
default charset=utf8;
create table localschema.federated_t1
(
id int unsigned not null auto_increment primary key
,c1 int
,c2 varchar(100)
)
engine=federated
default charset=utf8
connection = 'mysql://remoteuser:remotepass@127.0.0.1:3307/remoteschema/t1';
7. - 6/17 -
Federated Table 생성 – 방법2: Remote Server 정보 등록 후 사용
Remote Server 정보 등록
Local Federated Table 생성
CREATE SERVER remote_server
FOREIGN DATA WRAPPER 'mysql' OPTIONS
(HOST ‘127.0.0.1',
DATABASE 'remoteschema',
USER 'remoteuser',
PASSWORD 'remotepass',
PORT 3307
);
← host
← schema
← username
← password
← port
CREATE TABLE 접근할대상테이블이름
(
Remote Server에 있는 것과 동일한 컬럼 구성
)
ENGINE=FEDERATED
CONNECTION='remote_server/접근할대상테이블이름'
COMMENT='코멘트'
DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_bin;
8. - 7/17 -
Federated Engine의 특성
SELECT, INSERT, UPDATE, DELETE, TRUNCATE 구문을 지원한다.
INSERT ON DUPLICATE KEY UPDATE 는 지원되지 않는다.
: 쿼리문에서 에러가 발생하진 않으나, 중복데이터가 있으면 UPDATE가 되지 않고 KEY 중복 에러가 발생한다.
ALTER TABLE 이나 DDL 문은 허용되지 않는다.
Query Cache를 이용하지 않고, 쿼리가 실행될 때마다 매번 데이터를 다시 읽는다.
사용자 정의 파티션을 지원하지 않는다.
Federated table를 이용하면 remote에 있는 모든 데이터를 local로 가져온다.
인덱스를 지원한다.
local의 연결이 종료돼도 remote의 연결은 남아있으며, remote에 남아있는 연결은 remote server의 timeout
설정에 따라서 추후에 정리된다.
9. - 8/17 -
Federated Table 동작 원리
테스트를 통한 Federated Table의 동작 원리를 이해하기 위해 테스트용 테이블을 생성한다.
Remote
Server
create table remoteschema.t1
(
id int unsigned not null auto_increment primary key
,c1 int
,c2 varchar(100)
)
engine=innodb
default charset=utf8;
Local
Server
create table localschema.federated_t1
(
id int unsigned not null auto_increment primary key
,c1 int
,c2 varchar(100)
)
engine=federated
default charset=utf8
connection = 'mysql://remoteuser:remotepass@127.0.0.1:3307/remoteschema/t1';
10. - 9/17 -
Federated Table 동작 원리
INSERT ~ SELECT ~ 문의 처리
입력될 모든 데이터를 가져와서 리터럴 변수를 이용한 INSERT문 처럼 만들어서 처리한다.
Local
Server
insert into localschema.federated_t1 (c1, c2)
select @rownum:=@rownum+1 as id
,a.table_name
from information_schema.tables a
,(select @rownum := 0) b
limit 5;
Remote
Server
151126 13:53:49 2 Connect remoteuser@localhost as anonymous on
remoteschema
2 Query SET AUTOCOMMIT=0
2 Query SAVEPOINT save1
2 Query INSERT INTO `t1` (`id`, `c1`, `c2`) VALUES
(0, 1 , 'ALL_PLUGINS')
2 Query INSERT INTO `t1` (`id`, `c1`, `c2`) VALUES
(0, 2 , 'APPLICABLE_ROLES') ,
(0, 3 , 'CHARACTER_SETS') ,
(0, 4 , 'CLIENT_STATISTICS') ,
(0, 5 , 'COLLATIONS')
2 Query COMMIT
11. - 10/17 -
Federated Table 동작 원리
LAST_INSERT_ID()
federated를 이용해서 auto_increment가 포함된 테이블에 데이터를 입력하고 last_insert_id()를 확인해보면
federated를 통해서 입력된 테이블의 last_insert_id()가 나오지 않고 다른 값이 나온다.
즉, federated를 이용할 때는 last_insert_id()를 사용할 수 없다.
SELECT문의 처리 : 인덱스가 있는 컬럼이 조건으로 사용되는 경우
Local
Server
select * from localschema.federated_t1 where id = 1;
Remote
Server
151126 14:31:06 2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1` WHERE (`id` = 1)
Local
Server
select * from localschema.federated_t1 where id between 3 and 6;
Remote
Server
151126 14:32:05 2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1`
WHERE ( (`id` >= 3) ) AND ( (`id` <= 6) )
12. - 11/17 -
Federated Table 동작 원리
SELECT문의 처리: limit을 사용하는 경우 = remote에 있는 모든 데이터를 local로 읽어온 후에 1건을 반환한다.
SELECT문의 처리: 인덱스가 없는 컬럼을 조건으로 사용하는 경우 = remote의 모든 데이터를 local로 가져온
후에 처리한다.
Local
Server
select c2 from localschema.federated_t1 limit 1;
Remote
Server
151126 14:33:11 2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1`
Local
Server
select c2 from localschema.federated_t1 where c2 like 'ALL%';
Remote
Server
151126 14:34:16 2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1`
13. - 12/17 -
Federated Table 동작 원리
SELECT문의 처리: 인덱스가 없던 컬럼에 인덱스를 생성하는 경우
remote에서 인덱스가 없던 컬럼에 인덱스를 생성한 후에 데이터를 조회해도 local에서는 여전히
인덱스가 없는 것으로 인식하여 remote의 모든 데이터를 local로 가져온 후에 처리한다.
Remote
Server
create index t1_idx on remoteschema.t1 (c2);
Local
Server
select c2 from localschema.federated_t1 where c2 like 'ALL%';
Remote
Server
151126 14:36:30 2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1`
14. - 13/17 -
Federated Table 동작 원리
SELECT문의 처리: 인덱스가 없던 컬럼에 인덱스를 생성하는 경우
인덱스 정보를 추가해서 Federated table을 재생성하면 인덱스를 인식하여 remote에서 인덱스를
사용해서 필요한 데이터만 읽어서 local로 가져온다.
Remote
Server
drop table if exists localschema.federated_t1;
create table localschema.federated_t1
(
id int unsigned not null auto_increment primary key
,c1 int
,c2 varchar(100)
,INDEX t1_idx (c2)
)
engine=federated
default charset=utf8
connection = 'mysql://remoteuser:remotepass@127.0.0.1:3307/remoteschema/t1';
Local
Server
select c2 from localschema.federated_t1 where c2 like 'ALL%';
Remote
Server
151126 14:42:06 6 Query SHOW TABLE STATUS LIKE 't1'
6 Query SELECT `id`, `c1`, `c2` FROM `t1` WHERE
( (`c2` >= 'ALL000...000') ) AND
( (`c2` <= 'ALL...') )
15. - 14/17 -
Federated Table 동작 원리
DELETE문의 처리
remote server에서 바로 delete문을 처리하는 것이 아니라 조건에 해당되는 데이터를 remote에서
local로 모두 읽어온 후에 다시 조건을 주고 remote에서 처리한다.
Local
Server
delete from localschema.federated_t1 where c2 like 'ALL%';
Remote
Server
151126 14:43:19 6 Query SET AUTOCOMMIT=0
6 Query SAVEPOINT save1
6 Query SHOW TABLE STATUS LIKE 't1'
6 Query SELECT `id`, `c1`, `c2` FROM `t1` WHERE
( (`c2` >= 'ALL000...000') ) AND
( (`c2` <= 'ALL...') )
6 Query DELETE FROM `t1` WHERE `id` = 1
AND `c2` = 'ALL_PLUGINS' LIMIT 1
6 Query DELETE FROM `t1` WHERE `id` = 11
AND `c2` = 'ALL_PLUGINS' LIMIT 1
6 Query DELETE FROM `t1` WHERE `id` = 16
AND `c2` = 'ALL_PLUGINS' LIMIT 1
6 Query DELETE FROM `t1` WHERE `id` = 21
AND `c2` = 'ALL_PLUGINS' LIMIT 1
6 Query COMMIT
16. - 15/17 -
Federated Table 동작 원리
UPDATE문의 처리
remote server에서 바로 update문을 처리하는 것이 아니라 조건에 해당되는 데이터를 remote에서
local로 모두 읽어온 후에 다시 조건을 주고 remote에서 처리한다.
Local
Server
update localschema.federated_t1
set c2 = 'X'
where c2 like 'ENGINE%';
Remote
Server
151126 14:45:06 6 Query SAVEPOINT save1
6 Query SHOW TABLE STATUS LIKE 't1'
6 Query SELECT `id`, `c1`, `c2` FROM `t1` WHERE
( (`c2` >= 'ENGINE000...000') ) AND
( (`c2` <= 'ENGINE...') )
6 Query UPDATE `t1` SET `c2` = 'X'
WHERE `id` = 10 AND `c2` = 'ENGINES'
6 Query COMMIT
17. - 16/17 -
Routine 안에서 Federated Table 사용될 때 remote에서의 처리
Local
Server
MainBlock: BEGIN
... 생략 ...
DECLARE out_cursor CURSOR FOR
select id from localschema.federated_t1;
... 생략 ...
OPEN out_cursor;
outLoopBlock: LOOP
FETCH out_cursor INTO v_out_value;
... 생략 ...
update localschema.federated_t1 set c1 = 9
where id = v_out_value;
END LOOP outLoopBlock;
END MainBlock
Remote
Server
2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1`
2 Query SET AUTOCOMMIT=0
2 Query SAVEPOINT save1
2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1` WHERE ( (`id` = 2) ) AND ( (1=1) )
2 Query UPDATE `t1` SET `c1` = 2 WHERE `id` = 2
2 Query COMMIT
2 Query SAVEPOINT save1
2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1` WHERE ( (`id` = 3) ) AND ( (1=1) )
2 Query UPDATE `t1` SET `c1` = 3 WHERE `id` = 3
2 Query COMMIT
2 Query SAVEPOINT save1
2 Query SHOW TABLE STATUS LIKE 't1'
2 Query SELECT `id`, `c1`, `c2` FROM `t1` WHERE ( (`id` = 4) ) AND ( (1=1) )