728x90

안녕하세요. IBM 커뮤니티에서 DBACCESS_COLUMNS 환경변수에 대한 질문을 올렸다가

Benjamin Thompson의 답변을 통해 rlwrap (readline wrapper) 이라는 유틸리티를 알게 되었습니다.

사실 알려진지는 꽤 된 것 같습니다만 저는 뒤늦게 알게되었네요 ^^;

리눅스나 유닉스용으로 설치패키지가 제공되네요. 리눅스의 경우는 yum 같은 툴을 이용해 설치하실 수 있습니다.

 

아래는 rlwrap을 이용해서 dbaccess를 실행한 과정입니다.

[informix@db2 ids1410fc3]$ alias dbaccess='DBACCESS_COLUMNS=1024 rlwrap dbaccess'
[informix@db2 ids1410fc3]$ dbaccess stores_demo -
Database selected.
> select * from customer;
customer_num fname           lname           company              address1             address2             city            state zipcode phone
         101 Ludwig          Pauli           All Sports Supplies  213 Erstwild Court                        Sunnyvale       CA    94086   408-789-8075
         102 Carole          Sadler          Sports Spot          785 Geary St                              San Francisco   CA    94117   415-822-1289
         103 Philip          Currie          Phil's Sports        654 Poplar           P. O. Box 3498       Palo Alto       CA    94303   415-328-4543
         104 Anthony         Higgins         Play Ball!           East Shopping Cntr.  422 Bay Road         Redwood City    CA    94026   415-368-1100
         105 Raymond         Vector          Los Altos Sports     1899 La Loma Drive                        Los Altos       CA    94022   415-776-3249
         106 George          Watson          Watson & Son         1143 Carver Place                         Mountain View   CA    94063   415-389-8789
         107 Charles         Ream            Athletic Supplies    41 Jordan Avenue                          Palo Alto       CA    94304   415-356-9876
         108 Donald          Quinn           Quinn's Sports       587 Alvarado                              Redwood City    CA    94063   415-544-8729
         109 Jane            Miller          Sport Stuff          Mayfair Mart         7345 Ross Blvd.      Sunnyvale       CA    94086   408-723-8789
         110 Roy             Jaeger          AA Athletics         520 Topaz Way                             Redwood City    CA    94062   415-743-3611
         111 Frances         Keyes           Sports Center        3199 Sterling Court                       Sunnyvale       CA    94085   408-277-7245
         112 Margaret        Lawson          Runners & Others     234 Wyandotte Way                         Los Altos       CA    94022   415-887-7235
         113 Lana            Beatty          Sportstown           654 Oak Grove                             Menlo Park      CA    94025   415-356-9982
         114 Frank           Albertson       Sporting Place       947 Waverly Place                         Redwood City    CA    94062   415-886-6677
         115 Alfred          Grant           Gold Medal Sports    776 Gary Avenue                           Menlo Park      CA    94025   415-356-1123
         116 Jean            Parmelee        Olympic City         1104 Spinosa Drive                        Mountain View   CA    94040   415-534-8822
         117 Arnold          Sipes           Kids Korner          850 Lytton Court                          Redwood City    CA    94063   415-245-4578
         118 Dick            Baxter          Blue Ribbon Sports   5427 College                              Oakland         CA    94609   415-655-0011
         119 Bob             Shorter         The Triathletes Club 2405 Kings Highway                        Cherry Hill     NJ    08002   609-663-6079
         120 Fred            Jewell          Century Pro Shop     6627 N. 17th Way                          Phoenix         AZ    85016   602-265-8754
         121 Jason           Wallack         City Sports          Lake Biltmore Mall   350 W. 23rd Street   Wilmington      DE    19898   302-366-7511
         122 Cathy           O'Brian         The Sporting Life    543 Nassau Street                         Princeton       NJ    08540   609-342-0054
         123 Marvin          Hanlon          Bay Sports           10100 Bay Meadows Ro Suite 1020           Jacksonville    FL    32256   904-823-4239
         124 Chris           Putnum          Putnum's Putters     4715 S.E. Adams Blvd Suite 909C           Bartlesville    OK    74006   918-355-2074
         125 James           Henry           Total Fitness Sports 1450 Commonwealth Av                      Brighton        MA    02135   617-232-4159
         126 Eileen          Neelie          Neelie's Discount Sp 2539 South Utica Str                      Denver          CO    80219   303-936-7731
         127 Kim             Satifer         Big Blue Bike Shop   Blue Island Square   12222 Gregory Street Blue Island     NY    60406   312-944-5691
         128 Frank           Lessor          Phoenix University   Athletic Department  1817 N. Thomas Road  Phoenix         AZ    85008   602-533-1817
28 row(s) retrieved.
> select * from customer;

rlwrap을 통해 dbaccess를 실행하면 프롬프트에서 화살표키를 사용해 이전에 수행한 문장을 불러올 수 있습니다.

 

또한 12.10.xC9 버전부터 dbaccess의 라인이 80자 이상 출력이 가능하도록 DBACCESS_COLUMNS라는 환경변수가 추가되었습니다. 이 기능을 dbaccess를 실행할 때 같이 응용하면 좋을 것 같네요.

 

728x90
728x90

인포믹스 12.10.FC14버전에서 발견된 defect를 공유드립니다.

경우에 따라서는 심각한 문제가 될 것 같은데요. LPAD와 RPAD 함수 사용시 발생하는 문제입니다.

 

오류가 발생하는 조건은 아래와 같습니다.

1) multi-byte character set으로 구성된 데이터베이스 (en_us.utf8, ko_kr.ksc, ko_kr.949등)

2) source string이 varchar 또는 lvarchar 타입일 경우

3) source string이 empty string('')인 경우

 

상당히 오류가 발생할 가능성이 높은 조건입니다. 아래는 오류를 재현한 과정입니다.

/work2/INFORMIX/1210FC14]export DB_LOCALE=en_us.utf8
/work2/INFORMIX/1210FC14]export CLIENT_LOCALE=en_us.utf8
/work2/INFORMIX/1210FC14]echo "create database tdb with log"  | dbaccess -
Database created.
Database closed.
/work2/INFORMIX/1210FC14]dbaccess tdb -
Database selected.
> select lpad ( '', 2, '0' ) from sysmaster:sysdual;
  202: An illegal character has been found in the statement.
Error in line 1
Near character position 48
> select rpad ( '', 2, '0' ) from sysmaster:sysdual;
  202: An illegal character has been found in the statement.
Error in line 1
Near character position 48
>

IBM Community에 문의한 결과 이번 문제는 APAR IT32236 LPAD() and RPAD() on empty string getting -202 when used in multi-byte character set database로 확정되었습니다.

 

12.10.xC14 Fix Pack이 공개된지 얼마되지 않았는데 안타깝네요.

기존에는 문제없이 작동하는 기능이었기 때문에 패치적용시 우선적으로 고려해야 할 사항입니다.

 

