shioyakitaroのブログ

主にオラクルDBやLinuxについて調べたことを書いてます。

オラクル:マルチバイトの最大文字数を確認する際に発見したRPAD関数の挙動

久しぶりの更新。

実はこの春から以下のページにて技術ブログを書き始めた。

dakensuk.github.io


興味のある方は読んでいただければ幸いである。

さて、今回は題名の件について。

dakensuk.github.io


要点はざっくり以下の通り。

  • MAX_STRING_SIZEをEXTENDEDに変更すると4000バイト制限だった文字列データ型が32767バイトに拡張される
  • RPAD関数を用いてひらがなを5000文字埋めようとしたら実際には2500文字しか入らなかった。二倍の10000文字にしたら5000文字入った。
  • varchar2( 32767 CHAR )にすると、ひらがなの最大文字数は半分の16384であることが分かった。
  • なお、varchar2( 32767 CHAR )の際、RPAD関数で二倍の65534、またそれ以上を指定してもエラーは返らず、16384文字格納されることが分かった。


ではでは。

PDBではデフォルトのDATA_PUMP_DIRは使用できません

オラクルDBのマルチテナント環境ではまったので備忘録として記しておく。

Oracle RAC環境からデータポンプでエクスポートしたデータを、マルチテナント環境のPDBにデータポンプでインポートしようとした際にエラーが発生。

ディレクトリオブジェクトにDATA_PUMP_DIRが存在しているのにも関わらず

そこにダンプファイルを置いて、ディレクトリオブジェクトにDATA_PUMP_DIRを指定してもディレクトリオブジェクト関連のエラーでインポートができない。

ディレクトリオブジェクトへの書き込み、読み込み権限を付与してもエラーは変わらず。

調べたところ、公式ドキュメントを見ると次の一文が

デフォルトのデータ・ポンプ・ディレクトリ・オブジェクトのDATA_PUMP_DIRは、PDBでは使用できません。エクスポートまたはインポートするPDB内に明示的なディレクトリ・オブジェクトを定義する必要があります。

Oracle Data Pumpの概要

にしてもエラー内容が分かりにくい。使えないなら上記のメッセージを表示してほしいものである。

小技:tnsnames.oraにおけるネットサービス名の一覧確認コマンド

どうも。

今回はoracleのネットサービス名の一覧確認コマンドを書いておきます。

エントリ数が多い場合に便利です。ってこんなのいちいち検索しなくてもコマンド書いてると思いますが

ちょっと何かしらアウトプットしたくなったので書いておきます。

oracle$ cd $ORACLE_HOME/network/admin
oracle$ cat tnsnames.ora | grep -v "^ " | grep -v "^$" | grep -v "^#" | sed -e "s/=//" | sort

以上。

備忘録:Oracle RACのリスナー周りの関係と値指定のメリット

さてさて、今回はOracle RACのリスナー周りの関係について理解したことを備忘録として書く。

環境
OS : Oracle Linux Server release 6.9
DB : Oracle RAC
リスナー:SCANリスナー、アプリケーション用にデフォルトリスナー同様net1に別にリスナーを立てているケース

事前知識

Oracle RACにおいては、
値を設定していなくてもリスナーの情報が下記パラメータに自動的に登録される。

パラメータ名:登録される情報
local_listener : net1のリスナーの情報(デフォルトリスナーなど)
remote_listener : SCANのホスト名:ポート番号
listener_networks : net2のリスナーの情報

DB起動時にはこれらのリスナーに動的にサービスが登録される。
良しなにやってくれるし、これらのパラメータには値を設定しない方が良いのだろうか。

値未指定で良い?

値は指定した方が良いというのが持論。今のところ理由は二つ。

理由1:自動登録の失敗の可能性

リスナー数が多くなっていった際にALTER SYSTEM SET文で指定可能な文字数(255文字)を超えるとOracle Clusterwareによる自動登録が失敗する。

理由2:リスナーで受け付けるサービスが汚くなる

複数DBを同一サーバー群で構成すると、それらすべてのリスナーの情報が登録されてしまう。

たとえばDB1とDB2を同一サーバー群で運用する場合、かつリスナーを分ける場合、
net1に属するリスナーがそれぞれ存在するとき、両方の値がlocal_listenerに登録され、
同様にnet2に属するリスナーがそれぞれ存在するとき、両方の値がlistener_networksに登録される。

