Menu Close

Oracle参数查看(持续更新中)

Oralce Database Reference:https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/index.html

1. 数据库总体运行情况

1.1. 数据库运行时间查询

  • 单实例数据库
COL host_name         FORMAT a10 HEADING "Host"                NEWLINE
COL instance_name     FORMAT a8  HEADING "Instance"            NEWLINE
COL stime             FORMAT a40 HEADING "Database Started At" NEWLINE
COL uptime            FORMAT a80 HEADING "Uptime"              NEWLINE
SET HEADING OFF

SELECT 'Hostname      : ' || host_name
      ,'Instance Name : ' || instance_name
      ,'Started At    : ' || to_char(startup_time,'DD-MON-YYYY HH24:MI:SS') stime
      ,'Uptime        : ' || floor(sysdate - startup_time) || ' days(s) ' ||
       trunc( 24*((sysdate-startup_time) -
       trunc(sysdate-startup_time))) || ' hour(s) ' ||
       mod(trunc(1440*((sysdate-startup_time) -
       trunc(sysdate-startup_time))), 60) ||' minute(s) ' ||
       mod(trunc(86400*((sysdate-startup_time) -
       trunc(sysdate-startup_time))), 60) ||' seconds' uptime
FROM v$instance;
  • RAC数据库
COL host_name         FORMAT a10 HEADING "Host"                NEWLINE
COL instance_name     FORMAT a8  HEADING "Instance"            NEWLINE
COL stime             FORMAT a40 HEADING "Database Started At" NEWLINE
COL uptime            FORMAT a80 HEADING "Uptime"              NEWLINE
SET heading off

SELECT 'Hostname      : ' || host_name
      ,'Instance Name : ' || instance_name
      ,'Started At    : ' || to_char(startup_time,'DD-MON-YYYY HH24:MI:SS') stime
      ,'Uptime        : ' || floor(sysdate - startup_time) || ' days(s) ' ||
       trunc( 24*((sysdate-startup_time) -
       trunc(sysdate-startup_time))) || ' hour(s) ' ||
       mod(trunc(1440*((sysdate-startup_time) -
       trunc(sysdate-startup_time))), 60) ||' minute(s) ' ||
       mod(trunc(86400*((sysdate-startup_time) -
       trunc(sysdate-startup_time))), 60) ||' seconds' uptime
FROM gv$instance;

数据库如果 HANG 住了,最优先排查的就是会话和等待事件!!!

1.2. 当前时刻活动的会话(按用户统计)

SET feed off
SET lines 300 pages 999
column username format a20
column machine  format a40

SELECT a.username,a.machine,count(*)
  FROM gv$session a
 -- WHERE a.status = 'ACTIVE'
 GROUP BY a.username,machine
 ORDER BY 3 desc;
  • 或查询进程
SET feed off
SET lines 300 pages 999
column username format a20
column machine  format a40

SELECT b.username,b.machine,b.program, COUNT(*)
  FROM v$process a
  LEFT JOIN v$session b ON a.addr = b.paddr
 GROUP BY b.username,b.machine,b.program
 ORDER BY 4 DESC;

1.3. 查询会话的等待事件

SET LINES 300 PAGES 999
COLUMN inst_id   HEADING "Inst_ID" FORMAT 999999
COLUMN sid       HEADING "Session_ID" FORMAT 9999999999999
COLUMN serial#   HEADING "Session_Serial#" FORMAT 9999999999
COLUMN sql_id    HEADING "Sql_ID" FORMAT A16
COLUMN machine   HEADING "machine" FORMAT A16
COLUMN username  HEADING "User_Name" FORMAT A16
COLUMN event     HEADING "event" FORMAT A30
COLUMN blocking_session HEADING "Blocking_Session" FORMAT 9999999999999

SELECT sid, serial#, inst_id, sql_id, event, p1,p2,p3, machine, username, blocking_session
  FROM gv$session
 WHERE wait_class# <> 6;

1.4. 当前时刻活动会话正在执行的SQL

SET LINES 300 PAGES 999
COL username FOR A12
COLUMN inst_id   HEADING "Inst_ID" FORMAT 999999
COLUMN sid       HEADING "Session_ID" FORMAT 9999999999999
COLUMN serial#   HEADING "Session_Serial#" FORMAT 9999999999
COLUMN event     HEADING "Event" FORMAT A20
COLUMN wait_class HEADING "wait_class" FORMAT A12
COLUMN action HEADING "action" FORMAT A12
COL sql_text FOR A50

SELECT s.username,
       s.sid,
       s.serial#,
       s.inst_id,
       s.event,
       s.wait_class,
       to_char(s.sql_exec_start,'yyyy-MM-dd hh24:mi:ss') AS sql_exec_start,
       s.seconds_in_wait,
       s.action,
       sq.sql_text
  FROM gv$session s, gv$sqlarea sq
 WHERE s.status = 'ACTIVE'
   AND s.username IS NOT NULL
   AND s.inst_id = sq.inst_id
   AND s.sql_id = sq.sql_id
   AND s.sid <> USERENV('SID');

或 结合未提交的事务进行查询:

WITH transaction_details AS
 (SELECT inst_id,
         ses_addr,
         SYSDATE - start_date AS diff
    FROM gv$transaction)
  SELECT s.username,
         TO_CHAR(TRUNC(t.diff)) || ' days, ' ||
         TO_CHAR(TRUNC(MOD(t.diff * 24,24))) || ' hours, ' ||
         TO_CHAR(TRUNC(MOD(t.diff * 24 * 60,24))) || ' minutes, ' ||
         TO_CHAR(TRUNC(MOD(t.diff * 24 * 60 * 60, 60))) || ' seconds' AS TRANSACTION_DURATION,
       s.program,
       s.terminal,
       s.status,
       s.sid,
       s.serial#
  FROM gv$session s, transaction_details t
 WHERE s.inst_id = t.inst_id
   AND s.saddr = t.ses_addr
 ORDER BY t.diff DESC

1.5. 数据库长时间执行的SQL

  • NON RAC
SET LINES 300 PAGES 999
COL username FOR A12
COLUMN sid       HEADING "Session_ID" FORMAT 9999999999999
COLUMN serial#   HEADING "Session_Serial#" FORMAT 9999999999
COLUMN opname    HEADING "op_name" FORMAT A20
COLUMN progress  HEADING "progress" FORMAT A20
COLUMN sql_text HEADING "sql_text" FORMAT A120

SELECT sl.username,
       sl.sid,
       sl.serial#,
       sl.opname,
       ROUND(sl.sofar * 100 / sl.totalwork, 0) || '%' AS progress,
       sl.time_remaining,
       sq.sql_text
  FROM v$session_longops sl, v$sql sq
 WHERE sl.time_remaining <> 0
   AND sl.sql_address = sq.address
   AND sl.sql_hash_value = sq.hash_value;
  • RAC
SET LINES 300 PAGES 999
COL username FOR A12
COLUMN inst_id   HEADING "Inst_ID" FORMAT 999999
COLUMN sid       HEADING "Session_ID" FORMAT 9999999999999
COLUMN serial#   HEADING "Session_Serial#" FORMAT 9999999999
COLUMN sql_text HEADING "sql_text" FORMAT A120

SELECT a.inst_id, a.sid, a.serial#, a.username, a.sql_id, c.sql_text -- , c.sql_fulltext, b.*
  FROM gv$session a, gv$session_longops b, gv$sql c
 WHERE a.sid = b.sid
   AND a.serial# = b.serial#
   AND a.inst_id = b.inst_id
   AND a.inst_id = c.inst_id
   AND a.sql_id = c.sql_id;

