Oracle Database 19c Install [Single Instance] (RU19.20)

# はじめに
今回は、Oracle Database 19c （RU19.20）をOracle Linux 8.0 にインストールする手順です。
今回、OUIでソフトウェアインストールする際にRUを適用する感じで進めております。

巷に溢れているものではりますが、自分用にメモを加えておこうかなと。

:::note warn
何かあっても自己責任！
:::


# 環境情報
今回検証をする環境は以下の通りです。


| 項目 | 詳細 |
|:-:|:--|
|VM|Oracle VirtualBox|
|CPU|4 core|
|Memory|8 GiB|
|Disk|120 GiB|
|OS|Oracle Linux 8 Update 0 (kernel 4.18.0-80.el8.x86_64)|
|DB|Oracle Database 19.3.0.0.0|
|Patch|Database Release Update 19.20.0.0 (Patch#35320081)|

※とりあえずOSはインストール時に「サーバ（GUI 使用）」で
　EFI有効にしてインストールしたところから。

# OS設定まわり
Oracle Databaseをインストールする前提条件的なところの設定。

## OS再起動が必要なもの諸々
OS設定変更では再起動が必要なものがいくつかあるので設定していく。

### Transparent hugepages (THP) の無効化
OracleではOSのTHPを無効化することを推奨しているので無効化する。
（OSデフォルトで有効になっている）

確認するには以下のコマンド
```shell-session
# cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
```
neverが無効化なので、```/etc/default/grub```の下記を修正する。
```diff_vim_l:/etc/default/grub
- GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet"
+ GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet transparent_hugepage=never"
```
編集が終わったら以下のコマンドでGRUB設定ファイルを再作成
```shell-session
# grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
Generating grub configuration file ...
Adding boot menu entry for EFI firmware configuration
done
```
本来はここで再起動なのだけど、何回も再起動をするのが面倒（）なのでついでに下記あたりも設定変更しておく。

### firewalldの停止と自動起動の無効化
このあたりは要件によりけりだけど、検証環境なので無効化してまう（）
```shell-session
# systemctl stop firewalld.service
```
```shell-session

# systemctl disable firewalld.service
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
```
```shell-session
# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
```

### SELinuxの無効化
検証環境なので（ry

```shell-session
# getenforce
Enforcing

# vi /etc/selinux/config
```
```diff_vim_l:/etc/selinux/config
- SELINUX=enforcing
+ SELINUX=disabled
```

### OS再起動
諸々の準備が整ったのでOS再起動
```shell-session
# reboot
```


OS再起動が終わったら設定ができているかを確認しましょう。
```shell-session
# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]

# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

# getenforce
Disabled
```

## OSユーザとかディレクトリの準備
### カーネルパラメータの修正
カーネルパラメータの修正用にファイル（```/etc/sysctl.d/97-oracle-database-sysctl.conf```）を新規作成
```shell-session
# vi /etc/sysctl.d/97-oracle-database-sysctl.conf
```
```shell:/etc/sysctl.d/97-oracle-database-sysctl.conf
fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 4294967295
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
```

設定反映
```shell-session
# sysctl --system
```
<details><summary>出力例</summary>

```shell
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
kernel.yama.ptrace_scope = 0
* Applying /usr/lib/sysctl.d/50-coredump.conf ...
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %e
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.sysrq = 16
kernel.core_uses_pid = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.promote_secondaries = 1
net.core.default_qdisc = fq_codel
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /usr/lib/sysctl.d/50-libkcapi-optmem_max.conf ...
net.core.optmem_max = 81920
* Applying /usr/lib/sysctl.d/60-libvirtd.conf ...
fs.aio-max-nr = 1048576
* Applying /etc/sysctl.d/97-oracle-database-sysctl.conf ...
fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 4294967295
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.conf ...
```
</details>

### OSグループとユーザの作成
グループIDとユーザIDは空いているところから任意で。
OSグループは正味、oinstall, dba があればいい。あとは必要に応じて。

```shell-session
# groupadd -g 54321 oinstall
# groupadd -g 54322 dba
# groupadd -g 54323 oper
# groupadd -g 54324 dgdba
# groupadd -g 54325 kmdba
# groupadd -g 54326 racdba
```

続いてOSユーザの作成（Oracle Databaseの所有者）
```shell-session
# useradd -u 54321 -g oinstall -G dba,oper,backupdba,dgdba,kmdba,racdba oracle
```

パスワードを設定。
良い子はちゃんとパスワード要件を満たしましょうね。
```shell-session
# passwd oracle
ユーザー oracle のパスワードを変更。
新しいパスワード:
よくないパスワード: このパスワードは 8 文字未満の文字列です。
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。
```

こんな感じになっていればOK
oracle のプライマリグループは oinstall です。
```shell-session
# id oracle
uid=54321(oracle) gid=54321(oinstall) groups=54321(oinstall),54322(dba),54323(oper),54324(backupdba),54325(dgdba),54326(kmdba),54327(racdba)
```

### リソース制御の設定
お作法的に以下を設定しましょう。

```shell-session
# vi /etc/security/limits.conf
```
```shell:/etc/security/limits.conf
oracle  soft  nofile  1024
oracle  hard  nofile  65536
oracle  soft  nproc   2047
oracle  hard  nproc   16384
oracle  soft  stack   10240
oracle  hard  stack   32768
oracle  soft  memlock 5274299
oracle  hard  memlock 5274299
```
というのは乱暴なので、ちょっと説明。

> | リソース・シェル制限 | resource | soft limit | hard limit |
> |:--|:--|:--|:--|
> | オープン・ファイル記述子数 | nofile | 1024 以上 | 65536 以上 |
> | 単一ユーザが使用可能なプロセス数 | nproc | 2047 以上 | 16384 以上 |
> | プロセスのスタック・セグメントのサイズ | stack | 10240KB 以上 | 1024KB ~ 32768KB |
> | ロックされたメモリの最大上限 | memlock | 無制限 | 無制限 |

https://docs.oracle.com/cd/F19136_01/ladbi/checking-resource-limits-for-oracle-software-installation-users.html#GUID-293874BD-8069-470F-BEBF-A77C06618D5A

※上記、執筆時点では有効なリンクですが、Oracleマニュアルはよくリンク切れになるのでググってくださいな。。

<details><summary> memlock 算出方法 </summary>

面倒なのは memlock. 無制限て。。。

memlock ってなんぞ？という諸氏はググっていただけると。最近AIが賢いので。
とりあえず物理メモリにロックできるメモリ量だと思っていただけると。
Oracle DBだとSGAに割り当てるとパフォーマンス良くなるよ。

さて、Oracleさんが言うには、memlock の値は、
hugepages が有効な場合は現在RAMの90%以上、
hugepagesが無効な場合は3145728KB (3GB) とのこと。

実際に使われてるかどうかは、Hugepages_Rsvd あたりを見てください。
んで、計算に使うのは ```Hugepagesize``` の値です。たいていは 2048kB だと思います。
```shell-session
# cat /proc/meminfo | grep hugepage
```
```shell-session
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
```

計算はざっくりと以下でSGAに割り当てるページ数を算出する
```shell-session
SGAサイズ(MB) / hugepagesize(MB) = 必要ページ数
```

ほんでもって、ページ数を少し切り上げたうえで、2048 をかけると出せる。

```shell-session
必要ページ数 + キリバンまでの値 = 必要ページ数（盛り）
必要ページ数（盛り） * 2048 = memlock に設定する値
```

超ざっくりだけど、これで大丈夫。

e.g.)
SGA に 4GB 割り当てたいなーって場合は以下のように計算。

