Post

MariaDB Dump & Stored Program

MariaDB 버전 11.2에서 작성 및 테스트한 글입니다.

사내에서 DB 관리도 담당하고 있기 때문에 DB 백업 구성 및 정책을 수립해야 했다. DB 백업 구성 과정에서 발생했던 문제 상황과 해결 방법, 그리고 그와 관련된 개념(스토어드 프로그램)을 살펴보고자 한다.


문제 상황

DB 서버의 백업을 위해서 mariadb-dump를 사용해 백업 파일을 생성하는 스크립트를 작성하고, crontab에 등록해 수립한 관리 정책에 맞춰 주기적으로 백업이 이루어지도록 구성하였다. 작성한 스크립트 일부는 아래와 같다.

1
$ /usr/bin/mariadb-dump -uroot -p{비밀번호} --routines {스키마명} 1> backup.sql 2> error-log.txt

mariadb-dump를 사용해 백업하는 경우, 기본적으로 스토어드 프로그램(스토어드 프로시저, 스토어드 함수, 이벤트, 뷰)는 포함되지 않기 때문에 이를 포함시키기 위해 —routines 옵션을 주었다. 백업이 정상 수행되면 백업 파일을 backup.sql로 저장하고, 오류가 발생하면 추적을 위해 error-log.txt에 출력을 저장하도록 하였다.

여러 스키마가 존재하기 때문에 스키마별로 스크립트를 작성하고, 정상 동작 확인을 위해 실행시키던 중 한 스키마에서만 오류가 발생한 것을 발견했다. image.png

오류 메시지는 "The user specified as a definer({계정}) does not exist" when using LOCK TABLES로, 단순히 해당 유저를 생성해주면 덤프는 정상적으로 수행된다. 그러나, 이는 근본적인 해결책이 아니며, 추후 계정을 삭제하거나 변경하면 재발할 수 있는 문제이다. 따라서, 이와 관련된 스토어드 프로그램의 개념과 예제를 간단히 살펴보고, 보안 옵션에 대해 다룬 뒤 실제로 이 문제를 해결하기 위해 수행한 조치를 작성해보고자 한다.


스토어드 프로그램

스토어드 프로그램은 MySQL 계열의 데이터베이스에서 절차적인 처리를 위해 작성할 수 있는 프로그램을 총칭하며, 스토어드 프로시저와 스토어드 함수, 트리거와 이벤트 등을 포함한다. 장단점은 아래와 같다.

장점

  • 데이터베이스의 보안 향상: MySQL의 스토어드 프로그램은 자체적인 보안 설정 기능을 가지고 있으며, 스토어드 프로그램 단위로 실행 권한을 부여할 수 있다.
  • 기능의 추상화: 특정 기능(ex. 타임스탬프와 정수를 결합해 BIGINT 타입의 일련번호 발급하는 기능)을 스토어드 프로그램으로 작성해 등록해두면 개발 언어나 도구와 상관없이 해당 기능을 쉽게 활용할 수 있고 관리가 용이하다.
  • 네트워크 소요 시간 절감: 하나의 프로그램에서 100번, 200번씩 실행해야 하는 쿼리를 스토어드 프로그램으로 구현한다면 스토어드 프로그램을 호출할 때 한 번만 네트워크를 경유하면 되기 때문에 네트워크 소요 시간을 줄이고, 성능을 개선할 수 있다.
  • 절차적 기능 구현: SQL 쿼리에서는 복잡한 형태의 IF나 WHILE가 같은 제어 문장을 사용할 수 없다. 즉, SQL 쿼리는 절차적인 기능을 제공하지 않지만, 스토어드 프로그램은 DBMS 서버에서 절차적인 기능을 실행할 수 있는 제어 기능을 제공한다.

단점

  • 낮은 처리 성능: 스토어드 프로그램은 MySQL 엔진에서 해석되고 실행되지만, 엔진은 절차적 코드 처리가 주목적이 아니기 때문에 성능이 다른 프로그램 언어에 비해 상대적으로 떨어진다. 또한, 다른 DBMS 스토어드 프로그램과 달리 MySQL 서버의 스토어드 프로그램은 실행 시마다 프로그램 코드가 파싱돼야 한다.
  • 애플리케이션 코드의 조각화: 각 기능을 담당하는 프로그램 코드가 자바와 MySQL 스토어드 프로그램으로 분산된다면 애플리케이션 설치나 배포가 더 복잡해지고 유지보수가 어려워질 수 있다.

