Oracle Database を使う機会があったのですが、事情により Oracle Linux が使えなかったので Rocky Linux へインストールしました。その時の手順のメモです。

環境

用語

Oracle Database のインストール手順

Rocky Linux (や RHEL や Oracle Linux) では RPM パッケージを使って yum コマンドで Oracle Database をインストールできます。インストールは以下の手順で行います。

  1. Preinstall パッケージをインストール
  2. Oracle Database パッケージをインストール
  3. Oracle Database の初期構成スクリプトを実行

※なお今回は Non-CDB 環境 (CDB と PDB の構成ではなく、従来の 1 サーバーインスタンスに 1 データベースの構成) の方法をベースにしていますが、CDB環境の場合に必要なコマンドはコメントに記載しています。

1). Preinstall パッケージのインストール

以下のコマンドで、preinstall パッケージをダウンロード + インストールします。

# Preinstall パッケージのダウンロード
$ curl -o oracle-database-preinstall-19c-1.0-1.el8.x86_64.rpm 
https://yum.oracle.com/repo/OracleLinux/OL8/appstream/x86_64/getPackage/oracle-database-preinstall-19c-1.0-1.el8.x86_64.rpm

# Preinstall パッケージをインストール
$ sudo yum localinstall ./oracle-database-preinstall-19c-1.0-1.el8.x86_64.rpm

2). Oracle Database パッケージのインストール

Oracle のサイトから Linux x86-64 の RPM パッケージをダウンロードします。ダウンロードする時に Oracle アカウントにログインしないといけないので、事前にアカウントを作成しておきます。

https://www.oracle.com/database/technologies/oracle-database-software-downloads.html

ダウンロードした RPM をインストールします。

$ sudo yum -y localinstall oracle-database-ee-19c-1.0-1.x86_64.rpm

3). Oracle Database 初期構成スクリプトの実行

/etc/init.d/oracledb_ORCLCDB-19c というスクリプトを実行して Oracle Database の初期構成を行います。

$ sudo /etc/init.d/oracledb_ORCLCDB-19c configure
...
Database configuration completed successfully. The passwords were auto generated, you must change them by connecting to the database using 'sqlplus / as sysdba' as the oracle user.

これで ORCLCDB という CDB と、ORCLPDB1 というデフォルトの PDB が作成されます。

Non-CDB 構成にする場合

CDB 環境にせず Oracle Database を構成することも可能です。その場合は /etc/init.d/oracledb_ORCLCDB-19c スクリプトの以下の箇所を変更し、configure を実行します。

$ sudo vim /etc/init.d/oracledb_ORCLCDB-19c
---
# export CREATE_AS_CDB=true
export CREATE_AS_CDB=false
---
$ sudo /etc/init.d/oracledb_ORCLCDB-19c configure 

これで ORCLCDB というデータベースが構成されます。

4). SQL*Plus のインストール

SQL*Plus は Oracle Database のコマンドラインクライアントです。Oracle では DB サーバーにクライアントツールは含まれていないため、別途クライアントをインストールします。

SQL*Plus にも RPM パッケージが用意されていますが、Oracle Database パッケージと競合するためインストールできません。そのため ZIP ファイルをダウンロードして展開した後、PATH を通して使用します。

4-1). ZIPファイルのダウンロードと配置

以下の URL から “Basic Package (ZIP)” と “SQL*Plus Package (ZIP)” をダウンロードします。

https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html

ZIP ファイルを展開しバイナリを配置します。

$ sudo unzip -d /opt/oracle instantclient-basic-linux.x64-19.14.0.0.0dbru.zip
$ sudo unzip -d /opt/oracle instantclient-sqlplus-linux.x64-19.14.0.0.0dbru.zip

4-2). 共有ライブラリへの登録

Oracle クライアントツールのライブラリを、共有ライブラリへ登録します。

$ sudo su
$ echo "/opt/oracle/instantclient_19_14/" > /etc/ld.so.conf.d/sqlplus.conf
$ ldconfig
$ exit