file

动态性能视图 v$session_longopsgv$session_longops
该视图记录了执行时间长于6秒的某个操作(这些操作可能是备份,恢复,收集统计信息,Hash Join,Sort ,Nested loop,Table Scan, Index Scan 等等),这个视图通常用来分析SQL运行缓慢的原因,配合 V$SESSION 视图。
1.必须将初始化参数 timed_statistics设置为true或者开启sql_trace
2.必须用ANALYZE或者DBMS_STATS对对象收集过统计信息

字段名 含义 字段名 含义
SID Session标识 TIMESTAMP 操作的时间戳
SERIAL# Session串号 TIME_REMAINING 预计完成操作的剩余时间(秒)
OPNAME 操作简要说明 ELAPSED_SECONDS 从操作开始总花费时间(秒)
TARGET 操作运行所在的对象 CONTEXT 前后关系
TARGET_DESC 目标对象说明 MESSAGE 统计项的完整描述
SOFAR 至今为止完成的工作量 USERNAME 执行操作的用户ID
TOTALWORK 总工作量 SQL_ADDRESS 关联v$sql
UNITS 工作量单位 SQL_HASH_VALUE 关联v$sql
START_TIME 操作开始时间 SQL_ID 关联v$sql
LAST_UPDATE_TIME 统计项最后更新时间 QCSID 主要是并行查询一起使用
  • 查看执行的进度
SET LINE 300 PAGESIZE 9999
COL USERNAME FORMAT A10
COL SESSION_INFO FORMAT A30
COL TARGET FORMAT A20
COL OPNAME FORMAT A25
COL MESSAGE FORMAT A60
COL SOFAR_TOTALWORK FORMAT A20
COL PROGRESS FORMAT A8

SELECT a.username,
       (SELECT nb.sid || ',' || nb.serial# || ',' || pr.spid || ',' ||nb.osuser|| ',' ||nb.status|| ',' ||nb.event
          FROM gv$process pr, gv$session nb
         WHERE nb.paddr = pr.addr
           AND nb.sid = a.sid
           AND nb.serial# = a.serial#
           AND pr.inst_id = nb.inst_id
           AND a.inst_id = nb.inst_id) session_info,
       a.target,
       a.opname,
       TO_CHAR(a.start_time, 'yyyy-MM-dd hh24:mi:ss') AS start_time,
       ROUND(a.sofar * 100 / a.totalwork, 2) || '%'   AS progress,
       (a.sofar || ':' || a.totalwork)                AS sofar_totalwork,
       a.time_remaining                               AS time_remaining,
       a.elapsed_seconds                              AS elapsed_seconds,
       message                                        AS message
  FROM gv$session_longops a
 WHERE a.time_remaining <> 0
 ORDER BY a.time_remaining desc, a.sql_id, a.sid;

file

1.6. 查看数据库历史的负载

SET LINES 300 PAGES 999

SELECT *
  FROM (SELECT a.instance_number,
               a.snap_id,
               b.begin_interval_time + 0 AS begin_time,
               b.end_interval_time + 0   AS end_time,
               ROUND(VALUE - LAG(VALUE, 1 , '0') OVER(ORDER BY a.instance_number, a.snap_id)) AS "DB TIME"
          FROM (SELECT b.snap_id,
                       instance_number,
                       SUM(VALUE) / 1000000 / 60  AS VALUE
                  FROM dba_hist_sys_time_model b
                 WHERE b.dbid = (SELECT dbid FROM v$database)
                   AND UPPER(b.stat_name) IN UPPER('DB TIME')
                 GROUP BY b.snap_id, instance_number) a, dba_hist_snapshot b
         WHERE a.snap_id = b.snap_id
           AND b.dbid = (SELECT dbid FROM v$database)
           AND b.instance_number = a.instance_number)
 WHERE TO_CHAR(begin_time, 'yyyy-MM-dd') = TO_CHAR(SYSDATE , 'yyyy-MM-dd')
 ORDER BY begin_time;

1.7. 查询执行慢的SQL

-- NON RAC,查询完整的SQL可以根据sql_id查询
SET LINES 300 PAGES 999
COL user_name FOR A12
COL sql_text FOR A100

SELECT *
  FROM (SELECT sa.sql_id                                           AS sql_id,
               sa.executions                                       AS executions,
               round(sa.elapsed_time / 1000000, 2)                 AS sum_elapsed_time,
               round(sa.elapsed_time / 1000000 / sa.executions, 2) AS avg_execute_time,
               sa.command_type                     AS command_type,
               sa.parsing_user_id                  AS user_id,
               u.username                          AS user_name,
               sa.hash_value                       AS hash_value,
               sa.sql_text                         AS sql_text
               -- sql_fulltext
          FROM v$sqlarea sa
          LEFT JOIN all_users u ON sa.parsing_user_id = u.user_id
         WHERE sa.executions > 0
        ORDER BY (sa.elapsed_time / sa.executions) desc)
 WHERE rownum <= 50;

1.8. 查询日志切换频率

包含RAC所有实例

SET LINES 300 PAGES 999
COL H00 FOR 9999
COL H01 FOR 9999
COL H02 FOR 9999
COL H03 FOR 9999
COL H04 FOR 9999
COL H05 FOR 9999
COL H06 FOR 9999
COL H07 FOR 9999
COL H08 FOR 9999
COL H09 FOR 9999
COL H10 FOR 9999
COL H11 FOR 9999
COL H12 FOR 9999
COL H13 FOR 9999
COL H14 FOR 9999
COL H15 FOR 9999
COL H16 FOR 9999
COL H17 FOR 9999
COL H18 FOR 9999
COL H19 FOR 9999
COL H20 FOR 9999
COL H21 FOR 9999
COL H22 FOR 9999
COL H23 FOR 9999

SELECT TO_CHAR(FIRST_TIME, 'MM/DD') DAY,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '00', 1, 0)) H00,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '01', 1, 0)) H01,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '02', 1, 0)) H02,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '03', 1, 0)) H03,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '04', 1, 0)) H04,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '05', 1, 0)) H05,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '06', 1, 0)) H06,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '07', 1, 0)) H07,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '08', 1, 0)) H08,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '09', 1, 0)) H09,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '10', 1, 0)) H10,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '11', 1, 0)) H11,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '12', 1, 0)) H12,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '13', 1, 0)) H13,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '14', 1, 0)) H14,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '15', 1, 0)) H15,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '16', 1, 0)) H16,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '17', 1, 0)) H17,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '18', 1, 0)) H18,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '19', 1, 0)) H19,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '20', 1, 0)) H20,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '21', 1, 0)) H21,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '22', 1, 0)) H22,
       SUM(DECODE(TO_CHAR(FIRST_TIME, 'HH24'), '23', 1, 0)) H23,
       COUNT(*) AS TOTAL
  FROM (SELECT rownum rn, first_time
          FROM gv$log_history
         WHERE first_time > SYSDATE - 18
           AND first_time > ADD_MONTHS(SYSDATE, -1)
         ORDER BY first_time)
 GROUP BY TO_CHAR(first_time, 'MM/DD')
 ORDER BY MIN(RN);

1.9. 查看闪回区的使用率

SET LINES 300 PAGES 999
COL name FOR A40
COL limit_gb FOR 99999999999999999
COL used_gb  FOR 99999999999999999
COL space_reclaimable FOR 99999999999999999
SELECT name,
       space_limit / 1024 / 1024 / 1024 AS limit_gb,
       space_used / 1024 / 1024 / 1024  AS used_gb,
       space_reclaimable / 1024 / 1024 / 1024 AS space_reclaimable,
       number_of_files,
       con_id
  FROM v$recovery_file_dest;