```shell-session
(4gB * 1,024) / (2,048kB / 1,024) = 2,048 (page)
2,048 + 52 = 2,100 (page)
2,100 * 2,048 = 4,300,800
```
--> limits.conf に memlock soft/hard 4300800 を設定する

参考までに。

</details>

続いて、limits が読み込まれる様に以下を設定。
末尾とかでいいです。
```shell-session
# vi /etc/pam.d/login
```
```diff_vim_l:/etc/pam.d/login
-
+ session    required     pam_limits.so
```

### 追加パッケージのインストール
まずは、不足してるパッケージを探してみる。
※環境によって異なるので参考までに。
```shell-session
# export LANG=C
# rpm -q {openssl,bc,binutils,elfutils-libelf,elfutils-libelf-devel,fontconfig-devel,glibc,glibc-devel,ksh,libaio,libaio-devel,libXrender,libX11,libXau,libXi,libXtst,libgcc,libnsl,librdmacm,libstdc++,libstdc++-devel,libxcb,libibverbs,make,smartmontools,sysstat} | grep "is not installed"

package elfutils-libelf-devel is not installed
package fontconfig-devel is not installed
package glibc-devel is not installed
package ksh is not installed
package libaio-devel is not installed
package libnsl is not installed
package libstdc++-devel is not installed
package make is not installed
package sysstat is not installed
```
不足しているものをインストール。
rpm -ivh でも yum install でも好きな方で。 rpm の場合は依存関係が大変な気持ち。
```shell-session
# yum -y install elfutils-libelf-devel fontconfig-devel glibc-devel ksh libaio-devel libnsl libstdc++-devel make sysstat
  :
(省略)
  :
Complete!
```