4-3). 環境変数の設定

そして PATH を通して必要な環境変数を設定します。

$ vim ~/.bashrc
---
export ORACLE_SID=ORCLCDB
export ORACLE_BASE=/opt/oracle
export ORACLE_HOME=$ORACLE_BASE/product/19c/dbhome_1
export PATH=$PATH:$ORACLE_HOME/bin
export PATH=$PATH:/opt/oracle/instantclient_19_14
---
$ source ~/.bashrc

4-4). SQL*Plus を使ってログイン

これで SQL*Plus を使って Oracle Database にログインできるのですが、まだユーザーを作っていないのでそのままではログインできません。

Oracle ではインストールを行った Linux ユーザーが管理者としてログインできるという機能があります。今回の RPM パッケージを使ったインストールでは、oracle という名前の Linux ユーザーが作成され、そのユーザーが Oracle Database のインストールを行いました。なので oracle ユーザーとして SQL*Plus を実行すれば Oracle Database にログインできます。

$ sudo su oracle

# 上記と同じように環境変数を設定
$ vim ~/.bashrc
---
export ORACLE_SID=ORCLCDB
(省略)
---
$ source ~/.bashrc

# SQL*Plus を使って Oracle にログイン
$ sqlplus / as sysdba
SQL> # ここからユーザーを作成したりできる
SQL> exit

Oracle 初期設定

1). Firewall, 自動起動設定、および管理者ユーザーのパスワード設定

oracle ユーザーでデータベースに接続できるのを確認したら、以下の要領で初期設定を行います。

# Firewall 許可
$ sudo firewall-cmd --add-port=1521/tcp --permanent
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-ports

# Oracleデータベースの自動起動設定
$ sudo systemctl enable oracledb_ORCLCDB-19c
$ sudo systemctl restart oracledb_ORCLCDB-19c

# (CDB 環境の場合のみ) Pluggable Database を open する
# $ sudo su oracle
# $ sqlplus / as sysdba
# SQL> alter pluggable database ORCLPDB1 open;
# SQL> alter pluggable database ORCLPDB1 save state;

# 管理者ユーザーの初期パスワード設定
SQL> alter user system identified by <password>;
SQL> alter user sys identified by <password>;

2). 新しいユーザー追加とテストテーブルの作成

新しいユーザーを作成して、そのユーザーでログインできるかテストしてみます。

# ユーザー作成
# (CDB 構成の場合のみ) 以下のコマンドでPDBへ接続し直す
# SQL> alter session set container = ORCLPDB1;
SQL> create user <username> identified by "<password>" default tablespace USERS temporary tablespace TEMP;

# 必要な権限を付与。今回はテストのためなので grant all としています。
SQL> grant all privileges to <username>;
SQL> exit;

# (CDB 環境の場合) 接続先データベースに ORCLPDB1 を指定
# $ sqlplus <username>/<password>@//localhost:1521/ORCLPDB1

# (Non-CDB 環境の場合) 接続先データベースに ORCLECDB を指定
$ sqlplus <username>/<password>@//localhost:1521/ORCLCDB
SQL>

テスト用にテーブルを作成しデータを登録してみます。

SQL> create table <table-name> (id number, name nvarchar2(255), updated timestamp);
SQL> select * from <table-name>;
SQL> insert into <table-name> values (1, 'name 1', current_timestamp);
SQL> commit;
SQL> select * from <table-name>;

3). Archive Log の有効化

Archive Log を有効化するにはデータベースを一度停止する必要があります。また Archive Log のログ保持期間を変更するには RMAN というツールを使ってポリシーを更新します。

最後に、Oracle のトランザクションログには通常更新されたカラムの情報のみが記載されます (例えば UPDATE 文で 1つのカラムしか更新されなかった場合、トランザクションログにはそのカラムの値のみが記載されます)。レプリケーション製品によってはトランザクションログに更新された行の全てのカラムの値が記載されている必要があるものがあり、このために Supplemental Logging という機能を有効化する必要があります。

