

# oracle\$1fdw 확장을 사용하여 Oracle 데이터베이스 작업
<a name="postgresql-oracle-fdw"></a>

 RDS for PostgreSQL DB 인스턴스에서 Oracle 데이터베이스에 액세스하려면 `oracle_fdw` 확장을 설치하고 사용할 수 있습니다. 이 확장은 Oracle 데이터베이스의 외부 데이터 래퍼입니다. 이 확장 프로그램에 대해 자세히 알아보려면 [oracle\$1fdw](https://github.com/laurenz/oracle_fdw) 문서를 참조하세요.

`oracle_fdw` 확장은 RDS for PostgreSQL 버전 12.7 및 13.3 이상에서 지원됩니다.

**Topics**
+ [oracle\$1fdw 확장 켜기](#postgresql-oracle-fdw.enabling)
+ [예제: Amazon RDS for Oracle Database에 연결된 외부 서버 사용](#postgresql-oracle-fdw.example)
+ [전송 중 암호화 작업](#postgresql-oracle-fdw.encryption)
+ [pg\$1user\$1mappings 보기 및 권한 이해](#postgresql-oracle-fdw.permissions)

## oracle\$1fdw 확장 켜기
<a name="postgresql-oracle-fdw.enabling"></a>

oracle\$1fdw 확장을 사용하려면 다음 절차를 수행하십시오.

**oracle\$1fdw 확장을 켜려면**
+ `rds_superuser` 권한이 있는 계정을 사용하여 다음 명령을 실행합니다.

  ```
  CREATE EXTENSION oracle_fdw;
  ```

## 예제: Amazon RDS for Oracle Database에 연결된 외부 서버 사용
<a name="postgresql-oracle-fdw.example"></a>

다음 예에서는 Amazon RDS for Oracle Database에 연결된 외부 서버를 사용하는 방법을 보여줍니다.

**RDS for Oracle Database에 연결된 외부 서버를 만들려면**

1. RDS for Oracle DB 인스턴스에서는 다음 사항에 유의하세요.
   + Endpoint
   + 포트
   + 데이터베이스 이름

1. 외부 서버를 만듭니다.

   ```
   test=> CREATE SERVER oradb FOREIGN DATA WRAPPER oracle_fdw OPTIONS (dbserver '//endpoint:port/DB_name');
   CREATE SERVER
   ```

1. `rds_superuser` 권한이 없는 사용자(예: `user1`)에게 사용 권한을 부여합니다.

   ```
   test=> GRANT USAGE ON FOREIGN SERVER oradb TO user1;
   GRANT
   ```

1. `user1`로 연결하고 Oracle 사용자에 대한 매핑을 생성합니다.

   ```
   test=> CREATE USER MAPPING FOR user1 SERVER oradb OPTIONS (user 'oracleuser', password 'mypassword');
   CREATE USER MAPPING
   ```

1. Oracle 테이블에 연결된 외부 테이블을 만듭니다.

   ```
   test=> CREATE FOREIGN TABLE mytab (a int) SERVER oradb OPTIONS (table 'MYTABLE');
   CREATE FOREIGN TABLE
   ```

1. 외부 테이블을 쿼리합니다.

   ```
   test=>  SELECT * FROM mytab;
   a
   ---
   1
   (1 row)
   ```

쿼리에서 다음 오류를 보고하면 보안 그룹 및 액세스 제어 목록(ACL)을 확인하여 두 인스턴스가 모두 통신할 수 있는지 확인합니다.

```
ERROR: connection for foreign table "mytab" cannot be established
DETAIL: ORA-12170: TNS:Connect timeout occurred
```

## 전송 중 암호화 작업
<a name="postgresql-oracle-fdw.encryption"></a>

PostgreSQL에서 Oracle 간의 전송 중인 암호화는 클라이언트와 서버 구성 파라미터의 조합을 기반으로 합니다. Oracle 21c를 사용하는 예제는 Oracle 문서의 [About the Values for Negotiating Encryption and Integrity](https://docs.oracle.com/en/database/oracle/oracle-database/21/dbseg/configuring-network-data-encryption-and-integrity.html#GUID-3A2AF4AA-AE3E-446B-8F64-31C48F27A2B5)를 참조하세요. Amazon RDS에서 oracle\$1fdw에 사용되는 클라이언트는 `ACCEPTED`로 구성됩니다. 즉, Oracle 데이터베이스 서버 구성에 따라 암호화가 달라지며, 암호화에 Oracle Security Library(libnnz)를 사용한다는 의미입니다.

데이터베이스가 RDS for Oracle에 있는 경우 암호화를 구성하려면 [Oracle 기본 네트워크 암호화](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.NetworkEncryption.html)를 참조하세요.

## pg\$1user\$1mappings 보기 및 권한 이해
<a name="postgresql-oracle-fdw.permissions"></a>

PostgreSQL 카탈로그 `pg_user_mapping`에서 RDS for PostgreSQL 사용자의 매핑을 외부 데이터(원격) 서버의 사용자에게 저장합니다. 카탈로그에 대한 액세스는 제한되어 있지만 `pg_user_mappings` 보기를 사용하여 매핑을 확인합니다. 다음에서는 예제 Oracle 데이터베이스를 통해 권한이 적용되는 방법을 보여 주는 예제를 확인할 수 있지만, 이 정보는 다른 외부 데이터 래퍼에도 일반적으로 적용됩니다.

다음 결과에서는 세 가지 예제 사용자에 매핑된 역할 및 권한을 찾을 수 있습니다. 사용자 `rdssu1`과 `rdssu2`는 `rds_superuser` 역할이며 `user1`은 아닙니다. 다음 예제에서는 `psql` 메타 명령 `\du`를 사용하여 기존 역할을 나열합니다.

```
test=>  \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+-------------------------------------------------------------
 rdssu1          |                                                            | {rds_superuser}
 rdssu2          |                                                            | {rds_superuser}
 user1           |                                                            | {}
```

`rds_superuser` 권한이 있는 사용자를 포함한 모든 사용자는 `pg_user_mappings` 테이블에서 자신의 사용자 매핑(`umoptions`)을 볼 수 있습니다. 다음 예제와 같이 `rdssu1`이 모든 사용자 매핑을 얻으려고 하면 `rdssu1``rds_superuser` 권한에도 불구하고 오류가 발생합니다.

```
test=> SELECT * FROM pg_user_mapping;
ERROR: permission denied for table pg_user_mapping
```

다음은 일부 예입니다.

```
test=> SET SESSION AUTHORIZATION rdssu1;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |            umoptions
-------+-------+---------+--------+------------+----------------------------------
 16414 | 16411 | oradb   |  16412 | user1      |
 16423 | 16411 | oradb   |  16421 | rdssu1     | {user=oracleuser,password=mypwd}
 16424 | 16411 | oradb   |  16422 | rdssu2     |
 (3 rows)

test=> SET SESSION AUTHORIZATION rdssu2;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |            umoptions
-------+-------+---------+--------+------------+----------------------------------
 16414 | 16411 | oradb   |  16412 | user1      |
 16423 | 16411 | oradb   |  16421 | rdssu1     |
 16424 | 16411 | oradb   |  16422 | rdssu2     | {user=oracleuser,password=mypwd}
 (3 rows)

test=> SET SESSION AUTHORIZATION user1;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |           umoptions
-------+-------+---------+--------+------------+--------------------------------
 16414 | 16411 | oradb   |  16412 | user1      | {user=oracleuser,password=mypwd}
 16423 | 16411 | oradb   |  16421 | rdssu1     |
 16424 | 16411 | oradb   |  16422 | rdssu2     |
 (3 rows)
```

`information_schema._pg_user_mappings` 및 `pg_catalog.pg_user_mappings`의 구현 차이점 때문에 수동으로 생성된 `rds_superuser`는 `pg_catalog.pg_user_mappings`에서 암호를 보려면 추가 권한이 필요합니다.

`information_schema._pg_user_mappings`에서 암호를 보려면 `rds_superuser`에 대한 추가 권한은 필요하지 않습니다.

`rds_superuser` 역할이 없는 사용자는 다음 조건에서만 `pg_user_mappings`에서 암호를 볼 수 있습니다.
+ 현재 사용자는 매핑되는 사용자이며 서버를 소유하거나 서버에 대한 `USAGE` 권한을 보유하고 있습니다.
+ 현재 사용자는 서버 소유자이고 매핑은 `PUBLIC`에 대한 것입니다.