[42000][1064] (conn=2775495) Routing query to backend failed. See the error log for further details.

    에러 내용

    로컬 개발 환경에서는 잘 실행되었는데.. 개발 서버에 배포하니까 405 에러가 났다.

    axios 에러였는데, 도대체 왜? ?!? ?!? 로컬에서는 잘 되었는데..? 이건 클라이언트 문제가 아니라는 확신이 들었다.

    그래서 API 서버 들어가서 로그를 확인해봤다.

     

    서버에서 확인해 보니 다음과 같은 에러가 찍혀있었는데

    [1064] (conn=2775495) Routing query to backend failed. See the error log for further details.

    결론부터 말하자면, 해당 에러는 maxscale의 use_sql_variables_in 설정값으로 인해 발생했다.

     

     

    환경 구성

    로컬 개발 환경 배포 개발 환경
    10.1.48-MariaDB-0ubuntu0.18.04.1 10.4.24-MariaDB-log
    maxscale X maxscale O

     

    에러 원인

    해당 에러에 대해 찾아보니 다음과 같다.

    WARNING
    
    If a SELECT query modifies a user variable when the use_sql_variables_in parameter is set to all, it will not be routed and the client will receive an error. A log message is written into the log further explaining the reason for the error. Here is an example use of a SELECT query which modifies a user variable and how MariaDB MaxScale responds to it.
    
    MySQL [(none)]> set @id=1;
    Query OK, 0 rows affected (0.00 sec)
    
    MySQL [(none)]> SELECT @id := @id + 1 FROM test.t1;
    ERROR 1064 (42000): Routing query to backend failed. See the error log for further details.
    You allow user variable modification in SELECT queries by setting the value of use_sql_variables_in to master. This will route all queries that use user variables to the master.
    

    use_sql_variables_in 매개 변수가 all로 설정되어 있을 때 SELECT 쿼리가 사용자 변수를 수정하면 사용자 변수가 라우팅 되지 않고 클라이언트에 오류가 발생한다.(default는 all이다.) use_sql_variables_in 값을 master로 설정하여 SELECT 쿼리에서 사용자 변수를 수정할 수 있다. 이렇게 하면 사용자 변수를 사용하는 모든 쿼리가 마스터로 라우팅 된다.

     

    쿼리로 보면 아래 구문 때문이다. sql 변수(@N)를 사용할 때  maxscale 설정으로 인해 에러가 발생했던 것이다.

    (SELECT
        @N:=@N + 1 AS TIME
    FROM
        테이블 명,
        (SELECT
            @N:=0
        FROM
            DUAL) NN

     

    해결 방법

    그래서 sql 변수를 사용하지 않도록 쿼리를 바꿨더니 정상적인 결과가 조회되었다! 

    변경한 쿼리는 다음과 같다.

    (SELECT TIME FROM (
                SELECT 1 AS TIME UNION ALL
                SELECT 2 AS TIME UNION ALL
                SELECT 3 AS TIME UNION ALL
                SELECT 4 AS TIME UNION ALL
                SELECT 5 AS TIME UNION ALL
                SELECT 6 AS TIME UNION ALL
                SELECT 7 AS TIME UNION ALL
                SELECT 8 AS TIME UNION ALL
                SELECT 9 AS TIME UNION ALL
                SELECT 10 AS TIME UNION ALL
                SELECT 11 AS TIME UNION ALL
                SELECT 12 AS TIME UNION ALL
                SELECT 13 AS TIME UNION ALL
                SELECT 14 AS TIME UNION ALL
                SELECT 15 AS TIME UNION ALL
                SELECT 16 AS TIME UNION ALL
                SELECT 17 AS TIME UNION ALL
                SELECT 18 AS TIME UNION ALL
                SELECT 19 AS TIME UNION ALL
                SELECT 20 AS TIME UNION ALL
                SELECT 21 AS TIME UNION ALL
                SELECT 22 AS TIME UNION ALL
                SELECT 23 AS TIME UNION ALL
                SELECT 24 AS TIME
            ) AS number_table) AS T

     

    WITH RECURSIVE 문법을 사용한다면 다음과 같다. - mariaDB 10.2 버전부터 사용 가능

    WITH RECURSIVE cte AS (
        SELECT 1 AS TIME
        UNION ALL
        SELECT TIME + 1 FROM cte WHERE TIME < 24
    )
    SELECT TIME FROM cte AS T

     

    728x90

    댓글