pg_trgm 을 이용한 전후위 like 검색

POSTGRESQL 2015. 4. 21. 17:12

하나의 컬럼에 대한 전후위 like 검색 시 인덱스 여부와 상관없이 table full scan 을 수행하는데 postgresql 은 pg_trgm 이라는 contrib 모듈을 통해 해결할 수 있습니다.

 

모듈 설치 전 실행계획입니다. 인덱스를 포함하는 컬럼에 대해 전후위 like 검색에 대하여 full scan을 수행합니다.

testdb=# explain analyze select * from test_table where test_column like '%TEXT%';
                                                     QUERY PLAN                                                      
---------------------------------------------------------------------------------------------------------------------
 Seq Scan on test_table  (cost=0.00..288431.08 rows=264 width=298) (actual time=952.905..1119.831 rows=6 loops=1)
   Filter: ((test_column)::text ~~ '%TEXT%'::text)
 Total runtime: 1119.854 ms
(3 rows)

 

contrib 모듈을 설치하고 해당 컬름으로 GIN INDEX를 생성합니다.
$ make && make install
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I. -I../../src/include -D_GNU_SOURCE   -c -o trgm_op.o trgm_op.c
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I. -I../../src/include -D_GNU_SOURCE   -c -o trgm_gist.o trgm_gist.c
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I. -I../../src/include -D_GNU_SOURCE   -c -o trgm_gin.o trgm_gin.c
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fpic -shared -o pg_trgm.so trgm_op.o trgm_gist.o trgm_gin.o -L../../src/port -Wl,--as-needed -Wl,-rpath,'/usr/local/pgsql/lib',--enable-new-dtags  
/bin/mkdir -p '/usr/local/pgsql/lib'
/bin/mkdir -p '/usr/local/pgsql/share/extension'
/bin/mkdir -p '/usr/local/pgsql/share/extension'
/bin/sh ../../config/install-sh -c -m 755  pg_trgm.so '/usr/local/pgsql/lib/pg_trgm.so'
/bin/sh ../../config/install-sh -c -m 644 ./pg_trgm.control '/usr/local/pgsql/share/extension/'
/bin/sh ../../config/install-sh -c -m 644 ./pg_trgm--1.0.sql ./pg_trgm--unpackaged--1.0.sql  '/usr/local/pgsql/share/extension/'
$ psql -p 5433 -d testdb -U pgdba
psql (9.2.8)
Type "help" for help.
testdb=# create extension pg_trgm;
CREATE EXTENSION
testdb=# CREATE INDEX trgm_idx ON test_table USING gin (test_column gin_trgm_ops);
CREATE INDEX

 

설치 후 인덱스 스캔으로 변경된 것을 확인할 수 있습니다.
testdb=# explain analyze select * from test_table where test_column like '%TEXT%';
                                                      QUERY PLAN                                                       
-----------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on test_table  (cost=22.42..1245.43 rows=313 width=298) (actual time=0.021..0.029 rows=6 loops=1)
   Recheck Cond: ((test_column)::text ~~ '%TEXT%'::text)
   ->  Bitmap Index Scan on trgm_idx  (cost=0.00..22.35 rows=313 width=0) (actual time=0.014..0.014 rows=6 loops=1)
         Index Cond: ((test_column)::text ~~ '%TEXT%'::text)
 Total runtime: 0.051 ms
(5 rows)
단, 3글자 미만에 대한 패턴검색 시 table full scan의 비용범위를 초과할정도로 인덱스 스캔비용이 급격히 증가하여 옵티마이져가 table seq scan을 강제하므로 글자수에 대한 제약사항 대처는 application레벨로 넘겨야 할 듯합니다.

prepare statements 와 casting

POSTGRESQL 2015. 4. 21. 16:32
상수값으로 잘 실행되는 SQL 구문이 parepare 구문을 이용하면 오류가 발생하는 경우가 있습니다. 이는 바인드변수로 SQL을 실행할때 묵시적형변환이 지원되지 않기 때문입니다.

 

상수값으로 실행한 결과입니다.
test=# create table test_table(col1 numeric);
CREATE TABLE
test=# insert into test_table values(1);
INSERT 0 1
test=# explain select col1 from test_table where col1 = '1';
                                  QUERY PLAN                                   
