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で圧縮されるかどうかを確認してみるやで彡(ﾟ)(ﾟ)

接続トポロジは以下の通り。

```
12ｃR1(データファイルのコピー元) ⇒ DBLINK ⇒ 12cR2(コピー先、DBMS_FILE_TRANSFERを実行)
```

下記のファイル(users.273.877103105, 約1GB)をコピーして検証してみます。

```sql
-- 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 ⇒ 受信となります。

```shell
# 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)
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
```

```shell
# 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値を確認します。

```sql
-- 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.
```

```shell
# 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)
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
```

```shell
# 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を受信してるやね彡(ﾟ)(ﾟ)

```shell
# 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を再起動しています。

```shell
# 12cR1側(コピー元)
cat $ORACLE_HOME/network/admin/sqlnet.ora
SQLNET.COMPRESSION=on ★
```

```shell
# 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値を確認します。

```shell
# 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)
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
```

```shell
# 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値を確認します。

```sql
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.
```

```shell
# 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)
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
```

```shell
# 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)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★
```

```shell
# 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(トランスポータブル表領域)をしてみる。
 > https://qiita.com/ora_gonsuke777/items/0604911d14d319654459

ちなこの機能(SQLNET.COMPRESSION=on)は PDB の Clone や Relocate に
効果は有るんですかね？どちらも裏でデータファイルのコピーが
走っているはずなんで、隙を見て検証してみますやで彡(ﾟ)(ﾟ)