728x90

안녕하세요. DBeaver와 같은 JDBC 연결 프로그램에서 인포믹스의 한글 데이터가 깨져보이는 경우가 있습니다.

이런 현상을 해결하기 위한 방법을 정리해보려고 합니다.

 

우선 대부분의 경우는 인포믹스 데이터베이스 로케일이 영문일 가능성이 높습니다.

아래와 같이 데이터베이스의 로케일을 확인하실 수 있습니다. 영문 로케일은 일반적으로 en_US.819 로 표시됩니다.

데이터베이스에 한글 데이터 INSERT 문장을 실행하면 오류메시지(Code-set conversion function failed due to an illegal sequence or invalid value.)가 발생합니다.

이번에는 터미널에서 한글 데이터를 입력해놓고 조회를 해봅니다. 조회는 오류가 발생하지 않지만 아래처럼 알아볼 수 없는 깨진 글자가 나옵니다.

근본적인 해결방법은 데이터베이스 생성시 한글 코드를 지원하는 데이터베이스에 마이그레이션 하는 것이 좋지만, 실제 사용중인 데이터베이스를 변경하기는 어려우므로, JDBC Driver에서 지원되는 기능을 사용하여 이 현상을 우회할 수 있습니다.

 

DBeaver Connection 설정에서 JDBC Driver 사용자 속성 NEWCODESET을 추가합니다.

해당 속성을 추가해서 JDK 로케일(ksc5601)과 인포믹스 JDBC 드라이버의 내부 테이블(8859-1,819)과 매핑시킬 수 있습니다.

속성을 추가한 후 새로 데이터베이스에 연결하면 한글 데이터 입력과 조회 모두 잘 실행됩니다.

 

NEWCODESET 속성은 인포믹스 서버 10버전 부터 소개되고 있는데, 이에 대응하는 JDBC Driver는 3버전 이상입니다.

DBeaver에서 JDBC Driver 3.00.JC1 버전으로 연결 테스트를 해보니 오류가 나네요. 최소 3.5버전 이상으로 테스트 해보시길 바랍니다.

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

jdbc tracing 기능을 사용하는 방법을 설명하는 글입니다. 샘플 자바 코드를 첨부하였습니다.


Technote (troubleshooting)


Problem(Abstract)

How to enable JDBC tracing for debugging JDBC related issues from version 3.00.JC1 onwards.

Resolving the problem

INTRODUCTION


From version 3.00.JC1 of IBM® Informix® JDBC Driver onwards, debug drivers are no longer shipped.
Informix JDBC Driver now supports SQLIDEBUG. You no longer need to set values for TRACETRACEFILE or PROTOCOLTRACEPROTOCOLTRACEFILE. You only need to set SQLIDEBUG.

STEPS

Using a simple java program called simple.java as an example, the following steps show how to create a trace with the Informix JDBC Driver.

Example:


1. Set the CLASSPATH to the Informix JDBC Driver package.

c:\Infx\Java>set
CLASSPATH=C:\infx\JDBC3.00JC3\lib\ifxjdbc.jar;C:\infx\JDBC3.00JC3\lib\ifxjdbcx.jar;.

2. Compile simple.java

c:\Infx\Java>javac simple.java

3. Ensure that SQLIDEBUG is set correctly

c:\Infx\Java>grep SQLIDEBUG simple.java  
conn=DriverManager.getConnection("jdbc:informix-sqli://irk:1526/sysmaster:INFORMIXSERVER=irk940;USER=informix;
PASSWORD=ximrofni;SQLIDEBUG=C:\\infx\\java\\trace");

Note: SQLIDEBUG is set in the connection string. It points to where the trace file will be found with a certain format i.e. trace.xxxxxxx

4. Remove or move all other trace files

c:\Infx\Java>del trace*

5. Run java.simple

c:\Infx\Java>java simple
systables
syscolumns
...
...
oledbordinals


6. Then locate the trace file

c:\Infx\Java>dir trace*
Volume in drive C has no label.
Volume Serial Number is B823-46D8

Directory of c:\Infx\Java

04/04/2006 14:12 20,560 trace1144156355642.0
1 File(s) 20,560 bytes
0 Dir(s) 4,067,995,648 bytes free


c:\Infx\Java>

7. You will be able to see that a trace file has been created however
you will not be able to read the file.

8. Send the trace file to your local technical support office for analysis.

Note: The code simple.java is found in the attachments

simple.java



출처 : https://www-01.ibm.com/support/docview.wss?uid=swg21237681

simple.java
0.0MB
728x90

+ Recent posts