以下に Archive Log の有効化、Archive Log 保持期間の変更、Supplemental Loggingの有効化の方法を記載します。

3-1). Archive Log 有効化

$ sudo su oracle
$ sqlplus / as sysdba;

# Archive Log モードを確認
SQL> SELECT LOG_MODE FROM V$DATABASE;
LOG_MODE
------------
NOARCHIVELOG (または ARCHIVELOG)

# NOARCHIVELOG と表示されたら、Archive Log を有効化する
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE ARCHIVELOG;
SQL> ALTER DATABASE OPEN;
SQL> SELECT LOG_MODE FROM V$DATABASE;
LOG_MODE
------------
ARCHIVELOG

SQL> exit

3-2). Archive Log 保持期間の変更

以下では Archive Log の保持期間を 7日に設定しています。

$ sudo su oracle
$ rman target /
RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
using target database control file instead of recovery catalog
new RMAN configuration parameters:
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
new RMAN configuration parameters are successfully stored

RMAN> exit

3-3). Supplemental Logging の有効化

$ sudo su oracle
$ sqlplus / as sysdba

# 以下のコマンドで全てのテーブル/カラムで Supplemental Logging を有効化できる
# (テーブル/カラムを個別に指定する方法もあります)
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (all) COLUMNS;

Oracle Database の基礎

Oracle は多機能で歴史のあるデータベースなので、調べる時も時間がかかると思います。この記事ではOracle を使う上で初めに知っておくと便利なトピックを簡単に説明したいと思います。

制御ファイルとパラメータファイル

Oracle にはデータファイルの他に、データベースを起動するために必要なファイルがいくつかあり、特に重要なのは “制御ファイル” と “パラメータファイル” です。

制御ファイル はデータベースの物理構造を記録したバイナリファイルで、データベース名、対応するデータファイルや REDO ログファイルの情報、現在のトランザクションログ番号などが保存されます。制御ファイルが無いとデータベースを構成する物理ファイルを読み込めないため、データベースを使うことができません。

パラメータファイル は Oracle Database の構成情報を記録するファイルです。この構成情報は “初期化パラメータ” または単に “パラメータ” と呼ばれます。

パラメータファイルには 2種類あり、それぞれ PFILE SPFILE と呼ばれます。

PFILE は古いフォーマットで、テキスト形式で構成情報を記述する構成ファイルです。

SPFILE は新しいフォーマットで、構成情報はバイナリ形式で保存されるため、テキストエディタ等で直接編集することはできません。SPFILE を使う場合は、ALTER SYSTEM SET <parameter-name> = <value>; という SQL を実行してパラメータを設定します。

現在は SPFILE を使う場合がほとんどですが、データベースの複製時などテキストエディタで直接パラメータを書き換えた方が楽な場合は、一度 SPFILE の内容を PFILE に書き出す、ということも行います。

なお、現在のパラメータ設定値を確認するには SHOW PARAMETER <parameter-name>; コマンドが使えます。

データベースの起動順序

Oracle Database は停止状態も含めると 4つの状態があります。状態は順に進めることも、特定の状態まで一度に進めることもできますが、1つ前の状態に戻すことはできません。状態を戻したい場合は一度シャットダウンしてから再度起動し直す必要があります。

データベースを停止する時は SHUTDOWN IMMEDIATE; コマンドで、開始する時は STARTUP <データベースの状態>; コマンドを使います。既に起動済みのデータベースの状態を進めるには ALTER DATABASE <データベースの状態> コマンドでできます。

  1. 停止状態: データベースが停止している状態で、DB に接続できません。
  2. NOMOUNT 状態: 初期化パラメータが読み込まれ、システム共有メモリが確保されバックグラウンドプロセスが開始した状態。
    • 初期化パラメータが読み込まれているため、パラメータの設定ができます。
    • いくつかのシステムビューに対して SELECT クエリを実行できます。
  3. MOUNT 状態: 制御ファイルが読み込まれます。
    • 制御ファイルにデータファイル等の場所が記録されているため、バックアップやリカバリを実行できます。
  4. OPEN 状態: システム表領域がロードされ、データディクショナリが利用可能になります。
    • データディクショナリとは、テーブル、ユーザー、その他の重要な情報が格納されているシステム テーブルです。
    • データディクショナリが利用可能になることで、データベースに対してクエリを実行できるようになります。