1.10. 容器数据库字符集

SET LINES 300 PAGES 999 FEED OFF
COLUMN value HEADING "Parameter|Value"    FORMAT a30

SELECT value
  FROM nls_database_parameters
 WHERE parameter = 'NLS_CHARACTERSET';

1.11. 查看数据库安装的组件

SET LINES 300 PAGES 999 FEED OFF
COL COMP_ID FOR A10
COL COMP_NAME FOR A60
COL VERSION FOR A20
COL STATUS FOR A20

SELECT comp_id, comp_name, version, status
  FROM dba_registry
 ORDER BY 1;

1.12. 查看数据库版本号

SET LINES 300 PAGES 999 FEED OFF
COL product FORMAT A42
COL version FORMAT A20
COL status  FORMAT A30
SELECT product, version, status
  FROM product_component_version;

或:

SET LINES 120 PAGES 999 HEADING OFF
COL con_id            FORMAT 999   HEADING "ContainerID"    NEWLINE
COL banner            FORMAT a120  HEADING "Banner"         NEWLINE
COL banner_full       FORMAT a120  HEADING "Banner Full"    NEWLINE
COL banner_legacy     FORMAT a20   HEADING "Banner Legacy"  NEWLINE

SELECT 'ContainerID :  '  || con_id,
       'Banner      :  '  || banner,
       'Banner Full :  '  || banner_full,
       'Banner Legacy: '  || banner_legacy
  FROM v$version;

字段 banner 的含义:组件名称和版本号
字段 banner_full 的含义: Oracle Database 18c 中引入的新的 2 行横幅格式。 横幅显示数据库版本和版本号。
字段 banner_legacy 的含义: Oracle Database 18c 之前使用的旧版 1 行横幅。 此列显示与 BANNER 列相同的值。
字段 con_id 的含义: 数据所属容器的 ID。 可能的值包括:0:此值用于包含与整个 CDB 相关的数据的行。 此值也用于非 CDB 中的行。1:此值用于包含仅与根相关的数据的行,n:其中 n 是包含数据的行的适用容器 ID。

Oracle版本号含义说明:

  1. Major Database Release Number
    第一个数字位,它代表的是一个新版本软件,也标志着一些新的功能。如11g,10g。

  2. Database Maintenance Release Number
    第二个数字位,代表一个maintenance release 级别,也可能包含一些新的特性。

  3. Fusion Middleware Release Number
    第三个数字位,反应Oracle 中间件(Oracle Fusion Middleware)的版本号。

  4. Component-Specific Release Number
    第四个数字位,主要是针对组件的发布级别。不同的组件具有不同的号码。 比如Oracle 的patch包。

  5. Platform-Specific Release Number
    第五个数字位,这个数字位标识一个平台的版本。 通常表示patch 号。

1.13. 查看数据库补丁

2. 当前会话

2.1. 查看当前用户的sid和serial

SET LINES 300 PAGES 999
COLUMN inst_id   HEADING "Inst_ID" FORMAT 999999
COLUMN sid       HEADING "Session_ID" FORMAT 9999999999999
COLUMN serial#   HEADING "Session_Serial#" FORMAT 9999999999
COLUMN status    HEADING "Status" FORMAT A20

SELECT inst_id,
       sid,
       serial#,
       status
  FROM gv$session
 WHERE audsid = sys_context('USERENV', 'SESSIONID')
   AND inst_id = sys_context('USERENV', 'INSTANCE');

2.2. 查看当前会话的spid 与 trace file路径

SET LINES 300 PAGES 999
COLUMN inst_id   HEADING "Inst_ID" FORMAT 999999
COLUMN sid       HEADING "Session_ID" FORMAT 9999999999999
COLUMN serial#   HEADING "Session_Serial#" FORMAT 9999999999
COLUMN spid      HEADING "Process_ID" FORMAT A10
COLUMN status    HEADING "Status" FORMAT A20
COLUMN tracefile HEADING "Trace_Fie" FORMAT A120

SELECT p.inst_id,
       s.sid,
       s.serial#,
       p.spid,
       s.status,
       p.tracefile
  FROM gv$process p, gv$session s
 WHERE p.addr = s.paddr
   AND s.audsid = userenv('sessionid')
   AND s.inst_id = userenv('instance');

2.3. 根据session相关信息查询操作系统进程号

SET LINES 300 PAGES 999
COL username FORMAT A12
COL machine  FORMAT A30
COL program  FORMAT A30
SELECT a.inst_id,
       a.sid,
       a.username,
       a.status,
       a.process,
       a.machine,
       a.program,
       b.spid
  FROM gv$session a, gv$process b
 WHERE a.inst_id = b.inst_id
   AND a.paddr = b.addr
   AND a.osuser = '&osuser';

根据 inst_id 与 spid,在操作系统层面使用 netstat 命令查询到与数据库连接的对端IP地址!

2.4. 已知spid,查看当前正在执行或最近一次执行的语句

-- NON RAC
SET LINES 300 PAGES 999
COLUMN sql_id FORMAT A20
COLUMN sql_text FORMAT A120

SELECT /*+ ordered */ sql_text, sql_id
  FROM v$sqltext sql
 WHERE (sql.hash_value, sql.address) IN (SELECT decode(sql_hash_value, 0, prev_hash_value, sql_hash_value),
                                                decode(sql_hash_value, 0, prev_sql_addr, sql_address)
                                           FROM v$session s
                                          WHERE s.paddr = (SELECT addr
                                                             FROM v$process p
                                                            WHERE p.spid = to_number('&spid')))
 ORDER BY piece ASC;

2.5. 查询会话打开的游标数

SET LINES 300 PAGES 999
col MACHINE format a50
col OSUSER format a50

SELECT s.username,
       o.sid,
       osuser,
       machine,
       count(*) AS num_curs
  FROM v$open_cursor o, v$session s
 WHERE o.sid = s.sid
   AND s.sid = '&sid'
   AND s.serial# = '&serial'
 GROUP BY s.username, o.sid, osuser, machine
 ORDER BY num_curs desc;

3. 阻塞与锁

3.1. 查看当前阻塞与被阻塞的会话

SET LINES 300 PAGES 999
COLUMN blocking_session   HEADING "Blocking_Session" FORMAT A60
COLUMN blocked_session   HEADING "Blocked_Session" FORMAT A60
COLUMN script            HEADING "Kill_Session_SQL" FORMAT 40
COLUMN blocked_cnt       HEADING 'Blocked_cnt' FORMAT 9999

