오로라 페일오버 후에도 Read-Only
오로라 페일오버 후에도 Read-Only 오류 발...
rdsrepladmin_priv_checks_user 라는 명칭의 계정이 Aurora MySQL 3.07.1에 새로 추가 되었습니다. 이 계정은 초기 구성시 부터 존재하는 것은 아니지만, 바이너리 로그 복제 설정 과정 중에 생성되어, 이후 복제 과정중에 사용되는 계정입니다. rdsrepladmin_priv_checks_user 계정이 어떠한 내용의 계정인지 세부 정보를 확인해봅시다.
Amazon Aurora MySQL 버전 3.07.1에서 Binary log Replication 기능 사용 중 권한 확인을 위한 유저 (PRIVILEGE_CHECKS_USER)로써 rdsrepladmin_priv_checks_user
를 신규 도입하였습니다. 이 유저는 복제 프로세스의 보안을 유지하고 필요한 액세스 제어 정책을 준수하는 데 중요한 역할을 합니다.
rdsrepladmin_priv_checks_user
개요rds_superuser_role
과 함께 replication_applier
권한을 보유합니다.mysql.rds_start_replication
저장 프로시저를 호출하면 rdsrepladmin_priv_checks_user
가 자동으로 생성됩니다.rdsrepladmin_priv_checks_user@localhost
는 예약된 사용자로, 이 사용자를 수정하거나 삭제하지 않는 것이 좋습니다.rds_superuser_role
‘ 라는 롤을 부여하고, 이 롤을 디폴트 롤로 설정합니다. replication_applier
‘ 라는 권한을 부여합니다. rds_superuser_role
권한rds_superuser_role
은 Aurora RDS에서 최상위 권한 역할로, 다음과 같은 권한을 포함합니다:
replication_applier
권한replication_applier
는 복제 프로세스에서 필요한 권한으로, 다음과 같은 작업을 허용합니다:
이 권한은 RDS 전용 권한이 아니라, 기본 MySQL에도 존재하는 권한입니다.
mysql.rds_start_replication
mysql.rds_start_replication
스토어 프로시저는 복제 프로세스를 시작하는 데 사용됩니다. 이 프로시저는 복제를 시작할 뿐만 아니라 rdsrepladmin_priv_checks_user
가 적절히 구성되었는지 확인합니다. 아래는 프로시저의 정의입니다:
CREATE DEFINER=`rdsadmin`@`localhost` PROCEDURE `rds_start_replication`()
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE v_autocommit_status BOOLEAN;
DECLARE v_mysql_version VARCHAR(20);
DECLARE v_threads_running INT;
DECLARE v_replica_parallel_workers INT;
DECLARE v_called_by_user VARCHAR(50);
DECLARE v_sleep INT;
DECLARE sql_logging BOOLEAN;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET @@sql_log_bin=sql_logging;
SET @@autocommit=v_autocommit_status;
RESIGNAL;
END;
SET v_autocommit_status=@@autocommit;
SET @@autocommit=1;
SELECT @@sql_log_bin INTO sql_logging;
SELECT user() INTO v_called_by_user;
SELECT version() INTO v_mysql_version;
SELECT COUNT(1) INTO v_threads_running FROM (SELECT service_state FROM performance_schema.replication_applier_status UNION ALL SELECT service_state FROM performance_schema.replication_connection_status) t WHERE service_state='ON';
SELECT @@replica_parallel_workers into v_replica_parallel_workers;
IF v_threads_running <= 1
THEN
SET @@sql_log_bin = OFF;
CALL mysql.rds_configure_privilege_checks_user();
UPDATE mysql.rds_replication_status SET called_by_user=v_called_by_user,action='start slave', mysql_version=v_mysql_version where action is not null;
COMMIT;
SELECT sleep(1) INTO v_sleep;
START REPLICA;
SELECT sleep(1) INTO v_sleep;
SELECT COUNT(1) INTO v_threads_running FROM (SELECT service_state FROM performance_schema.replication_applier_status UNION ALL SELECT service_state FROM performance_schema.replication_connection_status) t WHERE service_state='ON';
IF v_threads_running = 2
THEN
INSERT INTO mysql.rds_history (called_by_user,action,mysql_version) VALUES (v_called_by_user,'start slave', v_mysql_version);
COMMIT;
SELECT 'Replica running normally.' AS Message;
ELSE
SELECT 'Replica has encountered an error. Run SHOW REPLICA STATUS; to see the error.' AS Message;
END IF;
ELSE
IF v_threads_running > 1
THEN
SELECT 'Replica may already be running. Call rds_stop_replication to stop replication;' AS Message;
END IF;
END IF;
SET @@sql_log_bin=sql_logging;
SET @@autocommit=v_autocommit_status;
END;
28번째 라인을 보시면 CALL mysql.rds_configure_privilege_checks_user();
라는 내용을 확인 가능합니다.
mysql.rds_configure_privilege_checks_user
이 프로시저는 rds_start_replication
에 의해 내부적으로 호출되어 rdsrepladmin_priv_checks_user
를 구성합니다. 해당 계정을 생성 후, 필요한 권한을 부여하고 복제 설정이 일관되게 유지되도록 보장합니다.
CREATE DEFINER=`rdsadmin`@`localhost` PROCEDURE `rds_configure_privilege_checks_user`()
BEGIN
DECLARE is_user_created BOOLEAN;
DECLARE is_user_set BOOLEAN;
DECLARE is_user_role_set BOOLEAN;
DECLARE is_role_created BOOLEAN;
DECLARE username VARCHAR(30) DEFAULT 'rdsrepladmin_priv_checks_user';
DECLARE hostname VARCHAR(10) DEFAULT 'localhost';
DECLARE v_replication_threads_running INT;
DECLARE v_autocommit_status BOOLEAN;
DECLARE sql_logging BOOLEAN;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET @@sql_log_bin=sql_logging;
SET @@autocommit=v_autocommit_status;
RESIGNAL;
END;
SET v_autocommit_status=@@autocommit;
SET @@autocommit=1;
SELECT @@sql_log_bin into sql_logging;
SET @@sql_log_bin=off;
SELECT COUNT(1) INTO v_replication_threads_running FROM (SELECT service_state FROM performance_schema.replication_applier_status UNION ALL SELECT service_state FROM performance_schema.replication_connection_status) t WHERE service_state='ON';
IF v_replication_threads_running > 0 THEN
SELECT 'Replication is already running. Call mysql.rds_stop_replication to stop replication' AS Message;
ELSE
SET @cmd='';
SELECT EXISTS(SELECT * FROM mysql.user WHERE user=username AND host=hostname) INTO is_user_created;
SELECT EXISTS(SELECT * FROM mysql.default_roles WHERE user=username AND host=hostname AND default_role_user='rds_superuser_role' AND default_role_host='%') AND EXISTS(SELECT * FROM mysql.global_grants WHERE user=username AND host=hostname AND priv='REPLICATION_APPLIER') INTO is_user_role_set;
SELECT EXISTS(SELECT * FROM mysql.slave_relay_log_info WHERE Privilege_checks_username=username AND Privilege_checks_hostname=hostname) INTO is_user_set;
SELECT EXISTS(SELECT * FROM mysql.user WHERE user='rds_superuser_role' AND host='%') INTO is_role_created;
IF is_role_created = False THEN
SET @@sql_log_bin=sql_logging;
SET @@autocommit=v_autocommit_status;
SELECT 'rds_superuser_role needs to be present in order to start replication.' INTO @msg;
SIGNAL SQLSTATE VALUE '45000' SET MESSAGE_TEXT = @msg;
END IF;
IF (is_user_created = True AND is_user_role_set = False) THEN
SET @@sql_log_bin=sql_logging;
SET @@autocommit=v_autocommit_status;
SELECT CONCAT('Please drop the user ', QUOTE(username), '@', QUOTE(hostname), ' in order to start replication.') INTO @msg;
SIGNAL SQLSTATE VALUE '45000' SET MESSAGE_TEXT = @msg;
END IF;
IF is_user_created = False THEN
SELECT CONCAT('CREATE USER ', QUOTE(username), '@', QUOTE(hostname), " IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED' PASSWORD EXPIRE NEVER ACCOUNT LOCK;") INTO @cmd;
PREPARE create_user FROM @cmd;
EXECUTE create_user;
END IF;
IF is_user_role_set = False THEN
SELECT CONCAT('GRANT rds_superuser_role TO ', QUOTE(username), '@', QUOTE(hostname)) INTO @cmd;
PREPARE grant_user_role FROM @cmd;
EXECUTE grant_user_role;
SELECT CONCAT('SET DEFAULT ROLE rds_superuser_role TO ', QUOTE(username), '@', QUOTE(hostname)) INTO @cmd;
PREPARE set_user_role FROM @cmd;
EXECUTE set_user_role;
SELECT CONCAT('GRANT REPLICATION_APPLIER ON *.* TO ', QUOTE(username), '@', QUOTE(hostname)) INTO @cmd;
PREPARE set_user_applier FROM @cmd;
EXECUTE set_user_applier;
END IF;
IF is_user_set = False THEN
SELECT CONCAT('CHANGE REPLICATION SOURCE TO PRIVILEGE_CHECKS_USER = ', QUOTE(username), '@', QUOTE(hostname), ';') INTO @cmd;
PREPARE set_priv_checks_user FROM @cmd;
EXECUTE set_priv_checks_user;
END IF;
END IF;
SET @@sql_log_bin=sql_logging;
SET @@autocommit=v_autocommit_status;
END;
rdsrepladmin_priv_checks_user 계정이 이미 존재하는지 등을 확인하는 부분과,
계정생성 + 롤부여 + 디폴트 롤 설정 + PRIVILEGE_CHECKS_USER 변경 하는 부분으로 구성되어 있습니다.
rdsrepladmin_priv_checks_user
는 MySQL 기본 기능이 아니라, RDS Aurora MySQL 전용 계정입니다. 3.07.1에서 추가되었습니다. rdsrepladmin_priv_checks_user
는 바이너리 로그 복제 설정 중에 생성됩니다. RDS 초기 구성시부터 생성되는 계정은 아닙니다. rdsrepladmin_priv_checks_user
는 권한 확인을 중앙 집중화하여 복제 프로세스를 간소화하고 보안을 강화합니다.mysql.rds_start_replication
및 mysql.rds_configure_privilege_checks_user
와 같은 스토어드 프로시저는 복제 설정을 자동화하고 보호합니다.