추가로 확인된 바로는 12.10.xC15에서 수정될 예정입니다. 2020년 2분기에 공개될 예정입니다.

728x90
728x90

안녕하세요. 요즘 IBM 커뮤니티에서 열심히 댓글놀이를 하고 있는데요. 며칠전에 Informix에서 문자열에 대한 최빈값(MODE)을 구하는 방법에 대한 질문글이 올라왔습니다. 최빈값은 통계학에서 쓰는 용어로 액셀이나 분석 솔루션에서 MODE라는 함수로 사용되기도 합니다. 아래는 위키백과의 최빈값에 대한 설명입니다.

 

최빈값(最頻-), 모드(mode)는 통계학 용어로, 가장 많이 관측되는 수, 즉 주어진 값 중에서 가장 자주 나오는 값이다. 예를 들어, {1, 3, 6, 6, 6, 7, 7, 12, 12, 17}의 최빈값은 6이다. 최빈값은 산술 평균과 달리 유일한 값이 아닐 수도 있다.

또한 주어진 자료나 관측치의 값이 모두 다른 경우에는 존재하지 않는다.

주어진 자료에서 평균이나 중앙값을 구하기 어려운 경우에 특히 유용하다.

 

그런데 최빈값이라 함은 숫자가 대상이지 문자열은 아닙니다. 그리고 SQL에서는 MODE라는 함수가 따로 제공되는 것도 아니어서 문자열을 대상으로 하려면 별도의 로직을 구현해야합니다.

질문에서 제시하는 샘플데이터와 원하는 결과세트는 아래와 같습니다.

 

<샘플데이터>

Name dob score
JESSE 1992/10/27 10
JESSE 1992/10/27 20
JESSE 1992/11/06 30
JESSE 1992/11/11 40
JESSICA 1992/03/11 50
JESSICA 1992/11/03 60
JESSICA 1992/10/29 70
JESSICA 1992/11/10 80
JESSICA 1992/11/30 90
JESSICA 1992/11/12 10
JESSICA 1992/12/07 20
JESSICA 1992/12/09 30

 

<결과세트>

Name dob avg(score)
JESSE 1992/12/07  
JESSICA 1992/11/??  

 

결과세트에서 요구하는 사항은 다음과 같습니다.

1) 이름별로 가장 연도와 월 기준으로 가장 많은 값을 찾는다.

2) 일자는 해당 월의 아무 일자나 허용한다.

3) 1에서 찾은 값의 개수가 같은 것이 있으면 연도, 월, 일자를 같은 값을 우선한다.

 

그래서 이리저리 검색을 해서 아래와 같은 쿼리를 만들었습니다.

WITH t1 AS
(
SELECT 'JESSE' Name, '1992/10/27' dob, 10 score 
UNION ALL SELECT 'JESSE', '1992/10/27', 20 
UNION ALL SELECT 'JESSE', '1992/11/06', 30 
UNION ALL SELECT 'JESSE', '1992/11/11', 40 
UNION ALL SELECT 'JESSICA', '1992/03/11', 50 
UNION ALL SELECT 'JESSICA', '1992/11/03', 60 
UNION ALL SELECT 'JESSICA', '1992/10/29', 70 
UNION ALL SELECT 'JESSICA', '1992/11/10', 80 
UNION ALL SELECT 'JESSICA', '1992/11/30', 90 
UNION ALL SELECT 'JESSICA', '1992/11/12', 10 
UNION ALL SELECT 'JESSICA', '1992/12/07', 20  
UNION ALL SELECT 'JESSICA', '1992/12/09', 30 
)
SELECT a.Name,
       a.dob,
       a.avg	  
  FROM (SELECT t1.Name, 
               t1.dob, 
               ROW_NUMBER() OVER (PARTITION BY t1.Name ORDER BY COUNT(*) DESC) rn, 
               AVG(t1.score) OVER (PARTITION BY t1.Name) avg
          FROM t1,
               (SELECT t1.Name, 
                       t1.dob[1,7], 
                       RANK() OVER (PARTITION BY t1.Name ORDER BY COUNT(*) DESC) rk
                  FROM t1
                 GROUP BY t1.Name, t1.dob[1,7]
               ) t2
         WHERE t2.rk = 1
           AND t1.Name = t2.Name
           AND t1.dob like t2.dob||'%'
         GROUP BY t1.Name, t1.dob, t1.score
       ) a
 WHERE rn =1

쿼리의 흐름은 다음과 같습니다.

1) 이름을 기준으로 연도,월별 개수가 가장 많은 것을 구합니다. 가장 많은 개수가 같을 경우를 고려해 RANK 함수를 사용합니다. 그러면 같은 랭킹인 경우는 모두 첫번째가 됩니다.

2) 1에서 구한 데이터를 기준으로 일자를 포함하여 개수가 가장 많은 것을 구합니다. 여기선 월별로 일자 하나만 선택해야하므로 ROW_NUMBER를 사용합니다.

 

아래는 실행한 결과입니다.

[informix@db2 skjeong]$ dbaccess stores_demo mode.sql
Database selected.
name    dob                     avg
JESSE   1992/10/27 25.0000000000000
JESSICA 1992/11/30 60.0000000000000
2 row(s) retrieved.

 

인포믹스에서의 예제이긴 하지만 대부분의 RDBMS에서 지원하는 함수이기 때문에 필요한 경우 적용하기는 어렵지 않으실겁니다. 혹시 이 글을 읽는 분들께서 더 나은 방법을 알고 계시다면 조언 부탁드리겠습니다.

 

제가 참고한 사이트는 아래와 같습니다.

https://www.mssqltips.com/sqlservertip/3543/calculate-the-statistical-mode-in-sql-server-using-tsql/

 

 

데이터베이스 사랑넷에 자문을 구해 쿼리를 수정해보고, 새로운 쿼리도 알게 됐습니다.

위의 요구사항보다 조건을 좀 더 구체적으로 설정했습니다.

 

1) 평균은 월평균이 되어야한다. 이전 것은 이름만 기준으로한 평균

2) 가장 많은 갯수가 동일할 경우의 우선순위는? (빠른 날짜, 느린 날짜, 낮은 평균, 높은 평균 등)

여기서는 빠른 날짜를 기준으로 합니다.

 

아래는 수정된 쿼리입니다. 제가 수정한 쿼리는 마농님의 조언에 따라 약간 수정한 것입니다.

테스트를 위해 WITH절에  샘플 레코드를 추가했습니다.