SELECT blocking_session,blocked_session,script,blocked_cnt
  FROM (SELECT DISTINCT
               s1.username || '@' || s1.machine || ' ( INST=' || s1.inst_id || ' SID=' || s1.sid || ' ET=' || s1.last_call_et || 'sn. STATUS=' || s1.status || ' EVENT=' || s1.event || ' ACTION= ' || s1.action || ' PROGRAM=' || s1.program || ' MODULE=' || s1.module || ')' blocking_session,
               s2.username || '@' || s2.machine || ' ( INST=' || s2.inst_id || ' SID=' || s2.sid || ' ET=' || s2.last_call_et || 'sn. STATUS=' || s2.status || ' EVENT=' || s2.event || ' ACTION= ' || s2.action || ' PROGRAM=' || s2.program || ' MODULE=' || s2.module || ')' blocked_session,
               decode(s1.type,'USER','alter system kill session ''' || s1.sid || ',' || s1.serial# || ',@' || s1.inst_id || ''' immediate;' ,null)
               script ,
               COUNT(*) OVER(PARTITION BY s1.inst_id,s1.sid) blocked_cnt
          FROM gv$lock l1, gv$session s1, gv$lock l2, gv$session s2
         WHERE s1.sid=l1.sid
           AND s2.sid=l2.sid
           AND s1.inst_id=l1.inst_id
           AND s2.inst_id=l2.inst_id
           AND l1.block > 0
           AND l2.request > 0
           AND l1.id1 = l2.id1 and l1.id2 = l2.id2)
 ORDER BY blocked_cnt DESC;

3.2. 查询锁的源头SID

SELECT a.*,
       row_number() over(partition by blocking_source order by "LEVEL" asc) as rn
  FROM (SELECT *
          FROM (SELECT inst_id,
                       lpad(' ', (level - 1) * 2, ' ') || sid AS sid,
                       serial#,
                       sql_id,
                       paddr,
                       username,
                       event,
                       machine,
                       program,
                      SUBSTR(numtodsinterval(seconds_in_wait, 'second'),
                              12,
                              8) as wait_time,
                       wait_class,
                       state,
                       level,
                       blocking_session,
                       (PRIOR sid) AS blocking_sid,
                       (PRIOR serial#) AS blocking_serial#,
                       (PRIOR sql_id) AS blocking_sql_id,
                       sys_connect_by_path(sid, '->') as blocking_path,
                       connect_by_root(sid) AS blocking_source
                  FROM gv$session
                 start with blocking_session is NULL
                connect by (prior sid) = blocking_session)
         WHERE "LEVEL" > 1
         UNION
        SELECT inst_id,
               to_char(sid) as sid,
               serial#,
               sql_id,
               paddr,
               username,
               event,
               machine,
               program,
               SUBSTR(NUMTODSINTERVAL(seconds_in_wait, 'second'), 12, 8) as wait_time,
               wait_class,
               state,
               1,
               null,
               null,
               null,
               null,
               null,
               sid
          FROM gv$session
         WHERE sid IN (SELECT blocking_source
                         FROM (SELECT wait_class#,
                                      username,
                                      level,
                                      connect_by_root(sid) as blocking_source
                                 FROM gv$session
                                START WITH blocking_session IS NULL
                               CONNECT BY (PRIOR sid) = blocking_session)
                        WHERE "LEVEL" > 1)) a;

--使用v$session来查看RAC数据库和单实例阻塞session信息

SELECT
         LPAD(' ',5*(LEVEL-1))||S."USERNAME" ,
         LPAD(' ',5*(LEVEL-1))||S."INST_ID"||','||S."SID" ,
         S."SERIAL#" ,
         S."SQL_ID",
         S."ROW_WAIT_OBJ#",
         S."WAIT_CLASS",
         S."EVENT",
         S."P1",
         S."P2",
         S."P3",
         S."SECONDS_IN_WAIT",
         s."BLOCKING_INSTANCE"||','||s."BLOCKING_SESSION"
  FROM   GV$SESSION S
 WHERE   S."BLOCKING_SESSION" IS NOT NULL
    OR  (S."INST_ID"||','||S."SID") IN(SELECT DISTINCT BLOCKING_INSTANCE||','||BLOCKING_SESSION FROM GV$SESSION)
START WITH  (s."BLOCKING_INSTANCE"||','||s."BLOCKING_SESSION") = ','
CONNECT BY PRIOR (S."INST_ID"||','||S."SID") = (s."BLOCKING_INSTANCE"||','||s."BLOCKING_SESSION");

或:

 SELECT r.root_sid,
        s.serial#,
        r.blocked_num,
        TRUNC( r.avg_wait_seconds) AS avg_wait_seconds,
        s.username,s.status,
        s.event,s.MACHINE,
        s.PROGRAM,
        s.sql_id,
        s.prev_sql_id 
   FROM (SELECT root_sid, 
                AVG(seconds_in_wait) AS avg_wait_seconds,
                COUNT(*) - 1 AS blocked_num
          FROM (SELECT CONNECT_BY_ROOT sid AS root_sid,
                       seconds_in_wait
                  FROM v$session
                 START WITH blocking_session IS NULL
               CONNECT BY PRIOR SID = blocking_session)
                 GROUP BY root_sid HAVING COUNT(*) > 1
         ) r, v$session s
   WHERE r.root_sid = s.sid;

3.3. 查询数据库中被锁的对象

  • 容器数据库
SET LINES 300 PAGES 999
COL pdb_name FORMAT A20
COL oracle_username FORMAT A15
COL os_user_name FORMAT A20
COL object_name FORMAT A30
COL machine  FORMAT A20
COL terminal FORMAT A20
COL program FORMAT A15
SELECT lo.inst_id,
       cp.pdb_name,
       s.sid,
       s.serial#,
       lo.oracle_username,
       lo.os_user_name,
       ao.object_name,
       lo.locked_mode,
       s.machine,
       s.terminal,
       s.program
  FROM gv$locked_object lo, cdb_objects ao, gv$session s, cdb_pdbs cp
 WHERE ao.object_id = lo.object_id
   AND lo.session_id = s.sid
   AND lo.inst_id = s.inst_id
   AND lo.con_id = cp.pdb_id;
  • 非容器数据库
SET LINES 300 PAGES 999
COL oracle_username FORMAT A15
COL os_user_name FORMAT A20
COL object_name FORMAT A30
COL machine  FORMAT A20
COL terminal FORMAT A20
COL program FORMAT A15
SELECT lo.inst_id,
       s.sid,
       s.serial#,
       lo.oracle_username,
       lo.os_user_name,
       ao.object_name,
       lo.locked_mode,
       s.machine,
       s.terminal,
       s.program
  FROM gv$locked_object lo, dba_objects ao, gv$session s
 WHERE ao.object_id = lo.object_id
   AND lo.session_id = s.sid
   AND lo.inst_id = s.inst_id;

4. 表空间与数据库文件

4.1. 查看数据库表空间

  • 容器数据库
SET LINES 300 PAGES 999
COL pdb_name FORMAT A30
COL tablespace_name FORMAT A20
SELECT b.con_id,
       a.pdb_id,
       a.pdb_name,
       b.tablespace_name,
       b.contents,
       b.status,
       b.bigfile
  FROM dba_pdbs a
  FULL OUTER JOIN cdb_tablespaces b ON a.pdb_id = b.con_id
 ORDER BY b.con_id, b.tablespace_name;
  • 非容器数据库
SET LINES 300 PAGES 999
COL tablespace_name FORMAT A20
SELECT b.tablespace_name,
       b.contents,
       b.status,
       b.bigfile
  FROM dba_tablespaces b
 ORDER BY b.tablespace_name;

4.2. 查看数据库undo表空间所对应的数据文件

  • 容器数据库
SET LINES 300 PAGES 999
COL pdb_name FORMAT A20
COL file_name FORMAT A90
COL tablespace_name FORMAT A20
SELECT a.con_id,
       c.pdb_name,
       b.tablespace_name,
       a.retention,
       b.file_id,
       b.file_name,
       b.autoextensible,
       a.bigfile,
       round(b.bytes / 1024 / 1024,2) AS undo_size_mb
  FROM cdb_tablespaces a, cdb_data_files b, cdb_pdbs c
 WHERE a.con_id = b.con_id
   AND a.con_id = c.pdb_id
   AND a.tablespace_name = b.tablespace_name
   AND a.contents = 'UNDO'
 ORDER BY a.con_id, b.tablespace_name, b.file_id;
  • 非容器数据库
SET LINES 300 PAGES 999
COL file_name FORMAT A90
COL tablespace_name FORMAT A20
SELECT b.tablespace_name,
       a.retention,
       b.file_id,
       b.file_name,
       b.autoextensible,
       a.bigfile,
       round(b.bytes / 1024 / 1024,2) AS undo_size_mb
  FROM dba_tablespaces a, dba_data_files b
 WHERE a.tablespace_name = b.tablespace_name
   AND a.contents = 'UNDO'
 ORDER BY b.tablespace_name, b.file_id;

4.3. 查看数据库永久表空间所对应的数据文件

  • 容器数据库
    注意:容器数据库(即PDB)应处于READ WRITE状态,同时查询结果并不包含 PDB$SEED 以及 cdb$root 所创建的数据文件。
SET LINES 300 PAGES 999
COL pdb_name FORMAT A20
COL file_name FORMAT A90
COL tablespace_name FORMAT A20
SELECT a.con_id,
       c.pdb_name,
       b.tablespace_name,
       a.retention,
       b.file_id,
       b.file_name,
       b.autoextensible,
       a.bigfile,
       round(b.bytes / 1024 / 1024,2) AS permanent_size_mb
  FROM cdb_tablespaces a, cdb_data_files b, cdb_pdbs c
 WHERE a.con_id = b.con_id
   AND a.con_id = c.pdb_id
   AND a.tablespace_name = b.tablespace_name
   AND a.contents = 'PERMANENT'
 ORDER BY a.con_id, b.tablespace_name, b.file_id;
  • 非容器数据库
SET LINES 300 PAGES 999
COL file_name FORMAT A90
COL tablespace_name FORMAT A20
SELECT b.tablespace_name,
       a.retention,
       b.file_id,
       b.file_name,
       b.autoextensible,
       a.bigfile,
       round(b.bytes / 1024 / 1024,2) AS permanent_size_mb
  FROM dba_tablespaces a, dba_data_files b
 WHERE a.tablespace_name = b.tablespace_name
   AND a.contents = 'PERMANENT'
 ORDER BY b.tablespace_name, b.file_id;

4.4. 查看数据库临时表空间所对应的数据文件

  • 容器数据库
SET LINES 300 PAGES 999
COL pdb_name FORMAT A20
COL file_name FORMAT A90
COL tablespace_name FORMAT A20
SELECT a.con_id,
       c.pdb_name,
       b.tablespace_name,
       a.retention,
       b.file_id,
       b.file_name,
       b.autoextensible,
       a.bigfile,
       round(b.bytes / 1024 / 1024,2) AS temp_size_mb
  FROM cdb_tablespaces a, cdb_temp_files b, cdb_pdbs c
 WHERE a.con_id = b.con_id
   AND a.con_id = c.pdb_id
   AND a.tablespace_name = b.tablespace_name
   AND a.contents = 'TEMPORARY'
 ORDER BY a.con_id, b.tablespace_name, b.file_id;
  • 非容器数据库
SET LINES 300 PAGES 999
COL file_name FORMAT A90
COL tablespace_name FORMAT A20
SELECT b.tablespace_name,
       a.retention,
       b.file_id,
       b.file_name,
       b.autoextensible,
       a.bigfile,
       round(b.bytes / 1024 / 1024,2) AS temp_size_mb
  FROM dba_tablespaces a, dba_temp_files b
 WHERE a.tablespace_name = b.tablespace_name
   AND a.contents = 'TEMPORARY'
 ORDER BY b.tablespace_name, b.file_id;

4.5. 查看数据库联机重做日志文件所对应的数据文件

SET LINES 300 PAGES 999
COLUMN member FORMAT A50
COLUMN first_change# FORMAT 99999999999999999999
COLUMN next_change# FORMAT 99999999999999999999

SELECT l.thread#,
       lf.group#,
       lf.member,
       TRUNC(l.bytes/1024/1024) AS size_mb,
       l.status,
       l.archived,
       lf.type,
       lf.is_recovery_dest_file AS rdf,
       l.sequence#,
       l.first_change#,
       l.next_change#
FROM   v$logfile lf
       JOIN v$log l ON l.group# = lf.group#
ORDER BY l.thread#,lf.group#, lf.member;

4.6. 查看数据库归档日志文件所对应的数据文件

SET LINES 300 PAGES 999
COL NAME FORMAT A80
SELECT con_id,
       inst_id,
       name,
       dest_id,
       thread#,
       sequence#,
       standby_dest,
       applied,
       deleted,
       status,
       registrar,
       completion_time,
       block_size
  FROM gv$archived_log
 WHERE completion_time >= SYSDATE - 7;

4.7. 查询表空间使用大小与剩余容量

  • 容器数据库
set feed off  lines 300 pages 999
column "TablespaceName" heading "表空间名称" format a20
column "FileCount" heading "文件个数" format 999999
column "UsedFileSize" heading "已使用的|文件大小(MB)" format 999,999,999.99
column "MaxFileSize"  heading "最大|文件大小(MB)" format 999,999,999
column "UsedDiskSize" heading "已使用的|磁盘空间大小(MB)" format 999,999,999.99
column "UnusedDiskSize" heading "未使用的|磁盘空间大小(MB)" format 999,999,999.99
column "TotalAvailableDiskSize" heading "可使用的|全部磁盘空间大小(MB)" format 999,999,999.99

SELECT ts.tablespace_name AS TablespaceName,
       df.FileCount AS FileCount,
       TRUNC(df.UsedFileSize, 2)    AS UsedFileSize,
       df.MaxFileSize               AS MaxFileSize,
       TRUNC(df.UsedFileSize - fr.FreeDiskSize, 2)  AS UsedDiskSize,
       TRUNC(fr.FreeDiskSize, 2)   AS UnusedDiskSize,
       df.MaxFileSize - TRUNC(df.UsedFileSize - fr.FreeDiskSize, 2)  AS  TotalAvailableDiskSize
  FROM (SELECT tablespace_name, SUM(bytes) / (1024 * 1024) AS FreeDiskSize
          FROM cdb_free_space
         GROUP BY tablespace_name) fr,
       (SELECT tablespace_name,
               TRUNC(SUM(bytes) / (1024 * 1024),2) AS UsedFileSize,
               COUNT(*)  AS FileCount,
               TRUNC(SUM(maxbytes) / (1024 * 1024),2) AS MaxFileSize
          FROM cdb_data_files
         GROUP BY tablespace_name) df,
       (SELECT tablespace_name FROM cdb_tablespaces) ts
 WHERE fr.tablespace_name = df.tablespace_name(+)
   AND fr.tablespace_name = ts.tablespace_name(+)
 ORDER BY 7;
  • 非容器数据库
set feed off  lines 300 pages 999
column "TablespaceName" heading "表空间名称" format a20
column "FileCount" heading "文件个数" format 999999
column "UsedFileSize" heading "已使用的|文件大小(MB)" format 999,999,999.99
column "MaxFileSize"  heading "最大|文件大小(MB)" format 999,999,999
column "UsedDiskSize" heading "已使用的|磁盘空间大小(MB)" format 999,999,999.99
column "UnusedDiskSize" heading "未使用的|磁盘空间大小(MB)" format 999,999,999.99
column "TotalAvailableDiskSize" heading "可使用的|全部磁盘空间大小(MB)" format 999,999,999.99

SELECT ts.tablespace_name AS TablespaceName,
       df.FileCount AS FileCount,
       TRUNC(df.UsedFileSize, 2)    AS UsedFileSize,
       df.MaxFileSize               AS MaxFileSize,
       TRUNC(df.UsedFileSize - fr.FreeDiskSize, 2)  AS UsedDiskSize,
       TRUNC(fr.FreeDiskSize, 2)   AS UnusedDiskSize,
       df.MaxFileSize - TRUNC(df.UsedFileSize - fr.FreeDiskSize, 2)  AS  TotalAvailableDiskSize
  FROM (SELECT tablespace_name, SUM(bytes) / (1024 * 1024) AS FreeDiskSize
          FROM dba_free_space
         GROUP BY tablespace_name) fr,
       (SELECT tablespace_name,
               TRUNC(SUM(bytes) / (1024 * 1024),2) AS UsedFileSize,
               COUNT(*)  AS FileCount,
               TRUNC(SUM(maxbytes) / (1024 * 1024),2) AS MaxFileSize
          FROM dba_data_files
         GROUP BY tablespace_name) df,
       (SELECT tablespace_name FROM dba_tablespaces) ts
 WHERE fr.tablespace_name = df.tablespace_name(+)
   AND fr.tablespace_name = ts.tablespace_name(+)
 ORDER BY 7;

以下更准确:

SELECT d.tablespace_name AS TablespaceName,
       a.FileCount AS FileCount,
       d.status AS TablespaceStatus,
       to_char(NVL(a.bytes / 1024 / 1024, 0),'99G999G990D900') AS UsedFileSize,
       to_char(NVL(a.max_bytes / 1024 / 1024, 0),'99G999G990D900') AS MaxFileSize,
       to_char(NVL(a.bytes - NVL(f.bytes,0), 0) / 1024 / 1024, '99G999G990D900') AS UsedDiskSizeMb,
       to_char(NVL(a.max_bytes - NVL(a.bytes - NVL(f.bytes,0), 0), 0) / 1024 / 1024, '99G999G990D900') AS TotalAvailableDiskSizeMb,
       to_char(NVL((a.bytes - NVL(f.bytes,0)) / a.max_bytes * 100, 0), '990D00') AS UsedDiskPercent
  FROM sys.dba_tablespaces d,
       (SELECT tablespace_name,
               COUNT(file_id) AS filecount,
               SUM(bytes) bytes,
               SUM(CASE WHEN autoextensible = 'NO' THEN bytes 
                        WHEN autoextensible = 'YES' THEN maxbytes END) AS max_bytes
          FROM dba_data_files
         GROUP BY tablespace_name
         UNION ALL
        SELECT tablespace_name,
               COUNT(file_id) AS filecount,
               SUM(bytes) bytes,
               SUM(CASE WHEN autoextensible = 'NO' THEN bytes
                        WHEN autoextensible = 'YES' THEN maxbytes END) AS max_bytes
          FROM dba_temp_files
         GROUP BY tablespace_name ) a,
       (SELECT tablespace_name, SUM(bytes) bytes
          FROM dba_free_space
         GROUP BY tablespace_name) f
 WHERE d.tablespace_name = f.tablespace_name(+)
   AND d.tablespace_name = a.tablespace_name(+)
 ORDER BY 7;

4.8. 查询正在使用回滚段(UNDO)的会话(单实例)

SELECT s.sid,
       s.serial#,
       s.sql_id,
       v.usn,
       r.segment_name,
       r.status,
       v.rssize/1024/1024 mb
  FROM dba_rollback_segs r, v$rollstat v, v$transaction t, v$session s
 WHERE r.segment_id = v.usn
   AND v.usn = t.xidusn
   AND t.addr = s.taddr
 ORDER BY r.segment_name;

5. 数据库CPU与内存

5.1. 查看数据库内存分配模式

ASMM(Automatic Shared Memory Management,自动共享内存管理 )是Oracle 10g引入的概念。即让设置一个SGA的目标值以及SGA的最大值,数据库来动态调整其中的各个组件,如Database buffer cache、Shared pool等等。
AMM:automatic memory management 自动内存管理 (11.1才有的特性) 即让数据库完全管理SGA、PGA的大小,而对于管理员只需要设置一个总的大小(memory_target),数据库会动态的调整SGA、PGA的大小以及其中包含的各个组件大小,如Database buffer cache、Shared pool等等。
ORACLE 11g AMM 的引入,组合出来有 5 种内存管理形式.

内存管理模式 设置规则
自动内存管理(AMM) memory_target = 非0,是自动内存管理,如果初始化参数 LOCK_SGA=TRUE,则 AMM 是不可用的.
自动共享内存管理(ASMM) memory_target = 0 and sga_target为非0的情形下是自动内存管理.
手工共享内存管理 memory_target = 0 and sga_target = 0 指定 share_pool_size 、db_cache_size 等 sga 参数.
自动 PGA 管理 memory_target = 0 and workarea_size_policy=auto and PGA_AGGREGATE_TARGET=值.
手动 PGA 管理 memory_target = 0 and workarea_size_policy=manal 然后指定 SORT_AREA_SIZE 等 PGA 参数,一般不使用手动管理PGA.

show parameter target;
show parameter memory_target;
show parameter sga_target;
show parameter pga_aggregate_target;

  • 如果Memory_target 设置为非0 值
1、sga_target 和 pga_aggregate_target 已经设置大小
Memory_Target = SGA_TARGET + PGA_AGGREGATE_TARGET,其大小不能超过memory_max_size。

2、sga_target 设置大小, pga_aggregate_target 没有设置大小
pga_aggregate_target的初始化值 = memory_target - sga_target

3、sga_target 没有设置大小, pga_aggregate_target 设置大小
sga_target的初始化值 = memory_target - pga_aggregate_target

4、sga_target 和 pga_aggregate_target 都没有设置大小
两个值没有最小值和默认值,Oracle 将根据数据库运行状况进行分配大小,但在数据库启动是会有一个固定比例来分配:
sga_target = memory_target * 60%
pga_aggregate_target = memory_target * 40%
  • 如果Memory_target 设置为0
    11g 中默认为0 则初始状态下取消了 Memory_target 的作用,完全和10g 在内存管理上一致,完全向下兼容。
1、SGA_TARGET设置值
自动调节SGA 中的shared pool,buffer cache,redo log buffer,java pool,larger pool等内存空间的大小。PGA 则依赖pga_aggregate_target 的大小。

2、SGA_target 和PGA_AGGREGATE_TARGET 都没有设置
SGA 中的各组件大小都要明确设定,不能自动调整各组件大小。PGA不能自动增长和收缩

3、MEMORY_MAX_TARGET 设置而 MEMORY_TARGET = 0  这种情况先和10g 一样。

5.2. 查看数据库内存使用率

SET LINES 300 PAGES 999
COL NAME FORMAT A10
SELECT name,
       ROUND(total,2)                  AS total_size_mb,
       ROUND(total-free,2)             AS used_size_mb,
       ROUND(free,2)                   AS free_size_mb,
       ROUND((total-free)/total*100,2) AS pctused
  FROM (SELECT 'SGA' AS name,
               (SELECT sum(value/1024/1024) FROM v$sga)  AS total,
               (SELECT sum(bytes/1024/1024) FROM v$sgastat WHERE name = 'free memory') AS free
          FROM dual)
 UNION
SELECT name,
       ROUND(total,2)          AS total_size_mb,
       ROUND(used,2)           AS used_size_mb,
       ROUND(total-used,2)     AS free_size_mb,
       ROUND(used/total*100,2) AS pctused
 FROM (SELECT 'PGA' name,
              (SELECT value/1024/1024 total FROM v$pgastat WHERE name = 'aggregate PGA target parameter') AS total,
              (SELECT value/1024/1024 used FROM v$pgastat WHERE name = 'total PGA allocated') AS used
        FROM dual);

5.3. 19c 数据库启用 IN-Memory特性

启用IMO非常简单,12.1.0.2及之后版本下,设置INMEMORY_SIZE 为非0值便可启用IM column store特性。
INMEMORY_SIZE 是个实例级参数,默认为0,设置一个非0值时,最小值为100M。从 12.2 开始,可以动态增加 In-Memory 区域的大小,为此,只需 通过 ALTER SYSTEM 命令增加 INMEMORY_SIZE 参数值即可。它也不会受到自动内存管理 (AMM) 的影响或控制。

我们还可以在 CDB 和 PDB 级别设置 inmemory_size 参数。如果您在 PDB 级别设置此参数,则无需重新启动实例或 PDB。所有 PDB 值的总和小于或等于 CDB 值。

  • 查询是否开启了inmemory
show parameter inmemory;
alter system set inmemory_size=10g scope=spfile sid='*';
  • 在grid用户下重启所有数据库实例
su - grid
srvctl status database -d racdb
srvctl stop   database -d racdb
srvctl start  database -d racdb
  • 表空间、表、(子)分区和实例化视图中启用 INMEMORY 属性。
    如果在表空间级别启用此属性,则默认情况下将为 IMCOLUMN 存储启用表空间中的所有表和实例化视图。

    alter table test inmemory;
  • 监控 inmemory 中的对象

SET LINES 300 PAGES 999
COL pdb_name     FORMAT A10
COL owner        FORMAT A12
COL segment_name FORMAT A60
SELECT a.con_id,
       b.pdb_name,
       a.owner,
       a.segment_name,
       ROUND(SUM(a.bytes)/1024/1024,2) "DATA MB",
       ROUND(SUM(a.inmemory_size)/1024/1024,2) "IN-MEM MB",
       ROUND(SUM(a.bytes - a.bytes_not_populated) * 100 / SUM(a.bytes),2) "% IN_MEM",
       ROUND(SUM(a.bytes - a.bytes_not_populated) / SUM(a.inmemory_size),2) "COMP RATIO"
  FROM v$im_segments a, cdb_pdbs b
 WHERE a.con_id = b.pdb_id
GROUP BY a.con_id, b.pdb_name, a.owner, a.segment_name
ORDER BY a.con_id, SUM(a.bytes) desc;

6. 其他

6.1. 在RAC环境下查看SCANIP

oracle11gR2 RAC开始引入scan概念,SCAN监听器可以监听到集群中运行的所有数据库,它是实现SCAN负载均衡的原理所在。 一个RAC 支持1~3个SCAN 配置,可以配置域名也可以配置IP地址,如果使用IP地址,有几个IP 配置就集群就会启动几个SCAN listener。 一般通过dns服务器或gns服务器解析scan,也可以使用/etc/hosts文件解析scan,只不过oracle官方不建议这样做。

因为域名可配置为轮询访问IP,三个IP轮流使用。假如我们配置了3个ip供SCAN 使用,同时配置了DNS 解析,监听配置中HOST的值是域名。 当其中一个IP故障不能使用时,dns 会自动解析下一个IP 地址。而且只有一个scan listener.

如果我们通过 /etc/hosts ,配置3个IP地址,并为每个IP配置一个别名,集群启动后就会有三个 scan 监听,当其实一个IP出现问题,无法使用时,对应的监听将失去存在的意义 。那么怎么解决这个问题呢: 使用客户端TAF配置,来实现类似于DNS轮询功能。

切换到 grid 用户下,在SHEll命令中执行。

  • 1个scanip情形
# 查看scan的配置信息
~] srvctl config scan

SCAN name: rac-scan1, Network: 1
Subnet IPv4: 192.168.37.0/255.255.255.0/bondeth0, static
Subnet IPv6:
SCAN 1 IPv4 VIP: 192.168.37.7
SCAN VIP is enabled.

# 查看scan的状态以及scan ip所处节点
~] srvctl status scan

