oracle问题解决方案汇总

ORACLE问题和解决方案汇总-持续更新

    • 查询并解决锁表
    • 查看所有表空间空间占用率(来源网络)
    • 建立索引时提示ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效
    • 分析索引
    • 数据库启动设置相关
      • ORA-00093数据库启动失败
      • 修改最大连接数据和会话数
    • 优化相关
      • 索引

查询并解决锁表

SELECT  locks.sql_id,
b.sid oracleID,
       b.username 登录Oracle用户名,
       b.serial#,
       spid 操作系统ID,
       paddr,
       c.SQL_TEXT,
       c.SQL_FULLTEXT 正在执行的SQL,
       b.machine 计算机名,
       b.PROGRAM,
       b.blocking_session ,
       b.blocking_session_status 锁状态,
       b.SECONDS_IN_WAIT 持续时间,
       'ALTER SYSTEM KILL SESSION ''' || B.sid || ',' || B.serial# || ''' immediate;' 解锁语句
  FROM v$process a,
       v$session b,
       v$sqlarea c,
       (select sess.sid, sess.serial#,sess.SQL_ID
          from v$locked_object lo, dba_objects ao, v$session sess
         where ao.object_id = lo.object_id
           and lo.session_id = sess.sid) locks
 WHERE a.addr = b.paddr
   AND b.sql_hash_value = c.hash_value
   and b.serial# = locks.serial#
   and b.sid = locks.sid
   order by b.SECONDS_IN_WAIT desc

在数据库中执行改语句后,会按照锁表的时间进行排序,并生成了对应的解锁语句,复制后执行即可。

查看所有表空间空间占用率(来源网络)

SELECT d.tablespace_name "Name", d.status "Status", 
       TO_CHAR (NVL (a.BYTES / 1024 / 1024, 0), '99,999,990.90') "Size (M)",
          TO_CHAR (NVL (a.BYTES - NVL (f.BYTES, 0), 0) / 1024 / 1024,
                   '99999999.99'
                  ) USE,
       TO_CHAR (NVL ((a.BYTES - NVL (f.BYTES, 0)) / a.BYTES * 100, 0),
                '990.00'
               ) "Used %"
  FROM SYS.dba_tablespaces d,
       (SELECT   tablespace_name, SUM (BYTES) BYTES
            FROM dba_data_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 = a.tablespace_name(+)
   AND d.tablespace_name = f.tablespace_name(+)
   AND NOT (d.extent_management LIKE 'LOCAL' AND d.CONTENTS LIKE 'TEMPORARY')
UNION ALL
SELECT d.tablespace_name "Name", d.status "Status", 
       TO_CHAR (NVL (a.BYTES / 1024 / 1024, 0), '99,999,990.90') "Size (M)",
          TO_CHAR (NVL (t.BYTES, 0) / 1024 / 1024, '99999999.99') USE,
       TO_CHAR (NVL (t.BYTES / a.BYTES * 100, 0), '990.00') "Used %"
  FROM SYS.dba_tablespaces d,
       (SELECT   tablespace_name, SUM (BYTES) BYTES
            FROM dba_temp_files
        GROUP BY tablespace_name) a,
       (SELECT   tablespace_name, SUM (bytes_cached) BYTES
            FROM v$temp_extent_pool
        GROUP BY tablespace_name) t
 WHERE d.tablespace_name = a.tablespace_name(+)
   AND d.tablespace_name = t.tablespace_name(+)
   AND d.extent_management LIKE 'LOCAL'
   AND d.CONTENTS LIKE 'TEMPORARY';

建立索引时提示ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效

出现该问题大部分的原因是在建立索引时,对应的数据表上有锁表的现象
解决方法两种,第一种是先杀会话,再建立索引。但是在生产环境上直接杀会话的话风险太大,会被投诉;
第二种方式是执行alter session set ddl_lock_timeout=10;,ddl_lock_timeout参数的含义是等待时间,这个参数默认是0,也就是当碰到锁时就直接失败,设置为10的意思是当ORACLE等待10秒,如果10秒内仍然无法获取资源则失败。这样ORACLE在10秒内会不停的尝试,直到能执行对应的事务。

分析索引

exec dbms_stats.gather_index_stats(ownname => 'ower_user',indname => 'idx_name',estimate_percent => '10',degree => '4');
analyze index idx_t estimate statistics sample 10 percent

这两条语句,60万条的记录,该语句执行不超过20秒,要在生产环境上执行的同学可以参考一下。

数据库启动设置相关

ORA-00093数据库启动失败

其实所有启动失败的处理流程类似,只是执行的具体修改不一样,

创建PFILE
修改pfile有问题的参数
使用pfile启动数据库
恢复spfile

具体的处理过程如下:

create pfile='/home/oracle/temp_init.ora' from spfile;
cd /home/oracle
ll -h
vim temp_init.ora

在VIM界面,找到有问题的参数进行修改,具体出现问题的参数,在启动失败的提示信息里会有。VIM界面编辑完成后先按esc,然后输入wq!保存退出
此时重新使用pfile启动数据库

sqlplus / as sysdba
startup pfile='/home/oracle/temp_init.ora'

启动成功后,一定要用当前正确的启动配置恢复spfile,不然下次启动还是需要带上pfile参数

create spfile from memory;

或者也可以先创建spfile再执行启动

sqlplus / as sysdba
create spfile from pfile='/home/oracle/temp_init.ora';
startup;

修改最大连接数据和会话数

修改最大连接数的同时,别忘了修改sessions会话数,sessions不可随意设置,计算公式:

sessions=(1.1*process+5)

一般和最大连接数porcess保持一致就可以

sqlplus / as sysdba
alter system set processes=3000 scope=spfile;
alter system set sessions=3000 scope=spfile;
--修改后必须重启数据库,注意如果是RAC,那么所有的节点都需要重启一下
shutdown immediate;
startup;

优化相关

索引

分析索引碎片、重建索引

select * from user_indexes i where I.table_name = 'XXXXX'; --查看表上的所有索引
analyze index IDX_NAME validate structure;--分析索引碎片
select t.name,t.height,t.pct_used,(t.del_lf_rows / t.lf_rows) from index_stats t;--查看索引碎片
--索引碎片如果大于0.1,我就直接重建索引了
alter index IDX_NAME rebuild online;
--自动生成rebuild语句(来源网络)
select 'alter index ' || index_owner || '.' ||index_name ||' rebuild partition ' || PARTITION_NAME || ' nologging parallel ;'  
from dba_ind_partitions  
where index_owner = 'USER_NAME'  
AND INDEX_NAME = 'idx_tbl_col'  

大约60万条记录的表,以上语句执行均不超过5秒钟,数据库服务器96核CPU,500G内存,供大家参考
分析表和索引

analyze table TABLE_NAME compute statistics;--60万条记录大概执行了30多秒
analyze index IDX_NAME compute statistics;
--删除分析数据
analyze table TABLE_NAME delete statistics;

ORACLE建议以dbms_stats package来替代analyze,所以analyze就学习记录一下就好

你可能感兴趣的:(oracle,oracle)