もっかい、rpm -q やって何も表示されなければOK
念のため、最後に再起動しておく。

```shell-session
# reboot
```

# DBインストール
※必要な媒体とかは適当な場所にWinSCPとかで転送しておく。wget.sh 使ってもOK
今回こんな構成です。

| 項目 | 詳細 |
|:--|:--|
| Oracleベース | /u01/app/oracle |
| Oracleホーム | /u01/app/oracle/product/19.0.0/dbhome_1 |
| インベントリ | /u01/app/oraInventory |
| OPatch | 12.2.0.1.39 |
| OSインストールグループ | oinstall |
| OSDBAグループ | dba |

OSをGUIでインストールしましたが、せっかくなのでCUIベースのインストールにします。

### ディレクトリの作成
必要なものを作ってく。

```shell-session
# mkdir -p /u01/app/oraInventory
# mkdir -p /u01/app/oracle/product/19.0.0/dbhome_1
# chown -R oracle.oinstall /u01
# chmod -R 775 /u01
```

## 環境変数の設定
ここからOSユーザは oracle さんです。

```shell-session
# su - oracle
```

さくっと環境変数を設定しておく。
```shell-session
$ vi ~/.bash_profile
```
```diff_shell:~/.bash_profile
# User specific environment and startup programs
-
+ export umask=022
+ export NLS_LANG=Japanese_Japan.AL32UTF8
+ export ORACLE_BASE=/u01/app/oracle
+ export ORACLE_HOME=${ORACLE_BASE}/product/19.0.0/dbhome_1
+ export PATH=${PATH}:${ORACLE_HOME}/bin
```

読み込んでおく
```shell-session
$ source ~/.bash_profile
```

## OSソフトウェアのインストール
媒体は /tmp に送っておいたので、ORACE_HOMEに展開

```shell-session
$ cd ${ORACLE_HOME}
$ pwd
/u01/app/oracle/product/19.0.0/dbhome_1
```
展開する
```shell-session
$ unzip -q -d ${ORACLE_HOME} /tmp/database_19c.zip
$ ls
OPatch      css          dmu            javavm   nls      owm          root.sh.old.1  srvm
QOpatch     ctx          drdaas         jdbc     odbc     perl         runInstaller   suptools
R           cv           dv             jdk      olap     plsql        schagent.conf  ucp
addnode     data         env.ora        jlib     opmn     precomp      sdk            usm
apex        dbjava       has            ldap     oracore  racg         slax           utl
assistants  dbs          hs             lib      ord      rdbms        sqldeveloper   wwg
bin         deinstall    install        md       ords     relnotes     sqlj           xdk
clone       demo         instantclient  mgw      oss      root.sh      sqlpatch
crs         diagnostics  inventory      network  oui      root.sh.old  sqlplus
```
OPatchが古いので差し替え
```shell-session
$ mv OPatch OPatch_org
$ unzip -q -d ${ORACLE_HOME} /tmp/p6880880_190000_Linux-x86-64.zip
$ OPatch/opatch version
OPatch Version: 12.2.0.1.39

OPatch succeeded.
```