SCAN VIP scan1 is enabled
SCAN VIP scan1 is running on node racdb01   <-- 说明scan在节点1上

# 查看scan listener
~] srvctl config scan_listener

SCAN Listeners for network 1:
Registration invited nodes:
Registration invited subnets:
Endpoints: TCP:1521
SCAN Listener LISTENER_SCAN1 exists
SCAN Listener is enabled.
  • 3个 scanip 情形
# 查看scan的配置信息
~] srvctl config scan

Subnet IPv4: 192.168.21.128/255.255.255.128/bond0, static
Subnet IPv6:
SCAN 1 IPv4 VIP: 192.168.21.135
SCAN VIP is enabled.
SCAN VIP is individually enabled on nodes:
SCAN VIP is individually disabled on nodes:
SCAN 2 IPv4 VIP: 192.168.21.134
SCAN VIP is enabled.
SCAN VIP is individually enabled on nodes:
SCAN VIP is individually disabled on nodes:
SCAN 3 IPv4 VIP: 192.168.21.136
SCAN VIP is enabled.
SCAN VIP is individually enabled on nodes:
SCAN VIP is individually disabled on nodes:

# 查看scan的状态以及scan ip所处节点
~] srvctl status scan

SCAN VIP scan1 is enabled
SCAN VIP scan1 is running on node dbcenter1
SCAN VIP scan2 is enabled
SCAN VIP scan2 is running on node dbcenter2
SCAN VIP scan3 is enabled
SCAN VIP scan3 is running on node dbcenter2

