GAGA LIFE.

インフラエンジニアブログ

スポンサーリンク

SQL*Loaderで、任意の列に固定の文字列を埋め込む方法(CONSTANT句)

目的

SQL*Loaderの動作確認や検証時にデータに固定値を設定する

マニュアル

Oracle® Database ユーティリティ 19c  
CONSTANTパラメータ  
列に定数値を設定するには、CONSTANTを指定して、その後に値を指定します。  

  CONSTANT  value  

CONSTANTデータは、SQL*Loaderでは、文字入力として認識されます。このデータは、必要に応じてデータベース列のデータ型に変換されます。  
値を引用符で囲むこともできます。特に、指定する値に空白や予約語が含まれている場合は、必ず引用符で囲んでください。  
また、ターゲット列に対して必ず有効な値を指定してください。指定した値が無効な場合は、すべてのレコードが拒否されてしまいます。   

注意点

CONSTANT句を使用して定数をロードするため、データファイルにはデータを含めない

事前準備

事前に下記の内容のSQLファイルを準備

SQL> DROP TABLE T1 PURGE;

Table dropped.

SQL> CREATE TABLE T1 (C1 NUMBER, C2 DATE, C3 VARCHAR2(100) , CONSTRAINT PK_T4 PRIMARY KEY (C1))
PARTITION BY RANGE(C2) SUBPARTITION BY HASH (C1) SUBPARTITIONS 4 (
    PARTITION PRT_202104 VALUES LESS THAN(TO_DATE('202105','YYYYMM')),
    PARTITION PRT_202105 VALUES LESS THAN(TO_DATE('202106','YYYYMM')),
    PARTITION PRT_202106 VALUES LESS THAN(TO_DATE('202107','YYYYMM')),
    PARTITION PRT_202107 VALUES LESS THAN(TO_DATE('202108','YYYYMM'))
);  2    3    4    5    6    7  

Table created.

SQL> CREATE INDEX T1IDX ON T1 (C2) LOCAL
(PARTITION I1
   (SUBPARTITION I1_H1,
    SUBPARTITION I1_H2,
    SUBPARTITION I1_H3,
    SUBPARTITION I1_H4),
 PARTITION I2
   (SUBPARTITION I2_H1,
    SUBPARTITION I2_H2,
    SUBPARTITION I2_H3,
    SUBPARTITION I2_H4),
 PARTITION I3
   (SUBPARTITION I3_H1,
    SUBPARTITION I3_H2,
    SUBPARTITION I3_H3,
    SUBPARTITION I3_H4),
 PARTITION I4
   (SUBPARTITION I4_H1,
    SUBPARTITION I4_H2,
    SUBPARTITION I4_H3,
    SUBPARTITION I4_H4));  2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21  

Index created.

SQL> CREATE INDEX T1GIDX ON t1 (C3);

Index created.

SQL> drop sequence s1;

Sequence dropped.

SQL> create sequence s1;

Sequence created.

SQL> declare
  varDate date;
  varSeq NUMBER;
begin
  varDate := to_date('2021-04-01', 'YYYY-MM-DD');
  for j in 1..4 loop
    for i in 1..10000 loop
      select s1.nextval into varSeq from dual;
      insert into T1 values(varSeq, varDate, lpad(to_char(varSeq), 100, '0'));
    end loop;
    commit;
    varDate := add_months(varDate, 1);
  end loop;
end;
/  2    3    4    5    6    7    8    9   10   11   12   13   14   15  

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'SCOTT',TABNAME=>'T1',DEGREE => 10,NO_INVALIDATE=>FALSE);

PL/SQL procedure successfully completed.

SQL> ALTER TABLE T1 TRUNCATE PARTITION PRT_202207;

Session altered.

実行例

SQL> desc T1
 Name    Null?    Type
 ------------------------------
 C1      NOT NULL NUMBER
 C2      NOT NULL DATE
 C3               VARCHAR2(105)
$ cat T1_07.csv
32049,"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032049",
32060,"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032060",
    :
  <中略>
    :
31867,"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031867",
31871,"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031871",

$ cat T1_07.ctl
OPTIONS(SKIP=0,ERRORS=0,DIRECT=true)
UNRECOVERABLE
LOAD DATA
BYTEORDERMARK NOCHECK
INFILE 'T1_07.csv'
INSERT
INTO TABLE T1 PARTITION(PRT_202207)
FIELDS TERMINATED BY ","
TRAILING NULLCOLS
(
C1
,C2 constant '01-JUL-22'
,C3
)

