Oracle Database の管理コマンド一覧(DBA)

Oracle DBA コースで覚える構文の一覧です。共通 SQL コースの構文(SELECT・JOIN・GROUP BY・ウィンドウ関数など)はすべて使えます。

CONNECT / AS SYSDBA管理者として接続する(Oracle)Lv1 で覚える

CONNECT / AS SYSDBA
CONN / AS SYSDBA
CONNECT ユーザー/パスワード@FREEPDB1
SHOW USER

SYSDBA で接続すると CDB$ROOT の SYS ユーザーになり、STARTUP・SHUTDOWN・ALTER DATABASE などの管理の操作ができます。一般のユーザー(QUEST)では ORA-01031: insufficient privileges になります。CONNECT quest/quest@FREEPDB1 で元のユーザーに戻ります(@FREEPDB1 を書かないと CDB$ROOT に接続しようとして ORA-01017)。接続に失敗すると、どのユーザーとしても接続していない状態(SP2-0640: Not connected)になります。

CONNECT / AS SYSDBA
SHOW USER
CONNECT quest/quest@FREEPDB1

コンテナ(CDB と PDB)どのデータベースにいるか(Oracle)Lv2 で覚える

SHOW CON_NAME
SHOW PDBS
ALTER SESSION SET CONTAINER = FREEPDB1;
ALTER SESSION SET CONTAINER = CDB$ROOT;
CONNECT ユーザー/パスワード@FREEPDB1

Oracle 23ai はマルチテナント構成です。インスタンスと REDO などを持つ入れ物 CDB$ROOT の中に、表やユーザーを置くプラガブル・データベース(PDB)の FREEPDB1 があります。CONNECT / AS SYSDBA は CDB$ROOT に入るので、表領域やユーザーの作業は ALTER SESSION SET CONTAINER = FREEPDB1 で PDB に移ってから行います。一般ユーザーは @FREEPDB1 を付けて PDB に接続します。CDB$ROOT で作るユーザーは C## で始まる共通ユーザーです。

SHOW CON_NAME
ALTER SESSION SET CONTAINER = FREEPDB1;
SHOW PDBS

V$ ビューインスタンスの状態を見る(Oracle)Lv3 で覚える

SELECT … FROM V$INSTANCE;  V$DATABASE  V$VERSION  V$SESSION  V$PROCESS
V$PARAMETER  V$SPPARAMETER  V$SGA  V$CONTROLFILE  V$NLS_PARAMETERS
V$TABLESPACE  V$DATAFILE  V$TEMPFILE  V$LOG  V$LOGFILE  V$ARCHIVED_LOG  V$RECOVER_FILE
V$PDBS  V$CONTAINERS  V$BACKUP_SET  V$BACKUP_PIECE  V$RMAN_BACKUP_JOB_DETAILS

SYSDBA や SELECT ANY DICTIONARY 権限で見ます(一般ユーザーは ORA-00942)。CDB$ROOT からは全コンテナの行(CON_ID)、PDB からはその PDB の行が見えます。V$ で始まる動的パフォーマンスビューで、インスタンスの起動状態(V$INSTANCE の STATUS)、データベースの状態(V$DATABASE の OPEN_MODE・LOG_MODE)、セッション、パラメータ、REDO ログなどを確かめます。インスタンスとは、メモリ(SGA)とプロセスのこと。データベースは、ディスクの上のファイルのことです。SERIAL# や GROUP# のように # の付く列もそのまま書けます。値は学習用に用意したもので、本物の Oracle とは違います。

SELECT instance_name, status, startup_time FROM v$instance;
SELECT name, open_mode, log_mode FROM v$database;
SELECT sid, serial#, username, status FROM v$session WHERE username IS NOT NULL;

SHUTDOWNデータベースを止める(Oracle)Lv4 で覚える

SHUTDOWN [NORMAL | IMMEDIATE | TRANSACTIONAL | ABORT]

NORMAL は全員の切断を待つ、TRANSACTIONAL は実行中のトランザクションの終わりを待つ、IMMEDIATE はすぐにロールバックして閉じる(ふだんはこれ)、ABORT は何もせずに落とす(次の起動で回復が要る)。止まったあとは、どの SQL も ORA-01034: ORACLE not available になります。SYSDBA で CDB$ROOT に接続して使います。NORMAL は他のセッションが残っていると終わらないので、Ctrl+C で取り消し(ORA-01013)、セッションを止めるか IMMEDIATE を使います。PDB の中で SHUTDOWN するとその PDB だけが閉じます。

SHUTDOWN IMMEDIATE

