6.4 전문 검색 엔진

MySQL 5.6 부터 InnoDB 에서도 전문 검색 엔진 기능 추가.
MySQL 5.5 에서는 MyISAM 의 한계로 전문 검색 엔진 효용 가치 낮음.


6.4.1 전문 검색 인덱스 추가

  • Demo

 create table employee_name_innodb (
   emp_no int(11) not null,
   first_name varchar(14) not null,
   last_name varchar(16) not null,
   primary key (emp_no)
) engine=innodb default charset=utf8;

insert into employee_name_innodb
select emp_no, first_name, last_name from employees;

alter table employee_name_innodb
  add fulltext index fx_firstname_lastname (first_name, last_name);

 show warnings;

  • 전문 검색 엔진 인덱스 생성 시 내부 FTS_DOC_ID 컬럼 필요, 없을 경우 경고와 함께 추가(Table rebuilding) 됨
  • 컬럼 추가는 온라인 처리 불가


6.4.2 전문 검색 인덱스를 위한 테이블 스페이스

  • ibd 파일
ibd 파일역할비고
employee_name_innodb.ibd테이블 데이터 저장용 기본 테이블 스페이스
FTS_xxx_yyy_DOC_ID.ibd단위 검색어로 구성 된 인덱스 테이블 스페이스컬럼의 값을 구분자로 자른 결과, 인덱스 별 존재
FTS_xxx_CONFIG.ibd전문 검색 인덱스 설정 저장optimize_checkpoint_limit, synced_doc_id, deleted_doc_count, stopword_table_name, use_stopword 등
FTS_xxx_STOPWORDS.ibd전문 검색 인덱스가 사용하는 구분자 저장기본 내장, 사용자 지정
FTS_xxx_{ADDED,DELETED}.ibd추가/삭제 레코드 FTS_DOC_ID 저장, 검색시 DELETED 레코드 제거 후 사용자에게 반환레코드 추가 삭제 즉시 전문 검색 인덱스 반영 안됨
FTS_xxx_BEING_{ADDED,DELETED}.ibd전문 검색 인덱스에 반영(임시→메인)시 작업중 FTS_DOC_ID 값 저장이 파일은 대부분 비어 있음
FTS_xxx_{ADDED,DELETED}_CACHE.ibd레코드 추가 삭제 내용을 즉시 반영하는 임시 전문 인덱스, 메인 전문 인덱스 반영은 테이블 리빌드에 의해 처리
  • 테이블 리빌드

-- 전문 검색 인덱스 반영을 위한 테이블 리빌드
ALTER TABLE employee_name_innodb ENGINE = InnoDB;
OPTIMIZE TABLE employee_name_innodb;

  • 메인 전문 검색 인덱스 생성 이후 변경 데이터는 임시 전문 인덱스로 관리.
  • 테이블 리빌드 시 임시 전문 인덱스는 메인 전문 인덱스에 병합.
  • 임시 전문 인덱스가 지나치게 커지지 않도록 주기적 테이블 리빌드 필요.
  • 각 테이블 스페이스 파일은 필요시 생성 되고, 전문 인덱스 삭제 후 테이블 리빌드 하야 모든 테이블 스페이스 파일 삭제됨


6.4.3 전문 검색 인덱스 관련 INFORMATION_SCHEMA 정보

  • 테이블
테이블단위내용
INNODB_FT_CONFIG전체전문 검색 인덱스의 기본 설정
INNODB_FT_DEFAULT_STOPWORD전체InnoDB의 기본 구분자 목록, 영어에 적합한 구분자 존재
INNODB_FT_INDEX_TABLE테이블innodb_ft_aux_table 변수값 저장
INNODB_FT_INDEX_CACHE테이블임시 전문 인덱스 내용 저장
INNODB_FT_{INSERTED,DELETED}테이블추가/삭제된 레코드의 FTS_DOC_ID 저장
INNODB_FT_BEING{INSERTED,DELETED}테이블테이블 리빌드에 의해 메인 전문 인덱스에 반영 중인 레코드 정보 저장
  • 테이블 단위 조회는 innodb_ft_aux_table 변수에 대상 테이블 명시 필요.

 SET GLOBAL innodb_ft_aux_table = 'employees/employee_name_innodb';
 


6.4.4 전문 검색 인덱스 사용

  • 전문 검색 전용 쿼리 문법 사용
  • MATCH 절에 전문 검색 인덱스 구성 컬럼 모두 명시 필수

