

# RDS for MySQL에 대한 역할 기반 권한 모델
<a name="Appendix.MySQL.CommonDBATasks.privilege-model"></a>

RDS for MySQL 버전 8.0.36부터는 `mysql` 데이터베이스의 테이블을 직접 수정할 수 없습니다. 특히 `grant` 테이블에서 데이터 조작 언어(DML) 작업을 수행하여 데이터베이스 사용자를 만들 수 없습니다. 대신 `CREATE USER`, `GRANT`, `REVOKE` 등의 MySQL 계정 관리 문을 사용하여 사용자에게 역할 기반 권한을 부여합니다. 또한 `mysql` 데이터베이스에 저장 프로시저를 비롯한 다른 종류의 객체를 생성할 수 없습니다. 여전히 `mysql` 테이블을 쿼리할 수 있습니다. 이진 로그 복제를 사용하는 경우 소스 DB 인스턴스의 `mysql` 테이블에 대한 직접 변경은 대상 클러스터로 복제되지 않습니다.

경우에 따라 애플리케이션에서 바로 가기를 사용하여 `mysql` 테이블에 삽입함으로써 사용자 또는 다른 객체를 만들 수 있습니다. 그렇다면 애플리케이션 코드를 변경하여 `CREATE USER`와 같은 해당 명령문을 사용합니다.

외부 MySQL 데이터베이스에서 마이그레이션하는 동안 데이터베이스 사용자의 메타데이터를 내보내려면 다음 메서드 중 하나를 사용합니다.
+ MySQL Shell의 인스턴스 덤프 유틸리티를 필터와 함께 사용하여 사용자, 역할 및 권한 부여를 제외합니다. 다음 예제는 사용하는 명령 구문을 보여 줍니다. `outputUrl`이 비어 있는지 확인합니다.

  ```
  mysqlsh user@host -- util.dumpInstance(outputUrl,{excludeSchemas:['mysql'],users: true})
  ```

  자세한 내용은 MySQL 참조 설명서의 [Instance Dump Utility, Schema Dump Utility, Table Dump Utility](https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-dump-instance-schema.html)를 참조하세요.
+ `mysqlpump` 클라이언트 유틸리티를 사용하세요. 이 예제에는 `mysql` 시스템 데이터베이스의 테이블을 제외한 모든 테이블이 포함됩니다. 또한 마이그레이션된 데이터베이스의 모든 MySQL 사용자를 재현하는 `CREATE USER` 및 `GRANT` 문이 포함됩니다.

  ```
  mysqlpump --exclude-databases=mysql --users
  ```

  MySQL 8.4에서는 `mysqlpump` 클라이언트 유틸리티를 더 이상 사용할 수 없습니다. 대신 `mysqldump`를 사용합니다.

많은 사용자 또는 애플리케이션에 대한 권한 관리를 단순화하려면 `CREATE ROLE` 문을 사용하여 권한 집합이 있는 역할을 만들 수 있습니다. 그런 다음, `GRANT` 및 `SET ROLE` 문과 `current_role` 함수를 사용하여 사용자 또는 애플리케이션에 역할을 할당하고 현재 역할을 전환하며 어떤 역할이 유효한지 확인할 수 있습니다. MySQL 8.0의 역할 기반 권한 시스템에 대한 자세한 내용은 MySQL 참조 설명서의 [역할 사용](https://dev.mysql.com/doc/refman/8.0/en/roles.html)을 참조하세요.

**중요**  
애플리케이션에서 직접 마스터 사용자를 사용하지 않는 것이 좋습니다. 대신에 애플리케이션에 필요한 최소 권한으로 생성한 데이터베이스 사용자를 사용하는 모범 사례를 준수하십시오.

버전 8.0.36부터 RDS for MySQL에는 다음과 같은 모든 권한이 있는 특수 역할이 포함됩니다. 이 역할의 이름은 `rds_superuser_role`입니다. 각 DB 인스턴스의 기본 관리 사용자에게는 이미 이 역할이 부여되었습니다. `rds_superuser_role` 역할에는 모든 데이터베이스 객체에 대한 다음과 같은 권한이 포함됩니다.
+  `ALTER` 
+  `APPLICATION_PASSWORD_ADMIN` 
+  `ALTER ROUTINE` 
+  `CREATE` 
+  `CREATE ROLE` 
+  `CREATE ROUTINE` 
+  `CREATE TEMPORARY TABLES` 
+  `CREATE USER` 
+  `CREATE VIEW` 
+  `DELETE` 
+  `DROP` 
+  `DROP ROLE` 
+  `EVENT` 
+  `EXECUTE` 
+  `INDEX` 
+  `INSERT` 
+  `LOCK TABLES` 
+  `PROCESS` 
+  `REFERENCES` 
+  `RELOAD` 
+  `REPLICATION CLIENT` 
+  `REPLICATION SLAVE` 
+  `ROLE_ADMIN` 
+  `SET_USER_ID` 
+  `SELECT` 
+  `SHOW DATABASES` 
+  `SHOW VIEW` 
+  `TRIGGER` 
+  `UPDATE` 
+  `XA_RECOVER_ADMIN`

 역할 정의에는 `WITH GRANT OPTION`이 포함되므로 관리 사용자가 다른 사용자에게 해당 역할을 부여할 수 있습니다. 특히 관리자는 MySQL 클러스터를 대상으로 사용하여 이진 로그 복제를 수행하는 데 필요한 모든 권한을 부여해야 합니다.

**작은 정보**  
 권한의 세부 정보를 모두 확인하려면 다음 문을 사용합니다.  

```
SHOW GRANTS FOR rds_superuser_role@'%';
```

 RDS for MySQL 버전 8.0.36 이상에서 역할을 사용하여 액세스 권한을 부여하는 경우 `SET ROLE role_name` 또는 `SET ROLE ALL` 문을 사용하여 해당 역할을 활성화합니다. 다음 예에서는 이 작업을 수행하는 방법을 보여줍니다. 적합한 역할 이름을 `CUSTOM_ROLE`로 대체합니다.

```
# Grant role to user
mysql> GRANT CUSTOM_ROLE TO 'user'@'domain-or-ip-address'

# Check the current roles for your user. In this case, the CUSTOM_ROLE role has not been activated.
# Only the rds_superuser_role is currently in effect.
mysql> SELECT CURRENT_ROLE();
+--------------------------+
| CURRENT_ROLE()           |
+--------------------------+
| `rds_superuser_role`@`%` |
+--------------------------+
1 row in set (0.00 sec)

# Activate all roles associated with this user using SET ROLE.
# You can activate specific roles or all roles.
# In this case, the user only has 2 roles, so we specify ALL.
mysql> SET ROLE ALL;
Query OK, 0 rows affected (0.00 sec)

# Verify role is now active
mysql> SELECT CURRENT_ROLE();
+--------------------------------------------------+
| CURRENT_ROLE()                                   |
+--------------------------------------------------+
| `CUSTOM_ROLE`@`%`,`rds_superuser_role`@`%` |
+--------------------------------------------------+
```