--- 제가 수정한 쿼리
WITH t1 AS
(
SELECT 'JESSE' Name , '1992/08/06' dob, 30 score
UNION ALL SELECT 'JESSE', '1992/08/06', 40 
UNION ALL SELECT 'JESSE', '1992/07/27', 10
UNION ALL SELECT 'JESSE', '1992/07/27', 20 
UNION ALL SELECT 'JESSE', '1992/11/06', 30 
UNION ALL SELECT 'JESSE', '1992/11/11', 40 
UNION ALL SELECT 'JESSICA', '1992/03/11', 50 
UNION ALL SELECT 'JESSICA', '1992/11/03', 60 
UNION ALL SELECT 'JESSICA', '1992/10/29', 70 
UNION ALL SELECT 'JESSICA', '1992/11/10', 80 
UNION ALL SELECT 'JESSICA', '1992/11/30', 90 
UNION ALL SELECT 'JESSICA', '1992/11/12', 10 
UNION ALL SELECT 'JESSICA', '1992/12/07', 20  
UNION ALL SELECT 'JESSICA', '1992/12/09', 30 
)
SELECT a.Name,
       a.dob,
       a.avg	  
  FROM (SELECT t1.Name, 
               t1.dob, 
               ROW_NUMBER() OVER (PARTITION BY t1.Name ORDER BY COUNT(*) DESC, t1.dob ASC) rn, 
               AVG(t1.score) OVER (PARTITION BY t1.Name, t1.dob[1,7] ) avg
          FROM t1,
               (SELECT t1.Name, 
                       t1.dob[1,7], 
                       RANK() OVER (PARTITION BY t1.Name ORDER BY COUNT(*) DESC) rk
                  FROM t1
                 GROUP BY t1.Name, t1.dob[1,7]
               ) t2
         WHERE t2.rk = 1
           AND t1.Name = t2.Name
           AND t1.dob like t2.dob||'%'
         GROUP BY t1.Name, t1.dob, t1.score
       ) a
 WHERE rn =1
--- 마농님의 쿼리 (WITH문 생략)
SELECT *
  FROM (SELECT name
             , dob
             , avg_m
             , ROW_NUMBER() OVER(
               PARTITION BY name ORDER BY cnt_m DESC, cnt_d DESC, dob) rn
          FROM (SELECT name
                     , dob
                     , COUNT(*)   OVER(PARTITION BY name, dob[1,7]) cnt_m
                     , COUNT(*)   OVER(PARTITION BY name, dob     ) cnt_d
                     , AVG(score) OVER(PARTITION BY name, dob[1,7]) avg_m
                  FROM t1
                ) a
        ) a
 WHERE rn = 1
;

제가 올린 질문글은 아래 링크에서 참고해주세요.

http://database.sarang.net/?inc=read&aid=3484&criteria=informix&subcrit=qna&id=&limit=20&keyword=&page=1

728x90
728x90

Lab 1에 이은 Lab 2입니다. replica를 만들고 모니터링하는 방법을 실습하는 내용입니다.

 

---- Scale apps with replicas

1. replica set 업데이트

먼저 Lab 1에서 배포한 deployment를 조회합니다.

[root@db2 Lab 2]# kubectl get deployment 
NAME          READY   UP-TO-DATE   AVAILABLE   AGE 
hello-world   1/1     1            1           30m

 

edit명령으로 deployment 설정파일을 수정합니다.

kubectl edit deployment

spec: 
  progressDeadlineSeconds: 600 
  replicas: 1                            // 1을 10으로 변경하고 저장 //
  revisionHistoryLimit: 10 
  selector: 
    matchLabels: 
      run: hello-world 
  strategy: 
    rollingUpdate: 
      maxSurge: 25% 
      maxUnavailable: 25% 
    type: RollingUpdate 
  template: 
    metadata: 
      creationTimestamp: null 
      labels: 
        run: hello-world 
[root@db2 Lab 2]# kubectl edit deployment hello-world 
deployment.apps/hello-world edited 


2. 변경한 사항 적용하기


kubectl rollout status deployment/hello-world

[root@db2 Lab 2]# kubectl rollout status deployment/hello-world
deployment "hello-world" successfully rolled out


3. pod 확인하기

kubectl get pods

[root@db2 Lab 2]# kubectl get pods 
NAME                           READY   STATUS    RESTARTS   AGE 
hello-world-684dfdd9c5-b48hq   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-gjf4p   1/1     Running   0          35m 
hello-world-684dfdd9c5-jqssq   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-nwx8x   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-p9ccg   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-q6grb   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-sw7qt   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-tbswg   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-vq9jn   1/1     Running   0          2m32s 
hello-world-684dfdd9c5-w8xwp   1/1     Running   0          2m32s 



----------- Update and roll back apps

1. 새 컨테이너 빌드

ibmcloud cr build --tag us.icr.io/<my_namespace>/hello-world:2 .

[root@db2 Lab 2]# ibmcloud cr build --tag us.icr.io/skjeong4/hello-world:2 . 
Sending build context to Docker daemon  14.85kB 
Step 1/6 : FROM node:9.4.0-alpine 
 ---> b5f94997f35f 
Step 2/6 : COPY app.js . 
 ---> Using cache 
 ---> 7709ec5f4400 
Step 3/6 : COPY package.json . 
 ---> Using cache 
 ---> e7a815f63218 
Step 4/6 : RUN npm install &&    apk update &&    apk upgrade 
 ---> Using cache 
 ---> 8cf455abe99a 
Step 5/6 : EXPOSE  8080 
 ---> Using cache 
 ---> 6d43110f568e 
Step 6/6 : CMD node app.js 
 ---> Using cache 
 ---> 34a819beea5a 
Successfully built 34a819beea5a 
Successfully tagged us.icr.io/skjeong4/hello-world:2 
The push refers to repository [us.icr.io/skjeong4/hello-world] 
99f142d4db2d: Layer already exists 
9043b37014f9: Layer already exists 
7eab2e812ea7: Layer already exists 
0804854a4553: Layer already exists 
6bd4a62f5178: Layer already exists 
9dfa40a0da3b: Layer already exists 
2: digest: sha256:a22a1e31c72344a671dad2c2343bb9238929b3c140306b986a187fc16e268c93 size: 1576 
OK 
[root@db2 Lab 2]# ibmcloud cr images 
Listing images... 
Repository                       Tag      Digest         Namespace   Created      Size    Security status 
us.icr.io/skjeong4/hello-world   2        a22a1e31c723   skjeong4    1 hour ago   27 MB   No Issues 
us.icr.io/skjeong4/hello-world   latest   a22a1e31c723   skjeong4    1 hour ago   27 MB   No Issues 
OK 


2. 새 컨테이너를 기존 deployment에 업데이트

kubectl set image deployment/hello-world hello-world=us.icr.io//hello-world:2

[root@db2 Lab 2]# kubectl set image deployment/hello-world hello-world=us.icr.io/skjeong4/hello-world:2 
deployment.apps/hello-world image updated 


3. 업데이트 내역 확인

kubectl rollout status deployment/hello-world
kubectl get replicasets

