SQL Server Agent running status query must return exactly one value(Debezium Connect 생성시 발생한 에러)

wontaekoh·2024년 5월 15일
0

Kakfa 도입기

목록 보기
5/6
post-thumbnail

Local PC에서 Kafka 환경을 구축하고나서 개발서버에 똑같이 Kafka 환경을 구축하던 중 발생한 에러로 분명 똑같이 실수한거 없이 작업을 하였는데도 에러가 발생하였습니다...

앞선 포스팅에서 설명했던 순서로 환경을 구축하던 중 Postman을 통해 Debezium-connector를 등록하던 중 발생한에러였습니다.

📌 에러 메시지 분석

Caused by: java.lang.IllegalStateException: SQL Server Agent running status query must return exactly one value

이 에러메시지는 Local에서도 발생했던 에러인데 SQL Server 에이전트가 실행중이지 않아서 발생했던 에러로 SQL Server 에이전트를 실행시키면서 금방 해결했던 에러였습니다.

그래서 SQL Server 에이전트를 실행시키고 다시 Connector를 등록시키면 해결될줄 알았지만... 똑같은 에러가 발생했습니다 ㅠㅠ

에러 메시지만 봐서 해결을 못할 것 같아 debezium-conector의 코드를 분석해야했습니다.

📌 Dedebzium-connector github 코드분석

isAgentRunning 메서드 분석

Debezium-connector-sqlserver의 SqlServerConnection 클래스

728번째 줄의 isAgentRunning 메서드가 에러가 발생한 코드로 아래와 같습니다.

public boolean isAgentRunning(String databaseName) throws SQLException {
    final String query = replaceDatabaseNamePlaceholder(config().getString(AGENT_STATUS_QUERY), databaseName);
    return queryAndMap(query,
            singleResultMapper(rs -> rs.getBoolean(1), "SQL Server Agent running status query must return exactly one value"));
}

AGENT_STATUS_QUERY 의 쿼리를 실행해서 쿼리 결과 값에 따라 에러가 발생하 것이였습니다.

AGENT_STATUS_QUERY 쿼리 분석

withDefault메서드의 매개변수의 쿼리문이 뭘까?

private static final Field AGENT_STATUS_QUERY = Field.create("sqlserver.agent.status.query")
        .withDescription("Query to get the running status of the SQL Server Agent")
        .withDefault(
                "SELECT CASE WHEN dss.[status]=4 THEN 1 ELSE 0 END AS isRunning FROM [#db].sys.dm_server_services dss WHERE dss.[servicename] LIKE N'SQL Server Agent (%';");

Field 객체에 create, withDescription, withDefault 메서드를 체이닝해서 AGENT_STATUS_QUERY 값이 반환되는 코드였는데 일단 withDefault의 문자열에 있는 쿼리가 동작할 것 같다 생각하여 일단 쿼리문을 실행해보았습니다. #db값은 현제 데이터 베이스 값으로 교체하여 실행하였습니다.

  • withDefault 메서드의 매개변수에 있는 쿼리문 실행
SELECT CASE WHEN dss.[status] = 4 THEN 1 ELSE 0 END AS isRunning 
FROM cdc_target_db.sys.dm_server_services dss 
WHERE dss.[servicename] LIKE N'SQL Server Agent (%';

쿼리 실행결과가 아무 값도 나오지 않더라고요;;
이게 뭐람...

where 문조건도 제거하고 select 절도 * 로 바꾼다음 아래 쿼리를 다시 실행해 보았습니다.

아닛? 결과 값을 보니 servicename이 한글로 되어있었습니다. withDefault의 매개변수에 들어가는 쿼리문을 보면 where 문에 Like 조건으로 SQL Server Agent (% 로 있지만 실제 DB를 확인해보면 한글로 있어서 에러가 발생한 것이였습니다;;

어쩐지... Local PC에서는 잘되었는데 개발 서버에서는 왜 안되나 했네요...

create메서드의 매개변수 값이 속성 값이지 않을까?

private static final Field AGENT_STATUS_QUERY = Field.create("sqlserver.agent.status.query")
        .withDescription("Query to get the running status of the SQL Server Agent")
        .withDefault(
                "SELECT CASE WHEN dss.[status]=4 THEN 1 ELSE 0 END AS isRunning FROM [#db].sys.dm_server_services dss WHERE dss.[servicename] LIKE N'SQL Server Agent (%';");

AGENT_STATUS_QUERY 의 타입인 Field 객체를 분석해봤는데 connect를 등록할 때 body값에 들어가는 속성 값에 create 메서드의 매개변수와 동일한 값을 넣으면 이에 해당하는 값이 AGENT_STATUS_QUERY 값으로 사용되는 것으로 파악을 하였습니다.

  • connect 등록시 body 값에 속성 추가
{
//생략...
  	"sqlserver.agent.status.query": "SELECT CASE WHEN dss.[status]=4 THEN 1 ELSE 0 END AS isRunning FROM sys.dm_server_services dss WHERE dss.[servicename] LIKE N'SQL Server 에%' or dss.[servicename] LIKE N'SQL Server Ag%';",
}

where 문의 like 조건에 or 조건으로 한글도 추가하여 SQL Server 에이전트가 한글이더라도 조회될 수 있도록 했습니다.

하지만 여전히 똑같은 에러가 발생하였습니다....ㅠㅠ

Rad Hat에 등록된 똑같은 이슈

debezium-connector github의 오른쪽 위를 보면 issue링크가 있는데 여기서 다행히 똑같은 이슈를 찾을 수 있었습니다!ㅎ

Rad Hat에 등록된 똑같은 이슈 링크

  • 이슈 해결 방법을 설명한 comment

Postman으로 connect를 등록할 때 저는 sqlserver.agent.status.query 를 키 값으로 해서 등록을 했는데 앞에 database 값도 추가해주면 되는 것이였습니다.

코드를 분석했을 때는 찾지 못했었는데 database관련 속성들은 일괄적으로 database 값을 prefix로 붙혀주는 코드가 있는건지 어딘가에 있지 싶습니다.

  • 키 값에 database도 추가하여 connect 등록
{
//생략...
  	"database.sqlserver.agent.status.query": "SELECT CASE WHEN dss.[status]=4 THEN 1 ELSE 0 END AS isRunning FROM sys.dm_server_services dss WHERE dss.[servicename] LIKE N'SQL Server 에%' or dss.[servicename] LIKE N'SQL Server Ag%';",
}

이렇게하니 드디어 CDC 동작이 되었습니다!!

✨ 마무리

에러가 왜 발생했는지 찾을 때는 너무 힘들지만 이를 해결했을 때 쾌감은 역시!!이맛에 개발하는 것 같습니다.

profile
주니어 백엔드 개발자, 오원택입니다!

0개의 댓글

관련 채용 정보