STARTUPデータベースを起こす(Oracle)Lv5 で覚える

STARTUP
STARTUP NOMOUNT | MOUNT | OPEN
STARTUP FORCE
STARTUP RESTRICT

インスタンスを起動し(SGA を確保:NOMOUNT)、制御ファイルを読み(MOUNT)、データファイルを開きます(OPEN)。STARTUP だけなら OPEN まで進みます。FORCE は動いていても ABORT してから起動し直します。起動のときに SPFILE の値がパラメータに読み込まれます。

STARTUP
STARTUP MOUNT

ALTER DATABASE MOUNT / OPEN段階を進める(Oracle)Lv6 で覚える

ALTER DATABASE MOUNT;
ALTER DATABASE OPEN;
ALTER PLUGGABLE DATABASE FREEPDB1 OPEN | CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE FREEPDB1 SAVE STATE;

STARTUP NOMOUNT のあと、MOUNT で制御ファイルを開き、OPEN でデータファイルを開きます。PDB は ALTER PLUGGABLE DATABASE で開け閉めし、SAVE STATE しておくと CDB の起動と一緒に開きます。ALTER DATABASE CLOSE したあとは、再起動しないと開けません(ORA-16196)。NOMOUNT では V$DATABASE は ORA-01507、MOUNT では表や DBA_ ビューは ORA-01219 になります(V$ ビューは見られる)。順番を飛ばすとエラーです。

STARTUP NOMOUNT
ALTER DATABASE MOUNT;
ALTER DATABASE OPEN;

SHOW PARAMETER初期化パラメータを見る(Oracle)Lv7 で覚える

SHOW PARAMETER 名前の一部
SHOW SPPARAMETER 名前の一部
SHOW SGA
SELECT name, value, isdefault FROM v$parameter WHERE name = '…';

名前を含むパラメータを NAME・TYPE・VALUE の表で出します。V$PARAMETER はいま使っている値(メモリ)、V$SPPARAMETER は SPFILE の値です。ISDEFAULT は、設定を変えると FALSE になります。

SHOW PARAMETER processes
SHOW PARAMETER undo

ALTER SYSTEM SETパラメータを変える(Oracle)Lv8 で覚える

ALTER SYSTEM SET 名前 = 値 [SCOPE = MEMORY | SPFILE | BOTH];
ALTER SYSTEM RESET 名前 SCOPE = SPFILE;

SCOPE=MEMORY は今だけ(再起動で戻る)、SPFILE は次の起動から、BOTH(省略時)は両方です。processes など起動中に変えられないパラメータは ORA-02095 になるので、SCOPE=SPFILE で設定して再起動します。存在しない名前は ORA-02065 です。

ALTER SYSTEM SET open_cursors = 500;
ALTER SYSTEM SET processes = 500 SCOPE = SPFILE;

制限モード管理者だけが接続できる状態(Oracle)Lv10 で覚える

STARTUP RESTRICT
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM DISABLE RESTRICTED SESSION;

メンテナンスの間、RESTRICTED SESSION 権限を持つユーザー(DBA)だけが接続できるようにします。V$INSTANCE の LOGINS が RESTRICTED になり、一般のユーザーは ORA-01035 で接続できません。

ALTER SYSTEM ENABLE RESTRICTED SESSION;
SELECT logins FROM v$instance;

DBA_ ビューデータベース全体の一覧を見る(Oracle)Lv12 で覚える

DBA_TABLESPACES  DBA_DATA_FILES  DBA_TEMP_FILES  DBA_FREE_SPACE  DBA_SEGMENTS  DBA_TABLES
DBA_USERS  ALL_USERS  DBA_SYS_PRIVS  DBA_ROLE_PRIVS  DBA_ROLES  DBA_TAB_PRIVS  DBA_TS_QUOTAS  DBA_PROFILES
CDB_TABLESPACES  CDB_DATA_FILES  CDB_USERS(CON_ID 付き)  DATABASE_PROPERTIES

表領域・データファイル・空き領域・セグメント・ユーザー・権限の一覧です。USER_ ビューは自分のものだけ、DBA_ ビューはいまのコンテナ(CDB$ROOT か FREEPDB1)の全員のもの、CDB_ ビューは全コンテナのものを見ます。SELECT ANY DICTIONARY などの権限が要ります。データベースが OPEN していないと見られません(ORA-01219)。

SELECT tablespace_name, contents, status FROM dba_tablespaces;
SELECT tablespace_name, SUM(bytes) FROM dba_free_space GROUP BY tablespace_name;