結果として、それぞれのリスナーに、すべてのDBのサービスが登録されてしまう。これは気持ち悪い。

最後に

運用上、ネットワーク的にもアプリケーション用、管理用にNICを分ける場合が多いと思うので
リスナーもそれぞれ存在するケースが想定される。上記の持論が助けになれば幸いである。
なおこれらのパラメータ、何も設定しなければDB起動時のアラートログを見れば分かる通り
システム側でalter system XX SCOPE=MEMORY文を発行して値を登録しているのだが
上記パラメータのどれかがspfile等に値が設定されているとシステム側では自動で設定しなくなる。
僕はlocal_listener,listener_networksに値を指定し、DB再起動をした際にremote_listenerに値を指定しなかったために
SCAN経由でのDB接続ができないという事態になった。個人的にはこれを気をつけたい。

最後の最後に

いくつか知識不足で理解がおかしい場合はご指摘いただきたい。優しければなおよし。

ifup後に静的ルーティングの設定が反映されない原因調査

久しぶりの更新。今回はifup時の静的ルーティング設定について書く。

背景

/etc/sysconfig/static-routesファイルに静的ルーティングの記述があっても
ifdown / ifupをすると静的ルーティングの設定が反映されない

環境:Oracle Linux Server release 6.9

原因

static-routesファイルの設定を反映させるには
ifup後にnetwork restartを実施する or OS再起動が必要だった。
つまりifupの際にstatic-routesファイルは読み込まれない。


なお、Oracle Linuxのドキュメントではroutes-デバイス名ファイルに記載するよう書かれていた。
https://docs.oracle.com/cd/E37670_01/E41138/html/ch11s07.html


To permanently configure static routes, you can configure them by creating a route-interface file in/etc/sysconfig/network-scripts for the interface.



このroutes-デバイス名ファイルに記載するとifup後に設定が反映される。

なお、network restartでstatic-routesファイルが反映されるのはnetworkコマンドの中身を見れば一目瞭然。

root# cat network | grep static
	# Add non interface-specific static-routes.
	if [ -f /etc/sysconfig/static-routes ]; then
	   grep "^any" /etc/sysconfig/static-routes | while read ignore args ; do
	# Add non interface-specific static arp entries.
root#

過去にifup/ifdownとifconfig up / ifconfig downコマンドの挙動の違いに驚いたことがあったが、またしてもifup/ifdownコマンドの挙動について知見を深めることができた。

RMAN小ネタ:nomount時のshow allの結果に注意

今回はRMANを使う際に見つけた小ネタを一つ。

ずばり

nomount状態でRMANコマンドのshow allの結果に注意

である。

背景
制御ファイルの自動バックアップをONにしていたはずなのに
RMANコマンドのshow allの結果でOFFと表示された。

原因
少し考えれば分かるが、DBがnomountの状態であった。
ゆえにshow allで表示されたものはただのデフォルト情報だったのである。


以下、実験結果。

環境:Oracle Multitenant
DB名:TESTDB
RMANリポジトリ:制御ファイル(デフォルト)

まずはDBをnomountで起動。

oracle$ sqlplus / as sysdba

SQL> startup nomount;
ORACLE instance started.

Total System Global Area 1644167168 bytes
Fixed Size		    2925024 bytes
Variable Size		  973082144 bytes
Database Buffers	  654311424 bytes
Redo Buffers		   13848576 bytes
SQL>


この状態でshow allしてみる。

oracle$ rman target /

Recovery Manager: Release 12.1.0.2.0 - Production on Tue Jan 30 17:57:03 2018

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

connected to target database: TESTDB (not mounted)

RMAN> show all;

using target database control file instead of recovery catalog
RMAN configuration parameters for database with db_unique_name TESTDB are:
CONFIGURE RETENTION POLICY TO REDUNDANCY 1; # default
CONFIGURE BACKUP OPTIMIZATION OFF; # default
CONFIGURE DEFAULT DEVICE TYPE TO DISK; # default
CONFIGURE CONTROLFILE AUTOBACKUP OFF; # default    <---------------これ
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F'; # default
CONFIGURE DEVICE TYPE DISK PARALLELISM 1 BACKUP TYPE TO BACKUPSET; # default
CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE MAXSETSIZE TO UNLIMITED; # default
CONFIGURE ENCRYPTION FOR DATABASE OFF; # default
CONFIGURE ENCRYPTION ALGORITHM 'AES128'; # default
CONFIGURE COMPRESSION ALGORITHM 'BASIC' AS OF RELEASE 'DEFAULT' OPTIMIZE FOR LOAD TRUE ; # default
CONFIGURE RMAN OUTPUT TO KEEP FOR 7 DAYS; # default
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE; # default

