728x90

오늘은 IBM Community에서 인포믹스 Smart Trigger 구현중에 발생한 오류에 대해서 질문이 있었습니다. 인포믹스 12.10.xC9 버전부터 Smart Trigger라는 기능이 소개되었는데 IBM Knowledge Center에서의 설명은 아래와 같습니다.

In a relational database environment, client applications are constantly monitoring and triggering other complex jobs, based on changes happening in the database. Applications need to be able to detect events in the database as they happen, without adding overhead to the database server.
With the release of Informix 12.10.xC9, clients can now create JDBC Smart Triggers to register changes in a dataset, using SELECT statements and WHERE clauses, and push data from the server to the client. Scaling is achieved by clients not having to poll for data, while the database server's parallel architecture can feed the data to all clients by asynchronously reading logical log file changes. This design lets client applications scale linearly without adding significant overhead to the database server or any OLTP applications making changes to the database.

요약하면 스마트 트리거를 사용하면 데이터베이스 서버에 변경을 가하지 않고 클라이언트 프로그램에서 정의한 SELECT 문장의 조건으로 데이터베이스 데이터의 변경을 감지할 수 있다고 설명하고 있습니다. 데이터베이스의 트리거와는 달리 비동기식으로 작동하므로 데이터베이스에 가해지는 부하가 적다고 합니다.

 

테스트를 위해 HCL 커뮤니티의 포스트에서 Java 코드를 참고했습니다.

http://www.hcl-informix-user.com/blogs/introducing-hcl-informix-smart-triggers

 

Java 프로그램을 실행하기 전에 데이터를 입력할 테이블을 하나 만듭니다.

CREATE TABLE account (id integer primary key, name varchar(200), balance float);

코드 내용에서 JDBC url 내용을 수정합니다. sysadmin 데이터베이스와 모니터링할 데이터베이스의 로케일을 고려하여 DB_LOCALE과 CLIENT_LOCALE 설정값을 지정합니다. 이 예시의 경우 sysadmin은 en_us.819, bank는 en_us.utf8입니다.

import java.sql.SQLException;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.informix.smartTrigger.IfmxSmartTriggerCallback;
import com.informix.smartTrigger.IfxSmartTrigger;
public class SmartTrigger implements IfmxSmartTriggerCallback {
               private final JsonParser p = new JsonParser();
               public static void main(String[] args) throws SQLException {
                              try(IfxSmartTrigger trigger = new IfxSmartTrigger("jdbc:informix-sqli://xxx.xx.xx.xx:53331/sysadmin:user=informix;password=password;DB_LOCALE=en_us.utf8;CLIENT_LOCALE=en_us.utf8");) {
                                             trigger.label("bank_alert").timeout(5); // optional parameters
                                             trigger.addTrigger("account", "informix", "bank", "SELECT * FROM account WHERE balance < 0", new SmartTrigger());
                                             trigger.watch();
                              }
               }
               @Override
               public void notify(String jsonString) {
                              JsonObject json = p.parse(jsonString).getAsJsonObject();
                              System.out.println("Bank Account Ping!");
                              if (json.has("ifx_isTimeout")) {
                                             System.out.println("-- No balance issues");
                              } else {
                                             System.out.println("-- Bank Account Alert detected!");
                                             System.out.println("   " + json);
                              }
               }
}

코드 내용을 보면 GSON 라이브러리를 사용하고 있으므로 다운로드 받습니다. 2.8.6 버전을 받아서 컴파일해보니 오류가 발생해서 2.8.2 버전을 다시 받았습니다.

[informix@db2 skjeong]$ wget https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.2/gson-2.8.2.jar
--2020-04-23 11:17:35--  https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.2/gson-2.8.2.jar
Resolving repo1.maven.org (repo1.maven.org)... 151.101.196.209
Connecting to repo1.maven.org (repo1.maven.org)|151.101.196.209|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 232932 (227K) [application/java-archive]
Saving to: ‘gson-2.8.2.jar’
100%[===================================================================================================================================================>] 232,932      366KB/s   in 0.6s
2020-04-23 11:17:36 (366 KB/s) - ‘gson-2.8.2.jar’ saved [232932/232932]

