postgresql 공간관리 살펴보기 이근오

45
PGDay Seoul 2016 2016.10.15 PostgreSQL 공간 관리 살펴보기 (PostgreSQL 9.4) 이근오

Upload: pgdayseoul

Post on 09-Jan-2017

197 views

Category:

Software


6 download

TRANSCRIPT

Page 1: PostgreSQL 공간관리 살펴보기 이근오

PGDay Seoul 2016

2016.10.15

PostgreSQL 공간 관리 살펴보기

(PostgreSQL 9.4)

이근오

Page 2: PostgreSQL 공간관리 살펴보기 이근오

Table of Agenda

Ⅱ. VM과 FSM 구조 분석

Ⅰ. Vacuum 시의 공간관리

Page 3: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리

Page 4: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리1. Vacuum 정의 및 필요성

‘Multi Generation Architecture’의 단점은?

데이터의 변경이 빈번할 경우, 파일 사이즈가 커져 심각한 성능저하의 원인이 될 수 있다!

그렇다면 이를 해결해주는 기능은?

VACUUM!

Page 5: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리1. Vacuum 정의 및 필요성

1) 변경 및 삭제된 자료들이 차지하고 있는 디스크 공간을 확보하기 위해서

2) transaction id가 겹침(wraparound)으로 인해 오래된 자료의 손실이 발생하는 것을 방지하기 위해서

3) Query Planner가 사용할 자료의 통계 정보를 갱신하기 위해서

4) 실자료 지도(visibility map, VM)의 정보를 갱신하기 위해서

(VM은 인덱스 전용의 검색 성능을 향상시키기 위해 사용함)

2. Vacuum의 필요성

1. Vacuum의 정의

PostgreSQL에서 특정 튜플을 update 하거나 delete 한다고 해서 해당 영역이 자동으로 재사용되거나 사라지지 않는다.

이렇게 오래된 영역을 정리하여 공간을 반환하는 명령어가 Vacuum이다. ≒ 디스크 조각 모음

VM (Visibility Map)

dead tuple의 존재 여부를 알려주는 정보

• dead tuple이 포함되지 않은 경우 : 1

• dead tuple이 포함되거나 확실하지 않은 경우 : 0

Page 6: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리2. Vacuum 실행 구조

① insert into t2 values('A1001','A','A');

insert into t2 values('A1002','A','A');② update t2 set c2='B' where c1 = 'A1001' ;

③ 표준 vacuum ④ Full vacuum

'A1001',‘B','A'

Page 7: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

① insert into t2 values('A1001','A','A');insert into t2 values('A1002','A','A');

③ 표준 vacuum ④ Full vacuum

② update t2 set c2='B' where c1 = 'A1001' ; pd_lower

pd_upper

itemst_xmin

t_infomask2

t_xmax

t_infomask

pd_prune_xid

Page 8: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리

Special

Page Header

'A1001','A','A''A1002','A','A'

line pointer

Tuple Header

3. 표준 vacuum VS Full vacuum

• insert into t2 values('A1001','A','A');• insert into t2 values('A1002','A','A');

2000801f

Page 9: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리

• SELECT * from heap_page_items(get_raw_page('t2', 0));

3. 표준 vacuum VS Full vacuum

① insert into t2 values('A1001','A','A');insert into t2 values('A1002','A','A');

create table t2 ( c1 char(19),c2 char(8),c3 char(8) );

• extension module

create extension pageinspect;

Page 10: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

• update t2 set c2='B' where c1 = 'A1001' ;

Special

Page Header

'A1001','A','A''A1002','A','A''A1001', 'B','A'

line pointer

Tuple Header

2400401f

새로운 위치/에 변경 데이터인“B” 레코드를 추가

“A1001” 원본은“xmax” 값을 변경

Page 11: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

② update t2 set c2='B' where c1 = 'A1001' ;

• SELECT * from heap_page_items(get_raw_page('t2', 0));

• select xmin,xmax,ctid, * from t2;

“A1001” item 의 xmin 변경됨

“A1001” 원본은“xmax” 값을 변경

Page 12: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

② update t2 set c2='B' where c1 = 'A1001' ;

• SELECT * from heap_page_items(get_raw_page('t2', 0));

• select xmin,xmax,ctid, * from t2;

“A1001” item 의 xmin 변경됨

“A1001” 원본은“xmax” 값을 변경

