부록 A. 트러블슈팅 가이드(Troubleshooting)#
이 장에서는 Altibase 커넥터에서 발생할 수 있는 주요 예외 상황과 해결 방안에 대해 설명한다.
커넥터의 상태가 FAILED 인 경우, trace 항목의 로그들을 확인한 후 아래의 해결방안에 따라 조치한다.
다음은 Altibase 커넥터에서 Exception이 발생했을 때의 예시이다.

소스 커넥터에서 예외 상황 및 해결 방안#
소스 커넥터 에러는 주로 소스 데이터베이스와의 이중화 문제로 발생한다. 로그의 첫줄(Message1)을 통해 대략적인 상황을 파악하고, 로그의 다른 줄(Message2)에서 구체적인 원인을 확인 할 수 있다.
주요 예외 및 조치 방안#
| Message 1 | Message 2 | 발생 원인 | 해결 방안 |
|---|---|---|---|
| Received REPL_STOP message from Source DB. | 이중화 중지 | 태스크 또는 커넥터를 재시작 한다. | |
| Received CHANGE_META message from Source DB. | 이중화 메타 변경 | 태스크 또는 커넥터를 재시작 한다. | |
| Failed to convert XLog to SourceRecord. | Column count is mismatched. | 소스 데이터베이스인 Altibase의 이중화 대상 테이블에 DDL SUPPLEMENTAL LOG DATA 설정이 되어있지 않았을 때 UPDATE XLog를 수신하면 발생 | 이중화 대상 테이블에 아래의 쿼리를 수행한다. ALTER TABLE table_name ADD SUPPLEMENTAL LOG DATA ( ALL ) COLUMNS; |
| Receiver thread is failed. | ALA_EnableLogging(): 335873, Failed to open log file | 로그 파일 생성 실패 | ala.log.directory 에 설정된 디렉토리 경로가 올바른지 확인한다. 디렉토리가 올바르다면, 디렉토리의 권한을 확인한다. |
| Receiving XLog timeout. | XLog 수신 대기 timeout | ala.receive.xlog.timeout 프로퍼티 값을 변경한다. | |
| ALA_Handshake(): Failed to wake up sender DB. | ala.sender.port 값이 0이 아닐 때, XLog 송신자 wake up 실패 | - wake up 필요하지 않으면 ala.sender.port 값을 0으로 변경한다. - ala.sender.port 값을 sender의 이중화 포트 번호로 변경한다. |
싱크 커넥터에서 예외 상황 및 해결 방안#
싱크 커넥터는 Kafka 에러 -> JDBC 드라이버 에러 -> DB 엔진 에러 순으로 예외가 중첩되어 전달된다. 따라서 로그의 첫출(Message1) 보다는 Message 2, Message3에 해당하는 실제 원인을 확인하고 대처한다.
주요 예외 및 조치 방안#
Message 1: Exiting WorkerSinkTask due to unrecoverable exception#
| Message 2 | Message 3 | 발생 원인 | 해결 방안 |
|---|---|---|---|
| Communication link failure: Connect timed out | java.sql/java.sql.DriverManager.getConnection | 해당 URL로 연결 불가 | - connection.url 값이 유효한지 확인한다. - 네트워크 상태를 확인한다. - DBMS 상태를 확인한다. |
| Invalid password | 유효하지 않은 비밀번호 | connection.password 에 설정된 비밀번호가 올바른지 확인한다. | |
| User not found | 사용자가 존재하지 않음 | - connection.user 값에 올바른 사용자 계정을 설정한다. - 싱크 데이터베이스에서 해당 사용자가 존재하는지 확인한다. |
|
| The row already exists in a unique index. | 동일 Primary Key를 가지는 메시지가 전송됨 | - DLQ를 사용한다. - insert.mode 값을 upsert 또는 update로 변경한다. |
|
| Sink connector 'CONNECTOR_NAME' is configured with 'delete.enabled=false' and 'pk.mode=none' and therefore requires records with a non-null Struct value and non-null Struct schema, but found record at | delete.enabled 값이 false인 상태에서 tombstone 메시지가 전달됨 | - DLQ를 사용한다. - delete.enabled 값을 true로 변경하고, pk.mode 값을 record_key로 변경한다. - 소스 커넥터의 data.skip.delete 값을 true로 변경한다. |
|
| Table \“TABLE_NAME\“ is missing and auto-creation is disabled | 대상 테이블이 존재하지 않음 | - 사용자 이름을 확인한다. - 싱크 데이터베이스의 테이블을 확인한다. ( 생성 여부 및 이름의 대소문자 여부 ) - 대소문자 문제인 경우 quote.sql.identifiers 값을 never로 변경한다. - table.types 값이 대상 테이블의 타입과 동일한지 확인한다. - 존재하지 않는 테이블을 생성하고자 할 경우, auto.create 값을 true로 변경한다. |
|
| Table \“TABLE_NAME\“ is missing fields (SCHEMA_INFO) and auto-evolution is disabled | 대상 컬럼이 존재하지 않음 | - 테이블 스키마를 확인한다. - 테이블 스키마 변경을 원하는 경우, auto.evolve 값을 true로 변경한다. |
|
| Write to table '\“TABLE_NAME\“' in UPSERT mode requires key field names to be known, check the primary key configuration | insert.mode 값이 upsert 인데 pk.mode 값이 none임 | - insert.mode 값을 insert로 변경한다. - pk.mode 값을 record_key로 설정한다. |
|
| PK mode for table 'TABLE_NAME' is RECORD_KEY with configured PK fields [COLUMN_NAME], but record key schema does not contain field: COLUMN_NAME | primary key 목록에 없는 컬럼을 pk.fields 컬럼에 추가함 | - pk.fields 값을 확인한다. - 테이블 스키마를 확인한다. |
|
| PK mode for table 'TABLE_NAME' is RECORD_VALUE with configured PK fields [COLUMN_NAME], but record value schema does not contain field: COLUMN_NAME | value 목록에 없는 컬럼을 pk.fields 컬럼에 추가함 | - pk.fields 값을 확인한다. - 테이블 스키마를 확인한다. |
|
| No fields found using key and value schemas for table: TABLE_NAME | key 목록 또는 value 목록의 컬럼 중 아무것도 whitelist에 존재하지 않음 | - fields.whitelist 값을 확인한다. - 테이블 스키마를 확인한다. |
|
| Batch update exception occurred: [Batch 1]:Unable to insert (or update) NULL into NOT NULL column. : COLUMN_NAME | - NOT NULL 컬럼에 NULL 값을 입력할 경우 발생 - NOT NULL 제약사항이 있고, DEFAULT 값이 설정되지 않은 컬럼을 fields.whitelist에 추가하지 않음 |
- fields.whitelist 값을 확인한다. - 테이블 스키마를 확인한다. |
|
| java.sql.SQLException: Invalid use of host variables | 0001 : MERGE INTO \“TABLE_NAME\“ USING ( ... ) INCOMING ON( ... ) WHEN MATCHED THEN UPDATE SET ... WHEN NOT MATCHED THEN INSERT( … ) VALUES( … ) | Altibase 서버의COERCE_HOST_VAR_IN_SELECT_LIST_TO_VARCHAR 프로퍼티 값이 0일 때 발생 | - insert.mode 값을 insert 또는 update로 변경한다. - 싱크 데이터베이스(Altibase) 서버의 COERCE_HOST_VAR_IN_SELECT_LIST_TO_VARCHAR 값을 32000으로 변경 후 재시작한다. |
| java.sql.SQLException: SQL syntax error | insert.mode 값이 update 로 설정되어 있을 때, tombstone 메시지를 수신함 | - insert.mode 값을 insert 또는 upsert로 변경한다. - 소스 커넥터의 data.skip.delete 값을 true로 변경한다. |
그 외#
| Message 1 | 발생 원인 | 해결 방안 |
|---|---|---|
| No matching QuoteMethod found for | quote.sql.identifiers 값이 빈 값일 때 발생 | quote.sql.identifiers 값을 유효한 값으로 변경한다. |
| Not a valid JDBC URL | JDBC URL 형식이 유효하지 않음 | connection.url 값을 유효한 값으로 변경한다. |