아래는 Java 코드 컴파일 후 프로그램을 실행한 화면입니다. 저 같은 경우 서버에 java 실행파일들이 여기저기 흩어져있어서 되는 것으로 일단 사용했습니다. 1.8 이상의 JRE와 인포믹스 JDBC 드라이버는 4.10.xC9 이상을 사용하시면 됩니다.

실행하면 timeout 값(초) 간격으로 'Bank Account Ping!' 메시지가 출력됩니다. 

[informix@db2 skjeong]$ export CLASSPATH=/work1/informix/1210FC10/jdbc/lib/ifxjdbc.jar:/work1/informix/ids1410fc3/skjeong/gson-2.8.2.jar:.
[informix@db2 skjeong]$ /opt/ibm/db2/V11.5.dc/java/jdk64/bin/javac SmartTrigger.java
[informix@db2 skjeong]$ /work1/informix/ids1410fc3/jvm/jre/bin/java SmartTrigger
Bank Account Ping!
-- No balance issues
Bank Account Ping!
-- No balance issues

이제 프로그램에서 정의한 조건에 감지될 수 있는 INSERT와 DELETE문장을 실행해보겠습니다.

[informix@db2 skjeong]$ dbaccess bank -
Database selected.
> insert into account (id, name, balance) values (22, 'John Doe', -23.45);
1 row(s) inserted.
> delete from account where id = 22;
1 row(s) deleted.