RMAN>

制御ファイルの自動バックアップがOFFになっている。てか全部defaultかい。

DBをマウントしてみる。

SQL> alter database mount;

Database altered.

再度確認してみる。

RMAN> show all;

RMAN configuration parameters for database with db_unique_name TESTDB are:
CONFIGURE RETENTION POLICY TO REDUNDANCY 2;
CONFIGURE BACKUP OPTIMIZATION OFF; # default
CONFIGURE DEFAULT DEVICE TYPE TO DISK; # default
CONFIGURE CONTROLFILE AUTOBACKUP ON;          <---------------これ
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F'; # default
CONFIGURE DEVICE TYPE DISK PARALLELISM 1 BACKUP TYPE TO BACKUPSET; # default
CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE MAXSETSIZE TO UNLIMITED; # default
CONFIGURE ENCRYPTION FOR DATABASE OFF; # default
CONFIGURE ENCRYPTION ALGORITHM 'AES128'; # default
CONFIGURE COMPRESSION ALGORITHM 'BASIC' AS OF RELEASE 'DEFAULT' OPTIMIZE FOR LOAD TRUE ; # default
CONFIGURE RMAN OUTPUT TO KEEP FOR 7 DAYS; # default
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE; # default
...

制御ファイルの自動バックアップがONになっている。


最後に
nomount状態でRMANからリストア等々実施することはあると思うのでshow allには注意すべし。

素朴な調査:オラクルに接続した際のプロセスについて

今回はオラクルのセッションのプロセスについて見てみる。ずばり、ローカル接続とリスナー経由接続の違いについて。

環境:2 node RAC

1. ローカル接続の場合

DBに対しローカル接続をする。

[oracle@node1 ~]$ sqlplus scott/tiger

SQL*Plus: Release 12.1.0.2.0 Production on 火 11月 21 18:42:14 2017

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

最終正常ログイン時間: 火 11月 21 2017 18:41:35 +09:00


Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
に接続されました。

SQL>


OS上のプロセスは以下で検索できる。

ps -ef | grep oracle$ORACLE_SID

まずは該当のプロセスを探す。

[oracle@node1 ~]$ ps -ef | grep oracleorcl_1
oracle   10375     1  0 18:32 ?        00:00:01 oracleorcl_1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   10385     1  0 18:32 ?        00:00:00 oracleorcl_1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   14892 14891  0 18:43 ?        00:00:00 oracleorcl_1(DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq))) <-- これ
oracle   15314 14473  0 18:47 pts/2    00:00:00 grep oracleorcl_1

続いてプロセスの親をたどっていく。

[oracle@node1 ~]$ ps -ef | grep 14891
oracle   14891 14240  0 18:43 pts/1    00:00:00 sqlplus
oracle   14892 14891  0 18:43 ?        00:00:00 oracleorcl_1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   15366 14473  0 18:48 pts/2    00:00:00 grep 14891

[oracle@node1 ~]$ ps -ef | grep 14240
oracle   14240 14226  0 18:39 pts/1    00:00:00 -bash
oracle   14891 14240  0 18:43 pts/1    00:00:00 sqlplus
oracle   14917 14473  0 18:43 pts/2    00:00:00 grep 14240

[oracle@node1 ~]$ ps -ef | grep 14226
oracle   14226 14174  0 18:39 ?        00:00:00 sshd: oracle@pts/1
oracle   14240 14226  0 18:39 pts/1    00:00:00 -bash
oracle   14934 14473  0 18:43 pts/2    00:00:00 grep 14226