C2(DATE)列に定数を指定する。データファイル(csv)にはC2列のデータを含めない。

$ sqlldr scott/tiger@pdb1 control=T1_07.ctl

SQL*Loader: Release 19.0.0.0.0 - Production on Fri Jul 29 20:33:35 2022
Version 19.12.0.0.0

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

Path used:      Direct

Load completed - logical record count 10000.

Table T1, partition PRT_202207:
  10000 Rows successfully loaded.

Check the log file:
  T1_07.log
for more information about the load.

【Oracle】特定のパーティションのロック

目的

テーブルの統計情報をLOCK_TABLE_STATSを使用してロックすることはよくあるが、 特定のパーティションの統計情報をロックする方法のメモ。

マニュアル

Oracle Database PL/SQLパッケージおよびタイプ・リファレンス 19c
171.7.79 LOCK_PARTITION_STATSプロシージャ
このプロシージャによって、ユーザーはパーティションの統計情報をロックできます。
構文
DBMS_STATS.LOCK_PARTITION_STATS (
    ownname    VARCHAR2,
    tabname    VARCHAR2,
    partname   VARCHAR2);

パラメータ
表171-83 LOCK_PARTITION_STATSプロシージャのパラメータ
パラメータ  説明
ownname     ロックするスキーマの名前。
tabname     表の名前
partname    (サブ・)パーティション名。

事前準備

パーティション表の準備

SQL> DROP TABLE T1 PURGE;

Table dropped.

SQL> CREATE TABLE T1 (C1 NUMBER, C2 DATE, C3 VARCHAR2(100) , CONSTRAINT PK_T4 PRIMARY KEY (C1))
PARTITION BY RANGE(C2) SUBPARTITION BY HASH (C1) SUBPARTITIONS 4 (
    PARTITION PRT_202104 VALUES LESS THAN(TO_DATE('202105','YYYYMM')),
    PARTITION PRT_202105 VALUES LESS THAN(TO_DATE('202106','YYYYMM')),
    PARTITION PRT_202106 VALUES LESS THAN(TO_DATE('202107','YYYYMM')),
    PARTITION PRT_202107 VALUES LESS THAN(TO_DATE('202108','YYYYMM'))
);  2    3    4    5    6    7  

Table created.

SQL> CREATE INDEX T1IDX ON T1 (C2) LOCAL
(PARTITION I1
   (SUBPARTITION I1_H1,
    SUBPARTITION I1_H2,
    SUBPARTITION I1_H3,
    SUBPARTITION I1_H4),
 PARTITION I2
   (SUBPARTITION I2_H1,
    SUBPARTITION I2_H2,
    SUBPARTITION I2_H3,
    SUBPARTITION I2_H4),
 PARTITION I3
   (SUBPARTITION I3_H1,
    SUBPARTITION I3_H2,
    SUBPARTITION I3_H3,
    SUBPARTITION I3_H4),
 PARTITION I4
   (SUBPARTITION I4_H1,
    SUBPARTITION I4_H2,
    SUBPARTITION I4_H3,
    SUBPARTITION I4_H4));  2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21  

Index created.

SQL> CREATE INDEX T1GIDX ON t1 (C3);

Index created.

SQL> drop sequence s1;

Sequence dropped.

SQL> create sequence s1;

Sequence created.

SQL> declare
  varDate date;
  varSeq NUMBER;
begin
  varDate := to_date('2021-04-01', 'YYYY-MM-DD');
  for j in 1..4 loop
    for i in 1..10000 loop
      select s1.nextval into varSeq from dual;
      insert into T1 values(varSeq, varDate, lpad(to_char(varSeq), 100, '0'));
    end loop;
    commit;
    varDate := add_months(varDate, 1);
  end loop;
end;
/  2    3    4    5    6    7    8    9   10   11   12   13   14   15  

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'SCOTT',TABNAME=>'T1',DEGREE => 10,NO_INVALIDATE=>FALSE);

PL/SQL procedure successfully completed.

実行例

特定のパーティションの統計をロック

SQL> SELECT OWNER,OBJECT_TYPE,TABLE_NAME,PARTITION_NAME,SUBPARTITION_NAME,NUM_ROWS,TO_CHAR(LAST_ANALYZED,'YYYY/MM/DD HH24:MI:SS') LAST_ANALYZED,STATTYPE_LOCKED,STALE_STATS
FROM DBA_TAB_STATISTICS WHERE TABLE_NAME = 'T1' ORDER BY PARTITION_NAME,SUBPARTITION_NAME;  2  