CREATE TABLESPACE表領域を作る(Oracle)Lv13 で覚える

CREATE TABLESPACE 名前 DATAFILE 'パス' SIZE 100M [AUTOEXTEND ON NEXT 10M MAXSIZE 1G];
CREATE TABLE 表 (…) TABLESPACE 名前;

表領域は、表や索引を置く入れ物です。中身はデータファイルに入ります。同じ名前は ORA-01543。CREATE TABLE … TABLESPACE で、表を置く表領域を決めます(書かなければユーザーの既定の表領域。QUEST は USERS)。

CREATE TABLESPACE app_data DATAFILE '/opt/oracle/oradata/FREE/app_data01.dbf' SIZE 100M;

ALTER TABLESPACE表領域を変える(Oracle)Lv14 で覚える

ALTER TABLESPACE 名前 ADD DATAFILE 'パス' SIZE 50M;
ALTER TABLESPACE 名前 OFFLINE | ONLINE;
ALTER TABLESPACE 名前 READ ONLY | READ WRITE;
ALTER TABLESPACE 名前 RENAME TO 新しい名前;

データファイルを足して大きくしたり、止めたり(OFFLINE:中の表は ORA-00376 で読めない)、読み取り専用にしたり(READ ONLY:変更は ORA-00372)します。SYSTEM はオフラインにできません(ORA-01541)。

ALTER TABLESPACE users ADD DATAFILE '/opt/oracle/oradata/FREE/users02.dbf' SIZE 50M;
ALTER TABLESPACE app_data READ ONLY;

ALTER DATABASE DATAFILEデータファイルの大きさを変える(Oracle)Lv15 で覚える

ALTER DATABASE DATAFILE 'パス' | 番号 RESIZE 200M;
ALTER DATABASE DATAFILE 'パス' AUTOEXTEND ON NEXT 10M MAXSIZE 1G;
ALTER DATABASE DATAFILE 'パス' AUTOEXTEND OFF;

RESIZE で大きさを変えます(使っている分より小さくはできない:ORA-03297)。AUTOEXTEND ON にすると、足りなくなったときに NEXT ずつ MAXSIZE まで自動で大きくなります。DBA_DATA_FILES の BYTES・AUTOEXTENSIBLE・MAXBYTES で確かめます。

ALTER DATABASE DATAFILE '/opt/oracle/oradata/FREE/users01.dbf' RESIZE 200M;

一時表領域と UNDO 表領域作業用と取り消し用の表領域(Oracle)Lv18 で覚える

CREATE TEMPORARY TABLESPACE 名前 TEMPFILE 'パス' SIZE 100M;
CREATE UNDO TABLESPACE 名前 DATAFILE 'パス' SIZE 100M;
ALTER SYSTEM SET undo_tablespace = 名前;
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE 名前;

一時表領域は並べ替えなどの作業に使い、ファイルは TEMPFILE(DBA_TEMP_FILES で見る)。UNDO 表領域は、変更前のデータ(ROLLBACK や読み取りの一貫性のため)を置きます。使う UNDO 表領域はパラメータ undo_tablespace で切り替えます。

CREATE TEMPORARY TABLESPACE temp2 TEMPFILE '/opt/oracle/oradata/FREE/temp02.dbf' SIZE 50M;

DROP TABLESPACE表領域を消す(Oracle)Lv19 で覚える

DROP TABLESPACE 名前;
DROP TABLESPACE 名前 INCLUDING CONTENTS AND DATAFILES;

中に表があると ORA-01549 で消せないので、INCLUDING CONTENTS で中身ごと消します(AND DATAFILES でファイルも)。SYSTEM・既定の表領域・使用中の UNDO 表領域は消せません。消す前に DBA_SEGMENTS で中身を確かめましょう。

DROP TABLESPACE app_data INCLUDING CONTENTS AND DATAFILES;

CREATE USER / DROP USERユーザーを作る・消す(Oracle)Lv22 で覚える

CREATE USER 名前 IDENTIFIED BY パスワード [DEFAULT TABLESPACE 表領域] [TEMPORARY TABLESPACE temp] [QUOTA 100M ON 表領域] [PROFILE p] [ACCOUNT LOCK];
DROP USER 名前 [CASCADE];

FREEPDB1 で作ったユーザーはローカルユーザーで、ユーザー/パスワード@FREEPDB1 で接続します。CDB$ROOT では C## で始まる共通ユーザーしか作れません(ORA-65096)。作っただけでは接続できません(CREATE SESSION 権限が要る)。同じ名前のユーザー・ロールがあると ORA-01920。接続中のユーザーは消せません(ORA-01940)。オブジェクトを持つユーザーは CASCADE を付けて消します。DBA_USERS で確かめます。

