Search

DOCKER PG16 설치와 PG_HINT_PLAN

1. DOCKER 다운로드 및 설치

DOCKER란?
소프트웨어를 컨테이너 단위의 격리된 환경 안에서 실행하도록 해주는 오픈소스 가상화 플랫폼
DOCKER를 사용해 리눅스 환경의 PG를 설치 할 수 있습니다.
DOCKER 설치(4.33 기준 / Windows 11 기준)
다운로드 받은, Docker Desktop Installer 를 실행
Use WSL2 instead of Hyper-v 부분 체크가 나오면 체크하고 설치를 진행합니다.
WSL은 리눅스 커널을 직접 사용하여 Windows 상에서 리눅스 환경을 제공
경량화되어 있으며, 리눅스와 Windows 간의 파일 시스템 통합이 용이
주로 리눅스 개발 환경을 Windows에서 구현하려는 사용자에게 적합
WSL 2는 Docker와 더욱 통합되어 있어, 리눅스 컨테이너를 더 효율적으로 실행
WSL을 사용하려면 윈도우에 관련된 추가 설치가 필요할 수 있다.
상황에 따라 WSL2 설치가 필요합니다. 아래 글을 참고해 진행합니다.
설치 완료 후 host 파일 변경 복원 메시지 나올 수 있습니다.
저는 복원 안하고 넘어갔습니다.
DOCKER 메뉴
설치된 DOCKER는 윈도우즈 상의 Docker Desktop을 사용해 활용 가능합니다.
또는 윈도우즈의 Command 창으로도 Docker의 기능을 사용할 수 있습니다.
Docker Desktop 화면
윈도우즈에서 Docker Desktop을 실행하면 다음과 같은 화면이 나옵니다.
Images
어플리케이션 실행에 필요한 모든 파일과 코드, 설정의 패키지.
pull 을 통해 Postgre 이미지를 다운로드 할 수 있다.
Containers
이미지를 통해 만들어진 실행 가능한 어플리케이션
pull을 통해 저장된 postgre 이미지를 실행하면 postgre 컨테이너가 만들어지고,
만들어진 postgre 컨테이너에 접속해서 사용할 수 있다.
Volumes
컨테이너와 독립적으로 존재하는 데이터 공간
컨테이너에 생성되는 데이터를 컨테이너 외부에 저장할 수 있다.

2. POSTGRESQL 설치 및 시작

Docker의 Pull 명령어를 사용해 Postgresql 16.4 를 설치합니다.
1.
윈도우즈의 윈도우 버튼 클릭
2.
검색창에 cmd 입력
3.
명령 프롬프트를 선택해서 실행
cmd(명령 프롬프트) 창에서 다음 명령어를 실행합니다.
docker pull postgres:16.4
위 명령어를 실행하면 Linux(debian)의 PG 16.4 의 이미지를 현재 PC에 다운로드(pull) 합니다.
pull 로 다운로드한 이미지는 run 명령어를 통해 실제 접속해서 사용할 수 있는 pg16 컨테이너가 만들어집니다.
run 명령어는 이미지를 컨테이너로 만드는 것이기 때문에 pull한 후에 한 번만 실행하면 됩니다.
run은 이미지를 컨테이너로 만드는 것이므로, DBMS의 start/stop과는 다릅니다.
아래의 명령어로 pull 해 놓은 이미지 리스트를 확인할 수 있습니다.
docker images
Shell
복사
이미지가 정상적으로 pull 되었다면 아래와 같은 리스트를 확인할 수 있습니다.
아래 명령어로 이미지를 run 합니다.
run할 때 pg의 admin 계정인 postgres의 암호를 설정합니다.
postgres:16.4 이미지를 mypg라는 이름의 컨테이너로 생성합니다.
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=1qaz2wsx --name mypg postgres:16.4
Shell
복사

3. DBeaver로 PG 접속하기