Oracle Database への接続について

Oracle にはいくつかの接続方法がありますが、ここでは一般的に使用される Oracle Net での接続方法を説明します。

Oracle Database への接続方法

先に説明したように、SQL*Plus から Oracle Database へ接続するには以下のコマンドを実行します。

$ sqlplus <user>/<password>@<データベース接続情報>
SQL>  # これでデータベースに接続した状態です

データベース接続情報” の部分には、接続文字列をそのまま記述することもできますし、”Net Service Name” (ネットサービス名) と呼ばれる接続情報につけた名前を指定することもできます。

接続文字列は、//<host>:<port>/<oracle-sid> というフォーマットで指定できます。

例えばローカルの ORCLCDB インスタンスに接続する場合は、sqlplus <user>/<password>@//localhost:1521/ORCLCDB というコマンドで接続できます。

また ローカル接続 (ローカルマシンの Oracle Database への接続) の場合は、環境変数に ORACLE_SID を指定することで、データベース接続情報を省略することも可能です。

ORACLE_SID (サービスD) と SERVICE_NAME (サービス名)

Oracle Database には複数の ID や名前がありますが、データベースへの接続に使われるのは主に ORACLE_SID SERVICE_NAME です。

ORACLE_SID は Oracle Database のインスタンスに付けられる ID で、ローカル接続にのみ使用されます。環境変数に ORACLE_SID を設定することで、ローカル接続時に接続情報を記述しなくてもデータベースに接続できます。

SERVICE_NAME は初期化パラメータで設定される名前で、リモート接続で使われます。

Oracle Database は起動する時に、自身をリスナーというリモート接続を処理するプロセスに登録します。この時、Oracle Database は自身の SERVICE_NAME を使ってリスナーに登録するため、クライアントがリモートから接続する時は、この SERVICE_NAME を指定する必要があります。

SERVICE_NAME の初期値は DB_UNIQUE_NAME という初期化パラメータが設定されます。この記事で紹介した手順でインストールした場合、DB_UNIQUE_NAME は SID と同じになります。

(正確には、SERVICE_NAME の初期値は <DB_DOMAIN>.<DB_UNIQUE_NAME> というフォーマットで設定され、DB_DOMAIN という別の初期化パラメータも使われます。ただ DB_DOMAIN はデフォルトで空なので、実質 DB_UNIQUE_NAME が設定されています)

OS 認証と パスワード認証

Oracle Database へ接続する時の認証方法に、”OS 認証” と “パスワード認証” の 2種類があります。

OS 認証は、Oracle Database がインストールされているマシンの OS の認証情報を使った方法で、ローカル接続のみで使用します。OS 認証では OS の認証情報が使用されるため、データベース接続時にユーザー名とパスワードを入力する必要はありません。

また Oracle Database では OS の dba グループのユーザーに対して、管理者 (SYSDBA) 権限を付与します。dba グループに含まれるユーザーがデータベースに接続する時も OS 認証が使われています。(なおこの場合、正確には SYS ユーザーとしてデータベースに接続しています)

先のインストール手順で以下のようにデータベースへ接続しました。

$ sudo su oracle
$ sqlplus / as sydba
SQL>

sqlplus のパラメータで、ユーザーやパスワード、データベース接続情報も空ですが、これは、

  1. oracle ユーザーは dba グループに含まれるユーザーなので、ユーザー名とパスワードを使用せず、OS 認証を使って SYSDBA 管理者としてログインすることができた。
  2. ORACLE_SID 環境変数が設定されているローカル接続なので、データベース接続情報を省略できた。

という理由によるものです。