앞서 실행한 Java 프로그램에서 정의한 SELECT 문장(은 balance가 음수일 경우에 경고를 알리는 메시지를 출력하도록 되어 있습니다. (SELECT * FROM account WHERE balance < 0) 출력 데이터 형식은 JSON입니다.

-- Bank Account Alert detected!
   {"operation":"insert","table":"account","owner":"informix","database":"bank","label":"bank_alert_1","txnid":1421639512296,"operation_owner_id":1001,"operation_session_id":584,"commit_time":1587608886,"op_num":1,"restart_logid":331,"restart_logpos":5329128,"rowdata":{"id":22,"name":"John Doe","balance":-23.4499999999999990}}
Bank Account Ping!
-- No balance issues
Bank Account Ping!
-- No balance issues
-- Bank Account Alert detected!
   {"operation":"delete","table":"account","owner":"informix","database":"bank","label":"bank_alert_1","txnid":1421639540968,"operation_owner_id":1001,"operation_session_id":584,"commit_time":1587608955,"op_num":1,"restart_logid":331,"restart_logpos":5357804,"rowdata":{"id":22,"name":"John Doe","balance":-23.4499999999999990}}
Bank Account Ping!
-- No balance issues

 

참고사이트

https://www.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.po.doc/new_features_ce.htm#newxc9__xc9_push_data

https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.jdbc_pg.doc/ids_jdbc_st_01.htm

728x90
728x90

안녕하세요. 데이터베이스 사랑넷에 두 날짜사이에서 주말을 제외한 일수를 구하는 방법에 대한 질문이 있어서 이것 저것 찾아보고 시험해봤습니다.

 

기능에 대해서 잘 모르다보니 working day sql postgresql 키워드로 구글에 검색해보니 비슷한 기능을 구현한 예제가 많이 있었습니다. 먼저 질문 내용입니다.

아래 쿼리는 mysql에서
두 날짜사이 주말일수를 제외한 일수를 구하는 sql문인데
PostgreSQl에서 적용되게 변환하고 싶습니다.
부탁드립니다.
select ABS(DATEDIFF('2020-04-23', '2020-04-26')) + 1 - ABS(DATEDIFF(ADDDATE('2020-04-23', INTERVAL 1 - DAYOFWEEK('2020-04-23') DAY),
ADDDATE('2020-04-26', INTERVAL 1 - DAYOFWEEK('2020-04-26') DAY))) / 7 * 2
- (DAYOFWEEK(IF('2020-04-26' < '2020-04-23', '2020-04-26', '2020-04-23')) = 1)
- (DAYOFWEEK(IF('2020-04-26' > '2020-04-23', '2020-04-26', '2020-04-23')) = 7);

찬찬히 살펴보면 주말일수를 먼저 빼고 그외의 경우에 대한 조건이 포함되어 있습니다. 이것 저것 경우의 수를 고려한 것인데 mysql에서 날짜를 바꾸어서 실행해보아도 맞는 결과가 나오는 것 같습니다.

 

그래서 최대한 위의 것을 참고해서 PostgreSQL 문법에 맞게 만들어 보았습니다.

SELECT ABS(DATE '2020-04-04' - DATE '2020-04-26') - 
       ABS((DATE '2020-04-04' - EXTRACT(DOW FROM DATE '2020-04-04')::INT) -
           (DATE '2020-04-26' - EXTRACT(DOW FROM DATE '2020-04-26')::INT))/7*2 -
       CASE WHEN EXTRACT(DOW FROM DATE '2020-04-04') = 0 THEN 1 ELSE 0 END +
       CASE WHEN EXTRACT(DOW FROM DATE '2020-04-26') = 0 THEN 1 ELSE 0 END

질문하신 분의 계산식과 유사하게 만들었지만, 여기서는 빠른 날짜에서 이후 날짜를 빼는 식이라 날짜 순서가 바뀌면 쿼리도 바뀌어야 합니다. 이런식으로도 불가능하진 않지만 상당히 복잡해질 수 있습니다.

 

그래서 좀더 나은 방법이 없을까 해서 구글을 찾아보니 액셀의 NETWORKDAYS라는 함수가 이것과 동일한 기능인 것을 알게 됐습니다. 그럼 더 나아가 PostgreSQL에 NETWORKDAYS를 구현한 사례도 있겠거니해서 찾아보니 아래와 같은 예제를 찾았습니다.

select start_date, end_date, 
       sum(case when extract (dow from dt) in (1,2,3,4,5) then 1 else 0 end) as thediff
from (
       select start_date, end_date, 
              generate_series(start_date, end_date, '1 day'::interval) as dt
       from   tbl
     ) t
group by start_date, end_date;

PostgreSQL에서 요일을 확인하려면 extract (dow from date) 와 같은식으로 사용하는데 0(일요일)에서 6(토요일)까지 규정되어 있습니다. 이것 저것 따질 것도 없이 날짜를 쭉 나열하고 요일을 판별하는 식으로 아주 직관적입니다.

다만 날짜 구간이 길면 성능이 어떨지 모르겠군요.

 

우선 여기까지 질문에 대해서는 해결이 되었는데 인포믹스에서 사용하는 방법도 정리해두면 좋을 것 같아 위의 방법을 따라 해보았습니다. 인포믹스도 0은 일요일을 나타내고 1은 월요일을 나타내는 식입니다.

select sum(case when weekday(dt) in (1,2,3,4,5) then 1 else 0 end) as thediff
from (
       select '2020-04-04'::date + level units day as  dt connect by level < abs('2020-04-04'::date - '2020-04-26'::date)
     ) t
         thediff
              15
1 row(s) retrieved.

 

참고사이트

https://www.postgresql.org/docs/8.1/functions-datetime.html

https://dba.stackexchange.com/questions/207701/count-business-days-between-2-dates-in-postgresql

https://stackoverflow.com/questions/7388420/get-datediff-excluding-weekends-using-sql-server

https://stackoverflow.com/questions/1964544/timestamp-difference-in-hours-for-postgresql

728x90
728x90

안타깝게도 인포믹스 12.10.xC14버전에서 추가로 확인된 defect 정보입니다.

이번에는 CHAR_LENGTH 함수의 문제인데요. 지난번 LPAD/RPAD 함수 사용시 발생하는 오류와 유사합니다.

 

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

1) character set과 연관 없어 보임 (en_us.utf8, ko_kr.ksc, ko_kr.949, ko_kr.ksc인 경우 모두 오류 발생)

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

 

사용 빈도에 따라 발생 가능성이 높은 오류입니다. 아래는 오류를 재현한 과정입니다.

/work2/INFORMIX/1210FC14]dbaccess tdb -
Database selected.
> select char_length("") from systables where tabid = 1;
  202: An illegal character has been found in the statement.
Error in line 1
Near character position 52

이 내용은 APAR IT32473: -202 ERROR WHEN USING CHAR_LENGTH("") FOR A NULL VALUE 로 확정되었습니다.

12.10.xC14 Fix Pack 적용은 하지 않는 것이 좋겠네요.

728x90
728x90

인포믹스 프로시저에서는 UNLOAD나 OUTPUT 문장을 실행할 수 없습니다. 이를 대체하려면 External Table 기능을 사용해 데이터를 파일로 내려받는 방법이 있습니다.