CREATE USER alice IDENTIFIED BY Welcome1 DEFAULT TABLESPACE users QUOTA 50M ON users;
DROP USER alice CASCADE;

ALTER USERユーザーを変える(Oracle)Lv23 で覚える

ALTER USER 名前 ACCOUNT LOCK | ACCOUNT UNLOCK;
ALTER USER 名前 IDENTIFIED BY 新しいパスワード;
ALTER USER 名前 PASSWORD EXPIRE;
ALTER USER 名前 QUOTA 100M | UNLIMITED ON 表領域;
ALTER USER 名前 DEFAULT TABLESPACE 表領域 | PROFILE プロファイル;

ロックすると接続できなくなります(ORA-28000)。PASSWORD EXPIRE は次の接続でパスワードを変えさせます。DBA_USERS の ACCOUNT_STATUS(OPEN・LOCKED・EXPIRED・EXPIRED & LOCKED)で確かめます。QUOTA は表領域ごとに使える量で、DBA_TS_QUOTAS で見ます(UNLIMITED は MAX_BYTES が -1)。

ALTER USER bob ACCOUNT LOCK;
ALTER USER alice QUOTA UNLIMITED ON users;

GRANT権限を与えるLv24 で覚える

GRANT SELECT ON 表 TO ロール;
Oracle: GRANT CREATE SESSION, CREATE TABLE TO ユーザー;
Oracle: GRANT SELECT, INSERT ON 表 TO ユーザー [WITH GRANT OPTION];
Oracle: GRANT ロール TO ユーザー [WITH ADMIN OPTION];

誰がどの表を読めるか・書けるか、何ができるかを決めます。Oracle ではシステム権限(CREATE SESSION など)・ロール・オブジェクト権限(表への SELECT など)を与えます。CREATE SESSION がないユーザーは接続できません(ORA-01045)。Oracle では DBA_SYS_PRIVS・DBA_ROLE_PRIVS・DBA_TAB_PRIVS で確かめます。

GRANT CREATE SESSION, CREATE TABLE TO alice;
GRANT SELECT ON emp TO alice WITH GRANT OPTION;

REVOKE権限を取り消すLv26 で覚える

REVOKE 権限 FROM ユーザー;
REVOKE ロール FROM ユーザー;
REVOKE SELECT ON 表 FROM ユーザー;

GRANT で与えたシステム権限・ロール・オブジェクト権限を取り消します。与えていない権限は ORA-01952(システム権限)・ORA-01951(ロール)・ORA-01927(オブジェクト権限)になります。

REVOKE CREATE TABLE FROM alice;
REVOKE SELECT ON emp FROM alice;

ロール権限をまとめて渡す(Oracle)Lv27 で覚える

CREATE ROLE ロール;
GRANT 権限 TO ロール;
GRANT ロール TO ユーザー;
DROP ROLE ロール;

権限の束に名前を付けて、まとめて渡します。最初からあるロールは CONNECT(CREATE SESSION)・RESOURCE(CREATE TABLE など)・DBA(ほぼすべて)。DBA_ROLES・DBA_ROLE_PRIVS で確かめます。

CREATE ROLE app_reader;
GRANT SELECT ON emp TO app_reader;
GRANT app_reader TO alice;

プロファイルパスワードと資源の決まり(Oracle)Lv29 で覚える

CREATE PROFILE 名前 LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LIFE_TIME 90 PASSWORD_LOCK_TIME 1;
ALTER PROFILE 名前 LIMIT 資源 値;
ALTER USER ユーザー PROFILE 名前;

パスワードを何回間違えたらロックするか(FAILED_LOGIN_ATTEMPTS)、何日で期限切れにするか(PASSWORD_LIFE_TIME)、同時に何セッションまでか(SESSIONS_PER_USER)などを決めます。書かなかった資源は DEFAULT(DEFAULT プロファイルの値)。DBA_PROFILES で確かめます。

CREATE PROFILE secure LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LIFE_TIME 90;
ALTER USER alice PROFILE secure;

KILL SESSIONセッションを止める(Oracle)Lv30 で覚える

SELECT sid, serial#, username, program FROM v$session WHERE username IS NOT NULL;
ALTER SYSTEM KILL SESSION 'sid,serial#' [IMMEDIATE];