이제, 스토어드 프로시저와 스토어드 함수, 트리거와 이벤트를 생성 시의 기본 문법을 살펴보자.

기본 구성

스토어드 프로그램은 헤더 부분과 본문 부분으로 나눌 수 있다. 헤더 부분은 정의부라고 하며, 주로 스토어드 프로그램의 이름과 입출력 값을 명시하는 부분이다. 추가로, 보안이나 스토어드 프로그램의 작동 방식과 관련된 옵션도 명시할 수 있다. 본문 부분은 스토어드 프로그램의 바디라고도 하며, 스토어드 프로그램이 호출됐을 때 실행하는 내용을 작성하는 부분이다.

아래는 스토어드 프로시저 예시로, CREATE 라인이 헤더(정의부)이며, BEGIN ~ END까지는 본문(바디부)이다.

1
2
3
4
CREATE PROCEDURE sp_sum(IN param1 INTEGER, IN param2 INTEGER, OUT param3 INTEGER)
BEGIN
   SET param3 = param1 + param2;
END ;;

스토어드 프로시저부터 하나씩 살펴보자.

스토어드 프로시저

스토어드 프로시저는 서로 데이터를 주고 받아야 하는 여러 쿼리를 하나의 그룹으로 묶어서 독립적으로 실행하기 위해 사용하는 것이다. 각 쿼리가 서로 연관되어 데이터를 주고받으면서 반복적으로 실행돼야 할 때 스토어드 프로시저를 사용하면 MySQL 서버와 클라이언트 간의 네트워크 전송 작업을 최소화하고 수행 시간을 줄일 수 있다.

스토어드 프로시저를 생성하고 사용하는 간단한 예제를 살펴보자.

1
2
3
4
5
6
7
8
DELIMITER ;;

CREATE PROCEDURE sp_sum(IN param1 INTEGER, IN param2 INTEGER, OUT param3 INTEGER)
BEGIN
   SET param3 = param1 + param2;
END ;;

DELIMITER ;

일단, CREATE PROCEDURE 앞뒤로 DELIMITER 명령어가 있는데, 이 두 문장이 왜 필요할까? 스토어드 프로그램은 본문 내부에 무수히 많은 “;” 문자를 포함하므로 MariaDB 클라이언트가 CREATE PROCEDURE 명령의 끝을 정확히 판별할 수 있도록 구분자를 새로 설정하는 것이다. 일반적으로 “;;” 또는 “//”과 같이 연속된 2개의 문자열을 종료 문자열로 설정한다. DELIMITER 명령어를 사용해 종료 문자를 변경하면 스토어드 프로그램 생성 명령 뿐만 아니라 일반적인 SELECT나 INSERT와 같은 명령에서도 변경된 종료 문자열을 사용해야 하기 때문에 작업 후 종료 문자열을 원래대로 되돌리는 것이 좋다.

이제 스토어드 프로시저를 생성하는 부분의 코드를 보자. 일반적으로 함수를 작성하면 반환값을 함께 작성하지만, 스토어드 프로시저는 내부에서 값을 반환하는 RETURN 명령어를 사용할 수 없다. 그렇다면 프로시저를 호출한 클라이언트는 결과값을 어떻게 알 수 있을까? 답은 세션 변수를 이용하는 것이다.

1
2
3
4
SET @result:=0;
SET @param1:=1;
CALL sp_sum(@param1, 2, @result);
SELECT @result;   // 3

또한, 여기서 확인할 수 있는 스토어드 프로시저의 특징은 “실행 방법”이다. 스토어드 프로시저는 SELECT나 UPDATE 같은 SQL 문장에 사용될 수 없으며, 반드시 CALL 명령어로 실행해야 한다.

만약 스토어드 프로시저의 파라미터나 처리 로직을 변경하고 싶으면 어떻게 할 수 있을까? 이때는 DROP PROCEDURE로 스토어드 프로시저를 삭제한 뒤 CREATE PROCEDURE로 새로 생성해야 한다. ALTER PROCEDURE 명령어가 존재하긴 하지만, 이는 보안이나 작동 방식과 관련된 특성을 변경할 때만 사용할 수 있다. 보안 옵션은 뒤에서 자세히 살펴본다.

1
2
ALTER PROCEDURE sp_sum SQL SECURITY DEFINER;
DROP PROCEDURE sp_sum;