[root@db2 Lab 2]# kubectl rollout status deployment/hello-world 
deployment "hello-world" successfully rolled out 
[root@db2 Lab 2]# kubectl get replicasets 
NAME                     DESIRED   CURRENT   READY   AGE 
hello-world-5c6cb477cf   10        10        10      5m12s 
hello-world-684dfdd9c5   0         0         0       109m 


4. 어플리케이션 실행 테스트 (curl 또는 웹)

curl <public-IP>:<nodeport>

[root@db2 Lab 2]# curl xxx.xxx.xx.xxx:32412 
Hello world from hello-world-5c6cb477cf-7r9dv! Your app is up and running in a cluster! 


5. 업데이트 롤백하기

kubectl rollout undo deployment/<name-of-deployment>

[root@db2 Lab 2]# kubectl rollout undo deployment/hello-world 
deployment "hello-world" successfully rolled out


---- Check the health of apps

1. Lab 2 디렉토리의 healthcheck.yml 파일 수정

image: ".icr.io//hello-world:2"
=> image: ".icr.io/skjeong4/hello-world:2"

2. IBM 클라우드의 클러스터 대시보드에서 디플로이먼트/파드/레플리카셋등 확인

728x90

'cloud' 카테고리의 다른 글

Kubernetes Essentials with IBM Cloud - Lab 1  (0) 2020.03.18
728x90

요즘 IBM Badge 모으는 재미에 빠졌네요. 오늘은 쿠버네티스 기본에 대해서 공부했습니다.

과정명은 Container & Kubernetes Essentials with IBM Cloud입니다.

Lab 1의 과정을 정리해봤습니다. 제가 연습한 실습 환경은 CentOS 7입니다.

아래 사이트를 순서대로 따라한 것입니다. 조금 시행착오는 있을 수 있는데 어렵지 않습니다.

 

참고 사이트 :

https://cloud.ibm.com/docs/cli?topic=cloud-cli-getting-started

https://github.com/IBM/container-service-getting-started-wt

 

---- 초기 구성


1. IBM Cloud CLI 설치

Linux에서 IBM Cloud에 접근할 수 있는 커맨드라인 인터페이스를 설치합니다.

curl -sL https://ibm.biz/idt-installer | bash

 

2. IBM Cloud 로그인

ibmcloud login -a cloud.ibm.com -r us-south -g default

ibmcloud ks cluster config --cluster bpkadubd0gijteu5rpt0

[root@db2 ~]# ibmcloud ks cluster ls
OK
Name        ID                     State    Created      Workers   Location   Version       Resource Group Name   Provider
mycluster   bpkadubd0gijteu5rpt0   normal   5 days ago   1         Dallas     1.16.7_1524   default               classic



---- IBM Cloud에 이미지 푸시

1. 네임스페이스 추가
<참고> 도커 데몬이 실행중인지 확인, 실행중이 아니라면 도커 데몬 실행
systemctl status docker
systemctl start docker

ibmcloud cr login
ibmcloud cr namespace-add <my_namespace>

[root@db2 Lab 1]# ibmcloud cr namespace-add skjeong4 
Adding namespace 'skjeong4'... 
Successfully added namespace 'skjeong4' 
OK 

 

2. Lab 1 폴더로 이동하여 도커 이미지 빌드

 

ibmcloud cr build --tag us.icr.io/<my_namespace>/hello-world .

[root@db2 Lab 1]# ibmcloud cr build --tag us.icr.io/skjeong4/hello-world . 
Sending build context to Docker daemon  14.85kB 
Step 1/6 : FROM node:9.4.0-alpine 
 ---> b5f94997f35f 
Step 2/6 : COPY app.js . 
 ---> Using cache 
 ---> 7709ec5f4400 
Step 3/6 : COPY package.json . 
 ---> Using cache 
 ---> e7a815f63218 
Step 4/6 : RUN npm install &&    apk update &&    apk upgrade 
 ---> Using cache 
 ---> 8cf455abe99a 
Step 5/6 : EXPOSE  8080 
 ---> Using cache 
 ---> 6d43110f568e 
Step 6/6 : CMD node app.js 
 ---> Using cache 
 ---> 34a819beea5a 
Successfully built 34a819beea5a 
Successfully tagged us.icr.io/skjeong4/hello-world:latest 
The push refers to repository [us.icr.io/skjeong4/hello-world] 
99f142d4db2d: Pushed 
9043b37014f9: Pushed 
7eab2e812ea7: Pushed 
0804854a4553: Pushed 
6bd4a62f5178: Pushed 
9dfa40a0da3b: Pushed 
latest: digest: sha256:a22a1e31c72344a671dad2c2343bb9238929b3c140306b986a187fc16e268c93 size: 1576 
OK


3. 도커 이미지 빌드 확인

[root@db2 Lab 1]# ibmcloud cr images 
Listing images... 
Repository                       Tag      Digest         Namespace   Created          Size    Security status 
us.icr.io/skjeong4/hello-world   latest   a22a1e31c723   skjeong4    30 minutes ago   27 MB   No Issues 
OK

 


---- 배포

1. 클러스터 설정 파일 가져오기 및 환경변수 적용

ibmcloud ks cluster-config <yourclustername>

[root@db2 Lab 1]# ibmcloud ks cluster-config mycluster 
WARNING: This legacy command is deprecated and will soon be unsupported. Use the 'ibmcloud ks cluster config' command instead. 
For more information, see 'https://ibm.biz/iks-cli-v1' 
WARNING: The behavior of this command in your current CLI version is deprecated, and becomes unsupported when CLI version 1.0 is released in March 2020. To use the new behavior now, set the 'IKS_BETA_VERSION' environment variable. In bash, run 'export IKS_BETA_VERSION=1'. 
Note: Changing the beta version can include other breaking changes. For more information, see 'https://ibm.biz/iks-cli-v1' 
OK 
The configuration for mycluster was downloaded successfully. 
Export environment variables to start using Kubernetes. 
export KUBECONFIG=/root/.bluemix/plugins/container-service/clusters/mycluster/kube-config-hou02-mycluster.yml 


2. 클러스터에 이미지 배포 - pod 생성

kubectl run hello-world --image=us.icr.io/<namespace>/hello-world

[root@db2 Lab 1]# kubectl delete deployment hello-world 
deployment.apps "hello-world" deleted 
[root@db2 Lab 1]# kubectl run hello-world --image=us.icr.io/skjeong4/hello-world 
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. 
deployment.apps/hello-world created 



3. pod 생성 확인

kubectl get pods

[root@db2 Lab 1]# kubectl get pods
NAME                           READY   STATUS              RESTARTS   AGE
hello-world-684dfdd9c5-gjf4p   0/1     ContainerCreating   0          5s
[root@db2 Lab 1]# kubectl get pods
NAME                           READY   STATUS    RESTARTS   AGE
hello-world-684dfdd9c5-gjf4p   1/1     Running   0          10s


참고 > pod 생성에 오류가 있는 경우 확인 방법