-------------------------------------------------------------------------
 Seq Scan on test_table  (cost=10000000000.00..10000000026.38 rows=7 width=32)
   Filter: (col1 = 1::numeric)
(2 rows)

 

prepare 구문으로 실행한 결과입니다.
test=# prepare foo(varchar) as
test-# select col1 from test_table where col1 = $1;
ERROR:  operator does not exist: numeric = character varying
LINE 2: select col1 from test_table where col1 = $1;
                                               ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
test=#

 

prepare 구문상 형변환을 명시하여 실행한 결과입니다.
test=# prepare foo(varchar) as
select col1 from test_table where col1 = $1::numeric;
PREPARE
test=# execute foo('1');
 col1 
------
    1
(1 row)

TEXT AWR 생성 및 파싱하기

ORACLE 2015. 4. 21. 16:24
AWR 레포트를 스냅샷 구간별로 텍스트파일을 통하여 생성하고, 파싱을 통하여 시간대별 챠트를 작성해 보았습니다.

1. 원하는 스냅샷 구간을 설정하여 AWR 레포트 파일을 출력하기 위한 사전 스크립트를 생성합니다. 스크립트 생성기 소스는 아래와 같습니다.
REM AWR-Generator.sql: Script for creating multiple consecutive Oracle AWR Reports
REM
REM Creates an output SQL script which, when run, will generate all AWR Reports
REM between the specificed start and end snapshot IDs, for all instances
REM
REM For educational purposes only - no warranty is provided
REM Test thoroughly - use at your own risk
REM
 
set feedback off
set echo off
set verify off
set timing off
 
-- Set AWR_FORMAT to "text" or "html"
define AWR_FORMAT = 'text'
define DEFAULT_OUTPUT_FILENAME = 'awr-generate.sql'
define NO_ADDM = 0
 
-- Get values for dbid and inst_num before calling awrinput.sql
 
set echo off heading on
column inst_num heading "Inst Num" new_value inst_num format 99999;
column inst_name heading "Instance" new_value inst_name format a12;
column db_name heading "DB Name" new_value db_name format a12;
column dbid heading "DB Id" new_value dbid format 9999999999 just c;
 
prompt
prompt Current Instance
prompt ~~~~~~~~~~~~~~~~
 
select d.dbid dbid
 , d.name db_name
 , i.instance_number inst_num
 , i.instance_name inst_name
 from v$database d,
 v$instance i;
-- Call the Oracle common input script to setup start and end snap ids
@@?/rdbms/admin/awrinput.sql
 
-- Ask the user for the name of the output script
prompt
prompt Specify output script name
prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~
prompt This script produces output in the form of another SQL script
prompt The output script contains the commands to generate the AWR Reports
prompt
prompt The default output file name is &DEFAULT_OUTPUT_FILENAME
prompt To accept this name, press  to continue, otherwise enter an alternative
prompt
 
set heading off
column outfile_name new_value outfile_name noprint;
select 'Using the output file name ' || nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME')
 , nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME') outfile_name
 from sys.dual;
 
set linesize 800
set serverout on
set termout off
 
-- spool to outputfile
spool &outfile_name
 
-- write script header comments
prompt REM Temporary script created by awr-generator.sql
prompt REM Used to create multiple AWR reports between two snapshots
select 'REM Created by user '||user||' on '||sys_context('userenv', 'host')||' at '||to_char(sysdate, 'DD-MON-YYYY HH24:MI') from dual;
 
set heading on
 
-- Begin iterating through snapshots and generating reports
DECLARE
 
c_dbid CONSTANT NUMBER := :dbid;
 c_inst_num CONSTANT NUMBER := :inst_num;
 c_start_snap_id CONSTANT NUMBER := :bid;
 c_end_snap_id CONSTANT NUMBER := :eid;
 c_awr_options CONSTANT NUMBER := &&NO_ADDM;
 c_report_type CONSTANT CHAR(4):= '&&AWR_FORMAT';
 v_awr_reportname VARCHAR2(100);
 v_report_suffix CHAR(5);
 
CURSOR c_snapshots IS
 select inst_num, start_snap_id, end_snap_id
 from (
 select s.instance_number as inst_num,
 s.snap_id as start_snap_id,
 lead(s.snap_id,1,null) over (partition by s.instance_number order by s.snap_id) as end_snap_id
 from dba_hist_snapshot s
 where s.dbid = c_dbid
 and s.snap_id >= c_start_snap_id
 and s.snap_id <= c_end_snap_id
 )
 where end_snap_id is not null
 order by inst_num, start_snap_id;
 
