2017年4月23日 (日)

Data Pumpも癖モノだよね〜w その4と1/2 - schemaモードでMviewを他のPDBへ複製 (紛らわしいステータスw)

Previously on Mac De Oracle

前回は、Data PumpのschemaモードでschemaごとまるっとMviewサイトを複製してみたところまで、でした。

エントリには記載していなかったログを見ていて驚いた!ことを調査してみる回として”その4と1/2”にしてみましたw

ほんと、癖モノですよねーMviewも!w



なに驚いたのか、その内容から

Data Pumpを利用しMviewを複製する今回の目的の一つである、完全リフレッシュしないでMviewを複製するという目論見が外れていた!!!?

と思われるログが残っていました。

以下のログは、Data Pumpのインポートログとその後のMview関連ビューをリストしたものですが、赤字部分に注目

Starting "SYSTEM"."SYS_IMPORT_FULL_01":  system/********@orcl2 directory=workdir dumpfile=mview_schema1.dmp logfile=imp_mview_schema1.dmp 
Processing object type SCHEMA_EXPORT/USER

・・・中略・・・

Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "MVIEW_SCHEMA1"."MV_MASTER" 5.5 KB 2 rows

・・・中略・・・

Processing object type SCHEMA_EXPORT/MATERIALIZED_VIEW
Processing object type SCHEMA_EXPORT/JOB
Processing object type SCHEMA_EXPORT/REFRESH_GROUP
Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at Sun Apr 23 20:30:19 2017 elapsed 0 00:00:28

インポート直後、2つのMviewの状態を確認したログですが、B列(DBA_REFRESH.BROKEN列)はどちらも”N"となっておりリフレッシュジョブは停止中です。問題は下のLAST_REF列(DBA_MVIEWS.LAST_REFRESH_TYPE列)がCOMPLETEとなっているというところです。
CON_ID=5は、PDB:ORCL2なのでインポートを行ったPDBを指します。DBA_MVIEWS.LAST_REFRESH_TYPE列は、「最新のリフレッシュに使用されるメソッド:COMPLETE- 最新のリフレッシュが完了した。」と説明されています。??
完全リフレッシュされちゃったの??? 

こうなったらData PumpでMviewが作成された時に完全リフレッシュされちゃうのか、されないのか確認するしかありませんねw。

ROWNER               RNAME                  REFGROUP        JOB B INTERVAL             NEXT_DATE               CON_ID
-------------------- -------------------- ---------- ---------- - -------------------- ------------------- ----------
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/23 20:38:31 5
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/23 20:43:30 3

MVIEW_NAME REFRES REFRESH_ LAST_REF AFTER_FAST_REFRESH COMPILE_STATE CON_ID
------------------------------ ------ -------- -------- ------------------- ------------------- ----------
MV_MASTER DEMAND FAST COMPLETE UNDEFINED VALID 5
MV_MASTER DEMAND FAST FAST UNDEFINED VALID 3

ということで、確認してみました。

最初は、前回と同じPDB:ORCLのスキーマ間で基本レプリケーション環境を作成し、リフレッシュジョブを停止するところまで(何をやっているかはDDLやSQL文を見ればわかると思うので略。わからないと言う方は前回の内容で確認ください。)

orcl12c@SYS> show pdbs

CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCL READ WRITE NO
4 ORDS READ WRITE NO
5 ORCL2 READ WRITE NO

orcl@SYS> create directory workdir as '/u01/userhome/oracle';

Directory created.

orcl@SYS> create user master_schema identified by welcome1
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;

User created.

orcl@SYS> grant create session, create table to master_schema;

Grant succeeded.

orcl@SYS> create user mview_schema1 identified by welcome1
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;

User created.

orcl@SYS> grant create session, create table, create database link, create materialized view to mview_schema1;

Grant succeeded.

orcl@SYS> conn master_schema/welcome1@orcl
Connected.
orcl@MASTER_SCHEMA> create table master (
2 id number primary key
3 ,foo varchar2(100));

Table created.

orcl@MASTER_SCHEMA> insert into master values(1,'foo');

1 row created.

orcl@MASTER_SCHEMA> insert into master values(2,'bar');

1 row created.

orcl@MASTER_SCHEMA> commit;

Commit complete.

orcl@MASTER_SCHEMA> create materialized view log on master;

Materialized view log created.

orcl@MASTER_SCHEMA> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> create database link to_master_schema
2 connect to master_schema identified by welcome1
3 using 'ORCL';

Database link created.

orcl@MVIEW_SCHEMA1> select count(*) from master@to_master_schema;

COUNT(*)
----------
2

orcl@MVIEW_SCHEMA1> create materialized view mv_master
2 refresh fast on demand
3 start with sysdate next sysdate+5/1440
4 as select * from master@to_master_schema;

Materialized view created.

orcl@MVIEW_SCHEMA1> select count(1) from mv_master;

COUNT(1)
----------
2

orcl@MVIEW_SCHEMA1> @mview_info_c
Connected.

Session altered.

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE CON_ID
-------------------- -------------------- ---------- ---------- - -------------------- ------------------- ----------
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/23 20:12:06 3

MVIEW_NAME REFRES REFRESH_ LAST_REF AFTER_FAST_REFRESH COMPILE_STATE
------------------------------ ------ -------- -------- ------------------- -------------------
MV_MASTER DEMAND FAST FAST UNDEFINED VALID

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/23 20:07:06 2017/04/23 20:12:06 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"');

orcl12c@SYS> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> exec dbms_job.broken(job=>81,broken=>true);

PL/SQL procedure successfully completed.

orcl@MVIEW_SCHEMA1> @mview_info_c

Session altered.

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE CON_ID
-------------------- -------------------- ---------- ---------- - -------------------- ------------------- ----------
MVIEW_SCHEMA1 MV_MASTER 61 81 Y sysdate+5/1440 4000/01/01 00:00:00 3

MVIEW_NAME REFRES REFRESH_ LAST_REF AFTER_FAST_REFRESH COMPILE_STATE CON_ID
------------------------------ ------ -------- -------- ------------------- ------------------- ----------
MV_MASTER DEMAND FAST FAST UNDEFINED VALID 3

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT    CON_ID
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------ ----------
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/23 20:07:06 4000/01/01 00:00:00 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"'); 3


ここまでは同じなのですが、Data PumpでMviewをインポートする際に完全リフレッシュしているのか?どうかを確認するため、リフレッシュジョブ停止後、マスター表を100行に増幅しておきます。
こうしておけば、Data PumpでMviewがインポートされる際、完全リフレッシュが行われていたとしたら、インポート後のMviewは100行になっているはずだし、
 逆に2行のままなら、LAST_REFRESH_TYPE=COMPLETEにはなっているものの実際には完全リフレッシュしなていない、という、なんともわかりづらい状況になるから気にすんな、ってことが見えてくるはず。

orcl12c@SYS> conn master_schema/welcome1@orcl
Connected.
orcl@MASTER_SCHEMA> begin for i in 3..100 loop insert into master values(i,'data#'||i); end loop; end;
2 /

PL/SQL procedure successfully completed.

orcl@MASTER_SCHEMA> commit;

Commit complete.

orcl@MASTER_SCHEMA> select count(1) from master;

COUNT(1)
----------
100

orcl@MASTER_SCHEMA> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> select count(1) from mv_master;

COUNT(1)
----------
2

エクスポートは2行となっているので、Mviewから2行エクスポートされているのは間違いない!(マスター表は100行!)

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "SYSTEM"."SYS_EXPORT_SCHEMA_01": system/********@orcl directory=workdir dumpfile=mview_schema1.dmp logfile=exp_mview_schema1.log schemas=mview_schema1
Estimate in progress using BLOCKS method...
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/DB_LINK
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/MATERIALIZED_VIEW
Processing object type SCHEMA_EXPORT/JOB
Processing object type SCHEMA_EXPORT/REFRESH_GROUP
. . exported "MVIEW_SCHEMA1"."MV_MASTER" 5.5 KB 2 rows
Master table "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYSTEM.SYS_EXPORT_SCHEMA_01 is:
/u01/userhome/oracle/mview_schema1.dmp
Job "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully completed at Sun Apr 23 20:28:25 2017 elapsed 0 00:00:54

PDB:ORCL2にて、Data Pump作業向けディレクトリオブジェクトを作成

[oracle@vbgeneric oracle]$ sqlplus sys/oracle@orcl2 as sysdba

SQL*Plus: Release 12.1.0.2.0 Production on Sun Apr 23 20:29:07 2017

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

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

orcl2@SYS> create directory workdir as '/u01/userhome/oracle';

Directory created.


インポートでも見ての通り、2行だけインポートされています!(ステータスが紛らわしい説が強くなってきました!!!)

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_FULL_01": system/********@orcl2 directory=workdir dumpfile=mview_schema1.dmp logfile=imp_mview_schema1.dmp
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/DB_LINK
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "MVIEW_SCHEMA1"."MV_MASTER" 5.5 KB 2 rows
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/MATERIALIZED_VIEW
Processing object type SCHEMA_EXPORT/JOB
Processing object type SCHEMA_EXPORT/REFRESH_GROUP
Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at Sun Apr 23 20:30:19 2017 elapsed 0 00:00:28


インポート後、どちらのリフレッシュジョブも停止中ですが、1箇所違いがみられます。
そう、インポートしたMviewのLAST_REF(DBA_MVIEWS.LAST_REFRESH_TYPE)がCOMPLETEになっています。前半に書いたとおりの状態が再現!!! なにっ!!

orcl12c@SYS> @mview_info_c
Connected.

Session altered.

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE CON_ID
-------------------- -------------------- ---------- ---------- - -------------------- ------------------- ----------
MVIEW_SCHEMA1 MV_MASTER 61 81 Y sysdate+5/1440 4000/01/01 00:00:00 3
MVIEW_SCHEMA1 MV_MASTER 61 81 Y sysdate+5/1440 4000/01/01 00:00:00 5

MVIEW_NAME REFRES REFRESH_ LAST_REF AFTER_FAST_REFRESH COMPILE_STATE CON_ID
------------------------------ ------ -------- -------- ------------------- ------------------- ----------
MV_MASTER DEMAND FAST FAST UNDEFINED VALID 3
MV_MASTER DEMAND FAST COMPLETE UNDEFINED VALID 5

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT CON_ID
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------ ----------
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/23 20:07:06 4000/01/01 00:00:00 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"'); 3
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 4000/01/01 00:00:00 sysdate+5/1440 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"'); 5

PDB_NAME CON_ID
------------------------------ ----------
PDB$SEED 2
ORCL 3
ORDS 4
ORCL2 5

DBA_MVIEWSビューのLAST_REFRESH_TYPEはCOMPLETE(完全リフレッシュされた)と設定されていますが、本当なのでしょうか? PDB:ORCL2のMV_MASTER表が本当に完全リフレッシュされていたとしたら100行になっているはずですが。。。。

PDB:ORCLのMViewの行数をカウント、2行です(リフレッシュジョブが停止しているので変化なし)

orcl12c@SYS> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> show con_id

CON_ID
------------------------------
3

orcl@MVIEW_SCHEMA1> show con_name

CON_NAME
------------------------------
ORCL

orcl@MVIEW_SCHEMA1> select count(1) from mv_master;

COUNT(1)
----------
2


さて、問題のPDB:ORCL2。。。。2行のまま!!!!! 
ということは、Data PumpによるMviewのインポートでは完全リフレッシュは行われず、エクスポートされた行数がそのままインポートされている!! ステータスが紛らわしい!! だけというのが真相のようです!

orcl@MVIEW_SCHEMA1> conn mview_schema1/welcome1@orcl2
Connected.
orcl2@MVIEW_SCHEMA1> show con_id

CON_ID
------------------------------
5

orcl2@MVIEW_SCHEMA1> show con_name

CON_NAME
------------------------------
ORCL2

orcl2@MVIEW_SCHEMA1> select count(1) from mv_master;

COUNT(1)
----------
2


ジョブを再開すると。。。マスターサイトと同期され各MViewは100行なっています。めでたしめでたし。

@> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> exec dbms_job.broken(job=>81,broken=>false,next_date=>sysdate);

PL/SQL procedure successfully completed.

orcl@MVIEW_SCHEMA1> conn mview_schema1/welcome1@orcl2
Connected.
orcl2@MVIEW_SCHEMA1> exec dbms_job.broken(job=>81,broken=>false,next_date=>sysdate);

PL/SQL procedure successfully completed.

orcl12c@SYS> @mview_info_c
Connected.

Session altered.

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE CON_ID
-------------------- -------------------- ---------- ---------- - -------------------- ------------------- ----------
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/23 20:44:05 5
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/23 20:43:30 3

MVIEW_NAME REFRES REFRESH_ LAST_REF AFTER_FAST_REFRESH COMPILE_STATE CON_ID
------------------------------ ------ -------- -------- ------------------- ------------------- ----------
MV_MASTER DEMAND FAST FAST UNDEFINED VALID 3
MV_MASTER DEMAND FAST FAST UNDEFINED VALID 5

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT CON_ID
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------ ----------
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/23 20:38:30 2017/04/23 20:43:30 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"'); 3
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/23 20:39:05 2017/04/23 20:44:05 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"'); 5

orcl12c@SYS> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> select count(1) from mv_master;

COUNT(1)
----------
100

orcl@MVIEW_SCHEMA1> conn mview_schema1/welcome1@orcl2
Connected.
orcl2@MVIEW_SCHEMA1> select count(1) from mv_master;

COUNT(1)
----------
100

やれやれ、お騒がせすぎるw 

次回へつづく。


参考:ログ中で利用したSQLスクリプト(mview_info_c.sql)のソース

conn sys/oracle@orcl12c as sysdba

col rowner for a20
col rname for a20
col mview_name for a30
col log_user for a20
col schema_user for a20
col interval for a20
col what for a60
alter session set nls_date_format='yyyy/mm/dd hh24:mi:ss';
select rowner,rname,refgroup,job,broken,interval,next_date,con_id from containers(dba_refresh) where rowner='MVIEW_SCHEMA1';
select mview_name,refresh_mode,refresh_method,last_refresh_type,after_fast_refresh,compile_state from containers(dba_mviews) where mview_name='MV_MASTER';
select job,log_user,schema_user,last_date,next_date,interval,failures,what from containers(dba_jobs) where log_user='MVIEW_SCHEMA1';




Data Pumpも癖モノだよね〜w その1 - queryパラメーターの解析タイミング
Data Pumpも癖モノだよね〜w その2 - Materialized ViewをTableとして移行する
Data Pumpも癖モノだよね〜w その3 - dbms_job と dbms_scheduler との複雑な関係
Data Pumpも癖モノだよね〜w その4 - schemaモードでMviewを他のPDBへ複製

| | コメント (0) | トラックバック (0)

2017年4月22日 (土)

Data Pumpも癖モノだよね〜w その4 - schemaモードでMviewを他のPDBへ複製

一回、おやすみしましたが、Previously on Mac De Oracle

前々回は、Data Pump、dbms_jobとdbms_schedulerの複雑な関係を紐解いてみました。

今回は、箸休めとして、schemaモードより上位のモードならMviewはMviewのまま複製や移行することは簡単に行えるよね。という確認だけしておこうと思います。
シンプルだと思わせておいて、細けーことやろうとすると一癖ある、まさに癖モノw ということで :)


まずは、おさらいから

data pumpのschemaモード向けSCHEMA_EXPORT_OBJECTSにはオブジェクトパスの定義でMviewに関連するオブジェクト全てが定義されています。

OBJECT_PATH                     COMMENTS
------------------------------- ------------------------------------------------------------
SCHEMA_EXPORT/DB_LINK Private database links in the selected schemas
SCHEMA_EXPORT/TABLE Tables in the selected schemas and their dependent objects
SCHEMA_EXPORT/MATERIALIZED_VIEW Materialized views
SCHEMA_EXPORT/JOB Jobs in the selected schemas
SCHEMA_EXPORT/REFRESH_GROUP Refresh groups in the selected schemas

一方、tableモード向けTABLE_EXPORT_OBJECTSには、Mview、リフレッシュに必要なJOBやREFRESH GROUPなどのオブジェクトパスが定義されていません。
tableモードでMviewを複製しようとすること自体に無理があるのは明らかですね。MViewとしてエクスポートしたくてもオプジェクトパスが定義されていないのですから。
表を対象としているモードだからそれ以外のオブジェクトパスが定義されていないんだよね〜と、無理やり納得しています:)

orcl@SYSTEM> r
1 select * from TABLE_EXPORT_OBJECTS where
2 object_path like '%/JOB'
3 or object_path like '%/MATERIALIZED_VIEW'
4* or object_path like '%/REFRESH_GROUP'

no rows selected

おさらいはこれくらいにして、schemaモードエクスポートで以下の図に示したようなMviewの複製が行えるか確認しておきます。

ポンチ絵のとおりではあるのですが、簡単に説明すると、
PDB:ORCLの異なるschema間で高速リフレッシュ可能なMviewがあり、Data Pumpのschemaモードを利用して異なるPDBにMviewを複製するというシナリオです。
複製後はMviewサイトが2つになります。

20170415_14044


なぜ、異なるDB(PDB)にMVIEWを複製するシナリオにしたかって?
理由は、DBMS_JOBのジョブは、同一データベース(MTA構成であればPDB毎)でJOB番号により一意に管理されています。
DBMS_JOBのジョブを同一データベース内でexport/importした場合、ジョブが単純に複製される事になりJOB番号の一意制約エラーとなりimportに失敗します。
importできなければ再作成すれば問題ないわけですが、MTA環境なのでわざわざ同一PDB内に作成する必要はないわけです。(手数を減らせるならその方が楽ですから)

エクスポートする前にリフレッシュジョブを一時停止する理由は?
一時停止している理由は静止点を作りたいこともありますが、それをサボると、なかなか理解しにくいタイミングイシューと言われてる事象に遭遇しやすくなるんですよ。(感覚的に)
前述の状況になると高速リフレッシュを再開するには、一度、完全リフレッシュする必要があります。
ここで利用するMviewは2行しかないので完全リフレッシュは苦でもないですが、巨大サイズの表だったら完全リフレッシュはできることなら避けたいですよね。


PDB:ORCLの異なるschema間でmaster表→mv_master表で基本レプリケーション環境作成からData PumpでOmv_master表のオーナースキーマごとPDB:ORCL2へ複製までをつらつらと記録してあります。:)

MTA環境となっています。PDB:ORCL内で基本レプリケーション環境を作り、PDB:ORCL2にDBリンクやMVIEW等関連オブジェクトをData Pumpを利用して複製します。

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

orcl12c@SYS> show pdbs

CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCL READ WRITE NO
4 ORDS READ WRITE NO
5 ORCL2 READ WRITE NO


PDB:ORCLデータベースにディレクトリオブジェクトを作成します。(Data Pump向け作業ディレクトリ)

orcl@SYS> create directory workdir as '/u01/userhome/oracle';

Directory created.

PDB:ORCLデータベースにマスターサイト向けユーザを作成し、必要最低限の権限を付与

orcl@SYS> create user master_schema identified by welcome1
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;

User created.

orcl@SYS> grant create session, create table to master_schema;

Grant succeeded.

PDB:ORCL、作成したユーザに接続し、マスター表を作成

orcl@SYS> conn master_schema/welcome1@orcl
Connected.
orcl@MASTER_SCHEMA> create table master (
2 id number primary key
3 ,foo varchar2(100));

Table created.

orcl@MASTER_SCHEMA> insert into master values(1,'foo');

1 row created.

orcl@MASTER_SCHEMA> insert into master values(2,'bar');

1 row created.

orcl@MASTER_SCHEMA> commit;

Commit complete.


PDB:ORCL、高速リフレッシュに必要なMaterialized View LogをMaster表に作成します。

orcl@MASTER_SCHEMA> create materialized view log on master;

Materialized view log created.


同じくPDB:ORCLデータベースにMviewサイト向けユーザを作成し、必要最低限の権限を付与します。

orcl@SYS> create user mview_schema1 identified by welcome1
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;

User created.

orcl@SYS> grant create session, create table, create database link, create materialized view to mview_schema1;

Grant succeeded.


PDB:ORCL、Mviewサイト向けに作成したユーザに接続し、マスターサイトへのデータベースリンクとMaterialized Viewを作成します。

orcl@SYS> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> create database link to_master_schema
2 connect to master_schema identified by welcome1
3 using 'ORCL';

Database link created.

orcl@MVIEW_SCHEMA1> select count(*) from master@to_master_schema;

COUNT(*)
----------
2

orcl@MVIEW_SCHEMA1> create materialized view mv_master
2 refresh fast on demand
3 start with sysdate next sysdate+5/1440
4 as select * from master@to_master_schema;

Materialized view created.


PDB:ORCL、MViewサイトのオブジェクト確認からDBMS_JOBとリフレッシュグループの高速リフレッシュされているところまでを確認しています。

Mviewを作成すると、作成したMviewは、TABLEでもあり、MVIEWでもある。ということが確認できます。これ重要ですよ!
data pumpのschemaモード向けSCHEMA_EXPORT_OBJECTSビューにTABLEとMATERIALIZED_VIEWの2つのオブジェクトパスがあるにも関わらず、
tableモードのTABLE_EXPORT_OBJECTSビューにはTABLEオブジェクトパスは定義されているのにMATERIALIZED_VIEWオブジェクトパスされていないからMVIEWとしてはエクポートできないと言っていた理由なんですよ!!!!

orcl@MVIEW_SCHEMA1> select object_name,object_type from user_objects;

OBJECT_NAME OBJECT_TYPE
------------------------------ -----------------------
MV_MASTER TABLE
SYS_C0014880 INDEX
MV_MASTER MATERIALIZED VIEW
TO_MASTER_SCHEMA DATABASE LINK

次はuser_jobsからリフレッシュジョブを確認しておきます。これもMviewをリフレッシュするのに必要なオブジェクトです。
data pumpのschemaモード向けSCHEMA_EXPORT_OBJECTSビューでJOBオブジェクトパスとして定義されています。これも重要なんです。
前回JOBオブジェクトパスに対応するオブジェクトは、DBMS_JOBのJOBだということを書きましたが、思い出していただけましたか? 

orcl@MVIEW_SCHEMA1> select job,log_user,schema_user,last_date,next_date,interval,failures,what from user_jobs;

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/15 00:09:04 2017/04/15 00:14:04 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"');

最後にリフレッシュグループの確認、意外とこれの存在を忘れてしまうんですよ。私もそうでした。
単一MVIEWのリフレッシュでもリフレッシュグループが自動的に作成されてしまうことを...複数のMVIEWをリフレッシュする時だけに必要なのかと思ったら大間違いw
いつも、つい、忘れちゃいますw 影薄過ぎ! ですが、前述のWHAT列の内容を見れば、なるほど! となるはずです。
dbms_refresh.refreshプロシージャは、リフレッシュグループ名が引数!!

orcl@MVIEW_SCHEMA1> select rowner,rname,refgroup,job,broken,interval,next_date from user_refresh;

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE
-------------------- -------------------- ---------- ---------- - -------------------- -------------------
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/15 00:29:29


PDB:ORCL、リフレッシュジョブを一時停止し、expdpのschemaモードでMviewサイト向けスキーマを丸ごとエクスポートします。

orcl@MVIEW_SCHEMA1> exec dbms_job.broken(job=>81,broken=>true);

PL/SQL procedure successfully completed.

orcl@MVIEW_SCHEMA1> select rowner,rname,refgroup,job,broken,interval,next_date from user_refresh;

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE
-------------------- -------------------- ---------- ---------- - -------------------- -------------------
MVIEW_SCHEMA1 MV_MASTER 61 81 Y sysdate+5/1440 4000/01/01 00:00:00


Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "SYSTEM"."SYS_EXPORT_SCHEMA_01": system/********@orcl directory=workdir dumpfile=mview_schema1.dmp logfile=exp_mview_schema1.log schemas=mview_schema1
Estimate in progress using BLOCKS method...
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/DB_LINK
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/MATERIALIZED_VIEW
Processing object type SCHEMA_EXPORT/JOB
Processing object type SCHEMA_EXPORT/REFRESH_GROUP
. . exported "MVIEW_SCHEMA1"."MV_MASTER" 5.5 KB 2 rows
Master table "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYSTEM.SYS_EXPORT_SCHEMA_01 is:
/u01/userhome/oracle/mview_schema1.dmp
Job "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully completed at Sat Apr 15 00:30:55 2017 elapsed 0 00:00:55


無事エクスポートできたようなので、次は、
PDB:ORCL2データベースで、ディレクトリオブジェクトを作成します。2つめのMviewサイトの準備です。

orcl2@SYSTEM> create directory workdir as '/u01/userhome/oracle';

Directory created.


PDB:ORCL2、schemaモードでインポート。(対象PDB:ORCL2には同一スキーマは存在しない状態で実施)

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_FULL_01": system/********@orcl2 directory=workdir dumpfile=mview_schema1.dmp logfile=imp_mview_schema1.dmp
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/DB_LINK
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "MVIEW_SCHEMA1"."MV_MASTER" 5.5 KB 2 rows
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/MATERIALIZED_VIEW
Processing object type SCHEMA_EXPORT/JOB
Processing object type SCHEMA_EXPORT/REFRESH_GROUP
Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at Sat Apr 15 00:39:00 2017 elapsed 0 00:00:23

と、すんなり終了w

PDB:ORCL2、インポートで複製されたMVIEW_SCHEMA1ユーザに接続しオブジェクトを確認
リフレッシュジョブは、エクスポート元と同一ジョブ番号でインポートされ、停止状態。想定通りで一安心:)

orcl2@MVIEW_SCHEMA1> select object_name,object_type from user_objects;

OBJECT_NAME OBJECT_TYPE
------------------------------ -----------------------
MV_MASTER TABLE
SYS_C0014884 INDEX
MV_MASTER MATERIALIZED VIEW
TO_MASTER_SCHEMA DATABASE LINK

orcl2@MVIEW_SCHEMA1> select job,log_user,schema_user,last_date,next_date,interval,failures,what from user_jobs;

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 4000/01/01 00:00:00 sysdate+5/1440 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"');

orcl2@MVIEW_SCHEMA1> select rowner,rname,refgroup,job,broken,interval,next_date from user_refresh;

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE
-------------------- -------------------- ---------- ---------- - -------------------- -------------------
MVIEW_SCHEMA1 MV_MASTER 61 81 Y sysdate+5/1440 4000/01/01 00:00:00


PDB:ORCLとORCL2、両MViewサイトのリフレッシュジョブを再開

orcl2@MVIEW_SCHEMA1> conn mview_schema1/welcome1@orcl2
Connected.
orcl2@MVIEW_SCHEMA1> exec dbms_job.broken(job=>81,broken=>false,next_date=>sysdate);

PL/SQL procedure successfully completed.

orcl2@MVIEW_SCHEMA1> conn mview_schema1/welcome1@orcl
Connected.
orcl@MVIEW_SCHEMA1> exec dbms_job.broken(job=>81,broken=>false,next_date=>sysdate);

PL/SQL procedure successfully completed.

最後に、containers句を使って全体を確認っと!

orcl2@MVIEW_SCHEMA1> conn sys/oracle@orcl12c as sysdba
Connected.
orcl12c@SYS> select rowner,rname,refgroup,job,broken,interval,next_date,con_id from containers(dba_refresh) where rowner='MVIEW_SCHEMA1';

ROWNER RNAME REFGROUP JOB B INTERVAL NEXT_DATE CON_ID
-------------------- -------------------- ---------- ---------- - -------------------- ------------------- ----------
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/15 22:25:47 5
MVIEW_SCHEMA1 MV_MASTER 61 81 N sysdate+5/1440 2017/04/15 22:26:52 3

orcl12c@SYS> select mview_name,refresh_mode,refresh_method,last_refresh_type,after_fast_refresh,compile_state from containers(dba_mviews) where mview_name='MV_MASTER';
MVIEW_NAME REFRES REFRESH_ LAST_REF AFTER_FAST_REFRESH COMPILE_STATE
------------------------------ ------ -------- -------- ------------------- -------------------
MV_MASTER DEMAND FAST FAST UNDEFINED VALID
MV_MASTER DEMAND FAST FAST UNDEFINED VALID

orcl12c@SYS> select job,log_user,schema_user,last_date,next_date,interval,failures,what from containers(dba_jobs) where log_user='MVIEW_SCHEMA1';
JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/15 22:20:47 2017/04/15 22:25:47 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"');
81 MVIEW_SCHEMA1 MVIEW_SCHEMA1 2017/04/15 22:21:52 2017/04/15 22:26:52 sysdate+5/1440 0 dbms_refresh.refresh('"MVIEW_SCHEMA1"."MV_MASTER"');

何事もなく複製できたところで、次回へ続く。

あ、その前に、環境を初期状態に戻さないと。。


Data Pumpも癖モノだよね〜w その1 - queryパラメーターの解析タイミング
Data Pumpも癖モノだよね〜w その2 - Materialized ViewをTableとして移行する
Data Pumpも癖モノだよね〜w その3 - dbms_job と dbms_scheduler との複雑な関係

| | コメント (0) | トラックバック (0)

2017年4月10日 (月)

Data Pumpも癖モノだよね〜w その3 - dbms_job と dbms_scheduler との複雑な関係

Previously on Mac De Oracle

前回は、Data PumpとMaterialized Viewという癖モノ二大巨頭を絡ませて見ました。

今回は、三つ巴?な感じでお送りしたいと思います。:)



以下は、Materialized ViewをリフレッシュするDBMS_JOBです。

今頃気づいたか! という感じですが、dbms_job で作成されるJOBは、ALL/DBA/USER_OBJECTSには含まれないのです!!

orcl@USERS> select job,log_user,schema_user,last_date,next_date,interval,failures,what from user_jobs;

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------
21 USERS USERS 2017/04/09 19:18:34 2017/04/09 19:19:34 sysdate+1/1440 0 dbms_refresh.refresh('"USERS"."MVIEW_MASTER"');

orcl@USERS> select object_name,object_type from user_objects;

OBJECT_NAME OBJECT_TYPE
------------------------------ -----------------------
MVIEW_MASTER MATERIALIZED VIEW
SYS_C0014637 INDEX
MVIEW_MASTER TABLE
TOUSERM DATABASE LINK


ここで、注目!!
dbms_jobは、dba_objectsにはカウントされませんが、dbms_schedulerは、object_type=JOBとしてdba_objectsにカウントされるということ!!
以下にある、OBJECT_TYPE=JOBは、OBJECT_NAME=TESTという直前に作成されたdbms_schedulerのJOBだということ!!

ORCL@USERS> begin
dbms_scheduler.create_job (
job_name=>'test'
,job_type=>'PLSQL_BLOCK'
,job_action=>'BEGIN dbms_refresh.refresh(''USERS.MVIEW_MASTER''); END;'
,start_date=>systimestamp
,repeat_interval=>'FREQ=MONTHLY'
,end_date=>systimestamp + interval '1' year
,enabled=>true
,comments=>null
);
end;
/

PL/SQL procedure successfully completed.


なんとまぁ、面倒くさい、DBMS_JOBのJOBも、DBMS_SCHEDULERのJOBも、同じ初期化パラメータ(job_queue_processes)を利用するのにオブジェクト扱いされたりされなかったり、面倒くさい癖モノです。注意しましょうね!!

Oracle® Databaseリファレンス 12c リリース1 (12.1) 1.126 JOB_QUEUE_PROCESSES
https://docs.oracle.com/cd/E57425_01/121/REFRN/GUID-B8B68D16-00A3-43DD-BE39-01F877880955.htm

ORCL@USERS> select object_name,object_type from user_objects;

OBJECT_NAME OBJECT_TYPE
------------------------------ -----------------------
MVIEW_MASTER TABLE
SYS_C0014637 INDEX
MVIEW_MASTER MATERIALIZED VIEW
TEST JOB
TOUSERM DATABASE LINK

という準備運動が終わったところで、本題の Data Pumpでのお話です。
癖モノData Pumpと癖モノ感たっぷりの2種類のJOB、2時間ドラマの複雑でドロドロした関係が予想される展開になってきましたw

orcl@USERS> select job,log_user,schema_user,last_date,next_date,interval,failures,what from user_jobs;

JOB LOG_USER SCHEMA_USER LAST_DATE NEXT_DATE INTERVAL FAILURES WHAT
---------- -------------------- -------------------- ------------------- ------------------- -------------------- ---------- ------------------------------------------------------------
21 USERS USERS 2017/04/09 19:18:34 2017/04/09 19:19:34 sysdate+1/1440 0 dbms_refresh.refresh('"USERS"."MVIEW_MASTER"');

orcl@USERS> select job_name,job_action,repeat_interval,start_date from user_scheduler_jobs;

JOB_NAME JOB_ACTION REPEAT_INTERVAL START_DATE
---------- ------------------------------------------------------------------- -------------------- ----------------------------------------
TEST BEGIN dbms_refresh.refresh('USERS.MVIEW_MASTER'); END; FREQ=MONTHLY 09-APR-17 10.36.05.814317 PM +09:00


まず、Data Pumpで扱える"OBJECT”が定義されているSCHEMA_EXPORT_OBJECTSをみると以下の"OBJECT”定義が見つかります。
JOBというオブジェクトのコメントを読んでも、2種類あるJOBのどちらを指しているのか、はたまた、いずれか一つなのかさっぱりわかりません。

OBJECT_PATH                     COMMENTS
------------------------------- ------------------------------------------------------------
SCHEMA_EXPORT/DB_LINK Private database links in the selected schemas
SCHEMA_EXPORT/TABLE Tables in the selected schemas and their dependent objects
SCHEMA_EXPORT/MATERIALIZED_VIEW Materialized views
SCHEMA_EXPORT/JOB Jobs in the selected schemas
SCHEMA_EXPORT/REFRESH_GROUP Refresh groups in the selected schemas

これは試して、ガッテン!! するしかありません!!!

schemaモードでエクスポートします。このとき、includeパラメータでJOBだけをエクスポートするよう指定します!! 

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "SYSTEM"."SYS_EXPORT_SCHEMA_01": system/********@orcl directory=homedir dumpfile=jobs.dmp logfile=jobsexp.log schemas=users include=job
Estimate in progress using BLOCKS method...
Total estimation using BLOCKS method: 0 KB
Processing object type SCHEMA_EXPORT/JOB
Master table "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYSTEM.SYS_EXPORT_SCHEMA_01 is:
/home/oracle/jobs.dmp
Job "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully completed at Sun Apr 9 23:13:47 2017 elapsed 0 00:00:04

SQLFILEパラメータを指定して内容を確認してみます。(SQLFILEパラメータを指定したimpdpコマンドでは実際にインポートは行われません)

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Master table "SYSTEM"."SYS_SQL_FILE_SCHEMA_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_SQL_FILE_SCHEMA_01": system/********@orcl directory=homedir dumpfile=jobs.dmp logfile=jobsexp.log schemas=users sqlfile=jobsexp_ddl.txt
Processing object type SCHEMA_EXPORT/JOB
Job "SYSTEM"."SYS_SQL_FILE_SCHEMA_01" successfully completed at Sun Apr 9 23:20:44 2017 elapsed 0 00:00:03


おおおおお、これは!!! 

なんということでしょう!
Data Pumpでは、JOBオブジェクトは、DBMS_JOBのJOBオブジェクト(dba_objectsではオブジェクト扱いされていないのに!!)

だとすると、dba_objectsでは”OBJECT"として扱われている、DBMS_SCHEDULERのJOBはの扱いはいかに。。。

以下のとおり、DBMS_IJOBと内部的プロリージャに置き換わっていますが、パラメータを見れば一目瞭然、DBMS_JOBの定義しかありません。
つまり、Data PumpのJOBオブジェクトは、DBMS_JOBのJOBであることがわかりました!!

[oracle@catfish ˜]$ cat jobsexp_ddl.txt 

・・・中略・・・

-- new object type path: SCHEMA_EXPORT/JOB
BEGIN SYS.DBMS_IJOB.SUBMIT(
JOB=> 21,
LUSER=> 'USERS',
PUSER=> 'USERS',
CUSER=> 'USERS',
NEXT_DATE=> TO_DATE('2017-04-09 23:13:51', 'YYYY-MM-DD:HH24:MI:SS'),
INTERVAL=> 'sysdate+1/1440',
BROKEN=> FALSE,
WHAT=> 'dbms_refresh.refresh(''"USERS"."MVIEW_MASTER"'');',

・・・中略・・・

では、DBMS_SCHEDULERのJOBは。。。それは。。。PROCOBJというOBJECT_PATHに含まれているようで(ほぼ誰にも読み取れないw)。。。

MOSにもありそうだけど、この辺りをまとめてて疲れて、めんどくさい病の発作がw 
もっと深掘りする気力があったら探すかもw
Export/Import Scheduler Jobs


手取り早く、試して、ガッテン! includeパラメータで”PROCOBJ”を指定します。

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "SYSTEM"."SYS_EXPORT_SCHEMA_01": system/********@orcl directory=homedir dumpfile=scheduler_jobs.dmp logfile=scheduler_jobsexp.log schemas=users include=procobj
Estimate in progress using BLOCKS method...
Total estimation using BLOCKS method: 0 KB
Processing object type SCHEMA_EXPORT/POST_SCHEMA/PROCOBJ
Master table "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYSTEM.SYS_EXPORT_SCHEMA_01 is:
/home/oracle/scheduler_jobs.dmp
Job "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully completed at Sun Apr 9 23:49:20 2017 elapsed 0 00:00:04

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Master table "SYSTEM"."SYS_SQL_FILE_SCHEMA_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_SQL_FILE_SCHEMA_01": system/********@orcl directory=homedir dumpfile=scheduler_jobs.dmp logfile=jobsddldump.log schemas=users sqlfile=jobsexp2_ddl.txt
Processing object type SCHEMA_EXPORT/POST_SCHEMA/PROCOBJ
Job "SYSTEM"."SYS_SQL_FILE_SCHEMA_01" successfully completed at Sun Apr 9 23:50:05 2017 elapsed 0 00:00:02


確かに、PROCOBJにDBMS_SCHEDULERのJOBが含まれている!!

[oracle@catfish ˜]$ cat jobsexp2_ddl.txt

・・・中略・・・

BEGIN
dbms_scheduler.create_job('"TEST"',
job_type=>'PLSQL_BLOCK'
, job_action=>'BEGIN dbms_refresh.refresh(''USERS.MVIEW_MASTER''); END;'
, number_of_arguments=>0
, start_date=>TO_TIMESTAMP_TZ('09-APR-2017 10.36.05.814317000 PM +09:00','DD-MON-RRRR HH.MI.SSXFF AM TZR','NLS_DATE_LANGUAGE=english')
, repeat_interval=> 'FREQ=MONTHLY'
, end_date=>TO_TIMESTAMP_TZ('09-APR-2018 10.36.05.814344000 PM +09:00','DD-MON-RRRR HH.MI.SSXFF AM TZR','NLS_DATE_LANGUAGE=english')
, job_class=>'"DEFAULT_JOB_CLASS"'
, enabled=>FALSE
, auto_drop=>TRUE
,comments=>NULL
);
dbms_scheduler.enable('"TEST"');
COMMIT;
END;
/

・・・中略・・・

登場人物の関係が複雑すぎてよくわからなくなってきたので、まとめ。

DBMS_JOBのJOBは、DBA_OBJECTS上、オブジェクトとは扱われていない。
DBMS_SCHEDULEのJOBは、DBA_OBJECTS上、オブジェクトとして扱われている。
どちらのJOBも、初期化パラメータ、job_queue_processesにより制御されている。
Data PumpのSCHEMA_EXPORT_OBJECTSにて定義されているJOBオブジェクトは、DBMS_JOBのJOBのことである。
Data PumpのSCHEMA_EXPORT_OBJECTSにて定義されているPROCOBJオブジェクトが、DBMS_SCHEDULERのJOBのこと!?であるようだ。
(オブジェクト名からは想像できない可読性の悪さはなんとかしてくれ!)

DBMS_SCHEDULERへの移行が推奨されながらDBMS_JOBが未だに存在していることの弊害のようにも思えてきた。
このあたり、理解しやすいように改善してもらいたい癖モノの一つとしてリストに加えておこう。


満開の桜なのに残念な天気の日曜日終わってしまった!! ということで今日はここまで。




Data Pumpも癖モノだよね〜w その1 - queryパラメーターの解析タイミング
Data Pumpも癖モノだよね〜w その2 - Materialized ViewをTableとして移行する

| | コメント (0) | トラックバック (0)

2017年4月 9日 (日)

Data Pumpも癖モノだよね〜w その2 - Materialized ViewをTableとして移行する

Previously on Mac De Oracle

前回はMac De OracleはData Pumpのqueryパラメーターの解析タイミングについて調べたメモでした。

今回はタイトルのとおり、Materialized ViewをTableとして移行していしまおうというお題。
実は、Materialized Viewとして移行しようとして失敗ったのがきっかけで知ったんですけど、あまり書かれていないので仕様だとは思うんですが(そうなんですよね?w)
(癖モノData Pumpと癖モノMaterialized Viewを扱おうとする時点で、すんなり行くわけがない、ぐらいの覚悟はしておいたほうが無難でしょうけど)


ちなみに、今回の内容とは関係ないですが、ViewをTableとしてエクスポートする機能も12cR1から提供されていますね(使ったことはまだないですが)
VIEWS_AS_TABLES
https://docs.oracle.com/database/121/SUTIL/GUID-E4E45E81-5391-43BE-B27D-B763EF79A885.htm#SUTIL3904

Exporting views as tables Oracle Database 12C release 1 (12.1)
http://dbaora.com/exporting-views-as-tables-oracle-database-12c-release-1-12-1/



以下のようなMVIEWがあります。
エクスポート側ではMaterialize Viewとして定義され、自動的にリフレッシュされています。

orcl@USERS>  select object_name,object_type from user_objects where object_name='MVIEW_MASTER';

OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------
MVIEW_MASTER MATERIALIZED VIEW
VIEW_MASTER TABLE

orcl@USERS> select job,log_user,last_date,next_date,interval,failures,broken,what from user_jobs;

JOB LOG_USER LAST_DATE NEXT_DATE INTERVAL FAILURES B WHAT
---------- ------------------------------ ------------------- ------------------- -------------------- ---------- - --------------------------------------------------
21 USERS 2017/04/09 14:16:53 2017/04/09 14:17:53 sysdate+1/1440 0 N dbms_refresh.refresh('"USERS"."MVIEW_MASTER"');

表モードでMviewからTableへの変換!
tablesパラメータでMviewを指定しているところがポイント! MVIEWでもありTABLEでもあるのでTABLEとしてエクスポートができます。

表モードで有効なオブジェクトをTABLE_EXPORT_OBJECTSで確認してみて気づいたのですが、TABLE_EXPORT_OBJECTSには MATERIALIZED_VIEW は存在しません。

orcl@SYSTEM^> r
1 select * from TABLE_EXPORT_OBJECTS where
2 object_path like '%/JOB'
3 or object_path like '%/MATERIALIZED_VIEW'
4* or object_path like '%/REFRESH_GROUP'

no rows selected


つまり、表モードではMaterialized ViewをMaterizlized Viewとしてエクスポート/インポートすることはできないということ!!(?)のようです。

[oracle@catfish ˜]$ expdp users/********@orcl directory=homedir dumpfile=mv2table.dmp logfile=mv2table.log tables=mview_master

Export: Release 12.1.0.2.0 - Production on Sun Apr 9 14:46:27 2017

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

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "USERS"."SYS_EXPORT_TABLE_01": users/********@orcl directory=homedir dumpfile=mv2table.dmp logfile=mv2table.log tables=mview_master
Estimate in progress using BLOCKS method...
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/COMMENT
Processing object type TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
. . exported "USERS"."MVIEW_MASTER" 5.492 KB 2 rows
Master table "USERS"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for USERS.SYS_EXPORT_TABLE_01 is:
/home/oracle/mv2table.dmp
Job "USERS"."SYS_EXPORT_TABLE_01" successfully completed at Sun Apr 9 14:47:09 2017 elapsed 0 00:00:38

同一DB(PDB)の異なるschemaへ表としてインポート(異なるschemaへインポートするのでremap_schamaパラメータをお忘れなく)

[oracle@catfish ˜]$ impdp hr/********@orcl directory=homedir dumpfile=mv2table.dmp logfile=mv2table.log remap_schema=users:hr

Import: Release 12.1.0.2.0 - Production on Sun Apr 9 14:49:56 2017

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

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Master table "HR"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "HR"."SYS_IMPORT_FULL_01": hr/********@orcl directory=homedir dumpfile=mv2table.dmp logfile=mv2table.log remap_schema=users:hr
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "HR"."MVIEW_MASTER" 5.492 KB 2 rows
Processing object type TABLE_EXPORT/TABLE/COMMENT
Processing object type TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Job "HR"."SYS_IMPORT_FULL_01" successfully completed at Sun Apr 9 14:50:19 2017 elapsed 0 00:00:22


表としてインポートされています!

orcl@HR> select object_name,object_type from user_objects where object_name='MVIEW_MASTER';

OBJECT_NAME OBJECT_TYPE
------------------------------ -----------------------
MVIEW_MASTER TABLE

orcl@HR> select job,log_user,last_date,next_date,interval,failures,broken,what from user_jobs;

no rows selected

orcl@HR> select count(1) from mview_master;

COUNT(1)
----------
2


さて、お次、
表モードとは異なり、schemaモードのオブジェクトを定義しているSCHEMA_EXPORT_OBJECTSには、Materialized ViewをMaterialized Viewとしてエクスポート/インポートするために必要な以下のオブジェクト定義が存在します。
ということは、schemaモードではMviewをMviewとして移行することも、MviewをTableとして移行することもできそうな設定になっているようです、

OBJECT_PATH                     COMMENTS
------------------------------- ------------------------------------------------------------
SCHEMA_EXPORT/DB_LINK Private database links in the selected schemas
SCHEMA_EXPORT/TABLE Tables in the selected schemas and their dependent objects
SCHEMA_EXPORT/MATERIALIZED_VIEW Materialized views
SCHEMA_EXPORT/JOB Jobs in the selected schemas
SCHEMA_EXPORT/REFRESH_GROUP Refresh groups in the selected schemas


ということで、schemaモードでも同様の変換が可能かためしてみます。
schemaモードでinclude=TABLEとして表関連オブジェクトのみエクスポート。
schemaモードを選択した場合は、materialized view、job、refresh groupもスコープに入ってしまうので、余分なオブジェクトや定義を取り込まないようにするのがポイント(でした)

[oracle@catfish ˜]$ expdp users/******** directory=homedir dumpfile=test.dmp logfile=testexp.log include=TABLE

Export: Release 12.1.0.2.0 - Production on Wed Apr 5 00:40:17 2017

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

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "USERS"."SYS_EXPORT_SCHEMA_01": users/******** directory=homedir dumpfile=test.dmp logfile=testexp.log include=TABLE
Estimate in progress using BLOCKS method...
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
. . exported "USERS"."MVIEW_MASTER" 5.484 KB 1 rows
Master table "USERS"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for USERS.SYS_EXPORT_SCHEMA_01 is:
/home/oracle/test.dmp
Job "USERS"."SYS_EXPORT_SCHEMA_01" successfully completed at Wed Apr 5 00:40:43 2017 elapsed 0 00:00:25

同一DB(PDB)の異なるschemaへ表としてインポート(異なるschemaへインポートするのでremap_schamaパラメータをお忘れなく)

[oracle@catfish ˜]$ impdp users2/******** directory=homedir dumpfile=test.dmp logfile=testexp.log include=TABLE remap_schema=users:users2

Import: Release 12.1.0.2.0 - Production on Wed Apr 5 00:42:18 2017

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

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Master table "USERS2"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "USERS2"."SYS_IMPORT_FULL_01": users2/******** directory=homedir dumpfile=test.dmp logfile=testexp.log include=TABLE remap_schema=users:users2
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "USERS2"."MVIEW_MASTER" 5.484 KB 1 rows
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Job "USERS2"."SYS_IMPORT_FULL_01" successfully completed at Wed Apr 5 00:42:24 2017 elapsed 0 00:00:05


マスター表からDBリンク経由でCTASするという手もありますが、Materialized ViewではなくTableとして移行する場合、Data Pumpを利用する方法もあるなぁと。
そして、includeパラメータやエクスポートモードには注意しないと、いろいろハマりそうだなぁ、と思ったのでしたw


ということで、schemaモードでもMaterialized ViewをTableとして移行できるよ! めでたしめでたしw (失敗は気づきの母w)

[oracle@catfish ˜]$ sqlplus users2/********

SQL*Plus: Release 12.1.0.2.0 Production on Wed Apr 5 00:42:39 2017

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

Last Successful login time: Wed Apr 05 2017 00:42:18 +09:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

ORCL@USERS2> select object_name,object_type from user_objects where object_name='MVIEW_MASTER';

OBJECT_NAME OBJECT_TYPE
------------------------------ -----------------------
MVIEW_MASTER TABLE

ORCL@USERS2> select * from user_mviews;
no rows selected

ORCL@USERS2> select job,log_user,last_date,next_date,interval,failures,broken,what from user_jobs;

no rows selected

ORCL@USERS2> select * from mview_master;

ID DATA
---------- ----------
1 test1


今日はここまで。


Data Pumpも癖モノだよね〜w その1 - queryパラメーターの解析タイミング

| | コメント (0) | トラックバック (0)

2017年4月 8日 (土)

Data Pumpも癖モノだよね〜w その1 - queryパラメーターの解析タイミング

AWS、MS、Oracle、それぞれのクラウド環境へのデータ移行なんてことも珍しくなくなってきました。
そして移行ツールとしても利用されるData Pump。

でも細かい機能を使おうと調べていると、Data Pump、いろいろ癖があるよなぁ〜。と改めて気づくんですw

ということで、そんな癖もの! Data PumpのFAQっぽいことを備忘録として書いておきますね。(要するに、ハマったこと集w)


 

queryパラメータに記述したwhere句っていつ解析されるかご存知ですか?
expdpコマンドを実行した時点でqueryパラメータのwhere句のシンタックスがチェックされると思う方、手をあげて!

私もそう思ってました、最近までw
あえて書いてるのですから、勘の良いかたなら、ちがうのか! と気づいちゃいますよねw 

そう!ちがうんです!

では、シンタックスエラーのあるqueryパラメータで実行してみますよ。 赤字の部分、where であるべきですが、 while としてあります。パースされればシンタックスエラーとなるはずです!!
いいですか〜〜〜、よ〜〜〜〜く見ててくださいよ〜。みて、みて、みてみてみてみて〜〜〜〜っ

パラメータファイルは以下のとおり

[oracle@crayfish ˜]$ cat query.par
tables=hoge
query=hoge:"while id = 1"


実行してみると、あーら不思議、正常終了してしまいます!

[oracle@crayfish ˜]$ expdp hr/hr@orcl directory=homedir dumpfile=testhr_query45.dmp logfile=testhr_query45.log parfile=query.par

Export: Release 12.1.0.2.0 - Production on Sat Apr 8 00:34:48 2017

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

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "HR"."SYS_EXPORT_TABLE_01": hr/********@orcl directory=homedir dumpfile=testhr_query45.dmp logfile=testhr_query45.log parfile=query.par
Estimate in progress using BLOCKS method...
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
. . exported "HR"."HOGE" 0 KB 0 rows
Master table "HR"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for HR.SYS_EXPORT_TABLE_01 is:
/home/oracle/testhr_query45.dmp
Job "HR"."SYS_EXPORT_TABLE_01" successfully completed at Sat Apr 8 00:35:13 2017 elapsed 0 00:00:24

なぜなのかわかりますか????

queryパラメータでデータを選択する対象の表が空だと、queryパラメータに指定したwhere句はパースされない! 
そもそも取り出すデータが無いので無駄なことはしない!
ということのようです。

ということで、queryパラメータのシンタックスチェックだけを事前に行いたい場合、1行以上のデータが必要でっす!
0件の状態で実行してもqueryパラメータのシンタックスチェックにはならないのでご注意を!!

[oracle@crayfish ˜]$ sqlplus hr/hr@orcl

SQL*Plus: Release 12.1.0.2.0 Production on Sat Apr 8 00:36:29 2017

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

Last Successful login time: Sat Apr 08 2017 00:34:48 +09:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

orcl@HR> insert into hoge values(1,'test');

1 row created.

orcl@HR> commit;

Commit complete.

orcl@HR> select count(1) from hoge;

COUNT(1)
----------
1

空の表に1行だけデータを登録すると! queryパラメターのwhere句が解析されシンタックスエラーとなります!

[oracle@crayfish ˜]$ cat query.par
tables=hoge
query=hoge:"while id = 1"

[oracle@crayfish ˜]$
[oracle@crayfish ˜]$ expdp hr/hr@orcl directory=homedir dumpfile=testhr_query46.dmp logfile=testhr_query46.log parfile=query.par

Export: Release 12.1.0.2.0 - Production on Sat Apr 8 00:37:08 2017

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

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Starting "HR"."SYS_EXPORT_TABLE_01": hr/********@orcl directory=homedir dumpfile=testhr_query46.dmp logfile=testhr_query46.log parfile=query.par
Estimate in progress using BLOCKS method...
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
ORA-31693: Table data object "HR"."HOGE" failed to load/unload and is being skipped due to error:
ORA-00933: SQL command not properly ended
Master table "HR"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for HR.SYS_EXPORT_TABLE_01 is:
/home/oracle/testhr_query46.dmp
Job "HR"."SYS_EXPORT_TABLE_01" completed with 1 error(s) at Sat Apr 8 00:37:34 2017 elapsed 0 00:00:24

ということで本日はここまで。

| | コメント (0) | トラックバック (0)

2017年4月 6日 (木)

複数のApple Watchとペアリングできるんですよ!

開発用途などで、Series 2など複数のApple Watchを持っている方も少なくないと思います。

そして、iPhoneとペリングしないとな〜〜〜にもできないこともご存知かと思います。

でも、でもですねぇ、複数のApple Watchとペアリングできることを知らない方も多いんじゃないかと思う今日この頃w


Apple Watchとのペリングって1つだけしかできないと勘違いしていませんか?

複数の Apple Watch を iPhone につなぐ

できるんですよ! 

Img_1433


| | コメント (0) | トラックバック (0)

2016年12月17日 (土)

スタースキーマを扱う実行計画の特徴

JPOUG Advent Calendar 2016の17日目のエントリです。
昨日は、id:kenken08さんのMySQLのsql_modeにあるORACLEとは - kenken0807_DBメモでした。

第三の柴田さんのネタを見て、急遽内容を変更しました。:)
SQLチューニングと対戦格闘ゲームの類似性について語る。- JPOUG Advent Calendar 2016 Day 15 - - ねら~ITエンジニア雑記


DWH系のスタースキーマを扱う実行計画の特徴を簡単にまとめておきたいと思います。(個人的には、in-memory aggregationが今年のハイライトだったのでw)

※サンプルスキーマ:SHスキーマを利用しています。
Installing Sample Schemas

まず、ハッシュ結合とBloom Filterを利用した実行計画です。面倒な準備もなく、癖も少ないので力技でなんとかする系ではよく見かける実行計画です。
Right-Deep Join + Bloom Filter
Right-Deep Joinが可能なのはHash Joinのみです。 意図的に行う場合は、LEADING/USE_HASH/SWAP_JOIN_INPUTSを利用します。
Right-Deep Join Trees and Star Schema Queries
津島博士のパフォーマンス講座 - 第46回 パーティション・プルーニングとハッシュ結合について

スタースキーマでない結合や、NLJではLeft-Deep Joinとなるのが一般的なので見慣れない実行計画だと思う方もいると思いますが、巨大なファクト表よりサイズの小さいディメンジョン表が常にハッシュ結合のビルド表(外部表)になるように結合順序が入れ替えられています。

ハッシュ結合の実行計画としては理にかなっているのですが、超巨大なファクト表との結合がある場合、Exadataをもってしても倒すことができない敵に出会うこともありますw
弱点といえば弱点ですが、方式上難しいところでもあります。
パラレル度を増加させたとしても太刀打ちできないケースもね。。。。とほほ。

Execution Plan
----------------------------------------------------------
Plan hash value: 2503647845

------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1546 | 137K| 3879 (1)| 00:00:01 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (ORDER) | :TQ10003 | 1546 | 137K| 3879 (1)| 00:00:01 | | | Q1,03 | P->S | QC (ORDER) |
| 3 | SORT GROUP BY | | 1546 | 137K| 3879 (1)| 00:00:01 | | | Q1,03 | PCWP | |
| 4 | PX RECEIVE | | 1546 | 137K| 3879 (1)| 00:00:01 | | | Q1,03 | PCWP | |
| 5 | PX SEND RANGE | :TQ10002 | 1546 | 137K| 3879 (1)| 00:00:01 | | | Q1,02 | P->P | RANGE |
| 6 | HASH GROUP BY | | 1546 | 137K| 3879 (1)| 00:00:01 | | | Q1,02 | PCWP | |
|* 7 | HASH JOIN | | 580K| 50M| 3875 (1)| 00:00:01 | | | Q1,02 | PCWP | |
| 8 | PX RECEIVE | | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,02 | PCWP | |
| 9 | PX SEND BROADCAST | :TQ10000 | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,00 | P->P | BROADCAST |
| 10 | PX BLOCK ITERATOR | | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,00 | PCWC | |
| 11 | TABLE ACCESS INMEMORY FULL | COUNTRIES | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 12 | HASH JOIN | | 580K| 35M| 3872 (1)| 00:00:01 | | | Q1,02 | PCWP | |
| 13 | PX RECEIVE | | 55500 | 541K| 8 (13)| 00:00:01 | | | Q1,02 | PCWP | |
| 14 | PX SEND BROADCAST | :TQ10001 | 55500 | 541K| 8 (13)| 00:00:01 | | | Q1,01 | P->P | BROADCAST |
| 15 | PX BLOCK ITERATOR | | 55500 | 541K| 8 (13)| 00:00:01 | | | Q1,01 | PCWC | |
| 16 | TABLE ACCESS INMEMORY FULL| CUSTOMERS | 55500 | 541K| 8 (13)| 00:00:01 | | | Q1,01 | PCWP | |
|* 17 | HASH JOIN | | 580K| 29M| 3864 (1)| 00:00:01 | | | Q1,02 | PCWP | |
|* 18 | TABLE ACCESS INMEMORY FULL | CHANNELS | 2 | 42 | 2 (0)| 00:00:01 | | | Q1,02 | PCWP | |
|* 19 | HASH JOIN | | 1161K| 36M| 3862 (1)| 00:00:01 | | | Q1,02 | PCWP | |
| 20 | PART JOIN FILTER CREATE | :BF0000 | 1845 | 22140 | 2 (0)| 00:00:01 | | | Q1,02 | PCWP | |
|* 21 | TABLE ACCESS INMEMORY FULL| TIMES | 1845 | 22140 | 2 (0)| 00:00:01 | | | Q1,02 | PCWP | |
| 22 | PX BLOCK ITERATOR | | 3673K| 73M| 3857 (1)| 00:00:01 |:BF0000|:BF0000| Q1,02 | PCWC | |
| 23 | TABLE ACCESS FULL | SALES | 3673K| 73M| 3857 (1)| 00:00:01 |:BF0000|:BF0000| Q1,02 | PCWP | |
------------------------------------------------------------------------------------------------------------------------------------------------

Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 4 because of session
- 1 Sql Plan Directive used for this statement

Star Transformation
巨大なファクト表とディメンジョン表の結合が辛いなら、昔からあるスター変換だ! 
とも思うのですが、スター変換は頑固ものかつ、曲者なのが難点。

頑固さ
ディメンジョン表やファクト表にビットマップ索引や参照整合性制約作成等、利用できるようにするお膳立てができてないと、ピクリとも動きませんw
巨大なファクト表の外部キー列にビットマップ索引を1つ作成するのに、数時間w 複数作成して、さらに、ディメンジョン表との参照整合性制約まで必要なのでまともにやっていると、1日では終わらないことも><
(俺を信じろ、 RELYが利用できるデータの状態であれば楽ではありますが

スター変換の最大の弱点は、ビットマップ索引を利用したROWIDアクセス(以下の実行計画ではId=42の部分)による読み込み件数が多すぎるケースです。性能が伸びなかったり、または、悪化することもあります。
スター変換を利用するかどうかは、ディメンジョン表との結合でファクト表が十分に絞り込めるかにかかっています。

ディメンジョン表との結合キーがビットマップ索引中にあるため、ディメンジョン表とファクト表を結合することなく、ROWIDでファクト表をアクセスして集計することができます。
ファクト表のアクセス量が少ない場合はROWIDアクセスがメリットとなるわけですが、その逆のケースでは、ファクト表はROWIDで1行ごとにアクセスされることになるため、アクセスするファクト表の行数が多くなればなるほど不利になります。

ROWIDによるシングルブロックリードが数十億回繰り返されるとしたら、待機イベントのほとんどが、db file sequential readやcell single block physical read(Exadata)になってしまうことになります。

使いどころを見誤らないようにしたいものです。

Execution Plan
----------------------------------------------------------
Plan hash value: 2513598833

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6490 | 627K| | 5584 (1)| 00:00:01 | | | | | |
| 1 | TEMP TABLE TRANSFORMATION | | | | | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q1,00 | P->S | QC (RAND) |
| 4 | LOAD AS SELECT (TEMP SEGMENT MERGE) | SYS_TEMP_0FD9D662C_336236 | | | | | | | | Q1,00 | PCWP | |
| 5 | PX BLOCK ITERATOR | | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q1,00 | PCWC | |
|* 6 | TABLE ACCESS INMEMORY FULL | TIMES | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 7 | PX COORDINATOR | | | | | | | | | | | |
| 8 | PX SEND QC (ORDER) | :TQ20003 | 6490 | 627K| | 5582 (1)| 00:00:01 | | | Q2,03 | P->S | QC (ORDER) |
| 9 | SORT GROUP BY | | 6490 | 627K| 60M| 5582 (1)| 00:00:01 | | | Q2,03 | PCWP | |
| 10 | PX RECEIVE | | 6490 | 627K| | 5582 (1)| 00:00:01 | | | Q2,03 | PCWP | |
| 11 | PX SEND RANGE | :TQ20002 | 6490 | 627K| | 5582 (1)| 00:00:01 | | | Q2,02 | P->P | RANGE |
| 12 | HASH GROUP BY | | 6490 | 627K| 60M| 5582 (1)| 00:00:01 | | | Q2,02 | PCWP | |
|* 13 | HASH JOIN | | 580K| 54M| | 4334 (1)| 00:00:01 | | | Q2,02 | PCWP | |
| 14 | PX RECEIVE | | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q2,02 | PCWP | |
| 15 | PX SEND BROADCAST | :TQ20000 | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q2,00 | P->P | BROADCAST |
| 16 | PX BLOCK ITERATOR | | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q2,00 | PCWC | |
| 17 | TABLE ACCESS FULL | SYS_TEMP_0FD9D662C_336236 | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q2,00 | PCWP | |
|* 18 | HASH JOIN | | 580K| 48M| | 4332 (1)| 00:00:01 | | | Q2,02 | PCWP | |
|* 19 | TABLE ACCESS INMEMORY FULL | CHANNELS | 2 | 42 | | 2 (0)| 00:00:01 | | | Q2,02 | PCWP | |
|* 20 | HASH JOIN | | 580K| 36M| | 4329 (1)| 00:00:01 | | | Q2,02 | PCWP | |
| 21 | PX RECEIVE | | 55500 | 2005K| | 10 (10)| 00:00:01 | | | Q2,02 | PCWP | |
| 22 | PX SEND BROADCAST | :TQ20001 | 55500 | 2005K| | 10 (10)| 00:00:01 | | | Q2,01 | P->P | BROADCAST |
|* 23 | HASH JOIN | | 55500 | 2005K| | 10 (10)| 00:00:01 | | | Q2,01 | PCWP | |
| 24 | TABLE ACCESS INMEMORY FULL | COUNTRIES | 23 | 621 | | 2 (0)| 00:00:01 | | | Q2,01 | PCWP | |
| 25 | PX BLOCK ITERATOR | | 55500 | 541K| | 8 (13)| 00:00:01 | | | Q2,01 | PCWC | |
| 26 | TABLE ACCESS INMEMORY FULL | CUSTOMERS | 55500 | 541K| | 8 (13)| 00:00:01 | | | Q2,01 | PCWP | |
| 27 | VIEW | VW_ST_A44449E3 | 580K| 16M| | 4319 (1)| 00:00:01 | | | Q2,02 | PCWP | |
| 28 | NESTED LOOPS | | 580K| 28M| | 4315 (1)| 00:00:01 | | | Q2,02 | PCWP | |
| 29 | PX PARTITION RANGE SUBQUERY | | 580K| 12M| | 15 (14)| 00:00:01 |KEY(SQ)|KEY(SQ)| Q2,02 | PCWC | |
| 30 | BITMAP CONVERSION TO ROWIDS | | 580K| 12M| | 15 (14)| 00:00:01 | | | Q2,02 | PCWP | |
| 31 | BITMAP AND | | | | | | | | | Q2,02 | PCWP | |
| 32 | BITMAP MERGE | | | | | | | | | Q2,02 | PCWP | |
| 33 | BITMAP KEY ITERATION | | | | | | | | | Q2,02 | PCWP | |
| 34 | BUFFER SORT | | | | | | | | | Q2,02 | PCWP | |
|* 35 | TABLE ACCESS INMEMORY FULL| CHANNELS | 2 | 26 | | 2 (0)| 00:00:01 | | | Q2,02 | PCWP | |
|* 36 | BITMAP INDEX RANGE SCAN | SALES_CHANNEL_BIX | | | | | |KEY(SQ)|KEY(SQ)| Q2,02 | PCWP | |
| 37 | BITMAP MERGE | | | | | | | | | Q2,02 | PCWP | |
| 38 | BITMAP KEY ITERATION | | | | | | | | | Q2,02 | PCWP | |
| 39 | BUFFER SORT | | | | | | | | | Q2,02 | PCWP | |
| 40 | TABLE ACCESS FULL | SYS_TEMP_0FD9D662C_336236 | 1845 | 14760 | | 2 (0)| 00:00:01 | | | Q2,02 | PCWP | |
|* 41 | BITMAP INDEX RANGE SCAN | SALES_TIME_BIX | | | | | |KEY(SQ)|KEY(SQ)| Q2,02 | PCWP | |
| 42 | TABLE ACCESS BY USER ROWID | SALES | 1 | 29 | | 4304 (1)| 00:00:01 | ROWID | ROWID | Q2,02 | PCWP | |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 4 because of session
- star transformation used for this statement
- 1 Sql Plan Directive used for this statement

長い前置きでしたが、やっと真打の登場です!
in-memory aggregationとして解説されていることが多いのですが、実行計画を眺めている人間からすると機能名よりvector transformationの方がイメージしやすいので、以下、Vector Tranformation/ベクター変換とします。

Vector Transformation
スター変換同様に、巨大なファクト表とディメンジョン表を直接結合しない点や、パラレル実行時も他の実行計画ではみられない(誤解をおそれずにいうと、全力投球に近いかもw)特徴があります。
索引や参照整合性制約などの作成は不要。
in-memory database関連の機能ではあるのですが、全ての表がinmemory化されていなくても発動させることができます。(inmemory_sizeパラメータの設定は必要となる模様。後述)
最強の力を発揮するのは、全てがinmemoryで動作した場合であることは間違いないわけですが、巨大過ぎるファクト表がinmemory化できるほどメモリが潤沢にあるかというと、そうじゃなかっりしますし。


ベクター変換の動きを簡単に説明すると以下のような感じです。
ディメンジョン表を元に集計結果相当の構造体(in-memory accumulatorと呼ばれる多次元構造体)をメモリ上に構築後、ファクト表を読みながらin-memory accumulator上で集計します!!!(画期的!)
ハッシュ結合が全くなくなるわけではないですが、集計終了後に読み替え目的で少量(この部分が少量じゃないと辛くなるはずなのでよーく確認しておくことをおすすめします)はのハッシュ結合が行われるだけなので、冒頭で紹介した巨大なファクト表とディメンジョン表の結合によるCPUネック部分を華麗に回避していることがわかります。
Right-Deep Join+Bloom Filterで苦しい状況になったら、in-memory aggregationのことを思い出してあげてください。

助けてくれるかもしれません。



Oracle Database In-Memory: In-Memory Aggregation - Oracle White Paper JANUARY 2015


Execution Plan
----------------------------------------------------------
Plan hash value: 3211261687

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 483 | 60858 | | 3840 (1)| 00:00:01 | | | | | |
| 1 | TEMP TABLE TRANSFORMATION | | | | | | | | | | | |
| 2 | LOAD AS SELECT | SYS_TEMP_0FD9D6630_336236 | | | | | | | | | | |
| 3 | PX COORDINATOR | | | | | | | | | | | |
| 4 | PX SEND QC (RANDOM) | :TQ10001 | 21 | 336 | | 3 (34)| 00:00:01 | | | Q1,01 | P->S | QC (RAND) |
| 5 | BUFFER SORT | | 21 | 336 | | 3 (34)| 00:00:01 | | | Q1,01 | PCWP | |
| 6 | VECTOR GROUP BY | | 21 | 336 | | 3 (34)| 00:00:01 | | | Q1,01 | PCWP | |
| 7 | KEY VECTOR CREATE BUFFERED | :KV0000 | 1845 | 29520 | | 3 (34)| 00:00:01 | | | Q1,01 | PCWP | |
| 8 | PX RECEIVE | | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q1,01 | PCWP | |
| 9 | PX SEND HASH | :TQ10000 | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q1,00 | P->P | HASH |
| 10 | PX BLOCK ITERATOR | | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q1,00 | PCWC | |
|* 11 | TABLE ACCESS INMEMORY FULL | TIMES | 1845 | 22140 | | 2 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 12 | LOAD AS SELECT | SYS_TEMP_0FD9D6631_336236 | | | | | | | | | | |
| 13 | PX COORDINATOR | | | | | | | | | | | |
| 14 | PX SEND QC (RANDOM) | :TQ20001 | 23 | 851 | | 12 (25)| 00:00:01 | | | Q2,01 | P->S | QC (RAND) |
| 15 | HASH GROUP BY | | 23 | 851 | 2624K| 12 (25)| 00:00:01 | | | Q2,01 | PCWP | |
| 16 | KEY VECTOR CREATE BUFFERED | :KV0001 | | | | | | | | Q2,01 | PCWP | |
| 17 | PX RECEIVE | | 55500 | 2005K| | 10 (10)| 00:00:01 | | | Q2,01 | PCWP | |
| 18 | PX SEND HASH | :TQ20000 | 55500 | 2005K| | 10 (10)| 00:00:01 | | | Q2,00 | P->P | HASH |
|* 19 | HASH JOIN | | 55500 | 2005K| | 10 (10)| 00:00:01 | | | Q2,00 | PCWP | |
| 20 | TABLE ACCESS INMEMORY FULL | COUNTRIES | 23 | 621 | | 2 (0)| 00:00:01 | | | Q2,00 | PCWP | |
| 21 | PX BLOCK ITERATOR | | 55500 | 541K| | 8 (13)| 00:00:01 | | | Q2,00 | PCWC | |
| 22 | TABLE ACCESS INMEMORY FULL | CUSTOMERS | 55500 | 541K| | 8 (13)| 00:00:01 | | | Q2,00 | PCWP | |
| 23 | LOAD AS SELECT | SYS_TEMP_0FD9D6632_336236 | | | | | | | | | | |
| 24 | PX COORDINATOR | | | | | | | | | | | |
| 25 | PX SEND QC (RANDOM) | :TQ30001 | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | P->S | QC (RAND) |
| 26 | BUFFER SORT | | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | PCWP | |
| 27 | VECTOR GROUP BY | | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | PCWP | |
| 28 | KEY VECTOR CREATE BUFFERED | :KV0002 | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | PCWP | |
| 29 | PX RECEIVE | | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,01 | PCWP | |
| 30 | PX SEND HASH | :TQ30000 | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,00 | P->P | HASH |
| 31 | PX BLOCK ITERATOR | | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,00 | PCWC | |
|* 32 | TABLE ACCESS INMEMORY FULL | CHANNELS | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,00 | PCWP | |
| 33 | PX COORDINATOR | | | | | | | | | | | |
| 34 | PX SEND QC (ORDER) | :TQ40003 | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,03 | P->S | QC (ORDER) |
| 35 | SORT GROUP BY | | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,03 | PCWP | |
| 36 | PX RECEIVE | | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,03 | PCWP | |
| 37 | PX SEND RANGE | :TQ40002 | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,02 | P->P | RANGE |
| 38 | HASH GROUP BY | | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,02 | PCWP | |
|* 39 | HASH JOIN | | 483 | 60858 | | 3820 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 40 | PX RECEIVE | | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,02 | PCWP | |
| 41 | PX SEND BROADCAST | :TQ40000 | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,00 | P->P | BROADCAST |
| 42 | PX BLOCK ITERATOR | | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,00 | PCWC | |
| 43 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6631_336236 | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,00 | PCWP | |
|* 44 | HASH JOIN | | 483 | 42987 | | 3818 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 45 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6630_336236 | 21 | 252 | | 2 (0)| 00:00:01 | | | Q4,02 | PCWP | |
|* 46 | HASH JOIN | | 483 | 37191 | | 3816 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 47 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6632_336236 | 2 | 42 | | 2 (0)| 00:00:01 | | | Q4,02 | PCWP | |
| 48 | VIEW | VW_VT_AF0F4755 | 483 | 27048 | | 3814 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 49 | HASH GROUP BY | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 50 | PX RECEIVE | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 51 | PX SEND HASH | :TQ40001 | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,01 | P->P | HASH |
| 52 | VECTOR GROUP BY | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,01 | PCWP | |
| 53 | HASH GROUP BY | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,01 | PCWP | |
| 54 | KEY VECTOR USE | :KV0001 | 580K| 18M| | 3811 (1)| 00:00:01 | | | Q4,01 | PCWC | |
| 55 | KEY VECTOR USE | :KV0002 | 580K| 16M| | 3811 (1)| 00:00:01 | | | Q4,01 | PCWC | |
| 56 | KEY VECTOR USE | :KV0000 | 1161K| 27M| | 3811 (1)| 00:00:01 | | | Q4,01 | PCWC | |
| 57 | PX BLOCK ITERATOR | | 3673K| 73M| | 3811 (1)| 00:00:01 |KEY(SQ)|KEY(SQ)| Q4,01 | PCWC | |
|* 58 | TABLE ACCESS FULL| SALES | 3673K| 73M| | 3811 (1)| 00:00:01 |KEY(SQ)|KEY(SQ)| Q4,01 | PCWP | |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 4 because of session
- 2 Sql Plan Directives used for this statement
- vector transformation used for this statement

超絶必殺技にも思えるベクター変換ですが、癖がないわけではありません。(大技につきものの反動というか、なんというかw)

癖 その1)
パラレルクエリー時に割り当てられるサーバープロセスが多く、割り当てられるサーバー数は、KEY VECTORの作成数により大きく変化します。
以下、SQL MONITORのParallel Execution Detailsセクション(抜粋)の比較

並列度は同じでも割り当てるサーバー数はこんなに違う!
VECTOR TRANSFORMATION
KEY VECTORが3つ作成されるベクター変換の場合
(SQL MONITORのParallel Execution Detailsセクションより抜粋)
Parallel Execution Details (DOP=4 , Servers Allocated=32)

KEY VECTORが2つ作成されるベクター変換の場合
Parallel Execution Details (DOP=4 , Servers Allocated=24)

STAR TRANSFORMATION
Parallel Execution Details (DOP=4 , Servers Allocated=12)

Hash Joinのみ
Parallel Execution Details (DOP=4 , Servers Allocated=8)


癖 その2)
スター変換を発動させるための索引作成や、制約作成の煩雑さは無く、全ての表がinmemoryになっていなくても発動させることはできるのですが、発動させるためは、最低限設定しなればならない(ほんと? 不具合?)パラメータが存在します。(

inmemory化する表は無くとも、inmemory_size=100m(設定可能な最小サイズ)に設定しないとVECTOR_TRANSFORMヒントが無視されるという点です。
この制限?を記載しているマニュアルなどは探し出せていないのですが、どこかに記載されているのでしょうか?(いまのところ見つけることができず。。。教えていただけるとうれしいです)


では、最後に、inmemory_size初期化パラメータの設定有無による変化をみてみましょう。

inmemory_size初期化パラメータが設定されている場合にはVECTOR_TRANSFORMヒントでベクター変換を強制できています。

10:36:23 orcl12c@SYSTEM> show parameter inmemory

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
inmemory_clause_default string
inmemory_force string DEFAULT
inmemory_max_populate_servers integer 3
inmemory_query string ENABLE
inmemory_size big integer 512M
inmemory_trickle_repopulate_servers_ integer 1
percent
optimizer_inmemory_aware boolean TRUE


10:37:04 ORCL@SH> set autot trace exp stat
10:56:18 ORCL@SH> @sample3_2

135 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3211261687

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 483 | 60858 | | 3967 (1)| 00:00:01 | | | | | |
| 1 | TEMP TABLE TRANSFORMATION | | | | | | | | | | | |
| 2 | LOAD AS SELECT | SYS_TEMP_0FD9D6609_33B383 | | | | | | | | | | |
| 3 | PX COORDINATOR | | | | | | | | | | | |
| 4 | PX SEND QC (RANDOM) | :TQ10001 | 21 | 336 | | 20 (5)| 00:00:01 | | | Q1,01 | P->S | QC (RAND) |
| 5 | BUFFER SORT | | 21 | 336 | | 20 (5)| 00:00:01 | | | Q1,01 | PCWP | |
| 6 | VECTOR GROUP BY | | 21 | 336 | | 20 (5)| 00:00:01 | | | Q1,01 | PCWP | |
| 7 | KEY VECTOR CREATE BUFFERED | :KV0000 | 1845 | 29520 | | 20 (5)| 00:00:01 | | | Q1,01 | PCWP | |
| 8 | PX RECEIVE | | 1845 | 22140 | | 19 (0)| 00:00:01 | | | Q1,01 | PCWP | |
| 9 | PX SEND HASH | :TQ10000 | 1845 | 22140 | | 19 (0)| 00:00:01 | | | Q1,00 | P->P | HASH |
| 10 | PX BLOCK ITERATOR | | 1845 | 22140 | | 19 (0)| 00:00:01 | | | Q1,00 | PCWC | |
|* 11 | TABLE ACCESS FULL | TIMES | 1845 | 22140 | | 19 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 12 | LOAD AS SELECT | SYS_TEMP_0FD9D660A_33B383 | | | | | | | | | | |
| 13 | PX COORDINATOR | | | | | | | | | | | |
| 14 | PX SEND QC (RANDOM) | :TQ20001 | 23 | 851 | | 122 (3)| 00:00:01 | | | Q2,01 | P->S | QC (RAND) |
| 15 | HASH GROUP BY | | 23 | 851 | 2624K| 122 (3)| 00:00:01 | | | Q2,01 | PCWP | |
| 16 | KEY VECTOR CREATE BUFFERED | :KV0001 | | | | | | | | Q2,01 | PCWP | |
| 17 | PX RECEIVE | | 55500 | 2005K| | 119 (0)| 00:00:01 | | | Q2,01 | PCWP | |
| 18 | PX SEND HASH | :TQ20000 | 55500 | 2005K| | 119 (0)| 00:00:01 | | | Q2,00 | P->P | HASH |
|* 19 | HASH JOIN | | 55500 | 2005K| | 119 (0)| 00:00:01 | | | Q2,00 | PCWP | |
| 20 | TABLE ACCESS FULL | COUNTRIES | 23 | 621 | | 2 (0)| 00:00:01 | | | Q2,00 | PCWP | |
| 21 | PX BLOCK ITERATOR | | 55500 | 541K| | 117 (0)| 00:00:01 | | | Q2,00 | PCWC | |
| 22 | TABLE ACCESS FULL | CUSTOMERS | 55500 | 541K| | 117 (0)| 00:00:01 | | | Q2,00 | PCWP | |
| 23 | LOAD AS SELECT | SYS_TEMP_0FD9D660B_33B383 | | | | | | | | | | |
| 24 | PX COORDINATOR | | | | | | | | | | | |
| 25 | PX SEND QC (RANDOM) | :TQ30001 | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | P->S | QC (RAND) |
| 26 | BUFFER SORT | | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | PCWP | |
| 27 | VECTOR GROUP BY | | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | PCWP | |
| 28 | KEY VECTOR CREATE BUFFERED | :KV0002 | 2 | 50 | | 3 (34)| 00:00:01 | | | Q3,01 | PCWP | |
| 29 | PX RECEIVE | | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,01 | PCWP | |
| 30 | PX SEND HASH | :TQ30000 | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,00 | P->P | HASH |
| 31 | PX BLOCK ITERATOR | | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,00 | PCWC | |
|* 32 | TABLE ACCESS FULL | CHANNELS | 2 | 42 | | 2 (0)| 00:00:01 | | | Q3,00 | PCWP | |
| 33 | PX COORDINATOR | | | | | | | | | | | |
| 34 | PX SEND QC (ORDER) | :TQ40003 | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,03 | P->S | QC (ORDER) |
| 35 | SORT GROUP BY | | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,03 | PCWP | |
| 36 | PX RECEIVE | | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,03 | PCWP | |
| 37 | PX SEND RANGE | :TQ40002 | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,02 | P->P | RANGE |
| 38 | HASH GROUP BY | | 483 | 60858 | | 3821 (1)| 00:00:01 | | | Q4,02 | PCWP | |
|* 39 | HASH JOIN | | 483 | 60858 | | 3820 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 40 | PX RECEIVE | | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,02 | PCWP | |
| 41 | PX SEND BROADCAST | :TQ40000 | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,00 | P->P | BROADCAST |
| 42 | PX BLOCK ITERATOR | | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,00 | PCWC | |
| 43 | TABLE ACCESS FULL | SYS_TEMP_0FD9D660A_33B383 | 23 | 851 | | 2 (0)| 00:00:01 | | | Q4,00 | PCWP | |
|* 44 | HASH JOIN | | 483 | 42987 | | 3818 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 45 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6609_33B383 | 21 | 252 | | 2 (0)| 00:00:01 | | | Q4,02 | PCWP | |
|* 46 | HASH JOIN | | 483 | 37191 | | 3816 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 47 | TABLE ACCESS FULL | SYS_TEMP_0FD9D660B_33B383 | 2 | 42 | | 2 (0)| 00:00:01 | | | Q4,02 | PCWP | |
| 48 | VIEW | VW_VT_AF0F4755 | 483 | 27048 | | 3814 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 49 | HASH GROUP BY | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 50 | PX RECEIVE | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,02 | PCWP | |
| 51 | PX SEND HASH | :TQ40001 | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,01 | P->P | HASH |
| 52 | VECTOR GROUP BY | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,01 | PCWP | |
| 53 | HASH GROUP BY | | 483 | 15939 | | 3814 (1)| 00:00:01 | | | Q4,01 | PCWP | |
| 54 | KEY VECTOR USE | :KV0001 | 580K| 18M| | 3811 (1)| 00:00:01 | | | Q4,01 | PCWC | |
| 55 | KEY VECTOR USE | :KV0002 | 580K| 16M| | 3811 (1)| 00:00:01 | | | Q4,01 | PCWC | |
| 56 | KEY VECTOR USE | :KV0000 | 1161K| 27M| | 3811 (1)| 00:00:01 | | | Q4,01 | PCWC | |
| 57 | PX BLOCK ITERATOR | | 3673K| 73M| | 3811 (1)| 00:00:01 |KEY(SQ)|KEY(SQ)| Q4,01 | PCWC | |
|* 58 | TABLE ACCESS FULL| SALES | 3673K| 73M| | 3811 (1)| 00:00:01 |KEY(SQ)|KEY(SQ)| Q4,01 | PCWP | |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

11 - filter("T"."FISCAL_YEAR"=2000 OR "T"."FISCAL_YEAR"=2005 OR "T"."FISCAL_YEAR"=2010 OR "T"."FISCAL_YEAR"=2015 OR "T"."FISCAL_YEAR"=2016)
19 - access("C"."COUNTRY_ID"="R"."COUNTRY_ID")
32 - filter("CH"."CHANNEL_DESC"='Internet' OR "CH"."CHANNEL_DESC"='Partners')
39 - access("ITEM_13"=INTERNAL_FUNCTION("C0") AND "ITEM_14"="C4")
44 - access("ITEM_17"=INTERNAL_FUNCTION("C0") AND "ITEM_18"="C2")
46 - access("ITEM_15"=INTERNAL_FUNCTION("C0") AND "ITEM_16"="C2")
58 - filter(SYS_OP_KEY_VECTOR_FILTER("S"."TIME_ID",:KV0000) AND SYS_OP_KEY_VECTOR_FILTER("S"."CHANNEL_ID",:KV0002))

Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 4 because of session
- 2 Sql Plan Directives used for this statement
- vector transformation used for this statement

inmemory_size初期化パラメータを0にし、同一SQL文を実行すると。。。。なんということでしょう。ベクター変換は発動しません!

10:46:22 orcl12c@SYSTEM> show parameter inmemory

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
inmemory_clause_default string
inmemory_force string DEFAULT
inmemory_max_populate_servers integer 0
inmemory_query string ENABLE
inmemory_size big integer 0
inmemory_trickle_repopulate_servers_ integer 1
percent
optimizer_inmemory_aware boolean TRUE


10:47:56 ORCL@SH> @sample3_2

135 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 2503647845

--------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1546 | 137K| 4006 (1)| 00:00:01 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (ORDER) | :TQ10003 | 1546 | 137K| 4006 (1)| 00:00:01 | | | Q1,03 | P->S | QC (ORDER) |
| 3 | SORT GROUP BY | | 1546 | 137K| 4006 (1)| 00:00:01 | | | Q1,03 | PCWP | |
| 4 | PX RECEIVE | | 1546 | 137K| 4006 (1)| 00:00:01 | | | Q1,03 | PCWP | |
| 5 | PX SEND RANGE | :TQ10002 | 1546 | 137K| 4006 (1)| 00:00:01 | | | Q1,02 | P->P | RANGE |
| 6 | HASH GROUP BY | | 1546 | 137K| 4006 (1)| 00:00:01 | | | Q1,02 | PCWP | |
|* 7 | HASH JOIN | | 580K| 50M| 4002 (1)| 00:00:01 | | | Q1,02 | PCWP | |
| 8 | PX RECEIVE | | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,02 | PCWP | |
| 9 | PX SEND BROADCAST | :TQ10000 | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,00 | P->P | BROADCAST |
| 10 | PX BLOCK ITERATOR | | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,00 | PCWC | |
| 11 | TABLE ACCESS FULL | COUNTRIES | 23 | 621 | 2 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 12 | HASH JOIN | | 580K| 35M| 3999 (1)| 00:00:01 | | | Q1,02 | PCWP | |
| 13 | PX RECEIVE | | 55500 | 541K| 117 (0)| 00:00:01 | | | Q1,02 | PCWP | |
| 14 | PX SEND BROADCAST | :TQ10001 | 55500 | 541K| 117 (0)| 00:00:01 | | | Q1,01 | P->P | BROADCAST |
| 15 | PX BLOCK ITERATOR | | 55500 | 541K| 117 (0)| 00:00:01 | | | Q1,01 | PCWC | |
| 16 | TABLE ACCESS FULL | CUSTOMERS | 55500 | 541K| 117 (0)| 00:00:01 | | | Q1,01 | PCWP | |
|* 17 | HASH JOIN | | 580K| 29M| 3882 (1)| 00:00:01 | | | Q1,02 | PCWP | |
|* 18 | TABLE ACCESS FULL | CHANNELS | 2 | 42 | 2 (0)| 00:00:01 | | | Q1,02 | PCWP | |
|* 19 | HASH JOIN | | 1161K| 36M| 3879 (1)| 00:00:01 | | | Q1,02 | PCWP | |
| 20 | PART JOIN FILTER CREATE| :BF0000 | 1845 | 22140 | 19 (0)| 00:00:01 | | | Q1,02 | PCWP | |
|* 21 | TABLE ACCESS FULL | TIMES | 1845 | 22140 | 19 (0)| 00:00:01 | | | Q1,02 | PCWP | |
| 22 | PX BLOCK ITERATOR | | 3673K| 73M| 3857 (1)| 00:00:01 |:BF0000|:BF0000| Q1,02 | PCWC | |
| 23 | TABLE ACCESS FULL | SALES | 3673K| 73M| 3857 (1)| 00:00:01 |:BF0000|:BF0000| Q1,02 | PCWP | |
--------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

7 - access("C"."COUNTRY_ID"="R"."COUNTRY_ID")
12 - access("S"."CUST_ID"="C"."CUST_ID")
17 - access("S"."CHANNEL_ID"="CH"."CHANNEL_ID")
18 - filter("CH"."CHANNEL_DESC"='Internet' OR "CH"."CHANNEL_DESC"='Partners')
19 - access("S"."TIME_ID"="T"."TIME_ID")
21 - filter("T"."FISCAL_YEAR"=2000 OR "T"."FISCAL_YEAR"=2005 OR "T"."FISCAL_YEAR"=2010 OR "T"."FISCAL_YEAR"=2015 OR
"T"."FISCAL_YEAR"=2016)

Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 4 because of session
- 1 Sql Plan Directive used for this statement

参考
Database Virtual Box Appliance / Virtual Machine
Installing Sample Schemas
Getting started with Oracle Database In-Memory Part V - Aggregation
津島博士のパフォーマンス講座 - 第54回 Oracle Database In-Memoryについて(2)

利用したSQL
sample1_2.sql
Right-Deep Join (Right-Deep Treeにならない場合には SWAP_JOIN_INPUTSで制御する必要がありますが、SHスキーマでオプティマイザ統計が取得されているのであれば不要.今回の例ではSWAP_JOIN_INPUTSは利用していませんが、オプティマイザは判断を誤るようであれば利用したほうがよいと思います。)

SELECT	
/*+
MONITOR
LEADING(r sum)
USE_HASH(r sum)
*/
sum.fiscal_year
, r.country_name
, sum.channel_class
, sum.sales_amount
FROM
(
SELECT
t.fiscal_year
, c.country_id
, ch.channel_class
, SUM(s.amount_sold) sales_amount
FROM
sales s
, times t
, customers c
, channels ch
WHERE
s.time_id = t.time_id
AND s.cust_id = c.cust_id
AND s.channel_id = ch.channel_id
AND ch.channel_desc in ('Internet','Partners')
AND t.fiscal_year IN (
2000, 2005, 2010, 2015, 2016
)
GROUP BY
ch.channel_class
, c.country_id
, t.fiscal_year
) sum
, countries r
WHERE
sum.country_id = r.country_id
ORDER BY
sum.fiscal_year
, r.country_name
, sum.channel_class
/

sample2_2.sql
スター変換ヒントが必要です。スター変換はデフォルトでOFFに設定されています。
SHスキーマはスタースキーマかつ、スター変換をすぐに試せる環境(ファクト表の外部キーのビットマップ索引やデョメンジョン表への参照整合性制約等)になっています。

SELECT	
/*+
MONITOR
LEADING(r sum)
USE_HASH(r sum)
*/
sum.fiscal_year
, r.country_name
, sum.channel_class
, sum.sales_amount
FROM
(
SELECT
/*+
STAR_TRANSFORMATION
*/
t.fiscal_year
, c.country_id
, ch.channel_class
, SUM(s.amount_sold) sales_amount
FROM
sales s
, times t
, customers c
, channels ch
WHERE
s.time_id = t.time_id
AND s.cust_id = c.cust_id
AND s.channel_id = ch.channel_id
AND ch.channel_desc in ('Internet','Partners')
AND t.fiscal_year IN (
2000, 2005, 2010, 2015, 2016
)
GROUP BY
ch.channel_class
, c.country_id
, t.fiscal_year
) sum
, countries r
WHERE
sum.country_id = r.country_id
ORDER BY
sum.fiscal_year
, r.country_name
, sum.channel_class
/

sample3_2.sql
ベクター変換の例です。ベクター変換のヒントは数種類(ファクト表を記述場合、ディメンジョン表を記述場合)あります。(詳細はv$sql_hintを参照のこと)

SELECT	
/*+
MONITOR
LEADING(r sum)
USE_HASH(r sum)
*/
sum.fiscal_year
, r.country_name
, sum.channel_class
, sum.sales_amount
FROM
(
SELECT
/*+
VECTOR_TRANSFORM
*/
t.fiscal_year
, c.country_id
, ch.channel_class
, SUM(s.amount_sold) sales_amount
FROM
sales s
, times t
, customers c
, channels ch
WHERE
s.time_id = t.time_id
AND s.cust_id = c.cust_id
AND s.channel_id = ch.channel_id
AND ch.channel_desc in ('Internet','Partners')
AND t.fiscal_year IN (
2000, 2005, 2010, 2015, 2016
)
GROUP BY
ch.channel_class
, c.country_id
, t.fiscal_year
) sum
, countries r
WHERE
sum.country_id = r.country_id
ORDER BY
sum.fiscal_year
, r.country_name
, sum.channel_class
/


明日は、@yoshikawさんです! お楽しみに!


俺のターンおわたー!:)

| | コメント (0) | トラックバック (0)

2016年12月 3日 (土)

macOS : カレンダーへのスパム参加通知をなんとかする方法を考えてみた

最近多くなってきているスパムメールを利用したカレンダーへのスパム参加通知。
はっきりいってうざいです。

https://discussionsjapan.apple.com/thread/10180695

https://discussionsjapan.apple.com/thread/10179171

https://discussions.apple.com/message/30890223#30890223


Spam iCloud Calendar Invitations


メールアドレス変えるという方法もあるけど、変えない対処方法を考えてみました。
Appleさん根本的な対策考えてくれるといいけど。


私が今試している方法は、簡単に言うと、メールの”スパムフォルダ振り分け”に近いのですが、スパムな参加通知を振り分けられないので、

デフォルトカレンダーをスパム参加通知用にしちゃうという

方法です。

通常の参加通知は、個別にカレンダーを作って参加依頼時や予定を入れる時にカレンダー指定で振り分けてもらってます。(想像しやすいカレンダー名にしてるとそれもねらわれるかも。。。)

(性悪説的な対応しか、いまのところできないのが辛いが)


いま試している方法は次のとおり。

20161130_214621

最初に新規カレンダーを作ります。
複数のアカウントを設定している場合は、サブメニューでどのアカウントにカレンダーを作成するかも選択できます。

20161130_214650


カレンダーのチェックボックスをオフにしておきます。
オフしたカレンダーのイベントは表示されなくなります!

20161130_214709

この例ではカレンダー名をspamとしていますが他と区別できればなんでもいかと。

20161130_214721

ついでに色もブラックに変更

20161203_141109

20161130_214746

「カレンダー」→ポップアップメニュー→「情報をみる」

20161203_142148

「通知を無視」をチェック

20161130_214758


「メニュー」→「カレンダー」→「環境設定...」
作成したカレンダーをデフォルトにします。

20161130_214841

20161130_214907

これでスパム通知用デフォルトカレンダーのできあがり、表示もされないし。
ある程度、スパム通知たまったらフォーラムでのディスカッションにもあるように、カレンダーごと、「通知しないで削除」すればイベントごとの対処は不要なので、楽になるかなぁ〜と。

ただいま試行中。

20161203_134018


| | コメント (0) | トラックバック (0)

2016年11月19日 (土)

macOS SierraのiMovie10.1.3がクラッシュしまくる時の対処 / FAQ

まあ、OSアップグレードとかiMovieのアップグレードとかではありがちなのですが....
キャッシュ系かとおもったら違ったので、自分メモ


Why does iMovie 10.1.3 always crashes right after starting?

上記、スレにある対処法で一発解決しまっす。

lampeye:˜ lempeyes$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.12.1
BuildVersion: 16B2555
lampeye:˜ lempeyes$
lampeye:˜ lempeyes$
lampeye:˜ lempeyes$
lampeye:˜ lampeyes$ /usr/sbin/system_profiler SPApplicationsDataType | grep iMovie -A 2 | grep -E 'Version|iMovie'
iMovie:
Version: 10.1.3
Location: /Applications/iMovie.app
lampeye:˜ lempeyes$
lampeye:˜ lempeyes$
lampeye:˜ lempeyes$ ll
total 24
drwx------@ 12 lempeyes staff 408B 11 19 12:04 Dropbox
drwx------+ 21 lempeyes staff 714B 11 19 00:50 Downloads

・・・中略・・・

-rw------- 1 lempeyes staff 3B 1 22 2011 dead.letter
drwxr-xr-x 10 lempeyes staff 340B 12 19 2007 Image Kit Browser
drwxr-xr-x 10 lempeyes staff 340B 12 19 2007 Image Browser
lampeye:˜ lempeyes$
lampeye:˜ lempeyes$
lampeye:˜ lempeyes$ cd Library/Containers/
lampeye:Containers lempeyes$
lampeye:Containers lempeyes$
lampeye:Containers lempeyes$ ls -l | grep iMovie*
drwx------ 4 lempeyes staff 136 10 26 22:51 com.apple.iMovieApp
lampeye:Containers lempeyes$
lampeye:Containers lempeyes$
lampeye:Containers lempeyes$ rm -rf com.apple.iMovieApp
lampeye:Containers lempeyes$
lampeye:Containers lempeyes$ ls -l | grep iMovie*
lampeye:Containers lempeyes$

| | コメント (0) | トラックバック (0)

2016年9月24日 (土)

VirtualBoxとSIMD

Previously on Mac De Oracle
SIMDのメモをあれこれ貼り付けただけでしたが、実は今回のことを調べてる次いでに見つけたものだったんですよ。



OracleもSIMDを使う操作が多くなりつつあるようなのでどうなんだろというわけで、今回もメモです。

元ネタは以下のエントリ

VirtualBoxゲストでSIMD命令: DB In-Memory
https://blogs.oracle.com/LetTheSunShineIn/entry/virtualboxゲストでsimd命令_db_in_memory

上記は約2年前の記事で現在のVirtualBoxでは、SSE4.1/SSE4.2は有効化されています。
以下ドキュメントを参照のこと。

9.27. Experimental support for passing through SSE4.1 / SSE4.2 instructions
https://www.virtualbox.org/manual/ch09.html#sse412passthrough


ただ、AVXはどうなのか書かれてはいないのでどうなってんのかな〜とか、ググってたら

Ticket #14427 (new defect)
https://www.virtualbox.org/ticket/14427#comment:3
こんな記事を見つけたのであー有効になってるよねーということで、うちの環境での確認

確認に利用したVirtualBoxは現時点の最新版です。

MacBook:˜ lampeyes$ VBoxManage -version
5.1.6r110634
MacBook:˜ lampeyes$


うちのMacファミリーでは最古参w (そろそろなんとか新しいのにしたいなぁ〜w)
古いCPUだけど、マニュアル通り、SSE4.1/4.2はguestでも有効化されていました。おし!

MacPro:˜ lampeyes$ /usr/sbin/system_profiler SPHardwareDataType | grep -E 'Model|Processor|Core|Cache'
Model Name: Mac Pro
Model Identifier: MacPro5,1
Processor Name: 6-Core Intel Xeon
Processor Speed: 2.4 GHz
Number of Processors: 2
Total Number of Cores: 12
L2 Cache (per Core): 256 KB
L3 Cache (per Processor): 12 MB
Processor Interconnect Speed: 5.86 GT/s
MacPro:˜ lampeyes$
MacPro:˜ lampeyes$ grep -E 'Mnemonic|SSE4|AVX' '/Users/lampeyes/VirtualBox VMs/Linux Group/OralceLinux (Oracle12c R1)/Logs/VBox.log'
00:00:02.472827 Mnemonic - Description = guest (host)
00:00:02.472916 SSE4_1 - SSE4_1 support = 1 (1)
00:00:02.472919 SSE4_2 - SSE4_2 support = 1 (1)
00:00:02.472934 AVX - AVX support = 0 (0)
00:00:02.472942 Mnemonic - Description = guest (host)
00:00:02.472951 AVX2 - Advanced Vector Extensions 2 = 0 (0)
00:00:02.472968 AVX512F - AVX512 Foundation instructions = 0 (0)
00:00:02.472978 AVX512PF - AVX512 Prefetch instructions = 0 (0)
00:00:02.472980 AVX512ER - AVX512 Exponential & Reciprocal instructions = 0 (0)
00:00:02.472981 AVX512CD - AVX512 Conflict Detection instructions = 0 (0)
00:00:02.473041 Mnemonic - Description = guest (host)
00:00:02.473103 SSE4A - SSE4A instructions = 0 (0)
MacPro:˜ lampeyes$

最近のメインマシンw
SSE4.1/4.2に加えてAVXもguestで有効化されていました。
(探したかぎりではドキュメントには見当たらないかった。もしご存知の方がいたら教えてくだい!

ただし、AVX2はguestでは無効化されています。。。。大人の事情でもあるのかとググってますが今の所見つからず。

MacBookAir:˜ lampeyes$ /usr/sbin/system_profiler SPHardwareDataType | grep -E 'Model|Processor|Core|Cache'
Model Name: MacBook Air
Model Identifier: MacBookAir7,2
Processor Name: Intel Core i7
Processor Speed: 2.2 GHz
Number of Processors: 1
Total Number of Cores: 2
L2 Cache (per Core): 256 KB
L3 Cache: 4 MB
MacBookAir:˜ lampeyes$ grep -E 'Mnemonic|SSE4|AVX' '/Users/lampeyes/VirtualBox VMs/OracleLinux/Logs/VBox.log'
00:00:02.654824 Mnemonic - Description = guest (host)
00:00:02.654876 SSE4_1 - SSE4_1 support = 1 (1)
00:00:02.654877 SSE4_2 - SSE4_2 support = 1 (1)
00:00:02.654886 AVX - AVX support = 1 (1)
00:00:02.654890 Mnemonic - Description = guest (host)
00:00:02.654894 AVX2 - Advanced Vector Extensions 2 = 0 (1)
00:00:02.654903 AVX512F - AVX512 Foundation instructions = 0 (0)
00:00:02.654909 AVX512PF - AVX512 Prefetch instructions = 0 (0)
00:00:02.654909 AVX512ER - AVX512 Exponential & Reciprocal instructions = 0 (0)
00:00:02.654910 AVX512CD - AVX512 Conflict Detection instructions = 0 (0)
00:00:02.654987 Mnemonic - Description = guest (host)
00:00:02.655021 SSE4A - SSE4A instructions = 0 (0)


AVX2をguestで有効化することは可能なようです。

MacBookAir:˜ lampeyes$ 
MacBookAir:˜ lampeyes$ VBoxManage setextradata "OracleLinux" VBoxInternal/CPUM/IsaExts/AVX2 1

MacBookAir:˜ lampeyes$  grep -E 'Mnemonic|SSE4|AVX' '/Users/lampeyes/VirtualBox VMs/OracleLinux/Logs/VBox.log'
00:00:02.557798 AVX2 = 0x0000000000000001 (1)
00:00:02.815177 Mnemonic - Description = guest (host)
00:00:02.815226 SSE4_1 - SSE4_1 support = 1 (1)
00:00:02.815227 SSE4_2 - SSE4_2 support = 1 (1)
00:00:02.815235 AVX - AVX support = 1 (1)
00:00:02.815248 Mnemonic - Description = guest (host)
00:00:02.815253 AVX2 - Advanced Vector Extensions 2 = 1 (1)
00:00:02.815262 AVX512F - AVX512 Foundation instructions = 0 (0)
00:00:02.815267 AVX512PF - AVX512 Prefetch instructions = 0 (0)
00:00:02.815268 AVX512ER - AVX512 Exponential & Reciprocal instructions = 0 (0)
00:00:02.815269 AVX512CD - AVX512 Conflict Detection instructions = 0 (0)
00:00:02.815348 Mnemonic - Description = guest (host)
00:00:02.815381 SSE4A - SSE4A instructions = 0 (0)
MacBookAir:˜ lampeyes$

最後に Intel Core m5のMacBookですが、こちらは、MacBook Airと同様で、AVX2がguest側で無効化されていて、同様に手順で有効化できました。

何か不都合があったらオフればいいので、このまま使ってみようかと。:)

MacBook:˜ lampeyes$  /usr/sbin/system_profiler SPHardwareDataType | grep -E 'Model|Processor|Core|Cache'
Model Name: MacBook
Model Identifier: MacBook9,1
Processor Name: Intel Core m5
Processor Speed: 1.2 GHz
Number of Processors: 1
Total Number of Cores: 2
L2 Cache (per Core): 256 KB
L3 Cache: 4 MB
MacBook:˜ lampeyes$
MacBook:˜ lampeyes$ grep -E 'Mnemonic|SSE4|AVX' '/Users/lampeyes/VirtualBox VMs/DOC-921720/Logs/VBox.log'
00:00:02.791014 Mnemonic - Description = guest (host)
00:00:02.791076 SSE4_1 - SSE4_1 support = 1 (1)
00:00:02.791077 SSE4_2 - SSE4_2 support = 1 (1)
00:00:02.791088 AVX - AVX support = 1 (1)
00:00:02.791093 Mnemonic - Description = guest (host)
00:00:02.791100 AVX2 - Advanced Vector Extensions 2 = 0 (1)
00:00:02.791112 AVX512F - AVX512 Foundation instructions = 0 (0)
00:00:02.791119 AVX512PF - AVX512 Prefetch instructions = 0 (0)
00:00:02.791120 AVX512ER - AVX512 Exponential & Reciprocal instructions = 0 (0)
00:00:02.791121 AVX512CD - AVX512 Conflict Detection instructions = 0 (0)
00:00:02.791227 Mnemonic - Description = guest (host)
00:00:02.791270 SSE4A - SSE4A instructions = 0 (0)
MacBook:˜ lampeyes$
MacBook:˜ lampeyes$ VBoxManage setextradata "DOC-921720" VBoxInternal/CPUM/IsaExts/AVX2 1
MacBook:˜ lampeyes$
MacBook:˜ lampeyes$
MacBook:˜ lampeyes$ grep -E 'Mnemonic|SSE4|AVX' '/Users/lampeyes/VirtualBox VMs/DOC-921720/Logs/VBox.log'
00:00:01.243213 AVX2 = 0x0000000000000001 (1)
00:00:01.405462 Mnemonic - Description = guest (host)
00:00:01.405592 SSE4_1 - SSE4_1 support = 1 (1)
00:00:01.405593 SSE4_2 - SSE4_2 support = 1 (1)
00:00:01.405604 AVX - AVX support = 1 (1)
00:00:01.405610 Mnemonic - Description = guest (host)
00:00:01.405616 AVX2 - Advanced Vector Extensions 2 = 1 (1)
00:00:01.405628 AVX512F - AVX512 Foundation instructions = 0 (0)
00:00:01.405635 AVX512PF - AVX512 Prefetch instructions = 0 (0)
00:00:01.405636 AVX512ER - AVX512 Exponential & Reciprocal instructions = 0 (0)
00:00:01.405637 AVX512CD - AVX512 Conflict Detection instructions = 0 (0)
00:00:01.405758 Mnemonic - Description = guest (host)
00:00:01.405836 SSE4A - SSE4A instructions = 0 (0)
MacBook:˜ lampeyes$


一つ忘れてた、うちで一番古いやつ。(これもそろそろ刷新したいw) 古いのでAVX以降はないですね。Windows 10 Proのリアルマシンなのでコマンドプロンプトからbashで情報取得。う~~ん便利bash w
lampeyes@LAMPEYES:/mnt/c$ cat /proc/cpuinfo | grep -E 'model name|cpu core|siblings' | sort -n | uniq
cpu cores : 6
model name : Intel(R) Core(TM) i7 CPU X 980 @ 3.33GHz
siblings : 12
lampeyes@LAMPEYES:/mnt/c$
lampeyes@LAMPEYES:/mnt/c$ grep -E 'Mnemonic|SSE4|AVX' '/mnt/c/Users/lampeyes/VirtualBox VMs/CentOS6.5 64bit/Logs/VBox.log'
00:00:04.805674 Mnemonic - Description = guest (host)
00:00:04.805719 SSE4_1 - SSE4_1 support = 1 (1)
00:00:04.805720 SSE4_2 - SSE4_2 support = 1 (1)
00:00:04.805728 AVX - AVX support = 0 (0)
00:00:04.805732 Mnemonic - Description = guest (host)
00:00:04.805756 AVX2 - Advanced Vector Extensions 2 = 0 (0)
00:00:04.805765 AVX512F - AVX512 Foundation instructions = 0 (0)
00:00:04.805770 AVX512PF - AVX512 Prefetch instructions = 0 (0)
00:00:04.805771 AVX512ER - AVX512 Exponential & Reciprocal instructions = 0 (0)
00:00:04.805772 AVX512CD - AVX512 Conflict Detection instructions = 0 (0)
00:00:04.805811 Mnemonic - Description = guest (host)
00:00:04.805842 SSE4A - SSE4A instructions = 0 (0)
lampeyes@LAMPEYES:/mnt/c$

| | コメント (0) | トラックバック (0)

2016年9月22日 (木)

メモ:SIMDあれこれ

SIMDあれこれ自分メモ

primitive: blog / introdunction to SIMD programming
http://i-saint.hatenablog.com/entry/2015/05/26/212441

wikipedia / Streaming SIMD Extensions
https://ja.wikipedia.org/wiki/Streaming_SIMD_Extensions

IA Software User Society / コンパイラー最適化入門: 第1回 SIMD 命令とプロセッサーの関係
http://www.isus.jp/products/c-compilers/compiler_part1/

IA Software User Society / コンパイラー最適化入門: 第2回 SIMD 命令と伝統的な IA 命令
http://www.isus.jp/products/c-compilers/compiler_part2/

IA Software User Society / コンパイラー最適化入門: 第3回 インテル® コンパイラーのベクトル化レポートを活用する
http://www.isus.jp/products/c-compilers/compiler_part3/

IA Software User Society / コンパイラー最適化入門: 第4回 自動ベクトル化はどんな時に行われるか
http://www.isus.jp/products/c-compilers/compiler_part4/

IA Software User Society / コンパイラー最適化入門: 第5回 明示的にベクトル化されたコードを記述する
http://www.isus.jp/products/c-compilers/compiler_part5/

IA Software User Society / コンパイラー最適化入門: 第6回 ベクトル化の裏技集
http://www.isus.jp/products/c-compilers/compiler_part6/

Oracle In-Memory Column Store Internals – Part 1 – Which SIMD extensions are getting used?
http://blog.tanelpoder.com/2014/10/05/oracle-in-memory-column-store-internals-part-1-which-simd-extensions-are-getting-used/

SIMD-Scan: Ultra Fast in-Memory Table Scan using on- Chip Vector Processing Units
http://www.vldb.org/pvldb/2/vldb09-327.pdf

Rethinking SIMD Vectorization for In-Memory Databases
http://www.cs.columbia.edu/~orestis/sigmod15.pdf

Oracle … as usual / SIMD Extensions in and out Oracle 12.1.0.2
https://laurent-leturgez.com/2015/04/22/simd-extensions-in-and-out-oracle-12-1-0-2/

Laurent Leturgez, / Ukoug15 SIMD outside and inside Oracle 12c (12.1.0.2)
http://www.slideshare.net/lolo115/ukoug15-simd-outside-and-inside-oracle-12c-12102

Cellプログラミングチュートリアル Version 0.2c
http://cell.fixstars.com/ps3linux/tutorial/index.html

| | コメント (0) | トラックバック (0)

2016年9月20日 (火)

Boot Camp de Windows 10 Pro

Previously on Mac De Oracle から結構間が空いてしまった m(_ _)m

VIrtualBoxで一つ、エクスリームなPCで一つWindows Pro環境があるのですが、訳あって、Boot CampでMacBookにもう一つのWindows 10 Pro環境を作った。

Boot Camp を使って Mac で Windows 10 を使う
https://support.apple.com/ja-jp/HT204990

Appleサポートに記載されている手順で楽チン構築でした。ニッコリ。

Windows10pro_withbootcamp_2


Boot CampでWindows 10 Proインストールまでの流れ.(OS X側)
詳細はAppleサポートに記載されている手順通りに進めればOK

20160908_222628
20160908_222646
20160908_222650

事前にダウンロードしておいた.ISOファイルを選択して..
20160908_222701
20160908_222706
20160908_222714
20160908_222900

OS XとWindowsのパーティション配分は以下がデフォルトになっているので、使用サイズに合わせて変える必要があります。今回は50%/50%に設定してみました。いろいろお試し環境なので作り変えちゃうかもしれないですが...
20160908_225407
20160908_225411

20160908_225422

この後は、Windowsのインストールになるので省略w

MacBookでのインストール意外に速くてびっくり:)


| | コメント (0) | トラックバック (0)

2016年8月10日 (水)

Safari起動時に前回参照ページではなく、ホームページを表示したい etc.

Mac で前回と同じウインドウ、App、書類を自動的に開くという機能が働いてSafariを起動すると前回開いていたページを表示したりするようになった。

便利なんだけど、そのページがパスワード変更依頼ぺージだったりすると、次回起動時に再度そのページを送信したりすることがあるw

逆にめんどくさいなー、この機能と思ったら固定ページを表示するようできるんですよね。
(再開機能がなかった頃のようにする方法です)

Safari


再開機能で前回参照していたページを開かないようにしたうえで、起動直後の新規ページには固定ページを開き、新規タブでは空のページを表示するようにしてみました。:)

このあたりなんとなく、Appleらしくない面倒くさいUIだなぁ〜と思いますよ。直感的じゃないんでw
Photo

設定後はこんな感じになります。なんとなく落ち着く :)

起動直後はブログを固定表示
20160810_04236


新規タプを開くと空白ページ。こんな感じになります。
20160810_04230


| | コメント (0) | トラックバック (0)

2016年7月31日 (日)

個人的に気なるVirtualBox Extension PackのLincenseダイアログの「同意します」ボタンの位置w

久々に役に立たねいネタですw

VirtualBox Extension Packライセンスダイアログの「同意しません」、「同意します」ボタンの位置が、OS Xだけ違ってて、WindowsやLinuxの位置だと思い込み、「同意しません」ボタンをクリックしてしまい、イラッとすることがたまに。

デフォルトボタンになっているので、スペースバー対応すれば逆でも問題はないわけですが、気になる気になるw

OS XのVirtualBox Extension Packライセンス同意ダイアログのボタンの配置
Virtualbox_licenseconfermation_maco


WindowsのVirtualBox Extension Packライセンス同意ダイアログのボタンの配置

Virtualbox_license_confermation_d_2


LinuxのVirtualBox Extension Packライセンス同意ダイアログのボタンの配置
Virtualboxlicensecofermation_linux


ね。

| | コメント (0) | トラックバック (0)

2016年5月 6日 (金)

AirMacベースステーションの拡張ワイヤレスネットワーク設定

AirMacベースステーションの拡張ネットワーク設定のハマリどころ。(含む自分メモ)

昨年末にAirMac ExtremeとAirMac Time Capsuleの2台構成にしようとしてハマったところを書き残そうと思いつつすっかり忘れていた。 orz


マニュアルちゃんと読めよ! 

と妻にも言っている私が、

Apple Supportのエントリに書かれていた一文を読み飛ばすなんて、なんってこったいw
というのがオチだったわけですが。。。 (^^;;;;


以下をしっかりw 読めばハマることはないと思いまっす。  


AirMac ベースステーション:拡張ワイヤレスネットワーク (802.11n) の設定と構成

Wi-Fi base stations: Extending the range of your wireless network by adding additional Wi-Fi base stations

私が読み飛ばしてしまったのは、以下。
”これまでに Wi-Fi ベースステーションを構成したことがある場合は、構成に着手する前に、拡張ワイヤレスネットワークを構成する各 Wi-Fi ベースステーションを工場出荷時の状態にリセットしておいた方がよいでしょう。”

Time Capsule単体のネットワーク構成だったところへ、Extremeを追加して拡張しようとしたのですが、Time Capsule側を工場出荷状態にリセットしないで拡張しようとししため失敗していたのでした。。。。とほほ。

工場出荷状態にリセットしたら、あら不思議、 あっというまに拡張終了w (当たり前かw)

でAirMac ExtremeとTime Capsuleの2台構成で1つのSSIDで接続できる拡張ワイヤレスネットワーク構成のできあがり〜!
12191541_980958431970436_1074074517


| | コメント (0) | トラックバック (0)

2016年3月27日 (日)

OracleのB*Tree索引にはNULLが含まれる場合があるんです! - その性質を使ってチューニングすることもあるよ:) その3


前回までのMac De Oracle

OracleのB*Tree索引にはNULLが含まれる場合があるんです! - その性質を使ってチューニングすることもあるよ:)
OracleのB*Tree索引にはNULLが含まれる場合があるんです! - その性質を使ってチューニングすることもあるよ:) その2

ということで、続きで〜〜すっ。

こんな表定義で

orcl@SCOTT> desc tab01
Name Null? Type
--------- -------- --------
FOO NUMBER
BAR NUMBER
HOGE NOT NULL CHAR(2)
ID NOT NULL NUMBER

こんな索引があって

****** Index column info : tab01 ******

INDEX_NAME COLUMN_NAME DESC
------------------------------ ------------------------------ ----
IX1_TAB01 FOO ASC

IX2_TAB01 BAR ASC
FOO ASC

IX3_TAB01 ID ASC
FOO ASC

IX4_TAB01 ID ASC
BAR ASC
FOO ASC

PK_TAB01 ID ASC


こんなデータで

orcl@SCOTT> set null [NULL]
orcl@SCOTT> select * from tab01

FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1
1 [NULL] ** 2
[NULL] 1 ** 3
1 1 ** 4


2列の複合索引、どちらの列もNULLだと、やはり、NULLは索引に含まれないので IS NULL検索だと索引は利用されないですよねぇ〜。このような状態ではヒントで索引利用を強制利用させようとしても無理です。

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 index(tab01 ix2_tab01)
5 no_index(tab01 ix4_tab01)
6 no_index(tab01 ix3_tab01)
7 */
8 *
9 from
10 tab01
11 where
12 foo is null
13* and bar is null
     
FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1

・・・略・・・
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 8 |
|* 1 | TABLE ACCESS FULL| TAB01 | 1 | 1 | 1 |00:00:00.01 | 8 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NULL AND "BAR" IS NULL))

でも、NOT NUL制約の列が1列でも含まれている索引であればNULLは索引に含まれます。(前回までの復習も兼ねた確認)
第1列がWHERE句で記述されていないので索引スキップスキャンになっていますが.....IS NULL検索を索引アクセスだけで行っているのがよく分かる例の一つです:)

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 */
5 *
6 from
7 tab01
8 where
9 foo is null
10* and bar is null

FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1

・・・略・・・
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
--------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 3 | 1 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TAB01 | 1 | 1 | 1 |00:00:00.01 | 3 | 1 |
|* 2 | INDEX SKIP SCAN | IX4_TAB01 | 1 | 1 | 1 |00:00:00.01 | 2 | 1 |
--------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("BAR" IS NULL AND "FOO" IS NULL)
filter(("FOO" IS NULL AND "BAR" IS NULL))


最後にもう少しわかりやすい例を。

SQL文を少々書き換えてIndex Only Scanになるようにしました。索引にNULLが含まれていないと索引だけのアクセスで済むわけがないわけで、これ以上わかりやすい例はないと思います:)

まず、索引が利用できない例から。
FOO列とBAR列だけの複合索引をヒントで強制利用させようとしていますが、この索引は2列ともnullableなので2列をIS NULL検索しても索引が利用されません!
全ての列がNULLである場合、キーエントリーは索引に作成されない。単一列でも複合索引でも同じであることが確認できます。

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 index(tab01 ix2_tab01)
5 no_index(tab01 ix4_tab01)
6 no_index(tab01 ix3_tab01)
7 */
8 *
9 from
10 tab01
11 where
12 foo is null
13* and bar is null

FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1

・・・略・・・
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 8 |
|* 1 | TABLE ACCESS FULL| TAB01 | 1 | 1 | 1 |00:00:00.01 | 8 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NULL AND "BAR" IS NULL))

おっと、
大切なのを忘れてました。

FOO列(nullable(、BAR列(nullable)の複合索引を IS NOT NULL AND IS NULLで検索した場合はどうなるか?
答えは以下の通り。IS NULL と IS NOT NULLの組み合わせでも、索引が利用されます。:)

BAR IS NULLで範囲検索しFOO IS NOT NULLでフィルタリングしています。 NULLが含まれていないと不可能な索引レンジスキャンと索引読み時のフィルタリング!

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 no_index(tab01 ix4_tab01)
6 */
7 foo
8 , bar
9 from
10 tab01
11 where
12 foo is not null
13* and bar is null

FOO BAR
---------- ----------
1 [NULL]

・・・略・・・
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.02 | 1 | 1 |
|* 1 | INDEX RANGE SCAN| IX2_TAB01 | 1 | 1 | 1 |00:00:00.02 | 1 | 1 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("BAR" IS NULL)
filter("FOO" IS NOT NULL)

その逆も!

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 no_index(tab01 ix4_tab01)
6 */
7 foo
8 , bar
9 from
10 tab01
11 where
12 foo is null
13* and bar is not null

FOO BAR
---------- ----------
[NULL] 1

・・・略・・・
----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 2 |
|* 1 | INDEX SKIP SCAN | IX2_TAB01 | 1 | 1 | 1 |00:00:00.01 | 2 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("FOO" IS NULL)
filter(("FOO" IS NULL AND "BAR" IS NOT NULL))


もういっちょ!
2列とものnullableな索引だとindex fast full scanにはできないけど、index full scanにはできるんですよ〜。

orcl@SCOTT7gt; r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 no_index(tab01 ix4_tab01)
6 */
7 foo
8 , bar
9 from
10 tab01
11 where
12 foo is not null
13* and bar is not null

FOO BAR
---------- ----------
1 1

・・・略・・・
----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 2 |
|* 1 | INDEX FULL SCAN | IX2_TAB01 | 1 | 1 | 1 |00:00:00.01 | 2 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NOT NULL AND "BAR" IS NOT NULL))

Note
-----
- statistics feedback used for this statement

後に、NOT NULL列が含まれる索引なら index fast full scanでもできるはず!
独り言;index only scan+index fast full scanなんてのもセグメントサイズが小さければ物理読み込み量削減には効果があるんですよねぇ〜 ;-)

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 index_ffs(tab01 ix4_tab01)
6 no_index(tab01 ix2_tab01)
7 */
8 foo
9 , bar
10 from
11 tab01
12 where
13 foo is not null
14* and bar is not null

FOO BAR
---------- ----------
1 1

・・・略・・・
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.03 | 4 | 1 |
|* 1 | INDEX FAST FULL SCAN| IX4_TAB01 | 1 | 1 | 1 |00:00:00.03 | 4 | 1 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NOT NULL AND "BAR" IS NOT NULL))


オラクルの索引にNULLは絶対含まれない、というのは都市伝説! 
IS NOT NULLは索引使えないとかIS NULLは索引使えないというというのも違うんですよね。 

OracleのB*Tree索引では、索引に含まれる全列がNULLの場合以外はNULLが含まれてまっす! というのが正しいですよね!?

この手の問題でピンチになったら、思い出してみてください ;)
USE THE INDEX ONLY SCAN, LUKE! w

| | コメント (0) | トラックバック (0)

2016年3月20日 (日)

OracleのB*Tree索引にはNULLが含まれる場合があるんです! - その性質を使ってチューニングすることもあるよ:)

先日、OracleのB*Tree索引には絶対にNULLが含まれないって思い込んでる人が意外にいるよね〜とか。
OracleのB*Tree索引には絶対NULLが含まれないって都市伝説があるのはなんでだろう。
Oracle® Database概要12cリリース1 (12.1) - 一意索引と非一意索引

みたいなことが話題になって、
ある一人が、「だよね〜、ダンプ見れば含まれてるのわかります。」って言ってて、それ、ふつ〜の人は見ないからw

と思いつつ、私の周りには、やはり、変態が多いことに改めて気づいた次第です。:) はい。


で、
変態じゃない、ごく一般的なエンジニアの方々(ブロックダンプを華麗かつ自然にキメちゃわない方々)向けに、

OracleのB*Tree索引にNULLが含まれているか、NULLが含まれていないかの簡単な確認方法をお伝えしなければ!w

ということで、数回にわけて書いておこうかと思ってます。(予定は未定w)

(実は、このネタとほぼ同じことを1年前ぐらい前に、ローカルかつクローズドな勉強会?、でも使ってました。 最近、やってないみたいですけど)

環境は最近の定番 Oracle Database 12c R1 EE

orcl@SCOTT> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
CORE 12.1.0.2.0 Production
TNS for Linux: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production


SCOTTスキーマに以下のような表と索引を作成し少ないですが、データを登録
今回の主役は索引とNULLなのでデータ量少なくても必要なパターンが登録できていれば十分です。
(データ量を増やせばチューニングのお題の元ネタにもなると思います。)

orcl@SCOTT> create table tab01 (foo number, bar number, hoge char(2) not null,id number not null);

Table created.

orcl@SCOTT> insert into tab01 values(null,null,'**',1);

1 row created.

orcl@SCOTT> insert into tab01 values(1,null,'**',2);

1 row created.

orcl@SCOTT> insert into tab01 values(null,1,'**',3);

1 row created.

orcl@SCOTT> insert into tab01 values(1,1,'**',4);

1 row created.

orcl@SCOTT> commit;

Commit complete.

orcl@SCOTT> alter table tab01 add constraint pk_tab01 primary key(id) using index;

Table altered.

orcl@SCOTT> exec dbms_stats.gather_table_stats(ownname=>'SCOTT',tabname=>'TAB01',cascade=>true,no_invalidate=>false);

PL/SQL procedure successfully completed.

orcl@SCOTT> create index ix1_tab01 on tab01 (foo);

Index created.

orcl@SCOTT> create index ix2_tab01 on tab01 (bar,foo);

Index created.

orcl@SCOTT> create index ix3_tab01 on tab01(id,foo);

Index created.

orcl@SCOTT> create index ix4_tab01 on tab01(id,bar,foo);

Index created.


FOOとBAR列はNullableにしています

orcl@SCOTT> desc tab01
Name Null? Type
----------------------------------------- -------- ----------------------------
FOO NUMBER
BAR NUMBER
HOGE NOT NULL CHAR(2)
ID NOT NULL NUMBER

主演の索引たち

NULLが索引でどう扱われるかを確認するため、事前作成の索引をたくさん用意してしました。後から作るの面倒なのでw
これだけ類似索引も含めて多数の索引があると確認時に意図した索引が利用されない可能性も高いため、検証では内容に合わせて利用する索引をヒントで指定することにします。

ちなみに、
普通の環境でこんなに索引があったら、アンチパターン:インデックスショットガンですからね。ご注意ください:) たまにこのような環境に遭遇することはありますが。。。

IX1_TAB01はnullableなFOO列だけの単一列索引
IX2_TAB01はnullableなBAR列とFOO列からなる複合索引
IX3_TAB01とTX4_TAB01は上記の列に加え主キー列のID列を第1キーとする複合索引

としてあります。

orcl@SCOTT> break on table_name on index_name skip 1
orcl@SCOTT> select table_name,index_name,column_name from user_ind_columns where table_name='TAB01' order by table_name,index_name,column_position;

TABLE_NAME INDEX_NAME COLUMN_NAME
------------------------------ ------------------------------ ------------------------------
TAB01 IX1_TAB01 FOO

IX2_TAB01 BAR
FOO

IX3_TAB01 ID
FOO

IX4_TAB01 ID
BAR
FOO

PK_TAB01 ID

登録したデータは以下の通り
NULLは索引とともに今回の主役なので、どこがNULLになっているかメモしておいてくださいませ。

orcl@SCOTT> set null [NULL]
orcl@SCOTT> select * from tab01 order by id;

FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1
1 [NULL] ** 2
[NULL] 1 ** 3
1 1 ** 4

さて、索引にNULLが含まれているか、いないか、どうやって確認すると思います? ブロックダンプを華麗にキメきめる以外の方法でw

SQLチューニングをしたことがある方なら一般的に利用してい(と思ってる)機能で簡単に確認できちゃうんですよ。これが。

SQL*Plusのautotraceや、explain plan それに、DBMS_XPLAN.DISPLAY* なファンクションでも確認できます。
SQLclはautotraceにはまだ未対応となっているようですが、それ以外の方法ならはできるようです。
(今回はSQL*Plusを使い、dbms_xplan.display_cursor(format=>'ALLSTATS LAST'))で確認します)


どうやって、どの部分で確認するのか? 
autottraceやDBMS_XPLAN.DISPLAY*などでリストされるpredicate information部分のaccess/filter predicate部分で確認できるんです!


例1)FOO = 1 で検索した例

注):索引が多いので意図した索引を利用するようにヒントで固定しています

おわかりでしょうか?
Predicate Infomation部分から、Id=2のINDEX RANGE SCANで IX1_TAB01索引を FOO=1でアクセスしていることが読み取れますよね?
つまり、1 という値が索引に含まれている(含まれる)からaccess pathとしてIX1_TAB01索引を参照しているわけです。

orcl@SCOTT> r
1 SELECT
2 /*+
3 gather_plan_statistics
4 index(tab01 ix1_tab01)
5 */
6 *
7 FROM
8 tab01
9 WHERE
10* foo = 1

FOO BAR HO ID
---------- ---------- -- ----------
1 [NULL] ** 2
1 1 ** 4

orcl@SCOTT> select * from table(dbms_xplan.display_cursor(format=>'ALLSTATS LAST'));

ーーー中略ーーー

Plan hash value: 3795960549

-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2 |00:00:00.01 | 4 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TAB01 | 1 | 2 | 2 |00:00:00.01 | 4 |
|* 2 | INDEX RANGE SCAN | IX1_TAB01 | 1 | 2 | 2 |00:00:00.01 | 2 |
-----------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("FOO"=1)


ということで、今日は馬事公苑の散歩は気持ちいいよ〜。

次回へつづく。

| | コメント (0) | トラックバック (0)

2016年3月13日 (日)

FAQ になりそうな、12c MTA環境での統計履歴管理 ー CDBとPDBの間で迷子になりそう PART2

PART1ってあったっけ? というのは置いといて、
PART III以降もなにかありそうなアトモスフィアなのですが、ここで書いておかないとハマりそうなので備忘録代わりに。


みなさん、統計履歴って知ってます?
dbms_stats.gather_*_stats を実行するとオプティマイザ統計情報が取得された表、索引、列統計が自動的にバックアップされることを。
そのバックアップは統計履歴と呼ばれています。(履歴統計と呼んでる人のほうが多いと思うのですが。。。マニュアルだと統計履歴って書いてますね。。。。誰も履歴統計を統計履歴だろ、それ! と突っ込んでくれなてなかった気がw)

Oracle® Database SQLチューニング・ガイド 12cリリース1(12.1) オプティマイザ統計の保存の管理
Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 12c リリース1(12.1) DBMS_STATS.GET_STATS_HISTORY_RETENTIONファンクション
Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 12c リリース1(12.1) DBMS_STATS.ALTER_STATS_HISTORY_RETENTIONプロシージャ
Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 12c リリース1(12.1) PURGE_STATSプロシージャ
Oracle® Database SQL言語リファレンス 12cリリース1 (12.1) SYS_CONTEXT


で、オプティマイザ統計収集が原因と思われる事象があった場合、統計履歴をリストアしてトラブルを華麗に回避なんて手法もあるんです。
古くは小田さんの記事でも取り上げられています。
門外不出のOracle現場ワザ 第4章 Oracleデータベースの頭脳 「オプティマイザ」徹底研究


と、ここまでは、11gとか12cでも非MTA環境のお話です。

先日、12cのMTA環境で統計履歴をリストアしようとしたら。。。統計履歴。。。なんとなく言いづらい。。。履歴統計が無いw
履歴統計の保存期間はデフォルトで31日なのでパージされる前に保存期間を無期限に変更しました。。。(その時はMTA環境の罠にハマったとは気付かず、無期限にしたからもう気にしなくていいや! と思ったんです)

ところが、いざ履歴統計をみると。。。。パージされてる。。。。。焦りましたw 

どういうことだったのか、最初に書いてしまうと、

履歴統計は、CDB/PDB、それぞれ独立して管理されてまっす!。

(え〜〜〜〜〜〜〜〜っ。知らんかったというか、マニュアルのどこかに記載されているのなら、どなたかそのページへのリンクをおしえてくだしぁ。。。)


久々に長〜い前置きはこれぐらいにして確認してみましょう。(--;

PDBが1つあるシングルテナント構成(1 PDB/CDB)で確認してみました。

CDB及び、PDBの履歴統計保存期間を確認します。(デフォルト設定のままです)
なにもしてないデフォルト状態では、CDBもPDBも履歴統計保存期間は31日となっています。


CDB側の履歴統計保存期間

SYSTEM@orcl12c> @show_stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c CDB$ROOT

stats history retention
-----------------------
31

PDB側の履歴統計保存期間

SYSTEM@pdborcl12c> @show_stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c PDBORCL12C

stats history retention
-----------------------
31


では最初にどちらも履歴統計を保存しない状態にしてみます。

CDB
履歴統計を保存なしに設定して既存履歴統計をパージ。
事前作成しておいた stats_hist_retention.sqlを実行。(スクリプトはエントリの最後に記載しておきました。)

DBMS_STATS.GATHER_DATABASE_STATSを実行しても履歴統計数の増加なし。想定通り。

SYSTEM@orcl12c> exec dbms_stats.alter_stats_history_retention(0);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@orcl12c> exec dbms_stats.purge_stats(null);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@orcl12c> @stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c CDB$ROOT


stats history retention
-----------------------
0

PL/SQLプロシージャが正常に完了しました。


number of tab stats histories
-----------------------------
0


PDB

SYSTEM@pdborcl12c> exec dbms_stats.alter_stats_history_retention(0);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@pdborcl12c> exec dbms_stats.purge_stats(null);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@pdborcl12c> @stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c PDBORCL12C

stats history retention
-----------------------
0

PL/SQLプロシージャが正常に完了しました。

number of tab stats histories
-----------------------------
0

さて、次にCDBの履歴統計保存期間を無期限に変更し、PDBは履歴統計保存なしにしてみます。

CDBの履歴統計数は増加し、PDB側は変化なしということになるはず。。。


CDB

SYSTEM@orcl12c> exec dbms_stats.alter_stats_history_retention(-1);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@orcl12c> @stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c CDB$ROOT

stats history retention
-----------------------
-1

PL/SQLプロシージャが正常に完了しました。

number of tab stats histories
-----------------------------
2499

CDB側の履歴統計数が増加した。まあ、そうだよね〜。

PDB
PDB側は履歴統計無しのままなので変化はないです。個別に設定できてるからそうなんでしょうね。多分。

SYSTEM@pdborcl12c> @stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c PDBORCL12C


stats history retention
-----------------------
0

PL/SQLプロシージャが正常に完了しました。

number of tab stats histories
-----------------------------
0


逆にしてみます。CDBは履歴統計無し、PDBの履歴統計保存期間を無期限にしてみます。
履歴統計はCDB/PDB個別管理ならCDBの履歴統計なし、PDB側には履歴統計ありという構成もできるはず!!

なお、確認しやすくするために、CDB側は履歴統計無しに変更後、履歴統計を手動パージしておきます。

CDB

SYSTEM@orcl12c> exec dbms_stats.alter_stats_history_retention(0);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@orcl12c> exec dbms_stats.purge_stats(null);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@orcl12c> @stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c CDB$ROOT

stats history retention
-----------------------
0

PL/SQLプロシージャが正常に完了しました。

number of tab stats histories
-----------------------------
0




PDB
これが確認できれば問題なさそうですね。CDB/PDBの履歴統計保存期間の管理及びパージは個別管理できるってことで。。。。
Workload RepositoryはCDBでのみ管理できるようになっているので間違いやすいぞ、と
この辺りをまとめたマニュアルがあれば解りやすいのになぁ(ボソっ

SYSTEM@pdborcl12c> exec dbms_stats.alter_stats_history_retention(-1);

PL/SQLプロシージャが正常に完了しました。

SYSTEM@pdborcl12c> @stats_hist_retention

cdb name container name
-------------------- --------------------
orcl12c PDBORCL12C

stats history retention
-----------------------
-1

PL/SQLプロシージャが正常に完了しました。

number of tab stats histories
-----------------------------
2659


履歴統計は、CDB/PDB個別管理なので、履歴統計保存期間、履歴統計のパージはCDB/PDBそれぞれで行えるようですが、
Workload Repository:AWRのスナップショットの保存期間やパージなどは、CDBのみでしか行えない。(AWRのスナップショットはCDB/PDBどこで実行しても全体が取得されます。)


それに、PDBで変更できる初期化パラメータと変更できないパラメータのまとめがあればもっと便利かも。
以前調べたPDB側で変更できる初期化パラメータの保存場所とかも合わせてまとめとくか。。。

PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #1
PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #2 - PDBの初期化パラメータは何処!?
PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #3 - 消えたPDBの初期化パラメータの謎... Truth is out there.

いろいろ整理できてないので只今混乱中w


今回試した環境
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
CORE 12.1.0.2.0 Production
TNS for Linux: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production


使ったクエリーなど
stats_hist_retention.sql

SELECT 
SYS_CONTEXT('USERENV', 'CDB_NAME') AS "cdb name"
, SYS_CONTEXT('USERENV', 'CON_NAME') AS "container name"
FROM
dual;

SELECT
DBMS_STATS.GET_STATS_HISTORY_RETENTION AS "stats history retention"
FROM
dual;

EXEC DBMS_STATS.GATHER_DATABASE_STATS;

SELECT
COUNT(1) AS "number of tab stats histories"
FROM
dba_tab_stats_history;


show_stats_hist_retention.sql

SELECT 
SYS_CONTEXT('USERENV', 'CDB_NAME') AS "cdb name"
, SYS_CONTEXT('USERENV', 'CON_NAME') AS "container name"
FROM
dual;

SELECT
DBMS_STATS.GET_STATS_HISTORY_RETENTION AS "stats history retention"
FROM
dual;

| | コメント (0) | トラックバック (0)

2015年12月 4日 (金)

OTHER_XMLの中身

JPOUG Advent Calendar 2015 - 4日目のエントリーです。

役に立たないから、絶対最後まで読まないでね!!! (^^)

さて、
みなさん、マニュアル読んでますか? 
最近は量が多いので、必要になってから、なりそうだから読むことが多いです。
Oracle® Databaseリファレンス 12cリリース1 (12.1) なんて特にそうです。
ただ、一度読み始めると、いろいろと気づくところもあるわけです...こんな情報が取れるのか! とか。


あ〜、これは、禁断のw マニュアルに記載されてないパラメータを指定すると見れるやつだ!!! とか気づくこともあったり。

例えば、V$SQL_PLANDBA_HIST_SQL_PLANのOTHER_XML列。

この列の説明には実に興味深いことが書かれています。以下の説明、読んでてワクワクしますw 
何が格納されているのでしょう???(もう、みんな知ってるくせに〜)

”アウトライン・データ(同じ計画の再作成に使用できる一連のオプティマイザ・ヒント)”

見たくないですか? 中身。

見たいですよね。私もそうです!


ただ、OTHER_XML列、列名の通り、CLOB型で中身はXMLです!!!
SQL*Plusで普通に表示しようとすると長すぎて読みにくいってのが難点w


ならばXMLにも対応しているSQL文で何とかしてみたいと思います。

ゴニョゴニョ、パタパタ。

できました。

dba_hist_sql_plan向けですが。(v$sql_planビューでも同様のことができます!)
(注:dba_hist_*ビューを参照するにはOracle Diagnostics Packが必要でっす。ですが、v$sql_planを参照するのならオプションはいらないですよね.)

こんな感じです

SYSTEM> !cat report_outline_hints.sql
col outline for a200
set linesize 300
set pagesize 10000
set veri off

SELECT '/*+' AS outline FROM DUAL
UNION ALL
SELECT ' '||'BEGIN_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT
' '||o.outlinehint
FROM
(
SELECT
EXTRACTVALUE(
VALUE(x)
, '/hint/text()'
) AS outlinehint
FROM
XMLTABLE(
'/*/outline_data/hint'
PASSING(
SELECT
XMLTYPE(other_xml)
FROM
dba_hist_sql_plan
WHERE
other_xml IS NOT NULL
AND sql_id = '&1'
AND plan_hash_value = &2
)
) x
) o
UNION ALL
SELECT ' '||'END_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT '*/' FROM DUAL
/
set veri on

実行すると以下のような、:) 情報を取り出すことができます!!

SYSTEM> @report_outline_hints gdtyuqcyk8x1c 2236229349

OUTLINE
------------------------------------------------------------------------------------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
DB_VERSION('12.1.0.2')
ALL_ROWS
OUTLINE_LEAF(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "B"@"SEL$1" ("ILM_EXECUTION$"."EXECUTION_ID"))
NO_ACCESS(@"SEL$1" "A"@"SEL$1")
LEADING(@"SEL$1" "B"@"SEL$1" "A"@"SEL$1")
USE_MERGE(@"SEL$1" "A"@"SEL$1")
PQ_FILTER(@"SEL$1" SERIAL)
INDEX(@"SEL$2" "A"@"SEL$2" ("ILM_EXECUTION$"."EXECUTION_ID"))
FULL(@"SEL$2" "B"@"SEL$2")
LEADING(@"SEL$2" "A"@"SEL$2" "B"@"SEL$2")
USE_MERGE(@"SEL$2" "B"@"SEL$2")
USE_HASH_AGGREGATION(@"SEL$2")
END_OUTLINE_DATA
*/

表示された内容に、身に覚え、
いや、見覚えのある方も多いことと思います :) あれでね。そう、あれです。
マニュアルに記載されいないパラメータを利用しなくても取り出せるんです。

ついでなので、マニュアルに記載のないパラメータを使ったDBMS_XPLAN.DISPLAY_AWRで同じ情報をリストしてみました。DBMS_XPLAN.DISPLAY_AWR以外のDISPLAY*関数のformatパラメータでもできます:)
(注: DISPLAY_AWRでAWRを参照するのでOracle Diagnostics Packが必要でっす。 ですが、DISPLAY_CURSOR(),DISPLAY()とDISPLAY_PLAN()ならAWRは参照しないのでオプションはいらないですよね。)

PROMPT
PROMPT ****** display_awr with outline option *********
SELECT
plan_table_output as outline
FROM
TABLE(DBMS_XPLAN.DISPLAY_AWR(sql_id=>'&1',plan_hash_value=>&2,format=>'OUTLINE'))
/


****** DBMS_XPLAN.DISPLAY_AWR with OUTLINE option *******

OUTLINE
------------------------------------------------------------------------------------------
SQL_ID gdtyuqcyk8x1c
--------------------
SELECT B.EXECUTION_ID, NVL(A.N_COUNT,0), A.COMP_TIME FROM ( SELECT
A.EXECUTION_ID, COUNT(*) N_COUNT, NVL(MAX(B.COMPLETION_TIME), SYSDATE)
COMP_TIME FROM SYS.ILM_EXECUTION$ A, SYS.ILM_RESULTS$ B WHERE
EXECUTION_STATE = :B7 AND A.EXECUTION_ID = B.EXECUTION_ID AND
B.JOB_STATUS NOT IN (:B6 , :B5 , :B4 , :B3 , :B2 , :B1 ) GROUP BY
A.EXECUTION_ID )A, ILM_EXECUTION$ B WHERE B.EXECUTION_ID =
A.EXECUTION_ID (+) AND EXECUTION_STATE = :B7 AND (ROWNUM <= :B9 OR :B9
= :B8 )

Plan hash value: 2236229349

-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | COUNT | | | | | |
| 2 | FILTER | | | | | |
| 3 | MERGE JOIN OUTER | | 1 | 65 | 4 (50)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID | ILM_EXECUTION$ | 1 | 26 | 0 (0)| |
| 5 | INDEX FULL SCAN | PK_TASKID | 1 | | 0 (0)| |
| 6 | SORT JOIN | | 1 | 39 | 4 (50)| 00:00:01 |
| 7 | VIEW | | 1 | 39 | 3 (34)| 00:00:01 |
| 8 | HASH GROUP BY | | 1 | 65 | 3 (34)| 00:00:01 |
| 9 | MERGE JOIN | | 1 | 65 | 3 (34)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID| ILM_EXECUTION$ | 1 | 26 | 0 (0)| |
| 11 | INDEX FULL SCAN | PK_TASKID | 1 | | 0 (0)| |
| 12 | SORT JOIN | | 1 | 39 | 3 (34)| 00:00:01 |
| 13 | TABLE ACCESS FULL | ILM_RESULTS$ | 1 | 39 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Outline Data
-------------

/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
DB_VERSION('12.1.0.2')
ALL_ROWS
OUTLINE_LEAF(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "B"@"SEL$1" ("ILM_EXECUTION$"."EXECUTION_ID"))
NO_ACCESS(@"SEL$1" "A"@"SEL$1")
LEADING(@"SEL$1" "B"@"SEL$1" "A"@"SEL$1")
USE_MERGE(@"SEL$1" "A"@"SEL$1")
PQ_FILTER(@"SEL$1" SERIAL)
INDEX(@"SEL$2" "A"@"SEL$2" ("ILM_EXECUTION$"."EXECUTION_ID"))
FULL(@"SEL$2" "B"@"SEL$2")
LEADING(@"SEL$2" "A"@"SEL$2" "B"@"SEL$2")
USE_MERGE(@"SEL$2" "B"@"SEL$2")
USE_HASH_AGGREGATION(@"SEL$2")
END_OUTLINE_DATA
*/

ちなみに、11g R2でも動作します!


どうでしたか?役に立たなかったですよね?
以上、OUTLINE HINTSより愛を込めてお送りしました!


参考: (日本語で書かれたエントリーは見当たらない。初か、もしかして!w)

Oracle SQL Plan Stability
http://blog.tanelpoder.com/oracle/performance/sql/oracle-sql-plan-stability/


Plan stability in 10g - using existing cursors to create Stored Outlines and SQL profiles
http://oracle-randolf.blogspot.jp/2009/03/plan-stability-in-10g-using-existing.html


FORCE_MATCH for Stored Outlines and/or SQL Baselines????? – follow up
https://tonyhasler.wordpress.com/2011/12/

How to hint – 1
https://jonathanlewis.wordpress.com/2011/06/08/how-to-hint-1/

dbms_xplan(3)
https://jonathanlewis.wordpress.com/2008/03/06/dbms_xplan3/



追記:

@yoshikawさんに指摘され、EXTRACTVALUE()が11.2で非推奨になっていたとことに気づく orz.

@yoshikawさん、指摘ありがとうございます。 

XMLTABLE().... COLUMNSを使えばEXTRACTVALUE()はいらなかった!!!! ということでEXTRACTVALUEなし版も作りました!!

ただ、CON_IDも見ないとマルチテナントに対応できず、エラーになると気づいたが、
11gにも対応しようとすると、もう一工夫必要なことに気づき、再び、orz.

つづきは、...いずれ...

変更したSQL文は以下のとおり。

SYSTEM> !cat report_outline_hints.sql
col outline for a200
set linesize 300
set pagesize 10000
set veri off

SELECT '/*+' AS outline FROM dual
UNION ALL
SELECT ' '||'BEGIN_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT
' '||x.outline_hint
FROM
XMLTABLE(
'/*/outline_data/hint/text()'
PASSING(
SELECT
XMLTYPE(other_xml)
FROM
dba_hist_sql_plan
WHERE
other_xml IS NOT NULL
AND sql_id = '&1'
AND plan_hash_value = &2
)
COLUMNS outline_hint PATH '/text()'
) x
UNION ALL
SELECT ' '||'END_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT '*/' FROM DUAL
/

SYSTEM> @report_outline_hints gdtyuqcyk8x1c 2236229349

OUTLINE
--------------------------------------------------------------------------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
DB_VERSION('12.1.0.2')
ALL_ROWS
OUTLINE_LEAF(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "B"@"SEL$1" ("ILM_EXECUTION$"."EXECUTION_ID"))
NO_ACCESS(@"SEL$1" "A"@"SEL$1")
LEADING(@"SEL$1" "B"@"SEL$1" "A"@"SEL$1")
USE_MERGE(@"SEL$1" "A"@"SEL$1")
PQ_FILTER(@"SEL$1" SERIAL)
INDEX(@"SEL$2" "A"@"SEL$2" ("ILM_EXECUTION$"."EXECUTION_ID"))
FULL(@"SEL$2" "B"@"SEL$2")
LEADING(@"SEL$2" "A"@"SEL$2" "B"@"SEL$2")
USE_MERGE(@"SEL$2" "B"@"SEL$2")
USE_HASH_AGGREGATION(@"SEL$2")
END_OUTLINE_DATA
*/

JPOUG Advent Calendar 2015、12/5は、Yohei Azekatsu さんです。どんな変態ネタが飛び出すのか、乞うご期待!!

| | コメント (0) | トラックバック (0)

2015年5月18日 (月)

Xcode Serverの暴走 @ Yosemite

Yosemiteの影響なのか不明だけどMavericksでもハマった方はいるようなのと日本語のネタが少なそうなのでメモ代わりに書いておきますね。

やったこと
OS X ServerでXcode Serverを設定 →試しに、Xcode Serverの設定をした。
動作確認岳済んだので、一旦無効化したのですが......

その時の記憶は曖昧なのだけど、無効化したのは確かなので画面のコピペを。
20150518_22611


その後、OS Xをシャットダウンしようとすると、fast user switchingで他のユーザにログインしたままの状態だと表示されるワーニングダイアログが表示されるようになった。(他のユーザでログインしてないのに!!!!!!

20150303_190815

シャットダウンしようとするたびに表示されるので面倒だし、気になるし。
ということで調べてらバグっぽいw

アクティビティモニタで見ると _xcsbuildd ってユーザのプロセスがすげーことになっているw
20150518_23433


これ、無効化したはずの Xcode Serverなんですよ!!!

さらに調べていくと、developer forum でも幾つかthreadがあり、とりあえずの解決策が! (シンプルな解決作だけど、これが大当たりでした :)

_mdworker が大暴れしてたことを思いだしてブルーな気分だったんだけど、なんとか落ち着いたw

https://devforums.apple.com/message/1047083#1047083
https://devforums.apple.com/message/1053273#1053273


以下、解決までの記録です。

discus-mother:˜ discus$ stat -f '%u %Su' /dev/console
263 _xcsbuildd


discus-mother:˜ discus$ sudo xcrun xcscontrol --reset
Password:
2015-03-09 20:14:42.716 xcscontrol[2954:79163] I am xcscontrol (version 2.0 from /Applications/Xcode.app)
2015-03-09 20:14:42.717 xcscontrol[2954:79163] Arguments: (
"/Applications/Xcode.app/Contents/Developer/usr/bin/xcscontrol",
"--reset"
)
2015-03-09 20:14:43.490 xcscontrol[2954:79163] Xcode version: 6.1.1 (6A2008a) (OS X SDK 13F26, iOS SDK 12B411)
2015-03-09 20:14:43.492 xcscontrol[2954:79163] Server version: 4.0.3 (14S350)
2015-03-09 20:14:43.492 xcscontrol[2954:79163] OS X version: 10.10.2 (14C109)
2015-03-09 20:14:43.495 xcscontrol[2954:79163] Launching task: /bin/launchctl unload -w /System/Library/LaunchDaemons/com.apple.xcsd.plist
2015-03-09 20:14:44.490 xcscontrol[2954:79163] Launching task: /bin/launchctl unload -w /System/Library/LaunchDaemons/com.apple.xcscouch.plist
2015-03-09 20:14:44.566 xcscontrol[2954:79163] Launching task: /bin/launchctl unload -w /System/Library/LaunchDaemons/com.apple.xcsredis.plist
2015-03-09 20:14:44.729 xcscontrol[2954:79163] Launching task: /bin/launchctl unload -w /System/Library/LaunchDaemons/com.apple.xcscontrol.plist
2015-03-09 20:14:47.985 xcscontrol[2954:79163] Launching task: /usr/bin/killall -u 263 -9
2015-03-09 20:14:48.661 xcscontrol[2954:79163] Launching task: /usr/bin/xcode-select --reset
2015-03-09 20:14:49.745 xcscontrol[2954:79163] Reset completed successfully

これで再起動すれば解決 :)

| | コメント (0) | トラックバック (0)

2014年6月13日 (金)

SQL Developer 4の素敵なコマンドライン de SQL整形 :)

Version 4.0.1ではWindowsでも同じ問題がでていたようですね。以下OTNフォーラムにも投稿されていたようです。
OS X版 Version 4.0.1でも同じだったので不具合だったようです。
https://community.oracle.com/thread/3562219


Version 4.0.2がリリースされたので改善されたか確かめてみました。 OS X版のSQLDeveloper 4.0.2 で!

OTN-JPではまだ、4.0.1のようですが、USでは 4.0.2のようです。OTN-JPでもそのうち4.0.2になるのでしょうね :)
以下はUSへリンクです。
http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html

20140613_45308


OS X版のsdcliを実行するには実行権を付与する必要があります。sdcliは以下のパスにあります。かなり深いところにあります!
(OS X版は以下深いところにあるので、SQLDeveloperのアイコン上で右クリック>コンテクストメニュー>パッケージの内容を表示から辿ってパスを探してもいいですし、以下のパス直接コピペでも行けます。)

20140613_45551

20140613_45613


discus-mother:˜ oracle$ cd /Applications/SQLDeveloper.app/Contents/Resources/sqldeveloper/sqldeveloper/bin
discus-mother:bin oracle$ chmod +x sdcli
discus-mother:bin oracle$ ll
total 672
-rw-r--r--@ 1 oracle staff 49279 5 3 02:48 SQLDeveloperIcons.icns
-rw-r--r--@ 1 oracle staff 0 5 3 02:48 jdk.conf
-rw-r--r--@ 1 oracle staff 440 5 3 02:48 logging-debug.conf
-rw-r--r--@ 1 oracle staff 363 5 3 02:48 logging.conf
-rwxrwxr-x@ 1 oracle staff 586 5 3 02:50 sdcli
-rw-r--r--@ 1 oracle staff 99 5 3 02:50 sdcli-Darwin.conf
-rw-r--r--@ 1 oracle staff 446 5 3 02:50 sdcli.boot
-rw-r--r--@ 1 oracle staff 854 5 3 02:50 sdcli.conf
-rw-r--r--@ 1 oracle staff 71205 5 3 02:48 splash.gif
-rw-r--r--@ 1 oracle staff 71205 5 3 02:48 splash.png
-r-xr-xr-x@ 1 oracle staff 3220 5 3 02:48 sqldeveloper
-rw-r--r--@ 1 oracle staff 415 5 3 02:48 sqldeveloper-Darwin.conf
-rw-r--r--@ 1 oracle staff 661 5 3 02:48 sqldeveloper-debug.conf
-rw-r--r--@ 1 oracle staff 204 5 3 02:48 sqldeveloper-nondebug.conf
-rw-r--r--@ 1 oracle staff 445 5 3 02:48 sqldeveloper.bat
-rw-r--r--@ 1 oracle staff 340 5 3 02:48 sqldeveloper.boot
-rw-r--r--@ 1 oracle staff 1175 5 3 02:48 sqldeveloper.conf
-rw-r--r--@ 1 oracle staff 83456 5 3 02:48 sqldeveloper64W.exe
-rw-r--r--@ 1 oracle staff 131 5 3 02:54 version.properties
discus-mother:bin oracle$


パスは通っていないので設定する必要があります。

discus-mother:˜ oracle$ cat .bashrc
alias ll='ls -lv'

#for SQLDeveloper sdcli
export PATH=$PATH:/Applications/SQLDeveloper.app/Contents/Resources/sqldeveloper/sqldeveloper/bin

discus-mother:˜ oracle$


Version 4.0.1では以下の状況でExceptionが発生していましたが、Version 4.0.2では解決してます!!! 

discus-mother:˜ oracle$ sdcli

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

使用可能な機能:
cart: データベース・カート・バッチ・タスク
dba: 基本バッチDBAタスク
format: SQL Format Task
migration: Database Migration Tasks
reports: 基本バッチ・レポート・タスク
unittest: ユニット・テスト・バッチ・タスク
discus-mother:˜ oracle$

ということで、
前から試したかった SQL文の整形機能。 GUIだとSQLワークシートでSQL文整形機能が提供されているためデータベースへ接続必要だったんですよね。
機能としては素敵だったのですが、データベース接続が行えない環境では使えない機能だったんですよ。
そんな環境で読むに耐えない巨大で未整形なSQL文を渡され涙目だった日々を思い出しますw

コマンドラインならデータベース接続不要なのがいいっす!

discus-mother:˜ oracle$ sdcli format

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

format input=<入力ファイルまたはディレクトリ> output=<出力ファイルまたはディレクトリ>
成功しました。
discus-mother:˜ oracle$


以下のようなSQL文を整形してみます。

discus-mother:˜ oracle$ cat sample_unformated.sql
select a.id,a.name,b.location,b.phone_no from foo a innter join bar b on a.id = b.id order by a.name;


意外と地味な感じの処理終了メッセージですが、整形できたようです。整形結果を確認!

discus-mother:˜ oracle$ sdcli format input=sample_unformated.sql output=sample_formated.sql

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

成功しました。
discus-mother:˜ oracle$


いいですね〜 :) 最後の改行がないのですは、ご愛嬌ということで.

discus-mother:˜ oracle$ cat sample_formated.sql
SELECT a.id,
a.name,
b.location,
b.phone_no
FROM foo a innter
JOIN bar b
ON a.id = b.id
ORDER BY a.name;discus-mother:˜ oracle$
discus-mother:˜ oracle$

では、超便利な一括整形のテスト。 以下のような未整形なSQLファイルを含むディレクトリと整形後SQLファイルを格納するディレクトリを用意して....

discus-mother:˜ oracle$ mkdir unformated_sqls
discus-mother:˜ oracle$ mkdir formated_sqls
discus-mother:˜ oracle$ dir=unformated_sqls; for fname in `ls $dir`; do echo -e \\n\\nfile : $fname; cat $dir/$fname; done;


file : sample1.sql
select a.id,a.name,b.location,b.phone_no from foo a innter join bar b on a.id = b.id order by a.name;


file : sample2.sql
select a.id,a.name,b.location,b.phone_no from foo a innter join bar b on a.id = b.id order by a.name;


一括整形の場合はディレクトリ名のみ指定すればOK!
おおおおおおおおお〜〜〜〜、できた〜〜〜〜SQL文の一括整形!!!  素敵!!

discus-mother:˜ oracle$ sdcli format input=unformated_sqls output=formated_sqls

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

成功しました。


かくに〜〜〜〜〜ん!!

discus-mother:˜ oracle$ dir=formated_sqls; for fname in `ls $dir`; do echo -e \\n\\nfile : $fname; cat $dir/$fname; done;


file : sample1.sql
SELECT a.id,
a.name,
b.location,
b.phone_no
FROM foo a innter
JOIN bar b
ON a.id = b.id
ORDER BY a.name;

file : sample2.sql
SELECT a.id,
a.name,
b.location,
b.phone_no
FROM foo a innter
JOIN bar b
ON a.id = b.id
ORDER BY a.name;


Good job!!!!! SQL Developer Team!


| | コメント (0) | トラックバック (0)

2014年4月29日 (火)

Oracle Database 12cで実装されたidentity columnのメモ

Oracle® Database SQL言語リファレンス 12cリリース1 (12.1) CREATE TABLE identity_clause


制限事項に、「CREATE TABLE AS SELECTを使用すると、列に対するIDのプロパティが継承されなくなります。」と記載されているのでかるく確認 :)

SCOTT@nonpdb12c> CREATE TABLE table_foobar_identity2
2 (
3 id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY
4 ,data VARCHAR2(10)
5 );

表が作成されました。

SCOTT@nonpdb12c> create table table_foobar_identity2_tmp as select * from table_foobar_identity2;

表が作成されました。

SCOTT@nonpdb12c> break on table_name skip 1
SCOTT@nonpdb12c> select table_name,column_name,identity_column from user_tab_columns where table_name like 'TABLE_FOOBAR%' order by table_name,column_id;

TABLE_NAME COLUMN_NAME IDE
------------------------------ ------------------------------ ---
TABLE_FOOBAR_IDENTITY2 ID YES
DATA NO

TABLE_FOOBAR_IDENTITY2_TMP ID NO
DATA NO

CREATE TABLE AS SELECTで復籍してもidentity columnは継承されてない。ふむふむ。


同マニュアルの注意には、「ID列を作成するときには、パフォーマンスを向上するために、デフォルトの20よりも大きな値を使用してCACHE句を指定してください。」
とある.
シーケンスを利用しているので注意するところは一緒ということね。

SCOTT@nonpdb12c> select * from user_sequences;

SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY C O CACHE_SIZE LAST_NUMBER PARTITION_COUNT S K
------------------------------ ---------- ---------- ------------ - - ---------- ----------- --------------- - -
ISEQ$$_93570 1 1.0000E+28 1 N N 20 1 N N

参考
ORACLE-BASE:Identity Columns in Oracle Database 12c Release 1 (12.1)
Inside Oracle – Julian Dyke:Oracle 12c New Feature – Identity Columns

| | コメント (0) | トラックバック (0)

2014年4月20日 (日)

シーケンス.NEXTVALが使えないからぐるぐる〜〜〜っとしていいですか? (30歳 エンジニア 男性)

CREATE TABLE 〜 AS SELECT文でシーケンス.NEXTVALって使えないからぐるぐる〜〜〜っとしたループ処理しないといけないですよね〜。

と質問されたのですが、1文で書けますからね!
(SQL文でワンライナーって言いそうになったけど、飲み込んだw)


準備

SCOTT> l
1 CREATE TABLE table_foobar
2 (
3 id NUMBER PRIMARY KEY
4 ,data VARCHAR2(10)
5* )
SCOTT> /

表が作成されました。

SCOTT> l
1 INSERT INTO table_foobar
2 SELECT
3 LEVEL
4 ,'D'||TO_CHAR(LEVEL,'FM099999999')
5 FROM
6 dual
7 CONNECT BY
8* LEVEL <= 100.
SCOTT> /

100行が作成されました。

SCOTT> commit;

コミットが完了しました。

SCOTT> SELECT * FROM table_foobar ORDER BY id;

ID DATA
---------- ----------
1 D000000001
2 D000000002
3 D000000003
4 D000000004
5 D000000005
6 D000000006
7 D000000007
8 D000000008
9 D000000009
10 D000000010

   ...中略...

90 D000000090
91 D000000091
92 D000000092
93 D000000093
94 D000000094
95 D000000095
96 D000000096
97 D000000097
98 D000000098
99 D000000099
100 D000000100

100行が選択されました。


前述のデータを複製しtable_foobar_tmp表を作成するとします。
なお、DATA列はそのままで、ID列は、次のシーケンスを利用してID = 1..100の順にシーケンスから採番しなおしたい。
(以下のシーケンスの定義からすると、 ID=1 は、1000、 ID=2は、1001にしたい。)

SCOTT> CREATE SEQUENCE seq_foobar start with 1000 maxvalue 999999999;

順序が作成されました。

1文で書けますよね!

SCOTT> l
1 CREATE TABLE table_foobar_tmp
2 AS
3 SELECT
4 seq_foobar.NEXTVAL AS id
5 ,t01.data
6 FROM
7 (
8 SELECT
9 id
10 ,data
11 FROM
12 table_foobar
13 ORDER BY
14 id
15* ) t01
SCOTT> /

表が作成されました。

SCOTT> SELECT * FROM table_foobar_tmp ORDER BY ID;

ID DATA
---------- ----------
1000 D000000001
1001 D000000002
1002 D000000003
1003 D000000004
1004 D000000005
1005 D000000006
1006 D000000007
1007 D000000008
1008 D000000009
1009 D000000010
1010 D000000011

   ...中略...

1090 D000000091
1091 D000000092
1092 D000000093
1093 D000000094
1094 D000000095
1095 D000000096
1096 D000000097
1097 D000000098
1098 D000000099
1099 D000000100

100行が選択されました。

はい、できました!


マニュアルには、「NEXTVALへの参照が含まれる単一のSQL文の中では、Oracleは、次の各行につき1回順序を増加させます。」
と記載されているので、質問してきた方は、マニュアルを読んでいないか、マニュアル読んでなくても実際に試していない食わず嫌い状態だったか、
以下のようなシーケンスの制限に遭遇して、できないんだ!と思い込んでしまった。

病は気からという状態だったのでしょうね。:)


SCOTT> l
1 CREATE TABLE table_foobar_tmp_NG
2 AS
3 SELECT
4 seq_foobar.NEXTVAL AS ID
5 ,t01.data
6 FROM
7 table_foobar t01
8 ORDER BY
9* t01.id
SCOTT> /
seq_foobar.NEXTVAL AS ID
*
行4でエラーが発生しました。:
ORA-02287: ここでは順序番号は使用できません。

エラーメッセージを見ても、Action がRemove the sequence numberだけですからね....

SCOTT> !oerr ORA 2287
02287, 00000, "sequence number not allowed here"
// *Cause: The specified sequence number (CURRVAL or NEXTVAL) is inappropriate
// here in the statement.
// *Action: Remove the sequence number.

そんな時はマニュアルを..
Oracle® Database SQL言語リファレンス 11gリリース2 (11.2) 順序疑似列

順序値の使用方法には、CREATE TABLE ... AS SELECTで使用できると書いてるのに。なんでだろう?
と,、なるかもしれないですが、よ〜〜〜くマニュアルを読んでくださいよ〜っ。

順序値の制限事項にGROUP BY句やORDER BY句を持つSELECT文では使用できないとも書かれているところにちゅうも〜〜〜〜く!

ORDER BY句を含んでいるのでORA-02287回避のために、サブクエリにして別クエリブロック化、シーケンスを利用しているクエリブロックにはORDER BY句を含まないようにしているところがポイント :)

テストデータ作るときとか、知ってると便利ですよ〜と。

SCOTT> l
1 CREATE TABLE table_foobar_tmp
2 AS
3 SELECT
4 seq_foobar.NEXTVAL AS id
5 ,t01.data
6 FROM
7 (
8 SELECT
9 id
10 ,data
11 FROM
12 table_foobar
13 ORDER BY
14 id
15* ) t01
SCOTT> /

Enjoy SQL!

| | コメント (0) | トラックバック (0)

2013年12月21日 (土)

Windows XPのサポート終了 @  うち

Windows XP、Office 2003 のサポート終了まで、12 月 30 日であと 100 日を迎えます。早めの移行をオススメします。 (The Official Microsoft Japan Blogより)

ということで、一足早く、Window XPのサポート終了 @ うち :)


20131221_211712

20131221_211941


20131221_211738

20131221_211752


これで終わり。 :)


20131221_214417


| | コメント (0) | トラックバック (0)

2013年9月 6日 (金)

shutdown immeidateしない、ほかの理由に遭遇! は修正されていた! (12c)

数年前に、shutdown immeidateしない、ほかの理由に遭遇!
というエントリを書いていたことをご存知の方も多いと思います。

リリースされたばかりのOracle Database 12c R1 12.1.0.1.0ではどうなったか知りたくないですか? (俺だけかw)

Oracle Database 12c R1 12.1.0.1.0をリスナーも含め起動します。

※ /optの下がu01なのはこちらの事情なので突っ込みなしでお願いします m(_ _)m

[oracle@emperortetra ˜]$ lsnrctl start

LSNRCTL for Linux: Version 12.1.0.1.0 - Production on 06-9月 -2013 13:27:09

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

/opt/u01/product/12.1.0/dbhome_1/bin/tnslsnrを起動しています。お待ちください...

TNSLSNR for Linux: Version 12.1.0.1.0 - Production
システム・パラメータ・ファイルは/opt/u01/product/12.1.0/dbhome_1/network/admin/listener.oraです。
ログ・メッセージを/opt/u01/diag/tnslsnr/emperortetra/listener/alert/log.xmlに書き込みました。
リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=emperortetra)(PORT=1521)))

(DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))に接続中
リスナーのステータス
------------------------
別名 LISTENER
バージョン TNSLSNR for Linux: Version 12.1.0.1.0 - Production
開始日 06-9月 -2013 13:27:10
稼働時間 0 日 0 時間 0 分 0 秒
トレース・レベル off
セキュリティ ON: Local OS Authentication
SNMP OFF
パラメータ・ファイル /opt/u01/product/12.1.0/dbhome_1/network/admin/listener.ora
ログ・ファイル /opt/u01/diag/tnslsnr/emperortetra/listener/alert/log.xml
リスニング・エンドポイントのサマリー...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=emperortetra)(PORT=1521)))
リスナーはサービスをサポートしていません。
コマンドは正常に終了しました。
[oracle@emperortetra ˜]$ sqlplus / as sysdba

SQL*Plus: Release 12.1.0.1.0 Production on 金 9月 6 13:27:15 2013

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

アイドル・インスタンスに接続しました。

SYS@orcl12c> startup
ORACLEインスタンスが起動しました。

Total System Global Area 534462464 bytes
Fixed Size 2290416 bytes
Variable Size 473959696 bytes
Database Buffers 50331648 bytes
Redo Buffers 7880704 bytes
データベースがマウントされました。
データベースがオープンされました。
SYS@orcl12c> alter pluggable database all open;

プラガブル・データベースが変更されました。

SYS@orcl12c>


別terminalでSQL*Plusを起動しshellに入っておきます。

そして、

今回は特別に!

なんと、もう一度、SQL*Plus経由で、shellに入っておきます。:)

[oracle@emperortetra ˜]$ 
[oracle@emperortetra ˜]$ sqlplus system

SQL*Plus: Release 12.1.0.1.0 Production on 金 9月 6 13:31:13 2013

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

パスワードを入力してください:
最終正常ログイン時間: 金 9月 06 2013 13:30:24 +09:00

Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
に接続されました。
SYSTEM@orcl12c> !
[oracle@emperortetra ˜]$ sqlplus system

SQL*Plus: Release 12.1.0.1.0 Production on 金 9月 6 13:31:22 2013

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

パスワードを入力してください:
最終正常ログイン時間: 金 9月 06 2013 13:31:14 +09:00

Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
に接続されました。
SYSTEM@orcl12c>


前述の状態でpstreeでプロセスツリーを見ると以下のようになっています。

[oracle@emperortetra ˜]$ pstree -ualp oracle
VBoxClient,2099 --draganddrop
├─{VBoxClient},2104
└─{VBoxClient},2105

...中略...

sshd,3854
└─bash,3855
└─sqlplus,3876 \040\040\040\040\040\040
├─bash,3878
│ └─sqlplus,3891 \040\040\040\040\040\040
│ ├─bash,4019
│ └─oracle_3894_orc,3894 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
└─oracle_3877_orc,3877 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))

tnslsnr,3304 LISTENER -inherit
└─{tnslsnr},3305
[oracle@emperortetra ˜]$

確認してみましょう!。11gではshutdown timeoutすら効かず停止できない状態になっていたのですが.....

SYS@orcl12c> shutdown immediate
データベースがクローズされました。
データベースがディスマウントされました。
ORACLEインスタンスがシャットダウンされました。
SYS@orcl12c>

おおおおおおおお〜〜〜、shutdown immediateできた〜〜〜〜! 12cでは修正されたようですね。:)




shutdown immeidateしない、ほかの理由に遭遇!
shutdown immeidateしない、ほかの理由に遭遇! #2
shutdown immeidateしない、ほかの理由に遭遇! #3
shutdown immeidateしない、ほかの理由に遭遇! おまけ
shutdown immeidateしない、ほかの理由に遭遇! おまけのおまけ(でた〜最近、よくあるパターンw)

ablog - shutdown immeidate ...

| | コメント (0) | トラックバック (0)

2013年8月21日 (水)

PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #3 - 消えたPDBの初期化パラメータの謎... Truth is out there.

CDB、PDBの各データベースで変更可能な初期化パラメータを変更してもspfileに書き出しているのはCDBのパラメータだけなのです。

spfileのタイムスタンプを確認してもCDBの時だけしかタイムスタンプは更新されません。もちろん心の目で見てもw

同じことで不思議に感じている方々も多いようです
Living with Oracle / oracle 12c database - pluggable database and spfile/parameter - how does that work?

いったい、どこに書き込んでるんでしょう....

PDB個別に設定した初期化パラメータは、spfileに書き込まれていないのは確かです。

どこかしらない、Cloud上に書いてくれちゃってるのでしょうかw 12c だけに... (ありえんw たぶん...

ということは、DBに書くしかないじゃないですか! 


どうやって調べるか....

あ、そうだ、 alter database set system hogehoge = xxxx scope=spfile をPDBでタイプしてるところを、心の目で見ればいいんだ :)

dbms_monitor.session_trace_enable.............awrレポートでも見えるわな、これw なんで気づかんのだ、俺 ><

....


見つけた

SYS@orcl12c> show con_name

CON_NAME
------------------------------
CDB$ROOT
SYS@orcl12c> select table_name from dba_tables where table_name like '%SPFILE%';

TABLE_NAME
------------------------------
PDB_SPFILE$


SYS@orcl12c> conn sys@pdborcl as sysdba
パスワードを入力してください:
接続されました。
SYS@pdborcl> show con_name

CON_NAME
------------------------------
PDBORCL
SYS@pdborcl> select table_name from dba_tables where table_name like '%SPFILE%';

TABLE_NAME
------------------------------
PDB_SPFILE$


SYS@pdborcl> conn sys@pdbdiscus as sysdba
パスワードを入力してください:
接続されました。
SYS@pdbdiscus> show con_name

CON_NAME
------------------------------
PDBDISCUS
SYS@pdbdiscus> select table_name from dba_tables where table_name like '%SPFILE%';

TABLE_NAME
------------------------------
PDB_SPFILE$


PDB_SPFILE$というSYSユーザの表の書き込んでいました!

CDBのPDB_SPFILE$を覗いてみます。

SYS@orcl12c> show con_name

CON_NAME
------------------------------
CDB$ROOT
SYS@orcl12c> l
1 select
2 db_uniq_name
3 ,sid
4 ,pdbs.name as "PDB NAME"
5 ,psf.name as "PARAMETER NAME"
6 ,value$
7 from
8 pdb_spfile$ psf
9 join v$pdbs pdbs
10 on
11 psf.pdb_uid = pdbs.con_uid
12 order by
13 db_uniq_name
14 ,sid
15 ,pdbs.name
16 ,psf.name
17*
SYS@orcl12c> /

DB_UNIQ_NAME SID PDB NAME PARAMETER NAME VALUE$
-------------- -------------- -------------- ------------------------------ --------------------------------------------------
orcl12c * PDBDISCUS open_cursors 500

DB_UNIQ_NAME SID PDB NAME PARAMETER NAME VALUE$
-------------- -------------- -------------- ------------------------------ --------------------------------------------------
orcl12c * PDBORCL open_cursors 200

いました! いましたよ〜〜〜〜。 PDBで設定した初期化パラメータが! (ちなみに、alter system resetコマンドで上記表から削除されます!)


実は、謎は、まだまだ、続くんです。

上記クエリはCDB上で実行しました。 PDB上で設定した初期化パラメータなのだから、PDB側のpdb_spfile$には対象PDBの初期化パラメータが見えるはず...

PDB上のpdb_spfile$を問い合わせてみると.....

SYS@pdborcl> show con_name

CON_NAME
------------------------------
PDBORCL

SYS@pdborcl> select name,value$ from pdb_spfile$;

レコードが選択されませんでした。


SYS@pdbdiscus> show con_name

CON_NAME
------------------------------
PDBDISCUS

SYS@pdbdiscus> select name,value$ from pdb_spfile$;

レコードが選択されませんでした。

むむ! むむむむむむ!!!!! 私個人は実に普通というか常識的な想像を働かせてPDB上のpdb_spfile$表を覗いたのに、裏切られた!!!

PDB側で設定した初期化パラメータなのにPDB側のpdb_spfile$表には格納されていなんです。 CDB側のpdb_spfile$しか格納されていません。(実はBugなんてことはないですよね)

俺の初期化パラメータなのに!


部下の手柄は上司の手柄....的なw いや〜〜〜な感じですね。


PDB側のpdb_spfile$表には、いつ初期化パラメータが入るのでしょうか?

それとも、いまの仕様では入ることはない....まだ見ぬ先のリリースでは利用されるのでしょうか....謎は深まる。というか気になって寝れないw 

何か気づいたら。続きはあるかもしれません. 一旦シリーズ終了 :)




PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #1
PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #2 - PDBの初期化パラメータは何処!?

| | コメント (0) | トラックバック (0)

2013年8月20日 (火)

PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #2 - PDBの初期化パラメータは何処!?

制限はあるものの、PDBごとに変更可能な初期化パラメータの存在は確認できました。 :)

試してみます!

CDBのOPEN_CURSORSを変更してみます。
他のPDBで変更していないのでCDBの値が継承されるはずです。

$ sqlplus / as sysdba

SQL*Plus: Release 12.1.0.1.0 Production on 月 8月 19 23:12:19 2013

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

アイドル・インスタンスに接続しました。

SYS@orcl12c> startup
ORACLEインスタンスが起動しました。

Total System Global Area 534462464 bytes
Fixed Size 2290416 bytes
Variable Size 473959696 bytes
Database Buffers 50331648 bytes
Redo Buffers 7880704 bytes
データベースがマウントされました。
データベースがオープンされました。
SYS@orcl12c> alter pluggable database all open;

プラガブル・データベースが変更されました。

SYS@orcl12c>
SYS@orcl12c> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 300
SYS@orcl12c>
SYS@orcl12c> alter system set open_cursors=400 scope=both;

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

SYS@orcl12c> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 400
SYS@orcl12c>


PDBの初期化パラメータ値はCDBの初期化パラメータ値を継承しています!

SYS@orcl12c> conn sys@pdborcl as sysdba
パスワードを入力してください:
接続されました。
SYS@pdborcl>
SYS@pdborcl> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 400


PDBの初期化パラメータを変更してみます。(MEMORYとSPFILEを変更)

SYS@pdborcl> alter system set open_cursors=200 scope=both;

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

SYS@pdborcl> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 200

変更できますね :)


ついでなので、もひとつのPDBの初期化パラメータも他の値に変更してみます。(同じくscope=bothで)

変更前なのでOPEN_CURSORSパラメータはCDBの同パラメータを継承しています!

SYS@pdborcl> conn sys@pdbdiscus as sysdba
パスワードを入力してください:
接続されました。
SYS@pdbdiscus>
SYS@pdbdiscus> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 400

400から500に増やてみます。

SYS@pdbdiscus> alter system set open_cursors=500 scope=both;

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

SYS@pdbdiscus> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 500

問題なく変更できました。:)  順調、順調


SQL*Plusのshow parameter同様に、v$parameterではCDB,PDB毎のパラメータのみ参照できるようですね。ふむふむ。

SYS@orcl12c> select name,value from v$parameter where name='open_cursors';

NAME VALUE
------------------------------ ------------------------------
open_cursors 400

SYS@orcl12c> conn sys@pdborcl as sysdba
パスワードを入力してください:
接続されました。
SYS@pdborcl> /

NAME VALUE
------------------------------ ------------------------------
open_cursors 200

SYS@pdborcl> conn sys@pdbdiscus as sysdba
パスワードを入力してください:
接続されました。
SYS@pdbdiscus> /

NAME VALUE
------------------------------ ------------------------------
open_cursors 500

ついでなので、もう少し検証してみましょう。

初期化パラメータを変更する際、scope=bothとしたのでSPFILEにも格納されているはずですよね。

マルチテナント化されてもSPFILEは一つ!  確認しておきましょう。

SYS@orcl12c> !find $ORACLE_BASE -name spfile*.ora
/opt/u01/product/12.1.0/dbhome_1/dbs/spfileorcl12c.ora

一つだけです!


中身がどうなっているか確認しておきましょう。

SYS@orcl12c> !strings $ORACLE_HOME/dbs/spfileorcl12c.ora
orcl12c.__data_transfer_cache_size=0
orcl12c.__db_cache_size=33554432
orcl12c.__java_pool_size=16777216
orcl12c.__large_pool_size=50331648
orcl12c.__oracle_base='/opt/u01'#ORACLE_BASE set from environment
orcl12c.__pga_aggregate_target=570425344
orcl12c.__sga_target=1090519040
orcl12c.__shared_io_pool_size=0
orcl12c.__shared_pool_size=213909504
orcl12c.__streams_pool_size=0
*.audit_file_dest='/opt/u01/admin/orcl12c/adump'
*.audit_trail='db'
*.compatible='12.1.0.0.0'
*.control_files='
/opt/u01/oradata/orcl12c/control01.ctl','/opt/u01/fast_recovery_area/orcl12c/control02.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_name='orcl12c'
*.db_recovery_file_dest='/opt/u01/fast_recovery_area'
*.db_recovery_file_dest_size=4800m
*.diagnostic_dest='/opt/u01'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orcl12cXDB)'
*.enable_pluggable_database=true
*.memory_max_target=0
*.memory_target=0
*.open_cursors=400
*.pga_aggregate_target=536870912
*.processes=300
*.remote_login_passwordfile='
EXCLUSIVE'
*.sga_max_size=536870912
*.undo_tablespace='UNDOTBS1'

あれれれれれれ〜〜、 なんで CDBのパラメータしかないんでしょう!!!!!!! 

scope=bothと指定してもエラーのでずに設定されてる。 

SPFILEのバイナリ部分だけに記録さされているのか?。イヤそんなことはないだろ!

scope=memoryと同じではないことを確認するために一旦、再起動!! 

SYS@orcl12c> alter pluggable database all close;

プラガブル・データベースが変更されました。

SYS@orcl12c> shutdown
データベースがクローズされました。
データベースがディスマウントされました。
ORACLEインスタンスがシャットダウンされました。
SYS@orcl12c>
SYS@orcl12c> startup
ORACLEインスタンスが起動しました。

Total System Global Area 534462464 bytes
Fixed Size 2290416 bytes
Variable Size 473959696 bytes
Database Buffers 50331648 bytes
Redo Buffers 7880704 bytes
データベースがマウントされました。
データベースがオープンされました。
SYS@orcl12c>
SYS@orcl12c> alter pluggable database all open;

プラガブル・データベースが変更されました。

SYS@orcl12c>
SYS@orcl12c> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 400
SYS@orcl12c>
SYS@orcl12c> conn sys@pdborcl as sysdba
パスワードを入力してください:
接続されました。
SYS@pdborcl> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 200
SYS@pdborcl>
SYS@pdborcl> conn sys@pdbdiscus as sysdba
パスワードを入力してください:
接続されました。
SYS@pdbdiscus> show parameter open_cursors

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 500


むむ!  むむむ!!!!!  SPFILEには格納されていない..ようなのに......

PDBの初期化パラメータは、何処にあるんだ〜〜〜〜!。 

次回へつづく!

次回、心の目を研ぎすませば、見えてくるものがある....みえないものもある...かもしれない

...乞うご期待w




PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #1

| | コメント (0) | トラックバック (0)

2013年8月18日 (日)

PDB毎に初期化パラメータを変更できるんですよ!(制限はあるけど) #1

11g R2と12c R1の初期化パラメータ(隠しパラメータを含む)の差分をチェックしようとして気づいたのですが....

いままでとちがうんですよ。 シングルインスタンスなのに、なぜ、同じパラメータが4つあるんだ?

SYS@orcl12c> l
1 select
2 count(ksppinm)
3 from
4 x$ksppi
5 where
6* ksppinm='open_cursors'
SYS@orcl12c> /

COUNT(KSPPINM)
--------------
4
SYS@orcl12c> l
1 select
2 count(distinct ksppinm)
3 from
4 x$ksppi
5 where
6* ksppinm='open_cursors'
SYS@orcl12c> /

COUNT(DISTINCTKSPPINM)
----------------------
1

実は、CDB (Container Database)が1つ、PDB SEED (Pluggable Database Seed)が1つ、PDB (Pluggable Database)が2つあるんです.....1インスタンスに

SYS@orcl12c> l
1 select
2 inst_id
3 ,cons.name
4 ,ksppinm
5 from
6 x$ksppi params
7 join v$containers cons
8 on
9 params.con_id = cons.con_id
10 where
11* ksppinm='open_cursors'
SYS@orcl12c> /

INST_ID NAME KSPPINM
---------- ------------------------------ ----------------------------------------
1 CDB$ROOT open_cursors
1 PDB$SEED open_cursors
1 PDBORCL open_cursors
1 PDBDISCUS open_cursors

初期化パラメータはCDBだけでなく、PDB毎に設定できるようになっているようです!


ただし、よくよく調べてみると、PDBで変更可能な初期化パラメータは制限されているんです。

今後のためにPDBで変更可能な初期化パラメータ一覧(隠しパラメータ含む)をHTML形式でスプールしておきました。
Oracle Database 12c r1 12.1.0.1.0 - Pluggable Database Modifiable Parameters (including hidden parameters)

何かのときに役にたつかも... :)

...え、どうやって隠しパラメータの分もリストしたのかって?、 PDBで変更できる初期化パラメータはv$parameterのISPDB_MODIFIABLE列を見ればわかるのですが、隠しパラメータの分まではでてないですものね〜、

v$parameterを心の目で見ればいいんですよ。(謎


次回は、PDBで設定できる初期化パラメータを変更していて気づいたことを書く予定 :)

| | コメント (0) | トラックバック (0)

2013年8月 8日 (木)

Difference of Initialization Parameters between 11g r1 (11.1.0.6.0) and 12c r1 (12.1.0.1.0) - including hidden params

※2014/8/4 修正、追記
比較したバージョンが誤っていたため訂正しました。正しくは、11g R1 11.1.0.6.0でした。


型の差分までは取得しませんでしが、Oracle11g R2 (11.2.0.1.0)とOracle12c R1 (12.1.0.1.0)の初期化パラメータ(隠しパラメータ含む)の差分をHTML化しました。(クエリ結果をHTML形式でspoolしただけですが)

まだどのような差分があるのか見切れていませんが、じ〜〜〜っくりと見ようと思っています :)

参考 (パラメータ数)
11g R2 11.2.0.1.0
11g R1 11.1.0.6.0
パラメータ総数 : 2049
隠しパラメータ数 : 1755 (うち ダブルアンダースコア隠しパラメータ数 : 10 )

11g R1 11.2.0.1.0
パラメータ総数 : 2399
隠しパラメータ数 : 2057 (うち ダブルアンダースコア隠しパラメータ数 : 10 )

12c R1 12.1.0.1.0
パラメータ総数 : 3351
隠しパラメータ数 : 2984 (うち ダブルアンダースコア隠しパラメータ数 : 11 )

隠しパラメータの増加が目立ちます.... (@@)

Difference of Initialization Parameters between 11g r1 (11.1.0.6.0) and 12c r1 (12.1.0.1.0)

| | コメント (0) | トラックバック (0)

2013年7月25日 (木)

Oracle Database 12c New Feature : Invisible Columnsの怪w s/怪w/謎/

Oracle® Database New Features Guide 12c Release 1 (12.1) - 1.5.5.3 Invisible Columns
Oracle® Database Administrator's Guide 12c Release 1 (12.1) - Understand Invisible Columns


予告通り Invisible Columnの小ネタを。
(祭りに呼び出されて書けないかかもしれない、という状況にはならずw この時間に自宅にいるのはラッキーw)

本題とは関係ないですが、改行されないのはご愛嬌:)

SYS@orcl12c> startup pluggable database pdborcl;
ラガブル・データベースがオープンされました。SYS@orcl12c>
SYS@orcl12c>
SYS@orcl12c> conn scott@pdborcl
パスワードを入力してください:
接続されました。
SCOTT@pdborcl>

Invisible columnを含む表を作成します。(問題なく作成されました。当たり前か..)

SCOTT@pdborcl> create table hoge (a number, b number, c number invisible);

表が作成されました。


SQL*Plusのdescコマンドで見てみます。マニュアルの通り、Invisible columnはリストされません。

SCOTT@pdborcl> desc hoge
名前 NULL? 型
----------------------------------------- -------- ----------------------------
A NUMBER
B NUMBER


さあ、ここから、気持ち悪い事が起きますよ〜〜。よ〜〜〜く見ててくださいね〜〜。

列は隠れていますが、存在を知って、Invisible Columnでもカラムを指定すればデータを登録できるんです。見えてないだけなんです!

SCOTT@pdborcl> insert into hoge(a,b,c) values(1,2,4);

1行が作成されました。


カラム指定しないとa列と、b列しかないものとして扱われ、見慣れたエラー、「ORA-00913: 値の個数が多すぎます。」となります。

いい感じの気持ち悪さでしょ :)

SCOTT@pdborcl> insert into hoge values(11,12,14);
insert into hoge values(11,12,14)
*
行1でエラーが発生しました。:
ORA-00913: 値の個数が多すぎます。

2列分なら正常に登録できます。見えるのはa列とb列の2列なので当然と言えば当然。

SCOTT@pdborcl> insert into hoge values(11,12);

1行が作成されました。

SELECTリストに * を指定すれば、ほらほら、自然です。 a列とb列だけがリストされています。

SCOTT@pdborcl> select * from hoge;

A B
---------- ----------
1 2
11 12


でも...c列の存在を知っている人には....見えちゃうんです。

SCOTT@pdborcl> select a, b, c from hoge;

A B C
---------- ---------- ----------
1 2 4
11 12 [null]

同様に削除や更新もできちゃいます。見えないものが見えてる人にはw。
(その存在を知らない人には見えないわですが...)

SCOTT@pdborcl> update hoge set c = 14 where c is null;

1行が更新されました。

SCOTT@pdborcl> select a, b, c from hoge where c = 14;

A B C
---------- ---------- ----------
11 12 14

SCOTT@pdborcl> delete from hoge where c = 14;

1行が削除されました。

SCOTT@pdborcl> select a, b, c from hoge;

A B C
---------- ---------- ----------
1 2 4


ORDER BY句でも、その存在さえ知っていればいろいろイタズラできますね。

SCOTT@pdborcl> select a,b,c from hoge order by c desc;

A B C
---------- ---------- ----------
11 12 14
1 2 4


おもしろいですね。

SCOTT@pdborcl> select * from hoge order by c desc;

A B
---------- ----------
11 12
1 2

Invisible columnには索引も作れます!

SCOTT@pdborcl> create index hoge_ix on hoge(c);

索引が作成されました。

SCOTT@pdborcl> set autot trace exp
SCOTT@pdborcl> select * from hoge where c = 14;

実行計画
----------------------------------------------------------
Plan hash value: 3349209795

-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| HOGE | 1 | 39 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | HOGE_IX | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("C"=14)

Note
-----
- dynamic statistics used: dynamic sampling (level=2)

SCOTT@pdborcl>

次のようなイタズラもできます! うひゃw うひゃw 

相手の腕試をしするにはぴったりなイタズラです(嘘

SCOTT@pdborcl> alter table hoge modify (c number not null);

表が変更されました。

SCOTT@pdborcl>
SCOTT@pdborcl> insert into hoge(a, b) values(100,111);
insert into hoge(a, b) values(100,111)
*
行1でエラーが発生しました。:
ORA-01400: ("SCOTT"."HOGE"."C")にはNULLは挿入できません。


イタズラはこれくらいにして、Invisible Columnをディクショナリビューから覗いてみましょう。
Invisible Indexもディクショナリビューからいろいろと情報を得ることができましたよね! 
(多分、同じように見れるのでは...と思っていたが...

desc[ribe]コマンドではInvisible Columnは見えませんが、 ALL/DBA/USER_TAB_COLUMNSからは見る事ができます。

racle® Database Reference 12c Release 1 (12.1) - ALL_TAB_COLUMNS


ただし、見る事はできるのですが、その列がInvisible Columnかどうかを確認する列がないんですよ。(ぱっと見)

例えば、Invisible IndexだとALL/DBA/USER_INDEXES確認できます

SCOTT@pdborcl> select index_name,visibility from user_indexes where table_name='HOGE';

INDEX_NAME VISIBILIT
------------------------------ ---------
HOGE_IX INVISIBLE
HOGE_PK VISIBLE


そこで疑問!
SQL*PLusのdesc[ribe]コマンドはどのような情報を基にVisible Columeだけを表示してるんでしょうねぇ〜。

これ、探すのにてこずりましたよ!

以下のマニュアルにも記載されていますが、Visible/InvisibleにするとColumn Orderが変化することにも関連しているようです。
Oracle® Database Administrator's Guide 12c Release 1 (12.1) - Understand Invisible Columns

desc[ribe]ではInvisible Columnは見えません

SCOTT@pdborcl> desc hoge
名前 NULL? 型
----------------------------------------- -------- ----------------------------
A NUMBER
B NUMBER


どのような情報を見てInvisibleであると判断しているのか....

SCOTT@pdborcl> select column_name,data_type,nullable,column_id from user_tab_columns where table_name='HOGE' order by column_id;

COLUMN_NAME DATA_TYPE N COLUMN_ID
------------------------------ ---------- - ----------
A NUMBER Y 1
B NUMBER Y 2
C NUMBER N [null]


COLUMN_IDがNULLである列がInvisible Columns !!!!

SCOTT@pdborcl> l
1 select
2 column_name
3 ,data_type
4 ,nullable
5 ,column_id
6 from
7 user_tab_columns
8 where
9 table_name='HOGE'
10 and column_id is not null
11 order by
12* column_id
SCOTT@pdborcl> /

COLUMN_NAME DATA_TYPE N COLUMN_ID
------------------------------ ---------- - ----------
A NUMBER Y 1
B NUMBER Y 2

いずれ、ALL/DBA/USER_TAB_COLUMNSに、VISIBILITYという列が追加されるんじゃないかと想像してます :)

それまでは俺俺 USER_TAB_COLUMNSビューでも作っておくと便利かも...しれない。

SCOTT@pdborcl> create view my_tab_columns as
2 select
3 user_tab_columns.*
4 ,case when user_tab_columns.column_id is null
5 then 'INVISIBLE' else 'VISIBLE' end as VISIBILITY
6 from
7 user_tab_columns
8 ;

ビューが作成されました。
SCOTT@pdborcl> select column_name,data_type,nullable,visibility from my_tab_columns where table_name='HOGE' order by column_id;

COLUMN_NAME DATA_TYPE N VISIBILIT
------------------------------ ---------- - ---------
A NUMBER Y VISIBLE
B NUMBER Y VISIBLE
C NUMBER N INVISIBLE


このような特性を理解した上で、どのような場面で使うと便利なのか、じ〜〜〜〜っくり考えてみたいと...と思いつつ...寝ます。パタリ。 1:48am


| | コメント (0) | トラックバック (0)

2013年7月13日 (土)

Oracle Database 12c R1 : コンテナデータベースとプラガブルデータベースを歩きやすくしてみる

世界を見渡せば、かなりの方がOracle Database 12cのインストール手順を公開し始めているのでインストール後の話を書いておきますね。

インストール時にPluggable Databaseも同時に作成してもtnsnames.oraにはContainer Databaseへの接続定義しか無かったんです。(私のインストール手順に問題がなければ..なんですが)
無くてもEasy connectを使えば接続できるので問題はないんですが...

ただ、Easy connectで毎回タイプするのも面倒(少々長いし)なので、tnsnames.oraにPluggable Database接続用定義を作成しておきましょう。

定義内容はいままでと変わらず。 SERVICE_NAMEの箇所を接続先のPluggable Database名にするだけ。
(Pluggable Database名と書いたが、マニュアル読みきれてないので表現は間違っているかもしれません。間違っていたら後で修正します)

[oracle@emperortetra]$ cat $ORACLE_HOME/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File: /opt/u01/product/12.1.0/dbhome_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

# for Container Database : orcl12c
ORCL12C =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = emperortetra)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl12c)
)
)

# for Pluggable Database : pdborcl
PDBORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = emperortetra)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = pdborcl)
)
)

本題である、歩きやすくするための設定がこれ。

複数のPluggable DatabaseとContainer Database間を旅することも多くなりそうですから、今、自分はどこにいるのか把握しやすくしておいたほうが吉かと。

12c以前から定番で設定している内容ではあるのですが。赤字部分がポイント

目立たないけど、地味に大切なのが、 set tab off だと思っているのは私だけだろうか!w 
(ここのところ、set tab offじゃない人のコピペしてきた、位置ズレまくりの実行計画見せられててイライラしている影響もある :)


それ以外の設定も、設定してるだけで、「むむむ、この方できるかも!」 と、
思わせる(思わせるだけですからね!w つかみはOK的な感じなので、あとはあなた次第)設定内容なので大切と言えば大切。
(login.sqlでもOK)

[oracle@emperortetra]$ cat $ORACLE_HOME/sqlplus/admin/glogin.sql
--
-- Copyright (c) 1988, 2005, Oracle. All Rights Reserved.
--
-- NAME
-- glogin.sql
--
-- DESCRIPTION
-- SQL*Plus global login "site profile" file
--
-- Add any SQL*Plus commands here that are to be executed when a
-- user starts SQL*Plus, or uses the SQL*Plus CONNECT command.
--
-- USAGE
-- This script is automatically run
--
set linesize 180
set pagesize 10000
set timi on
set time on
define _EDITOR=vi
col table_name for a30
col column_name for a30
col segment_name for a30
col tablespace_name for a30
col index_name for a30
col partition_name for a30
col sub_partition_name for a30
set sqlp "_USER'@'_CONNECT_IDENTIFIER> "
set tab off
[oracle@emperortetra]$


リスナーを起動してステータスを見てみましょう (u01が/optの下にあるのは内緒w じゃないw
まだ、データベースを起動していないのでこんな感じです。

[oracle@emperortetra]$ lsnrctl status

LSNRCTL for Linux: Version 12.1.0.1.0 - Production on 06-7月 -2013 09:10:04

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

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


Container Databaseの起動(12cより前のOracle Databaseと同じですね)

Container Databaseである orcl12c がSQL*Plusのプロンプトに表示されていますよね!! :)

[oracle@emperortetra]$ sqlplus / as sysdba

SQL*Plus: Release 12.1.0.1.0 Production on 土 7月 6 09:25:22 2013

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

アイドル・インスタンスに接続しました。

09:25:22 SYS@orcl12c> startup
ORACLEインスタンスが起動しました。

Total System Global Area 1653518336 bytes
Fixed Size 2289016 bytes
Variable Size 1040188040 bytes
Database Buffers 603979776 bytes
Redo Buffers 7061504 bytes
データベースがマウントされました。
データベースがオープンされました。
09:25:32 SYS@orcl12c>



Pluggable Databaseを起動します!

09:25:34 SYS@orcl12c> alter pluggable database pdborcl open;

プラガブル・データベースが変更されました。

経過: 00:00:00.86


Pluggable DatabaseのSYS、SYSTEMおよび、SCOTTユーザに接続してみます!
09:25:53 SYSTEM@orcl12c> conn sys@pdborcl as sysdba
パスワードを入力してください:
接続されました。
09:26:06 SYS@pdborcl>
09:26:07 SYS@pdborcl>
09:26:07 SYS@pdborcl> conn system@pdborcl
パスワードを入力してください:
接続されました。
09:26:34 SYSTEM@pdborcl>
09:26:34 SYSTEM@pdborcl>
09:26:35 SYSTEM@pdborcl> conn scott@pdborcl
パスワードを入力してください:
接続されました。
09:26:50 SCOTT@pdborcl>
09:26:51 SCOTT@pdborcl>
09:26:51 SCOTT@pdborcl>


SQL*Plusのプロンプトに接続先の情報を表示しておくと便利ですよね。Database間を歩きやすく、迷子になりにくくなりますよ! :)

おまけ
Container Databaseおよび、Pluggable Database起動後のlistenerのステータスは以下の通り。

[oracle@emperortetra]$ lsnrctl status

LSNRCTL for Linux: Version 12.1.0.1.0 - Production on 06-7月 -2013 09:28:09

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

(DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))に接続中
リスナーのステータス
------------------------
別名 LISTENER
バージョン TNSLSNR for Linux: Version 12.1.0.1.0 - Production
開始日 06-7月 -2013 09:06:38
稼働時間 0 日 0 時間 21 分 31 秒
トレース・レベル off
セキュリティ ON: Local OS Authentication
SNMP OFF
パラメータ・ファイル /opt/u01/product/12.1.0/dbhome_1/network/admin/listener.ora
ログ・ファイル /opt/u01/diag/tnslsnr/emperortetra/listener/alert/log.xml
リスニング・エンドポイントのサマリー...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=emperortetra)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=emperortetra)(PORT=5500))(Security=(my_wallet_directory=/opt/u01/admin/orcl12c/xdb_wallet))(Presentation=HTTP)(Session=RAW))
サービスのサマリー...
サービス"orcl12c"には、1件のインスタンスがあります。
インスタンス"orcl12c"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"orcl12cXDB"には、1件のインスタンスがあります。
インスタンス"orcl12c"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"pdborcl"には、1件のインスタンスがあります。
インスタンス"orcl12c"、状態READYには、このサービスに対する1件のハンドラがあります...
コマンドは正常に終了しました。
[oracle@emperortetra]$

Enjoy Oracle Database 12c R1 :)


| | コメント (0) | トラックバック (0)

2013年5月11日 (土)

Automator : サービスの作成から削除まで (FAQ)

私のブログでもアクセス数の多いAutomator de ファイル名一括変換のコメントへ答えた次いでなので、もう少し詳しく書いておきますね。

これもOS XではFAQだと思いますますが、Automatorの認知度が低いのかな〜。


サービスを作るほうはこのヘルプで分かるかと。
Mac 101:Automator 

削除のヘルプページを探せないw (俺の検索の仕方がまずいのかw..


ってことで、Automatorでサービス(ワークフローの仲間)を作成して、メニューから削除するまでの流れを。

Autometorでサービスを作成します。
DeveloperToolsのプロファイルをテキストに書き出すだけの簡単なサービスを作るところから。

アプリケーション>Automatorを起動

Automator_icon


  1. 「書類の種類を選択してください」ダイアログ>「サービス」アイコンをクリック>「選択」ボタンをクリック
    Making_services001
  2. 「入力なし」、「Finder.app」限定で使えるようにしておきます。利用できる範囲は適当に設定してね。
    Making_services002

  3. 「ライブラリ」ペイン>「アクション」>「ユーティリティ」>「システムプロファイル」アクションをワークフローペインへドラッグ&ドロップ
    「システムプロファイル」アクションの「書き出しフォーマット」メニューは「テキスト」を、「カテゴリ」チェックボックスは「DeveloperTools」を選択
    Making_services003

  4. 「ライブラリ」ペイン>「アクション」>「テキスト」>「新規テキストファイル」アクションをワークフローペインへドラッグ&ドロップ
    「新規テキストファイル」アクションの各パラメータを設定。(ファイルフォーマット、ファイル名、作成場所、置換有無、エンコーディング)
    Making_services004

  5.  (「メニュー」>「ファイル」>「保存」) or ⌘S >「サービスを別名で保存」テキストボックスへサービス名入力>「保存」ボタンをクリック
    Making_services005

  6.  保存すると指定した「アプリケーションメニュー」の「サービス」サブメニューに保存した名称で表示される
    Making_services006


「test」というサービスを実行すればDeveloperToolsのプロファイルがテキストファイルとしてデスクトップに保存されます。


いよいろこれからが、今回の本題。「アプリケーションメニュー」の「サービス」サブメニューに追加された「test」というサービスをどうやって削除するのか?

  1. 「アプリケーション」メニュー>「サービス」サブメニュー>「サービス環境設定...」をクリック
    Removing_service001
  2. 「キーボード」環境設定>「キーボードショートカット」タブ>「説明」ペイン>「サービス」>「test」を選択
    Removing_service002

  3. 「test」を右クリック>ポップアップメニューの「Finderに表示」を選択
    Removing_service003

  4. 「test.workflow」が表示される。
    Removing_service004

  5. 「test.workflow」を右クリック>ポップアップメニューの「ゴミ箱に入れる」を選択
    Removeing_service005

  6. 「test.workflow」はゴミ箱です:)、ゴミ箱ではなくても ~/ライブラリ/Servicesフォルダから取り除けば同じです。(また使いたくなったら戻せばいいですし)
    Removing_service007


はい、サービスメニューから消えました :)

Removing_service008


Enjoy Automator!


| | コメント (0) | トラックバック (0)

2013年5月 6日 (月)

散らかってる部屋へ、突然の来客、散らかってるものはどうします? 

散らかってる部屋へ、突然の来客、散らかってるものはどうします? 

とりあえず、押入やクローゼットへ放り込むw

そんな、地味だけど便利な機能がこれ。

そういえば、Windowsのデスクトップが書類だらけで埋まっている方いますよね。

Macな方なら、そんなときでも慌てずに、ささっと、ね :)

20130506_222712


とりあえず、片付けちゃいたいファイルをすべて選択>ポップアップメニュー「選択項目(N項目)から新規フォルダ」を選択するだけ!

| | コメント (0) | トラックバック (0)

2013年5月 2日 (木)

FileVault de USBメモリ暗号化

2009年にUSBメモリ de 暗号化ディスクイメージというエントリを書ていたのですが、Moutain LionではFileVaultが機能拡張され、USBメモリにディスクイメージを作成するという小細工が不要になったよ! というお話。

ネタとしては新しくないのですが意外としならない方が多いようなのでFAQとして書いておきますね。

今回利用するUSBメモリはMercedes-Benz Connection Roppingiでポイント交換してきたキー型USB 4GBを使用しました。
(普通のUSBメモリなので暗号化はありません。なのでそのままだとセキュリティー面で弱いわけです。はい)

Mercedesusb4g_2

Mercedesusb4b_1

と、いうことで、File Vault de USBメモリ暗号化作戦! 開始。

  1. USBメモリをマウント
  2. 001

  3. 「Finder」>「アプリケーション」>「ユーティリティ」>「ディスクユーティリティ」>ダブルクリックでディスクユーティリティを起動

  4. マウントしたUSBメディア>「パーティション」タブ>「パーティションレイアウトメニュー」>「1パーティション」>パーティション情報「名前」>フォーマット「MacOS拡張(ジャーナリング)」>「オプション」ボタンをクリック
  5. 002

  6. 「GUIDパーティションテーブル」ラジオボタン>「OK」ボタンクリック
  7. 003

  8. 「適用」ボタンをクリックしてパーティションを作成
  9. 004

  10. 右クリック>"USBのボリューム名"を暗号化メニュー選択
  11. 005

  12. 「暗号化パスワード」、「パスワードの確認」、「パスワードのヒント」を入力
    「ディスクを暗号化」ボタンクリックで暗号化開始
  13. 006

  14. 7.で「鍵アイコン」ボタンをクリックするとパスワードアシスタントが表示される(オプション)
  15. 007_passward_assistant

  16. 7.の「ディスクを暗号化」ボタンをクリック後、4GBなら3分余(メモリサイズ依存)で暗号化された
    暗号化処理中のポップアップメニューには、「”パーティション名”を暗号化中...」と表示される
  17. 008

    利用したマシンは、MacPro / OS X : Moutain Lion 10.8.3
    Os_version

  18. ポップアップメニューに「”パーティション名”を暗号化解除中...」と表示されたら暗号化終了
    (暗号化処理中、そして暗号化処理終了をもっと見やすくしてほしいですよね。ダウンロード時のようにアイコン上にプログレスバーを表示するとか)
  19. 009_about_3min

  20. FileVaultで暗号化されたUSBメモリーをマウントするとパスワードが要求されます! :)
    以下は1世代前のMac OS Xつまり、Lionにマウントした例です
  21. Usbmoutainlion001
    Usbmoutainlion002


| | コメント (0) | トラックバック (0)

2013年5月 1日 (水)

TimeMachine応用編

容量不足のMBAをMountain Lionへ移行する際にTimeMachineを活用するのはありだな。

仕事でヘビーにMBAを利用していると新しいOSがリリースされたとしてもすぐには飛びつけないんですよね。昨年がそういう状況でした。:)

やっと落ち着いたのでGW前半で母艦と同じMountain Lionへ移行しようと思ったらMBAの空き容量不足が発覚!w


TimeMachineをバックアップ兼一時保管として利用することに...

・TimeMachineにバックアップを取得しておく。
・デスクトップや書類フォルダにあるファイルを一旦削除。
・Mountain Lionへ移行
・必要なファイルだけをリストア

:) 超簡単w

20130501_114312

| | コメント (0) | トラックバック (0)

2013年3月 9日 (土)

VirtualBoxのWindows7だとPaSoRi RC-S380認識しないのな

妻がPaSoRi RC-S380を使いたいというので、ダメもとで試してみた。 ダメだった。(^^;;;

以上、ご報告までw


ちなみに、リアルなPCにWindows8インストールしたら一発で認識した。 人柱ばんざ〜い:)

PASMOの履歴って、カード内の20件しか見れないのな orz.... 無駄遣いなのは間違いないw

Pasori_with_mac

VirtualBox4.2.8+Windows7で使おうとすると以下のように認識してくれない。残念

20130305_235713


20130305_235955


| | コメント (0) | トラックバック (0)

2012年9月30日 (日)

あ、Mountain LionにはX11含まれてなかったんだった

Mountain LionにはX11含まれてなかったことを忘れてた><


ということで、ナビゲートされるので以下、XQuartsのサイトからダウンロードするべし。という備忘録

http://xquartz.macosforge.org/landing/

20120930_213625



20120930_214535

20120930_214413

| | コメント (0) | トラックバック (0)

2012年6月23日 (土)

Mac OS X Lion (Server) で Hyper-Threading を ON/OFFする方法

Mac OS X Lion (Server) でHyper-ThreadingのON/OFFを試してみた。

Terminalからnvramコマンドたたけばできるのね。脳のシワ1つ増えたw

(sudo nvram -h でヘルプでるから!)

HTを止めて、12coreで動作させてみる。
設定内容を確認しとく

discus-mother:˜ oracle$ sudo nvram -p
SystemAudioVolume 0
EFIBluetoothDelay %b8%0b
fmm-computer-name discus_mother
discus-mother:˜ oracle$

SMT=0を設定するとHTをOFFにできる。設定内容も確認しておくよ。

discus-mother:˜ oracle$ sudo nvram SMT=0
discus-mother:˜ oracle$ sudo nvram -p
SMT 0
fmm-computer-name discus_mother
EFIBluetoothDelay %b8%0b
SystemAudioVolume 0
discus-mother:˜ oracle$

設定内容を反映させるには再起動が必要なのでお忘れなく。
(いったん起動してから、再び、起動音とともに再起動、ようするに、2度起動音がでるので驚かないでね)

アプリケーション>ユーティリティ>アクティビティモニター>⌘2 でCPU使用率フローティングウィンドウを表示して確認!
確かに12CPUに見える。次いでなので軽く負荷をかけてみた :)


20120622_235639


再び、HTをONにして24CPUにしてみる。

discus-mother:˜ oracle$ sudo nvram -d SMT
discus-mother:˜ oracle$ sudo nvram -p
SystemAudioVolume 0
EFIBluetoothDelay %b8%0b
fmm-computer-name discus_mother
discus-mother:˜ oracle$

ここで再起動。

CPU使用率フローティングウィンドウ。こんどは思いきって負荷をかけてみた。お〜〜〜〜〜っw




20120623_01129

20120621_03925


| | コメント (0) | トラックバック (0)

2012年6月 7日 (木)

MacOS X Lion で HP Photosmart C6175をスキャナーとして使う方法

久々にというか、MacOS X Lionにしてから初めて HP Photosmart C6175 をスキャナーとして使おうとしてハマった。

Mac OS X LionになってからApple Software Update経由でプリンタドライバが提供されるようになり、以前使ってたPhotosmartのユーティリティが無くなってしまった。ので をスキャナとして利用する方法がわかりにくい… ><

としばしぼーーーぜん。

あ、マニュアル見ればいいよね! とHPさん(HPはHOME PAGEの略じゃないからね!)のページを見てみると…

http://h10025.www1.hp.com/ewfrf/wc/document?docname=c02942039&lc=ja&cc=jp&dlc=ja&product=1153493#N979

このページだと「システム環境設定」>「プリントとスキャン」からスキャナーとして使えるような記載に読めるような読めないような…わかりずら〜〜〜い。
(あ、ちなみに私のは、Mac OS X Lion 10.7.4です)

いろいろ試してみたものの実際にはそのようなペインは無いんです。はい。

と、再び、ぼ〜〜〜〜〜ぜん…

ではどうするか、Mac OS X にはイメージキャプチャというアプリケーションが付属しています! それを使えばいいの! (キリっ

20120607_03750


| | コメント (0) | トラックバック (0)

2012年1月30日 (月)

AWRレポート、AWR SQLレポート一括取得スクリプトを作ったよ。

Statspackレポートもそうなのですが、AWRレポート/AWR SQLレポートも個別に取得していると凄ーく辛いんですよね。一日分出力するとか、AWRレポートで処理時間の長いSQL文のAWR SQLレポートを個別に取得しようとなると...

ただでさえ忙しいのに、AWRレポート取得するのに時間掛けたくないですよね。

ということで、やっつけで作ったのですが、そのまま載せるのもあれなんで、やっつけで作った感じを多少減らしてgithubに公開しました。;)

https://github.com/discus/Oracle-AWR-batch-generation-script/blob/master/awrreport_batch.sql


もっといい感じに改造してくれるといいな〜とかとか... :)

Oracle11g R1/R2 Enterprise Edition、HTML形式で出力します。(RAC環境では試してないので多分だめかと。)。
AWRを利用するには追加ライセンスが必要なのでご注意を


使い方は・・

SQL*plusを起動し、select any dictionaryシステム権限、dbms_repositoryパッケージの実行権限が付与されたユーザで接続して実行するだけ。
SYSTEMユーザでやる事が多いけど、所変わればなんとやらなので・・・そこんとこよろしく。(w


一括取得なので実行当日を含めてn日分のAWRレポートを取得し、同時に処理時間の長いTop20のAWR SQLレポートも取得します。
レポートは各スナップショット間(今のところ固定)で取得します。

指定するパラメータは、以下の3つ。

Enter snap_id for starting AWR report generation. [NULL] : 
AWRレポートを取得する最初のSNAP_IDを指定します。 NULLがデフォルトでほとんどの場合デフォルトのままで事足りると思います。


Enter number of days for reporting period. [1] : 

一括取得する日数を指定します。当日を含みます。
当日分のAWRレポートを出力するのであれば、デフォルト値の1のままでOKです。


Enter suffix for AWR reports filename. [NULL] : test

保存するAWRレポートのファイル名に付加するsuffixを指定します。
試験名とか設定するといいですよね。

"test"と指定した場合

awrrpt_nnnn_nnnn_test.htmlや
awrsqrpt_nnnn_nnnn_test_sqlid.html

の形式で保存します。(nnnnはSNAP_ID)


実行例1)当日分の全レポートを取得する例

SYSTEM> 
SYSTEM> !ls -l awr*.sql
-rw-r--r-- 1 oracle oinstall 6065 1月 29 18:23 awrreport_batch.sql

SYSTEM> @awrreport_batch
--
-- Oracle AWR and AWR SQL report batch generation script
--
-- ***** This script always generate html format AWR reports. *****
--
Enter snap_id for starting AWR report generation. [NULL] :
Enter number of days for reporting period. [1] :
Enter suffix for AWR reports filename. [NULL] : test
--
--
--
clear break compute;
repfooter off;
ttitle off;
btitle off;

・・・中略・・・

<p />
<br /><a class="awr" href="#top">Back to Top</a><p />
</body></html>

SYSTEM>


実行例2)当日分かつsnap_id=291以降で一括取得。(事前にsnap_idを調べておいてね)

SYSTEM> 
SYSTEM> @awrreport_batch
--
-- Oracle AWR and AWR SQL report batch generation script
--
-- ***** This script always generate html format AWR reports. *****
--
Enter snap_id for starting AWR report generation. [NULL] : 291
Enter number of days for reporting period. [1] :
Enter suffix for AWR reports filename. [NULL] : test
--
--
--
clear break compute;
repfooter off;
ttitle off;
btitle off;

・・・中略・・・

<p />
<br /><a class="awr" href="#top">Back to Top</a><p />
</body></html>

SYSTEM>
SYSTEM>
SYSTEM> !ls -l *.html
-rw-r--r-- 1 oracle oinstall 379083 1月 29 22:23 awrrpt_291_292_test.html
-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_0c83z9rqx45hu.html
-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_0h3mfbzk6uyw0.html
-rw-r--r-- 1 oracle oinstall 11897 1月 29 22:23 awrsqrpt_291_292_test_2p7t0mw7zvu5z.html

・・・中略・・・

-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_bhtycgwkxhfj9.html
-rw-r--r-- 1 oracle oinstall 11900 1月 29 22:23 awrsqrpt_291_292_test_bpaggvtfkar9k.html
-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_c50hdbyuwhfn6.html
-rw-r--r-- 1 oracle oinstall 11892 1月 29 22:23 awrsqrpt_291_292_test_g3f3cw3zy5aat.html

SYSTEM>

なお、Oracleインスタンスが再起動された期間でawrrpt.sqlなどを実行すると、レポートが作成できずエラーでSQL*Plusも終了してしまいますが、本スクリプトでは該当部分のレポートはスキップするようにしてあります。:)

Instance     DB Name      Snap Id   Snap Started       Level
------------ ------------ --------- ------------------ -----
lampeye LAMPEYE 274 29 1月 2012 09:33 1
275 29 1月 2012 10:00 1
276 29 1月 2012 10:30 1
277 29 1月 2012 11:00 1
278 29 1月 2012 11:30 1
279 29 1月 2012 12:00 1
280 29 1月 2012 12:30 1
281 29 1月 2012 13:00 1
282 29 1月 2012 13:30 1
283 29 1月 2012 14:00 1
284 29 1月 2012 14:30 1
285 29 1月 2012 15:00 1
286 29 1月 2012 15:30 1
287 29 1月 2012 16:00 1
288 29 1月 2012 16:30 1
289 29 1月 2012 17:00 1
290 29 1月 2012 17:30 1

291 29 1月 2012 18:31 1 ←再起動されてる
292 29 1月 2012 18:34 1

293 29 1月 2012 22:26 1 ←再起動されてる


Enjoy!

| | コメント (0) | トラックバック (0)

2012年1月14日 (土)

shutdown immeidateしない、ほかの理由に遭遇! (FYI)


ず〜〜〜〜っと、追記しようと思ってたんだけど書いてなかったので、徹夜明けで早起きした次いでなんで書いておきます。

もう一年近く前のネタなんだけどね。「shutdown immeidateしない、ほかの理由に遭遇!」

> yoheia-a さんありがとう :)

私か書いた記事がキッカケで調べなきゃいけなくなったらしいんだけどね。 ;)

http://d.hatena.ne.jp/yohei-a/20110627/1309180675




shutdown immeidateしない、ほかの理由に遭遇!
shutdown immeidateしない、ほかの理由に遭遇! #2
shutdown immeidateしない、ほかの理由に遭遇! #3
shutdown immeidateしない、ほかの理由に遭遇! おまけ
shutdown immeidateしない、ほかの理由に遭遇! おまけのおまけ(でた〜最近、よくあるパターンw)

| | コメント (0) | トラックバック (0)

2011年8月16日 (火)

CentOS6.0 on VirtualBox4.1.0 for MacOS X(Snow Leopard) - Can't mount VBoxGuestAdditions.iso as Virtual CD/DVD-ROM

MacOS XのVirtualBoxでGuest Additionsがインストールできないというか VBoxGuestAdditions.isoファイルを仮想CD/DVDとしてマウントできないなー、なんて状態になったら、これから紹介する方法で解決できますよ。というお話です。:)

VirtualBox for MacOS Xは他のアプリケーションと同様にアプリケーション・パッケージ形式なのでVirtualBoxアプリケーションアイコンを右クリックし、「ボップアップメニュー」>「パッケージの内容を表示」を選択します。

Menu




でFinderに表示されたVirtualBoxパッケージないを開いていくと Contents/MacOS/VBoxGuestAdditions.iso というファイルが見つかります。これがGuest Additions用の.iso形式ファイル。これがなぜかマウントできないんだな。以前はマウントできてたのに…

Iso


この VBoxGuestAdditions.iso をDesktopなどアクセスしやすい場所にコピーしちゃいます。

あとはいつものように、CD/DVD-ROMとしてマウントして…


Mount


Mount2


コマンドを打つだけ。:)


[discus@angelfish VBOXADDITIONS_4.1.0_73009]$ su -
パスワード:
[root@angelfish &]# cd /media
[root@angelfish media]# ll
合計 2
dr-xr-xr-x. 4 discus root 2048 7月 19 19:43 2011 VBOXADDITIONS_4.1.0_73009
[root@angelfish media]# cd VBOXADDITIONS_4.1.0_73009
[root@angelfish VBOXADDITIONS_4.1.0_73009]# ll
合計 41440
dr-xr-xr-x. 3 discus root 2048 7月 19 19:43 2011 32Bit
dr-xr-xr-x. 2 discus root 2048 7月 19 19:43 2011 64Bit
-r-xr-xr-x. 1 discus root 647 8月 14 00:58 2010 AUTORUN.INF
-r-xr-xr-x. 1 discus root 7525824 7月 19 19:38 2011 VBoxLinuxAdditions.run
-r-xr-xr-x. 1 discus root 14235136 7月 19 19:42 2011 VBoxSolarisAdditions.pkg
-r-xr-xr-x. 1 discus root 13097968 7月 19 19:30 2011 VBoxWindowsAdditions-amd64.exe
-r-xr-xr-x. 1 discus root 7277968 7月 19 19:25 2011 VBoxWindowsAdditions-x86.exe
-r-xr-xr-x. 1 discus root 278832 7月 19 19:24 2011 VBoxWindowsAdditions.exe
-r-xr-xr-x. 1 discus root 6966 7月 19 19:36 2011 autorun.sh
-r-xr-xr-x. 1 discus root 5523 7月 19 19:36 2011 runasroot.sh
[root@angelfish VBOXADDITIONS_4.1.0_73009]# sh ./VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 4.1.0 Guest Additions for Linux.........
VirtualBox Guest Additions installer
Removing existing VirtualBox DKMS kernel modules [ OK ]
Removing existing VirtualBox non-DKMS kernel modules [ OK ]
Building the VirtualBox Guest Additions kernel modules
Building the main Guest Additions module [ OK ]
Building the shared folder support module [ OK ]
Building the OpenGL support module [ OK ]
Doing non-kernel setup of the Guest Additions [ OK ]
Starting the VirtualBox Guest Additions [ OK ]
Installing the Window System drivers
Installing X.Org Server 1.7 modules [ OK ]
Setting up the Window System to use the Guest Additions [ OK ]
You may need to restart the hal service and the Window System (or just restart
the guest system) to enable the Guest Additions.

Installing graphics libraries and desktop services componen[ OK ]
[root@angelfish VBOXADDITIONS_4.1.0_73009]#

このお遊びの続きはいずれまた。

2011/8/16追記
実は、こんな事しなくてもちゃんとマウンドできた><。

VirtualBoxの「メニュー」>「デバイス」>「Guest Addtionsのインストール(I)...」でマウントできるじゃないですかー。失礼しました。 m(_ _)m

20110816_230742


これまでのあらずじ…

CentOS6.0 on VirtualBox4.1.0 for MacOS X(Snow Leopard)

| | コメント (0) | トラックバック (0)

2010年10月23日 (土)

Dashboard de Aquarium v1.5

Dashboard de Aquarium v1.5 の動画あるといいな〜なんて事言われててずーっと放置プレイだったので、Quicktime XのScreen recording、iMovieとGarageBandで。

PCの音量は控えめに (^^;;

さて、次はなにをするかちょいとネタ探し中。

| | コメント (0) | トラックバック (0)

2010年10月11日 (月)

MacOSXでCD-RWやDVD-RWに記録した内容を全て消去する方法(Unix/Linux使いだけど、MacOS Xは初心者って方向けの方法)

さて、さて、MacOS XのTerminalからいろいろと初心者向けじゃないことを続けて書いちゃおーかなーということで。

今回は、CD-RWととかDVD-RWとか追記可能な光ディスクに記録したデータなど不要になり全部消去したい場合の方法。
quickはオプションなので時間がかかってもよい場合はquickなしでいいよ!

discus:˜ discus$ diskutil -help
Disk Utility Tool
Utility to manage local disks and volumes.
Most options require root access to the device

Usage: diskutil <verb> <options>
<verb> is one of the following:
list (List the partitions of a disk)
information | info (Get information on a disk or volume)

unmount (Unmount a single volume)
unmountDisk (Unmount an entire disk (all volumes))
eject (Eject a disk)
mount (Mount a single volume)
mountDisk (Mount an entire disk (all mountable volumes))
rename (Rename a volume)

enableJournal (Enable HFS+ journaling on a mounted HFS+ volume)
disableJournal (Disable HFS+ journaling on a mounted HFS+ volume)

verifyVolume (Verify the structure of a volume)
repairVolume (Repair the structure of a volume)

verifyPermissions (Verify the permissions of a volume)
repairPermissions (Repair the permissions of a volume)
repairOS9Permissions (Repair the permissions for the current
Classic boot volume)

eraseDisk (Erase an existing disk, removing all volumes)
eraseVolume (Erase an existing volume)
reformat (Reformat an existing volume)
eraseOptical (Erase an optical media (CD/RW, DVD/RW, etc.))
zeroDisk (Erase a disk, writing zeros to the media)
randomDisk (Erase a disk, writing random data to the media)
secureErase (Securely erase a disk or freespace on a volume)
resizeVolume (resize a volume, increasing or decreasing its size)

partitionDisk ((re)Partition a disk, removing all volumes)

createRAID (Create a RAID set on multiple disks)
destroyRAID (Destroy an existing RAID set)
checkRAID (Check a RAID set for errors)
enableRAID (Convert a disk to a degraded RAID mirror set)
convertRAID (Convert a RAID 1.x (pre-Tiger) to a RAID 2.x (Tiger))
updateRAID (Update the settings of an existing RAID)
addToRAID (Add a spare or member disk to an existing RAID)
removeFromRAID (Remove a spare or member disk from an existing RAID)
repairMirror (Repair a damaged RAID mirror set)

diskutil <verb> with no options will provide help on that verb

discus:˜ discus$ diskutil eraseOptical -help
Disk Utility Tool
Usage: diskutil eraseOptical [quick]
[Mount Point|Disk Identifier|Device Node]
Completely erase an existing optical disk. Ownership of the affected disk is required.
Example: diskutil eraseOptical quick /dev/disk2
discus:˜ discus$

消去したいCD-RWやDVD-RWを挿入後、デバイス名を確認! この例の場合、/dev/disk1ですね。

discus:˜ discus$ mount | grep discus_cd_img
/dev/disk1s1s3 on /Volumes/discus_cd_img (hfs, local, nodev, nosuid, read-only, noowners)
discus:˜ discus$

以下の例ではquickオプション付けてます!

discus:˜ discus$
discus:˜ discus$ diskutil eraseOptical quick /dev/disk1
Started erase on disk disk1
[ + 0%..10%..20%..30%..40%..50%..60%..70%..80%..90%..100% ]
Finished erase on disk disk1
discus:˜ discus$

終了!!!

まっさらになったDISCなので以下のようなダイアログが表示される.「取り出す」ボタンをクリックして取り出しましょ!
Diskutil_quick_eraseing_cd

| | コメント (0) | トラックバック (0)

MacOSXでCDやDVDを焼く方法 #2(Unix/Linux使いだけど、MacOS Xは初心者って方向けの方法)

前回は、isoイメージをshell commandで焼く方法だったけど、ついでなのでdisk imageを焼く方法をdisk imageの作成、disk imageへのファイルコピー、最後にCDを焼くという流れでも書いておきますね。 :)

コマンドの詳細はhelpをどうぞ。沢山オプションあるけど。(^^;;;

G5Server:/tmp discus$ hdiutil create -help

hdiutil create: create a disk image image
Usage: hdiutil create <sizespec> <imagepath>
Size specifiers:
-size < ?? | ??b | ??k | ??m | ??g | ??t | ??p | ??e >
(mkfile(8) plus terabytes, petabytes, & exabytes)
-sectors <count>
-megabytes <count>

Image options:
-layout <layout> [SPUD unless -fs -> NONE]
SPCD - single partition CD/DVD
SPUD - 単一パーティション
UNIVERSAL CD - CD/DVD
NONE - パーティションマップなし
UNIVERSAL HD - ハードディスク
-partitionType <partitionType> [Apple_HFS or per -fs]
-align <sector alignment> [4 aka 2K]
-ov

Filesystem options:
-fs <filesystem>
Case-sensitive HFS+ - Mac OS Extended (Case-sensitive)
Journaled HFS+ - Mac OS Extended (Journaled)
Case-sensitive Journaled HFS+ - Mac OS Extended (Case-sensitive, Journaled)
HFS+ - Mac OS Extended
HFS - Mac OS Standard
MS-DOS FAT32 - MS-DOS File System (FAT32)
MS-DOS FAT16 - MS-DOS File System (FAT16)
MS-DOS - MS-DOS File System
MS-DOS FAT12 - MS-DOS File System (FAT12)
UFS - UNIX File System
-volname <volumename> ["untitled"]
-stretch < ?? | ?b | ??k | ??m | ??g | ??t | ??p | ??e > (HFS+)

New Blank Image options:
-type <image type> [UDIF]
UDIF - 読み込み/書き込みディスクイメージ
SPARSE - スパースディスクイメージ

Image from Folder options:
-srcfolder <source folder>
-(no)anyowners do (not) attempt to preserve owners
-(no)skipunreadable do (not) skip unreadable files/directories [no]
-format <image type> [UDZO]
DC42 - Disk Copy 4.2
RdWr - NDIF 読み込み/書き込み
Rdxx - NDIF 読み込み専用
ROCo - NDIF 圧縮
Rken - NDIF 圧縮(KenCode)
UDRO - 読み込み専用
UDCO - 圧縮(ADC)
UDZO - 圧縮
UDBZ - 圧縮(bzip2)
UFBI - 装置全体
IPOD - iPod イメージ
UDxx - UDIF スタブ
UDRW - 読み込み/書き込み
UDTO - DVD/CD マスター
UDSP - スパース
UDIF - 読み込み/書き込みディスクイメージ
SPARSE - スパースディスクイメージ

Image from Device options:
-srcdevice <source dev node, e.g. disk1, disk2s1>
-format <image type> [UDZO]
DC42 - Disk Copy 4.2
RdWr - NDIF 読み込み/書き込み
Rdxx - NDIF 読み込み専用
ROCo - NDIF 圧縮
Rken - NDIF 圧縮(KenCode)
UDRO - 読み込み専用
UDCO - 圧縮(ADC)
UDZO - 圧縮
UDBZ - 圧縮(bzip2)
UFBI - 装置全体
IPOD - iPod イメージ
UDxx - UDIF スタブ
UDRW - 読み込み/書き込み
UDTO - DVD/CD マスター
UDSP - スパース
-segmentSize < ?? | ??b | ??k | ??m | ??g | ??t | ??p | ??e >
(blocks, bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes)

Attach options:
-attach attach image after creation

Common options:
-encryption <crypto method>
-stdinpass
-certificate <path-to-cert-file>
-imagekey <key>=<value>
-tgtimagekey <key>=<value>
-plist return results in plist format
-puppetstrings
-verbose
-debug
-quiet
G5Server:/tmp discus$

disk imageの作成例)

CD用に500MBのdisk imageを1パーティションかつ、HFS+で、discus_cd_imgというボリューム名作成します。ファイル名は、discus.dmgというファイル名にしておきます。
disk imageが作成されたらマウントさせるように -attachオプションも付けて!

G5Server:/tmp discus$ hdiutil create -size 500m -layout SPCD -fs HFS+ -volname discus_cd_img -attach discus
...........................................................................................................
/dev/disk3 Apple_partition_scheme
/dev/disk3s1 Apple_partition_map
/dev/disk3s2 Apple_Driver_ATAPI
/dev/disk3s3 Apple_HFS /Volumes/discus_cd_img
created: /private/tmp/discus.dmg
G5Server:/tmp discus$

作成したdisk imageへファイルをコピーして、マウントしていたdisk imageをアンマウント。

G5Server:/tmp discus$
G5Server:/tmp discus$ cp -pr /Users/discus/Pictures/DesktopPics/* /Volumes/discus_cd_img
G5Server:/tmp discus$
G5Server:/tmp discus$ hdiutil detach -help
hdiutil detach: detach disk image from system
Usage: hdiutil detach <devname>

Note: you can specify a mount point (e.g. /Volumes/MyDisk)
instead of a dev node (e.g. /dev/disk1)

Options:
-force forcibly detach

Common options:
-verbose
-debug
-quiet
G5Server:/tmp discus$
G5Server:/tmp discus$
G5Server:/tmp discus$ hdiutil detach /Volumes/discus_cd_img
"disk3" unmounted.
"disk3" ejected.
G5Server:/tmp discus$


焼き方は、isoイメージの場合と同じ。

注)

hdiutil: burn: “ディスクイメージファイル名”not recognized - リソースが一時的に使用できません。
hdiutil: burn failed - リソースが一時的に使用できません。

というエラーになった場合は、burn前に、ディスクイメージをdetachしてからburnすればOKですよ〜ん。MacOS X 10.4ではattachしたままでも焼けたけど、MacOS 10.5以降では前述のエラーを返すのでご注意を!
G5Server:/tmp discus$
G5Server:/tmp discus$ hdiutil burn discus.dmg
Please insert a disc:
ディスクに書き込むデータを準備中
セッションを開いています
トラックを開いています
トラックを書き込み中
...........................................................................................................
トラックを閉じています
............................................................................................................
セッションを閉じています
ディスクの作成を終了中
ディスク作成の検証中...
検証
.............................................................................................................
ディスクの作成は問題なく完了しました
.............................................................................................................
hdiutil: burn: completed
G5Server:/tmp discus$




MacOSXでCDやDVDを焼く方法(初心者でも分かり易い方法)
MacOSXでCDやDVDを焼く方法(Unix/Linux使いだけど、MacOS Xは初心者って方向けの方法)

| | コメント (0) | トラックバック (0)

2010年10月10日 (日)

MacOSXでCDやDVDを焼く方法(Unix/Linux使いだけど、MacOS Xは初心者って方向けの方法)

最近、Macユーザが多くなってきた影響か、MacOSXでCDやDVDを焼く方法(初心者でも分かり易い方法)ってエントリがよくググられているので、PC初心者向きではないけど、Linux使いな方でMacは初心者って方向け、terminalからcommandでisoイメージのCDやDVDを焼く方法。

hdiutilというコマンドで焼く事ができます!
オプションはhelp参照のこと。(尚、以下のログはMacOS X 10.4なのですが、10.6でも同じです。暗号化に指定できる暗号化方法は増えてたかな。その程度の差だったはず。)

G5Server:/tmp discus$
G5Server:/tmp discus$ hdiutil burn -help

hdiutil burn: burn an image to optical media
Usage: hdiutil burn <image>
Options:
-speed <speed e.g. 1, 2, 4, 8, ... max>
-device <OpenFirmware path>
-sizequery just calculate size of disc required
-testburn don't turn on laser

Toggles:
-noeject don't eject disc after burning
-noverifyburn don't verify disc contents after burn
-noaddpmap don't add partition map
-noskipfinalfree don't skip burning final free partition
-optimizeimage optimize filesystem for burning
-forceclose close disc after burning
-nounderrun disable buffer underrun protection
-[no]synth synthesize new filesystem from volume

Common options:
-encryption <crypto method>
-stdinpass
-srcimagekey <key>=<value> (-imagekey is a synonym)
-shadow <shadowfile>
-insecurehttp
-cacert <file|dir>
-puppetstrings
-verbose
-debug
-quiet

Related actions:
-erase erase disc (quickly)
-fullerase completely erase disc
-list list all burning devices, for -device
G5Server:/tmp discus$

早速、簡単な例を1つ。CentOS5.5のLiveCDのisoイメージをMacOS X上にダウンロード後、isoイメージCDを焼いちゃいます。
MacOSXの場合、Linuxと違って、wgetじゃなくてcurlなんですよ、プログラミング言語のCurlとと勘違いしちゃう人もたまにいますけどw

※まず、curlでCentOS5.5 LiveCD isoイメージのダウンロードから!

G5Server:/tmp discus$ curl -O http://ftp.osuosl.org/pub/centos/5.5/isos/x86_64/CentOS-5.5-x86_64-LiveCD.iso

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 694M 100 694M 0 0 384k 0 0:30:47 0:30:47 --:--:-- 395k

G5Server:/tmp discus$
G5Server:/tmp discus$ ll CentOS-5.5-x86_64-LiveCD.iso
-rw-r--r-- 1 discus wheel 728184832 Oct 10 10:28 CentOS-5.5-x86_64-LiveCD.iso

G5Server:/tmp discus$

※hdiutilコマンドでburnしちゃいます。簡単。コマンドを実行するとCD/DVDトレイにDISCを挿入するように要求されるので、指示通りにDISCを挿入すれば後は、勝ってにやいてくれて、焼き終わったらEjectしてくれます。

G5Server:/tmp discus$ hdiutil burn CentOS-5.5-x86_64-LiveCD.iso
Please insert a disc:
ディスクに書き込むデータを準備中
セッションを開いています
トラックを開いています
トラックを書き込み中
............................................................................................................
トラックを閉じています
............................................................................................................
セッションを閉じています
............................................................................................................
ディスクの作成を終了中
ディスク作成の検証中...
検証
.............................................................................................................
ディスクの作成は問題なく完了しました
.............................................................................................................
hdiutil: burn: completed
G5Server:/tmp discus$


MacOSXでCDやDVDを焼く方法(初心者でも分かり易い方法)
MacOSXでCDやDVDを焼く方法 #2(Unix/Linux使いだけど、MacOS Xは初心者って方向けの方法)

| | コメント (0) | トラックバック (0)

2009年9月18日 (金)

QuickTime X - Screen Recorder

以前もちょっと書いたけどSnow LeopardのQuickTime XからScreen Recorder機能が追加されている。この機能、操作ガイドなど作るのには非常に便利。いままではShareware使ってたりした方が多かったと思うけどSnow LeopardならQuickTime Xを起動してレコーディングすだけでOK。

1

QuickTime X Playerを起動して「メニュー」→「新規画面収録 ^⌘N」を選択。
2

「画面収録」ダイアログが表示された録画ボタンをクリックするだけで開始される。デフォルトの保存場所は「ムービー」フォルダ」。
「収録の開始」ボタンをクリックすると操作が録画される。

6

4

実際に収録したムービーは次の記事の時にで使う予定。

| | コメント (0) | トラックバック (0)

2009年6月29日 (月)

MacBook Pro と MacOS X 10.5.7 と Sleep と Hang-up

Macオンリーな話題です。

先日、MacBook ProのMacOS X 10.5.6を10.5.7にアップデートしてからSleepさせるとファンがスリープせずファンが凄い勢いで廻りっぱなしになったり、ハングアップしまくっていた。おかしいね、アップデータが問題なんだろうねと話していたら、すかさず、アップデータのアップデータが出ていたのでアップデートした。
すると、ファンが凄い勢いで廻りっぱなしになる現象は消えたものの99%の確立でSleepさせようとするとハングアップするようになった。なんだよ〜〜早くバグ直せ〜〜とAppleさんにお怒りモードの私。

しばらく考えこんだあげく、Apple Supportのforumを検索してみると日本のフォーラムには無かったが、USのフォーラムにはそれらしき対処方法があった。。。。。
ということで先日から試しているが、それ以降一度もハングしていない!!!!
やった〜〜〜。

とにかくAppleさん、ちゃんとバグ修正してね!!

以下、症状と対処方法を書いておきます。


症状:
MacBook Pro 15inchでMacOS X 10.5.7へアップデート後からSleepさせようとするとハングアップする。ハングアップしたまま冷却ファンが凄い勢いで廻りっぱなしになる。

Hang_when_sleep_002_2

対処方法:
システム環境設定→ネットワーク

Hang_when_sleep_001

左側のネットワークポートペインにイーサネットポートがリストされていない場合、本現象に遭遇する。"+"ボタンで使っていなくてもイーサーネットポートを追加する。
Hang_when_sleep_003
Hang_when_sleep_004
Hang_when_sleep_005

イーサーネットポートを追加したらOSを再起動する。このような対処でSleepさせようとするとhangしてしまう問題を回避できる。
(対処から4日経過したがいまのところ問題は再発していない。もし状況に変化があれば本記事を更新する予定。)

| | コメント (0) | トラックバック (0)

2009年5月14日 (木)

Leopard de Oracle10g R2 (Intel x86-64) #8 - (APEX3.2と遊ぶ #1)

さて、前回予告していたようにOracle10g R2 10.2.0.4.0 for MacOSX (Intel x86-64)へOracle Application Express 3.2をインストールして無理矢理使ってみましょう! の第一話。

Oracle Application Express3.2(以下、APEX3.2)は、http://www.oracle.com/technology/products/database/application_express/download.htmlからダウンロード。


2

今回はOracle10g R2 10.2.0.4.0 for MacOSX (Intel x86-64)APEX3.2の英語環境をインストールするところまでを試してみる。
PL/SQLパッケージ等の作成がメインだから問題になりそうな箇所はないんだけど、なんで未サポートなんだろう?。 Oracle HTTP Serverが未サポートだからその影響か?


上記URLからダウンロードしたAPEX3.2を解凍したディレクトリに移動(MacOSX Leopardでは通常Downloadフォルダへダウンロードされる。)

guppy:˜ oracle$ 
guppy:˜ oracle$ cd /Users/oracle/Downloads/apex
guppy:apex oracle$ ll
total 424
-r--r--r--@ 1 oracle oinstall 690 9 10 2008 apex_epg_config.sql
-r--r--r--@ 1 oracle oinstall 15749 1 18 17:38 apex_epg_config_core.sql
-r--r--r--@ 1 oracle oinstall 5208 1 8 13:33 apexins.sql
-r--r--r--@ 1 oracle oinstall 8476 1 8 13:33 apexvalidate.sql
-r--r--r--@ 1 oracle oinstall 1549 1 8 13:33 apxchpwd.sql
-r--r--r--@ 1 oracle oinstall 2830 12 23 18:39 apxconf.sql

・・・・中略・・・・

drwxr-xr-x@ 873 oracle oinstall 29682 2 11 05:50 images
-r--r--r--@ 1 oracle oinstall 1295 12 23 18:39 load_trans.sql
drwxr-xr-x@ 64 oracle oinstall 2176 2 8 19:34 owa
drwxr-xr-x@ 9 oracle oinstall 306 2 8 21:30 utilities
-rw-rw-r-- 1 oracle oinstall 4803 2 17 12:13 welcome.html
guppy:apex oracle$
guppy:apex oracle$

ディレクトリを移動後、SQL*Plusから赤太文字で示したapexins.sql(前述)を実行する。
実行時のパラメータはAPEXのマニュアルを見てね

guppy:apex oracle$ sqlplus /nolog

SQL*Plus: Release 10.2.0.4.0 - Production on 水 5月 13 19:08:04 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

> conn / as sysdba
接続されました。
SYS> @apexins SYSAUX SYSAUX TEMP /i/

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

. ____ ____ ____ ____
. / \ | \ /\ / | /
.| || / / \ | | |
.| ||--- ---- | | |--
.| || \ / \ | | |
. \____/ | \/ \ \____ |____ \____
.
. Application Express Installation.
...................................
.
... Checking prerequisites

・・・・中略・・・・

I. I N S T A L L P R E - C R E A T E T A B L E S P E C S
...wwv_flow_init_htp_buffer

プロシージャが作成されました。

エラーはありません。

権限付与が成功しました。

・・・・中略・・・・

II. I N S T A L L F L O W T A B L E S
...create v function stub

ファンクションが作成されました。

エラーはありません。
...create nv function stub

ファンクションが作成されました。

エラーはありません。

・・・・中略・・・・

III. I N S T A L L F L O W P A C K A G E S P E C S
...wwv_flow_hot_http_links

ファンクションが作成されました。

エラーはありません。

・・・・中略・・・・

Package Specsのタイミング。
経過: 00:00:11.13

IV. I N S T A L L F L O W P A C K A G E B O D I E S
...wwv_dbms_sql
エラーはありません。

・・・・中略・・・・

Package Bodiesのタイミング。
経過: 00:02:50.20

V. P E R F O R M F L O W G R A N T S
Installing flows_files objects 2
...create flows_files
...trigger wwv_biu_flow_file_objects
エラーはありません。
Grantsのタイミング。
経過: 00:00:00.09

VI. I N S T A L L F L O W S
define "^" (hex 5e)
...internal messages
APPLICATION 4411 - APEX - System Messages
Set Credentials...
Check Compatibility...
WWV_FLOW_API.FLOWS_API_LAST_EXTENDED20090112
WWV_FLOW_API.CURRENT_FLOWS_VERSION20090112

・・・・中略・・・・

......Message f4400_p12_howto_step7
......Message internal_users
......Message database_users
......Message f4400_p22_obj_created
......Message f4400_p10_queries_help
......Message f4400_p9_tables_help
......Message f4400_p22_table_info
......Message f4400_p8_forms_help
......Message f4400_p20_reports_help
......Message f4400_p49_defs_help
......Message wwv_flow_item_protection_save_item_internal_only_show
......Message wwv_flow_sw_parser_line_exceeds_32k
......Message wwv_flow_sw_api_check_priv_obj
......Message f4050_approved_account_req_display
......Message archivelog

・・・・中略・・・・

Install Internal Flowsのタイミング。
経過: 00:00:34.94

...Development install if necessary

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

I. O R A C L E S Y S I N S T A L L P R O C E S S
dev_grants
...grant APEX owner development privileges

・・・・中略・・・・

...done grant APEX owner core privileges
...CONNECT as the Oracle user who will own the APEX engine

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

III. I N S T A L L F L O W P A C K A G E S P E C S
wwv_flow_plsql_editor.sql

・・・・中略・・・・

Development Package Specsのタイミング。
経過: 00:00:40.17
wwv_flow_plsql_editor.plb

パッケージ本体が作成されました。

・・・・中略・・・・

Development Package Bodiesのタイミング。
経過: 00:00:29.69

権限付与が成功しました。


PL/SQLプロシージャが正常に完了しました。

VI. I N S T A L L F L O W S
define "^" (hex 5e)
APPLICATION 4000 - APEX - Application Builder
Set Credentials...
Check Compatibility...
API Last Extended:20090112
Your Current Version:20090112

・・・・中略・・・・

Install Internal Development Applicationsのタイミング。
経過: 00:09:10.55

load verification images

PL/SQLプロシージャが正常に完了しました。

エラーはありません。

・・・・中略・・・・

Thank you for installing Oracle Application Express.

Oracle Application Express is installed in the APEX_030200 schema.

The structure of the link to the Application Express administration services is as follows:
http://host:port/pls/apex/apex_admin (Oracle HTTP Server with mod_plsql)
http://host:port/apex/apex_admin (Oracle XML DB HTTP listener with the embedded PL/SQL gateway)

The structure of the link to the Application Express development interface is as follows:
http://host:port/pls/apex (Oracle HTTP Server with mod_plsql)
http://host:port/apex (Oracle XML DB HTTP listener with the embedded PL/SQL gateway)

JOB_QUEUE_PROCESSES: 10

PL/SQLプロシージャが正常に完了しました。


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


Performing Application Express component validation - please wait...

Completing registration process.
Validating installation.

PL/SQLプロシージャが正常に完了しました。

Validate Installationのタイミング。
経過: 00:02:04.77

・・・・中略・・・・

VII. L O A D E N G L I S H D I C T I O N A R Y

トリガーが変更されました。

...10000 rows
...20000 rows
...30000 rows
...40000 rows
...50000 rows
...60000 rows
...70000 rows
English Dictionaryのタイミング。
経過: 00:02:58.72
Upgradeのタイミング。
経過: 00:00:01.15
...End of install if runtime install
...create null.sql
Development Installationのタイミング。
経過: 00:17:28.33
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing optionsとの接続が切断されました。
guppy:apex oracle$
guppy:apex oracle$


特に問題もなくAPEX3.2の英語版はインストールできた。これなら次も順調かもよ・・・・・


次はAPEXのバージョン確認(FAQですが)。
apex_030200.wwv_flows_release関数を使えば確認できます。
ちなみにhtmldbなんて呼ばれていたころから flows_02000とか、リリース毎にスキーマ名が変る点にご注意を。但し関数名は変らないのでスキーマ名だけ注意すれば問題ないです。

guppy:apex oracle$ sqlplus /nolog

SQL*Plus: Release 10.2.0.4.0 - Production on 水 5月 13 19:08:04 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

> conn / as sysdba
接続されました。

SYS> select apex_030200.wwv_flows_release from dual;

WWV_FLOWS_RELEASE
--------------------------------------------------------------------------------
3.2.0.00.27

SYS>

次回、日本語リソースのインストール。毎回思うけど、apexins.sqlで一緒にやってくれないかな?
jaとか指定するとenにつづいてjaをインストールしてくれるとか・・・・面倒で・・・。




バックナンバー

Oracle10g R2 for MacOSX (Intel x86-64) released !!!
Leopard de Oracle10g release 2 (Intel x86-64)
Leopard de Oracle10g R2 (Intel x86-64) #1
Leopard de Oracle10g R2 (Intel x86-64) #2
Leopard de Oracle10g R2 (Intel x86-64) #3 (ちょいと寄り道)
Leopard de Oracle10g R2 (Intel x86-64) #4 (Companion CD installation)
Leopard de Oracle10g R2 (Intel x86-64) #5 (dbstart and dbshut does not work!! But....)
Leopard de Oracle10g R2 (Intel x86-64) #6 (onsがバグっている?件..)
Leopard de Oracle10g R2 (Intel x86-64) #7 (iSQL*Plusのメッセージがものすごく怖い件)

| | コメント (0) | トラックバック (0)

2009年5月 8日 (金)

MacOSXでCDやDVDを焼く方法(初心者でも分かり易い方法)

義理の妹が妻のお下がりのIMac G5を使いだしてからいろいろと質問されることがあるのだが専門的な用語はあまり使えない(Mac初心者なので)。多分言葉より分かり易いのはやはり絵で見る方だよね?!。
ということで、一昨日「iPhotoで管理している画像ファイルをCDやDVDに記録するにはどうするの?」という質問への回答。
(ちなみに、MacOSXでCDやDVDに画像データ等を直接書き出す方法として複数の方法があるのだが今回はMacOSX初心者でも簡単な方法を紹介しておくね。)


「Finderのメニュー」→「ファイル」→「新規ディスク作成フォルダ」をクリック。
Finder_de_make_disc_001

ディスクトップ上に以下のようなフォルダが作成されるのでお好きな名前を付けておく
Finder_de_make_disc_002

新規ディスク作成フォルダをダブルクリックして開くと以下のようになっている。
Finder_de_make_disc_003

次にiPhotoを起動してCDやDVDに書き込みたい画像を選択する。(以下の例では、イベント単位で複数選択している。イベントを複数選択するときは⌘キーを押しながら該当イベントをクリックする。)
Finder_de_make_disc_005

次に「iPhotoメニュー」→「ファイル」→「書き出し」を選択する。
Finder_de_make_disc_006

「写真の書き出し」ダイアログが表示されるので、「ファイルの書き出し」タブで「種類」は”現在”、「サイズ」は”フルサイズ”となっていることを確認し「書き出し」ボタンをクリックする。
Finder_de_make_disc_007

次に「ファイル選択」で先ほど作成した「新規ディスク作成フォルダ」を選択して「OK]ボタンをクリック。
Finder_de_make_disc_008



Finder_de_make_disc_009

書き出しが終わったら、「新規ディスク作成フォルダ」内にある「ディスクを作成」ボタンをクリック。
空のCDかDVDを挿入するよう指示されるので、CD(CD-R/RW等)又はDVD(DVD-R/RW等)を挿入する。

Finder_de_make_disc_010

Finder_de_make_disc_011

挿入すると書き込み速度やディスク名を聞かれるので必要であれば入力する。(「新規ディスク作成フォルダ」に名称を付けていればその名称が設定される)
確認後、「ディスクを作成」ボタンをクリックする。(あとはディスクが焼終わるのを待つだけ。

Finder_de_make_disc_012

Finder_de_make_disc_013_2

この例ではCD-RWを利用して約8MBの画像ファイルを書き込んだ。書き込みが完了すると以下のような感じでデスクトップ上に現れる。ダブルクリックして開けばiPhotoから書き出した画像ファイルが確認できるはず。あとはディスクを取り出せば終わり。:)

ディスクに書き出した「新規ディスク作成フォルダ」はゴミ箱へポイしてしまえばOK.

どう? わかった? 簡単でしょ?!ーー>義妹

Finder_de_make_disc_014

Finder_de_make_disc_015




おまけ。

ちなみに、もし「新規ディスク作成フォルダ」へ、挿入するCDやDVDに書き込めないくらいの画像データ等を入れてしまった場合はちゃ〜〜〜〜んと、駄目よ〜〜〜と警告を出してくれるからCDやDVDに書き込める程度になるまでファイルを削除してね!、1枚に入りきれなければまた別のディスクを焼けばいいわけだから。:)


以下の例は、「新規ディスク作成フォルダ」へ約2.6GBのデータを入れた状態。(DVDじゃないと書き込めないサイズになってます。)
「ディスク作成」ボタンをクリックすると2.63GB以上の容量のあるディスクが必要だと警告を出してくれるし、書き込みまで進めてしまってもディスクに書き込む前に容量不足で書き込めないことを知らせてくれます。

Finder_de_make_disc_017

Finder_de_make_disc_018_2

Finder_de_make_disc_019

Finder_de_make_disc_020

Finder_de_make_disc_021




2010/10/10追記

MacOSXでCDやDVDを焼く方法(Unix/Linux使いだけど、MacOS Xは初心者って方向けの方法)
MacOSXでCDやDVDを焼く方法 #2(Unix/Linux使いだけど、MacOS Xは初心者って方向けの方法)

| | コメント (2) | トラックバック (0)

2009年4月 2日 (木)

ちょいと迷惑だったストアドファンクション(おまけ)

〜〜〜〜し〜〜し〜〜でぃ〜〜っ。む、ぶん!
やけに耳の残っちゃうんだよな〜。あの声とアクセント

なんて関係ない話はおいといて。。と



以前、
ちょいと迷惑だったストアドファンクション
ちょいと迷惑だったストアドファンクション(つづき)

ということを書いていたが、ちょいと迷惑だったストアドファンクションの例外ハンドラーで問題解決の手がかりとするためログ出力が実装されていたらどうするの? っていうこともあるのでおまけのおまけということで書いておきます。

以前の例では例外ハンドラーをバッサリ切り捨ててしまったのですが、例外ハンドラーで問題解決の手がかりとするためのログ出力が実装されていて例外ハンドラーを取り除くことが出来ない場合、例外名無しのRAISE文を使えば解決できますよ。:)

ちょいと迷惑だったストアドファンクションの例外ハンドラーで問題解決の手がかりとするためのログ出力を実装していたらという例・・・・(赤太字部分)

尚、この例ではオープンソースのPL/SQL向けロギングフレームワークLog4PLSQLを利用している。

CREATE OR REPLACE
PACKAGE inconvenient_package
AS
TYPE employeesType IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER;
TYPE membersType IS RECORD (
deptNo dept.deptNo%TYPE
,deptName dept.dName%TYPE
,employees employeesType
);
FUNCTION inconvenient_function(iDeptNo IN dept.deptNo%TYPE)
RETURN membersType;
END inconvenient_package;
/
show errors


CREATE OR REPLACE
PACKAGE BODY inconvenient_package
AS
FUNCTION inconvenient_function(iDeptNo IN dept.deptNo%TYPE)
RETURN membersType
AS
members membersType;
Log4PlsqlCtx plogparam.log_ctx := plog.init(pDBMS_OUTPUT => TRUE); -- Log4PLSQL setting
BEGIN
SELECT
deptNo
,dName
INTO
members.deptNo
,members.deptName
FROM
dept
WHERE
deptNo = iDeptNo
;
--
SELECT *
BULK COLLECT INTO
members.employees
FROM
emp
WHERE
deptno = iDeptNo
;
RETURN members;
EXCEPTION
WHEN NO_DATA_FOUND THEN
plog.warn(Log4PlsqlCtx, sqlerrm()); -- Log4PLSQL warnning
RETURN NULL;
END inconvenient_function;
END inconvenient_package;
/
show errors


変更前ファンクションの例外ハンドラー部分にある"RETURN NULL;"を"RAISE;"(例外名無しのRAISE文)に変更するだけ。

CREATE OR REPLACE
PACKAGE BODY inconvenient_package
AS
FUNCTION inconvenient_function(iDeptNo IN dept.deptNo%TYPE)
RETURN membersType
AS
members membersType;
Log4PlsqlCtx plogparam.log_ctx := plog.init(pDBMS_OUTPUT => TRUE); -- Log4PLSQL setting
BEGIN
SELECT
deptNo
,dName
INTO
members.deptNo
,members.deptName
FROM
dept
WHERE
deptNo = iDeptNo
;
--
SELECT *
BULK COLLECT INTO
members.employees
FROM
emp
WHERE
deptno = iDeptNo
;
RETURN members;
EXCEPTION
WHEN NO_DATA_FOUND THEN
plog.warn(Log4PlsqlCtx, sqlerrm()); -- Log4PLSQL warnning
RAISE;
END inconvenient_function;
END inconvenient_package;
/


例外ハンドラー内で例外名を省略すると該当する例外がさらに外側のブロックへスローされます。詳細はマニュアル(Oracle Database PL/SQL Language Reference 11g Release 1 : RIASE statement)及び、Oracle Database PL/SQL Language Reference 11g Release 1 : How PL/SQL Exceptions Propagate参照のこと。

SCOTT> set linesize 132
SCOTT> set serveroutput on
SCOTT> l
1 DECLARE
2 members inconvenient_package.membersType;
3 Log4PlsqlCtx plogparam.log_ctx := plog.init(pDBMS_OUTPUT => TRUE);
4 BEGIN
5 BEGIN
6 members := inconvenient_package.inconvenient_function(99);
7 DBMS_OUTPUT.PUT_LINE(
8 'Dept name/id:'
9 ||members.deptname
10 ||'/'||TO_CHAR(members.deptno)
11 );
12 FOR i IN members.employees.FIRST..members.employees.LAST LOOP
13 DBMS_OUTPUT.PUT_LINE(' -- '||members.employees(i).ename);
14 END LOOP;
15 EXCEPTION
16 WHEN NO_DATA_FOUND THEN
17 plog.warn(Log4PlsqlCtx, sqlerrm());
18 END;
19* END;
SCOTT> /
12:35:27:02-WARN-block-->SCOTT.INCONVENIENT_PACKAGE ORA-01403: データが見つかりません。
12:35:27:03-WARN-block ORA-01403: データが見つかりません。

PL/SQLプロシージャが正常に完了しました。

SCOTT> l
1 DECLARE
2 members inconvenient_package.membersType;
3 Log4PlsqlCtx plogparam.log_ctx := plog.init(pDBMS_OUTPUT => TRUE);
4 BEGIN
5 BEGIN
6 members := inconvenient_package.inconvenient_function(10);
7 DBMS_OUTPUT.PUT_LINE(
8 'Dept name/id:'
9 ||members.deptname
10 ||'/'||TO_CHAR(members.deptno)
11 );
12 FOR i IN members.employees.FIRST..members.employees.LAST LOOP
13 DBMS_OUTPUT.PUT_LINE(' -- '||members.employees(i).ename);
14 END LOOP;
15 EXCEPTION
16 WHEN NO_DATA_FOUND THEN
17 plog.warn(Log4PlsqlCtx, sqlerrm());
18 END;
19* END;
SCOTT> /
Dept name/id:ACCOUNTING/10
-- CLARK
-- KING
-- MILLER

PL/SQLプロシージャが正常に完了しました。

SCOTT>

| | コメント (0) | トラックバック (0)

2008年4月17日 (木)

埋込みPL/SQL Gatewayで外部URLアクセス

Oracle11g R1 11.1.0.6.0 for Linux x86 and Oracle Application Expressという記事で埋込みPL/SQL GatewayをでPython Challengeを試してみたのだが・・・埋込みPL/SQL Gatewayを利用した場合、UTL_HTTPパッケージで外部のURLへアクセスすることはできないみたいなので、あきらめて通常のmod_plsqlでやってみるか・・・。Oracle11gからならACLで許可してやればアクセスできるのに、Oracle11gに内蔵されているXDB HTTP Serverではそれは効かないのね。。遊べると思ったのに。。orz.(Oracle11gの埋込みPL/SQL Gatewayの備忘録として残しておくか。。)

エラーメッセージは以下の通り。(Apexを3.1にするとできるようになったりして。。。2008/4/19追記)

ORA-31020:操作できません。 理由:For security reasons, ftp and http access over XDB repository is not allowed on server side

以下、埋込みPL/SQL Gatewayを利用したOracle Application Expressのスクリーンショット
9


4/18追記
どうもこれは埋込みPL/SQL GatewayというよりOracle Application Express側の影響のように思えてきた。10gのmod_plsql経由でもApexでは同じエラーだった。
ちなみに、mod_plsql経由で呼び出すだけならACL定義でアクセスするホストを許可してやるだけでOK。

以下にその時のスクリーンショットを載せておく。
答えにLevel17の答えに結びつく部分はぼかしてますよ〜〜。

19


でも何故、ApexからUTL_HTTPを利用するとXDB絡みのエラーになるんだ? 不思議すぎる。。。これは追々調べておくか。。何か手順から漏れていることがあったりして。。。。つづく。

さらに追記、やはり出来ない(11gからはできなくなったと言ったほうがいいだろう)というのが正しいようだ。10gではApexから直接UTL_HTTPパッケージからHTTPリクエスト出してfeedやらHTMLやらアクセスし放題だったのに〜〜〜、プンプンのプン。 ふ〜普通のmod_plsqlでやりますよ〜〜〜〜だ。

| | コメント (0) | トラックバック (0)

2008年4月14日 (月)

Java AppletがWindowsのJavaSE6.0 Update5で動作しない件

megawattさんのブログは見ていたものここ数日コメント欄までは見ていなかったよ。megawattさんが忙しいのは知ってたけどメールくれれば調べといたのに〜。 :)
megawattさんのブログの日本の借金時計は私のブログ内にあるアプレットを呼び出しているだけですから。

ということで調べてみた。

おかげで、何ヶ月か振りでWindowsを起動しちゃったよ。(笑

結論から言うと、Java SE6.0 update 5のバグっぽい。

試してみたところWindows XP SP1(32bit)にJ2SE5.0のJREのみインストールしてある場合にはIE6、FIrefox2、Safari3.1とも特に問題もなくapplet動作する

次に、J2SE5.0をアンインストールした後にJavaSE6.0のJREのみインストールし、IE6、FIrefox2、Safari3.1でappletを起動してみると、IE6以外はappletが正しく動作せず、Firefox2やSafari3.1ではその後挙動があやしくなりHang upしたり、強制終了すると起動しなくなったりと散々な結果になった。IEはやはり動きが特殊なのなかぁ。
以下、その時のスクリーンショット。

Javase6_applet_win01

Javase6_applet_win02 Javase6_applet_win03

Javase6_applet_win04


Javase6_applet_win06


Javase6_applet_win07


Javase6_applet_win08


それは置いといて、JavaSE6.0でappletを動作させる方法は、このブログに書かれていた。(ありがとうございます)ので早速試してみると、お〜〜お見事! 回避できた。
Javase6_applet_win09

Javase6_applet_win10

Javase6_applet_win11


ちなみに、MacOSXではJavaSE6.0はPreview ReleaseのままですがWindowsのコントロールパネルと違い、Appletを実行するjavaのversionを簡単に切り替えられる。
とは言ってもMacOSX版では今のところ今回のような問題は起きていない(ようだ)。

Javase6_applet_mac_preference


ちなみに、MacOSX 10.4.11 PowerPC G5ではOpera9.25/Safari3.1/Firefox2.0.0.13ともOKだった。

| | コメント (7) | トラックバック (0)

2008年2月 4日 (月)

Oracle SQL Developer for MacOSX で Oracle Instant Clientを使ってみる

前回、Oracle Instant Client 10g R1 for MacOSX(PPC)がMacOSX LeopardのRosettaによって動作するところまでは確認できたということを書いたが、今日は、Oracle SQL Developer 1.2.1 for MacOSX(現時点での最新版)で Oracle Instant Client 10g R1のTNS接続する方法を書いておくことにする。

SQL*PlusをTerminalやxtermから起動するのであれば .bashrc 等で環境変数を設定すればよいですが、Oracle SQL DeveloperのようなGUIツールはどうすればいいのか?
MacOSXのGUI環境では、.bashrc等は利用できない。その変わりにenvironment.plistが利用される。environment.plistの説明は、Apple Technical Q&A QA1067 : Setting environment variables for user processesを見てもらうとして早速試してみます。

Oracle_sql_developer_sprash Oracle_sql_developer_1_2_1

まず、最初は、environment.plistが存在しない状態でOracle SQL Developerを起動し、前回設定したOracle Instant Client 10g R1 for MacOSX(PPC)のtnsnames.oraを利用したTNS接続が行えるか確認してみる。
Oracle_sql_developer_create_conne_2


tnsnames.oraの定義してある接続文字列がドロップダウンメニューに現れないですね。TNS_ADMIN環境変数などが効いていません。
Oracle_sql_developer_not_appear_con


次にApple Technical Q&A QA1067 : Setting environment variables for user processesの説明通りにenvironment.plistを作成後、一旦ログオフする。
(尚、environment.plistに設定する環境変数に関しては、前回のエントリを参照してください。

Last login: Mon Feb  4 18:58:45 on console
Macintosh:˜ discus$ mkdir .MacOSX
Macintosh:˜ discus$ cat environment.plust
cat: environment.plust: No such file or directory
Macintosh:˜ discus$ cat environment.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>DYLD_LIBRARY_PATH</key>
<string>/Users/Shared/oracleInstantClient</string>
<key>NLS_LANG</key>
<string>Japanese_Japan.AL32UTF8</string>
<key>ORACLE_HOME</key>
<string>/Users/Shared/oracleInstantClient</string>
<key>TNS_ADMIN</key>
<string>/Users/Shared/oracleInstantClient</string>
</dict>
</plist>
Macintosh:˜ discus$ mv environment.plist .MacOSX
Macintosh:˜ discus$

再度、ログインして、Oracle SQL Developerを起動し同じ手順でTNS接続できるか確認する。
お〜〜、こんどは、tnsnames.oraに定義してある接続文字列がドロップダウンメニューにリストされています。
Oracle_sql_developer_appear_connect


接続テストも上手く行きました。
Oracle_sql_developer_test_session_s


最後に、SQL WorkSheetなどでEMP表にデータを登録したり問い合わせたりしてみました。これまた問題なく使えます。
Oracle_sql_developer_insert_data_to

Oracle_sql_developer_query_data_fro


この例では、MacOSX Leopard(Intel Mac)のRosetta配下で動作しているOracle Instant Clientを利用しましたが、MacOSX Tiger(PPC)版でも同様の手順で動作します。
興味のある方はお試しあれ。。..

| | コメント (0) | トラックバック (0)

2008年1月27日 (日)

MacOSX で Eclipse の日本語化(備忘録)

Eclipseの日本語化プラグインのインストール手順について以下を参考にしたのだが、MacOSX以外の記述もあり少々分かりにくかったので自分なりの備忘録として書いておく。
とはいってもMacOSX上で利用する可能性は低いのだけれど・・・
Eclipse Wiki - 日本語化に関する記述

だったら何故、EclipseをMacOSXで使おうと思ったのか?・・・・

先日、OTN-Jのエントリに回答したのがきっかけで・・・、仕事ではEclipseを利用する事が多いウチの奥さんと

私     :「MacOSXでEclipseを日本語化する手順ってブログで書いてたっけ?
ウチの奥さん:「書いてないと思う」

という話になりこのエントリを書く気になったというわけ。。。(個人的には日本語化しないと使いにくいというわけでもないのですが・・・)

2008/1/28追記
奥さん曰く、Eclipseネタは沢山あるからネタとしてはつまらないし、誰かがもう書いていると思ったからだとか。。。

今回利用した Eclipse for MacOSXのバージョンは、3.3.1.1
日本語化プラグインは、pleiades-all-in-one-java-wtp_20071121.zip
MacOSX : version 10.4.11

http://www.eclipse.org/downloads/
http://mergedoc.sourceforge.jp/

※ダウンロードしたEclipseと日本語化プラグインはぞれぞれ適当なフォルダで解凍済み。

以下の例では、Eclpseと日本語化プラグインはそれぞれ

/Volumes/ExtraDisk/Application



/Volumes/DiscusWork/temp

以下に解凍した。

Last login: Wed Jan 23 17:16:05 on console
Welcome to Darwin!
G5Server:˜ discus$
G5Server:˜ discus$ cd /Volumes/ExtraDisk/Application/eclipse/
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$ ls -l
total 64
drwxr-xr-x 3 discus discus 102 Nov 4 02:47 Eclipse.app
drwxr-xr-x 10 discus discus 340 Jan 23 18:06 configuration
lrwxrwxrwx 1 discus discus 34 Jan 23 17:48 eclipse -> Eclipse.app/Contents/MacOS/eclipse
-rw-r--r-- 1 discus discus 16536 Nov 4 02:47 epl-v10.html
drwxr-xr-x 104 discus discus 3536 Jan 23 17:50 features
-rw-r--r-- 1 discus discus 6506 Nov 4 02:47 notice.html
drwxr-xr-x 461 discus discus 15674 Jan 23 17:52 plugins
drwxr-xr-x 3 discus discus 102 Nov 4 02:47 readme
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$

※これが重要。
日本語化パッケージのconfiguration、features、pluginsの各ディレクトリ以下にある全ファイルをコピーする(注:ディレクトリごと上書きしないように!)

G5Server:/Volumes/ExtraDisk/Application/eclipse discus$ cp -Rf /Volumes/DiscusWork/temp/pleiades-all-in-one-java-wtp_20071121/configuration/*.* configuration
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$ cp -Rf /Volumes/DiscusWork/temp/pleiades-all-in-one-java-wtp_20071121/features/*.* features
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$ cp -Rf /Volumes/DiscusWork/temp/pleiades-all-in-one-java-wtp_20071121/plugins/*.* plugins
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$

※eclipse.iniを編集。

(configuration以下のelipse.iniではないので注意。)
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$ cat Eclipse.app/Contents/MacOS/eclipse.ini
-showsplash
org.eclipse.platform
-vmargs
-Xdock:icon=../Resources/Eclipse.icns
-XstartOnFirstThread
-Xms40m
-Xmx512m
-XX:MaxPermSize=256m
-javaagent:/Volumes/ExtraDisk/Application/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar=no.mnemonic
-Dosgi.requiredJavaVersion=1.5
-Dorg.eclipse.swt.internal.carbon.smallFonts


※細かいことは考えずにとりあえず、-cleanを付けて起動しちゃう。(日本語プラグイン追加後に一度だけ。)

G5Server:/Volumes/ExtraDisk/Application/eclipse discus$ 
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$ ./eclipse -clean &
[1] 1814
2008-01-23 18:06:41.005 eclipse[1704] [Java CocoaComponent compatibility mode]: Enabled
2008-01-23 18:06:41.005 eclipse[1704] [Java CocoaComponent compatibility mode]: Setting timeout for SWT to 0.100000

G5Server:/Volumes/ExtraDisk/Application/eclipse discus$
[1]+ Done ./eclipse -clean
G5Server:/Volumes/ExtraDisk/Application/eclipse discus$

上手くできました〜。 :)


Eclipse1 Eclipse2

Eclipse3

Eclipse4

最後の画像は、最初に

先日、OTN-Jのエントリに回答したのがきっかけで・・・、

と書いた”きっかけ”の話題に関連したおまけ・・・次回のエントリはそのネタにしようかと思う。

| | コメント (0) | トラックバック (0)

2008年1月22日 (火)

Mac De Oracle なんですが、Windows(32bit)でのOracleな話 #4 のおまけ

Mac De Oracle なんですが、Windows(32bit)でのOracleな話 #4では専用サーバ接続であるためoracle.exeがユーザメモリ空間の制限である2GBを超えてスレッドを作れずにORA-12518が発生していた。
では2GBを超えない範囲で共有サーバを起動して接続した場合はどうなるだろうか?(大抵の方は共有サーバ接続であればこの問題を解決できることは認識されていると思うが共有サーバ接続にした場合、専用サーバ接続に比べデメリットもある。テスト環境でしっかりテストし条件を満たせるかしっかり見極める必要がある。共有サーバ接続のご利用は計画的に!!)

2006年のOOWで興味深い資料が公開されていたのでURLを載せておきます。
http://www.oracle.co.jp/openworld/tokyo2006/session_download/1B-8.pdf

以下に示した初期化パラメータ以外は以前のエントリで記載した値に同じ

SYS> alter system set shared_servers=5 scope=both;

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

SYS> alter system set dispatchers='(PROTOCOL=TCP)(SERVICE=catfishS)(DIS=10)' scope=both;

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

SYS> select name,network from v$dispatcher;

NAME NETWORK
---- --------------------------------------------------------------------------------
D000 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=3818))
D001 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1463))
D002 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1464))
D003 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1465))
D004 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1466))
D005 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1467))
D006 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1468))
D007 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1469))
D008 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1470))
D009 (ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=1471))


10行が選択されました。

SYS> $lsnrctl service

SYS> select count(*) from v$session;

COUNT(*)
----------
16


ここでJDeveloperから接続(400セッション)接続に利用したコードは以前テストで利用したものと同じ。
Shared_server_jdev

Shared_server_win_mon

SYS> select count(*) from v$session;

COUNT(*)
----------
416

SYS> $lsnrctl service

LSNRCTL for 32-bit Windows: Version 10.2.0.2.0 - Production on 20-1月 -2008 14:47:56

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

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=catfish.macdeoracle.jp)(PORT=1521)))に接続中
サービスのサマリー...
サービス"catfish.macdeoracle.info"には、1件のインスタンスがあります。
インスタンス"catfish"、状態READYには、このサービスに対する1件のハンドラがあります...
ハンドラ:
"DEDICATED" 確立:0 拒否:0 状態:ready
LOCAL SERVER
サービス"catfishS.macdeoracle.info"には、1件のインスタンスがあります。
インスタンス"catfish"、状態READYには、このサービスに対する10件のハンドラがあります...
ハンドラ:
"D009" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 320>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2213))
"D008" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 2756>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2212))
"D007" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 2912>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2211))
"D006" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 856>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2210))
"D005" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 2092>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2209))
"D004" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 1256>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2208))
"D003" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 3236>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2206))
"D002" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 3248>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2205))
"D001" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 3312>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2204))
"D000" 確立:40 拒否:0 現行:40 最大:1002 状態:ready
DISPATCHER <machine: CATFISH, pid: 3288>
(ADDRESS=(PROTOCOL=tcp)(HOST=catfish.macdeoracle.jp)(PORT=2203))
コマンドは正常に終了しました。

SYS>
SYS>

| | コメント (0) | トラックバック (0)

2007年12月21日 (金)

太った空白

書こうか迷っていたのだが、意外とハマっている方が多いらしいので書いておく事にした。
まあ、エラーメッセージがわかりずらいのでしょうがないとは思うが。

PL/SQLで開発する際に出くわす事がある。
(私もたまにやっちゃいますけどハマることはないです。こればかりは慣れるしかないですね。)

ということで太った空白のお話。

PL/SQLではマルチバイト文字の空白(全角の空白と言ったほうがわかりやすいでしょうか?)が原因で意味不明のコンパイルエラーを引き起こす。
そう、”太った空白”と書いたのはマルチバイト文字の空白。半角の空白が2つあるように見えるが全角の空白が1文字。

まずは、以下の例を見てください。

Last login: Fri Dec 21 08:25:31 on console
Welcome to Darwin!
G5Server:˜ discus$ su - oracle
Password:
G5Server:˜ oracle$ ssh oracle@corydoras
oracle@corydoras's password:
Last login: Sun Dec 16 18:02:52 2007 from 192.168.1.19
[oracle@corydoras ˜]$ sqlplus /nolog

SQL*Plus: Release 11.1.0.6.0 - Production on 金 12月 21 19:50:10 2007

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

> conn scott/tiger
接続されました。
SCOTT> create or replace function now
2 return timestamp
3 is
4 begin
5  return systimestamp;
6 end;
7 /

警告: ファンクションが作成されましたが、コンパイル・エラーがあります。

SCOTT> show errors
FUNCTION NOWのエラーです。

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/3 PLS-00103: 記号""が見つかりました。 次のうちの1つが入るとき:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
記号"" は無視されました。

上記では、now()というストアドファンクションを作成しようとして5行目の3カラム目でコンパイルエラーが発生している。
(ストアドファンクション自体は意味の無いものなので気にしないでね。コンパイルエラーに注目してください。)

5行目の3カラム目は、"r"だなと思ったあなたは、もうすでにハマっていますよ。

実は、5行目の先頭の空白は半角の空白2文字ではなく”全角の空白1文字”なんです。

もうお分かりですよね。では、全角空白1文字を半角空白2文字に置換して再実行してみましょう。

SCOTT> list 5
5*  return systimestamp;
SCOTT> c / return/ return
5* return systimestamp;
SCOTT> l
1 create or replace function now
2 return timestamp
3 is
4 begin
5 return systimestamp;
6* end;
SCOTT> /

ファンクションが作成されました。

SCOTT> select now() from dual;

NOW()
---------------------------------------------------------------------------
07-12-21 19:56:19.046993000

SCOTT> /

| | コメント (0) | トラックバック (0)

2007年11月14日 (水)

Mac De Oracle なんですが、Windows(32bit)でのOracleな話 #4

久々のオラクルネタですがWindows版のOracleネタです。随分前にこんなこと書いてました。

で、それ以後、見た目にはどんなエラーがでるの? とか、最近の検索フレーズ/ワードに、"Windows oracle 最大 session数"のようなフレーズを多く目にするようになったので、超簡単な再現例を一つ。


尚、Windows 32ビット環境で同時接続可能なセッション数(processes、sessions初期化パラメータに設定している値を超えた場合を除く。)は、SGAのサイズや各セッションのPGAサイズ、それに専用サーバーであるか、共有サーバーであるかという点にも影響される。お使いのシステムで、どの程度まで同時に接続できるかはその環境でしか確認できないということを付け加えておく。

また、必要最小限のPGAサイズ(単に接続しているだけなので)でどれだけ同時に接続できるのかを試している点にもご注意願いたい。(ストアドやDML文を実行する際に必要なPGAサイズはもっと大きくなる場合がほとんどなので実際に同時接続できるセッション数はもっと少なくなることの方が多い。)

●準備

この例ではすぐに接続数の上限に達するようSGAサイズはOracle10g R2 EE for Windows(32bit)が起動できる限界付近のサイズまで増加させた。

注)この方法でテストするのであれば、変更前のspfileをpfileへ退避して置く事をおすすめします。SGAサイズを大きくし過ぎてOracleを起動できなくなった場合でもpfileを使って起動することで元に戻せますから。

接続は専用サーバー接続で行い、目的のエラーを発生させる以前にprocess数やsession数の上限を超えないようにprocesses初期化パラメータを調整してある。
(SGA_TARGET及び、SGA_MAX_SIZE初期化パラメータは、私の環境でOracle10g EEが起動できる最大サイズに近い値に設定してある。ここまでSGAサイズを大きくすると、SQL*Plusを複数起動して接続するという力技でも目的のエラーを再現できる。その他初期化パラメータは以下を参照のこと。)

SYS>

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Prod
PL/SQL Release 10.2.0.2.0 - Production
CORE 10.2.0.2.0 Production
TNS for 32-bit Windows: Version 10.2.0.2.0 - Production
NLSRTL Version 10.2.0.2.0 - Production

SYS> show parameter sga_

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sga_max_size big integer 1760M
sga_target big integer 1760M
SYS>

SYS> show parameter pga

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target big integer 60M
SYS>
SYS> show parameter sessions

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
・・・・中略・・・・
sessions integer 555
・・・・中略・・・・
SYS>
SYS>
SYS> show parameter processes

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
・・・・中略・・・・
processes integer 500
SYS>

SYS> select sum(value) from v$sga;

SUM(VALUE)
----------
1845493760

SYS>
SYS> select count(*) from v$session;

COUNT(*)
----------
16


前述の状態で、ひたすら(と言っても400までだが)Oracleへ接続するだけのjava programを実行すると。。。oracle.exeのVMサイズが2GBを超えた為に、あたらなスレッドを作れないことが原因で、ORA-12518というエラーが発生する。

●以下、JDeveloper10gで試してるスナップショット

Jdev_macosx_maxconn

/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/bin/java -server -classpath /Users/discus/jdevhome/mywork/MaxConnection/
MaxConnection/classes:/Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/jdbc/lib/ojdbc14dms.jar:/Volumes/ExtraDisk/
Application/JDeveloper.app/Contents/Resources/jdev/jdbc/lib/orai18n.jar:/Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/
jdbc/lib/ocrs12.jar:/Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/diagnostics/lib/ojdl.jar:/
Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/lib/dms.jar maxconnection.MaxConnection
コネクション数:21
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12518, TNS:listener could not hand off client connection
The Connection descriptor used by the client was:
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(PORT=1521)(HOST=192.168.1.2))(CONNECT_DATA=(SERVICE_NAME=catfish.macdeoracle.info)))

at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:138)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:293)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:328)
at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:430)
at oracle.jdbc.driver.T4CConnection.(T4CConnection.java:151)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:608)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:218)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:159)
at maxconnection.MaxConnection.(MaxConnection.java:26)
at maxconnection.MaxConnection.main(MaxConnection.java:41)


●21セッション増えたことの確認!

SYS> r   
1* select count(*) from v$session

COUNT(*)
----------
37

SYS>

SGAサイズをOracleが起動可能な最大値に近づけたため、たった22セッションでoracle.exeのVMサイズが2GBを超えORA-12518が発生した。

ハッキリ言って、ORA-12518 : TNS:listener could not hand off client connection というエラーメッセージを見て32ビット版Windowsの上で実行されているoracle.exeが2GBの制限を超えたため新たなスレッドを作ることができなかったエラーであると、直感的に理解出来る人は少ないんじゃないかと思う。
(他の原因でこのエラーが発生する場合もあるのかもしれないが、私がこのエラーを目にしたのはWindows環境でoracle.exeが利用できるメモリサイズを超過したため新たに専用サーバーのスレッドを作れなかった場合だけだった。
2007/11/29追記:共有サーバーモードでも試してみるか!。またWindowsでOracleを使う事もあるだろうから。。ー>TODO)

不幸にしてORA-12518に遭遇した場合は、まず最初にoracle.exeのVMサイズが2GBを超えていないか確認したほうがいいだろう。(尚、本番システムやテスト環境で発生する場合は、SGAと新たに必要とするされるPGAサイズの関係で、oracle.exeのVMサイズが1.5GBから1.6GB程度でも発生する場合もある。)

●以下、マニュアルからの引用


ORA-12518: TNS: リスナーはクライアント接続をハンドオフできませんでした
 原因: クライアント接続を別のプロセスにハンドオフするプロセスが失敗しました。
 処置: トレースをオンにして、失敗した操作を再実行してください。
    リスナーおよびデータベース・インスタンスが、

    ダイレクト・ハンドオフに対して正しく構成されていることを確認してください。
    問題が解決されない場合は、オラクル社カスタマ・サポート・センターに連絡して
    ください。



●以下、テストに利用したjavaのソース。

package jp.macdeoracle.maxconnection;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import oracle.jdbc.pool.OracleDataSource;


public class MaxConnection
{
public MaxConnection()
{
OracleDataSource ods;
ArrayList connList = new ArrayList();
try
{
ods = new OracleDataSource();
ods.setServerName( "192.168.1.2" );
ods.setServiceName( "catfish.macdeoracle.info" );
ods.setPortNumber( 1521 );
ods.setDriverType( "thin" );
ods.setUser( "scott" );
ods.setPassword( "tiger" );

for (int i=0;i<400;i++){
connList.add( ods.getConnection() );
}

} catch (SQLException e)
{
e.printStackTrace();
} finally
{
System.out.println("コネクション数:"+connList.size());
}
}

public static void main(String[] args)
{
MaxConnection maxConnection = new MaxConnection();

try
{
Thread.sleep(60000L); //sleep 60sec
}
catch (InterruptedException e)
{
// TODO
}
}
}


おまけ。
ORA-12518が発生した際、Pslist.exeを実行して取得したoracle.exeのVMサイズとスレッド一覧の例)

VMサイズ(赤字)が2GBに近い。

Thread detail for CATFISH:

Name Pid VM WS Priv Priv Pk Faults NonP Page
oracle 972 2074972 324688 1918700 1922024 123716 59 165
oracle 972:
Tid Pri Cswtch State User Time Kernel Time Elapsed Time
2832 9 314 Wait:Executive 0:00:00.000 0:00:00.250 0:37:03.156
2228 9 97 Wait:UserReq 0:00:00.000 0:00:00.031 0:37:01.281
2236 9 327 Wait:UserReq 0:00:00.000 0:00:00.015 0:37:01.265
2376 10 1082 Wait:UserReq 0:00:00.000 0:00:00.046 0:36:57.718
2380 8 1363 Wait:UserReq 0:00:00.015 0:00:00.000 0:36:57.687
2384 8 999 Wait:UserReq 0:00:00.375 0:00:00.015 0:36:57.671
・・・・中略・・・・
2484 10 45 Wait:UserReq 0:00:00.000 0:00:00.015 0:00:02.359
1512 10 48 Wait:UserReq 0:00:00.031 0:00:00.015 0:00:02.312
2316 10 45 Wait:UserReq 0:00:00.015 0:00:00.015 0:00:02.250

| | コメント (0) | トラックバック (0)

2007年9月28日 (金)

"日本語"のデータベースオブジェクト名 #2

ということで、前回のつづきというか、予告通り、"日本語"(マルチバイト文字)をデータベースオブジェクト名として定義しているデータベースで起こりうる問題点について。

"日本語"(マルチバイト文字)で 表名、列名、いないと思うけど(笑)ストアドプロシージャ名などを定義している方々は注意しておいたほうがよいだろう。

Oracleで許可されているデータベースオブジェクト名のサイズは、マニュアルにも記載されているように、データベース名とデータベースリンクを除き、30バイトまでと規定されていることを思い出してほしい。

日本語:Oracle Database SQLリファレンス 10g リリース2(10.2) - スキーマ・オブジェクトのネーミング規則

英語:Oracle® Database SQL Reference 10g Release 2 (10.2) - Schema Object Names and Qualifiers

例えば、データベースキャラクタセットが、JA16SJISである場合、テーブル名や列名を日本語(マルチバイト文字)で定義すると利用できる文字数は最大15文字までである。(半角英数字であれば、30文字)

以下、データベースキャラクタセット:JA16SJIS環境下でマルチバイト/シングルバイトでテーブル名を定義した場合の例

SCOTT> select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';

PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_CHARACTERSET JA16SJISTILDE

SCOTT>
SCOTT>
SCOTT> create table z12345678901234567890123456789 (a number);

表が作成されました。

●マルチバイト文字で15文字(30バイト)なのでOK!

SCOTT> create table "Z12345678901234" (a number);

表が作成されました。

SCOTT> create table z12345678901234567890123456789x (a number);
create table z12345678901234567890123456789x (a number)
*
行1でエラーが発生しました。:
ORA-00972: 識別子が長すぎます。

●マルチバイト文字で16文字(32バイト)なのでNG!

SCOTT> create table "Z123456789012345" (a number);
create table "Z123456789012345" (a number)
*
行1でエラーが発生しました。:
ORA-00972: 識別子が長すぎます。


SCOTT>
SCOTT> select table_name,lengthb(table_name) from user_tables;

TABLE_NAME LENGTHB(TABLE_NAME)
------------------------------ -------------------
Z12345678901234567890123456789 30
Z12345678901234 30

SCOTT>


前述のようなJA16SJISをデータベースキャラクタセットとするデータベースを、Unicodeのキャラクタセットである AL32UTF8 をデータベースキャラクタセットとするデータベースへ移行しようとした場合、どうなるか想像できますか?

想像できますよね? 

そう、単純には移行できないのですよ。JA16SJISでは2バイトだった文字がAL32UTF8では3バイトになる訳ですから。

マルチバイト1文字のバイト数の増加によりデータ量も増加するので、DISK容量の見直しも必要になるのですが、一番問題になるのが、日本語でデータベースオブジェクト名を定義しているという点でしょう。

もし、表名や列名を日本語(マルチバイト文字)11文字以上で定義しているとしたら、データベースキャラクタセットが AL32UTF8 であるデータベース上では、DDL全てがエラーになるはずです。
それらを修正するとなると、SQL/DDL文。その他プログラムに至まで、その影響は広範囲に渡るのではないでしょうか?


将来的なことも考慮してUnicode環境へ移行したいということであれば、コストを掛けて移行する価値はあると思います。その際にはシングルバイト文字で各名称を定義したほうがよいでしょうね。日本語の表名や列名の方が、直感的にわかりやすいからと日本語でテーブル名や列名を定義し、たった10文字でわかりやすい名称を定義することはかなり難しいと思いますから。

A:「--------」
B:「え、10文字でも定義できますよって!? 」
B:「もしや、"T123456789"とかいうテーブル名にでもしようと考えていますか?」
B:「それとも、名称を省略しまくって10文字以内の略名にしようと考えているのでしょうか?」
B:「それが、直感的に見てわかりやすい名称でしょうか?」
B:「見て、直感的に理解しやすいから日本語名称でテーブル名を定義したいのではないですか?」
な〜〜〜〜んて、やりとりが聞こえてきそう。。。

私が関わったところではそんな面倒なところは無かったので幸せだったりするが・・・・・

以下、データベースキャラクタセット:AL32UTF8環境でマルチバイト/シングルバイト、それぞれでテーブル名を定義した場合の例

SCOTT> select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';

PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_CHARACTERSET AL32UTF8

SCOTT>
SCOTT> create table z12345678901234567890123456789 (a number);

表が作成されました。

●マルチバイト文字で15文字(45バイト)!、当然サイズ超過!


SCOTT> create table "Z1234567891234" (a number);
create table "Z1234567891234" (a number)
*
行1でエラーが発生しました。:
ORA-00972: 識別子が長すぎます。

●マルチバイト文字で10文字。(30バイト)

SCOTT> create table "Z123456789" (a number);

表が作成されました。

●シングルバイト文字で31文字(31バイト)なので当然エラー!

SCOTT> create table z12345678901234567890123456789x (a number);
create table z12345678901234567890123456789 (a number)
*
行1でエラーが発生しました。:
ORA-00972: 識別子が長すぎます。


SCOTT>


SCOTT> select table_name,lengthb(table_name) from user_tables;

TABLE_NAME LENGTHB(TABLE_NAME)
------------------------------------------------------------ -------------------
Z123456789 30
Z12345678901234567890123456789 30

SCOTT>

| | コメント (0) | トラックバック (0)

2007年9月27日 (木)

"日本語"のデータベースオブジェクト名 #1

Oracle10gのグローバリゼーションガイドには、新たに構築するデータベースでは、データベースキャラクタセットとして AL32UTF8 を推奨している。
Oracle Database グローバリゼーション・サポート・ガイド
10g リリース2(10.2)- データベース・キャラクタ・セットに関する指示書

ちなみに、Oracle製品間であっても、こんな注意点もある。
Oracle Content Management SDK(Oracle CM SDK)

とにかく、データベースキャラクタセットを選択する際には、関連するプロダクトの制限などもよ〜〜く調査して、方針を決めないといけないだろうね。あとで苦労しないためにも。

次回は、データベースキャラクタセット絡みで注意しないとならない点を書こうかな。
特に、日本語(マルチバイト文字)で表名、列名、その他のデータベースオブジェクト名を定義しているようなところでは注意しておいたほうがよい点について書いてみようかと。

そういえば、"日本語" de ストアドなんてお遊びもやってましたねぇ。(^^;;

| | コメント (0) | トラックバック (0)

2007年9月23日 (日)

SQL*Loader で BLOBロード

少々前に、大量のBLOBデータをデータベースへロードするためのプログラムをコーディングしている方がいたのだが、そのプログラムの仕様を聞いてみたら、SQL*Loaderでも対応可能な内容だった。SQL*LoaderでBLOBデータをローディングできることは知らなかったのだ。知っていたらもっと楽だったろうに。


今回の例ではOracle10g R1を利用しているのだが、Oracle10g R2でも使い方は同じ。

● 参考:
・Oracle Database ユーティリティ 10g リリース1(10.1)
・Oracle Database ユーティリティ 10g リリース2(10.2)LOBFILEからのLOBデータロード
・Oracle Database ユーティリティ 10g リリース2(10.2)EXPRESSIONパラメータ

ということで、前述の話に比べると少々単純なのだがロードの例を一つ。

● まずは準備。

BLOBを格納する表のキーはユニークな数値なので、シーケンスを利用する。え!? SQL*Loaderでシーケンスが利用できるのか?
できるんです。EXPRESSIONパラメータを利用すれば!(EXPRESSIONパラメータの利用例は随分前にOTN-JのCode Tipsへも投稿してあったっけ。OTN-JのCode Tipsを参照するにはOTN-Jへのユーザ登録(無料)必要です。)

> conn scott/tiger
接続されました。
SCOTT>
SCOTT>
SCOTT> create sequence sq_blob_key
2 start with 1
3 increment by 1
4 maxvalue 999999
5 nocycle
6 nocache;

順序が作成されました。

BLOBデータを登録する表の定義は以下。
(blob用表領域は他のデーブルデータとは別表領域にしている)

SCOTT> l
1 create table blobtab
2 (
3 blob_id number primary key,
4 blob_type varchar(4),
5 content blob
6 )
7 lob(content) store as
8 (
9 tablespace blobspace
10 nocache logging
11* )
SCOTT> /

表が作成されました。

SCOTT>


● SQL*Loaderの制御ファイルとBLOBとして登録するファイルは同一ディレクトリ上へ配置。

ちなみに、Linux/Unix系OSでは、hostコマンドまたは、! を利用すればSQL*Plusからshellコマンドなとを直接実行できる。
SCOTT>  
SCOTT> !ls | grep -E '¥.(ctl|jpg|zip|png|gif)$'
blobload.ctl
discus.gif
generic_connectivity.zip
image001.png
neontetra.jpg

SCOTT>


● SQL*Loaderの制御ファイルの内容

ポイントは、シーケンスを利用するために、expressionパラメータで sq_blob_key.nextval と設定している点と、ex_fname FILLER以降の定義(赤字部分)。
SCOTT> !cat blobload.ctl
LOAD DATA
INFILE 'blobload.dat'
INTO TABLE blobtab
FIELDS TERMINATED BY ','
(
blob_id expression "sq_blob_key.nextval",
blob_type,
ext_fname FILLER CHAR(80),
content LOBFILE(ext_fname) TERMINATED BY EOF
)


● SQL*Loaderの制御ファイルのINFILEパラメータで指定するデータファイルの内容

この例では同一ディレクトリに配置した gif/zip/png/jpgを登録対象とした。
拡張子、ファイル名の順にカンマ区切りでデータファイルを作成。(awkを使えば簡単ですしね)

SCOTT> !ls | grep -E '¥.(zip|jpg|png|gif)$' | awk '{print substr($1,index($1,".")+1)","$1","}' > blobload.dat
SCOTT> !cat blobload.dat
gif,discus.gif,
zip,generic_connectivity.zip,
png,image001.png,
jpg,neontetra.jpg,

SCOTT>
SCOTT>


● 準備完了!

準備が整った。今回はSQL*Loaderの制御ファイル、データファイル、BLOBとして登録するファイルを同一ディレクトリに配置した。
SCOTT> !ls | grep -E '¥.(ctl|dat|jpg|zip|png|gif)$'
blobload.ctl
blobload.dat
discus.gif
generic_connectivity.zip
image001.png
neontetra.jpg

SCOTT>


● SQL*Loaderの実行

SCOTT> !sqlldr userid=scott/tiger@xtiger control=blobload.ctl log=blobload.log

SQL*Loader: Release 10.1.0.3.0 - Production on 土 9月 22 17:12:16 2007

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

コミット・ポイントに達しました。 - 論理レコード件数4

SCOTT>


● SQL*Loaderのログを確認!

SCOTT> !cat blobload.log

SQL*Loader: Release 10.1.0.3.0 - Production on 土 9月 22 17:12:16 2007

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

制御ファイル: blobload.ctl
データ・ファイルblobload.dat
不良ファイル: blobload.bad
廃棄ファイル: 指定なし

(すべて廃棄できます)

ロード数: ALL
スキップ数: 0
許容エラー数: 50
バインド配列: 64行、最大256000バイト
継続文字: 指定なし
使用パス: 従来型

表BLOBTAB、 ロード済 すべての論理レコードから
この表に対する有効な挿入オプション: INSERT

Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
BLOB_ID EXPRESSION
列のSQL文字列 : "sq_blob_key.nextval"
BLOB_TYPE FIRST * , CHARACTER
EXT_FNAME NEXT 80 , CHARACTER
(FILLERフィールド)
CONTENT DERIVED * EOF CHARACTER
動的LOBFILE - ファイル名EXT_FNAME


表BLOBTAB:
4行のロードに成功しました。
0行はデータ・エラーのためロードされませんでした。
0行はWHEN句のエラーのためロードされませんでした。
0行はすべてのフィールドがNULLのためロードされませんでした。

バインド配列に割り当てられた領域: 21760バイト(64行)
読取りバッファのバイト数: 1048576

スキップされた論理レコードの合計: 0
読み込まれた論理レコードの合計: 4
拒否された論理レコードの合計: 0
廃棄された論理レコードの合計: 0

実行開始土 9月 22 17:12:16 2007
実行終了土 9月 22 17:12:17 2007

実行時間: 00: 00: 00.80
CPUタイム : 00: 00: 00.06

SCOTT>


● 内容確認。(登録ファイルのサイズとBLOBサイズが同じであることを確認)

SCOTT> select
2 blob_id,
3 blob_type,
4 lengthb(content)
5 from
6 blobtab
7 order by
8 blob_id;

BLOB_ID BLOB LENGTHB(CONTENT)
---------- ---- ----------------
1 gif 9675
2 zip 20070
3 png 2327573
4 jpg 6492

SCOTT>
SCOTT> !ls -l | grep -E '¥.(jpg|zip|png|gif)$'
-rw-r--r-- 1 oracle oinstall 9675 Dec 31 1997 discus.gif
-rw-r--r-- 1 oracle oinstall 20070 Nov 17 2005 generic_connectivity.zip
-rw-r--r-- 1 oracle oinstall 2327573 Jul 21 16:21 image001.png
-rw-r--r-- 1 oracle oinstall 6492 May 4 1999 neontetra.jpg

SCOTT>

| | コメント (0) | トラックバック (0)

2007年8月 4日 (土)

Shutdown Timeout

今回は、Oracle10g R2から実装された停止タイムアウトネタです。よく、shutdown immediateを実行したのに、”すぐにshutdownしない”。なんて話を聞きますが、
当然ですよ、immediateという言葉とは裏腹に、shutdown immediateにより強制的にrollbackされたトランザクションが、大量にundoブロックを保持していたらどうなると思いますか?

トランザクションのロールバックに時間がかかり、shutdown処理が待たされる、という状況が発生します!

これが、shutdown immediateを実行したのに、”すぐには停止しない”理由です。(これ以外の理由で停止しない場合もあるにはあるようだが・・・、大抵の場合はこれが原因。)

Oracle10g R2 より前のリリースでは、shutdown immeidateが終了せず、遠くを見つめて、ただ、ひたすら終了を待ち続けた方は、意外と多いかもしれません。。
しかも、Oracleさん、な〜〜〜んにもメッセージ出してくれないので何を待機しているのか、何をしているのか分かりずらいし。
で、そのガス抜き策? なのか、 Oracle10g R2から、停止タイムアウトという機能が追加されています。
これは、文字通り、shutdownが一定時間内に終了しないと、shutdown自体がキャンセルされてしまうという機能です。
正常に復帰しても、本当に実行したかったのは、shutdownなのですから、それはそれで欲求不満状態ではあるのですが・・・(笑)


SYS> l
1 create smallfile tablespace test datafile E:¥ORACLE¥ORADATA¥CATFISH¥CATFISH¥test.dbf' size 10g
2 autoextend on
3 extent management local uniform size 1m
4* segment space management auto
SYS> /

表領域が作成されました。

SYS>
SYS> create table scott.test (data varchar2(4000)) tablespace test;

表が作成されました。

いうことで、準備完了。(Windows版のOracle Database 10g R2を利用しています。)

次に、以下のように、大量のデータを登録し、1時間以上実行させておく。
(当然、ストレージの性能などにより、どの程度のデータを登録すれば、ロールバックが1時間以上になるのか異なってくることをお忘れなく。今回テストに利用したものは、HDDが2本、OSとは別ドライブのDISKにOracleのバイナリ及びデータファイルを配置。)

では、SCOTTユーザに接続して、大量データを登録!

SCOTT> 
SCOTT> l
1 begin
2 for i in 1..2000000 loop
3 insert into test values(lpad('x',4000,'x'));
4 end loop;
5* end;
SCOTT> /


おまけ。
別途、SQL*Plusを起動し、SYSDBAで接続して、UNDOの量をモニタしているところ。

SYS> r
1 select
2 s.username,
3 t.used_ublk,
4 to_char(systimestamp,'hh24:mi:ss.ff') as time
5 from
6 v$session s join v$transaction t
7* on t.addr = s.taddr

USERNAME USED_UBLK TIME
---------- ---------- ------------------------------------
SCOTT 2618 17:29:43.890000


大量データ登録処理を実行したまま、一時間以上経過したところで、shutdown immediateを実行!!
すると、一時間以上実行していたトランザクションのロールバック処理のため、shutdownが待機させられる。

そう、これが、shutdown immediateで、shutdownしても言葉通り、即刻には停止しない状況の一例なのである。
Oracle10g R2より前のリリースであれば、延々と待たなければならない。それが、2時間や3時間だとキツいですよね。
しかも、shutdownを実行してしまったので、その後は何もできないし。

そこで、Oracle10g R2から実装されたのが、shutdownが自動的にcancelされるという機能。
(便利なだと感じるかどうかは。。。いろいろ・・・)


では、ロールバックに1時間以上かかる状態になったところで、shutdown immeidateを実行!!!

SYS> shutdown immediate;
・・・・・ここでおおよそ1時間ほど待たされます。コーヒーでも飲んで、ゆったりと・・・・お待ちください。

ほぼ1時間経過しても、shutdownが待機させられていると、以下のようなメッセージとともに
SQL*plusへ制御が返されます。

ORA-01013: ユーザーによって現行の操作の取消しがリクエストされました。

SYS>

この時点で、shutdownがキャンセルされ、通常の状態に戻っています。再度コマンドを投入できる状態に戻っています。(Oracle11gのマニュアルにtimeout時の注意が追加されています。10gのマニュアルにはキャンセルされるという事以外書かれていいませんが。2010/1/12追記)


alert_<SID>.logには以下のように記録されます。
以前のリリースに比べると、shutdownが待機させられているというメッセージや、shutdownがキャンセルされたというメッセージなど、意外と分かり易いメッセージが記録されている事に気付くはずです。ず〜〜〜っと、なんのメッセージもなく待たされるよりはましといったところです。

Tue Jul 31 23:03:16 2007
Shutting down instance: further logons disabled
Tue Jul 31 23:03:24 2007
Stopping background process QMNC
Tue Jul 31 23:03:24 2007
Stopping background process CJQ0
Tue Jul 31 23:03:25 2007
Stopping background process MMNL
Tue Jul 31 23:03:26 2007
Stopping background process MMON
Tue Jul 31 23:03:26 2007v
Thread 1 advanced to log sequence 289
Current log# 1 seq# 289 mem# 0: E:¥ORACLE¥ORADATA¥CATFISH¥CATFISH¥REDO01.LOG
・・・・中略・・・・
Tue Jul 31 23:03:27 2007
Shutting down instance (immediate)
License high water mark = 14
Tue Jul 31 23:03:27 2007
Stopping Job queue slave processes
Tue Jul 31 23:03:27 2007
Job queue slave processes stopped
・・・・中略・・・・
Tue Jul 31 23:08:26 2007
Active call for process 884 user 'SYSTEM' program 'ORACLE.EXE (SHAD)'
SHUTDOWN: waiting for active calls to complete.

Tue Jul 31 23:22:39 2007
MMNL absent for 1203 secs; Foregrounds taking over
・・・・中略・・・・
Wed Aug 01 00:03:26 2007
SHUTDOWN: Active sessions prevent database close operation

まあ、shutdown immediateする場合には事前に、rollbackに時間を要するトランザクションが実行中でないことをよ〜〜〜〜く確認するか、運用ルールで実行しない/できないように制限したりすることが重要だと思いますね。

次回は、ロールバックの終了時刻を大雑把に見積もるファンクションでも作成してみるか・・・

参考:「Oracle Database 管理者ガイド 10g リリース 2(10.2)- 停止タイムアウト」

2010/1/12追記.
Oracle11g R2のマニュアルの停止タイムアウトの解説に停止タイムアウトが発生した場合、再度、shutdown immediateを実行して、それでもなお、timeoutするようならshutdown abort行う。という記述が追加されています。ご注意ください。Oracle® Database Administrator's Guide 11g Release 2 (11.2) - Shutdown Timeout
shutdown timeout

| | コメント (0) | トラックバック (0)

2007年6月 8日 (金)

Mac De Oracle : PL/SQL de Collection #5


Marcus Miller - Silver Rain - It'll Come Back to YouMarcus Miller - Silver Rain - It'll Come Back to You

ちょいと間が空いたが、PL/SQLのコレクションでのお遊び。その5回目。

検索ワードで結構目にするのが、"N次元 結合配列" というキーワード。

ということで、今回は、多次元のコレクションの例を。

N次元のコレクションってどうやって作るの? ってことで情報を検索しているのだと思いますが、しっかりマニュアルにも記載されているので、そちらもしっかり読んでおくことをおすすめしますよ!。

Associative Array(以下、結合配列)、VARRAYやNested Table(以下、ネスト表)どれでも、考え方は同じ。
コレクション自体を別コレクションの要素にすればできるんですよ。 コレクションを入れ子にする と言えばイメージしやすい? ですかね。


以下のコードで赤太字で示しているところが多次元コレクション定義とアクセスのポイント。
まず、empType型を要素とするNestedTableType型(ネスト表)を定義し、次にNestedTalbType型を要素とするStrAssociativeArrayType型(結合配列)を定義している。
以下の例は多少、ひねくれた例? として結合配列とネスト表という異なるコレクションを利用して多次元コレクションを定義している。その影響でコレクションの操作は多少面倒になるのだが..

尚、empType型は、事前に作成しておいたオブジェクト型。

create or replace
PROCEDURE multiLevelCollections
AS
TYPE NestedTableType IS TABLE OF empType;
TYPE StrAssociativeArrayType IS TABLE OF NestedTableType INDEX BY VARCHAR2(50);

myNestedTable NestedTableType := NestedTableType();
myStrAssociativeArray StrAssociativeArrayType;


claerMyStrAssociateArray StrAssociativeArrayType;

myEmp empType;
j dept.dname%TYPE;
vDeptName dept.dname%TYPE := NULL;

CURSOR csrEmp IS
SELECT
emp.job,
emp.deptno,
dept.dname,
emp.empno,
emp.ename,
emp.sal,
emp.hiredate
FROM
emp JOIN dept
ON emp.deptno = dept.deptno
ORDER BY
emp.deptno,
emp.ename;

PROCEDURE printArray
IS
BEGIN
DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE('**** コレクションに要素が存在している状態 ****');
DBMS_OUTPUT.PUT_LINE(
'myStrAssociativeArray('
|| myStrAssociativeArray.COUNT
|| ')'
);

j := myStrAssociativeArray.FIRST;
WHILE j IS NOT NULL LOOP
DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE(
'myStrAssociativeArray('
|| j || ')(' || myStrAssociativeArray(j).COUNT || ')'
);

FOR k IN
myStrAssociativeArray(j).FIRST..myStrAssociativeArray(j).LAST
LOOP
DBMS_OUTPUT.PUT_LINE(
'myStrAssociativeArray(' || j || ').'
|| 'myNestedTable(' || TO_CHAR(k) || ') = '
|| myStrAssociativeArray(j)(k).TO_STRING()
);
END LOOP;
j := myStrAssociativeArray.NEXT(j);
END LOOP;
END;

BEGIN
FOR emp_rec IN csrEmp LOOP
IF csrEmp%ROWCOUNT = 1 THEN
vDeptName := emp_rec.dname;
END IF;

myEmp := empType (
emp_rec.empno,
emp_rec.ename,
emp_rec.job,
emp_rec.hiredate,
emp_rec.sal,
emp_rec.deptno
);

IF vDeptName <> emp_rec.dname THEN
myStrAssociativeArray(vDeptName) := myNestedTable;
vDeptName := emp_rec.dname;
myNestedTable := NestedTableType();
END IF;

myNestedTable.EXTEND(1);
myNestedTable(myNestedTable.COUNT) := myEmp;
END LOOP;

IF myNestedTable.COUNT > 0 THEN
myStrAssociativeArray(vDeptName) := myNestedTable;
END IF;

printArray();

-- 結合配列を空にする!
myStrAssociativeArray := claerMyStrAssociateArray;

DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE('**** コレクションが空の状態 ****');
DBMS_OUTPUT.PUT_LINE(
'myStrAssociativeArray('
|| myStrAssociativeArray.COUNT
|| ')'
);


END;
/

SCOTT> l
1 select
2 emp.deptno,
3 dept.dname,
4 emp.empno,
5 emp.ename,
6 emp.sal,
7 emp.hiredate
8 from
9 emp join dept
10 on emp.deptno = dept.deptno
11 order by
12 emp.deptno,
13* emp.ename
SCOTT> /

DEPTNO DNAME EMPNO ENAME SAL HIREDATE
---------- -------------- ---------- ---------- ---------- --------
10 ACCOUNTING 7782 CLARK 2450 81-06-09
10 ACCOUNTING 7839 KING 5000 81-11-17
20 RESEARCH 7876 ADAMS 1100 87-05-23
20 RESEARCH 7566 JONES 2975 81-04-02
20 RESEARCH 7788 SCOTT 3000 87-04-19
20 RESEARCH 7369 SMITH 800 80-12-17
30 SALES 7499 ALLEN 1600 81-02-20
30 SALES 7698 BLAKE 2850 81-05-01
30 SALES 7900 JAMES 950 81-12-03
30 SALES 7654 MARTIN 1250 81-09-28
30 SALES 7844 TURNER 1500 81-09-08
30 SALES 7521 WARD 1250 81-02-22

12行が選択されました。

SCOTT>

実行結果は次のようになる。(Oracle SQL Developer 1.1 for MacOSX) 
1.2がリリースされたようなので後でダウンロードしとくか・・> TODO

Oracleplsqldev11

Mlevelcollresults


ということで、今日はここまで。

Have a good Week end!

| | コメント (0) | トラックバック (0)

2007年5月29日 (火)

Mac De Oracle : PL/SQL de Collection #4

さて、PL/SQLのコレクションでのお遊び。その4回目。

今回は、既に要素を持っているコレクションを空にしてみましょう。

第二回目にも似たようなことをやっているので、VarrayとNested Tableについては想像できると思いますが、Associative Arrayにいてはどうすればよいでしょう?

ということで、答えは以下のコードを読めば分かりますよ!

create or replace
PROCEDURE COLLECTIONS AS
TYPE VarrayType IS VARRAY(100) OF empType;
TYPE NestedTableType IS TABLE OF empType;
TYPE StrAssociativeArrayType IS TABLE OF empType INDEX BY VARCHAR2(50);
TYPE NumAssociativeArrayType IS TABLE OF empType INDEX BY BINARY_INTEGER;

myVarray VarrayType := VarrayType();
myNestedTable NestedTableType := NestedTableType();
myStrAssociativeArray StrAssociativeArrayType;
myNumAssociativeArray NumAssociativeArrayType;

claerMyStrAssociateArray StrAssociativeArrayType;
clearMyNumAssociateArray NumAssociativeArrayType;

myEmp empType;

CURSOR csrEmp IS
SELECT
job,
empno,
ename,
hiredate,
sal,
deptno
FROM
emp
ORDER BY
empno;

PROCEDURE printCount
IS
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Varray : '
|| myVarray.COUNT
|| ' 件の要素が存在します。'
);
DBMS_OUTPUT.PUT_LINE(
'Nested Table : '
|| myNestedTable.COUNT
|| ' 件の要素が存在します。'
);
DBMS_OUTPUT.PUT_LINE(
'Associative Array(String) :'
|| myStrAssociativeArray.COUNT
|| ' 件の要素が存在します。'
);
DBMS_OUTPUT.PUT_LINE(
'Associative Array(Number) :'
|| myNumAssociativeArray.COUNT
|| ' 件の要素が存在します。'
);
END;

BEGIN
FOR emp_rec IN csrEmp LOOP
myEmp := empType (
emp_rec.empno,
emp_rec.ename,
emp_rec.job,
emp_rec.hiredate,
emp_rec.sal,
emp_rec.deptno
);
myVarray.EXTEND(1);
myVarray(myVarray.COUNT) := myEmp;
myNestedTable.EXTEND(1);
myNestedTable(myNestedTable.COUNT) := myEmp;
myStrAssociativeArray(TO_CHAR(myEmp.empno) || ':' || myEmp.ename) := myEmp;
myNumAssociativeArray(myEmp.empno) := myEmp;
END LOOP;


DBMS_OUTPUT.PUT_LINE('**** コレクションに要素が存在している状態 ****');
printCount;


myVarray := VarrayType();
myNestedTable := NestedTableType();
myStrAssociativeArray := claerMyStrAssociateArray;
myNumAssociativeArray := clearMyNumAssociateArray;

DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE('**** コレクションが空の状態 ****');
printCount;


END;
/


上記のコードの通り、Assciative Array(結合配列)を空にする方法は、同じ型の”空”結合配列をセットしてやればいいわけです。
今回の例では1次元の結合配列ですが、N次元の結合配列でも考え方は同じです。(VarrayやNested Tableとは異なります。)
ちなみに、第二回目にも書きましたが、VarrayやNexted Tableは、NULLにすることができます。その場合、VarrayやNexted Tableは、atomic nullであるためコンストラクタによる初期化が行われるまで一切の操作は行えないということもお忘れなく。

最後に、上記プロシージャの実行結果。

SCOTT> set serveroutput on size 10000 format wrapped
SCOTT> exec collections;
**** コレクションに要素が存在している状態 ****
Varray : 29 件の要素が存在します。
Nested Table : 29 件の要素が存在します。
Associative Array(String) :29 件の要素が存在します。
Associative Array(Number) :29 件の要素が存在します。

**** コレクションが空の状態 ****
Varray : 0 件の要素が存在します。
Nested Table : 0 件の要素が存在します。
Associative Array(String) :0 件の要素が存在します。
Associative Array(Number) :0 件の要素が存在します。

PL/SQLプロシージャが正常に完了しました。

SCOTT>

Collection4

今日はこのへんで。

| | コメント (0) | トラックバック (0)

2007年5月17日 (木)

Mac De Oracle : Oracleのバージョン確認(FAQ) #9

OCFS2 のバージョン確認方法は?

10万円 de RAC #22の最後にも記載してありますが、ググれば沢山ヒットすると思いますよ。   


Googleで検索する例も載せておきましょう!

how to determine ocfs2 version で検索すれば英語のページは沢山ヒットする。
ocfs2のバージョン確認 と入力して検索すれば、私のBlogも含んだ検索結果が返ってきますよ。

以下のスクリーンショットは、MacOSXのTerminalからCentOSへssh接続したもの
Mac_linux_ssh


[root@discus1 ˜]# cat /proc/fs/ocfs2/version
OCFS2 1.2.3 Thu Aug 10 18:16:03 PDT 2006 (build 6b798aaadf626d3b137c3952809b2f38)
[root@discus1 ˜]#

| | コメント (0) | トラックバック (0)

2007年5月16日 (水)

Mac De Oracle : Oracleのバージョン確認(FAQ) #8

Oracle JDBC Driverのバージョンは確認方法は?

マニュアルにしっかり載ってます。 
今回は、先日公開された、Oracle JDeveloper11g Technology Previewで試してみた。

ちなみに、接続先は、Oracle10g R2 EE 10.2.0.2.0
Jdev11g_jdbc11

よく見えないかもしれないので、ログペインを拡大したスクリーンショットも載せておく。
Jdbcversionresult

Oracle JDeveloper11g Technology Previewでは、Oracle JDBC Driver 11.1.0.0.0-Alpha が使われているんですね!。

Determining the Version of the JDBC Driverを見れば分かるし、マニュアルからコピペすればよいので、書くまでもないのだが。。。。。。。

読んでないのか!?、見つけられないのか?  よく聞かれるのでコードも載せておく。

package jp.macdeoracle.discus;

import oracle.jdbc.pool.OracleDataSource;
import java.sql.DatabaseMetaData;
import java.sql.Connection;
import java.sql.SQLException;

public class JdbcVersion
{
public static void main(String[] args)
{
OracleDataSource ods = null;
Connection conn = null;
try {
ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:scott/tiger@192.168.1.2:1521:catfish");
conn = ods.getConnection();
DatabaseMetaData meta = conn.getMetaData();
System.out.println(meta.getDriverName() + "," + meta.getDriverVersion());
}
catch (SQLException se) {
System.out.println(se.getSQLState());
System.out.println(se.getErrorCode());
}
finally
{
try {
if (ods != null && conn != null && !conn.isClosed()) {
conn.close();
ods.close();
}
}
catch (SQLException se){
se.printStackTrace();
}
}
}
}

| | コメント (0) | トラックバック (0)

2007年5月14日 (月)

Mac De Oracle : Oracleのバージョン確認(FAQ) #7

Oracle Enterprise Manager 10g Database Controlのバージョンは以下のようにしても確認できる。ついでに、URLの確認にもなるから便利。

ちなみに、EM10g R1 と R2では、Port番号が異なっているので要注意。

G5Server:˜ oracle$ emctl status dbconsole
Oracle Enterprise Manager 10g Database Control Release 10.1.0.3.0
Copyright (c) 1996, 2004 Oracle Corporation. All rights reserved.
http://192.168.1.19:5500/em/console/aboutApplication
Oracle Enterprise Manager 10g is not running.
G5Server:˜ oracle$

[oracle@discus1 ˜]$ emctl status dbconsole
TZ set to Japan
Oracle Enterprise Manager 10g Database Control Release 10.2.0.1.0
Copyright (c) 1996, 2005 Oracle Corporation. All rights reserved.
http://192.168.1.100:1158/em/console/aboutApplication
Oracle Enterprise Manager 10g is not running.
[oracle@discus1 ˜]$

| | コメント (0) | トラックバック (0)

2007年4月27日 (金)

Mac De Oracle : Oracleのバージョン確認(FAQ) #6

リスナーのバージョン確認方法は?

注意)この方法でバージョンを確認するには、リスナーが起動している必要があります。

[oracle@discus1 ˜]$ lsnrctl version

LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 26-4月 -2007 22:44:06

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

(ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))に接続中
TNSLSNR for Linux: Version 10.2.0.1.0 - Production
TNS for Linux: Version 10.2.0.1.0 - Production
Unix Domain Socket IPC NT Protocol Adaptor for Linux: Version 10.2.0.1.0 - Production
Oracle Bequeath NT Protocol Adapter for Linux: Version 10.2.0.1.0 - Production
TCP/IP NT Protocol Adapter for Linux: Version 10.2.0.1.0 - Production,,
コマンドは正常に終了しました。
[oracle@discus1 ˜]$

| | コメント (0) | トラックバック (0)

2007年4月26日 (木)

Mac De Oracle : Ask Discus : 問い合わせた結果、ある列(文字列)の右端2文字でソートするには?

Ask Tomのパクリ! なんてことはやりませんが、ウチの奥さんからヘルプメールが来たので。

今、Oracle10g R2 + Seaser2 + Hibernate だっけ? を使ったプロジェクトで奮闘しているウチの奥さんから SQL文に関するヘルプメールが来たので、 Ask Discus という Ask Tomのパクリ風? ヘルプを一つ。 
FAQだと思うのでFAQカテゴリにしておきます。


You Asked...
ウチの奥さんからのヘルプ内容:

問い合わせた結果をソートする必要がある。
そして、ソート条件は、varchar2型として定義されている列で、右端から2文字で昇順にソートする。
この場合、order by句はどのように書けばいいの?  
おしえて Discus! (ダーリン!。。。かも。。。笑い)


という質問。

and I said...

簡単なんだけど。。(知らない人には簡単では無いかも。。。。)

order by句でもスカラ関数が利用できるので、 substr()を利用して可変長文字列の右端2文字を取り出せば OK.

では、お約束のscottユーザに接続し、emp表の ename列の右端2文字で昇順にソートしてみよう!

length()を利用しなくても substr()の第二引数に負の値を指定すれば簡単にできるということを忘れていた!!
こちらの方がスマートです。コメントくださった方に感謝します。

SCOTT> l
1 select
2 emp.*,
3 substr(ename,-2) as right2chars
4 from
5 emp
6 where
7 empno < 8000
8 order by
9* substr(ename,-2)
SCOTT> /

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RIGHT2CHARS
---------- ---------- --------- ---------- -------- ---------- ---------- ---------- ----------
7905 JEAN 7904 AN
7901 SADE 7876 DE
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30 EN
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30 ER
7934 MILLER CLERK 7782 82-01-23 1300 10 ER
7566 JONES MANAGER 7839 81-04-02 2975 20 ES
7900 JAMES CLERK 7698 81-12-03 950 30 ES
7903 ALEX 7901 EX
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30 IN
7698 BLAKE MANAGER 7839 81-05-01 2850 30 KE
7876 ADAMS CLERK 7788 87-05-23 1100 20 MS
7839 KING PRESIDENT 81-11-17 5000 10 NG
7521 WARD SALESMAN 7698 81-02-22 1250 500 30 RD
7902 FORD ANALYST 7566 81-12-03 3000 20 RD
7782 CLARK MANAGER 7839 81-06-09 2450 10 RK
7369 SMITH CLERK 7902 80-12-17 800 20 TH
7788 SCOTT ANALYST 7566 87-04-19 3000 20 TT
7904 DISCUS 7903 US
7907 Wendy 7906 dy
7906 Duke 7905 ke

20行が選択されました。

この方法でもできるんだが、length()関数を使わないので上記の方法がいいですね。

SCOTT> l
1 select
2 emp.*,
3 substr(ename,length(ename)-1,2) as right2chars
4 from
5 emp
6 order by
7* substr(ename,length(ename)-1,2)
SCOTT> /


ちなみに、NLSSORTを利用すれば、言語ソートも可能。 
length()関数を利用しないよう修正。

SCOTT> select 
2 emp.*,
3 substr(ename,-2) as right2chars
4 from
5 emp
6 where
7 empno between 8000 and 8010
8 order by
9 substr(ename,-2)
10 /

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RIGH
---------- ---------- --------- ---------- -------- ---------- ---------- ---------- ----
8002 かきくあい あい
8001 おえういあ いあ
8000 あいうえお えお
8008 カキクアイ アイ
8007 オエウイア イア
8006 アイウエオ エオ
8004 カキクアイ アイ
8005 オエウイア イア
8003 アイウエオ エオ

9行が選択されました。

SCOTT> l
1 select
2 emp.*,
3 substr(ename,-2) as right2chars
4 from
5 emp
6 where
7 empno between 8000 and 8010
8 order by
9 nlssort(
10 substr(ename,-2),
11 'NLS_SORT=JAPANESE_M'
12* )
SCOTT> /

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RIGH
---------- ---------- --------- ---------- -------- ---------- ---------- ---------- ----
8002 かきくあい あい
8008 カキクアイ アイ
8004 カキクアイ アイ
8001 おえういあ いあ
8007 オエウイア イア
8005 オエウイア イア
8000 あいうえお えお
8006 アイウエオ エオ
8003 アイウエオ エオ

9行が選択されました。


NLSSORT()関数や言語ソートの詳細はマニュアルを参照していろいろと試してみてくださいね。。
Oracle Database グローバリゼーション・サポート・ガイド 10g リリース2(10.2) 言語ソート
Oracle Database グローバリゼーション・サポート・ガイド 10g リリース2(10.2) 言語ソートパラメータ
Oracle Database グローバリゼーション・サポート・ガイド 10g リリース2(10.2)言語ソートの使用
Oracle Database グローバリゼーション・サポート・ガイド 10g リリース2(10.2) NLSSORT関数

| | コメント (2) | トラックバック (0)

2007年4月25日 (水)

Mac De Oracle : Oracleのバージョン確認(FAQ) #5

APEXのバージョンを確認するには?

以下は、APEX3.0でのバージョン確認方法だが、APEX2.2の場合には、flows_020200.wwv_flows_release()ファンクションを実行する必要がある。この方法はバージョン毎にスキーマ異なるので少々面倒だ。(APEX上で表示するのならば話は別だが。。)

SYS> select flows_030000.wwv_flows_release from dual;

WWV_FLOWS_RELEASE
--------------------------------------------------------
3.0.0.00.20

SYS>

そこで、スキーマに関係なく確認する方法として、以前にも紹介した、DBA_REGISTRYビューを問い合わせる方法がある。

| | コメント (0) | トラックバック (0)

2007年4月24日 (火)

Mac De Oracle : Oracleのバージョン確認(FAQ) #4

Oracle WebTool kitのバージョンを確認するには?

OWA_UTILパッケージの get_version関数を使う!


ちなみに、SQL*Plusから接続するユーザは、SYSユーザである必要はないが、Web toolkit関連パッケージの実行を制限している場合には権限が付与されているユーザで接続すれはOK。


OWA_UTILパッケージにアクセスできるか簡単に確認するには、

SQL> desc owa_util

としてパッケージに定義されているプロシージャやファンクションの一覧がでてくれば実行可能だ。


SYS> select owa_util.get_version from dual;

GET_VERSION
--------------------------------------------------------------------------------
10.1.2.0.6

SYS>

| | コメント (0) | トラックバック (0)

2007年4月23日 (月)

Mac De Oracle : Oracleのバージョン確認(FAQ) #3

Oracleデータベースにロードされている各コンポーネントのバージョンを知りたいときは、dba_registryビューを問い合わせる。

マニュアル「Oracle® Database Reference 10g Release 2 (10.2)」 
普段参照することはなくても、こんなビューがあるということを思えておくだけでも、いざという時には役に立つんじゃないかなぁ。

SYS> select comp_name,version,status from dba_registry;

COMP_NAME VERSION STATUS
---------------------------------------- ------------------------------ -----------
Oracle Application Express 3.0.0.00.20 VALID
Oracle Ultra Search 10.1.0.3.0 VALID
Oracle Enterprise Manager 10.1.0.3.0 VALID
Oracle XML Database 10.1.0.3.0 VALID
OLAP Catalog 10.1.0.3.0 VALID
Oracle Text 10.1.0.3.0 INVALID
Spatial 10.1.0.3.0 VALID
Oracle interMedia 10.1.0.3.0 VALID
Oracle Expression Filter 10.1.0.3.0 VALID
Oracle Workspace Manager 10.1.0.2.0 VALID
Oracle Data Mining 10.1.0.3.0 VALID
Oracle Database Catalog Views 10.1.0.3.0 VALID
Oracle Database Packages and Types 10.1.0.3.0 INVALID
JServer JAVA Virtual Machine 10.1.0.3.0 VALID
Oracle XDK 10.1.0.3.0 VALID
Oracle Database Java Packages 10.1.0.3.0 VALID
OLAP Analytic Workspace 10.1.0.3.0 VALID
Oracle OLAP API 10.1.0.3.0 VALID

18行が選択されました。

SYS>

注意)この静的ディクショナリービューは、Oracle9i R2以降で利用可能。

| | コメント (0) | トラックバック (0)

Mac De Oracle : Oracleのバージョン確認(FAQ) #2

Oracleのバージョン確認 その2は、SQL*Plusのバージョン確認

特に解説することも無いが、SQL*Plusのバージョンを確認は以下の方法もある。
(たまに、Oracle Universal Installerを起動して確認している方もいるが、以下の方法で確認するほうが簡単。)

discus1:˜ oracle$ sqlplus -version

SQL*Plus: Release 10.2.0.2.0 - Production

discus1:&tilde oracle$

| | コメント (0) | トラックバック (0)

2007年4月21日 (土)

Mac De Oracle : Oracleのバージョン確認(FAQ) #1

検索ワードを見ていると、ORA-20000から ORA-20999までのエラーコードに次いで、バージョン確認というキーワードが目立つ。。。。。

基本はマニュアルを見ることですよ!

該当部分を発見しにくいマニュアルにも原因はあるかもしれないけど。。。(^^;;;;;

では、よく言聞かれるであろう、Oracle のバージョンや、Oracle のエディションの確認方法。

サポートに確認する場合、その他いろいろなフォーラムでオラクルに関する質問する際、バージョンやエティション、それにプラットフォームやそのバージョンを提示するのは当たり前のことなのだが、、、

最近、そのような基本的な事を提示しない方も多いなぁ、と感じる場面も少なくない。
しかも、検索ワードで、"Oracle Version確認" の検索数が目立つ状況だと、Blogのネタとしては面白くないのだが、確認方法を載せたほうがよいだろうと思い、FAQとして載せておく事にした。
(バージョンやエディションを提示するということ以前に、バージョンの確認方法を知らないという可能性もあるので。。。)

以下は、MacOSX Server版 Oracle10g R1 EEの例

v$version動的パフォーマンスビューを問い合わせれば確認することができる。
但し、Oracle9i 以降では、v$系のビューはselect any dictionaryシステム権限が無いと参照できないため、sysユーザか、systemユーザ、又は前述の権限を付与されたユーザで確認する。
SYS> conn / as sysdba
接続されました。
SYS>
SYS> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - Prod
PL/SQL Release 10.1.0.3.0 - Production
CORE 10.1.0.3.0 Production
TNS for MacOS X Server: Version 10.1.0.3.0 - Production
NLSRTL Version 10.1.0.3.0 - Production

SYS>

v$version動的パフォーマンスビューを問い合わせれば、 Oracle のバージョン と エディション以外に、SQL*net や PL/SQLのバージョンも確認することができる。

尚、v$パフォーマンスビューや その他のビューからは有益な情報を問い合わせることが可能なので、暇のある時にでも眺めてみるだけでも見てみるといいだろう。 
「きっと、後々役に立つと思うよ。 あ、そういえば、あんなのがあったなぁ。とか。。。ね。」
Oracle Database リファレンス (10.2)

また、次のような確認方法もある。(但し、SQL*Plusがインストールされているという前提である。)

以下の例は、Oracle9i R2 9.2.0.1.0 のOracle Clientから、Oracle10g R2 10.2.0.2.0 EE へ接続した際のログであるが、接続後のバナーと、 exitコマンド入力後のバナーに、接続先データベースのバージョンとエディションが表示されるので、v$version動的パフォーマンスビューを問い合わせる権限の無いユーザで接続している場合でも、Oracleのversionとeditionを容易に確認することができる。 知っていて損はないだろう。
discus1:˜ oracle$ sqlplus scott@catfish

SQL*Plus: Release 9.2.0.1.0 - Production on 土 4月 21 12:49:12 2007

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

パスワードを入力してください:

Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options
に接続されました。
SQL> exit
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Production
With the Partitioning, OLAP and Data Mining optionsとの接続が切断されました。
discus1:˜ oracle$

| | コメント (0) | トラックバック (0)

2007年4月 9日 (月)

ORA-20001

マニュアルにもしっかり記載されているが、意外に多いなぁと感じた検索ワードの ”ORA-20001”を取り上げておこうと思います。

ORA-20001 を エラーメッセージマニュアルで確認してみると、

ORA-20000: %s
原因:
このメッセージが発生する原因となったストアド・プロシージャraise_application_errorが呼び出されました。
処置:
エラー・メッセージの記述どおりに問題を修正するか、詳細をアプリケーション管理者またはDBAに問い合せてください。

と、少々、不親切な書き方になっています。

上記、エラーメッセージの解説からは、ORA-20001が、ORA-20000と同じ、ユーザ定義エラーとして予約されているエラーコードであるとは読み取れません。
(Oracleさん、もうちょっとだけ、親切なドキュメントに修正してくれるとありがたいのですが・・・・・)


PL/SQLに慣れた方なら、最初に、冒頭でリンクしているこのマニュアルを見る確立は高いでしょうが、そうで無い方は、ORA-20001というエラーコードを見て、最初に参照するマニュアルはエラーメッセージマニュアルであることの方が多いはず!。 

で、「マニュアルに記載されていない!」 ということになり、ハマるわけです。。。。ね。

前置きはこれくらいにして、本題。

Oracle Database PL/SQLユーザーズ・ガイドおよびリファレンス 10g リリース2(10.2)に書かれているように、ORA-20000からORA-20999は、ユーザが自由にメッセージを割り当てる事ができるように予約されているエラーコードだ。

つまり、ORA-20000 というエラーコードには、Oracle側では対応するエラーメッセージが割り当てられていない。
ユーザが自由にエラーメッセージを割当て意味を持たせることができるエラーコードなんですよ。

たとえば、プロシージャAでは、ORA-20000は、「URLが指定されていません。」というエラーメッセージを割り当てたり、ファンクションBでは、ORA-20001には「指定された予約がありません。」というメッセージを割り当てることができるわけです。


尚、ORA-20000からORA-20999までのエラーコードはユーザが自由に設定できるエラーコードであるため、ほとんどの場合、プロジェクト毎に標準化されることが多いと思います。理由は、ORA-20000からORA-20999のエラーコードに対して一意にエラーメッセージを割り当て、1つのエラーコードが複数の意味を持たないようにするためです。
私が関わったプロジェクトでは、台帳で一元管理し、リリース後は該当システム独自のエラーメッセージマニュアルとしても利用させました。

サンプルコードは、Oracle Database PL/SQLユーザーズ・ガイドおよびリファレンス 10g リリース2(10.2)にもあるのでそちらも参照してください。

以下、簡単なサンプル。。。と行きたいところだがここまで。
(後日、このエントリを更新してサンプルを載せるかも。。。マニュアルに記載されているから追記しないかも。。。。気分次第です。)

| | コメント (0) | トラックバック (0)

2006年10月15日 (日)

アクセスログを見ていて #3 - 全角半角入り乱れ

ココログのアクセスログには、サーチエンジンで検索された検索ワード/フレーズが記録されている。
その検索ワード/フレーズを見ていると、英数字及び半角カナの全角半角入り乱れが目につくことも少なくない。

その中から、半角/全角が ”細かく”切り替えられているものをビックアップし、入力の器用度等も含め、10点満点で評価してみた。(笑)


ブラウザや、ご使用のフォントによっては全角/半角の区別しずらい状況があるかもしれないので、半角文字は、”赤”にしてあります。



この検索ワードでは、 PLとSQLが全角英字で、なぜか、"/"が半角。DIRECTORYは半角英字。、なかなか半角/全角英数字の切り替えが器用ですね。8点
一文字単位で切り替えてくれたら、10点だった。(笑)
作成 DIRECTRY PL/SQL



半角英字から全角英数字、そして又、半角英字。3点。
ORACLE10g USER_TAB_COLUMNS



"型"の勢いで、全角英字、途中からなぜか、半角英字。3点。
型 datetime オラクル



途中から全角文字。1点。
oraー12560 



そして、全角カナから、半角カナになり、また全角。 ネット上で半角カナを使うという”勇気”ある行動 (笑) だね。 10点。
oracle ストアド char型パラメータバイト上限



これも、半角英数字->半角カナ、途中から全角カナ。前の検索ワードに比べるとパターンが単純なので、9点。
Oracle10g データベース リスナー 停止

ところで、MacOSX で、"ことえり"や"ATOK for MacOSX"を利用している場合、デフォルトでは、半角カナは入力できない。(入力できるように設定することも可能だが使うこともないので入力できるようにしたことはないが。。)

Img2 Img3

ちなみに、アクセスログを見てみると、意外に半角カナを検索文字列として入力しているものが多いのだが、100% Windowsユーザであった。(Mac De Oracleのアクセスログより)ついでなので調べてみたのだが、Windowsでは、半角カナの入力制限及び、半角カナへの変換を制限する設定は無いようですね、今でも。

最後に、
レガシーなシステムやラインプリンタだと、半角カナが無くちゃ困るなんてところもまだ残っているかもしれませんが、ネット上では困った問題を起こす事はあっても、半角カナが無くて困ることは無いだろうと思う。したがって、MacOSXの半角カナ入力制限がデフォルト設定となっていることに対しては大賛成なのである。Windowsもそうなってほしいものだ。

| | コメント (0) | トラックバック (0)

2006年3月30日 (木)

"日本語" de ストアド

少なくなったとはいえ、今でも、日本語(マルチバイト文字でと言ったほうがいいかもしれない)で表名や列名などを定義したがる方達がいるのですよ。
Oracleでは、""(引用識別子)で囲めば正式にサポートされているわけですから、”利用できるか” といえば、「はい」というのは正しい答えであるわけです。

日本語を用いる理由としては、日本人なら直感的に理解し易い、論理名と同じで理解し易いからだとか。(それ以外の理由を聞いたことがない。。)
本当にそうでしょうか? 日本語で書こうが、英語で書こうが、意味が分かりづらい名称を付けてしまえば同じ事だと思うのですが。。。

マルチバイトで表名や列名を定義した場合の利点と欠点を比べた場合、欠点のほうが多いという事実があるにも関わらず、頑にマルチバイトのオブジェクト名に固執する方には出会ったことはないですが、既存システムで、数百もある表名と列名全てがマルチバイトで定義されているというシステムに不運にも遭遇したことはあります。

その事実を知らされたとき、「そこまで、日本語を使いたいんだったら、スドアドプロシージャ名も日本語で書けや〜〜〜っ!」、と怒鳴りたい気持ちと、暗い穴の中に落ちていく感覚が・・・・・「あ〜〜〜〜〜〜〜っ!」。 orz。
さらに、部屋の反対側で、ソースコードを編集している姿が目に映る。DISPLAYを遠くから眺めると、DISPLAYには以下のような模様が(間違いなくプログラムだと思うが模様に見えた)・・・・・・。そして、その模様はWINDOWをかなりスクロールしても終わらないようだった・・・・・・・模様としては美しいかな。(かなり引きつりならが、苦笑い。)

**********************
*********************
********************
********************
*******************
*******************
******************
*******************
********************
*******************
******************
*******************
*******************
********************
********************
*********************
**********************
**********************
*********************
********************
********************
*******************
*******************
******************
*******************
********************
*******************
******************
*******************
*******************
********************
********************
*********************
**********************

という思い出話とともに、”日本語" de スドアド をやってみましょう。
こんなことやらないとは思いますが、良い子の皆さんは、危険ですので、絶対にやらないでくださいね。念のため。(笑)
> conn / as sysdba
接続されました。

SYS> create user pleco identified by zebra
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;

ユーザーが作成されました。

SYS> grant connect,create procedure to pleco;

権限付与が成功しました。

SYS> conn pleco
パスワードを入力してください:
接続されました。
PLECO>

PLECO> CREATE OR REPLACE FUNCTION "おりゃ"
2 RETURN VARCHAR2 AS
3 BEGIN
4 RETURN 'マルチバイトのプロシージャ名';
5 END;
6 /

ファンクションが作成されました。

PLECO>
PLECO> col "おりゃ" for a40
PLECO> select "おりゃ"() as "おりゃ" from dual;

おりゃ
----------------------------------------
マルチバイトのプロシージャ名

PLECO>
PLECO> CREATE OR REPLACE PROCEDURE "おりゃおりゃ"
2 AS
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('マルチバイトのプロシージャ名');
5 END;
6 /

プロシージャが作成されました。

PLECO> set serveroutput on
PLECO> execute "おりゃおりゃ";
マルチバイトのプロシージャ名

PL/SQLプロシージャが正常に完了しました。

PLECO>

さらに、Oracle SQL Developer 1.0 for MacOSXでもやってみた。そこまでしなくても・・・・。
(Oracle SQL Developer 1.0 for MacOSXで、どこまで出来るのか試したかったというのが本音だったりして。。)

ところで、Oracle SQL Developer 1.0 for MacOSX では、スプラッシュを表示する設定になっていてもスプラッシュがでません。(Windowsや、Linuxでもそうなんだろうか? --> 自分で試せば早いのだが。。)








それにしても、ココログの管理画面が重たい。。バージョンアップの影響とのことだが。。これまたクレーム処理が大変だろうなぁ。大きなトラブルのあとだけに。。。

| | コメント (0) | トラックバック (0)