小ネタ: RDS for Oracle でDB名を変更する

RDSのコンソールにも表示される「DB名」を変更する方法を、RDS for Oracleで検証した結果と合わせて紹介します。
2020.02.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Guten Abend、ベルリンの伊藤です。

表題の件、ご存知の方には今さらかもしれませんがググると意外と情報が見つからなかったので、書きます。RDS インスタンスを最初に起動する際に指定する DB名 であり、インスタンス名ではありません。

※DBインスタンス名の変更はこちらのドキュメントから。

結論から言うと、現時点でそのまま変更することはできず、スナップショットからリストアする際にDB名を再度指定することができます。インスタンスのスナップショットを取得、取得したスナップショットからインスタンスの復元、その際に次のようにDB名を指定するだけです。

以下、EC2を起動してsqlplusでRDS (Oracle)に接続するまでの流れも簡単に紹介します。

前提条件

以下の条件で検証しました。

  • エンジン: Oracle Standard Edition One
  • バージョン: 11.2.0.4.v22

手順

DBインスタンスの起動

上のエンジンバージョンに加え、下記の通りRDSインスタンスを作成しました。

  • ライセンス: licence-included
  • テンプレート: 開発/テスト
  • インスタンスサイズ: db.t3.micro
  • 自動スケーリング、マルチAZ配置: なし
  • パブリックアクセス、自動バックアップ、Performance Insights、拡張モニタリング、各種ログも無効

今回セキュリティグループには VPC のデフォルトのものを関連づけています。

次の通りDB名は指定しませんでした。(指定しないとRDSはデータベースを作成しないと表示されていますが、Oracleの場合はデフォルトで「ORCL」が作成されます。もちろん指定してもOK。)

注1:
Oracleではエンジンバージョンによってサポートされるインスタンスクラスが異なるので、あらかじめドキュメントを確認しましょう。

注2:
今回インスタンス作成、スナップショットの復元時に、何度か 互換性のないネットワーク となり起動に失敗しました。AWSのトラブルシューティングページではいろいろ書いてありますが、もし設定でどこも問題ない場合は「起動したサブネットに、使用可能な IP アドレスがありません」に該当するかと思います。今回アイルランド(eu-west-1)では、AZを指定しないと3,4回のうち2度ほど失敗しましたが、既に起動に成功していたeu-west-1bに指定すると失敗なく起動できました。

EC2インスタンスの起動(DB接続用)

Linuxインスタンスを起動します。今回利用したのは Amazon Linux 2 AMI (HVM), SSD Volume Type - ami-0713f98de93617bb4 です。

セキュリティグループには、EC2とRDS間の通信のため、先ほどRDSで指定したのと同じ VPC のデフォルトのものを。加えて、自分の端末からEC2のSSH通信を許可するセキュリティグループも関連付けます。

ログインします。

$ ssh -i .ssh/KEY-PAIR.pem ec2-user@ec2-xx-xx-xx-xx.eu-west-1.compute.amazonaws.com

EC2からsqlplusでRDSに接続

sqlplus のインストールのため、OracleのLinux用Instant Clientダウンロードページから instantclient-basic-linux.x64-11.2.0.4.0.zipinstantclient-sqlplus-linux.x64-11.2.0.4.0.zip をダウンロードしました。(※ダウンロード時、Oracleアカウントへのログインが必要)

ローカル端末からEC2にダウンロードしたインストーラを送ります。

$ scp -i .ssh/KEY-PAIR.pem Downloads/instantclient-basic-linux.x64-11.2.0.4.0.zip ec2-user@ec2-xx-xx-xx-xx.eu-west-1.compute.amazonaws.com:/home/ec2-user
$ scp -i .ssh/KEY-PAIR.pem Downloads/instantclient-sqlplus-linux.x64-11.2.0.4.0.zip ec2-user@ec2-xx-xx-xx-xx.eu-west-1.compute.amazonaws.com:/home/ec2-user

EC2に戻り、ホームに置かれたインストーラを unzip した後、~/.bash_profile に下記を追記します。

export ORACLE_HOME=/home/ec2-user/instantclient_11_2
export PATH=${ORACLE_HOME}:${PATH}
export LD_LIBRARY_PATH=${ORACLE_HOME}

ようやくDBに接続できます。RDS作成時のユーザ名・パスワードと、インスタンスのエンドポイント、ポート、DB名を使います。

$ sqlplus RDS-MASTER-USER/PASSWORD@INSTANCE-NAME.xxxxxxxxxx.eu-west-1.rds.amazonaws.com:1521/ORCL

試しに簡単にテーブル作成してみました。

SQL> CREATE TABLE emp 
 (
 empno VARCHAR2(10) NOT NULL,
 empname VARCHAR2(50),
 gender_f NUMBER(1,0)
 );

SQL> INSERT INTO emp VALUES ('A002', 'ccccc', 1);
SQL> INSERT INTO emp VALUES ('A001', 'aaaaa', 0);
SQL> INSERT INTO emp VALUES ('A003', 'bbbbb', 1);

SQL> commit;

スナップショットからの復元

あとは冒頭でお伝えした通り、コンソールに戻ってDBスナップショットを作成し、スナップショットから復元する際に、DB名を指定します。DB名には文字と数字のみ、8文字までという制限があります。

復元したインスタンスへの接続時には、DB名に元の名前 ORCL を指定してもログインできず、変更した名前 RESTORE でログイン成功できます。またDB名を変えてリストアしましたが、作成したテーブルレコードが取得できることも確認できました。

SQL> select * from emp;

EMPNO      EMPNAME                      GENDER_F
---------- -------------------------------------------------- ----------
A002       ccccc                               1
A001       aaaaa                               0
A003       bbbbb                               1

補足その1

DB名は接続時に使用するだけでなく、コンソールでも表示されます。表示される場所は...すみません、キャプチャ撮り忘れたんですが、次のブログで確認できます。

RDS初期構築時に作ったDB名をAWS CLIから確認する方法

このブログではPostgreSQLを使用しており、コンソール上ではDB名の箇所にインスタンス名が表示されてしまうとありますが、Oracleでは正しくDB名が表示されます。また現時点でPostgreSQLでは、今回のようにスナップショットからの復元ではDB名の変更ができないことを確認しています。

補足その2

RDSではデータベースに関する変更権限がないため ALTER DATABASE は下記のように失敗するものの、その代替となるプロシージャを使ってデータベースのグローバル名を変更することができます。

SQL> ALTER DATABASE RENAME GLOBAL_NAME TO db0204;
ALTER DATABASE RENAME GLOBAL_NAME TO db0204
                                     *
ERROR at line 1:
ORA-01031: insufficient privileges

SQL> exec rdsadmin.rdsadmin_util.rename_global_name(p_new_global_name => 'db0204');

PL/SQL procedure successfully completed.

ということで一瞬勘違いしたんですが、これはグローバル名であってDB名とは異なり、コンソールの表示もログイン時の指定も更新されません。(グローバル名変更後も、下記NAMEは変更されず)

SQL> SELECT global_name FROM global_name;

GLOBAL_NAME
--------------------------------------------------------------------------------
DB0204

SQL> SELECT DBID,NAME,DB_UNIQUE_NAME,CURRENT_SCN,LOG_MODE FROM V$DATABASE ;  

      DBID NAME      DB_UNIQUE_NAME         CURRENT_SCN LOG_MODE
---------- --------- ------------------------------ ----------- ------------
0000000000 ORCL      ORCL_A              000000 NOARCHIVELOG

ということでした。

以上です!Schönen Abend!