[oracle@node1 ~]$ ps -ef | grep 14174
root     14174  2558  0 18:39 ?        00:00:00 sshd: oracle [priv]
oracle   14226 14174  0 18:39 ?        00:00:00 sshd: oracle@pts/1
oracle   14992 14473  0 18:44 pts/2    00:00:00 grep 14174
[oracle@node1 ~]$ ps -ef | grep 2558
root      2558     1  0 18:22 ?        00:00:00 /usr/sbin/sshd
root     14174  2558  0 18:39 ?        00:00:00 sshd: oracle [priv]
root     14411  2558  0 18:39 ?        00:00:00 sshd: root@pts/2
oracle   15017 14473  0 18:44 pts/2    00:00:00 grep 2558


これを見る通り、ローカルの場合、sqlplusからプロセスがforkされていることが分かる。
プロセスがsqlplusだけだったのが意外。


ちなみにPROTOCOL=beqとはなんぞやと思い調べてみると

https://docs.oracle.com/cd/E49329_01/network.121/b71288/concepts.htm#sthref128

クライアントとデータベースが同じコンピュータ上に存在する場合、クライアント接続は、リスナーを経由せずに専用サーバー・プロセスに直接渡すことができます。これは、bequeathプロトコルとして知られています。セッションを開始するアプリケーションは、接続要求に対する専用サーバー・プロセスを生成します。データベースの起動に使用されるアプリケーションがデータベースと同じコンピュータ上にある場合、この処理は自動的に実行されます。

とのこと。ローカル接続を意味しているってことかな。

2. リスナー経由の接続の場合

[oracle@node1 ~]$ sqlplus scott/tiger@node1-vip.oracle12c.jp:1522/orcl

SQL*Plus: Release 12.1.0.2.0 Production on 火 11月 21 18:54:35 2017

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

最終正常ログイン時間: 火 11月 21 2017 18:54:12 +09:00


Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
に接続されました。
SQL>
[oracle@node1 ~]$ ps -ef | grep oracleorcl
oracle   10375     1  0 18:32 ?        00:00:01 oracleorcl_1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   10385     1  0 18:32 ?        00:00:00 oracleorcl_1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   15859     1  0 18:54 ?        00:00:00 oracleorcl_1 (LOCAL=NO) <-- これ
oracle   15904 15526  0 18:55 pts/1    00:00:00 grep oracleorcl

親プロセスが1なのでこれより先に親はいない。

ちなみにリスナーのプロセスも確認したが他に親子関係を持つプロセスもないことがわかる。

[oracle@node1 ~]$ ps -ef | grep tns
root        23     2  0 18:20 ?        00:00:00 [netns]
grid      4787     1  0 18:25 ?        00:00:00 /u01/app/12.1.0/grid/bin/tnslsnr ASMNET1LSNR_ASM -no_crs_notify -inherit
grid      4789     1  0 18:25 ?        00:00:00 /u01/app/12.1.0/grid/bin/tnslsnr ASMNET2LSNR_ASM -no_crs_notify -inherit
grid      4791     1  0 18:25 ?        00:00:00 /u01/app/12.1.0/grid/bin/tnslsnr MGMTLSNR -no_crs_notify -inherit
grid      4846     1  0 18:25 ?        00:00:00 /u01/app/12.1.0/grid/bin/tnslsnr LISTENER -no_crs_notify -inherit
grid      4870     1  0 18:25 ?        00:00:00 /u01/app/12.1.0/grid/bin/tnslsnr LISTENER_SCAN2 -no_crs_notify -inherit
grid      4884     1  0 18:25 ?        00:00:00 /u01/app/12.1.0/grid/bin/tnslsnr LISTENER_SCAN3 -no_crs_notify -inherit
oracle   15825     1  0 18:54 ?        00:00:00 /u01/app/oracle/product/12.1.0/homeDB/bin/tnslsnr LISTENER_TEST -inherit
oracle   16291 15526  0 19:00 pts/1    00:00:00 grep tns
[oracle@node1 ~]$ ps -ef | grep 15825
oracle   15825     1  0 18:54 ?        00:00:00 /u01/app/oracle/product/12.1.0/homeDB/bin/tnslsnr LISTENER_TEST -inherit
oracle   16344 15526  0 19:00 pts/1    00:00:00 grep 15825
[oracle@node1 ~]$

まとめ

ローカル接続とリスナー経由接続でのプロセスの違いについて調査した。
ローカル接続、リスナー経由の接続ともに独立してプロセスが立てられる。って当たり前か。
ローカル接続の場合のprotocolはbeqになり、リスナー経由の場合はLOCAL=NOという情報のみになる。