참고로 External Table 기능은 인포믹스 11.5 버전부터 사용할 수 있습니다.

/work2/INFORMIX/1210FC13/skjeong]cat myproc.sql
DROP PROCEDURE MYPROC();
CREATE PROCEDURE MYPROC()
CREATE EXTERNAL TABLE load_tmp
(
   load_stmt char(1024)
)
USING (
DATAFILES    ("DISK:/tmp/load.sql"),
DELIMITER ";"
);
INSERT INTO load_tmp SELECT 'load from ' || trim(tabname) || ' insert into ' || trim(tabname) FROM systables WHERE tabid > 99 AND tabtype = 'T';
DROP TABLE load_tmp;
END PROCEDURE;
/work2/INFORMIX/1210FC13/skjeong]dbaccess stores_demo myproc.sql
Database selected.
Routine dropped.
Routine created.
Database closed.
/work2/INFORMIX/1210FC13/skjeong]cat /tmp/load.sql
load from customer insert into customer;
load from orders insert into orders;
load from manufact insert into manufact;
load from stock insert into stock;
load from items insert into items;
load from state insert into state;
load from call_type insert into call_type;
load from cust_calls insert into cust_calls;
load from catalog insert into catalog;
...
load from calendarpatterns insert into calendarpatterns;
load from calendartable insert into calendartable;
load from tsinstancetable insert into tsinstancetable;
load from tscontainertable insert into tscontainertable;
load from tscontainerusageactivewindowvti insert into tscontainerusageactivewindowvti;
load from tscontainerusagedormantwindowvti insert into tscontainerusagedormantwindowvti;
load from tscontainerwindowtable insert into tscontainerwindowtable;
load from ts_data insert into ts_data;
load from customer_ts_data insert into customer_ts_data;
load from ts_data_v insert into ts_data_v;
load from ts_data_multiplier_v insert into ts_data_multiplier_v;
load from spatial_references insert into spatial_references;
load from geometry_columns insert into geometry_columns;
load from st_units_of_measure insert into st_units_of_measure;
load from se_metadatatable insert into se_metadatatable;
load from se_views insert into se_views;
load from ts_data_location insert into ts_data_location;
load from tab insert into tab;
load from warehouses insert into warehouses;
load from classes insert into classes;
load from dbms_alert_events insert into dbms_alert_events;
load from dbms_alert_registered insert into dbms_alert_registered;
load from dbms_alert_signaled insert into dbms_alert_signaled;
load from employee insert into employee;
load from employee3 insert into employee3;
load from tab0 insert into tab0;
load from l_nextval insert into l_nextval;
load from stock3 insert into stock3;
load from test_bk insert into test_bk;
load from test4 insert into test4;
load from test1 insert into test1;
load from stock2_trans insert into stock2_trans;
load from catcopy insert into catcopy;
load from test insert into test;
load from test2 insert into test2;
load from test3 insert into test3;
load from stock2 insert into stock2;

 

프로시저 작성은 아래 문서를 참고했습니다.

https://stackoverflow.com/questions/31992388/using-an-unload-statement-in-an-informix-stored-procedure

728x90
728x90

안녕하세요. IBM 커뮤니티에서 인포믹스의 통합 백업 암호화(Integrated Backup Encryption) 기능에 대한 질문이 있어서 소개하려고 합니다.

질문의 요지는 암호화된 백업 파일의 압축이 잘 되는가 하는 것인데, PGP로 암호화된 파일은 압축이 잘 안되었던 모양입니다. 그래서 몇가지 상황을 가정하고 백업 암호화 기능의 작동 방식을 테스트 해보았습니다.

 

인포믹스의 통합 백업 암호화 기능은 14.10 버전부터 제공됩니다.

매뉴얼에서는 통합 백업 암호화 기능을 사용한다면 원격지의 키서버를 통해 백업 암호화 키를 생성할 것을 권장하고 있으나 여기서는 편의상 로컬 암호화 키를 사용하겠습니다. 로컬 암호화 키를 생성하는 방법은 IBM Knowledge Center의 아래 링크를 참고했습니다.

https://www.ibm.com/support/knowledgecenter/SSGU8G_14.1.0/com.ibm.bar.doc/ids_bar_local_encryption_key.htm