RUも展開しておく。
```shell-session
$ unzip -q -d /tmp /tmp/p35320081_190000_Linux-x86-64.zip
$ ls /tmp/35320081
README.html  README.txt  custom  etc  files 
```

今回使う db.rsp はこちら。
```shell-session
$ cat ~/db.rsp | grep -v "#" | grep -v "^$"
```
```shell:~/db.rsp
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v19.0.0
oracle.install.option=INSTALL_DB_SWONLY
UNIX_GROUP_NAME=oinstall
INVENTORY_LOCATION=/u01/app/oraInventory
ORACLE_BASE=/u01/app/oracle
oracle.install.db.InstallEdition=EE
oracle.install.db.OSDBA_GROUP=dba
oracle.install.db.OSOPER_GROUP=oper
oracle.install.db.OSBACKUPDBA_GROUP=backupdba
oracle.install.db.OSDGDBA_GROUP=dgdba
oracle.install.db.OSKMDBA_GROUP=kmdba
oracle.install.db.OSRACDBA_GROUP=racdba
oracle.install.db.rootconfig.executeRootScript=true
oracle.install.db.rootconfig.configMethod=ROOT
oracle.install.db.rootconfig.sudoPath=
oracle.install.db.rootconfig.sudoUserName=
oracle.install.db.CLUSTER_NODES=
oracle.install.db.config.starterdb.type=GENERAL_PURPOSE
oracle.install.db.config.starterdb.globalDBName=
oracle.install.db.config.starterdb.SID=
oracle.install.db.ConfigureAsContainerDB=false
oracle.install.db.config.PDBName=
oracle.install.db.config.starterdb.characterSet=
oracle.install.db.config.starterdb.memoryOption=false
oracle.install.db.config.starterdb.memoryLimit=
oracle.install.db.config.starterdb.installExampleSchemas=false
oracle.install.db.config.starterdb.password.ALL=
oracle.install.db.config.starterdb.password.SYS=
oracle.install.db.config.starterdb.password.SYSTEM=
oracle.install.db.config.starterdb.password.DBSNMP=
oracle.install.db.config.starterdb.password.PDBADMIN=
oracle.install.db.config.starterdb.managementOption=DEFAULT
oracle.install.db.config.starterdb.omsHost=
oracle.install.db.config.starterdb.omsPort=0
oracle.install.db.config.starterdb.emAdminUser=
oracle.install.db.config.starterdb.emAdminPassword=
oracle.install.db.config.starterdb.enableRecovery=false
oracle.install.db.config.starterdb.storageType=
oracle.install.db.config.starterdb.fileSystemStorage.dataLocation=
oracle.install.db.config.starterdb.fileSystemStorage.recoveryLocation=
oracle.install.db.config.asm.diskGroup=
oracle.install.db.config.asm.ASMSNMPPassword=
```

不具合対策のため、以下の環境変数をセットしてからインストールを実行。
（今回はソフトウェアのみのインストールを指定）

:::note info
```-ignorePrereqFailure``` オプションを付与しているのはRHEL8/OL8系の前提条件チェックでパッケージ ```compat-libcap1-1.10``` 確認で失敗するため。その失敗は無視していいとOracleさんが言うので「**前提条件エラーがそれだけなら**」除外していいかと。
:::