마지막으로, MySQL 8.0 버전부터는 스토어드 프로시저를 사용자에게 보이지 않는 시스템 테이블로 저장한다. 사용자는 information_schema 데이터베이스의 ROUTINES 뷰를 통해 스토어드 프로시저의 메타 정보를 조회할 수만 있다. information_schema 데이터베이스의 ROUTINES 뷰는 스토어드 프로시저와 스토어드 함수의 메타 정보를 저장하고 있기 때문에 다음에 살펴볼 스토어드 함수의 메타 정보도 마찬가지로 ROUTINES 뷰를 통해 확인할 수 있다.

1
SELECT * FROM information_schema.ROUTINES WHERE routine_schema = 'test' AND routine_type = 'procedure'\G;

image.png

스토어드 함수

스토어드 함수는 하나의 SQL 문장으로 작성이 불가능한 기능을 하나의 SQL 문장으로 구현해야 할 때 사용한다. 스토어드 함수는 상대적으로 스토어드 프로시저에 비해 제약 사항이 많으며, 유일한 장점은 SQL 문장의 일부로 사용할 수 있다는 점이다. 제약 사항은 책 ‘Real MySQL 8.0 Vol.2’을 참고하길 바란다.

아래는 두 파라미터를 입력 받고 그 합을 구한 뒤 반환하는 스토어드 함수이다.

1
2
3
4
5
6
7
8
9
DELIMITER ;;
CREATE FUNCTION sf_sum(param1 INTEGER, param2 INTEGER)
	RETURNS INTEGER
BEGIN
	DECLARE param3 INTEGER DEFAULT 0;
	SET param3 = param1 + param2;
	RETURN param3;
END ;;
DELIMITER ;

DELIMITER 관련된 부분은 앞의 스토어드 프로시저에서 설명했기 때문에 생략하겠다. 위 예제를 통해 알 수 있는 스토어드 프로시저와의 차이점은 크게 두 가지이다. 스토어드 함수는,

  • 모든 입력 파라미터가 읽기 전용으로 IN, OUT, INOUT 같은 형식을 지정할 수 없다.
  • 함수 본문 마지막에 정의부에 지정된 타입과 동일한 타입의 값을 RETURN 명령으로 반환해야 한다.

스토어드 프로시저와의 또 다른 차이점은 실행 방식이다. 스토어드 프로시저는 CALL 명령으로 실행할 수 있었던 반면, 스토어드 함수는 SELECT문을 이용해 실행할 수 있다.

1
SELECT sf_sum(1, 2) AS sum;   # 3

마지막으로, ALTER 명령과 DROP 명령의 동작은 스토어드 프로시저와 동일하다. 스토어드 함수의 입력 파라미터를 변경하거나 처리 로직을 변경하려면 DROP 후 CREATE를 해야 하며, ALTER 명령은 스토어드 함수의 특성만 변경할 수 있다.

1
2
ALTER FUNCTION sf_sum SQL SECURITY DEFINER;
DROP FUNCTION sf_sum;

트리거와 이벤트는 자주 사용되진 않으므로 간단한 정의와 예제만 살펴보고 스토리지 프로그램의 보안 옵션으로 넘어가겠다.

트리거

트리거는 테이블의 레코드가 저장되거나 변경될 때 미리 정의해 둔 작업을 자동으로 실행해주는 스토어드 프로그램이다. MariaDB 트리거는 테이블 레코드가 INSERT, UPDATE, DELETE 될 때 시작되도록 설정할 수 있다. 대표적으로 칼럼의 유효성 체크나 다른 테이블로의 복사나 백업, 계산된 결과를 다른 테이블에 함께 업데이트 하는 등의 작업을 위해 트리거를 자주 사용한다.

그러나, 트리거를 사용하지 않아도 애플리케이션 개발 난이도나 성능에 영향이 없기 때문에 스토어드 함수나 프로시저보다는 필요성이 떨어진다. 오히려 트리거가 생성돼 있는 테이블에 칼럼을 추가하거나 삭제할 때 실행 시간이 훨씬 더 오래 걸린다.

아래는 employees 테이블의 레코드가 삭제되기 전에 실행하는 on_delete 트리거를 생성하는 명령이다.

1
2
3
4
5
6
7
DELIMITER ;;
CREATE TRIGGER on_delete BEFORE DELETE ON employees
	FOR EACH ROW
BEGIN
	DELETE FROM salaries where emp_no=OLD.emp_no;