새로운 위치에 변경 데이터인“B” 레코드를 추가

Page 13: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

Special

Page Header line pointer

Tuple Header

'A1002','A','A''A1001', 'B','A'

• 표준 Vacuum

A의 line pointer는 삭제되나 공간은 남아있고, items에는 공간도 삭제된다. free space가 증가된다.

그러나 items에서 실제로 데이터있는 것처럼 보인다.

2400801f

A1001 위치도 아래로 변경 A1002가 제일 아래로 내려감

A1001 원래 위치의 데이터는

그대로 두고 Item Id Data만 삭제

'A1001',‘B','A'

Page 14: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

③ 표준 vacuum

A1001 원래 위치의 데이터는 그대로 두고 Item Id Data만 삭제

• SELECT * from heap_page_items(get_raw_page('t2', 0));

• select xmin,xmax,ctid, * from t2;

Page 15: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

③ 표준 vacuum

A1001 원래 위치의 데이터는 그대로 두고 Item Id Data만 삭제

• SELECT * from heap_page_items(get_raw_page('t2', 0));

• select xmin,xmax,ctid, * from t2;

A1002가 제일 아래로 내려감

Page 16: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

③ 표준 vacuum

A1001 원래 위치의 데이터는 그대로 두고 Item Id Data만 삭제

• SELECT * from heap_page_items(get_raw_page('t2', 0));

• select xmin,xmax,ctid, * from t2;

A1002가 제일 아래로 내려감

A1001 위치도 아래로 변경

Page 17: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

• Full Vacuum

Full Vacuum을 하면 삭제되지 않았던 line pointer의 공간도 삭제된다.

Special

Page Header

'A1002','A','A''A1001',‘B','A'

Tuple Header

2000801f

line pointer

line pointer 삭제

Page 18: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

• select xmin,xmax,ctid, * from t2;

④ Full vacuum

line pointer 삭제

Page 19: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

표준 vacuum Full vacuum

처리 방식• 다른 자료가 저장될 수 있도록 빈 공간으로 표시

• OS 입장에서는 디스크의 여유 공간 확보가 불가

• 새 파일에 저장하는 방식

(pg_class의 relfilenode값이 변경)

• OS 입장에서 디스크의 여유 공간 확보가 가능

• 최적의 물리적 크기로 테이블 생성

처리 속도 Full vacuum보다는 시간이 적게 걸림 처리 속도가 매우 느려 시간이 오래 걸림

Lock 여부여러 다른 작업들과 함께 사용 가능select, update, insert, delete (단, ALTER TABLE는 안됨)

해당 테이블에 배타적 잠금을 지정하기 때문에 어떤 작업도함께 사용할 수 없음

Page 20: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅰ. Vacuum 시의 공간관리3. 표준 vacuum VS Full vacuum

표준 Vacuum

표준 Vacuum, Full Vacuum 후, 각각의 결과

Full Vacuum

Vacuum 전

Page 21: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

Page 22: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석1. Visibility Map

Visibility Map (≒ bitmap index)

• 각각의 heap relation은 VM을 통해 어떤 페이지가 모두 active 상태의 트랜잭션으로 보이는 튜플만 포함하는 지를 추적

• 메인 릴레이션 데이터를 따라서 저장이 되는데, filenode 번호 뒤에 ' _vm' 이라는 접미사가 붙는 형태로 생성

• 예를 들면, 릴레이션의 filenode가 ‘123’이면, vm은 ‘123_vm’ 형태로 생성

• 한 heap page당 1bit씩 저장

• bit는 vacuum 작업에 의해 설정이 되며, 페이지의 데이터 변경 작업에 의해서 clear될 수 있음

Page 23: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• 블록 1은 dead tuple 없는 ‘1’을 나타내므로 vacuum 작업이 필요 없다.

• 블록 2는 삭제된 튜플이 있기 때문에 ‘0’이 표시된다.

• 업데이트시에 새로 추가된 튜플은 dead tuple이 없지만 0으로 표시된다.

• Index-Only Scan시에 블록1의 튜플은 모두 존재한다고 알고있다.

출처: http://www.postgresqlinternals.org/index.php/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:4_9.jpg

레코드1

레코드3

레코드4

레코드2

레코드5

(레코드6)

레코드7

레코드8

레코드6A

레코드9

블록1

블록2

테이블A의 데이터 블록 테이블A의 Visibility Map (bitmap)