[root@db2 Lab 1]# kubectl get pods 
NAME                           READY   STATUS         RESTARTS   AGE 
hello-world-5dd7d6d7d4-78g4h   0/1     ErrImagePull   0          3s 
[root@db2 Lab 1]# kubectl delete deployment hello-world 
deployment.apps "hello-world" deleted 
[root@db2 Lab 1]# kubectl describe pod hello-world-5dd7d6d7d4-78g4h 
Name:               hello-world-5dd7d6d7d4-78g4h 
Namespace:          default 
Priority:           0 
PriorityClassName:   
Node:               10.77.223.248/10.77.223.248 
Start Time:         Thu, 12 Mar 2020 10:47:52 +0900 
Labels:             pod-template-hash=5dd7d6d7d4 
                    run=hello-world 
Annotations:        kubernetes.io/psp: ibm-privileged-psp 
Status:             Pending 
IP:                 xxx.xx.xx.xx 
Controlled By:      ReplicaSet/hello-world-5dd7d6d7d4 
Containers: 
  hello-world: 
    Container ID: 
    Image:          us.icr.io/skjeong4/hello-world:1 
    Image ID: 
    Port:            
    Host Port:       
    State:          Waiting 
      Reason:       ImagePullBackOff 
    Ready:          False 
    Restart Count:  0 
    Environment:     
    Mounts: 
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-zj8ts (ro) 
Conditions: 
  Type              Status 
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes: 
  default-token-zj8ts: 
    Type:        Secret (a volume populated by a Secret) 
    SecretName:  default-token-zj8ts 
    Optional:    false 
QoS Class:       BestEffort 
Node-Selectors:   
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 600s 
                 node.kubernetes.io/unreachable:NoExecute for 600s 
Events: 
  Type     Reason     Age               From                    Message 
  ----     ------     ----              ----                    ------- 
  Normal   Scheduled  13s               default-scheduler       Successfully assigned default/hello-world-5dd7d6d7d4-78g4h to 10.77.223.248 
  Warning  Failed     12s               kubelet, 10.77.223.248  Failed to pull image "us.icr.io/skjeong4/hello-world:1": rpc error: code = NotFound desc = failed to pull and unpack image "us.icr.io/skjeong4/hello-world:1": failed to resolve reference "us.icr.io/skjeong4/hello-world:1": us.icr.io/skjeong4/hello-world:1: not found 
  Warning  Failed     12s               kubelet, 10.77.223.248  Error: ErrImagePull 
  Normal   BackOff    11s               kubelet, 10.77.223.248  Back-off pulling image "us.icr.io/skjeong4/hello-world:1" 
  Warning  Failed     11s               kubelet, 10.77.223.248  Error: ImagePullBackOff 
  Normal   Pulling    0s (x2 over 12s)  kubelet, 10.77.223.248  Pulling image "us.icr.io/skjeong4/hello-world:1" 


3. 해당 pod에 서비스 포트 할당

kubectl expose deployment/hello-world --type="NodePort" --port=8080

[root@db2 Lab 1]# kubectl expose deployment/hello-world --type="NodePort" --port=8080 
service/hello-world exposed 


4. 클러스터에 배포된 포트 확인

kubectl describe service <name-of-deployment>

[root@db2 Lab 1]# kubectl describe service hello-world 
Name:                     hello-world 
Namespace:                default 
Labels:                   run=hello-world 
Annotations:               
Selector:                 run=hello-world 
Type:                     NodePort 
IP:                       xxx.xx.xxx.xxx 
Port:                       8080/TCP 
TargetPort:               8080/TCP 
NodePort:                   32412/TCP 
Endpoints:                xxx.xx.xx.xx:8080 
Session Affinity:         None 
External Traffic Policy:  Cluster 
Events:                    


5. 클러스터의 Public IP 확인

ibmcloud ks workers <name-of-cluster>

[root@db2 script]# ibmcloud ks workers mycluster 
OK 
ID                                                     Public IP        Private IP      Flavor   State    Status   Zone    Version 
kube-bpkadubd0gijteu5rpt0-mycluster-default-00000094   xxx.xxx.xx.xxx   xx.xx.xxx.xxx   free     normal   Ready    hou02   1.16.7_1525

 

6. 클러스터에 배포된 어플리케이션 실행

 

curl <public-IP>:<nodeport>

[root@db2 Lab 3]# curl xxx.xxx.xx.xxx:32412
Hello world from hello-world-684dfdd9c5-fll85! Your app is up and running in a cluster!
728x90

'cloud' 카테고리의 다른 글

Kubernetes Essentials with IBM Cloud - Lab 2  (0) 2020.03.18
728x90

안녕하세요. 인포믹스 14.10.xC2 버전부터 파일시스템의 Chunk를 빠르게 생성하는 기능이 추가되었습니다.

기존에는 파일시스템에서 Chunk를 생성하면 크기가 클수록 오래걸렸는데요.

이 기능을 사용하면 onspaces 명령을 실행하는 즉시 Chunk가 생성됩니다.

 

Configuration 설명을 보면 다음과 같이 나와있습니다.

Configuration Parameter Info
id   name                      type    maxlen   units   rsvd  tunable
108  USE_FALLOCATE             BOOL    2                      *
     default : 1
     onconfig: 1
     current : 1
     This parameter is undocumented.
     Description:
     Enabling USE_FALLOCATE allows the server to allocate space for a new
     cooked chunk much more quickly by making use of posix_fallocate(). This
     is only supported on platforms which have posix_fallocate() available.
     A performance improvement can only be expected when the underlying file
     system supports the required functionality. Please refer to your operating
     system vendor documentation for further details.

posix_fallocate 함수를 살펴보면 리눅스 커널에서만 지원되는 함수인 것 같습니다. 혹시 잘못된 내용이라면 알려주세요.

xfs , ext4 , btrfs, tmpfs 등의 파일시스템에서 이 동작을 지원합니다.

 

아래는 실제로 CentOS 7.6의 Informix 14.10.FC3 환경에서 테스트해본 내용입니다.

onspaces 명령을 실행하자마자 청크가 생성된 것을 확인할 수 있습니다.

[informix@db2 ids1410fc3]$ ls -la /work1/informix/storage/test
-rw-rw----. 1 informix informix 0 Mar 10 09:09 /work1/informix/storage/test
[informix@db2 ids1410fc3]$ time onspaces -c -d test -p /work1/informix/storage/test -o 0 -s 6000000
Verifying physical disk space, please wait ...
Space successfully added.
** WARNING **  A level 0 archive of Root DBSpace will need to be done.
real    0m0.094s
user    0m0.011s
sys     0m0.025s
[informix@db2 ids1410fc3]$ ls -la /work1/informix/storage/test
-rw-rw----. 1 informix informix 6144000000 Mar 10 09:18 /work1/informix/storage/test

해당 기능에 대해서는 아직 IBM Knowledge Center에는 나와있지 않네요.