SELECT * FROM employee_name_innodb WHERE MATCH(first_name, last_name) AGAINST ('+Matt +Wallrath' IN BOOLEAN MODE);

EXPLAIN
SELECT * FROM employee_name_innodb WHERE MATCH(first_name) AGAINST ('+Matt +Wallrath' IN BOOLEAN MODE);
-- ALL

EXPLAIN
SELECT * FROM employee_name_innodb WHERE MATCH(first_name, last_name) AGAINST ('+Matt +Wallrath' IN BOOLEAN MODE);
-- FULLTEXT


6.4.5 주의 사항

  • MyISAM, InnoDB 전문 검색 인덱스의 기본 구분자 리스트는 서로 다르므로 검색 결과가 다를 수 있음.
    • 빌트인 구분자 리스트 : INFORMATION_SCHEMA.innodb_ft_default_stopword
    • 커스텀 구분자 리스트 : 기본 구분자 리스트 와 같은 구조 테이블 생성 후 구분자 입력 하고, innodb_ft_server_stopword_table 시스템 변수에 설정 (db_name/table_name)
    • 커스텀 구분자 리스트 설정 이후 테이블에 대해서만 적용 됨

CREATE TABLE stopword_for_employees (
  value varchar(18) NOT NULL DEFAULT ''
) ENGINE = InnoDB;

INSERT INTO stopword_for_employees SELECT * FROM INFORMATION_SCHEMA.innodb_ft_default_stopword;

SELECT * FROM stopword_for_employees limit 10;

SET GLOBAL innodb_ft_server_stopword_table = 'employees/stopword_for_employees';
-- ERROR 1231 / Latin1 문자 셋만 사용 가능

ALTER TABLE stopword_for_employees CONVERT TO CHARACTER SET Latin1;
SET GLOBAL innodb_ft_server_stopword_table = 'employees/stopword_for_employees';

  • 구분자 리스트 테이블 이용 순서
    1. 사용자 : innodb_ft_user_stopword_table
    2. 시스템 : innodb_ft_server_stopword_table
    3. 기본값 : INFORMATION_SCHEMA.innodb_ft_default_stopword
  • 단위 검색어 길이 기본 값
구분최소최대
MyISAMft_min_word_len(4)ft_max_word_len(무제한)
InnoDBinnodb_ft_min_token_size(3)innodb_ft_max_token_len(64)
  • InnoDB 전문 검색 추가 시스템 변수
    • innodb_ft_result_cache_limit : 검색 쿼리 중간/최종 결과가 저장되는 메모리 공간 제한, 초과 시 쿼리 취소 (기본값:2GB)
    • innodb_ft_total_cache_size : 모든 임시 전문 검색 인덱스 사용 공간 제한, 초과 시 강제 동기화
  • 전문 검색 알고리즘


6.5 Memcached 플러그인

  • PK 를 통한 검색 과 같은 단순한 쿼리의 반복 수행은 분석/최적화 부하가 상대적으로 큼
    • MariaDB 5.5 의 HandlerSocket 인터페이스 제공
    • MySQL 5.6 InnoDB 의 Memcached API 제공 (윈도우 미제공)


6.5.1 아키텍처

  • 모든 테이블 접근은 모든 스토리지 엔진을 위한 "핸들러 API" 계층 경유 (최적X)
    • Memcached 플러그인은 직접 InnoDB 스토리지 엔진 호출 (최적, MySQL 서버 프로세스 내 별도 스레드 형태)

  • Memcached 플러그인 기능 과 특성
    • MySQL 서버 프로세스 내 스레드로 작동 하므로 InnoDB 스토리지 엔진 접근 빠름
    • InnoDB API 직접 사용으로 빠름 (쿼리 분석/최적화, 핸들러 API 우회)
    • Memchached 텍스트/바이너리 프로토콜 지원, Memcapable 의 55개 호환성 테스트 통과
    • InnoDB 테이블의 멀티 컬럼을 구분자 활용하여 Memcached 의 Value 로 매핑 가능
    • Memcached 의 캐시 메모리와 InnoDB 버퍼 풀 메모리 조합 사용 가능
    • Memcached 옵션 지정 가능 : daemon_memcached_option 시스템 변수
    • Memcached 플러그 인으로 유입되는 요청의 격리 수준 설정 가능 (innodb_api_trx_level )


6.5.2 설치 및 테스트

  • libevent 1.4.3 이상 필요
  • 컴파일 시 "-DWITH_INNODB_MEMCACHED=ON" 옵션 필요
  • my.cnf