1 0

dead tuple이 없음

블록1 블록2

dead tuple 있을 수도 있고, 없을 수도 있음

1. Visibility Map

Page 24: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. Visibility map은 heap page당 한 비트씩 저장한다.

2. Visibility map 비트들은 오직 vacuum에 의해서 정해진다. 하지만 다른 페이지 내의 데이터 변경 작업(update, delete)에 의해서 clear 된다.

* Byte 단위로 한 bit씩 Little-endian 순서로 저장 ( 하위 비트부터 저장 )

VM Layout

VM Header

1. Visibility Map

Page 25: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석1. Visibility Map

1111 1110 1111 1111 1111 1111

0145 2367

A1080...A1084

A1085...A1089

A1100...A1104

A1105...A1109

A1110...A1114

A1040...A1044

A1045...A1049

A1050...A1054

A1060...A1064

A1065...A1069

A1070...A1074

A1075...A1079

A1000...A1004

A1005...A1009

A1020...A1024

A1025...A1029

1 2 3 4 5 6 70

16진수를 2진수로 변환

Page 26: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. t2 테이블에 120건 insert ( 24페이지 생성, 1 페이지당 5건 )

2. vacuum 실행

3. vm 페이지 Dump 전부 visible 이므로 “1111 1111 1111 1111 1111 1111” ( ff ff ff - hexa )

insert into t2 SELECT 'A' || generate_series(1000,1000+120-1),'A','A';vacuum t2 ;

1. Visibility Map

Page 27: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. 0번 페이지에서 1번째 레코드 삭제 * ctid ( 0,1 ) : 0번 페이지에서 1번째 레코드

2. vm 페이지 Dump 0번 페이지에 dead tuple이 발생해서 1번 Byte의 8번 Bit가 clear

“1111 1110 1111 1111 1111 1111”( fe ff ff – hexa )

delete from t2 where c1 = 'A1000' ;

1. Visibility Map

Page 28: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. 5번 페이지에서 1번째 레코드 삭제

2. vm 페이지 Dump 5번 페이지에 dead tuple이 발생해서 1번 Byte의 3번 Bit가 clear

“1101 1110 1111 1111 1111 1111”( de ff ff – hexa )

1. Visibility Map

delete from t2 where c1 = 'A1025' ;

Page 29: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. 10번 페이지에서 1번째 레코드 삭제

2. vm 페이지 Dump 10번 페이지에 dead tuple이 발생해서 2번 Byte의 6번 Bit가 clear

“1101 1110 1111 1011 1111 1111”( de fb ff – hexa )

1. Visibility Map

delete from t2 where c1 = 'A1050' ;

Page 30: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. 15번 페이지에서 1번째 레코드 삭제

2. vm 페이지 Dump 15번 페이지에 dead tuple 이 발생해서 2번 Byte의 1번 Bit가 clear

“1101 1110 0111 1011 1111 1111”( de 7b ff – hexa )

1. Visibility Map

delete from t2 where c1 = 'A1075' ;

Page 31: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. 16번 페이지에서 1번째 레코드, 17번 페이지에서 1번째 레코드를 삭제

2. vm 페이지 Dump 16,17번 페이지에 dead tuple이 발생해서 3번 Byte의 7,8번 Bit가 clear

“1101 1110 0111 1011 1111 1100”( de 7b fc – hexa )

delete from t2 where c1 in ( 'A1080','A1085' ) ;

1. Visibility Map

Page 32: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

1. 20번 페이지에서 1번째 레코드, 21번 페이지에서 1번째 레코드, 22번 페이지에서 1번째 레코드 삭제

2. vm 페이지 Dump 20,21,22번 페이지에 dead tuple이 발생해서 3번 Byte의 2,3,4번 Bit가 clear

“1101 1110 0111 1011 1000 1100”( de 7b 8c – hexa )

delete from t2 where c1 in ( 'A1100','A1105','A1110' ) ;

1. Visibility Map

Page 33: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

Free Space Map (≒ Freelist)

• 각 heap과 index relation은 fsm을 통해 릴레이션의 사용 가능한 공간을 추적

• 메인 릴레이션 데이터를 따라서 저장이 되는데, filenode 번호 뒤에 ' _fsm' 이라는 접미사가 붙는 형태로 생성

ex) 릴레이션의 filenode가 ‘123’이면, fsm은 ‘123_fsm’ 형태로 생성