V$SESSION で SID と SERIAL# を調べてから止めます。IMMEDIATE を付けるとすぐに消え、付けないと STATUS が KILLED になります。番号の間違いは ORA-00030、自分のセッションは ORA-00027 です。止める前に USERNAME・PROGRAM を確かめましょう。

ALTER SYSTEM KILL SESSION '142,21877' IMMEDIATE;

ログスイッチREDO ログを切り替える(Oracle)Lv33 で覚える

ALTER SYSTEM SWITCH LOGFILE;
ALTER SYSTEM CHECKPOINT;
SELECT group#, sequence#, status FROM v$log;

REDO ログはグループを順番に使い回します。スイッチすると CURRENT が次のグループに移り、SEQUENCE# が増え、前のグループは ACTIVE(まだ回復に要る)になります。チェックポイントで ACTIVE は INACTIVE になります。

ALTER SYSTEM SWITCH LOGFILE;

REDO ロググループの追加・削除REDO ログを増やす(Oracle)Lv34 で覚える

ALTER DATABASE ADD LOGFILE GROUP 4 ('パス') SIZE 200M;
ALTER DATABASE ADD LOGFILE MEMBER 'パス' TO GROUP 1;
ALTER DATABASE DROP LOGFILE GROUP 4;

グループを足すと、最初は STATUS が UNUSED です。メンバー(同じ内容のコピー)を足すと、壊れたときに備えられます(V$LOGFILE で見る)。CURRENT のグループは消せません(ORA-01623)。ACTIVE のグループも消せないので、チェックポイントしてから消します。

ALTER DATABASE ADD LOGFILE GROUP 4 ('/opt/oracle/oradata/FREE/redo04.log') SIZE 200M;

ARCHIVELOG モードREDO ログを保存しておく(Oracle)Lv35 で覚える

ARCHIVE LOG LIST
SHUTDOWN IMMEDIATE → STARTUP MOUNT → ALTER DATABASE ARCHIVELOG; → ALTER DATABASE OPEN;
ALTER SYSTEM ARCHIVE LOG CURRENT;
SELECT sequence#, name FROM v$archived_log;

ARCHIVELOG モードでは、ログスイッチのたびに REDO ログをアーカイブログとして保存します(V$ARCHIVED_LOG)。OPEN のままバックアップを取ったり、障害の直前まで戻したりできます。切り替えは MOUNT の状態でだけでき、OPEN 中は ORA-01126 です。V$DATABASE の LOG_MODE で確かめます。

ARCHIVE LOG LIST
ALTER DATABASE ARCHIVELOG;

RMAN の BACKUPバックアップを取る(Oracle)Lv37 で覚える

rman target /
BACKUP DATABASE;
BACKUP DATABASE PLUS ARCHIVELOG;
BACKUP TABLESPACE 名前;  BACKUP DATAFILE 番号;  BACKUP ARCHIVELOG ALL;
exit

RMAN(Recovery Manager)はバックアップと復旧の道具です。SQL> で rman target / と打つと RMAN> になり、exit で SQL> に戻ります。RMAN のコマンドは ; で終わります。OPEN のままのバックアップは ARCHIVELOG モードが必要です(NOARCHIVELOG では ORA-19602。MOUNT で取ります)。取ったバックアップは V$BACKUP_SET・V$RMAN_BACKUP_JOB_DETAILS で見られます。

rman target /
BACKUP DATABASE PLUS ARCHIVELOG;
exit

RMAN の LIST / REPORTバックアップを確かめる(Oracle)Lv38 で覚える

LIST BACKUP SUMMARY;
LIST BACKUP OF DATABASE;
REPORT NEED BACKUP;
REPORT SCHEMA;
REPORT OBSOLETE;

LIST はバックアップの一覧、REPORT NEED BACKUP は保存方針に足りないファイル、REPORT SCHEMA はデータファイルの一覧、REPORT OBSOLETE は保存方針で要らなくなったバックアップです。

LIST BACKUP SUMMARY;
REPORT NEED BACKUP;

RMAN の RESTORE / RECOVER障害から戻す(Oracle)Lv39 で覚える

STARTUP MOUNT
RESTORE DATAFILE 番号;  RESTORE TABLESPACE 名前;  RESTORE DATABASE;
RECOVER DATAFILE 番号;  RECOVER DATABASE;
ALTER DATABASE OPEN;

