source

MySQL/MARIADB에서 사용자 수준 잠금 강제 해제

gigabyte 2023. 1. 22. 22:29
반응형

MySQL/MARIADB에서 사용자 수준 잠금 강제 해제

My Session Management(Zebra Session)에서는 사용자 수준 잠금을 사용하여 동일한 세션에 있는 두 요청 간의 경쟁 조건을 방지합니다.세션을 시작하려면 GET_LOCK을 사용합니다.세션을 닫으면 RELEASE_LOCK이 사용됩니다.

MariaDB [planner_20201026]> select GET_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587aaaa', '5');
+-------------------------------------------------------------------+
| GET_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587aaaa', '5') |
+-------------------------------------------------------------------+
|                                                                 1 |
+-------------------------------------------------------------------+
1 row in set (0.000 sec)

MariaDB [planner_20201026]> select  RELEASE_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587aaa');
+-----------------------------------------------------------------+
| RELEASE_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587aaa') |
+-----------------------------------------------------------------+
|                                                            NULL |
+-----------------------------------------------------------------+
1 row in set (0.000 sec)

현재 어디에 자물쇠가 제대로 풀리지 않았는지 알 수 없는 상황입니다.GET_LOCK은 타임아웃으로 인해 종료되며 RELEASE_LOCK은 다른 스레드에 의해 확립되어 있기 때문에 잠금을 해제할 수 없음을 알려줍니다.

MariaDB [xyz]> select GET_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587ac8b', '5');
+-------------------------------------------------------------------+
| GET_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587ac8b', '5') |
+-------------------------------------------------------------------+
|                                                                 0 |
+-------------------------------------------------------------------+
1 row in set (5.015 sec)

MariaDB [xyz]> select  RELEASE_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587ac8b');
+------------------------------------------------------------------+
| RELEASE_LOCK('session_ebe210e9b39f1ad3a409763be60efebff587ac8b') |
+------------------------------------------------------------------+
|                                                                0 |
+------------------------------------------------------------------+
1 row in set (0.000 sec)

현재 세션은 거의 차단/사용 없음/종료되었으며 각 요청에는 TIMOUT 초가 추가로 소요됩니다.

특히 타임아웃 후에 어떻게 그 잠금을 해제할 수 있을까요?

RELEASE_LOCK()은 같은 스레드에서 취득한 잠금을 해제하는 경우에만 사용할 수 있습니다.스레드는 다른 스레드가 잠금을 포기하도록 강제할 수 있는 권한이 없습니다.

잠금장치를 얻을 수 있지만 다른 스레드는 일방적으로 잠금을 해제하도록 강요할 수 있다면 상당히 쓸모없는 잠금장치입니다!

이 문제를 해결할 수 있는 한 가지 방법은 IS_USED_LOCK()을 호출하여 잠금을 유지하는 스레드를 알려주는 것입니다.홀더의 정수 스레드 ID를 반환합니다.잠금이 유지되지 않은 경우 NULL을 반환합니다.

SUPER 권한이 있는 경우 스레드는 다른 스레드를 죽일 수 있습니다.이것에 의해, 클라이언트의 접속이 해제되어 잠금이 강제 해제됩니다.하지만 그건 꽤 무례한 짓이에요.

XY의 문제인 것 같습니다.다른 스레드에 의해 유지되고 있는 잠금을 해제하기 위한 솔루션을 찾고 있지만, 실제 문제가 해결되지 않기 때문에 이 솔루션은 좋지 않습니다.

진짜 문제는 다음과 같습니다.

현재 어디에 자물쇠가 제대로 풀리지 않았는지 알 수 없는 상황입니다.

당신은 이것에 대해 더 잘 생각해 보고 누가 잠금을 획득했는지에 대한 추적을 잃지 않는 시스템을 설계할 필요가 있다.

힌트:GET_LOCK(name, 0)도움이 될 수도 있습니다.이것은 즉시 반환됩니다(즉, 타임아웃이 제로인 경우).잠금을 취득할 수 있으면 취득하고, GET_LOCK의 반환치는 1이다.이미 다른 스레드에 의해 유지되고 있는 경우 GET_LOCK은 즉시 반환되지만 반환값은 0으로 반환되므로 취득할 수 없음을 알 수 있습니다.

언급URL : https://stackoverflow.com/questions/65112301/force-release-a-user-level-lock-in-mysql-mariadb

반응형