아래 그림을 참고해 PG에 접속합니다.
디비버로 PG에 접속해, SQL창을 열고 다음 SQL로 연습용 데이터베이스(startdbpg)를 생성합니다.
CREATE DATABASE startdbpg;
SQL
복사
디비버에 startdb로 접속하는 컨넥션을 축가합니다.
PG는 MySQL처럼 특정 DB에 접속 후 DB를 변경할 수 없다.
Dbeaver에서 새로운 컨넥션을 추가
Database를 새로 만든 startdbpg로 설정한다.
아래 SQL로 확장팩 관련된 정보를 확인합니다.
SELECT * FROM pg_available_extensions; -- 설치 가능한 확장팩 SELECT * FROM pg_extension; -- 설치된 확장팩
SQL
복사

3. PG_HINT_PLAN 설치하기

PG는 힌트를 사용하기 위해서는 확장팩인 pg_hint_plan을 설치해야 합니다.
조금 복잡할 수 있습니다. 개인적으로 이렇게 복잡해서.. 나중에 관리가 될까 싶습니다.
아래 경로에서 pg_hint_plan rpm 파일을 다운로드 합니다.
여기서는 pg_hint_plan16-1.6.0-1.el8.x86_64.rpm 파일을 다운로드했습니다.
다운로드 받은 파일을, C 드라이드에 mypg_upload 이란 폴더에 카피해놓습니다.
다운로드 받은 파일을 pg 컨테이너에 올려야 하는데, 파일 단위가 아닌 폴더 단위로만 올릴 수 있습니다. 그러므로 폴더 하나에 다운로드한 rpm 파일 하나만 놓도록 합니다.
rpm 파일을 컨테이너에 업로드합니다.
Docker Desktop을 사용해 rpm 파일을 업로드합니다.
1.
containers를 선택합니다.
2.
mypg 컨테이너를 선택합니다.
3.
Files를 선택합니다.
4.
tmp 디렉토리에 마우스 우클릭 후 import를 선택합니다.
a.
앞에서 만든 mypg_upload 폴더를 선택하면 해당 폴더 채로 컨테이너에 업로드가 됩니다.
b.
업로드된 폴더를 확인할 수 있습니다.
rpm 파일을 설치합니다.
debian linux에서 rpm 을 직접 설치하는데 이슈가 있습니다.
alien을 사용해 rpm을 deb 형태 파일로 변환후 설치해야 합니다.
1.
Docker Desktop에서 컨테이너에 진입해 Exec 메뉴를 클릭합니다.
a.
여기서 Linux Shell 명령어를 실행할 수 있습니다.
2.
다음의 명령어들을 차례대로 하나씩 입력합니다.
a.
apt install alien 과정에서 y/n을 물으면 y를 선택합니다.
b.
alien 이후에 rpm 파일의 이름이 변경됩니다. _(언더바)가 -(대쉬)로 변경되니 주의하세요.
apt update apt install alien alien -d /tmp/mypg_upload/pg_hint_plan16-1.6.0-1.el8.x86_64.rpm dpkg -i pg-hint-plan16_1.6.0-2_amd64.deb
Shell
복사
3.
계속해서 EXEC창에서 다음 shell 명령어로 pg_hint_plan이 컨테이너에 잘 설치되어 있는지 확인합니다.
a.
pg_hint_plan.so란 파일이 보여지면 정상 설치된 것입니다.
ls /usr/pgsql-16/lib/
Shell
복사
4.
설치된 파일을 정상적인 경로로 카피해서 옮깁니다.
a.
설치한 파일 경로와 실제 컨테이너상에 실행되는, pg의 확장팩 경로가 맞지 않는거 같습니다. (아마도 확장팩 소스와 실제 컨테이너의 경로가 서로 상이한듯 합니다.)
b.
계속해서 EXEC 창에서 다음 명령어로 설치된 pg_hint_plan 모듈들을 정상 경로로 카피해줍니다.
i.
pg_hint_plan.so는 옮기지 않고 현재 경로에 그대로 둡니다.
ii.
/usr/pgsql-16/share/extension 에 설치된 파일만 다른 곳으로 옮깁니다.
cp -a /usr/pgsql-16/share/extension/* /usr/share/postgresql/16/extension/
Shell
복사
pg_hint_plan을 pg의 conf 파일에 등록합니다.
설치된 pg_hint_plan 모듈을 pg가 가동될 때 불러올 수 있도록 설정해야 합니다.
1.
컨테이너의 Files 메뉴를 선택
a.
var/lib/postgresql/data 폴더까지 내려갑니다.
2.
postgresql.conf 를 마우스 우클릭 후 Edit File을 선택합니다.
3.
아래 부분에 파일의 내용이 열립니다. shared_preload_libraries 부분의 주석을 제거하고 다음과 같이 수정합니다.
a.
기본 설치된 경로 문제인지 경로 없이 pg_hint_plan을 바로 설정하면 제대로 작동하지 않습니다.
shared_preload_libraries = 'pg_stat_statements, /usr/pgsql-16/lib/pg_hint_plan' # (change requires restart)
Shell
복사
4.
오른쪽 위에 저장 버튼을 누릅니다.
5.
컨테이너를 종료했다. 다시 시작합니다.
추가로, postgresql.conf (var/lib/postgresql/data) 에서 병렬 처리를 제한합니다.
방금 위에서 수정한 postgresql.conf 파일을 다시 엽니다.(열려 있다면 바로 수정하면 됩니다.)
1.
max_parallel_workers_per_gather 부분을 찾아서 주석을 제거하고 값을 0으로 설정합니다.
2.
저장합니다.
3.
종료 후 다시 시작합니다.
max_parallel_workers_per_gather = 0 # limited by max_parallel_workers
Python
복사

4. PG_HINT_PLAN 작동 확인하기

DBeaver를 사용해 앞에서 생성한 startdbpg에 재접속합니다.
아래 SQL로 설치된 pg_hint_plan을 확인합니다.
SELECT * FROM pg_available_extensions WHERE name like '%pg_hint%';
SQL
복사
DBeaver에서 다음 명령어로 확장팩을 사용할 수 있도록 합니다.
startdb에 접속해서 실행해야, startdb안에서 확장팩을 사용할 수 있습니다.
-- startdb에 확장팩 두 개를 설치합니다. -- pg_hint_plan은 추가 설치한 내용. -- pg_stat_statements는 기본 제공하는 확장팩(shared_preload에 추가해야 사용할 수 있음) CREATE EXTENSION pg_hint_plan; -- 힌트 관련 확장팩 CREATE EXTENSION pg_stat_statements; -- SQL 성능 수집 확장팩
SQL
복사
다음 SQL을 차례대로 입력해 힌트가 작동하는지 확인합니다.
힌트를 사용하지 않았을때는 Bitmap Index Scan를, 힌트를 사용한 경우에는 Index Scan이 작동합니다. 힌트로 인해 실행계획이 변경되므로 힌트가 작동함을 알 수 있습니다.
create table test(a varchar(10), c varchar(10)); create index test_x1 on test(a); insert into test(a,c)values('abc','abc'); insert into test(a,c)values('aaa','a12'); insert into test(a,c)values('ccc','cba'); EXPLAIN SELECT t1.* FROM test t1 WHERE t1.a = 'abc'; -- 위 SQL의 실행계획 Bitmap Heap Scan on test t1 (cost=4.18..12.64 rows=4 width=76) Recheck Cond: ((a)::text = 'abc'::text) -> Bitmap Index Scan on test_x1 (cost=0.00..4.18 rows=4 width=0) Index Cond: ((a)::text = 'abc'::text) EXPLAIN SELECT /*+ IndexScan(t1 test_x1) */ t1.* FROM test t1 WHERE t1.a = 'abc'; -- 힌트를 사용한 SQL의 실행계획(IndexScan으로 변경됨) Index Scan using test_x1 on test t1 (cost=0.15..20.22 rows=4 width=76) Index Cond: ((a)::text = 'abc'::text) -- 이후 데이터베이스 생서을 위해 test 테이블을 DROP 합니다. DROP TABLE IF EXISTS test;
SQL
복사