```shell-session
$ cd ${ORACLE_HOME}
$ pwd
/u01/app/oracle/product/19.0.0/dbhome_1

$ export CV_ASSUME_DISTID=OL7
$ env | grep CV
CV_ASSUME_DISTID=OL7

$ ./runInstaller -silent -ignorePrereqFailure -responseFile /home/oracle/db.rsp -applyRU /tmp/35320081
```

<details><summary>出力例</summary>

```shell-session:runInstaller 実行例
パッチを適用するホームの準備中...
パッチ/tmp/35320081の適用中...
パッチが正常に適用されました。
ログの格納場所: /tmp/InstallActions2023-10-03_00-54-09AM/installerPatchActions_2023-10-03_00-54-09AM.log
Oracle Database設定ウィザードを起動中...

[WARNING] [INS-32047] 中央インベントリに指定した場所(/u01/app/oraInventory)は空ではありません。
   アクション: インベントリには空の場所を指定することをお薦めします。

 'root'ユーザーのパスワードを入力してください。
[WARNING] [INS-13014] ターゲット環境は、いくつかのオプションの要件を満たしていません。
   原因: 一部のオプションの前提条件が満たされていません。詳細はログを参照してください。installActions2023-10-03_00-54-09AM.log
   アクション: ログから失敗した前提条件チェックのリストを確認します: installActions2023-10-03_00-54-09AM.log。次に、ログ・ファイルまたはインストレーション・マニュアルのいずれかから、前提条件を満たす適切な構成を見つけ、手動で 修正してください。
このセッションのレスポンス・ファイルは次の場所にあります:
 /u01/app/oracle/product/19.0.0/dbhome_1/install/response/db_2023-10-03_00-54-09AM.rsp

このインストール・セッションのログは次の場所にあります:
 /tmp/InstallActions2023-10-03_00-54-09AM/installActions2023-10-03_00-54-09AM.log
Successfully Setup Software with warning(s).
インストール・セッション・ログの移動先:
 /u01/app/oraInventory/logs/InstallActions2023-10-03_00-54-09AM
```

:::note warn
[WARNING] [INS-32047] 中央インベントリに指定した場所(/u01/app/oraInventory)は空ではありません。
⇒ OPatch適用するとログが出るため。無視していい。
:::
:::note warn
[WARNING] [INS-13014] ターゲット環境は、いくつかのオプションの要件を満たしていません。
⇒ compat-libcap1-1.10 の話なので無視していい。
:::

</details>

確認
```shell-session
$ OPatch/opatch lspatches
35320081;Database Release Update : 19.20.0.0.230718 (35320081)
29585399;OCW RELEASE UPDATE 19.3.0.0.0 (29585399)

OPatch succeeded.
```


## リスナーの作成
リスナーはデフォルトのままでいいので、ありもののレスポンスファイルを使う。

| 項目 | 詳細 |
|:--|:--|
| 名前 | LISTENER |
| ポート | 1521 |

レスポンスファイルはこちらにあります。
```shell-session
$ cat ./assistants/netca/netca.rsp | grep -v "^#" | grep -v "^$"
```
```vim:${ORACLE_HOME}/assistants/netca/netca.rsp
[GENERAL]
RESPONSEFILE_VERSION="19.0"
CREATE_TYPE="CUSTOM"
[oracle.net.ca]
INSTALLED_COMPONENTS={"server","net8","javavm"}
INSTALL_TYPE=""typical""
LISTENER_NUMBER=1
LISTENER_NAMES={"LISTENER"}
LISTENER_PROTOCOLS={"TCP;1521"}
LISTENER_START=""LISTENER""
NAMING_METHODS={"TNSNAMES","ONAMES","HOSTNAME"}
NSN_NUMBER=1
NSN_NAMES={"EXTPROC_CONNECTION_DATA"}
NSN_SERVICE={"PLSExtProc"}
NSN_PROTOCOLS={"TCP;HOSTNAME;1521"}
```

特に準備もないのでさくっと作成しませう。