tnsnames.ora による接続情報の管理

先に “データベース接続情報は //<host>:<port>/<oracle-sid> というフォーマットで記述する” と書きました。これを毎回記述するのは面倒なので、接続情報に名前を付けて別の場所に記録しておくことができます。

接続情報を記録しておくファイルは tnsnames.ora という名前である必要があります。場所も $ORACLE_HOME/network/admin/ フォルダに配置する必要があります。

tnsnames.ora は以下のようなフォーマットで記述します。

<net-service-name> =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = <host-or-ip>)(PORT = <port>))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = <service-name>)
    )
  )

例えば IP アドレス 192.168.11.2 で、SERVICE_NAME に ORCLCDB が設定されたデータベースに接続する場合の設定は以下のようになります。

tnsnames.ora

TESTCONN =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.11.2)(PORT = <port>))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCLCDB)
    )
  )

sqlplus コマンド

# 以下のコマンドで上記で指定したデータベースに接続できる
$ sqlplus <user>/<password>@TESTCONN

REDO ログとアーカイブログ

Oracle では各トランザクションの記録が REDO ログというファイルに記録されます。Oracle では 2つ以上の REDO ログファイルが順番にローテーションして使われます。例えば初めは REDO ログファイル 1 にトランザクションログを記録し、ファイルがいっぱいになったら REDO ログファイル 2 を使う… という風に順番に使っていきます。

使用する REDO ログファイルを切り替える操作を “ログスイッチ” と呼びます。REDO ログが一巡すると、また初めの REDO ログファイルを上書きして使います。

トランザクションログには前回のフルバックアップを取った後の全ての操作が記録されているため、データの復元に使用されます。ただ REDO ログファイルは時間が経つと上書きされてしまうため、上書きされる前に別途コピーして保存します。そのコピーのことをアーカイブログと呼びます。

REDO ログはログスイッチのタイミングでアーカイブログとしてコピーされます。ログスイッチのタイミングはあらかじめ設定されているログファイルの容量がいっぱいになった時に行われる他、一定の時間間隔で定期的に実行するよう構成することもできます。

REDO ログファイルに含まれる各トランザクションのエントリーには システム変更番号 (SCN) が割り当てられます。トランザクションが実行される度に SCN はインクリメントされます。

また 各 REDO ログファイルには ログ順序番号 (LSN) が割り当てられます。LSN はログスイッチが行われる度にインクリメントされます。

Log Miner の使い方

Log Miner は REDO Log や Archive Log の中身を見る時に必要なツールで、Oracle Database に含まれています。

Log Miner は SQL*Plus で接続した後 EXECUTE 文を実行して使用します。まず中身を見たい Archive Log ファイルを追加し Log Miner を開始します。すると V$LOGMNR_CONTENTS というビューに Archive Log ファイルの中身が保存されるので、そのビューに対して SELECT 文を実行することで Archive Log の中身を見ることができる、という流れになります。

# Archive Log ファイルを確認
$ ls /opt/oracle/oradata/ORCLCDB/
redo01.log
redo02.log
...

$ sudo su oracle
$ sqlplus / as sysdba

# 中身を見たい Archive Log ファイルを追加
SQL> EXECUTE SYS.DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '/opt/oracle/oradata/ORCLCDB/redo01.log', OPTIONS => SYS.DBMS_LOGMNR.NEW);

# Log Miner を開始
SQL> EXECUTE SYS.DBMS_LOGMNR.START_LOGMNR(OPTIONS => SYS.DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + SYS.DBMS_LOGMNR.COMMITTED_DATA_ONLY);

# Archive ログの内容は `V$LOGMNR_CONTENTS` から見れる
SQL> SELECT SCN, TIMESTAMP, SQL_REDO FROM V$LOGMNR_CONTENTS ORDER BY SCN DESC

# Log Miner の終了
SQL> EXECUTE SYS.DBMS_LOGMNR.END_LOGMNR();

以上、Oracle Database のインストール方法および概要でした。