구분설정
TCP/IP 포트daemon_memcached_option = '-m 64 -p 11211 -c 200 -t 6'
Unix 소켓 파일daemon_memcached_option = '-m 64 -c 200 -t 6 -s /tmp/memcached.sock'
  • 옵션
옵션설명비고
-m로컬 캐시 메모리 크기(단위: MB)MySQL 쿼리 캐시, InnoDB 버퍼 풀 무관
-pListen Port
-s유닉스 도메인 소켓 파일클라이언트가 로컬에 있을 때, 설정 시 -p 옵션 무시
-c최대 연결 수
-t사용자 요청 처리용 스레드 수200개 커넥션의 요청을 6개 스레드가 처리
-v, -vv, -vvv에러/에러+경고/에러+경고+진단 로그 출력MySQL 서버 에러 로그 사용
  • Memcached 플러그인 활성화
 
-- 메타 테이블 생성
mysql> SOURCE $[MYSQL_HOME]/share/innodb_memcached_config.sql

-- 플러그인 활성화
mysql> INSTALL PLUGIN daemon_memcached SONAME "libmemcached.so";

  • Memcached 플러그인 메타 테이블
메타 테이블설명비고
cache_policiesSET/GET/DELETE/FLUSH 에 대한 캐시 정책 설정
config_options레코드가 Memcached 프로토콜로 전송될 수 있도록 설정separator : 각 컬럼의 구분자 지정, table_map_delimiter : 키 명시
containersMemcached 플러그인이 INSERT/SELECT 할 테이블의 정보 관리
  • 프로토콜
프로토콜설명비고
텍스트텍스트 기반, 단순함, 처음 부터 사용Endian 고려 불필요
바이너리CPU, 네트워크 대역폭 적게 사용
  • 테스트

-- TCP/IP Port 접속
$ telnet localhost 11211

-- 데이터 입력 : key, flag, expire_time, byte_count, value
set matt 0 3600 12
Real MariaDB

-- 데이터 조회 : key
get matt

-- 데이터 삭제 : key
delete matt

-- 종료
quit

-- 유닉스 도메인  소켓 파일 접속
$ nc -U /tmp/memcached.sock

  • SET 명령 인자
인자설명비고
key아이템의 키최대 250 Byte
flag응용프로그램에서 활용 가능한 4바이트 정수 타입 필드
expire_time캐시 메모리에 유지할 시간 (초단위)259200 보다 작으면 상대 시간, 크면 unixtimestamp 로 인식
byte_count아이템의 값(value)의 전체 바이트최대 1MB
value아이템의 값


6.5.3 캐시 정책

  • Memcached 플러그인 자체 캐시 메모리 정책 (테이블 단위 설정 가능)
정책설명비고
innodb_onlyMemcached 플러그인 자체 캐시 무시SET 된 데이터는 즉시 InnoDB 에 영구 저장
cache_onlyMemcached 플러그인 캐시만 사용, InnoDB 의 데이터와 무관하게 동작MySQL 서버 재기동 시 데이터 초기화
cachingInnoDB 엔진, Memcached 플러그인 협업 동작먼저 Memcached 캐시 메모리 액세스 후 필요시 InnoDB 엔진 액세스
disabledMemcached 플러그인 안씀


6.5.4 사용자 테이블 등록

  • 초기화 스크립트(innodb_memcached_config.sql)는 test 데이터베이스 내 test_demo 테이블 생성 후 Memcached 플러그인에 등록.
  • Memcached 플러그인 적용 테이블, 키 컬럼 제약 사항
    • 키 값에 공백/줄바꿈 포함 불가
    • 키 타입은 정수, 문자열 만 가능
    • 키 컬럼은 PRIMARY KEY, UNIQUE KEY 생성 필수
    • 파티션 테이블 적용 불가
  • 데모
 
create database my_service;
use my_service;

create table mc_store (
  c_key varchar(250) collate Latin1_bin not null,
  c_value mediumblob,
  c_flag int not null default '0'
  c_cas bigint unsigned not null default '0',
  c_expire int not null default '0',
  PRIMARY KEY (c_key)
) ENGINE = InnoDB STATS_PERSISTENT = 0;

use innodb_memcache;
insert into containers (name, db_schema, db_table, key_columns, value_columns, flags, cas_column, expire_time_column, unique_idx_name_on_key)
values ('default', 'my_service', 'mc_store', 'c_key', 'c_value', 'c_flag', 'c_ca', 'c_expire', 'PRIMARY');