```shell-session
$ lsnrctl status LISTENER

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 03-10月-2023 02:25:52

Copyright (c) 1991, 2023, Oracle.  All rights reserved.

(ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))に接続中
TNS-12541: TNS: リスナーがありません。
 TNS-12560: TNS: プロトコル・アダプタ・エラー
  TNS-00511: リスナーがありません。
   Linux Error: 111: Connection refused
```
```shell-session
$ netca -silent -responsefile ${ORACLE_HOME}/assistants/netca/netca.rsp

コマンドライン引数の解析:
    パラメータ "silent" = true
    パラメータ "responsefile" = /u01/app/oracle/product/19.0.0/dbhome_1/assistants/netca/netca.rsp
コマンドライン引数の解析が終了しました。
Oracle Net Servicesの構成:
プロファイルの構成が完了しました。
Oracle Net Listenerの起動:
    リスナーの制御の実行:
      /u01/app/oracle/product/19.0.0/dbhome_1/bin/lsnrctl start LISTENER
    リスナーの制御が完了しました。
    リスナーの起動に成功しました。
リスナーの構成が完了しました。
Oracle Net Servicesの構成に成功しました。終了コードは次のとおりです。0
```
```shell-session
$ lsnrctl status LISTENER

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 03-10月-2023 02:26:06

Copyright (c) 1991, 2023, Oracle.  All rights reserved.

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ol8ora19c.local)(PORT=1521)))に接続中
リスナーのステータス
------------------------
別名                      LISTENER
バージョン                TNSLSNR for Linux: Version 19.0.0.0.0 - Production
開始日                    03-10月-2023 02:26:02
稼働時間                  0 日 0 時間 0 分 4 秒
トレース・レベル          off
セキュリティ              ON: Local OS Authentication
SNMP                      OFF
パラメータ・ファイル      /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/listener.ora
ログ・ファイル            /u01/app/oracle/diag/tnslsnr/ol8ora19c/listener/alert/log.xml
リスニング・エンドポイントのサマリー...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ol8ora19c.local)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
リスナーはサービスをサポートしていません。
コマンドは正常に終了しました。
```

## DBの作成
今回はデータベース生成スクリプトを用意しておりますので、そちらで作成を進めていきたいと思います。
```${ORACLE_BASE}/admin/<DB_UNIQUE_NAME>/script``` ディレクトリを作成し、その配下に諸々配置してください。
※今回は検証用に諸々のコンポーネントは入れず、機能をそぎ落とした版のDBとなっています。
　追加するコンポーネントに応じて .sql が増減します。
　（そのうち、このあたりの動きを細かく検証していきたい気持ち）

```shell-session
$ cd /tmp
$ tar zxf /tmp/script.tgz
$ mkdir -p ${ORACLE_BASE}/admin/cdb/scripts
$ cp -pra /tmp/scripts ${ORACLE_BASE}/admin/cdb/.
$ ls -l ${ORACLE_BASE}/admin/cdb/scripts
合計 48
-rw-r--r-- 1 oracle oinstall  807 10月  3 15:41 CreateClustDBViews.sql
-rw-r--r-- 1 oracle oinstall 1640 10月  3 15:42 CreateDB.sql
-rw-r--r-- 1 oracle oinstall 2368 10月  3 15:42 CreateDBCatalog.sql
-rw-r--r-- 1 oracle oinstall  398 10月  3 15:42 CreateDBFiles.sql
-rw-r--r-- 1 oracle oinstall   90 10月  3 15:43 PDBCreation.sql
-rw-r--r-- 1 oracle oinstall  833 10月  3 15:42 cdb.sh
-rw-r--r-- 1 oracle oinstall  841 10月  3 15:43 cdb.sql
-rw-r--r-- 1 oracle oinstall 2089 10月  3 15:43 init.ora
-rw-r--r-- 1 oracle oinstall 1718 10月  3 15:43 lockAccount.sql
-rw-r--r-- 1 oracle oinstall  793 10月  3 15:43 plug_pdb.sql
-rw-r--r-- 1 oracle oinstall  782 10月  3 15:44 postDBCreation.sql
-rw-r--r-- 1 oracle oinstall 1357 10月  3 15:44 postPDBCreation_pdb.sql
```