아 그리고 참고로 스토리지 암호화 기능(DISK_ENCRYPTION)이 활성화 된 상태에서는 이 옵션이 적용되지 않는 것 같습니다.

 

728x90
728x90

Informix는 PDQ 값에 따라 가용한 스레드 수만큼 작업이 병렬로 수행됩니다.

PDQ 값은 세션에서 SET PDQPRIORITY 문장으로 설정할 수 있는데요. 프로시저가 컴파일될때 이 값이 인코딩되면서 카탈로그 테이블에 저장된다고 합니다.

Fernando 의 블로그에서 루틴의 PDQ값을 참조할 수 있는 자세한 설명을 보실 수 있습니다.

http://informix-technology.blogspot.com/2011/01/stored-procedure-pdq-pdq-dos.html

 

Stored procedure PDQ / PDQ dos procedimentos

This article is written in English and Portuguese Este artigo está escrito em Inglês e Português English version: A few years ago I needed...

informix-technology.blogspot.com

프로시저 내부 작업들이 병렬로 수행되는 것은 참 좋아보입니다만 시스템 자원을 과도하게 사용할 가능성도 생깁니다.

따라서 PDQ 값을 0또는 작은 값으로 설정하고 프로시저를 컴파일하는 것이 좋겠네요.

Informix의 각 데이터베이스 별로 sysprocplan과 sysprocedures 테이블이 존재합니다. 아래는 카탈로그 테이블들의 각 컬럼 값을 참조하여 PDQ값을 확인하는 사용자 정의 함수 코드입니다.

CREATE FUNCTION get_proc_pdq_value(v_proc_name VARCHAR(128))
RETURNING SMALLINT;
DEFINE v_ret_pdq_value SMALLINT;
SELECT
 CASE data[1,3]
     WHEN "AAA" THEN 0
     WHEN "AQA" THEN 1
     WHEN "AAE" THEN 1
     WHEN "AgA" THEN 2
     WHEN "AAI" THEN 2
     WHEN "AwA" THEN 3
     WHEN "AAM" THEN 3
     WHEN "BAA" THEN 4
     WHEN "AAQ" THEN 4
     WHEN "BQA" THEN 5
     WHEN "AAU" THEN 5
     WHEN "BgA" THEN 6
     WHEN "AAY" THEN 6
     WHEN "BwA" THEN 7
     WHEN "AAc" THEN 7
     WHEN "CAA" THEN 8
     WHEN "AAg" THEN 8
     WHEN "CQA" THEN 9
     WHEN "AAk" THEN 9
     WHEN "CgA" THEN 10
     WHEN "AAo" THEN 10
     WHEN "CwA" THEN 11
     WHEN "AAs" THEN 11
     WHEN "DAA" THEN 12
     WHEN "AAw" THEN 12
     WHEN "DQA" THEN 13
     WHEN "AA0" THEN 13
     WHEN "DgA" THEN 14
     WHEN "AA4" THEN 14
     WHEN "DwA" THEN 15
     WHEN "AA8" THEN 15
     WHEN "EAA" THEN 16
     WHEN "ABA" THEN 16
     WHEN "EQA" THEN 17
     WHEN "ABE" THEN 17
     WHEN "EgA" THEN 18
     WHEN "ABI" THEN 18
     WHEN "EwA" THEN 19
     WHEN "ABM" THEN 19
     WHEN "FAA" THEN 20
     WHEN "ABQ" THEN 20
     WHEN "FQA" THEN 21
     WHEN "ABU" THEN 21
     WHEN "FgA" THEN 22
     WHEN "ABY" THEN 22
     WHEN "FwA" THEN 23
     WHEN "ABc" THEN 23
     WHEN "GAA" THEN 24
     WHEN "ABg" THEN 24
     WHEN "GQA" THEN 25
     WHEN "ABk" THEN 25
     WHEN "GgA" THEN 26
     WHEN "ABo" THEN 26
     WHEN "GwA" THEN 27
     WHEN "ABs" THEN 27
     WHEN "HAA" THEN 28
     WHEN "ABw" THEN 28
     WHEN "HQA" THEN 29
     WHEN "AB0" THEN 29
     WHEN "HgA" THEN 30
     WHEN "AB4" THEN 30
     WHEN "HwA" THEN 31
     WHEN "AB8" THEN 31
     WHEN "IAA" THEN 32
     WHEN "ACA" THEN 32
     WHEN "IQA" THEN 33
     WHEN "ACE" THEN 33
     WHEN "IgA" THEN 34
     WHEN "ACI" THEN 34
     WHEN "IwA" THEN 35
     WHEN "ACM" THEN 35
     WHEN "JAA" THEN 36
     WHEN "ACQ" THEN 36
     WHEN "JQA" THEN 37
     WHEN "ACU" THEN 37
     WHEN "JgA" THEN 38
     WHEN "ACY" THEN 38
     WHEN "JwA" THEN 39
     WHEN "ACc" THEN 39
     WHEN "KAA" THEN 40
     WHEN "ACg" THEN 40
     WHEN "KQA" THEN 41
     WHEN "ACk" THEN 41
     WHEN "KgA" THEN 42
     WHEN "ACo" THEN 42
     WHEN "KwA" THEN 43
     WHEN "ACs" THEN 43
     WHEN "LAA" THEN 44
     WHEN "ACw" THEN 44
     WHEN "LQA" THEN 45
     WHEN "AC0" THEN 45
     WHEN "LgA" THEN 46
     WHEN "AC4" THEN 46
     WHEN "LwA" THEN 47
     WHEN "AC8" THEN 47
     WHEN "MAA" THEN 48
     WHEN "ADA" THEN 48
     WHEN "MQA" THEN 49
     WHEN "ADE" THEN 49
     WHEN "MgA" THEN 50
     WHEN "ADI" THEN 50
     WHEN "MwA" THEN 51
     WHEN "ADM" THEN 51
     WHEN "NAA" THEN 52
     WHEN "ADQ" THEN 52
     WHEN "NQA" THEN 53
     WHEN "ADU" THEN 53
     WHEN "NgA" THEN 54
     WHEN "ADY" THEN 54
     WHEN "NwA" THEN 55
     WHEN "ADc" THEN 55
     WHEN "OAA" THEN 56
     WHEN "ADg" THEN 56
     WHEN "OQA" THEN 57
     WHEN "ADk" THEN 57
     WHEN "OgA" THEN 58
     WHEN "ADo" THEN 58
     WHEN "OwA" THEN 59
     WHEN "ADs" THEN 59
     WHEN "PAA" THEN 60
     WHEN "ADw" THEN 60
     WHEN "PQA" THEN 61
     WHEN "AD0" THEN 61
     WHEN "PgA" THEN 62
     WHEN "AD4" THEN 62
     WHEN "PwA" THEN 63
     WHEN "AD8" THEN 63
     WHEN "QAA" THEN 64
     WHEN "AEA" THEN 64
     WHEN "QQA" THEN 65
     WHEN "AEE" THEN 65
     WHEN "QgA" THEN 66
     WHEN "AEI" THEN 66
     WHEN "QwA" THEN 67
     WHEN "AEM" THEN 67
     WHEN "RAA" THEN 68
     WHEN "AEQ" THEN 68
     WHEN "RQA" THEN 69
     WHEN "AEU" THEN 69
     WHEN "RgA" THEN 70
     WHEN "AEY" THEN 70
     WHEN "RwA" THEN 71
     WHEN "AEc" THEN 71
     WHEN "SAA" THEN 72
     WHEN "AEg" THEN 72
     WHEN "SQA" THEN 73
     WHEN "AEk" THEN 73
     WHEN "SgA" THEN 74
     WHEN "AEo" THEN 74
     WHEN "SwA" THEN 75
     WHEN "AEs" THEN 75
     WHEN "TAA" THEN 76
     WHEN "AEw" THEN 76
     WHEN "TQA" THEN 77
     WHEN "AE0" THEN 77
     WHEN "TgA" THEN 78
     WHEN "AE4" THEN 78
     WHEN "TwA" THEN 79
     WHEN "AE8" THEN 79
     WHEN "UAA" THEN 80
     WHEN "AFA" THEN 80
     WHEN "UQA" THEN 81
     WHEN "AFE" THEN 81
     WHEN "UgA" THEN 82
     WHEN "AFI" THEN 82
     WHEN "UwA" THEN 83
     WHEN "AFM" THEN 83
     WHEN "VAA" THEN 84
     WHEN "AFQ" THEN 84
     WHEN "VQA" THEN 85
     WHEN "AFU" THEN 85
     WHEN "VgA" THEN 86
     WHEN "AFY" THEN 86
     WHEN "VwA" THEN 87
     WHEN "AFc" THEN 87
     WHEN "WAA" THEN 88
     WHEN "AFg" THEN 88
     WHEN "WQA" THEN 89
     WHEN "AFk" THEN 89
     WHEN "WgA" THEN 90
     WHEN "AFo" THEN 90
     WHEN "WwA" THEN 91
     WHEN "AFs" THEN 91
     WHEN "XAA" THEN 92
     WHEN "AFw" THEN 92
     WHEN "XQA" THEN 93
     WHEN "AF0" THEN 93
     WHEN "XgA" THEN 94
     WHEN "AF4" THEN 94
     WHEN "XwA" THEN 95
     WHEN "AF8" THEN 95
     WHEN "YAA" THEN 96
     WHEN "AGA" THEN 96
     WHEN "YQA" THEN 97
     WHEN "AGE" THEN 97
     WHEN "YgA" THEN 98
     WHEN "AGI" THEN 98
     WHEN "YwA" THEN 99
     WHEN "AGM" THEN 99
     WHEN "ZAA" THEN 100
     WHEN "AGQ" THEN 100
 ELSE
     -1
 END pdq_value