END ;;
DELIMITER ;

스토어드 프로시저나 함수와 달리, 트리거가 잘 동작하는지 확인할 수 있는 명령어는 따로 없고, 트리거가 등록된 테이블에 직접 레코드를 INSERT하거나 UPDATE, DELETE해서 작동을 확인해야 한다. 생성된 트리거의 메타 정보를 확인하려면 information_schema 데이터베이스의 TRIGGERS 뷰를 통해 조회할 수 있다.

image.png

이벤트

주어진 특정한 시간에 스토어드 프로그램을 실행할 수 있는 스케줄러 기능이다. MariaDB 서버의 이벤트는 스케줄링을 전담하는 스레드가 있는데, 이 스레드가 활성화된 경우에만 이벤트가 실행된다. 이벤트 스케줄러의 활성화 여부와 활성화 방법은 따로 찾아보기 바란다.

이벤트는 반복 실행 여부에 따라 크게 일회성 이벤트와 반복성 이벤트로 나눌 수 있다. onetime_job는 현재 시점으로부터 1시간 뒤에 실행될 일회성 이벤트이며, daily_ranking은 2020년 9월 7일 새벽 1시부터 하루 단위로 2020년 말까지 실행될 반복성 이벤트이다. 또한, 이벤트의 처리 내용을 작성하는 DO 절에는 단순히 하나의 쿼리나 스토어드 프로시저를 호출하는 명령을 사용하거나 BEGIN … END로 구성되는 복합 절을 사용할 수 있다.

1
2
3
4
5
6
7
8
9
CREATE EVENT onetime_job
  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
  INSERT INTO daily_rank_log VALUES (NOW(), 'Done');

CREATE EVENT daily_ranking
  ON SCHEDULE EVERY 1 DAY STARTS '2020-09-07 01:00:00' ENDS '2021-01-01 00:00:00'
DO
  INSERT INTO daily_rank_log VALUES (NOW(), 'Done');

지금까지 스토어드 프로그램에 대해 간단히 알아보았다. 실제로 바디부(BEGIN … END)는 훨씬 더 복잡한 로직으로 작성될 수 있으며, 추후 스토어드 프로그램을 사용해야 한다면 위에서 소개한 문법 외 조건, 반복, 예외 처리 등에 대해서도 자세히 알아보는 것을 추천한다. 이제, 문제 상황과 연관된 스토어드 프로그램의 보안 옵션에 대해 알아보자.

보안 옵션

각 스토어드 프로그램을 생성하고 실행하는 권한을 살펴보면 우선 스토어드 프로그램의 DEFINERSQL SECURITY 옵션을 이해해야 한다.

  • DEFINER 옵션: 스토어드 프로그램의 소유권과 같은 의미를 지니며, SQL SECURITY 설정값에 따라 조금씩 다르지만 스토어드 프로그램이 실행될 때의 권한으로 사용되기도 한다.
  • SQL SECURITY 옵션: 스토어드 프로그램을 실행할 때 누구의 권한으로 실행할지 결정하는 옵션으로, DEFINER과 INVOKER 둘 중 하나를 선택할 수 있다. DEFINER는 스토어드 프로그램을 생성한 사용자를 의미하며, INVOKER는 그 스토어드 프로그램을 호출(실행)한 사용자를 의미한다.

예를 들어, DEFINER가 user1@%로 생성된 스토어드 프로그램을 user2@% 사용자가 실행한다고 가정해보자. SQL SECURITY 옵션에 따라 어떻게 결과가 달라질까?

 DEFINERINVOKER
스토어드 프로그램 실행 사용자
(어떤 사용자의 권한으로 실행할지)
user1@%user2@%
실행에 필요한 권한user1에 스토어드 프로그램을 실행할 권한이 있어야 하며,
스토어드 프로그램 내의 각 SQL 문장이 사용하는
테이블에 대해서도 권한을 가지고 있어야 한다.
user2가 스토어드 프로그램을 실행할 권한이 있어야 하며,
스토어드 프로그램 내의 각 SQL 문장이 사용하는
테이블에 대해서도 권한을 가지고 있어야 한다.

DEFINER는 모든 스토어드 프로그램이 기본적으로 가지는 옵션이지만, SQL SECURITY 옵션은 스토어드 프로시저와 스토어드 함수, 뷰만 가질 수 있다. 해당 옵션을 가지지 않는 트리거나 이벤트는 자동으로 SQL SECURITY가 DEFINER로 설정되므로 트리거나 이벤트는 DEFINER에 명시된 사용자의 권한으로 항상 실행된다.