シェルスクリプトに権限を付与しておく。
```shell-session
$ cd ${ORACLE_BASE}/admin/cdb/scripts
$ chmod +x cdb.sh
$ ls -l cdb.sh
-rwxr-xr-x 1 oracle oinstall 833 10月  3 15:42 cdb.sh
```

```/etc/oratab``` に追記する内容を確認したうえで追記をする。
```shell-session
$ tail cdb.sh
```
```shell:${ORACLE_BASE}/admin/cdb/scripts/cdb.sh
#!/bin/sh

OLD_UMASK=`umask`
umask 0027
mkdir -p /u01/app/oracle
mkdir -p /u01/app/oracle/admin/cdb/adump
mkdir -p /u01/app/oracle/admin/cdb/dpdump
mkdir -p /u01/app/oracle/admin/cdb/pfile
mkdir -p /u01/app/oracle/audit
mkdir -p /u01/app/oracle/cfgtoollogs/dbca/cdb
mkdir -p /u01/app/oracle/oradata/cdb
mkdir -p /u01/app/oracle/oradata/cdb/pdb
mkdir -p /u01/app/oracle/oradata/cdb/pdbseed
mkdir -p /u01/app/oracle/product/19.0.0/dbhome_1/dbs
umask ${OLD_UMASK}
PERL5LIB=$ORACLE_HOME/rdbms/admin:$PERL5LIB; export PERL5LIB
ORACLE_SID=cdb; export ORACLE_SID
PATH=$ORACLE_HOME/bin:$ORACLE_HOME/perl/bin:$PATH; export PATH
echo /etc/oratab: cdb:/u01/app/oracle/product/19.0.0/dbhome_1:Yにこのエントリを追加してください
/u01/app/oracle/product/19.0.0/dbhome_1/bin/sqlplus /nolog @/u01/app/oracle/admin/cdb/scripts/cdb.sql 
```

下から三行目あたりに ```echo /etc/oratab ~``` という記述があるのでそれを追記しておく。

```shell-session
$ echo "cdb:/u01/app/oracle/product/19.0.0/dbhome_1:Y" >> /etc/oratab
$ tail /etc/oratab
```
```shell:/etc/oratab
#
# The first and second fields are the system identifier and home
# directory of the database respectively.  The third field indicates
# to the dbstart utility that the database should , "Y", or should not,
# "N", be brought up at system boot time.
#
# Multiple entries with the same $ORACLE_SID are not allowed.
#
#
cdb:/u01/app/oracle/product/19.0.0/dbhome_1:Y
```

SYS, SYSTEM, PDBADMIN のパスワード入力を求められるので、事前に準備しておいて
いざDB作成スクリプトを実行。

```shell-session
$ ./cdb.sh
/etc/oratab: cdb:/u01/app/oracle/product/19.0.0/dbhome_1:Yにこのエントリを追加してください

SQL*Plus: Release 19.0.0.0.0 - Production on 火 10月 3 16:10:12 2023
Version 19.20.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.

Enter new password for SYS:
Enter new password for SYSTEM:
Enter new password for PDBADMIN:

Enter password for SYS:

アイドル・インスタンスに接続しました。
SQL> spool /u01/app/oracle/admin/cdb/scripts/CreateDB.log append
SQL> startup nomount pfile="/u01/app/oracle/admin/cdb/scripts/init.ora";
ORACLEインスタンスが起動しました。
　 ：
（中略）
　 ：
SQL> alter session set container=CDB$ROOT;

セッションが変更されました。

SQL> exit;
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.20.0.0.0との接続が切断されました。
$
```

と、いうことで長いプロンプトが終わったらエラーがないか確認してみてください。

### インストール後の確認あれこれ
プロセス
```shell-session
$ ps -ef | grep pmon
oracle    8853     1  0 16:43 ?        00:00:00 ora_pmon_cdb
```