• 각 fsm 페이지는 이진 트리로 구성되어 있으며 각 노드당 1byte

• 각 리프 노드는 heap page를 나타내거나 하위 레벨의 fsm 페이지를 나타냄

• 하위 레벨의 fsm 페이지에 각 heap 페이지의 사용 가능한 공간이 저장

• 상위 레벨은 하위 레벨로부터 모은 정보이기 때문에 루트는 최대값이 저장

2. Free Space Map

Page 34: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• 28 (Header) + 8191(13 레벨의 총합) = 8219 bytes

• 8219 - 8192(8k) = 27 bytes 초과

• 마지막 레벨인 4096 bytes 중 27 bytes 모자람 = 4069 bytes 즉, 테이블당 관리할 수 있는 페이지의 수 4069개

• 만약 FSM이 초과된다면 페이지가 하나 더 생김

2. Free Space Map

Header (28 byte)

2

4

8

16

4069

(8k = 8192 bytes)

13 레벨

Header (28 byte)

2

4

8

16

4069

1 1

(8k = 8192 bytes)

Page 35: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• 블록마다 1byte를 사용해서 공간을 BLCKSZ/ 256으로 나눈 값 유지 (1byte = 8bit = 28 =256)

• FSM value = Free space / (BLCKSZ/ 256) ex) 1024 / (8192/256) = 32

FSM Header

FSM Layout

2. Free Space Map

.

.

..

.

56

56 00

56 00

56 13

56

56

13

leafnode

1번 페이지Free space

2번 페이지Free space

Page 36: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• 1 페이지에 7건의 레코드가 적재된다.

• 21건의 레코드를 insert하면 3 페이지가 생성되고, FSM에는 2개만 보인다.

2. Free Space Map

• CREATE TABLE

• INSERT 0 21

.

.

..

.

13

13 00

13 00

13 13

13

FSM 2개

Page 37: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• Vacuum 작업이 처리되면 FSM에 반영이 된다.

VACUUM

2. Free Space Map

.

.

..

.

13

13 00

13 00

13 13

13

FSM 3개

13

13 00

Page 38: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• 2건을 delete 하면, FSM에 반영이 안 된다.

2. Free Space Map

DELETE 2

.

.

..

.

13

13 00

13 00

13 13

13 13

13 00 FSM 3개

Page 39: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• Vacuum 작업이 처리되면 FSM에 반영이 된다.

2. Free Space Map

VACUUM

.

.

..

.

56

56 00

56 00

56 13

56

56

13

13 00

Page 40: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• 19건을 Update 하면 페이지가 6개로 늘어나는데, FSM에는 반영이 되지 않는다. (5개)

2. Free Space Map

UPDATE 19

.

.

..

.

13

13 00

13 00

13 13

13

13

13

13

13 00

13 13 13 00 FSM 5개

Page 41: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Ⅱ. VM과 FSM 구조 분석

• Vacuum 작업이 처리되면 FSM에 반영이 된다. (6개 확인)

2. Free Space Map

VACUUM

.

.

..

.

fe

fe 00

fe 00

bb fe

fe

fe

fe

9a

9a 00

fe 13 13 9a FSM 6개

Page 42: PostgreSQL 공간관리 살펴보기 이근오

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

PG_DAY 2016Reference

1.https://en.wikipedia.org/wiki/PostgreSQL

2.http://postgresql.kr/docs/9.3/routine-vacuuming.html

3.http://www.postgresqlinternals.org/index.php/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:4_9.jpg

Page 43: PostgreSQL 공간관리 살펴보기 이근오

cafe.naver.com/playexem

Q & A

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Page 44: PostgreSQL 공간관리 살펴보기 이근오

NAVER http://cafe.naver.com/playexem

ITPUB (中) http://blog.itpub.net/31135309/

Wordpress https://playexem.wordpress.com/

Slideshare http://www.slideshare.net/playexem

Youtube https://www.youtube.com/channel/UC5wKR_-A0eL_Pn_EMzoauJg

Tudou (中) http://www.tudou.com/home/maxgauge/

교육 문의: 연구컨텐츠팀 김숙진

[email protected]

• Research & Contents Team

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.

Page 45: PostgreSQL 공간관리 살펴보기 이근오

cafe.naver.com/playexem

Thank You

© Copyrights 2001~2016, EXEM CO.,LTD. All Rights Reserved.