-- containers.name = 'default'

  • Memcached 는 테이블 개념 없으나, MySQL 테이블과 매핑 수단 제공
    • @@product.A01 : product 테이블의 키가 'A01' 인 아이템
    • @@order.A01 : order 테이블의 키가 'A01' 인 아이템
    • A01 : default(유일한) 테이블의 키가 'A01' 인 아이템


6.5.5 관련 시스템 변수

  • 변수
변수설명비고
daemon_memcached_optionMemcached 플러그인 기동 옵션
innodb_api_trx_levelMemcached 플러그인 커넥션 격리 수준 설정0:READ_UNCOMMITED, 1:READ_COMMITED, 2:REPEATABLE_READ, 3:SERIALIZABLE
daemon_memcached_{r,w}_batch_sizeCOMMIT 실행에 필요한 GET/SET 실행 수기본값:1, 중요하지 않은 데이터라면 값을 늘려서 성능 개선 가능
innodb_api_bk_commit_intervalMemcached 플러그인 관련 커넥션 일괄 커밋 Interval기본값:5초
innodb_api_enable_binlogMemcached 플러그인을 통한 변경 내용 바이너리 로그 기록 여부


6.6 카산드라 스토리지 엔진

  • 원격의 카산드라 서버로 접속하여 SQL 문법으로 데이터 조회 기능 제공

6.6.1 카산드라

  • 카산드라 : NoSQL 데이터베이스, P2P 방식으로 노드간 통신 하는 클러스터
  • 클러스상 자신의 위치가 정해져 있고 좌/우/임의 노드와 통신을 유지 하면서 전체 노드 상태 관리
  • Gossip : 다른 노드들의 상태를 전파하는 프로토콜
  • 클러스터 내 Ring 형태로 노드 존재, 데이터를 1/N 로 나누고 자신의 데이터에 대해서 서비스, 다른 노드 데이터에 대한 Proxy 서비스
  • 다차원 Key/Value 로 정보 관리 - (Key(Key/Value))
    • 테이블이나 레코드 개념 데이터 조립 가능.
  • 오브젝트
오브젝트설명비고
키 스페이스MariaDB 의 데이터베이스(Schema)
칼럼 패밀리(CF)MariaDB 의 테이블, 데이터 집합 정의함께 자주 사용하는 데이터를 모아서 정의
로우 키RDBMS의 Row 의 Primary Key
칼럼이름-값 쌍으로 관리, 정의 후 사용하는 구조 아님

CQL(Cassandra Query Language)

  • 조인, 서브쿼리 미지원
  • 집합, 정렬은 로우키 + 컬럼이름 만 가능
  • 로우키, 컬럼이름 만 WHERE 절 조건 가능


6.6.2 카산드라 스토리지 엔진

  • 원격 서버에 있는 카산드라 클러스터 데이터에 대한 뷰 제공

INSTALL PLUGIN cassandra SONAME 'ha_cassandra.so';

-- my.cnf [mysqld]
plugin-load = ha_cassandra.so


$ cqlsh

create keyspace cassandra_se
... with strategy_class = 'org.apache.cassandra.locator.SimpleStrategy'
... and strategy_options:replication_factor='1';

use cassandra_se;

create columnfamily cf_friends (
... uid varchar primary key,
... friend_uid varchar) with compact storage;

insert into cf_friends (uid, friend_uid) values ('matt', 'pitt');
insert into cf_friends (uid, friend_uid) values ('matt', 'pott');

select * from cf_friends;

-- 카산드라 컬럼 패밀리와 컬럼 이름 및 데이터 타입 일치 필요
$ mysql

create table cass_friends (
  uid varchar(64) primary key,
  friend_uid varchar(64)
) ENGINE = cassandra THRIFT_HOST = '192.168.0.1' KEYSPACE='cassandra_se' COLUMN_FAMILY='CF_FRIENDS';

-- thrift_host : 테이블 별 접속 카산드라 클러스터 설정
-- cassandra_default_thrift_host : 전체 테이블 공통 카산드라 클러스터 설정||

insert into cass_friend (uid, friend_uid) values ('toto', 'pitt');
insert into cass_friend (uid, friend_uid) values ('toto', 'pott');

select * from cass_friends where uid = 'toto';


6.7 CONNECT 스토리지 엔진


6.7.1 CONNECT 스토리지 엔진 설치