-- 1. 통합 백업 암호화 기능을 설정하지 않고 ontape 백업 수행
[informix@db2 backups]$ onstat -c | egrep '^BACKUP_FILTER|^RESTORE_FILTER|^BAR_ENC'
BACKUP_FILTER
RESTORE_FILTER
BAR_ENCRYPTION
[informix@db2 backups]$ ontape -s -L 0
10 percent done.
20 percent done.
30 percent done.
40 percent done.
100 percent done.
File created: /work1/informix/ids1410fc3/backups/db2_0_L0
Please label this tape as number 1 in the arc tape sequence.
This tape contains the following logical logs:
 247
Program over.
[informix@db2 backups]$ ls -la
total 266788
drwxrwxr-x.  3 informix informix        33 Mar 31 09:54 .
drwxr-xr-x. 28 informix informix      4096 Mar 21 22:30 ..
-rw-rw----.  1 informix informix 273186816 Mar 31 09:54 db2_0_L0
drwxrwxr-x.  2 informix informix       182 Mar 31 09:51 tmp
-- 2. 통합 백업 암호화 기능을 설정하고 ontape 백업 수행
[informix@db2 backups]$ openssl rand -base64 24 > /work1/informix/ids1410fc3/etc/l_key192
[informix@db2 backups]$ onstat -c | egrep '^BACKUP_FILTER|^RESTORE_FILTER|^BAR_ENC'
BACKUP_FILTER
RESTORE_FILTER
BAR_ENCRYPTION keyfile=/work1/informix/ids1410fc3/etc/l_key192,cipher=aes192
[informix@db2 backups]$ ontape -s -L 0
The backup volume will be encrypted.
10 percent done.
20 percent done.
30 percent done.
40 percent done.
100 percent done.
File created: /work1/informix/ids1410fc3/backups/db2_0_L0
Please label this tape as number 1 in the arc tape sequence.
This tape contains the following logical logs:
 247
Program over.
[informix@db2 backups]$ ls -la
total 533572
drwxrwxr-x.  3 informix informix        65 Mar 31 09:55 .
drwxr-xr-x. 28 informix informix      4096 Mar 21 22:30 ..
-rw-rw----.  1 informix informix 273186816 Mar 31 09:54 db2_0_20200331_095432_L0
-rw-rw----.  1 informix informix 273186816 Mar 31 09:55 db2_0_L0
drwxrwxr-x.  2 informix informix       182 Mar 31 09:51 tmp
-- 3. 백업 파일 내용 확인
[informix@db2 backups]$ strings db2_0_20200331_095432_L0 | head -30
Archive Backup TapeIBM Informix Dynamic Server Version 14.10.FC3DETue Mar 31 09:54:32 2020informix/dev/pts/0
/work1/informix/ids1410fc3/backups/
rootdbs                                                                                                                         plog                                                                                                                            llog                                                                                                                            datadbs1                                                                                                                        datadbs2                                                                                                                        datadbs3                                                                                                                        data8dbs1                                                                                                                       data8dbs2                                                                                                                       data8dbs3                                                                                                                       sbspace1
IBM Informix Dynamic Server Copyright 2001, 2019  IBM Corporation
14.10.xC2
        F"01-2020