INTO
 v_ret_pdq_value
FROM
 sysprocplan p, sysprocedures f
WHERE
 p.planid = -2 AND
 f.procid = p.procid AND
 f.procname = v_proc_name;
IF v_ret_pdq_value = -1
THEN
 RAISE EXCEPTION -746,0,'Could not decode PDQ value. Please check query';
ELSE
 RETURN v_ret_pdq_value;
END IF
END FUNCTION;

과연 일반 사용자들은 짐작조차 할 수 없겠군요. 어쨌든 이 함수를 사용해 각 함수나 프로시저의 PDQ값을 참조하여 재컴파일 등을 고려해볼 필요도 있겠습니다.

제가 프로시저를 재컴파일한 테스트 결과를 공유드립니다.

$ dbaccess testdb -
Database selected.
> select get_proc_pdq_value('temp_test') from systables where tabid = 1;
(expression)
          80
1 row(s) retrieved.
> set pdqpriority 100;
PDQ Priority set.
> update statistics for routine;
Routine Statistics updated.
> select get_proc_pdq_value('temp_test') from systables where tabid = 1;
(expression)
         100
1 row(s) retrieved.
> set pdqpriority 0;
PDQ Priority set.
> update statistics for routine;
Routine Statistics updated.
> select get_proc_pdq_value('temp_test') from systables where tabid = 1;
(expression)
           0
1 row(s) retrieved.
728x90
728x90

index page 최대 개수에 대해 조사하다보니 extent 할당에 대해서도 우연히 문서를 읽게 되었습니다.

IBM Knowledge Center에 따르면 11.70.xC1 버전부터 partition header pages의 공간이 부족해지면 secondary header pages가 자동으로 할당된다고 합니다.

https://www.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.perf.doc/ids_prf_309.htm

If you have a table that needs more extents and the database server runs out of space on the
partition header page, the database server automatically allocates extended secondary partition
header pages to accommodate new extent entries.
The database server can allocate up to 32767 extents for any partition, unless the size of a table
dictates a limit to the number of extents.

따라서 11.70 버전부터 extent가 최대 32,767개 까지 할당됩니다. 관리할 점은 줄었네요.

그렇지만 성능을 고려한다면 개수를 적게 유지하는 것이 좋겠죠.

 

아래와 같이 데이터를 대량으로 입력해서 extent 개수를 많이 늘려보았습니다.

일반적으로는 EXTENT DOUBLING 규칙에 의해 extent 크기가 2배씩 커지지만 작은 페이지 크기로 일정하게 할당되도록 NO_EXTENT_DOUBLING 옵션을 활성화 했습니다.

참고로 NO_EXTENT_DOUBLING 옵션은 11.70.xC9부터 사용가능합니다.

drop table "informix".log_01;
create table "informix".log_01
  (
    col1 varchar(50),
    col2 varchar(32),
    col3 varchar(5),
    col4 varchar(5),
    col5 varchar(10)
  ) in dbs1 extent size 16 next size 16 lock mode page;
  ...

아래의 SQL문장으로 1천만건의 레코드를 입력합니다.

$ nohup dbaccess -e demo /informix/skjeong/insert1.sql > /informix/skjeong/insert1.log 2>&1 &
$ cat insert1.sql
insert into log_01
select 'dolore eu fugiat nulla pariatur. Excepteur sint oc',
       '180e70d7-8684-4674-8d42-3c1e5f3b',
       'labor',
       'eiusm',
       level
from sysmaster:sysdual
connect by level <= 10000000;

데이터 입력중에 oncheck 명령으로 테이블의 extent 수를 확인해보았습니다.

와우! 2356개입니다. EXTENT DOUBLING이 되고 한계가 3만2천개라면 거의 제한이 없는 것으로 봐도 되겠지요.