스토어드 프로그램의 DEFINER와 SQL SECURITY 옵션을 조합해서 복잡한 권한 문제를 해결할 수도 있다. 예를 들어, mysql DB는 유저 정보와 같이 보안에 민감한 정보가 저장되어 있는데, 테이블 일부를 일반 사용자에게 제한된 수준으로 조회하거나 변경하는 작업을 허용해야 한다면 꼭 필요한 작업만 스토어드 프로그램으로 개발하고, DEFINER와 SQL SECURITY 옵션을 적절히 조절할 수 있다. 관리자 계정을 DEFINER로 설정하고 SQL SECURITY를 DEFINER로 설정하면 그 스토어드 프로그램을 호출하는 사용자는 주요 테이블에 대한 권한을 전혀 갖고 있지 않지만 스토어드 프로그램으로 해당 작업을 수행할 수 있다. 이때, 스토어드 프로그램은 일반 사용자가 실행하지만 사실은 관리자 계정의 권한으로 실행하는 것이다.

조심해야 할 점은 SQL SECURITY를 DEFINER로 설정하면 해당 스토어드 프로그램이 보안 취약점이 될 수 있으므로 꼭 필요한 경우가 아니라면 SQL SECURITY를 DEFINER보다 INVOKER로 설정하는 것이 좋다. SQL SECURITY를 INVOKER로 설정하면 해당 스토어드 프로그램을 누가 생성했는가와 관계없이 항상 스토어드 프로그램을 호출하는 사용자 권한으로 실행된다.


조치 과정 및 결과

문제가 발생했던 스키마에는 스토어드 함수, 뷰가 존재하기 때문에 정확히 어떤 스토어드 프로그램에서 문제가 생긴 건지 파악하기 위해 아래와 같이 DEFINER를 조회하는 명령어를 실행했다(스토어드 프로그램은 모두 SQL SECURITY 옵션이 DEFINER로 설정되어 있었다). image.png

그 결과, DEFINER가 master@% 계정으로 정의된 뷰를 발견할 수 있었다. 자, 우선 임시방편 해결책 두 가지를 소개한다.

  • 문제 상황 챕터에서 언급한 방법으로, 삭제한 계정을 다시 생성한다.
  • 뷰를 DROP하고 다시 CREATE 한다. 이때, 존재하는 계정을 DEFINER로 설정한다.

두 방법 모두 백업 파일 생성과 생성된 파일을 통한 복구 작업이 성공적으로 수행된다. 그러나, 계정의 변경 및 삭제에 영향을 직접적으로 받는 해결책임은 틀림없다. 더 나은 방법은 없을까?

물론 두 번째 해결책으로 DEFINER를 root@localhost 로 정의하면 계정의 변경 및 삭제에 전혀 영향을 받지는 않는다. 다만, 이는 계정이 갖고 있는 권한의 범위와 상관없이 모든 계정에서 실행 가능해진다는 점에서 보안적인 이슈가 발생할 수도 있다.