インスタンス（CDB）に接続して諸々
```shell-session
$ export ORACLE_SID=cdb
$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on 火 10月 3 16:53:15 2023
Version 19.20.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.



Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.20.0.0.0
に接続されました。
```
```sql
SQL> select banner_full from v$version;

BANNER_FULL
----------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.20.0.0.0

SQL> show con_name

CON_NAME
------------------------------
CDB

SQL> select instance_name, status from v$instance;

INSTANCE_NAME    STATUS
---------------- ------------
cdb              OPEN

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDB                            READ WRITE NO
SQL>
SQL> select comp_id, status from dba_registry;

COMP_ID                        STATUS
------------------------------ --------------------------------------------
CATALOG                        VALID
CATPROC                        VALID
RAC                            OPTION OFF
XDB                            VALID
OWM                            VALID

SQL> select tablespace_name, status from dba_tablespaces;

TABLESPACE_NAME                STATUS
------------------------------ ---------
SYSTEM                         ONLINE
SYSAUX                         ONLINE
UNDOTBS1                       ONLINE
TEMP                           ONLINE
USERS                          ONLINE

```

続いてPDBの情報
```sql
SQL> alter session set container = pdb;

セッションが変更されました。

SQL>
SQL> show con_name

CON_NAME
------------------------------
PDB
SQL> alter session set container = pdb;

セッションが変更されました。

SQL> select tablespace_name, status from dba_tablespaces;

TABLESPACE_NAME                STATUS
------------------------------ ---------
SYSTEM                         ONLINE
SYSAUX                         ONLINE
UNDOTBS1                       ONLINE
TEMP                           ONLINE
USERS                          ONLINE

SQL> exit;
```

という感じでインストール完了です。無事にRUも適用されている様子。
リスナーあたりも確認してみよう
```shell-session
$ lsnrctl status

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 03-10月-2023 17:11:55

Copyright (c) 1991, 2023, Oracle.  All rights reserved.

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ol8ora19c.local)(PORT=1521)))に接続中
TNS-12541: TNS: リスナーがありません。
 TNS-12560: TNS: プロトコル・アダプタ・エラー
  TNS-00511: リスナーがありません。
   Linux Error: 111: Connection refused
(DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))に接続中
TNS-12541: TNS: リスナーがありません。
 TNS-12560: TNS: プロトコル・アダプタ・エラー
  TNS-00511: リスナーがありません。
   Linux Error: 111: Connection refused
```

...あれ、起動してなかった。ので、起動します。

```shell-session
$ lsnrctl start
　 ：
（中略）
　 ：
リスナーはサービスをサポートしていません。
コマンドは正常に終了しました。
```

当然ながら、起動したてだとリスナーが認識してないので強制的に登録してしまいます。
時間経過でも登録されるのでコーヒータイムでもいいかもです。

```shell-session
$ sqlplus / as sysdba
SQL> alter system register;

システムが変更されました。

SQL> exit
$ lsnrctl status
　 ：
（中略）
　 ：
サービスのサマリー...
サービス"06cb96ed80151311e065322c6b579ae4.local"には、1件のインスタンスがあります。
  インスタンス"cdb"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"06cc0df247892328e065322c6b579ae4.local"には、1件のインスタンスがあります。
  インスタンス"cdb"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"cdb.local"には、1件のインスタンスがあります。
  インスタンス"cdb"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"cdbXDB.local"には、1件のインスタンスがあります。
  インスタンス"cdb"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"pdb.local"には、1件のインスタンスがあります。
  インスタンス"cdb"、状態READYには、このサービスに対する1件のハンドラがあります...
コマンドは正常に終了しました。
```

ということで、今度こそ終了！

# あとがき
今回はシングル構成で比較的簡単な構築でしたが、何事も基本が大事なので1本目の記事にしてみました。
一応、インストール前後でスナップショットは作成しておいたので、これからこのDBを使って遊んでいければなと思います。