OWNER                OBJECT_TYPE  TABLE_NAME           PARTITION_NAME       SUBPARTITION_NAME      NUM_ROWS LAST_ANALYZED       STATTYPE_LOCKED      STALE_STATS
-------------------- ------------ -------------------- -------------------- -------------------- ---------- ------------------- -------------------- --------------------
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3579
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3580
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3581
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3582
SCOTT                PARTITION    T1                   PRT_202104                                     10000 2022/07/15 20:21:19                      NO
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3583
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3584
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3585
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3586
SCOTT                PARTITION    T1                   PRT_202105                                     10000 2022/07/15 20:21:19                      NO
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3587
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3588
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3589
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3590
SCOTT                PARTITION    T1                   PRT_202106                                     10000 2022/07/15 20:21:19                      NO
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3591
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3592
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3593
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3594
SCOTT                PARTITION    T1                   PRT_202107                                     10000 2022/07/15 20:21:19                      NO
SCOTT                TABLE        T1                                                                  40000 2022/07/15 20:21:19                      NO

21 rows selected.

SQL> exec dbms_stats.lock_partition_stats(ownname=> 'SCOTT', tabname=> 'T1', partname=> 'PRT_202104');

PL/SQL procedure successfully completed.

SQL> SELECT OWNER,OBJECT_TYPE,TABLE_NAME,PARTITION_NAME,SUBPARTITION_NAME,NUM_ROWS,TO_CHAR(LAST_ANALYZED,'YYYY/MM/DD HH24:MI:SS') LAST_ANALYZED,STATTYPE_LOCKED,STALE_STATS
FROM DBA_TAB_STATISTICS WHERE TABLE_NAME = 'T1' ORDER BY PARTITION_NAME,SUBPARTITION_NAME;  2  

OWNER                OBJECT_TYPE  TABLE_NAME           PARTITION_NAME       SUBPARTITION_NAME      NUM_ROWS LAST_ANALYZED       STATTYPE_LOCKED      STALE_STATS
-------------------- ------------ -------------------- -------------------- -------------------- ---------- ------------------- -------------------- --------------------
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3579                                        ALL ★
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3580                                        ALL ★
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3581                                        ALL ★
SCOTT                SUBPARTITION T1                   PRT_202104           SYS_SUBP3582                                        ALL ★
SCOTT                PARTITION    T1                   PRT_202104                                     10000 2022/07/15 20:21:19 ALL ★               NO
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3583
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3584
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3585
SCOTT                SUBPARTITION T1                   PRT_202105           SYS_SUBP3586
SCOTT                PARTITION    T1                   PRT_202105                                     10000 2022/07/15 20:21:19                      NO
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3587
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3588
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3589
SCOTT                SUBPARTITION T1                   PRT_202106           SYS_SUBP3590
SCOTT                PARTITION    T1                   PRT_202106                                     10000 2022/07/15 20:21:19                      NO
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3591
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3592
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3593
SCOTT                SUBPARTITION T1                   PRT_202107           SYS_SUBP3594
SCOTT                PARTITION    T1                   PRT_202107                                     10000 2022/07/15 20:21:19                      NO
SCOTT                TABLE        T1                                                                  40000 2022/07/15 20:21:19                      NO

21 rows selected.

指定したパーティションと紐づくサブパーティションがロックされている

既存表からSQL*Loaderのデータファイルを作成する

目的

検証や移行用に既存表に格納されたデータをSQL*Loaderのデータファイルとしてテキストファイルに出力する方法

SQLファイル

事前に下記の内容のSQLファイルを準備