# 查看scan listener
~] srvctl config scan_listener

SCAN Listener LISTENER_SCAN1 exists. Port: TCP:1521,30011
Registration invited nodes:
Registration invited subnets:
SCAN Listener is enabled.
SCAN Listener is individually enabled on nodes:
SCAN Listener is individually disabled on nodes:
SCAN Listener LISTENER_SCAN2 exists. Port: TCP:1521,30011
Registration invited nodes:
Registration invited subnets:
SCAN Listener is enabled.
SCAN Listener is individually enabled on nodes:
SCAN Listener is individually disabled on nodes:
SCAN Listener LISTENER_SCAN3 exists. Port: TCP:1521,30011
Registration invited nodes:
Registration invited subnets:
SCAN Listener is enabled.
SCAN Listener is individually enabled on nodes:
SCAN Listener is individually disabled on nodes:

6.3. 查询容器数据库中所有状态为OPEN的用户

SET LINES 300 PAGES 999
COL pdb_name FORMAT A20
COL default_tablespace FORMAT A20
COL temporary_tablespace FORMAT A20
COL username FORMAT A20
SELECT a.con_id,
       b.pdb_name,
       a.username,
       a.account_status,
       a.default_tablespace,
       a.temporary_tablespace,
       to_char(a.last_login,'yyyy-MM-dd hh24:mi:ss') AS last_login
  FROM cdb_users a, cdb_pdbs b
 WHERE a.con_id = b.pdb_id
   AND a.account_status = 'OPEN'
 ORDER BY b.pdb_name,a.username;