문제에 대한 해결책으로 선택한 방법은 모든 스토어드 프로그램의 SQL SECURITY 옵션을 INVOKER로 변경하는 것이었다. 다만 여기서 한 가지 의문이 들 수 있다. 뷰의 옵션만 바꾸면 될 것 같은데, 왜 모든 스토어드 프로그램을 대상으로 옵션을 변경한 것일까? 이는 개인적으로 좀 더 디깅해보면서 문제 상황과 동일 버전에서 수행한 테스트에서 이유를 찾을 수 있다. 아래 테스트 시나리오를 살펴보자.

  1. 유저1이 test 스키마에 프로시저 함수(sf_sum)와 뷰(view_test)를 하나씩 생성한다(DEFINER는 유저1, SQL SECURITY 옵션은 디폴트로 DEFINER이다.)
  2. 유저2가 아래 명령어로 덤프를 수행한다. 문제 없이 수행된다.
    1
    
     $ mariadb-dump -uuser2 -puser2 test > backup4.sql
    
  3. 유저1을 삭제한다.
  4. 유저2가 동일 명령어로 덤프를 수행한다. 이번엔 실패한다. 에러 메시지는 The user specified as a definer ({계정}) does not exist" when using LOCK TABLES로, 이 포스팅에서 다루는 문제 상황과 동일한 상황임을 알 수 있다. image.png
  5. 유저2는 정확히 어디서 문제가 발생했는지 확인하고 싶다. 따라서, test 스키마의 테이블을 하나씩 덤프해본다. 그 결과, 프로시저 함수가 포함된 테이블은 문제 없이 덤프되지만, 뷰에서만 문제가 발생함을 확인할 수 있다. image.png

    왜 뷰에서만 문제가 발생할까? 스토어드 함수는 정상적으로 백업되는데…
    mariadb-dump에는 lock-tables 옵션이 존재한다. 이는 디폴트값이 TRUE이며, 덤프할 모든 테이블들에 대해 테이블 수준의 잠금을 건다는 의미이다. 뷰 잠금의 경우, SQL SECURITY 옵션에 따라 DEFINER 혹은 INVOKER에 정의된 계정으로 뷰에서 사용된 모든 테이블에 대해 잠금을 건다. 즉, 정의된 계정에 잠금을 걸 권한이 있어야 하는 것이다. 여기에선 SQL SECURITY 옵션이 DEFINER으로, DEFINER가 존재하지 않아서 에러가 발생하는 것이고, 에러 메시지의 끝에 when using LOCK TABLES가 표시되는 것이다. 스토어드 함수나 프로시저는 특정 테이블에 귀속되어, 하나의 “테이블”로 취급되지 않기 때문에 문제 없이 백업이 수행된다.
    따라서, 여기서 하나의 해결책을 도출할 수 있는데, 백업 시 잠금을 걸지 않도록 하는 옵션을 주는 것이다. 아래처럼 —skip-lock-tables, —single-transaction, —lock-tables=false 옵션을 주면 문제 없이 덤프가 수행된다. image.png

  6. 따라서, 뷰의 SQL SECURITY 옵션을 INVOKER로 변경한다. image.png
  7. 다시 덤프를 수행한다. 성공한다.
  8. tmp 스키마를 생성한 뒤 해당 덤프 파일로 복구 작업을 수행한다. 모두 문제 없이 수행된다.
    1
    2
    3
    
     > create schema tmp;
     > use tmp;
     > source backup4.sql; 
    
  9. 프로시저 함수(sf_sum)와 뷰(view_test)가 잘 복구되었는지 확인한다. 잘 복구되었다. image.png
  10. 프로시저 함수(sf_sum)와 뷰(view_test) 각각을 실행해본다. 결과는 어떻게 될 것이라 생각하는가?
    1
    2
    
    > select sf_sum(1, 2) as sum;
    > select * from view_test;
    


뷰는 성공적으로 실행되지만, 프로시저 함수는 에러가 발생하며 실행되지 않는다. image.png

프로시저 함수 실행 시 발생한 에러 메시지는 The user speicifed as a definer ({계정}) does not exist로, 문제 상황과는 조금 다르다는 것을 알 수 있다. 이는 프로시저 함수의 SQL SECURITY 옵션이 DEFINER로 정의된 상황에서, DEFINER인 user1이 실행 시점에 존재하지 않기 때문에 발생한 것이다.

따라서, 문제 상황의 해결책으로 뷰의 SQL SECURITY 옵션만을 INVOKER로 바꾸면, 백업과 복구는 문제 없이 수행되지만 복구 후 스토어드 함수를 실행할 때 에러가 발생한다. 현 상황에서는 모든 스토어드 프로그램의 SQL SECURITY 옵션을 INVOKER로 바꿔도 전혀 영향도나 사이드 이펙트가 없기 때문에 원터치 텐트⛺️ 같이 백업과 복구 작업이 특별한 조정 없이 매끄럽게 이어질 수 있도록 모든 스토어드 프로그램의 옵션을 변경하는 해결책을 선택한 것이다. 상황에 따라 백업만 정상적으로 수행할 수 있는 범위에 대해서만 옵션을 변경하거나, 기존 스토어드 프로그램을 삭제하고 다시 생성할 때 존재하는 계정을 DEFINER로 설정하거나, 백업 시 잠금이 걸리지 않도록 옵션을 주는 등의 방법을 선택할 수도 있을 것이다.

오늘의 결론은 이렇다.

스토어드 프로그램이 포함된 스키마를 백업할 때에는 DEFINER와 SQL SECURITY 옵션에 대한 고려가 필요하다.


Reference

This post is licensed under CC BY 4.0 by the author.