BEGIN
 
dbms_output.put_line('');
 dbms_output.put_line('prompt Beginning AWR Generation...');
 
dbms_output.put_line('set heading off feedback off lines 800 pages 5000 trimspool on trimout on');
 
-- Determine report type (html or text)
 IF c_report_type = 'html' THEN
 v_report_suffix := '.html';
 ELSE
 v_report_suffix := '.txt';
 END IF;
 
-- Iterate through snapshots
 FOR cr_snapshot in c_snapshots
 LOOP
 -- Construct filename for AWR report
 v_awr_reportname := 'awrrpt_'||cr_snapshot.inst_num||'_'||cr_snapshot.start_snap_id||'_'||cr_snapshot.end_snap_id||v_report_suffix;
 
dbms_output.put_line('prompt Creating AWR Report '||v_awr_reportname
 ||' for instance number '||cr_snapshot.inst_num||' snapshots '||cr_snapshot.start_snap_id||' to '||cr_snapshot.end_snap_id);
 dbms_output.put_line('prompt');
 
-- Disable terminal output to stop AWR text appearing on screen
 dbms_output.put_line('set termout off');
 
-- Set spool to create AWR report file
 dbms_output.put_line('spool '||v_awr_reportname);
 
-- call the table function to generate the report
 IF c_report_type = 'html' THEN
 dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_html('
 ||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
 ELSE
 dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_text('
 ||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
 END IF;
 
dbms_output.put_line('spool off');
 
-- Enable terminal output having finished generating AWR report
 dbms_output.put_line('set termout on');
 
END LOOP;
 
dbms_output.put_line('set heading on feedback 6 lines 100 pages 45');
 
dbms_output.put_line('prompt AWR Generation Complete');
 
-- EXCEPTION HANDLER?
 
END;
/
 
spool off
 
set termout on
 
prompt
prompt Script written to &outfile_name - check and run in order to generate AWR reports...
prompt
 
--clear columns sql
undefine outfile_name
undefine AWR_FORMAT
undefine DEFAULT_OUTPUT_FILENAME
undefine NO_ADDM
undefine OUTFILE_NAME
 
set feedback 6 verify on lines 100 pages 45

2. 스크립트를 실행하면 아래와 같은 과정을 거쳐 AWR TEXT파일이 생성됩니다.
SQL*Plus: Release 11.2.0.3.0 Production on Wed Feb 27 17:59:49 2013

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options

SQL> @awr-generator.sql

Current Instance
~~~~~~~~~~~~~~~~

   DB Id    DB Name      Inst Num Instance
----------- ------------ -------- ------------
 1334550050 ORCL                1 orcl

Instances in this Workload Repository schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   DB Id     Inst Num DB Name      Instance     Host
------------ -------- ------------ ------------ ------------
* 1334550050        1 ORCL         orcl         half-server4

Using 1334550050 for database Id
Using          1 for instance number

Specify the number of days of snapshots to choose from
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Entering the number of days (n) will result in the most recent
(n) days of snapshots being listed.  Pressing  without
specifying a number lists all completed snapshots.

Enter value for num_days: 1

Listing the last day's Completed Snapshots
                                                        Snap
Instance     DB Name        Snap Id    Snap Started    Level
------------ ------------ --------- ------------------ -----
orcl         ORCL              1389 27 Feb 2013 00:00      1
                               1390 27 Feb 2013 01:00      1
                               1391 27 Feb 2013 02:00      1
                               1392 27 Feb 2013 03:00      1
                               1393 27 Feb 2013 04:00      1
                               1394 27 Feb 2013 05:00      1
                               1395 27 Feb 2013 06:00      1
                               1396 27 Feb 2013 07:00      1
                               1397 27 Feb 2013 08:00      1
                               1398 27 Feb 2013 09:00      1
                               1399 27 Feb 2013 10:00      1
                               1400 27 Feb 2013 11:00      1
                               1401 27 Feb 2013 12:00      1
                               1402 27 Feb 2013 13:00      1
                               1403 27 Feb 2013 14:00      1
                               1404 27 Feb 2013 15:00      1
                               1405 27 Feb 2013 16:00      1
                               1406 27 Feb 2013 17:00      1

Specify the Begin and End Snapshot Ids
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enter value for begin_snap: 1400
Begin Snapshot Id specified: 1400

Enter value for end_snap: 1404
End   Snapshot Id specified: 1404

Specify output script name
~~~~~~~~~~~~~~~~~~~~~~~~~~
This script produces output in the form of another SQL script
The output script contains the commands to generate the AWR Reports

The default output file name is awr-generate.sql
To accept this name, press  to continue, otherwise enter an alternative

Enter value for outfile_name:

Using the output file name awr-generate.sql

Script written to awr-generate.sql - check and run in order to generate AWR reports...

SQL> @awr-generate.sql
Beginning AWR Generation...
Creating AWR Report awrrpt_1_1400_1401.txt for instance number 1 snapshots 1400 to 1401

Creating AWR Report awrrpt_1_1401_1402.txt for instance number 1 snapshots 1401 to 1402

Creating AWR Report awrrpt_1_1402_1403.txt for instance number 1 snapshots 1402 to 1403

Creating AWR Report awrrpt_1_1403_1404.txt for instance number 1 snapshots 1403 to 1404

AWR Generation Complete
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options
[oracle@server4 ~]$ ls -l awrrpt*
-rw-r--r--. 1 oracle oinstall 152333 Feb 27 18:00 awrrpt_1_1400_1401.txt
-rw-r--r--. 1 oracle oinstall 152676 Feb 27 18:00 awrrpt_1_1401_1402.txt
-rw-r--r--. 1 oracle oinstall 153511 Feb 27 18:00 awrrpt_1_1402_1403.txt
-rw-r--r--. 1 oracle oinstall 148614 Feb 27 18:00 awrrpt_1_1403_1404.txt


3. parser 를 리다이렉트와 함께 실행하면 아래와 같이 CSV 형태로 파일을 생성할 수 있습니다.
$ ./awr-parser.sh

Usage: ./awr-parser.sh [ -n | -H ] [ -s | -p | -v ]  (wildcards are accepted)

 Version v1.02 (published on 05/01/2015)

  Script for parsing multiple AWR reports and extracting useful information
  Redirect stdout to a CSV file to import into Excel
  Errors and info are printed to stderr

  Options:
    -h   Help        (print help and version information)
    -H   Header      (print the header row only and then exit)
    -n   NoHeader    (do not print the header row in the CSV file)
    -p   Print       (print AWR report values to screen)
    -s   Silent      (do not print AWR processing information)
    -v   Verbose     (show extra AWR processing details)

  Example usage:
    ./awr-parser.sh awr*.txt > awr.csv

$ ./awr-parser.sh SampleAWRs/*.txt > output.csv

Info : Parsing file SampleAWRs/awr_09h00_09h30.txt at 2014-12-01 15:43:00
Info : Parsing file SampleAWRs/awr_09h30_10h00.txt at 2014-12-01 15:43:58
Info : Parsing file SampleAWRs/awr_10h00_10h30.txt at 2014-12-01 15:44:53
Info : Parsing file SampleAWRs/awr_10h30_11h00.txt at 2014-12-01 15:45:51
Info : Parsing file SampleAWRs/awr_11h00_11h30.txt at 2014-12-01 15:46:51
Info : Parsing file SampleAWRs/awr_11h30_12h00.txt at 2014-12-01 15:47:45
Info : Parsing file SampleAWRs/awr_12h00_12h30.txt at 2014-12-01 15:48:38
Info : Parsing file SampleAWRs/awr_12h30_13h00.txt at 2014-12-01 15:49:35
Info : Parsing file SampleAWRs/awr_13h00_13h30.txt at 2014-12-01 15:50:31
Info : Parsing file SampleAWRs/awr_13h30_14h00.txt at 2014-12-01 15:51:26
Info : Parsing file SampleAWRs/awr_14h00_14h30.txt at 2014-12-01 15:52:24
Info : Parsing file SampleAWRs/awr_14h30_15h00.txt at 2014-12-01 15:53:47
Info : Parsing file SampleAWRs/awr_15h00_15h30.txt at 2014-12-01 15:55:07
Info : Parsing file SampleAWRs/awr_15h30_16h00.txt at 2014-12-01 15:56:12
Info : Parsing file SampleAWRs/awr_16h00_16h30.txt at 2014-12-01 15:57:14
Info : Parsing file SampleAWRs/awr_16h30_17h00.txt at 2014-12-01 15:58:14
Info : Parsing file SampleAWRs/awr_17h00_17h30.txt at 2014-12-01 15:59:16
Info : Parsing file SampleAWRs/awr_17h30_18h00.txt at 2014-12-01 16:00:20
Info : No more files found
Info :
Info : ______SUMMARY______
Info : Files found       : 18
Info : Files processed   : 18
Info : Processing errors : 0
Info :
Info : Completed successfully

 

4. 생성한 CSV 파일로 엑셀을 통하여 생성한 차트 예 입니다.


출처 : http://flashdba.com/database/useful-scripts




'ORACLE' 카테고리의 다른 글

sqlplus 백스페이스 사용하기  (0) 2014.12.09
sequence reset 프로시져  (0) 2014.10.26

[AIX] vi상 개행문자열로 치환하기

카테고리 없음 2015. 4. 6. 19:41
[AIX] vi상 개행문자열로 치환하기

 

:%s/[바꿀문자열]/[바꿀문자열]^M/g #ctrl v+M

sqlplus 백스페이스 사용하기

ORACLE 2014. 12. 9. 13:48
sqlplus 백스페이스 사용 시 profile에 아래와 같이 추가합니다.

 

$ vi ~/.bash_profile
stty erase ^H #추가

'ORACLE' 카테고리의 다른 글

TEXT AWR 생성 및 파싱하기  (0) 2015.04.21
sequence reset 프로시져  (0) 2014.10.26

C macro 사용 시 주의사항

C/C++ 2014. 12. 3. 11:18
C 코딩 간 macro 사용 시 연산자 우선순위를 고려하여 괄호처리를 해주는 것이 좋습니다.
아래는 잘못된 macro 설정사례입니다.
#define DANGER 60 + 2
위 사례는 아래와 같은 상황에서 잘못된 결과를 초래할 수 있습니다.
int wrong_value = DANGER * 2; //  124라는 결과 값 대신 60 + 2 * 2 = 64 가 할당됩니다.
괄호처리를 하여 아래와 같이 사용해야 합니다.
#define HARMLESS (60 + 2)

'C/C++' 카테고리의 다른 글

런타임 OS 식별 팁  (0) 2009.11.10

md5를 이용한 password hash value 구하기

POSTGRESQL 2014. 11. 26. 11:17
1. pgcrypto extension 을 생성합니다.
estdb=# create extension pgcrypto;
CREATE EXTENSION
testdb=# create table user_info(user_id varchar(30), password varchar(100));
CREATE TABLE
testdb=# insert into user_info values('id1', crypt('id1_password', gen_salt('md5')));
INSERT 0 1
testdb=# insert into user_info values('id2', crypt('id2_password', gen_salt('md5')));  
INSERT 0 1

 

2. 데이터를 조회할 때는 아래와 같이 SQL을 작성합니다.
testdb=# select user_id from user_info where user_id='id1' 
            and password = crypt('id1_password', password);
 user_id 
---------
 id1
(1 row)

testdb=# 

[9.4 beta]ALTER SYSTEM 구문을 이용한 파라메터 변경

POSTGRESQL 2014. 10. 29. 17:11
9.4 에 새롭게 적용될 ALTER SYSTEM 구문을 테스트해 보았습니다.
요약하자면 ALTER SYSTEM 구문을 통해 변경된 파라메터 이름과 value 는 postgresql.auto.conf 파일에 저장되며,
SQL 함수인 pg_reload_conf() 를 통해 reload 되는 방식입니다.
pg_settings 시스템뷰에서 정의하는 context 속성은 그대로 적용된듯 합니다.

1. ALTER SYSTEM 구문으로 파라메터값을 변경합니다.
(pg_reload_conf 함수 또는 pg_ctl reload 를 실행전까지 적용되지 않습니다.)
pg_test=# select context,name,setting from pg_settings
where name in ('enable_seqscan','authentication_timeout','max_connections');
  context   |          name          | setting 
------------+------------------------+---------
 sighup     | authentication_timeout | 60
 user       | enable_seqscan         | on
 postmaster | max_connections        | 100
(3 rows)

pg_test=# ALTER SYSTEM set authentication_timeout=30;
ALTER SYSTEM
pg_test=# ALTER SYSTEM set enable_seqscan = off;
ALTER SYSTEM
pg_test=# ALTER SYSTEM set max_connections = 1000;
ALTER SYSTEM
pg_test=# select context,name,setting from pg_settings
where name in ('enable_seqscan','authentication_timeout','max_connections');
  context   |          name          | setting 
------------+------------------------+---------
 sighup     | authentication_timeout | 60
 user       | enable_seqscan         | on
 postmaster | max_connections        | 100
(3 rows)


2. pg_reload_conf() 함수를 통해 reload 명령을 실행하고, 해당 파라메터의 변경된 값을 확인합니다.
(단, pg_settings.context 값이 postmaster인 경우 서버를 재기동해야 합니다.)
pg_test=# select pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)

pg_test=# select context,name,setting from pg_settings
where name in ('enable_seqscan','authentication_timeout','max_connections');
  context   |          name          | setting 
------------+------------------------+---------
 sighup     | authentication_timeout | 30
 user       | enable_seqscan         | off
 postmaster | max_connections        | 100
(3 rows)


3. reset 또는 default 구문을 이용하여 postgresql.conf 파일에 저장된 값으로 초기할 수 있습니다.
pg_test=# ALTER SYSTEM reset authentication_timeout;
ALTER SYSTEM
pg_test=# select pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)
pg_test=# select context,name,setting from pg_settings
where name in ('enable_seqscan','authentication_timeout','max_connections');
  context   |          name          | setting 
------------+------------------------+---------
 sighup     | authentication_timeout | 60
 user       | enable_seqscan         | off
 postmaster | max_connections        | 100
 


4. reset all 구문을 이용하여 모든 파라메터를 postgresql.conf 파일에 저장된 값으로 초기화 할 수 있습니다.
pg_test=# ALTER SYSTEM reset all;
ALTER SYSTEM

pg_test=# select pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)

pg_test=# select context,name,setting from pg_settings
where name in ('enable_seqscan','authentication_timeout','max_connections');
  context   |          name          | setting 
------------+------------------------+---------
 sighup     | authentication_timeout | 60
 user       | enable_seqscan         | on
 postmaster | max_connections        | 100
(3 rows)


※ data_directory파라메터와 block_size 등과 같이 context 구분이 internal인 파라메터는 변경할 수 없습니다.
pg_test=# alter system set data_directory='/data';
ERROR:  parameter "data_directory" cannot be changed

'POSTGRESQL' 카테고리의 다른 글

prepare statements 와 casting  (0) 2015.04.21
md5를 이용한 password hash value 구하기  (0) 2014.11.26
table inheritance(상속)  (0) 2014.10.28
max_connections 와 커널파라메터  (0) 2014.10.27
postgresql DBLINK 예제  (0) 2014.10.27

table inheritance(상속)

POSTGRESQL 2014. 10. 28. 10:40
postgreSQL은 테이블 생성시에 하나이상의 다른 테이블로부터의 상속기능을 제공합니다.
상속받은 테이블을 자식테이블, 상속대상 테이블을 부모테이블로 할때 자식테이블을 create table 시 INHERITS 옵션을 이용하여 부모테이블의 컬럼, check / not-null 제약조건을 상속받습니다.
아래는 자식테이블 생성 및 조회에 대한 예제입니다.

1. 부모테이블을 생성합니다.
postgres=# CREATE TABLE cities (
postgres(#     name            text,
postgres(#     population      float,
postgres(#     altitude        int     -- in feet
postgres(# );
CREATE TABLE
postgres=# \d+ cities
                       Table "public.cities"
   Column   |       Type       | Modifiers | Storage  | Description 
------------+------------------+-----------+----------+-------------
 name       | text             |           | extended | 
 population | double precision |           | plain    | 
 altitude   | integer          |           | plain    | 
Has OIDs: no


2. cities 테이블을 상속받는 자식테이블 capitals을 IHERIT 구문을 이용하여 생성합니다.
postgres=# CREATE TABLE capitals (
postgres(#     state           char(2)
postgres(# ) INHERITS (cities);
CREATE TABLE
postgres=# \d+ capitals;
                      Table "public.capitals"
   Column   |       Type       | Modifiers | Storage  | Description 
------------+------------------+-----------+----------+-------------
 name       | text             |           | extended | 
 population | double precision |           | plain    | 
 altitude   | integer          |           | plain    | 
 state      | character(2)     |           | extended | 
Inherits: cities
Has OIDs: no


3. 부모테이블에 대한 조회/수정/삭제 SQL은 자식테이블을 포함하여 조회/수정/삭제되며, only 옵션을 이용하여 하나의 테이블을 지정할 수 있습니다.
postgres=# insert into cities values('kms',10.23,1000);
INSERT 0 1
postgres=# insert into capitals values('kms',10.23,1000,'01');
INSERT 0 1
postgres=# select * from cities;
 name | population | altitude 
------+------------+----------
 kms  |      10.23 |     1000
 kms  |      10.23 |     1000
(2 rows)
                           ^
postgres=# select * from only cities;
 name | population | altitude 
------+------------+----------
 kms  |      10.23 |     1000
(1 row)


4. 상속받은 테이블을 부모테이블로 하는 또다른 자식테이블을 생성하면, 최상위 부모테이블에 대한 조회/수정/삭제질의는 전계층의 테이블을 포함합니다.
postgres=# create table streets(col1 char(1)) inherits(capitals);
insert into streets values ('kms',20.24,2100,02,'1');
INSERT 0 1

postgres=# select * from only cities;
 name | population | altitude 
------+------------+----------
 kms  |      10.23 |     1000
(1 row)

postgres=# select * from only capitals;
 name | population | altitude | state 
------+------------+----------+-------
 kms  |      10.23 |     1000 | 01
(1 row)

postgres=# select * from streets;
 name | population | altitude | state | col1 
------+------------+----------+-------+------
 kms  |      20.24 |     2100 | 2     | 1
(1 row)

postgres=# select * from cities;
 name | population | altitude 
------+------------+----------
 kms  |      10.23 |     1000
 kms  |      10.23 |     1000
 kms  |      20.24 |     2100
(3 rows)


※ 가독성을 높히기 위해 부모테이블을 대상으로 하는 쿼리를 작성할 때 테이블 후미에 *를 붙여 상속테이블이 포함될 것임을 표시하는 것을 권장합니다.
예시) select * from cities*;

max_connections 와 커널파라메터

POSTGRESQL 2014. 10. 27. 19:41
postgresql 의 max_connections 값을 증가시키고 나서 클러스터(인스턴스) 기동 시 다음과 같은 오류가 발생할 수 있습니다.
FATAL:  could not create semaphores: No space left on device
[2012-10-24 16:49:55.313 KST][][][][][20731]DETAIL:  Failed system call was semget(5433033, 17, 03600).
[2012-10-24 16:49:55.313 KST][][][][][20731]HINT:  This error does *not* mean that you have run out of disk space.
 It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number
 of semaphores (SEMMNS), would be exceeded.  You need to raise the respective kernel parameterively, reduce PostgreSQL's 
consumption of semaphores by reducing its max_connections parameter (currently 510).
 The PostgreSQL documentation contains more information about configuring your system for PostgreSQL.
이러한 오류는 max_connections 파라메터가 SEMMNI라는 세마포어 관련 커널 파라메터값을 초과해서 발생되는 오류로 커널 제한값을 늘리거나 postgresql의 max_connections 값을 줄여서 해결할 수 있습니다.
아래는 커널파라메터 값을 수정하는 방법입니다.(root권한이 필요합니다.)

1. 커널파라메터 확인 : Semaphore Limits 부분의 max number of arrays 항목을 확인합니다.
$ ipcs -l

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 67108864
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1

------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767

------ Messages: Limits --------
max queues system wide = 16
max size of message (bytes) = 65536
default max size of queue (bytes) = 65536


2. 커널파라메터 수정
$ vi /etc/sysctl.conf
kerlel.sem=250 256000 32 128    ## 네번째 값이 SEMMNI이고 이 값을 증가시켜야 합니다.(세마포어 배열의 최대갯수).
$ sysctl -p /etc/sysctl.conf    ## 수정한 값으로 리로드 합니다.
파라메터를 구하는 공식 :
SEMMNI = (max_connections + autovacuum_max_workers + 4) / 16