データファイルが壊れると OPEN できません(ORA-01157)。MOUNT の状態で、RESTORE でバックアップからファイルを戻し、RECOVER で REDO(アーカイブログ)を当てて最新にしてから OPEN します。RESTORE の前に RECOVER すると RMAN-06094 です。V$RECOVER_FILE で回復が要るファイルを確かめます。FREEPDB1 のファイルなら CDB は開くので、PDB だけを ALTER PLUGGABLE DATABASE … OPEN で開きます。NOARCHIVELOG では、要る REDO がオンラインログに残っていないと回復できません(RMAN-06054)。SQL*Plus の RECOVER は、アーカイブログごとに Specify log を聞きます(AUTO ですべて当てる)。

RESTORE DATAFILE 7;
RECOVER DATAFILE 7;
ALTER DATABASE OPEN;

RMAN の CONFIGURE / DELETE OBSOLETE保存方針を決める(Oracle)Lv40 で覚える

SHOW ALL;
CONFIGURE RETENTION POLICY TO REDUNDANCY 2;
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
DELETE NOPROMPT OBSOLETE;

保存方針(いくつ・何日分のバックアップを残すか)を決めます。REDUNDANCY 2 なら各ファイルの新しいバックアップ 2 つを残し、それより古いものが OBSOLETE(不要)になります。DELETE OBSOLETE で消します(NOPROMPT を付けないと YES / NO を聞かれます)。設定は V$RMAN_CONFIGURATION で見られます。

CONFIGURE RETENTION POLICY TO REDUNDANCY 2;
DELETE NOPROMPT OBSOLETE;

性能の V$ ビューいま何が起きているかを見る(Oracle)Lv42 で覚える

SELECT sid, event, wait_class, state, seconds_in_wait, sql_id, blocking_session FROM v$session WHERE wait_class <> 'Idle';
SELECT event, total_waits, time_waited_micro, wait_class FROM v$system_event ORDER BY time_waited_micro DESC;
SELECT sql_id, executions, elapsed_time, buffer_gets, sql_text FROM v$sql ORDER BY elapsed_time DESC FETCH FIRST 5 ROWS ONLY;
SELECT sid, type, lmode, request, block FROM v$lock WHERE block = 1 OR request > 0;
DBA_BLOCKERS  DBA_WAITERS  V$SESSION_WAIT  V$SQLAREA

V$SESSION の EVENT は、そのセッションがいま待っているもの(STATE が WAITING のとき)。WAIT_CLASS が Idle の待ち(SQL*Net message from client など)は「仕事がなくて待っている」だけなので除いて考えます。V$SYSTEM_EVENT は起動してからの待ちの累計、V$SQL は共有プールにある SQL ごとの実行回数・経過時間(ELAPSED_TIME、マイクロ秒)・論理読み込み(BUFFER_GETS)。BLOCKING_SESSION は行ロックで待たせている相手の SID です。

SELECT sid, event, seconds_in_wait FROM v$session WHERE state = 'WAITING' AND wait_class <> 'Idle';
SELECT sql_id, elapsed_time / executions FROM v$sql ORDER BY 2 DESC;

実行計画SQL の道すじを見る(Oracle)Lv44 で覚える

EXPLAIN PLAN FOR SELECT …;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id'));
EXPLAIN PLAN SET STATEMENT_ID = '名前' FOR …;

EXPLAIN PLAN は SQL を実行せずに、オプティマイザが選ぶ道すじ(実行計画)を PLAN_TABLE に入れます(Explained.)。DBMS_XPLAN.DISPLAY で表にして読みます。下の段(字下げの深いもの)から先に動きます。TABLE ACCESS FULL は表を全部読む、INDEX RANGE SCAN は索引で探す道。Rows は推定の行数、Cost は推定の重さです。DISPLAY_CURSOR(sql_id) は、共有プールにある SQL(V$SQL)の実際の計画を出します。

EXPLAIN PLAN FOR SELECT * FROM app.orders WHERE customer_id = 42;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

DBMS_STATSオプティマイザ統計を集める(Oracle)Lv46 で覚える

EXEC DBMS_STATS.GATHER_TABLE_STATS('持ち主', '表');
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('持ち主');
EXEC DBMS_STATS.GATHER_INDEX_STATS('持ち主', '索引');
SELECT table_name, num_rows, last_analyzed, stale_stats FROM dba_tab_statistics WHERE owner = '持ち主';

オプティマイザは統計(行数・列の値の種類・索引の形)から Rows と Cost を見積もります。データが大きく変わったのに統計が古いままだと、見積もりが外れて遅い道を選びます。DBA_TAB_STATISTICS の STALE_STATS が YES なら古い印(10% を超えて変わった)。集め直すと NUM_ROWS と LAST_ANALYZED が新しくなります。統計の一度も無い表は、実行のたびに動的サンプリング(dynamic sampling)で見積もります。

