federated engine 실무적용사례

18
Federated Engine 적용사례와 동작원리 2015. 11. 이윤정

Upload: i-goo-lee

Post on 23-Jan-2018

297 views

Category:

Internet


0 download

TRANSCRIPT

Federated Engine 적용사례와 동작원리

2015. 11.

이윤정

- 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건 처리

- 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을 이용 쿼리가 실행될 때

- 3/17 -

Federated Engine 이해

Remote Server에 있는 MySQL/MariaDB에 있는 테이블에 접근할 수 있게 하는 스토리지 엔진

(Oracle의 DB Link와 유사함)

Local Server에서 Remote Server에 있는 테이블을 Local Server에 있는 테이블처럼 사용할 수 있게 해준다.

MySQL에서 Federated, MariaDB에서는 FederatedX(확장된 기능의 Federated) 로 부르고 있다.

실체가 없는 브릿지 역할을 한다.

- 4/17 -

Federated Engine 활성화

Local Server에서 Federated 엔진이 활성화 돼 있어야 한다.

MariaDB: 별다른 옵션 없이 사용할 수 있다.(기본적으로 활성화 돼 있음)

MySQL: 환경을 설정한 후에 DB를 restart 한다.

엔진 활성화 여부 확인

vi my.cnf

[mysqld]

Federated

SHOW ENGINES;

- 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:[email protected]:3307/remoteschema/t1';

- 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;

- 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

설정에 따라서 추후에 정리된다.

- 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:[email protected]:3307/remoteschema/t1';

- 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

- 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) )

- 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`

- 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`

- 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:[email protected]: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` >= 'ALL\0\0\0...\0\0\0') ) AND

( (`c2` <= 'ALL...') )

- 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` >= 'ALL\0\0\0...\0\0\0') ) 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

- 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` >= 'ENGINE\0\0\0...\0\0\0') ) AND

( (`c2` <= 'ENGINE...') )

6 Query UPDATE `t1` SET `c2` = 'X'

WHERE `id` = 10 AND `c2` = 'ENGINES'

6 Query COMMIT

- 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) )

- 17/17 -

Q&A

Q&A