accept table_name prompt ' Enter Table Name : '
set heading off
set verify off
set feed off
set linesize 120
set pause off
set echo off
set termout off
set pagesize 0
col dummy noprint
spool &table_name..sql
select 0 dummy, 'select' from dual
union
select column_id dummy,
'''"'''||'||'||column_name||'||'||'''",''||'
from all_tab_columns
where table_name = upper('&table_name' )
union
select 944 dummy, ''' ''' from dual
union
select 999 dummy, 'from &table_name;' from dual
/
spool off
spool &table_name
start &table_name
spool off
exit

実行例

対象表のオーナーでSQL*Plus接続し、SQLファイル実行

SQL> show user
USER is "SCOTT"

SQL> @data_unload.sql
 Enter Table Name : EMP
Disconnected from Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production
Version 19.12.0.0.0

2ファイル(制御ファイル/データファイル)が作成される

$ ls  
EMP.lst  EMP.sql
$ cat EMP.lst
"7369","SMITH","CLERK","7902","17-DEC-80","800","","20",
"7499","ALLEN","SALESMAN","7698","20-FEB-81","1600","300","30",
"7521","WARD","SALESMAN","7698","22-FEB-81","1250","500","30",
"7566","JONES","MANAGER","7839","02-APR-81","2975","","20"
"7654","MARTIN","SALESMAN","7698","28-SEP-81","1250","1400","30",
"7698","BLAKE","MANAGER","7839","01-MAY-81","2850","","30",
"7782","CLARK","MANAGER","7839","09-JUN-81","2450","","10",
"7788","SCOTT","ANALYST","7566","09-DEC-82","3000","","20",
"7839","KING","PRESIDENT","","17-NOV-81","5000","","10",
"7844","TURNER","SALESMAN","7698","08-SEP-81","1500","0","30",
"7876","ADAMS","CLERK","7788","12-JAN-83","1100","","20",
"7900","JAMES","CLERK","7698","03-DEC-81","950","","30",
"7902","FORD","ANALYST","7566","03-DEC-81","3000","","20",
"7934","MILLER","CLERK","7782","23-JAN-82","1300","","10",
$ cat EMP.sql
selec
'"'||EMPNO||'",'||
'"'||ENAME||'",'||
'"'||JOB||'",'||
'"'||MGR||'",'|
'"'||HIREDATE||'",'|
'"'||SAL||'",'||
'"'||COMM||'",'||
'"'||DEPTNO||'",'||
' '
from EMP;

SQLファイル実行時に入力したテーブル名で2ファイルが作成される

ORA_HASHの使用

構文

構文:ORA_HASH(expr,max_bucket,seed_value)

目的

ORA_HASHファンクションは、指定された式のハッシュ値を計算します。
このファンクションは、データのサブセットの分析や、ランダムな標本の生成などの操作に有効です。

・expr引数には、Oracle Databaseでハッシュ値を計算するデータを指定します。exprに指定できるデータの長さに制限はありません。
このデータは通常、列名です。exprは、LONG型またはLOB型にすることはできません。
また、ネストした表型でない場合は、ユーザー定義オブジェクト型にすることはできません。
ネストした表型のハッシュ値は、コレクション内の要素の順序に依存しません。
その他のデータ型はすべて、exprでサポートされています。
・オプションのmax_bucket引数には、ハッシュ・ファンクションから戻される最大バケット値を指定します。
0(ゼロ)から4294967295の任意の値を指定できます。デフォルト値は4294967295です。
・オプションのseed_value引数を指定すると、同じデータ・セットに対して様々な結果を生成できます。
Oracleは、ハッシュ・ファンクションをexprとseed_valueの組合せに適用します。
0(ゼロ)から4294967295の任意の値を指定できます。デフォルト値は0です。

戻り値はNUMBERです。

使用例

SQL> SELECT ORA_HASH('ABCDE',1000,0) FROM DUAL;

ORA_HASH('ABCDE',1000,0)
------------------------
                     960

SQL> SELECT ORA_HASH('ABCDE',1000,1) FROM DUAL;

ORA_HASH('ABCDE',1000,1)
------------------------
                     207

応用(STSデータ)

ハッシュ分割して削除(UNDO使用の抑止目的)

SQL> SELECT ORA_HASH(SQL_ID,10,1),count(*)
  FROM TABLE(DBMS_SQLTUNE.SELECT_SQLSET('SYS_AUTO_STS'))
group by ORA_HASH(SQL_ID,10,1)
order by ORA_HASH(SQL_ID,10,1)
;
  2    3    4    5  

ORA_HASH(SQL_ID,10,1)   COUNT(*)
--------------------- ----------
                    0       4033
                    1       3983
                    2       3910
                    3       3947
                    4       4032
                    5       3880
                    6       4076
                    7       3888
                    8       4077
                    9       3945
                   10       3925

11 rows selected.

戻り値1を削除

SQL>  EXEC DBMS_SQLTUNE.DELETE_SQLSET(sqlset_name => 'SYS_AUTO_STS', basic_filter  => 'ORA_HASH(SQL_ID,10,1) = 1');

PL/SQL procedure successfully completed.

SQL> SELECT ORA_HASH(SQL_ID,10,1),count(*)
  FROM TABLE(DBMS_SQLTUNE.SELECT_SQLSET('SYS_AUTO_STS'))
group by ORA_HASH(SQL_ID,10,1)
order by ORA_HASH(SQL_ID,10,1)
;
  2    3    4    5  

ORA_HASH(SQL_ID,10,1)   COUNT(*)
--------------------- ----------
                    0       4033
                    2       3910
                    3       3947
                    4       4032
                    5       3880
                    6       4076
                    7       3888
                    8       4077
                    9       3945
                   10       3925

戻り値1のレコードが削除されている

単一パーティションをコンポジットパーティション化する(ALTER TABLE MODIFY)

概要

以前のバージョンでは、大きく以下の方法がありました。
* エクスポート/インポート
* サプクエリでインサート
* パーティション交換
* DBMS_REDEFINITION

12.2以降は、非パーティションからパーティション化する場合や単一パーティションからコンポジットパーティション化する場合に
以下の方法が使用できます。
* ALTER TABLE SQL 文で MODIFY 句を使用する

動作確認

リストパーティションをリスト-ハッシュ(4)のコンポジットパーティションに変更

事前準備:単一パーティション作成

SQL> drop table t1 purge;
SQL> CREATE TABLE t1 (C1 NUMBER, C2 varchar2(17) NOT NULL, C3 VARCHAR2(100) , CONSTRAINT PK_T4 PRIMARY KEY (C1)) 
PARTITION BY LIST(C2) (
   PARTITION PRT_20220217104758777 VALUES ('20220217104758777'),
   PARTITION PRT_20220217122637052 VALUES ('20220217122637052')
);

OWNER                OBJECT_TYPE  TABLE_NAME           PARTITION_NAME            SUBPARTITION_NAME      NUM_ROWS LAST_ANALYZED       STATTYPE_LOCKED      STALE_STATS
-------------------- ------------ -------------------- ------------------------- -------------------- ---------- ------------------- -------------------- --------------------
SCOTT                PARTITION    T1                   PRT_20220217104758777
SCOTT                PARTITION    T1                   PRT_20220217122637052
SCOTT                TABLE        T1

TABLE_NAME           PARTITION_NAME              NUM_ROWS GLOBAL_STATS         LAST_ANALYZED         NUM_ROWS
-------------------- ------------------------- ---------- -------------------- ------------------- ----------
T1                   PRT_20220217104758777                NO
T1                   PRT_20220217122637052                NO

単一パーティションをコンポジットパーティション化して、さらにADD PARTITIONする

SQL> ALTER TABLE T1 MODIFY PARTITION BY LIST (C2) SUBPARTITION BY HASH (C1) SUBPARTITIONS 4 (
    PARTITION PRT_20220217104758777 VALUES ('20220217104758777'),
    PARTITION PRT_20220217122637052 VALUES ('20220217122637052')
   ) ONLINE
;

OWNER                OBJECT_TYPE  TABLE_NAME           PARTITION_NAME            SUBPARTITION_NAME      NUM_ROWS LAST_ANALYZED       STATTYPE_LOCKED      STALE_STATS
-------------------- ------------ -------------------- ------------------------- -------------------- ---------- ------------------- -------------------- --------------------
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP640
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP641
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP642
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP643
SCOTT                PARTITION    T1                   PRT_20220217104758777
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP644
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP645
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP646
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP647
SCOTT                PARTITION    T1                   PRT_20220217122637052
SCOTT                TABLE        T1

TABLE_NAME           PARTITION_NAME              NUM_ROWS GLOBAL_STATS         LAST_ANALYZED         NUM_ROWS
-------------------- ------------------------- ---------- -------------------- ------------------- ----------
T1                   PRT_20220217104758777                NO
T1                   PRT_20220217122637052                NO

SQL> ALTER TABLE T1 ADD PARTITION PRT_20220317122637052 VALUES ('20220317122637052');

Table altered.

OWNER                OBJECT_TYPE  TABLE_NAME           PARTITION_NAME            SUBPARTITION_NAME      NUM_ROWS LAST_ANALYZED       STATTYPE_LOCKED      STALE_STATS
-------------------- ------------ -------------------- ------------------------- -------------------- ---------- ------------------- -------------------- --------------------
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP640
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP641
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP642
SCOTT                SUBPARTITION T1                   PRT_20220217104758777     SYS_SUBP643
SCOTT                PARTITION    T1                   PRT_20220217104758777
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP644
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP645
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP646
SCOTT                SUBPARTITION T1                   PRT_20220217122637052     SYS_SUBP647
SCOTT                PARTITION    T1                   PRT_20220217122637052
SCOTT                SUBPARTITION T1                   PRT_20220317122637052     SYS_SUBP648
SCOTT                SUBPARTITION T1                   PRT_20220317122637052     SYS_SUBP649
SCOTT                SUBPARTITION T1                   PRT_20220317122637052     SYS_SUBP650
SCOTT                SUBPARTITION T1                   PRT_20220317122637052     SYS_SUBP651
SCOTT                PARTITION    T1                   PRT_20220317122637052
SCOTT                TABLE        T1

16 rows selected.

TABLE_NAME           PARTITION_NAME              NUM_ROWS GLOBAL_STATS         LAST_ANALYZED         NUM_ROWS
-------------------- ------------------------- ---------- -------------------- ------------------- ----------
T1                   PRT_20220217104758777                NO
T1                   PRT_20220217122637052                NO
T1                   PRT_20220317122637052                NO

select ~ for update文でもredoが出る話

概要

通常、データ更新(INSERT/UPDATE/DELETE)でREDOログが出力されますが、更新を伴わないselect ~ for update文でもREDO生成がされます。
※for updateを伴わないselect文(参照のみ)ではREDOは生成されません。

また、SELECT FOR UPDATE文の対象となる行数の累計が多いほど大量になります。
これは、SELECT FOR UPDATE文が実行時にSELECT対象行に対して、下記の情報をREDO LOGに書き込むためです。
* 行に対して明示的にロックを獲得する処理
* 上記処理のロールバックのためのUNDO情報をロールバックセグメントに記録する処理

上記の動作は仕様動作となります。
SELECT FOR UPDATEの対象となる行数と回数が多いほどREDOログ生成量が増加することになります。

動作確認

  • SELECT文(for updateなし)
SQL> select m.sid,m.statistic#,s.name,m.value,m.con_id
from v$mystat m, v$statname s
where m.statistic#=s.statistic#
and m.con_id = s.con_id
and s.name = 'redo size';

       SID STATISTIC# NAME                      VALUE     CON_ID
---------- ---------- -------------------- ---------- ----------
      1837        313 redo size                   768          3

SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980/12/17 00:00:00        800                    20
      7499 ALLEN      SALESMAN        7698 1981/02/20 00:00:00       1600        300         30
        :
      <中略>
        :
      7902 FORD       ANALYST         7566 1981/12/03 00:00:00       3000                    20
      7934 MILLER     CLERK           7782 1982/01/23 00:00:00       1300                    10

14 rows selected.

SQL> select m.sid,m.statistic#,s.name,m.value,m.con_id
from v$mystat m, v$statname s
where m.statistic#=s.statistic#
and m.con_id = s.con_id
and s.name = 'redo size';

       SID STATISTIC# NAME                      VALUE     CON_ID
---------- ---------- -------------------- ---------- ----------
      1837        313 redo size                   768          3
  • SELECT ~ FOR UPDATE文
SQL> select m.sid,m.statistic#,s.name,m.value,m.con_id
from v$mystat m, v$statname s
where m.statistic#=s.statistic#
and m.con_id = s.con_id
and s.name = 'redo size';

       SID STATISTIC# NAME                      VALUE     CON_ID
---------- ---------- -------------------- ---------- ----------
      1377        313 redo size                   768          3

SQL> select * from emp for update;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980/12/17 00:00:00        800                    20
      7499 ALLEN      SALESMAN        7698 1981/02/20 00:00:00       1600        300         30
        :
      <中略>
        :
      7902 FORD       ANALYST         7566 1981/12/03 00:00:00       3000                    20
      7934 MILLER     CLERK           7782 1982/01/23 00:00:00       1300                    10

14 rows selected.

SQL> select m.sid,m.statistic#,s.name,m.value,m.con_id
from v$mystat m, v$statname s
where m.statistic#=s.statistic#
and m.con_id = s.con_id
and s.name = 'redo size';

       SID STATISTIC# NAME                      VALUE     CON_ID
---------- ---------- -------------------- ---------- ----------
      1377        313 redo size                  4148          3

スケジューラ自動タスクの再作成

概要

スケジューラ自動タスクの再作成方法についてのメモ

前提

ウィンドウがオープンされるべきではない時間帯にオープンされていたり、ウインドウがクローズされるべき時間に
DBA_SCHEDULER_WINDOWS.ACTIVE=TRUEになっていることが解消できない場合、またはDBA_AUTOTASK_WINDOW_CLIENTS.WINDOW_NEXT_TIMEで
過去の日付が示された場合には、ウィンドウを削除して再作成してみてください。

SQL> SELECT WINDOW_NAME,REPEAT_INTERVAL,DURATION,NEXT_START_DATE,NEXT_START_DATE,LAST_START_DATE,ENABLED,COMMENTS FROM DBA_SCHEDULER_WINDOWS WHERE ENABLED = 'TRUE';

WINDOW_NAME          REPEAT_INTERVAL                                         DURATION             NEXT_START_DATE                          NEXT_START_DATE                          ENABL
-------------------- ------------------------------------------------------- -------------------- ---------------------------------------- ---------------------------------------- -----
MONDAY_WINDOW        freq=daily;byday=MON;byhour=22;byminute=0; bysecond=0   +000 04:00:00        08-NOV-21 10.00.00.000000 PM ASIA/TOKYO  08-NOV-21 10.00.00.000000 PM ASIA/TOKYO  TRUE 
TUESDAY_WINDOW       freq=daily;byday=TUE;byhour=17;byminute=0; bysecond=0   +000 04:00:00        09-NOV-21 05.00.00.000000 PM ASIA/TOKYO  09-NOV-21 05.00.00.000000 PM ASIA/TOKYO  TRUE 
WEDNESDAY_WINDOW     freq=daily;byday=WED;byhour=22;byminute=0; bysecond=0   +000 04:00:00        03-NOV-21 10.00.00.000000 PM ASIA/TOKYO  03-NOV-21 10.00.00.000000 PM ASIA/TOKYO  TRUE 
THURSDAY_WINDOW      freq=daily;byday=THU;byhour=22;byminute=0; bysecond=0   +000 04:00:00        04-NOV-21 10.00.00.000000 PM ASIA/TOKYO  04-NOV-21 10.00.00.000000 PM ASIA/TOKYO  TRUE 
FRIDAY_WINDOW        freq=daily;byday=FRI;byhour=22;byminute=0; bysecond=0   +000 04:00:00        05-NOV-21 10.00.00.000000 PM ASIA/TOKYO  05-NOV-21 10.00.00.000000 PM ASIA/TOKYO  TRUE 
SATURDAY_WINDOW      freq=daily;byday=SAT;byhour=6;byminute=0; bysecond=0    +000 20:00:00        06-NOV-21 06.00.00.000000 AM ASIA/TOKYO  06-NOV-21 06.00.00.000000 AM ASIA/TOKYO  TRUE 
SUNDAY_WINDOW        freq=daily;byday=SUN;byhour=6;byminute=0; bysecond=0    +000 20:00:00        07-NOV-21 06.00.00.000000 AM ASIA/TOKYO  07-NOV-21 06.00.00.000000 AM ASIA/TOKYO  TRUE 

コマンド

-- メンテナンスウィンドウの削除(※エラーが出る場合がある)
@?/rdbms/admin/catnomwn.sql

-- ウィンドウの手動削除
execute dbms_scheduler.drop_window('MONDAY_WINDOW');
execute dbms_scheduler.drop_window('TUESDAY_WINDOW');
execute dbms_scheduler.drop_window('WEDNESDAY_WINDOW');
execute dbms_scheduler.drop_window('THURSDAY_WINDOW');
execute dbms_scheduler.drop_window('FRIDAY_WINDOW');
execute dbms_scheduler.drop_window('SATURDAY_WINDOW');
execute dbms_scheduler.drop_window('SUNDAY_WINDOW');

-- ウィンドウの作成
@?/rdbms/admin/catmwin.sql

再作成

SQL> conn / as sysdba
Connected.
SQL> alter session set container=pdb1;

Session altered.

SQL> sho user con_name
USER is "SYS"

CON_NAME
------------------------------
PDB1
SQL> @?/rdbms/admin/catnomwn.sql
BEGIN dbms_scheduler.drop_job('gather_stats_job'); END;
*
ERROR at line 1:
ORA-27475: unknown job "SYS"."GATHER_STATS_JOB"
ORA-06512: at "SYS.DBMS_ISCHED", line 278
ORA-06512: at "SYS.DBMS_SCHEDULER", line 751
ORA-06512: at line 1

BEGIN dbms_scheduler.drop_window_group('MAINTENANCE_WINDOW_GROUP'); END;
*
ERROR at line 1:
ORA-27479: Cannot drop "SYS"."MAINTENANCE_WINDOW_GROUP" because other objects
depend on it
ORA-06512: at "SYS.DBMS_ISCHED", line 650
ORA-06512: at "SYS.DBMS_SCHEDULER", line 1494
ORA-06512: at line 1

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

BEGIN dbms_scheduler.drop_job_class('AUTO_TASKS_JOB_CLASS'); END;
*
ERROR at line 1:
ORA-27476: "SYS"."AUTO_TASKS_JOB_CLASS" does not exist
ORA-06512: at "SYS.DBMS_ISCHED", line 518
ORA-06512: at "SYS.DBMS_SCHEDULER", line 945
ORA-06512: at line 1

PL/SQL procedure successfully completed.

BEGIN dbms_resource_manager.delete_consumer_group('AUTO_TASK_CONSUMER_GROUP'); END;
*
ERROR at line 1:
ORA-29368: consumer group AUTO_TASK_CONSUMER_GROUP does not exist
ORA-06512: at "SYS.DBMS_RMIN_SYS", line 1633
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86
ORA-06512: at "SYS.DBMS_RMIN_SYS", line 390
ORA-06512: at "SYS.DBMS_RMIN_SYS", line 1616
ORA-06512: at "SYS.DBMS_RESOURCE_MANAGER", line 226
ORA-06512: at line 1

PL/SQL procedure successfully completed.

SQL> execute dbms_scheduler.drop_window('MONDAY_WINDOW');
execute dbms_scheduler.drop_window('TUESDAY_WINDOW');
execute dbms_scheduler.drop_window('WEDNESDAY_WINDOW');
execute dbms_scheduler.drop_window('THURSDAY_WINDOW');
execute dbms_scheduler.drop_window('FRIDAY_WINDOW');
execute dbms_scheduler.drop_window('SATURDAY_WINDOW');
execute dbms_scheduler.drop_window('SUNDAY_WINDOW');

PL/SQL procedure successfully completed.

SQL> 
PL/SQL procedure successfully completed.

SQL> 
PL/SQL procedure successfully completed.

SQL> 
PL/SQL procedure successfully completed.

SQL> 
PL/SQL procedure successfully completed.

SQL> 
PL/SQL procedure successfully completed.

SQL> 
PL/SQL procedure successfully completed.

SQL> @?/rdbms/admin/catmwin.sql

Session altered.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

Session altered.

SQL> SELECT WINDOW_NAME,REPEAT_INTERVAL,DURATION,NEXT_START_DATE,NEXT_START_DATE,LAST_START_DATE,ENABLED FROM DBA_SCHEDULER_WINDOWS WHERE ENABLED = 'TRUE';

WINDOW_NAME          REPEAT_INTERVAL                                         DURATION             NEXT_START_DATE                          NEXT_START_DATE                          LAST_START_DATE                          ENABL
-------------------- ------------------------------------------------------- -------------------- ---------------------------------------- ---------------------------------------- ---------------------------------------- -----
MONDAY_WINDOW        freq=daily;byday=MON;byhour=22;byminute=0; bysecond=0   +000 04:00:00        08-NOV-21 10.00.00.000000 PM ASIA/TOKYO  08-NOV-21 10.00.00.000000 PM ASIA/TOKYO                                           TRUE 
TUESDAY_WINDOW       freq=daily;byday=TUE;byhour=22;byminute=0; bysecond=0   +000 04:00:00        09-NOV-21 10.00.00.000000 PM ASIA/TOKYO  09-NOV-21 10.00.00.000000 PM ASIA/TOKYO                                           TRUE 
WEDNESDAY_WINDOW     freq=daily;byday=WED;byhour=22;byminute=0; bysecond=0   +000 04:00:00        03-NOV-21 10.00.00.000000 PM ASIA/TOKYO  03-NOV-21 10.00.00.000000 PM ASIA/TOKYO                                           TRUE 
THURSDAY_WINDOW      freq=daily;byday=THU;byhour=22;byminute=0; bysecond=0   +000 04:00:00        04-NOV-21 10.00.00.000000 PM ASIA/TOKYO  04-NOV-21 10.00.00.000000 PM ASIA/TOKYO                                           TRUE 
FRIDAY_WINDOW        freq=daily;byday=FRI;byhour=22;byminute=0; bysecond=0   +000 04:00:00        05-NOV-21 10.00.00.000000 PM ASIA/TOKYO  05-NOV-21 10.00.00.000000 PM ASIA/TOKYO                                           TRUE 
SATURDAY_WINDOW      freq=daily;byday=SAT;byhour=6;byminute=0; bysecond=0    +000 20:00:00        06-NOV-21 06.00.00.000000 AM ASIA/TOKYO  06-NOV-21 06.00.00.000000 AM ASIA/TOKYO                                           TRUE 
SUNDAY_WINDOW        freq=daily;byday=SUN;byhour=6;byminute=0; bysecond=0    +000 20:00:00        07-NOV-21 06.00.00.000000 AM ASIA/TOKYO  07-NOV-21 06.00.00.000000 AM ASIA/TOKYO                                           TRUE 

スポンサーリンク