TBLspace Report for demo:informix.log_01
    Physical Address               2:5
    Creation date                  02/17/2020 13:23:41
    TBLspace Flags                 901        Page Locking
                                              TBLspace contains VARCHARS
                                              TBLspace use 4 bit bit-maps
    Maximum row size               107
    Number of special columns      5
    Number of keys                 0
    Number of extents              2356
    Current serial value           1
    Current SERIAL8 value          1
    Current BIGSERIAL value        1
    Current REFID value            1
    Pagesize (k)                   2
    First extent size              8
    Next extent size               128
    Number of pages allocated      301056
    Number of pages used           301056
    Number of data pages           300981
    Number of rows                 5422921
    Partition partnum              2097154
    Partition lockid               2097154
    Extents
         Logical Page     Physical Page        Size Physical Pages
                    0         6:5000427           8          8
                    8         6:5000483           8          8
                   16         6:5000611          16         16
                   32         6:5000851          32         32
                   64         6:5001395          64         64
                  128         6:5002675         128        128
                  256         6:5004083         128        128
                  384         6:5005363         128        128
                  512         6:5006515         128        128
                  ...
728x90
728x90

예전에 Ben Thompson의 블로그에서 Index fragment의 page limit에 대한 글을 읽었습니다.

2014년의 글인데 Index의 페이지 수가 12.1버전부터 2^31 (2,147,483,647)개로 증가했다는 것이지요.

IBM Knowledge Center에도 문서화되어 있습니다.

https://www.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.adref.doc/ids_adr_0718.htm#ids_adr_0718__table

 

블로그의 저자인 Ben은 11.7 버전에서도 테스트해보았다는 내용이 있습니다. 그러나 IBM 문서에는 해당 내용이 없어서, IBM Community에 자문을 구하고자 질문을 올렸고 Art와 Ben이 몇가지 조언을 주어서 직접 테스트를 하게 되었습니다.

 

테스트 환경은 인포믹스 11.50.FC6과 11.70.FC5이고, 테스트 시나리오를 위해 고객사의 테이블 스키마를 사용했습니다.

고객은 인포믹스 11.7 버전을 사용하고 있고, 매달 생성하는 테이블이 있는데 최근 몇달간의 데이터를 보니 약 4억4천만건의 레코드가 저장되고 있더군요.

문제는 테이블은 라운드 로빈(round robin) 형태인데 primary key에 해당하는 unique index는 분할되지 않아 기존에 알고 있던 한계치인 2^24 (16,775,134) 개에 육박하고 있다는 점입니다.

그런데 막상 IBM Knowledge Center의 11.7 버전의 문서에는 인덱스 페이지 수의 제한은 나와있지 않고..

 

이런 상황을 가정하고 아래의 테이블을 만들었습니다.

create table log_12
  (
    col1 varchar (50),
    col2 varchar (32),
    col3 varchar (5),
    col4 varchar (5),
    col5 varchar (10)
   .....
  ) fragment by round robin in dbs1, dbs2, dbs3
extent size 16000000 next size 10000000;​

데이터 입력 시간을 절약하기 위해, 더미 데이터를 약 5억건 입력하고 아래 인덱스를 만들었습니다.

create unique index log_12_pk on log_12 (col1, col2, col3, col4, col5) in idx1;​

11.5에서는 인덱스의 페이지 수가 2^24 (16,775,134)개에 도달하자 인덱스를 생성하는 트랜잭션은 롤백되면서 online.log에는 아래와 같은 메시지가 출력되었습니다.

15:22:42 partition 'demo: informix.log_12_pk': no more pages

11.7에서는 인덱스 생성이 완료되었고, 인덱스에 35,999,944개의 페이지가 할당되었습니다.

아래는 oncheck -pt의 결과물의 일부입니다.

                  Index log_12_pk fragment partition idx1 in DBspace idx1
    Physical Address               5:5
    Creation date                  02/14/2020 16:47:53
    TBLspace Flags                 801        Page Locking
                                              TBLspace use 4 bit bit-maps
    Maximum row size               107
    Number of special columns      0
    Number of keys                 1
    Number of extents              2
    Current serial value           1
    Current SERIAL8 value          1
    Current BIGSERIAL value        1
    Current REFID value            1
    Pagesize (k)                   2
    First extent size              8672897
    Next extent size               5420560
    Number of pages allocated      35999944
    Number of pages used           35705525
    Number of data pages           0
    Number of rows                 0
    Partition partnum              5242882
    Partition lockid               2097217
    Extents
         Logical Page     Physical Page        Size Physical Pages
                    0              5:53    23999947   23999947
             23999947               9:3    11999997   11999997

인포믹스 11.7 이상이라면 인덱스 페이지 수 제한을 걱정하지 않아도 되겠군요.

 

추가로 IBM에 공식적으로 문의한 결과, 11.7 문서화에 명시되지 않았을 뿐 인덱스 페이지 수 제한은 12.1 버전과 마찬가지로 2^31 (2,147,483,647)개임을 확인했습니다.

728x90
728x90


Question

I want to prevent SQL0964C  "The transaction log for the database is full" error.
How can I monitor applications that remain uncommitted for a long time or consume huge amount of transaction log space?

 

Answer

The combination of MON_GET_UNIT_OF_WORK and MON_GET_CONNECTION table functions can be used to achieve such purpose.

  1. Create a file (mon_transactions.sql) containing following SQL:
    SELECT
    con.application_handle,
    con.application_id,
    con.application_name,
    con.client_pid,
    uow.uow_start_time,
    uow.uow_log_space_used
    FROM
    table(mon_get_connection(cast(null as bigint), -1)) as con,
    table(mon_get_unit_of_work(null, -1)) as uow
    WHERE
    con.application_handle = uow.application_handle and
    uow.uow_log_space_used != 0
    ORDER BY uow.uow_start_time ;
  2. Connect to the database that you want to monitor using user ID that has DBADM authority.
    db2 connect to [database]
  3. Execute the monitoring SQL created in Step 1. 
    db2 -tvf mon_transactions.sql

[example output]

APPLICATION_HANDLE  APPLICATION_ID                APPLICATION_NAME CLIENT_PID  UOW_START_TIME             UOW_LOG_SPACE_USED
------------------ ------------------------------ ---------------- ----------  -------------------------- ------------------
             20136 192.168.1.1.49538.181224175700 db2bp                 10648  2018-12-25-09.59.43.450650              15593
             20201 *LOCAL.db2inst1.181214145300   db2bp                  8948  2018-12-25-10.27.51.465542              15436
2 record(s) selected.

 

 

The application with a very old UOW_START_TIME could cause SQL0964C error. If the UOW_LOG_SPACE_USED keeps increasing for a particular application, that application may also cause a log full situation.

Additional tips

"mon_req_metrics" database configuration parameter needs to be set as BASE (default) or EXTENDED in order to collect the metrics using the monitoring SQL. You can confirm the current value of database configuration parameters with the following command.

db2 get db cfg for [database]

 

 

728x90

+ Recent posts