EXEC DBMS_STATS.GATHER_TABLE_STATS('APP', 'ORDERS');
EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname => 'APP', tabname => 'ORDERS', cascade => TRUE);

AWR と ASH記録から性能を診る(Oracle・Diagnostics Pack)Lv49 で覚える

EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;
SELECT snap_id, begin_interval_time, end_interval_time FROM dba_hist_snapshot ORDER BY snap_id;
SELECT output FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT(dbid, 1, 開始の snap_id, 終わりの snap_id));
SELECT sql_id, event, COUNT(*) FROM v$active_session_history WHERE sample_time > SYSTIMESTAMP - INTERVAL '30' MINUTE GROUP BY sql_id, event;

AWR(Automatic Workload Repository)は、統計の累計を 1 時間ごとにスナップショットとして残します。2 つのスナップショットの差がレポートで、Top 10 Foreground Events(何を待っていたか)と SQL ordered by Elapsed Time(どの SQL が時間を使ったか)を読みます。ASH(Active Session History)は、動いているセッションを 1 秒ごとに記録したもの。どちらも Enterprise Edition の Diagnostics Pack のライセンスが必要です(CONTROL_MANAGEMENT_PACK_ACCESS)。

EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;
SELECT dbid FROM v$database;

フラッシュバック消した表・変えた行を取り戻す(Oracle)Lv52 で覚える

SHOW RECYCLEBIN
SELECT original_name, object_name, droptime FROM dba_recyclebin;
FLASHBACK TABLE 表 TO BEFORE DROP [RENAME TO 新しい名前];
PURGE TABLE 表;  PURGE RECYCLEBIN;
ALTER TABLE 表 ENABLE ROW MOVEMENT;
FLASHBACK TABLE 表 TO TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE;
SELECT * FROM 表 AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE;
SELECT * FROM 表 AS OF SCN 2471300;

DROP TABLE した表は、すぐには消えずにごみ箱(RECYCLEBIN)に BIN$ で始まる名前で入ります。FLASHBACK TABLE … TO BEFORE DROP で戻せますが、DROP TABLE … PURGE や PURGE で消したものは戻せません。同じ名前の表がもうあれば ORA-38312 になるので RENAME TO で別の名前にします(索引は BIN$ の名前のまま戻るので、ALTER INDEX … RENAME TO で直します)。COMMIT 済みの変更は、UNDO が残っている間(UNDO_RETENTION の秒数が目安)なら AS OF で過去の行を読めます。古すぎると ORA-01555。表ごと過去に戻す FLASHBACK TABLE … TO TIMESTAMP には ENABLE ROW MOVEMENT が要ります(ないと ORA-08189)。

FLASHBACK TABLE orders TO BEFORE DROP;
INSERT INTO orders SELECT * FROM orders AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE WHERE order_id = 7;

Data Pumpデータを書き出す・取り込む(Oracle)Lv54 で覚える

CREATE DIRECTORY dp_dir AS '/opt/oracle/dpdump';
GRANT READ, WRITE ON DIRECTORY dp_dir TO ユーザー;
expdp system/パスワード@FREEPDB1 SCHEMAS=app DIRECTORY=dp_dir DUMPFILE=app.dmp LOGFILE=exp_app.log
expdp ユーザー/パスワード@FREEPDB1 TABLES=表 DIRECTORY=dp_dir DUMPFILE=表.dmp
impdp system/パスワード@FREEPDB1 DIRECTORY=dp_dir DUMPFILE=app.dmp REMAP_SCHEMA=app:app_test [TABLES=app.表] [TABLE_EXISTS_ACTION=SKIP|APPEND|TRUNCATE|REPLACE]
!cat /opt/oracle/dpdump/exp_app.log

expdp / impdp は OS のコマンドです(SQL*Plus からは HOST か ! を付けても打てます)。ファイルはディレクトリ・オブジェクト(DBA_DIRECTORIES)が指す場所に書かれ、ログに表ごとの行数が出ます。PDB の中のスキーマは @FREEPDB1 を付けて接続して書き出します。取り込み先に同じ表があると、既定(SKIP)では飛ばされて ORA-39151。APPEND は行を足し、TRUNCATE は空にしてから入れ、REPLACE は作り直します。ほかのスキーマを扱うには DATAPUMP_EXP_FULL_DATABASE / DATAPUMP_IMP_FULL_DATABASE ロール(DBA に含まれる)が要ります。

