はてなブログの横幅を調整する。(デザインCSSのカスタマイズ)
テーマは「bordeaux」を使用。
デザイン ⇒ (スパナのアイコン) ⇒ デザインCSS と辿って、元の設定を残しつつ下記を貼り付ける。
/* 全体の横幅 */ #content { width: 1000px; } /* 記事の横幅 */ #main { width: 800px; }
参考:はてなブログ 横幅などカスタマイズ
http://kachua.hatenablog.com/entry/2018/02/03/210645
SQLNET.COMPRESSIONによる圧縮がDBMS_FILE_TRANSFERパッケージのファイル転送(コピー)に効くかを確かめる。(Oracle Database)
SQLNET.COMPRESSIONは12cR1の新機能で、
Oracle Net Servicesによる通信を圧縮する効果が期待されるパラメータです。
Oracle Database Net Servicesリファレンス 12cリリース1 (12.1) B71289-04 SQLNET.COMPRESSION https://docs.oracle.com/cd/E57425_01/121/NETRF/sqlnet.htm#CIHJIBBI データ圧縮を有効または無効にします。サーバー、クライアントの両方とも このパラメータをONに設定している場合、接続に圧縮が使用されます。
※2018/7/30追記:このパラメータは Advanced Compressionのオプション機能となります。
Oracle Databaseライセンス情報ユーザー・マニュアル 12cリリース1 (12.1) Oracle Advanced Compression https://docs.oracle.com/cd/E57425_01/121/DBLIC/options.htm#CJACCDBA 高度なネットワーク圧縮 An Oracle White Paper Advanced Network Compression http://www.oracle.com/technetwork/database/enterprise-edition/advancednetworkcompression-2141325.pdf
今回はDBMS_FILE_TRANSFERパッケージによるファイル転送(コピー)の通信が、
SQLNET.COMPRESSIONで圧縮されるかどうかを確認してみるやで彡(゚)(゚)
接続トポロジは以下の通り。
12cR1(データファイルのコピー元) ⇒ DBLINK ⇒ 12cR2(コピー先、DBMS_FILE_TRANSFERを実行)
下記のファイル(users.273.877103105, 約1GB)をコピーして検証してみます。
-- 12cR1 COLUMN FILE_NAME FORMAT A80 SELECT FILE_NAME, BYTES FROM DBA_DATA_FILES; FILE_NAME BYTES -------------------------------------------------------------------------------- ---------- +DATA/ORCL/13BEADB8DEA01985E0536538A8C0D6E9/DATAFILE/system.270.877103077 272629760 +DATA/ORCL/13BEADB8DEA01985E0536538A8C0D6E9/DATAFILE/sysaux.271.877103077 608174080 +DATA/ORCL/13BEADB8DEA01985E0536538A8C0D6E9/DATAFILE/users.273.877103105 1073741824 ★コピー対象(約1GB)^^^^^^^^^^^^^^^^^^^
1. ファイルコピー前のifconfig ethx TX/RX bytes値(SQLNET.COMPRESSION未設定)
ファイルコピー前の Network Interface の RX/TX bytes値を確認します。
TX ⇒ 送信、RX ⇒ 受信となります。
# 12cR1側(コピー元) $ ifconfig eth0 eth0 Link encap:Ethernet HWaddr 08:00:27:D0:22:C8 inet addr:192.168.56.101 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fed0:22c8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:23613 errors:0 dropped:0 overruns:0 frame:0 TX packets:747935 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1573399 (1.5 MiB) TX bytes:2112323918 (1.9 GiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
# 12cR2側(コピー先) $ ifconfig eth2 ifconfig eth2 eth2 Link encap:Ethernet HWaddr 08:00:27:44:DA:94 inet addr:192.168.56.201 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fe44:da94/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:747657 errors:0 dropped:0 overruns:0 frame:0 TX packets:23654 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1129696230 (1.0 GiB) TX bytes:1576027 (1.5 MiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
2. DBMS_FILE_TRANSFER実行後のifconfig ethx RX/TX bytes値(SQLNET.COMPRESSION未設定)
DBMS_FILE_TRANSFERでファイル転送(コピー)を実行して、
実行後の Network Interface の RX/TX bytes値を確認します。
-- 12cR2側でDBMS_FILE_TRANSFERを実行 CONNECT AYSHIBAT/xxxxxxxx@PDB01 BEGIN DBMS_FILE_TRANSFER.GET_FILE( 'DIR_DATAFILE' -- 12cR1側のディレクトリ・オブジェクト , 'users.273.877103105' -- 12cR1側のデータファイル名 , 'DBL_PDB1_12cR1' -- 12cR1 ⇒ 12cR2 の DBLINK名 , 'DIR_DATAFILE_PDB01' -- 12cR2側のディレクトリ・オブジェクト , 'users.273.877103105' -- 12cR2側のデータファイル名 ); END; / Connected. PL/SQL procedure successfully completed.
# 12cR1側(コピー元) $ ifconfig eth0 eth0 Link encap:Ethernet HWaddr 08:00:27:D0:22:C8 inet addr:192.168.56.101 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fed0:22c8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:45875 errors:0 dropped:0 overruns:0 frame:0 TX packets:1491835 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3043561 (2.9 MiB) TX bytes:4234449971 (3.9 GiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
# 12cR2側(コピー先) $ ifconfig eth2 eth2 Link encap:Ethernet HWaddr 08:00:27:44:DA:94 inet addr:192.168.56.201 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fe44:da94/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1491332 errors:0 dropped:0 overruns:0 frame:0 TX packets:45916 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2253854289 (2.0 GiB) TX bytes:3046189 (2.9 MiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
送受信のバイト数を計算すると、以下の結果になりました。
12cR1側は約1.97GBを送信、12cR2側では約1.05GBを受信してるやね彡(゚)(゚)
# 12cR1側(コピー元) TX bytes数 … 4,234,449,971(コピー後) - 2,112,323,918(コピー前) = 2,122,126,053bytes(約1.97GB) を送信 # 12cR2側(コピー先) RX bytes数 … 2,253,854,289(コピー後) - 1,129,696,230(コピー前) = 1,124,158,059bytes(約1.05GB) を受信
3. sqlnet.ora設定(SQLNET.COMPRESSION=on)
送信側(12cR1)と受信側(12cR2)のsqlnet.oraに、
それぞれSQLNET.COMPRESSION=onを設定します。
設定後に両方のDBを再起動しています。
# 12cR1側(コピー元) cat $ORACLE_HOME/network/admin/sqlnet.ora SQLNET.COMPRESSION=on ★
# 12cR2側(コピー先) cat $ORACLE_HOME/network/admin/sqlnet.ora # sqlnet.ora Network Configuration File: /u01/app/oracle/product/12.2.0/dbhome_1/network/admin/sqlnet.ora # Generated by Oracle configuration tools. NAMES.DIRECTORY_PATH= (TNSNAMES, ONAMES, HOSTNAME) SQLNET.COMPRESSION=on ★ #SQLNET.OUTBOUND_CONNECT_TIMEOUT=5 #SQLNET.INBOUND_CONNECT_TIMEOUT=5
4. ファイルコピー前のifconfig ethx RX/TX bytes値(SQLNET.COMPRESSION=on設定済み)
再度ファイルコピー前の Network Interface の RX/TX bytes値を確認します。
# 12cR1側(コピー元) $ ifconfig eth0 eth0 Link encap:Ethernet HWaddr 08:00:27:D0:22:C8 inet addr:192.168.56.101 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fed0:22c8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:45887 errors:0 dropped:0 overruns:0 frame:0 TX packets:1491865 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3044569 (2.9 MiB) TX bytes:4234451867 (3.9 GiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
# 12cR2側(コピー先) $ ifconfig eth2 eth2 Link encap:Ethernet HWaddr 08:00:27:44:DA:94 inet addr:192.168.56.201 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fe44:da94/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1491362 errors:0 dropped:0 overruns:0 frame:0 TX packets:45928 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2253856185 (2.0 GiB) TX bytes:3047197 (2.9 MiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
5. DBMS_FILE_TRANSFER実行後のifconfig ethx RX/TX bytes値(SQLNET.COMPRESSION=on設定済)
SQLNET.COMPRESSION=onの状態で、DBMS_FILE_TRANSFERで
ファイル転送(コピー)を実行してみます。
実行後の Network Interface の RX/TX bytes値を確認します。
CONNECT AYSHIBAT/xxxxxxxx@PDB01 BEGIN DBMS_FILE_TRANSFER.GET_FILE( 'DIR_DATAFILE' -- 12cR1側のディレクトリ・オブジェクト , 'users.273.877103105' -- 12cR1側のデータファイル名 , 'DBL_PDB1_12cR1' -- 12cR1 ⇒ 12cR2 の DBLINK名 , 'DIR_DATAFILE_PDB01' -- 12cR2側のディレクトリ・オブジェクト , 'users.273.877103105' -- 12cR2側のデータファイル名 ); END; / Connected. PL/SQL procedure successfully completed.
# 12cR1側(コピー元) $ ifconfig eth0 eth0 Link encap:Ethernet HWaddr 08:00:27:D0:22:C8 inet addr:192.168.56.101 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fed0:22c8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:58625 errors:0 dropped:0 overruns:0 frame:0 TX packets:1556074 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3888437 (3.7 MiB) TX bytes:4251723023 (3.9 GiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
# 12cR2側(コピー先) $ ifconfig eth2 eth2 Link encap:Ethernet HWaddr 08:00:27:44:DA:94 inet addr:192.168.56.201 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fe44:da94/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1555359 errors:0 dropped:0 overruns:0 frame:0 TX packets:58624 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2268359561 (2.1 GiB) TX bytes:3888293 (3.7 MiB) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
# 12cR1側(コピー元) TX bytes数 … 4,251,723,023(コピー後) - 4,234,451,867(コピー前) = 17,271,156bytes(約0.016GB) を送信 # 12cR2側(コピー先) RX bytes数 … 2,268,359,561(コピー後) - 2,253,856,185(コピー前) = 14,503,376bytes(約0.014GB) を受信
12cR1側は約0.016GBを送信、12cR2側では約0.014GBを受信しています彡(゚)(゚)
sqlnet.ora(SQLNET.COMPRESSION=on)設定前と比較して、
少なくなってますやね彡(^)(^)
#圧縮率は格納データの特性に依存する想定なので、実測してみて下さい。
まとめ
SQLNET.COMPRESSION=onによる圧縮は、DBMS_FILE_TRANSFERパッケージによる
ファイル転送(コピー)に効果が有ることが解りました。
下記の記事に書いた TTS(トランスポータブル表領域) で、ネットワーク帯域が
ボトルネックになるケースでは試してみる価値が有りそうですやね彡(^)(^)
#送信元が12cR1(12.1)以降の必要が有りますけど(゚ε゚ )
Oracle Database 11gR2(11.2.0.4)から12cR2(12.2.0.1)のPDBにTTS(トランスポータブル表領域)をしてみる。 http://d.hatena.ne.jp/gonsuke777/20180626/1530009840
ちなこの機能(SQLNET.COMPRESSION=on)は PDB の Clone や Relocate に
効果は有るんですかね?どちらも裏でデータファイルのコピーが
走っているはずなんで、隙を見て検証してみますやで彡(゚)(゚)
DBMS_FILE_TRANSFERパッケージでDB(11gR2) -> DBLINK -> PDB(12cR2)のデータファイルの転送(コピー)を実行する。(Oracle Database)
DBMS_FILE_TRANSFERパッケージで中間ファイルを介さずに、
DB(11gR2) to PDB(12cR2) の直接のファイル転送(コピー)を
実行してみますやで彡(゚)(゚)
Oracle Database PL/SQL Packages and Types Reference 12c Release 2 (12.2) 67 DBMS_FILE_TRANSFER https://docs.oracle.com/en/database/oracle/oracle-database/12.2/arpls/DBMS_FILE_TRANSFER.html#GUID-9E206058-78CB-4028-8883-7C28B845F86C
今回試すのは以下のような接続トポロジです。
11gR2(データファイルのコピー元) ⇒ DBLINK ⇒ 12cR2(コピー先、DBMS_FILE_TRANSFERを実行)
1. データファイルのコピー元にディレクトリ・オブジェクトを作成
データファイルのパスを参照可能なディレクトリ・オブジェクトを作成して、
READ権限を付与します。下記例では専用ユーザーを作成していますが、必須ではありません。
-- 11gR2(ユーザー作成) CREATE USER FILETRANS IDENTIFIED BY xxxxxxxx DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP; GRANT CREATE SESSION TO FILETRANS; -- 11gR2(ディレクトリ・オブジェクト作成) CREATE DIRECTORY DIR_DATAFILE as '+DATA/ORCL/DATAFILE'; GRANT READ ON DIRECTORY DIR_DATAFILE TO FILETRANS; User created. Grant succeeded. Directory created. Grant succeeded.
2. データファイルのコピー先(PDB)にディレクトリ・オブジェクトを作成
データファイルのコピー先(PDB)のパスにアクセス可能なディレクトリ・オブジェクトを
PDB上に作成して、DBMS_FILE_TRANSFERパッケージを実行するユーザーに
ディレクトリ・オブジェクトのWRITE権限を付与します。
-- 12cR2 CONNECT /AS SYSDBA ALTER SESSION SET CONTAINER = PDB01; SHOW CON_NAME; CREATE DIRECTORY DIR_DATAFILE_PDB01 as '/u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile/'; GRANT WRITE ON DIRECTORY DIR_DATAFILE_PDB01 TO AYSHIBAT; Connected. Session altered. CON_NAME ------------------------------ PDB01 Directory created. Grant succeeded.
3. データファイルのコピー先(PDB)に、コピー元へ接続するDBLINKを作成
データファイルのコピー先(PDB)に、コピー元(今回は11gR2)へ接続する
DBLINK(DATABASE LINK)を作成します。コピー元の接続ユーザーは、
コピーするデータファイルのディレクトリ・オブジェクトのREAD権限が必要です。
-- 12cR2 CONNECT AYSHIBAT/xxxxxxxx@PDB01 SHOW CON_NAME; CREATE DATABASE LINK DBL_ORCL_11GR2 CONNECT TO FILETRANS IDENTIFIED BY xxxxxxxx USING 'ORCL_11GR2'; -- DBLINKの動作確認 SET LINESIZE 170; SELECT * FROM V$VERSION@DBL_ORCL_11GR2; SELECT * FROM V$VERSION; Connected. CON_NAME ------------------------------ PDB01 Database link created. BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production PL/SQL Release 11.2.0.4.0 - Production CORE 11.2.0.4.0 Production TNS for Linux: Version 11.2.0.4.0 - Production NLSRTL Version 11.2.0.4.0 - Production BANNER CON_ID -------------------------------------------------------------------------------- ---------- Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0 PL/SQL Release 12.2.0.1.0 - Production 0 CORE 12.2.0.1.0 Production 0 TNS for Linux: Version 12.2.0.1.0 - Production 0 NLSRTL Version 12.2.0.1.0 - Production 0
4. DBMS_FILE_TRANSFERパッケージのGET_FILEプロシージャを実行して、データファイルをコピー
コピー先(今回は12cR2側)でDBMS_FILE_TRANSFERパッケージの
GET_FILEプロシージャを実行して、データファイルをコピーします。
-- 12cR2 BEGIN DBMS_FILE_TRANSFER.GET_FILE( 'DIR_DATAFILE' -- 11gR2側のディレクトリ・オブジェクト , 'tbs_tts1.266.979841605' -- 11gR2側のデータファイル名 , 'DBL_ORCL_11GR2' -- 12cR2 ⇒ 11gR2 の DBLINK名 , 'DIR_DATAFILE_PDB01' -- 12cR2側のディレクトリ・オブジェクト , 'tbs_tts1.266.979841605' -- 12cR2側のデータファイル名 ); END; / BEGIN DBMS_FILE_TRANSFER.GET_FILE( 'DIR_DATAFILE' -- 11gR2側のディレクトリ・オブジェクト , 'tbs_tts2.267.979841605' -- 11gR2側のデータファイル名 , 'DBL_ORCL_11GR2' -- 12cR2 ⇒ 11gR2 の DBLINK名 , 'DIR_DATAFILE_PDB01' -- 12cR2側のディレクトリ・オブジェクト , 'tbs_tts2.267.979841605' -- 12cR2側のデータファイル名 ); END; /
# DBMS_FILE_TRANSFER実行前 $ pwd /u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile $ ls -la total 1133172 drwxr-x---. 2 oracle oinstall 4096 Jun 27 14:26 . drwxr-x---. 3 oracle oinstall 4096 May 16 12:19 .. -rw-r-----. 1 oracle oinstall 398467072 Jun 27 14:25 o1_mf_sysaux_fhq8s86l_.dbf -rw-r-----. 1 oracle oinstall 272637952 Jun 27 14:37 o1_mf_system_fhq8s865_.dbf -rw-r-----. 1 oracle oinstall 135274496 Jun 26 19:11 o1_mf_temp_fhq8s86n_.dbf -rw-r-----. 1 oracle oinstall 104865792 Jun 27 14:37 o1_mf_undotbs1_fhq8s86m_.dbf -rw-r-----. 1 oracle oinstall 259530752 Jun 27 13:47 o1_mf_users_fhq8s86o_.dbf
SQL> BEGIN 2 DBMS_FILE_TRANSFER.GET_FILE( 3 'DIR_DATAFILE' -- 11gR2側のディレクトリ・オブジェクト 4 , 'tbs_tts1.266.979841605' -- 11gR2側のデータファイル名 5 , 'DBL_ORCL_11GR2' -- 12cR2 ⇒ 11gR2 の DBLINK名 6 , 'DIR_DATAFILE_PDB01' -- 12cR2側のディレクトリ・オブジェクト 7 , 'tbs_tts1.266.979841605' -- 12cR2側のデータファイル名 8 ); 9 END; 10 / PL/SQL procedure successfully completed. SQL> BEGIN 2 DBMS_FILE_TRANSFER.GET_FILE( 3 'DIR_DATAFILE' -- 11gR2側のディレクトリ・オブジェクト 4 , 'tbs_tts2.267.979841605' -- 11gR2側のデータファイル名 5 , 'DBL_ORCL_11GR2' -- 12cR2 ⇒ 11gR2 の DBLINK名 6 , 'DIR_DATAFILE_PDB01' -- 12cR2側のディレクトリ・オブジェクト 7 , 'tbs_tts2.267.979841605' -- 12cR2側のデータファイル名 8 ); 9 END; 10 / PL/SQL procedure successfully completed.
# DBMS_FILE_TRANSFER実行後 $ pwd /u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile $ ls -la total 1153668 drwxr-x---. 2 oracle oinstall 4096 Jun 27 14:40 . drwxr-x---. 3 oracle oinstall 4096 May 16 12:19 .. -rw-r-----. 1 oracle oinstall 398467072 Jun 27 14:25 o1_mf_sysaux_fhq8s86l_.dbf -rw-r-----. 1 oracle oinstall 272637952 Jun 27 14:37 o1_mf_system_fhq8s865_.dbf -rw-r-----. 1 oracle oinstall 135274496 Jun 26 19:11 o1_mf_temp_fhq8s86n_.dbf -rw-r-----. 1 oracle oinstall 104865792 Jun 27 14:37 o1_mf_undotbs1_fhq8s86m_.dbf -rw-r-----. 1 oracle oinstall 259530752 Jun 27 13:47 o1_mf_users_fhq8s86o_.dbf -rw-r-----. 1 oracle oinstall 10493952 Jun 27 14:40 tbs_tts1.266.979841605 ★コピーされたデータファイル -rw-r-----. 1 oracle oinstall 10493952 Jun 27 14:40 tbs_tts2.267.979841605 ★コピーされたデータファイル $
見事にデータファイルがコピーされましたやで!彡(^)(^)
5. まとめ
cpやscp等によるファイルシステム(中間ファイル)を介した転送と異なって、
DBMS_FILE_TRANSFERパッケージは DB to DB による直接のファイル転送(コピー)が
実現できるんやで彡(^)(^) #中間ファイルを介さないので理論上は速い。
転送中(転送経路上)の圧縮ができるとより理想的なんやけど、
下記パラメータ(SQLNET.COMPRESSION)を使ったら実現可能なんやろうか……?
彡(゚)(゚)
Oracle Database Net Servicesリファレンス 12cリリース2 (12.2) 5.2.20 SQLNET.COMPRESSION https://docs.oracle.com/cd/E82638_01/netrf/parameters-for-the-sqlnet-ora-file.html#GUID-61CE4FA9-3ABB-4E9B-B788-FB57E6B56F47 データ圧縮を有効または無効にします。サーバー、クライアントの両方ともこのパラメータをONに設定している場合、接続に圧縮が使用されます。
Oracle Database 11gR2(11.2.0.4)から12cR2(12.2.0.1)のPDBにTTS(トランスポータブル表領域)をしてみる。
表題の通り、Oracle Database 11gR2(11.2.0.4)から12cR2(12.2.0.1)の
PDBにTTS(トランスポータブル表領域)を実行してみるやで彡(゚)(゚)
プラットフォームはどちらも Linux x86 64bitで試します。
特別な手順は必要なくマニュアル通りに粛々と実施するだけです。
Oracle Database管理者ガイド 11gリリース2 (11.2) B56301-08 データベース間で表領域をトランスポートする手順および例 https://docs.oracle.com/cd/E16338_01/server.112/b56301/tspaces.htm#i1007252 Oracle Database データベース管理者ガイド 12c リリース2 (12.2) 15.1.2.2 トランスポータブル表領域またはトランスポータブル表の使用例 https://docs.oracle.com/cd/E82638_01/admin/transporting-data.html#GUID-5158E6EB-591A-4DF0-9A44-BAF1E10338A8
0. 移行対象の表/表領域
移行対象は以下の表(TBL_TEST_TTS1,TBL_TEST_TTS2)/表領域(TBS_TTS1,TBS_TTS2)とします。
-- 11gR2 COLUMN OWNER FORMAT A20; COLUMN SEGMENT_NAME FORMAT A20; COLUMN BYTES FORMAT 999,999,999; COLUMN TABLESPACE_NAME FORMAT A20; SELECT OWNER, SEGMENT_NAME, BYTES, TABLESPACE_NAME FROM DBA_SEGMENTS WHERE TABLESPACE_NAME IN ('TBS_TTS1', 'TBS_TTS2'); OWNER SEGMENT_NAME BYTES TABLESPACE_NAME -------------------- -------------------- ------------ -------------------- AYSHIBAT TBL_TEST_TTS1 196,608 TBS_TTS1 AYSHIBAT TBL_TEST_TTS2 196,608 TBS_TTS2
1. 移行元/移行先のエンディアンを確認
まず移行元/移行先のエンディアンを確認します。
今回はどちらも同じエンディアン彡(゚)(゚)
-- 移行元(11gR2)のエンディアン COLUMN PLATFORM_NAME FORMAT A30; COLUMN ENDIAN_FORMAT FORMAT A30; SELECT d.PLATFORM_NAME, ENDIAN_FORMAT FROM V$TRANSPORTABLE_PLATFORM tp, V$DATABASE d WHERE tp.PLATFORM_NAME = d.PLATFORM_NAME; PLATFORM_NAME ENDIAN_FORMAT ------------------------------ ------------------------------ Linux x86 64-bit Little -- 移行先(12cR2)のエンディアン COLUMN PLATFORM_NAME FORMAT A30; COLUMN ENDIAN_FORMAT FORMAT A30; SELECT d.PLATFORM_NAME, ENDIAN_FORMAT FROM V$TRANSPORTABLE_PLATFORM tp, V$DATABASE d WHERE tp.PLATFORM_NAME = d.PLATFORM_NAME; PLATFORM_NAME ENDIAN_FORMAT ------------------------------ ------------------------------ Linux x86 64-bit Little
2. 表領域が自己完結しているかを確認
下記のコマンドで表領域が自己完結しているかを確認します。
TRANSPORT_SET_VIOLATIONSで行が出なければ、自己完結しています。
-- 11gR2 EXECUTE SYS.DBMS_TTS.TRANSPORT_SET_CHECK('TBS_TTS1, TBS_TTS2', TRUE); SELECT * FROM SYS.TRANSPORT_SET_VIOLATIONS; PL/SQL procedure successfully completed. no rows selected
3. 移行対象の表領域を READ ONLY にします。
下記のコマンドで移行対象の表領域を READ ONLY にします。
-- 11gR2 ALTER TABLESPACE TBS_TTS1 READ ONLY; ALTER TABLESPACE TBS_TTS2 READ ONLY; Tablespace altered. Tablespace altered.
4. 表領域の定義情報をエクスポート(expdp)
expdpコマンドで表領域の定義情報をエクスポートします。
定義情報だけのエクスポートなので、時間はそれほど掛かりません。
# 11gR2 expdp AYSHIBAT/xxxxxxxx@orcl dumpfile=tts_users.dmp directory=DIR_AYSHIBAT transport_tablespaces=TBS_TTS1,TBS_TTS2 logfile=exp_tts_users.log Export: Release 11.2.0.4.0 - Production on Tue Jun 26 18:49:44 2018 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options Starting "AYSHIBAT"."SYS_EXPORT_TRANSPORTABLE_01": AYSHIBAT/********@orcl dumpfile=tts_users.dmp directory=DIR_AYSHIBAT transport_tablespaces=TBS_TTS1,TBS_TTS2 logfile=exp_tts_users.log Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK Processing object type TRANSPORTABLE_EXPORT/TABLE Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK Master table "AYSHIBAT"."SYS_EXPORT_TRANSPORTABLE_01" successfully loaded/unloaded ****************************************************************************** Dump file set for AYSHIBAT.SYS_EXPORT_TRANSPORTABLE_01 is: /home/oracle/work/ayshibat/tts_users.dmp ****************************************************************************** Datafiles required for transportable tablespace TBS_TTS1: +DATA/orcl/datafile/tbs_tts1.266.979841605 Datafiles required for transportable tablespace TBS_TTS2: +DATA/orcl/datafile/tbs_tts2.267.979841605 Job "AYSHIBAT"."SYS_EXPORT_TRANSPORTABLE_01" successfully completed at Tue Jun 26 18:50:53 2018 elapsed 0 00:01:06
5. dmpファイルとデータファイルの転送(コピー)
dmpファイルとデータファイルを移行先(12cR2)に転送(コピー)します。
データファイルの転送にはcpコマンド/DBMS_FILE_TRANSFER/RMAN等々の手段が有りますが、
今回は 11gR2のASM ⇒ asmcmdでファイルシステムに出力 ⇒ scpで転送 ⇒ 12cR2のファイルシステム とします。
# 11gR2 asmcmd cd +DATA/ORCL/DATAFILE ls -l Type Redund Striped Time Sys Name DATAFILE MIRROR COARSE JUN 26 18:00:00 Y SYSAUX.257.836897651 DATAFILE MIRROR COARSE JUN 26 18:00:00 Y SYSTEM.256.836897649 DATAFILE MIRROR COARSE JUN 26 18:00:00 Y TBS_TTS1.266.979841605 DATAFILE MIRROR COARSE JUN 26 18:00:00 Y TBS_TTS2.267.979841605 DATAFILE MIRROR COARSE JUN 26 18:00:00 Y UNDOTBS1.258.836897653 DATAFILE MIRROR COARSE JUN 26 18:00:00 Y USERS.259.836897653 cp '+DATA/ORCL/DATAFILE/TBS_TTS1.266.979841605' '/home/grid/work/ayshibat/TBS_TTS1.266.979841605' cp '+DATA/ORCL/DATAFILE/TBS_TTS2.267.979841605' '/home/grid/work/ayshibat/TBS_TTS2.267.979841605' copying +DATA/ORCL/DATAFILE/TBS_TTS1.266.979841605 -> /home/grid/work/ayshibat/TBS_TTS1.266.979841605 copying +DATA/ORCL/DATAFILE/TBS_TTS2.267.979841605 -> /home/grid/work/ayshibat/TBS_TTS2.267.979841605 ↓ 【scpでdmpファイルとデータファイルを転送(コピー)】 ↓ # 12cR2 cd /u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile/ ls -la -rw-r--r--. 1 oracle oinstall 10493952 Jun 26 18:55 TBS_TTS1.266.979841605 ★scpで転送(コピー)したデータファイル -rw-r--r--. 1 oracle oinstall 10493952 Jun 26 18:56 TBS_TTS2.267.979841605 ★scpで転送(コピー)したデータファイル -rw-r-----. 1 oracle oinstall 398467072 Jun 26 18:35 o1_mf_sysaux_fhq8s86l_.dbf -rw-r-----. 1 oracle oinstall 272637952 Jun 26 18:57 o1_mf_system_fhq8s865_.dbf : cd /home/oracle/work/ayshibat ls -la tts_users.dmp -rw-r--r--. 1 oracle oinstall 94208 Jun 26 18:50 tts_users.dmp ★scpで転送(コピー)したdmpファイル
6. PDBに表領域の定義情報をインポート(impdp)
impdpコマンドで表領域の定義情報をインポートします。
やはり定義情報だけのインポートなので、時間はそれほど掛かりません。
# 12cR2 impdp AYSHIBAT/xxxxxxxx@PDB01 dumpfile=tts_users.dmp directory=DIR_AYSHIBAT \ transport_datafiles=\ '/u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile/TBS_TTS1.266.979841605',\ '/u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile/TBS_TTS2.267.979841605' \ logfile=imp_tts_users.log Import: Release 12.2.0.1.0 - Production on Tue Jun 26 19:10:48 2018 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production Master table "AYSHIBAT"."SYS_IMPORT_TRANSPORTABLE_01" successfully loaded/unloaded Starting "AYSHIBAT"."SYS_IMPORT_TRANSPORTABLE_01": AYSHIBAT/********@PDB01 dumpfile=tts_users.dmp directory=DIR_AYSHIBAT transport_datafiles=/u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile/TBS_TTS1.266.979841605,/u01/app/oracle/oradata/AYUCDB/6C4B2D3386C20FB8E055000000000001/datafile/TBS_TTS2.267.979841605 logfile=imp_tts_users.log Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK Processing object type TRANSPORTABLE_EXPORT/TABLE Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK Job "AYSHIBAT"."SYS_IMPORT_TRANSPORTABLE_01" successfully completed at Tue Jun 26 19:11:05 2018 elapsed 0 00:00:13
7. PDBに接続してデータを確認
PDBに接続してデータを確認します。見事にデータが転送されています。
やったぜ彡(^)(^)
-- 12cR2 sqlplus /nolog CONNECT AYSHIBAT/xxxxxxxx@PDB01 SHOW CON_NAME; COLUMN OWNER FORMAT A20; COLUMN SEGMENT_NAME FORMAT A20; COLUMN BYTES FORMAT 999,999,999; COLUMN TABLESPACE_NAME FORMAT A20; SELECT OWNER, SEGMENT_NAME, BYTES, TABLESPACE_NAME FROM DBA_SEGMENTS WHERE TABLESPACE_NAME IN ('TBS_TTS1', 'TBS_TTS2'); SELECT COUNT(*) FROM TBL_TEST_TTS1; SELECT COUNT(*) FROM TBL_TEST_TTS2; SQL*Plus: Release 12.2.0.1.0 Production on Tue Jun 26 19:14:27 2018 Copyright (c) 1982, 2016, Oracle. All rights reserved. Connected. CON_NAME ------------------------------ PDB01 OWNER SEGMENT_NAME BYTES TABLESPACE_NAME -------------------- -------------------- ------------ -------------------- AYSHIBAT TBL_TEST_TTS2 196,608 TBS_TTS2 AYSHIBAT TBL_TEST_TTS1 196,608 TBS_TTS1 COUNT(*) ---------- 10000 COUNT(*) ---------- 10000
8. 表領域の READ ONLY状態を解除
表領域のREAD ONLY状態を解除します。ちな移行元(今回は11gR2)のREAD ONLY解除は、
データファイル書き出しが終わった時点で実施してOKですやで彡(゚)(゚)
-- 11gR2 SELECT TABLESPACE_NAME, STATUS FROM DBA_TABLESPACES WHERE TABLESPACE_NAME IN ('TBS_TTS1', 'TBS_TTS2'); ALTER TABLESPACE TBS_TTS1 READ WRITE; ALTER TABLESPACE TBS_TTS2 READ WRITE; SELECT TABLESPACE_NAME, STATUS FROM DBA_TABLESPACES WHERE TABLESPACE_NAME IN ('TBS_TTS1', 'TBS_TTS2'); TABLESPACE_NAME STATUS ------------------------------ --------- TBS_TTS1 READ ONLY TBS_TTS2 READ ONLY Tablespace altered. Tablespace altered. TABLESPACE_NAME STATUS ------------------------------ --------- TBS_TTS1 ONLINE TBS_TTS2 ONLINE -- 12cR2 SELECT TABLESPACE_NAME, STATUS FROM DBA_TABLESPACES WHERE TABLESPACE_NAME IN ('TBS_TTS1', 'TBS_TTS2'); ALTER TABLESPACE TBS_TTS1 READ WRITE; ALTER TABLESPACE TBS_TTS2 READ WRITE; SELECT TABLESPACE_NAME, STATUS FROM DBA_TABLESPACES WHERE TABLESPACE_NAME IN ('TBS_TTS1', 'TBS_TTS2'); TABLESPACE_NAME STATUS ------------------------------ --------- TBS_TTS1 READ ONLY TBS_TTS2 READ ONLY Tablespace altered. Tablespace altered. TABLESPACE_NAME STATUS ------------------------------ --------- TBS_TTS1 ONLINE TBS_TTS2 ONLINE
9. まとめ
特別な手順は無く、11gR2 ⇒ 12cR2(PDB) の
TTS(トランスポータブル表領域)が実行できました彡(^)(^)
リアルな環境を考慮すると、5. のデータファイル転送(コピー)のところで
最も時間が掛かるのですが、一旦中間ファイルに書き出す今回のやり方よりも、
中間ファイルを介さずに直接転送する方法も有るようなので、
詰める余地が有りますやね彡(゚)(゚)
Hard Parseに時間が掛かるお手軽なSQLを作ってみる。(Oracle Database)
「Hard Parseに時間が掛かる手軽なSQLを作りたい。彡(゚)(゚)」と呟いた
(※下記twitterモーメント参照)ところ、色々とアイデアを頂いたので、
全部ではないのですがお試し&まとめてみましたやで彡(゚)(゚)
Hard Parseに時間が掛かるSQL ※twitterモーメント https://twitter.com/i/moments/1001431132234072064
Case1. IN句リテラルを仕様上限(999個)まで
こちらの結果は下記の通り、ぼちぼち彡(゚)(゚)
SELECT A.ITEM_NAME , COUNT(*) FROM ITEM_TBL A WHERE ITEM_NO IN ( 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, : 975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999) GROUP BY ITEM_NAME call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.08 0.09 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 2 0 10 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.08 0.09 0 2 0 10
Case2. 結合表8個以上
こちらの結果は下記の通り、Case1. よりは増えました彡(゚)(゚)
SELECT A.ITEM_NAME , COUNT(*) FROM ITEM_TBL A , ITEM_TBL B , ITEM_TBL C , ITEM_TBL D , ITEM_TBL E , ITEM_TBL F , ITEM_TBL G , ITEM_TBL H , ITEM_TBL I , ITEM_TBL J WHERE J.REGIST_DATE BETWEEN TO_DATE('2012/08/01', 'YYYY/MM/DD') AND TO_DATE('2012/08/02', 'YYYY/MM/DD') AND A.ITEM_NO = B.ITEM_NO AND B.ITEM_NO = C.ITEM_NO AND C.ITEM_NO = D.ITEM_NO AND D.ITEM_NO = E.ITEM_NO AND E.ITEM_NO = F.ITEM_NO AND F.ITEM_NO = G.ITEM_NO AND G.ITEM_NO = H.ITEM_NO AND H.ITEM_NO = I.ITEM_NO AND I.ITEM_NO = J.ITEM_NO GROUP BY A.ITEM_NAME call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.48 0.48 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 10 0 10 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.48 0.48 0 10 0 10
Case3. 結合表8個以上 + permutation増強
こちらの結果は下記の通り、Case2. より更に増加彡(゚)(゚)
ALTER SESSION SET "_optimizer_max_permutations"=80000; SELECT A.ITEM_NAME , COUNT(*) FROM ITEM_TBL A , ITEM_TBL B , ITEM_TBL C , ITEM_TBL D , ITEM_TBL E , ITEM_TBL F , ITEM_TBL G , ITEM_TBL H , ITEM_TBL I , ITEM_TBL J WHERE J.REGIST_DATE BETWEEN TO_DATE('2012/08/01', 'YYYY/MM/DD') AND TO_DATE('2012/08/02', 'YYYY/MM/DD') AND A.ITEM_NO = B.ITEM_NO AND B.ITEM_NO = C.ITEM_NO AND C.ITEM_NO = D.ITEM_NO AND D.ITEM_NO = E.ITEM_NO AND E.ITEM_NO = F.ITEM_NO AND F.ITEM_NO = G.ITEM_NO AND G.ITEM_NO = H.ITEM_NO AND H.ITEM_NO = I.ITEM_NO AND I.ITEM_NO = J.ITEM_NO GROUP BY A.ITEM_NAME call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.66 0.68 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 10 0 10 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.67 0.69 0 10 0 10
Case4. UNION500行
こちらの結果は下記の通り、エエ感じやで!彡(^)(^)
SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION : SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 1.04 1.05 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.01 0.01 0 500 0 10 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 1.06 1.06 0 500 0 10
Case5. DUAL表を200個結合
Kazumasa Obaraさんネタ。元ネタの500個だと
終わらなかったので200個で計測。ぶっちぎりで草wwwww
SELECT A.* FROM DUAL A, DUAL, : DUAL, DUAL, DUAL, DUAL, DUAL call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 48.86 49.96 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 3 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 48.86 49.96 0 3 0 1
やっぱり結合順序の探索には時間が掛かるんやなぁ……彡(゚)(゚)
アイデアを頂いた皆さん、ありがとうございます!(`・ω・)ゞ
VirtualBoxのLinuxにGraalVMを入れてpythonのスクリプトを動かしてみた。
GraalVM、かなりアツいOSSですね。各所で話題になってます。
オラクル、JavaやJavaScript、Ruby、Pythonなど多言語対応を単一ランタイムで実現する「GraalVM」をオープンソースで公開。Twitterが本番環境で採用 http://www.publickey1.jp/blog/18/javajavascriptrubypythongraalvmtwitter.html
導入も簡単だったので置いときますやね彡(゚)(゚)
GraalVMのダウンロード&インストール
下記のリンク(Getting start) ⇒ Downloads ⇒ Community Edition (CE) で
「graalvm-ce-1.0.0-rc1-linux-amd64.tar.gz」をダウンロード
GraalVM Getting start https://www.graalvm.org/docs/getting-started/ Community Edition (CE) https://www.graalvm.org/downloads/
VirtualBoxのゲストOS(Linux、本記事ではOEL6を使用)の適当なディレクトリに展開する。
今回は「/home/oracle/work」配下に展開。超簡単やね。彡(゚)(゚)
tar xvzf graalvm-ce-1.0.0-rc1-linux-amd64.tar.gz
Graal Pythonコンポーネントのインストール
GraalVMのbinディレクトリにPATHを通す。オプションでJAVA_HOMEもGraalVMの展開ディレクトリにセット。
export PATH=/home/oracle/work/graalvm-1.0.0-rc1/bin:$PATH export JAVA_HOME=/home/oracle/work/graalvm-1.0.0-rc1
マニュアル(https://www.graalvm.org/docs/getting-started/#running-python-3)の通りに guコマンド(Graal updater)でpython componentをインストール
gu -c install org.graalvm.python Downloading: Component catalog Processing component archive: Component org.graalvm.python Downloading: Component org.graalvm.python Installing new component: Graal.python (org.graalvm.python, version 1.0.0-rc1)
Graal Pythonの実行
下記マニュアルを参考にしつつ、まずはコマンドラインから。
GraalVM - Python 3 https://www.graalvm.org/docs/reference-manual/languages/python/#python-3
graalpythonコマンドでコマンドラインを起動。
VMを起動しているせいなのか、print文の初めの1回は遅い彡(゚)(゚)
graalpython Please note: This Python implementation is in the very early stages, and can run little more than basic benchmarks at this point. >>> print ("1+2=", 1 + 2) 1+2= 3 >>> print ("1+2=", 1 + 2) 1+2= 3 :
cat py3test.py # -*- coding: utf-8 -*- print("Hello World!") for i in range(0,6): print(i,"Hello World!") for i in range(0,6): if i%2==0: print(i," is even number.") else: print(i," is odd number.")
スクリプトの実行コマンドは下記、こいつ……動くぞ!彡(゚)(゚)
graalpython --jvm --polyglot py3test.py Please note: This Python implementation is in the very early stages, and can run little more than basic benchmarks at this point. Hello World! 0 Hello World! 1 Hello World! 2 Hello World! 3 Hello World! 4 Hello World! 5 Hello World! 0 is even number. 1 is odd number. 2 is even number. 3 is odd number. 4 is even number. 5 is odd number.
うーん、こいつは凄い。他の言語も動くようだし、polyglotって機能で
言語が混ぜこぜでも同時に動くらしい。試してみないと。。。彡(゚)(゚)
JavaモジュールのNative Image化(※4/25追記)
python実行とは直接関係ないのですが、GraalVMにはNative Image化という
高速化という機能が有り、試してみたのでメモ。
まずワイ環境ではnative-imageコマンドの実行に、
gccとzlib-develのインストールが必要でした彡(゚)(゚)
yum install gcc yum install zlib-devel
以下のjavaをコンパイル&Native Image化彡(゚)(゚)
cat HelloGraalJava.java import org.graalvm.polyglot.*; class HelloGraalJava { public static void main(String[] args) { System.out.println("Hello, Graal Java!"); } } javac HelloGraalJava.java native-image HelloGraalJava Build on Server(pid: 3847, port: 26682) classlist: 909.56 ms (cap): 3,249.39 ms setup: 5,206.04 ms (typeflow): 15,378.97 ms (objects): 6,795.22 ms (features): 152.68 ms analysis: 22,692.12 ms universe: 1,248.48 ms (parse): 6,206.26 ms (inline): 3,647.32 ms (compile): 27,832.51 ms compile: 39,458.58 ms image: 3,222.35 ms write: 646.89 ms [total]: 73,892.84 ms
ALL小文字の「hellograaljava」というバイナリが生成されました。
timeコマンド付けつつ実行してみた。なるほど彡(゚)(゚)
#通常のjava実行 time java HelloGraalJava Hello, Graal Java! real 0m0.187s user 0m0.140s sys 0m0.043s #Native Image実行 time ./hellograaljava Hello, Graal Java! real 0m0.017s user 0m0.003s sys 0m0.011s
native-imageコマンドはpython関連のオプションも有るんですが、
使い方はイマイチ解らず。今後要検証彡(゚)(゚)
native-image --help : Available macro-options are: --language:python :
ALTER SYSTEM KILL SESSION…"だけ"の権限付与を12c新機能のCode Based Access Control+実行者権限プロシージャで実現してみる。(Oracle Database)
前回のエントリ
gonsuke777.hatenablog.com
からの続き。
Qiita の @tlokweng さんから 12c新機能のCode Based Access Control
なるものの存在を教えて頂きますた彡(゚)(゚)
ALTER SYSTEM KILL SESSION…によるユーザーセッションの切断は許可したいけど、
ALTER SYSTEM権限の付与(GRANT)は範囲が広過ぎる、権限が強過ぎる。。。
ALTER SYSTEM KILL SESSIONだけ許可したい……てな要件を、
今回は実行者権限(AUTHID CURRENT_USER)のプロシージャと、
12c新機能のCode Based Access Controlで実現してみるやで彡(゚)(゚)
概要
以下のような構成でDBユーザーとストアド・プロシージャを作成します。
DEFUSER … 権限の強いDBユーザー │ ↓ │ RL_EXE_KILL_SESS … ALTER SYSTEM権限を保持するロール │ │ │ (Code Based Access Controlでシステム権限をプロシージャに対してロール経由で付与) ↓ ↓ DEFUSER.PRC_KILL_SESS … KILL SESSIONを行うストアド・プロシージャ、実行者権限(AUTHID CURRENT_USER)で作成 ↓ 実行権限付与(GRANT EXECUTE…) ↓ EXEUSER ←権限の弱いDBユーザー
DBユーザー作成
プロシージャ所有者(DEFUSER)と実行ユーザー(EXEUSER)をそれぞれ作成します。
-- プロシージャの所有者を作成 CONNECT /AS SYSDBA CREATE USER DEFUSER IDENTIFIED BY xxxxxxxx DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP; -- DBAロールを付与 GRANT DBA TO DEFUSER; -- KILL SESSIONを実行するユーザー CREATE USER EXEUSER IDENTIFIED BY xxxxxxxx DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP; -- CREATE SESSION権限のみ付与 GRANT CREATE SESSION TO EXEUSER; Connected. User created. Grant succeeded. User created. Grant succeeded.
プロシージャ作成
実行者権限(AUTHID CURRENT_USER)のプロシージャを作成します。
-- 実行者権限(AUTHID CURRENT_USER)のKILL SESSIONプロシージャを作成 CONNECT DEFUSER/xxxxxxxx@yyyyyyyy CREATE OR REPLACE PROCEDURE DEFUSER.PRC_KILL_SESS ( in_sid IN NUMBER , in_serial IN NUMBER ) AUTHID CURRENT_USER IS BEGIN DBMS_OUTPUT.PUT_LINE('Current Schema => ' || SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA')); DBMS_OUTPUT.PUT_LINE('Current User => ' || SYS_CONTEXT('USERENV', 'CURRENT_USER')); DBMS_OUTPUT.PUT_LINE('Session User => ' || SYS_CONTEXT('USERENV', 'SESSION_USER')); EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' || in_sid || ',' || in_serial || ''''; END; / Connected. Procedure created.
ロール作成&権限付与 および Code Based Access Controlによる権限付与
プロシージャ所有者でロールを作成して、
ロール経由でALTER SYSTEM権限をプロシージャに付与します。
ユーザーやロールではなく、プロシージャに権限を付与するところがポイントで、
これが12c新機能のCode Based Access Control、、、と理解したやで。彡(゚)(゚)
CONNECT DEFUSER/xxxxxxxx@yyyyyyyy -- ロール作成とロールに対するALTER SYSTEM権限の付与 CREATE ROLE RL_EXEC_KILL_SESS; GRANT ALTER SYSTEM TO RL_EXEC_KILL_SESS; -- ALTER SYSTEM権限をロール経由でプロシージャに付与(Code Based Access Control) GRANT RL_EXEC_KILL_SESS TO PROCEDURE DEFUSER.PRC_KILL_SESS; -- プロシージャの実行権限付与 GRANT EXECUTE ON DEFUSER.PRC_KILL_SESS TO EXEUSER; Role created. Grant succeeded. Grant succeeded. Grant succeeded.
EXEUSERでKILL SESSIONの検証
EXEUSERでKILL SESSIONの検証をしてみます。下記のセッションをKILLしてみます。
CONNECT AYSHIBAT/xxxxxxxx@yyyyyyyy Connected. SELECT SID, SERIAL# FROM V$SESSION WHERE USERNAME = 'AYSHIBAT'; SID SERIAL# ---------- ---------- 787 62729
まずは ALTER SYSTEM KILL SESSION…から。権限が無いので当然失敗します。
CONNECT EXEUSER/xxxxxxxx@yyyyyyyy Connected. SHOW USER USER is "EXEUSER" ALTER SYSTEM KILL SESSION '787, 62729'; * ERROR at line 1: ORA-01031: insufficient privileges
ストアド・プロシージャ(PRC_KILL_SESS)によるKILL。こちらは成功します。
CONNECT EXEUSER/xxxxxxxx@yyyyyyyy Connected. SHOW USER USER is "EXEUSER" SET SERVEROUTPUT ON SIZE 1000000; EXEC DEFUSER.PRC_KILL_SESS(787, 62729); Current Schema => EXEUSER Current User => EXEUSER Session User => EXEUSER PL/SQL procedure successfully completed.
元のセッション(AYSHIBATユーザ)に戻ってみると……
見事にKILLされています。やったぜ。彡(^)(^)
SELECT SID, SERIAL# FROM V$SESSION WHERE USERNAME = 'AYSHIBAT'; * ERROR at line 1: ORA-00028: your session has been killed SELECT SID, SERIAL# FROM V$SESSION WHERE USERNAME = 'AYSHIBAT'; * ERROR at line 1: ORA-01012: not logged on Process ID: 4160 Session ID: 787 Serial number: 62729
ちなみにALTER SYSTEM権限をロールから剥奪(REVOKE)すると、
実行ユーザーからはKILL SESSIONが実行できなくなります。
Code Based Access Controlが有効に機能していることが解ります彡(゚)(゚)
CONNECT DEFUSER/xxxxxxxx@yyyyyyyy REVOKE ALTER SYSTEM FROM RL_EXEC_KILL_SESS; Connected. Revoke succeeded. CONNECT EXEUSER/xxxxxxxx@yyyyyyyy SET SERVEROUTPUT ON SIZE 1000000; EXEC DEFUSER.PRC_KILL_SESS(798, 56993); Connected. Current Schema => EXEUSER Current User => EXEUSER Session User => EXEUSER BEGIN DEFUSER.PRC_KILL_SESS(798, 56993); END; * ERROR at line 1: ORA-01031: insufficient privileges ORA-06512: at "DEFUSER.PRC_KILL_SESS", line 11 ORA-06512: at line 1
AUTHID DEFINERだと、問答無用で定義者の権限やロールで処理されてしまう所を、
実行者に付与された権限&ロールできめ細かく制御可能なのが、
この機能(Code Based Access Control)のメリットやね彡(^)(^)
#今回のケースだと、メリットが全面的には出し辛かったんやけどね。。。彡(-)(-)
マニュアルも読みませう彡(゚)(゚)
Oracle Database新機能ガイド 12cリリース1 (12.1) B71327-05 2.9.2.2 コードベース・セキュリティ https://docs.oracle.com/cd/E57425_01/121/NEWFT/chapter12101.htm#FEATURENO08676 Oracle Databaseセキュリティ・ガイド 12c リリース1 (12.1) B71285-10 定義者権限および実行者権限のコード・ベース・アクセス制御の使用 https://docs.oracle.com/cd/E57425_01/121/DBSEG/dr_ir.htm#GUID-45E77E8E-587F-42AF-A163-D814264341E2