7. RMAN备份相关

7.1. 查询RMAN备份时分配信道对应的操作系统进程号

SET LINES 300 PAGES 999
COLUMN EVENT FORMAT a60
COLUMN SECONDS_IN_WAIT FORMAT 999
COLUMN STATE FORMAT a20
COLUMN CLIENT_INFO FORMAT a30

SELECT p.spid,
       sw.event,
       sw.seconds_in_wait,
       sw.state,
       s.client_info
  FROM v$session_wait sw, v$session s, v$process p
 WHERE s.client_info LIKE '%rman%'
   AND s.sid = sw.sid
   AND s.paddr = p.addr;

7.2. 查询 RMAN 备份进度

SET LINES 300 PAGES 999
COL opname     FOR a35
COL start_time FOR a19

SELECT inst_id,
       sid,
       serial#,opname,
       to_char(start_time,'yyyy-mm-dd hh24:mi:ss') AS start_time,
       sofar,
       totalwork,
       round(sofar/totalwork*100,2) AS "%complete",
       ceil(elapsed_seconds/60)     AS elapsed_mi
  FROM gv$session_longops
 WHERE opname LIKE 'RMAN%'
   AND totalwork <> 0
 ORDER BY start_time ASC;

7.3. 查看每天RMAN备份大小

SET LINES 300 PAGES 999
SELECT TO_CHAR(start_time, 'yyyy-mm-dd')                 AS start_time,
       TO_CHAR(start_time, 'day')                        AS week_day,
       ROUND(SUM(output_bytes) / 1024 / 1024 / 1024, 2)  AS size_gb
  FROM v$backup_set_details
 GROUP BY TO_CHAR(start_time, 'yyyy-mm-dd'),TO_CHAR(start_time, 'day')
 ORDER BY start_time DESC;