INSTALL PLUGIN connect SONAME 'ha_connect.so';

SHOW ENGINES;

SHOW PLUGINS;


6.7.2 오라클 RDBMS 테이블 연결


-- DSN (ORCL) 등록

-- 테이블 생성
create table ora_emp engine = connect 
  table_type = odbc tabname = 'EMP' connection = 'DSN=ORCL;UID=SCOTT;PWD=TIGER'
  srcdef='SELECT empno, ename, mgr, level from emp connect by prior empno = mgr;';

select * from ora_emp;

-- engine_condition_pushdown = 'ON' 설정 시 WHERE 절 내용이 원격 DBMS에 전달 됨 (기본값 : OFF) 
SET optimizer_switch='engine_condition_pushdown = ON';


6.7.3 my.cnf 설정 파일 연결


create table mysql_config (
section varchar(64) flag = 1,
keyname varchar(64) flag = 2,
value varchar(256)
) engine = connect table_type = ini file_name = '/etc/my.cnf' option_list='Layout=Row;seclen=90000';

select * from mysql_config;
select * from mysql_config where section = 'mysqld' and keyname = 'port';


6.7.4 운영체제의 디렉터리 연결


create table temp_dir (
  path varchar(@56) not null flag = 1,
  fname varchar(256) not null,
  ftype char(4) not null,
  size double(12,0) not null flag = 5
) engine = connect table_type = dir file_name = '/data/*' option_list = 'subdir = 1';

-- subdir = 1 : 서브디렉터리 까지 조회
select * from temp_dir;


6.8 시퀀스 스토리지 엔진

  • 순차적 번호를 주어진 조건에 맞게 메모리 테이블로 생성

INSTALL PLUGIN sequence SONAME 'ha_sequence.so';


6.8.1 시퀀스 스토리지 엔진 기본 사용법

  • 테이블 이름 패턴
  • seq_<시작값>_to_<종료값>
  • seq_<시작값>_to_<종료값>_step_<건너뛸 값의 개수>
  • 특성
  • 음수 불가(UNSIGNED 타입), 반복 불가

 select * from seq_1_to_5;
 
 select * from seq_5_to_1;
 
 select * from seq_1_to_5_step_2; -- 1,3,5
 
 select * from seq_5_to_1_step_2; -- 5,3,1
 
 select * from 'seq_-5_to_1' limit 4; -- 안됨
 
 select -1 * convert(seq, signed integer) as seq from seq_5_to_1; -- -5 ~ -1


6.8.2 누락된 번호 찾기


create table seq_test (seq int) engine = InnoDB;
insert into seq_test values (1), (2), (3), (4), (5), (8), (9), (10);

select s.seq from seq_1_to_10 s left outer join seq_test t on t.seq = s.eq where t.seq is null;


6.8.3 순차적으로 조합된 번호 쌍 생성


select s1.seq, s2.seq from seq_1_to_2 s1, seq_1_to_3 s2 order by s1,seq, s2.seq;


6.8.4 배수 또는 공배수 찾기


-- 100 보다 작은 3의 배수
select seq from seq_3_to_100_step_3;

-- 100보다 작은 3과 의 공배수
select s1.seq from seq_5_to_100_step_5 s1, seq_3_to_100_step3 s2 on s1.seq = s2.seq;


6.8.5 순차적인 알파벳 생성


select char(seq) as seq_char from (
  -- 소문자
  (select seq from seq_97_to_122 l)
  union all
  -- 대문자
  (select seq from seq_65_to_90 u)
  union all 
  -- 숫자
  (select seq from seq_48_to_57 d)  
) seq_ch;


6.8.6 순차적인 날짜 생성


select date_add('2014-01-29', interval s.seq - 1 day) as seq_dat
  from seq_1_to_30 s;


6.8.7 데이터 복제 가공 (copy_t)


select case when seq = 1 then e.emp_no else 'MIN_HIREDATE' end emp_no,
     case when seq = 1 then e.first_name else '' end first_name,
	 case when seq = 1 then e.hire_date else min(e.hire_date) end hire_date
  from employees e, seq_1_to_2 s
  where e.emp_no between '10001 and 10020
  group by case when seq = 1 then e.emp_no else seq end;


6.9 Mroonga 전문 검색 스토리지 엔진

  • 일본 DeNA 에서 개발한 컬럼 기반 전문 검색 엔진
  • 두가지 실행 모드 : 스토리지 엔진 / 래퍼(Wrapper) - 실제 데이터는 InnoDB 스토리지 엔진에 저장하고 검색용 전문 인덱스만 Mroonga 스토리지 엔진에 저장
