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;