7.4. 查看数据库是否开启了块改变跟踪

SET LINES 300 PAGES 999
COL FILENAME FOR A60
SELECT * FROM v$block_change_tracking;
  • RAC环境中开启块改变跟踪
ALTER DATABASE ENABLE BLOCK CHANGE TRACKING USING FILE '+ARCHDG/etdb/block_change_tracking.log';
  • 单实例环境
alter database enable block change tracking using file '/dbData/OracleBack/rman_change_track.f' reuse;
  • 关闭块改变跟踪
ALTER DATABASE DISABLE BLOCK CHANGE TRACKING;
  • 查看 block change tracking 文件的位置及大小
SET LINES 300 PAGES 999
COLUMN filename FORMAT a60;

SELECT * FROM v$block_change_tracking;

file

8. 元数据相关

8.1. 查询某个用户下表的属性

8.2. 查询某个用户下字段的属性

8.3. 获取某个用户下主键、唯一性约束和检查约束的创建语句

SELECT dbms_metadata.GET_DEPENDENT_DDL('CONSTRAINT',table_name,owner)
  FROM dba_constraints a
 WHERE a.owner = UPPER('&请输入用户名')
   AND a.constraint_type NOT IN ('R','?','O')
 GROUP BY a.owner,a.table_name;

8.4. 查看表与索引的创建语句

SET heading off
SET echo off
SET pages 999
SET long 90000

spool get_TABLE_ddl.sql
SELECT dbms_metadata.get_ddl('TABLE','TABLE_NAME'[,'SCHEMA_NAME']) FROM dual;
SELECT dbms_metadata.get_ddl('INDEX','INDEX_NAME'[,'SCHEMA_NAME']) FROM dual;
spool off;

file

8.5. 查看索引占用的存储大小

SET LINES 300 PAGES 999
COL tablespace_name FORMAT a12
COL owner FORMAT a12
COL segment_name FORMAT a30
COL partition_count FORMAT 99999999
COL segment_size FORMAT 999999999999.99

SELECT tablespace_name              AS tablespace_name,
       owner                        AS owner,
       segment_name                 AS segment_name,
       NVL(COUNT(partition_name),0) AS partition_count,
       sum(bytes)/1024/1024         AS segment_size 
  FROM dba_segments
 WHERE tablespace_name = UPPER('&TablespaceName')
 GROUP BY Tablespace_name,owner,segment_name
 ORDER BY 2,3;

file

8.6. 获取某个用户下外键约束的创建语句

SELECT dbms_metadata.GET_DEPENDENT_DDL('REF_CONSTRAINT',table_name,owner)
  FROM dba_constraints a
 WHERE a.owner = UPPER('&请输入用户名')
   AND a.constraint_type = 'R'
 GROUP BY a.owner, a.table_name;

8.7. 启用/禁用某个用户下外键约束的语句

-- 启用外键约束
SELECT 'ALTER TABLE ' || table_name || ' ENABLE CONSTRAINT '|| constraint_name || ';'
  FROM dba_constraints
 WHERE owner = UPPER('&请输入用户名')
   AND constraint_type = 'R';
-- 禁用外键约束
SELECT 'ALTER TABLE ' || table_name || ' DISABLE CONSTRAINT ' || constraint_name ||';'
  FROM dba_constraints
 WHERE owner = UPPER('&请输入用户名')
   AND constraint_type = 'R';

8.8. 通过链接数据库获取插入表的SQL

WITH t
  AS (SELECT x.table_name AS table_name,
             listagg(x.column_name,',') WITHIN GROUP(ORDER BY x.table_name,x.column_id)  AS table_column_set
        FROM user_tab_columns x
       GROUP BY x.table_name)
SELECT 'insert into ' || t.table_name || '(' ||  t.table_column_set || ')' ||
       ' select ' || t.table_column_set ||
       '   from ' || t.table_name || '@to_qdu;'
  FROM t;

023. 查询数据库的密码生命同期

SET LINES 300 PAGES 999
COL profile       FOR a30
COL resource_name FOR a40
COL limit         FOR a40
SELECT *
  FROM dba_profiles
 WHERE resource_name LIKE '%PASSWORD%';

025. 查询角色及系统权限

-- 查询系统中的角色
SELECT *
  FROM dba_roles a
 WHERE a.role = UPPER('execute_catalog_role');

-- 查询某个用户或角色拥有的角色(或拥有某个角色的用户或角色)
SELECT *
  FROM dba_role_privs a
 WHERE a.granted_role = UPPER('connect')
    OR a.grantee = 'DBA';

-- 查询当前登陆用户拥有的角色权限
SELECT *
  FROM user_role_privs a;

-- 查询某个用户或角色拥有的系统权限
SET LINES 300 PAGES 999
COL GRANTEE FOR A30
SELECT *
  FROM dba_sys_privs a
 WHERE a.grantee = UPPER('connect');

-- 查询当前登陆用户拥有的系统权限
SELECT *
  FROM user_sys_privs a;

角色不一定包含系统权限,比如 EXECUTE_CATALOG_ROLE 角色。

预定义数据库角色(常见的5个):

角色名称 角色用途
CONNECT 基本的用户角色,允许授权者链接到数据库,然后在相关的模式中创建表、视图、同义词、序列和一些其他的对象类型。
RESOURCE 建议用于典型的应用开发人员。该角色允许授权者在相关的模式中创建表、序列、数据簇、过程、函数、包、触发器、对象类型、基于函数的索引和用户自定义的操作符。
DBA 建议用户管理员。该角色允许授权者执行任何数据库功能,因为它包含了说有的系统权限。此外,改DBA角色的授权者,可以向任何其他数据库用户或角色授予任何系统权限。
SELECT_CATALOG_ROLE 该角色允许授权者查询管理员(DBA)数据字典视图。
EXECUTE_CATALOG_ROLE 该角色允许授权者运行预制的DBMS工具包。

参见: https://oracle-base.com/dba/scripts