스토리지 모드래퍼 모드


6.9.1 인덱스 알고리즘

6.9.1.1 구분자(Stopword) 방식

  • 공백, 탭, 띄어쓰기, 마침표 같은 문장 기호, 한국어의 조사 등을 구분자 목록에 정의 하고, 구분자를 이용하여 키워드를 분석 후 인덱스 생성
  • 매우 자주 씌이는 단어를 구분자에 넣기 도 함
  • MySQL 내장 전문 검색 엔진 채택 방식


6.9.1.2 n-Gram 방식

  • 전문을 무조건적으로 몇 글자씩 잘라서 인덱싱
  • 인덱싱 알고리즘이 복잡하고, 인덱스가 상대적으로 큼
  • 2-Gram(Bi-Gram) 많이 사용


6.9.1.3 구분자와 n-Gram의 차이


SELECT * FROM tb_test WHERE MATCH(doc_body) AGAINST ('아이폰' IN BOOLEAN MODE);

doc_body구분자n-Gram
중고 아이폰 3G 팝니다.OO
아이폰 3Gs 구해 봅니다.OO
애플아이폰 3Gs 싸게 팝니다.XO


6.9.2 Mroonga 전문 검색 엔진 설치


INSTALL PLUGIN mroonga SONAME 'ha_mroonga.so';
CREATE FUNCTION last_insert_grn_id RETURNS INTEGER SONAME 'ha_mroonga.so';
CREATE FUNCTION mroonga_snippet RETURNS STRING SONAME 'ha_mroonga.so';


6.9.3 Mroonga 전문 검색 엔진 사용


create table tb_test (
  id int primary key auto_increment,
  content varchar(255),
  fulltext index fx_content (content) comment 'parser "TokenBigramIgnoreBlankSplitSynbolAlphaDigit"'
) ENGINE = mroonga COMMENT = 'engine "innodb"' DEFAULT CHARSET utf8mb4;

INSERT INTO TB_TEST (CONTENT) VALUES ('오늘은 MariaDB 공부를 했습니다. 내일도 MariaDB 공부를 할 것입니다.");
INSERT INTO TB_TEST (CONTENT) VALUES ('오늘은 MariaDB 공부를  했지만, 내일은 MariaDB 공부를 할 것입니다.");

SELECT *, MATCH (content) AGAINST ('MariaDB' IN BOOLEAN MODE) AS SCORE
  FROM tb_test
 WHERE MATCH (content) AGAINST ('MariaDB' IN BOOLEAN MODE)  
 ORDER BY MATCH (content) AGAINST ('MariaDB' IN BOOLEAN MODE)  DESC;


TokuDB

  • Fractal Tree 기반의 스토리지 엔진
  • 온라인 DDL 기능 제공
  • Fractal Tree 및 압축 효율로 Disk I/O 를 효과적으로 줄여서 Insert 성능 좋음


HandlerSocket

  • DeNA 에서 개발한 단순 읽기 최적 플러그인
  • 파싱/옵티마이즈 단계를 없애고 Handler API 직접 호출 하는 방식
  • Primary Key 로만 데이터 접근 하는 경우와 같이 단순한 쿼리라면 파서/옵티마이저 단계가 오버헤드일 수 있음
  • 쓰기 성능
  • 읽기 성능


FederatedX

  • 원격 데이터베이스 내 테이블을 로컬에 있는 것 처럼 접근 가능
  • 2-Phase Commit 일관성 제공
  • 테이블 파티션 별 다른 서버 연결 가능

create server 'remote' foreign data wrapper 'mysql' options
(host 'remote',
database 'target_db',
user 'appuser',
password 'passwd123',
port 3306,
socket ''
owner 'appuser');

SELECT * FROM mysql.servers;

-- 원격/로컬 이름이 같음
create table tb_remote (
 col01 bigint(20) not null,
 col02 bigint(20) not null,
 col03 varchar(20) not null default '',
 primary key (col01)
) engine = federated connection = 'remote';

-- 원격/로컬 이름이 다름
create table tb_local (
 col01 bigint(20) not null,
 col02 bigint(20) not null,
 col03 varchar(20) not null default '',
 primary key (col01)
) engine = federated connection = 'mysql://appuser:passwd123@remote:3306/target_db/tb_remote';