ROOTNAME rootdbs
ROOTPATH /work1/informix/ids1410fc3/storage/rootdbs
ROOTOFFSET 0
ROOTSIZE 157696
MIRROR 0
MIRRORPATH /work1/informix/ids1410fc3/tmp/demo_on.root_mirror
MIRROROFFSET 0
DBSERVERNAME ol_informix1410
SERVERNUM 0
MSGPATH /work1/informix/ids1410fc3/ol_informix1410.log
TAPEDEV /work1/informix/ids1410fc3/backups
TAPESIZE 0
TAPEBLK 32
LTAPEDEV /dev/null
LTAPESIZE 0
LTAPEBLK 32
PHYSFILE 65430
PHYSBUFF 512
LOGFILES 20
LOGSIZE 6144
LOGBUFF 256
DYNAMIC_LOGS 2
LTXHWM 70
LTXEHWM 80
[informix@db2 backups]$ strings db2_0_L0 | head -30
Archive Backup TapeIBM Informix Dynamic Server Version 14.10.FC3DETue Mar 31 09:55:07 2020informix/dev/pts/0
/work1/informix/ids1410fc3/backups/
aes192
DQZQ
QX9p
a5b(
H%*g
wecI
)rO0"
z\$b
#_t;
azXX
aW`g
$9s~f
{Rus
T<.u
(;*&
[!wS
{'dT
g9c%
k#|~
G)9)1
>X2B
CnSq
]SJ~
kmt9
ol!n
>JMsy
b!9~`
[C4R
-- 4. 통합 백업 암호화 기능 및 BACKUP_FILTER, RESTORE_FILTER를 설정하고 ontape 백업 수행
[informix@db2 backups]$ vi $INFORMIXDIR/etc/$ONCONFIG
[informix@db2 backups]$ onstat -c | egrep '^BACKUP_FILTER|^RESTORE_FILTER|^BAR_ENC'
BACKUP_FILTER /bin/gzip
RESTORE_FILTER /bin/gunzip
BAR_ENCRYPTION keyfile=/work1/informix/ids1410fc3/etc/l_key192,cipher=aes192
[informix@db2 backups]$ ontape -s -L 0
The backup volume will be encrypted.
Using the backup and restore filter /bin/gzip.
10 percent done.
20 percent done.
30 percent done.
40 percent done.
100 percent done.
File created: /work1/informix/ids1410fc3/backups/db2_0_L0
Please label this tape as number 1 in the arc tape sequence.
This tape contains the following logical logs:
 247
Program over.
[informix@db2 backups]$ ls -la
total 548100
drwxrwxr-x.  3 informix informix        97 Mar 31 09:56 .
drwxr-xr-x. 28 informix informix      4096 Mar 21 22:30 ..
-rw-rw----.  1 informix informix 273186816 Mar 31 09:54 db2_0_20200331_095432_L0
-rw-rw----.  1 informix informix 273186816 Mar 31 09:55 db2_0_20200331_095507_L0
-rw-rw----.  1 informix informix  14876672 Mar 31 09:56 db2_0_L0
drwxrwxr-x.  2 informix informix       182 Mar 31 09:51 tmp
-- 5. 통합 백업 암호화 기능 및 BACKUP_FILTER, RESTORE_FILTER를 설정하고 ontape 리스토어 수행
[informix@db2 backups]$ onmode -ky
[informix@db2 backups]$ onstat -c | egrep '^BACKUP_FILTER|^RESTORE_FILTER|^BAR_ENC'
BACKUP_FILTER /bin/gzip
RESTORE_FILTER /bin/gunzip
BAR_ENCRYPTION keyfile=/work1/informix/ids1410fc3/etc/l_key192,cipher=aes192
[informix@db2 backups]$ ontape -r
Restore will use level 0 archive file /work1/informix/ids1410fc3/backups/db2_0_L0. Press Return to continue ...
The volume to restore is encrypted.
Using the backup and restore filter /bin/gunzip.
Archive Tape Information
Tape type:      Archive Backup Tape
Online version: IBM Informix Dynamic Server Version 14.10.FC3DE
Archive date:   Tue Mar 31 09:56:06 2020
User id:        informix
Terminal id:    /dev/pts/0
Archive level:  0
Tape device:    /work1/informix/ids1410fc3/backups/
Tape blocksize (in k): 32
Tape size (in k): system defined for directory
Tape number in series: 1
Backup filter:  /bin/gzip
Spaces to restore:1 [rootdbs                                                                                                                         ]
2 [plog                                                                                                                            ]
3 [llog                                                                                                                            ]
4 [datadbs1                                                                                                                        ]
5 [datadbs2                                                                                                                        ]
6 [datadbs3                                                                                                                        ]
7 [data8dbs1                                                                                                                       ]
8 [data8dbs2                                                                                                                       ]
9 [data8dbs3                                                                                                                       ]
10 [sbspace1                                                                                                                        ]
Archive Information
IBM Informix Dynamic Server Copyright 2001, 2019  IBM Corporation
Initialization Time       01/08/2020 22:26:54
System Page Size          2048
Version                   31
Index Page Logging        OFF
Archive CheckPoint Time   03/31/2020 09:56:05
Dbspaces
number   flags    fchunk   nchunks  flags    owner                            name
1        10000001 1        2        N   AE   informix                         rootdbs                                                                                                        
2        11000001 2        1        N P AE   informix                         plog                                                                                                           
3        10000001 3        1        N   AE   informix                         llog                                                                                                           
4        10000001 4        1        N   AE   informix                         datadbs1                                                                                                       
5        10000001 5        1        N   AE   informix                         datadbs2                                                                                                       
6        10000001 6        1        N   AE   informix                         datadbs3                                                                                                       
7        10000001 7        1        N   AE   informix                         data8dbs1                                                                                                      
8        10000001 8        1        N   AE   informix                         data8dbs2                                                                                                      
9        10000001 9        1        N   AE   informix                         data8dbs3                                                                                                      
10       10002001 10       1        N T AE   informix                         tmpdbspace                                                                                                     
11       10008001 11       1        N S AE   informix                         sbspace1                                                                                                       
12       1000a001 12       1        N U AE   informix                         tmpsbspace                                                                                                     
Chunks
chk/dbs offset   size     free     bpages   flags pathname
1   1   0        78848    9236              PO--- /work1/informix/ids1410fc3/storage/rootdbs
2   2   0        32768    0                 PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_plog_p_1
3   3   0        70244    4791              PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_llog_p_1
4   4   0        32768    21236             PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_datadbs1_p_1
5   5   0        32768    32715             PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_datadbs2_p_1
6   6   0        32768    32715             PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_datadbs3_p_1
7   7   0        32768    32556             PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_data8dbs1_p_1
8   8   0        32768    32556             PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_data8dbs2_p_1
9   9   0        32768    32556             PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_data8dbs3_p_1
10  10  0        429812   429376            PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_2_tmpdbspace_p_1
11  11  0        32768    8466              POS-- /work1/informix/ids1410fc3/storage/ol_informix1410_2_sbspace1_p_1
12  12  0        32768    8466              POS-- /work1/informix/ids1410fc3/storage/ol_informix1410_2_tmpsbspace_p_1
13  1   0        60314    72                PO--E /work1/informix/ids1410fc3/storage/ol_informix1410_rootdbs_p_1
Continue restore? (y/n)y
Do you want to back up the logs? (y/n)n
The volume to restore is encrypted.
Using the backup and restore filter /bin/gunzip.
Warning: Parameter's user-configured value was adjusted. (DS_MAX_SCANS)
Warning: Parameter's user-configured value was adjusted. (ONLIDX_MAXMEM)
Restore a level 1 archive (y/n) n
Do you want to restore log tapes? (y/n)n
/work1/informix/ids1410fc3/bin/onmode -sy
Program over.
[informix@db2 backups]$ onstat -m
IBM Informix Dynamic Server Version 14.10.FC3DE -- Quiescent -- Up 00:00:26 -- 566920 Kbytes
Message Log File: /work1/informix/ids1410fc3/ol_informix1410.log
10:11:58  Physical Recovery Complete: 0 Pages Examined, 0 Pages Restored.
10:11:58  Clearing encrypted primary chunk 10 before initialization...
10:11:58  Clearing encrypted primary chunk 12 before initialization...
10:11:58  Logical Recovery Started.
10:11:58  72 recovery worker threads will be started.
10:12:00  Logical Recovery has reached the transaction cleanup phase.
10:12:00  Logical Recovery Complete.
          0 Committed, 0 Rolled Back, 0 Open, 0 Bad Locks
10:12:01  Bringing system to Quiescent Mode with no Logical Restore.
10:12:02  Quiescent Mode
10:12:02  Checkpoint Completed:  duration was 0 seconds.
10:12:02  Tue Mar 31 - loguniq 247, logpos 0x1ee018, timestamp: 0xeb6d094 Interval: 264
10:12:02  Maximum server connections 0
10:12:02  Checkpoint Statistics - Avg. Txn Block Time 0.000, # Txns blocked 0, Plog used 0, Llog used 1
10:12:04  Defragmenter cleaner thread now running
10:12:04  Defragmenter cleaner thread cleaned:0 partitions

테스트 결과로 보면 암호화된 백업본이라도 압축이 잘 되는 것을 확인할 수 있습니다.

 

참고 사이트 :

https://www.ibm.com/support/knowledgecenter/SSGU8G_14.1.0/com.ibm.bar.doc/ids_bar_integrated_encryption.htm

 

728x90
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

+ Recent posts