expdp system/oracle@FREEPDB1 SCHEMAS=app DIRECTORY=dp_dir DUMPFILE=app.dmp LOGFILE=exp_app.log
impdp system/oracle@FREEPDB1 DIRECTORY=dp_dir DUMPFILE=app.dmp REMAP_SCHEMA=app:app_test LOGFILE=imp.log

スケジューラ決まった時刻に仕事をさせる(Oracle)Lv56 で覚える

BEGIN DBMS_SCHEDULER.CREATE_JOB(job_name => 'APP.PURGE_LOGS', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN … END;', start_date => SYSTIMESTAMP, repeat_interval => 'FREQ=DAILY;BYHOUR=2;BYMINUTE=0;BYSECOND=0', enabled => TRUE); END;
EXEC DBMS_SCHEDULER.RUN_JOB('APP.PURGE_LOGS')
EXEC DBMS_SCHEDULER.DISABLE('APP.PURGE_LOGS')  /  ENABLE  /  DROP_JOB
EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('APP.PURGE_LOGS', 'repeat_interval', 'FREQ=…')
SELECT job_name, enabled, state, next_run_date FROM dba_scheduler_jobs;
SELECT job_name, status, error#, additional_info FROM dba_scheduler_job_run_details;

CREATE_JOB でジョブを作ります。enabled を書かないと FALSE(動かない)なので注意。repeat_interval は FREQ(DAILY・HOURLY など)と BYHOUR・BYMINUTE などで書き、BYHOUR だけだと分と秒は start_date のものになります。RUN_JOB はいますぐ動かし、結果は DBA_SCHEDULER_JOB_RUN_DETAILS(STATUS・ERROR#・ADDITIONAL_INFO)に残ります。ほかのユーザーのジョブを作るには CREATE ANY JOB が要ります。

EXEC DBMS_SCHEDULER.RUN_JOB('APP.PURGE_LOGS')

統合監査誰が何をしたかを記録する(Oracle)Lv57 で覚える

CREATE AUDIT POLICY 名前 ACTIONS DELETE ON app.orders, UPDATE ON app.orders;
CREATE AUDIT POLICY 名前 ACTIONS LOGON;
AUDIT POLICY 名前 [BY ユーザー | EXCEPT ユーザー] [WHENEVER [NOT] SUCCESSFUL];
NOAUDIT POLICY 名前;  DROP AUDIT POLICY 名前;
SELECT * FROM audit_unified_enabled_policies;
SELECT event_timestamp, dbusername, userhost, action_name, object_name, return_code FROM unified_audit_trail;

監査ポリシーで「何を記録するか」を決め、AUDIT POLICY で有効にします(作っただけでは記録されません)。記録は UNIFIED_AUDIT_TRAIL に残り、RETURN_CODE が 0 以外は失敗した操作(1017 はパスワードの間違い)です。最初から ORA_SECURECONFIG・ORA_LOGON_FAILURES などのポリシーが有効です。有効なポリシーは消せない(ORA-46361)ので、先に NOAUDIT します。

SELECT dbusername, userhost FROM unified_audit_trail WHERE action_name = 'LOGON' AND return_code <> 0;

Data Guardスタンバイで神殿を二重にする(Oracle)Lv59 で覚える

SELECT db_unique_name, database_role, protection_mode, open_mode, switchover_status FROM v$database;
SELECT dest_id, status, database_mode, recovery_mode, gap_status FROM v$archive_dest_status WHERE dest_id = 2;
SELECT name, value FROM v$dataguard_stats;   -- スタンバイで
ALTER SYSTEM SET log_archive_dest_state_2 = ENABLE;   -- プライマリで
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;   -- スタンバイで
ALTER DATABASE SWITCHOVER TO free_stby VERIFY;
ALTER DATABASE SWITCHOVER TO free_stby;
CONNECT sys/パスワード@free_stby AS SYSDBA

プライマリの REDO をスタンバイへ送り(転送)、スタンバイで当て続け(適用)ます。遅れは スタンバイの V$DATAGUARD_STATS の transport lag・apply lag で見ます。転送が止まる主な理由は LOG_ARCHIVE_DEST_STATE_2 が DEFER のこと、適用が止まる理由は MRP(RECOVER MANAGED STANDBY)が動いていないことです。スイッチオーバーは VERIFY で確かめてから行い、元のプライマリは止まるので STARTUP MOUNT して適用を始め、新しいプライマリは ALTER DATABASE OPEN で開きます。Enterprise Edition の機能で、スタンバイを開いたまま適用する(READ ONLY WITH APPLY)には Active Data Guard のライセンスが別に要ります。

ALTER DATABASE SWITCHOVER TO free_stby VERIFY;