ITPub博客

首页 > Linux操作系统 > Linux操作系统 > oracle

oracle

原创 Linux操作系统 作者:HelloWorld_001 时间:2013-08-19 19:17:56 0 删除 编辑

数据块结构图

update操作流程

cache buff chain 的原理,怎么解决

library cache pin/lock 的原理,怎么解决

log file sync的原理,怎么解决

怎么保持执行计划的稳定性

对数据库的监控有哪些

1.数据块结构图
块头(公共和变量)
表目录
行目录
可用空间(free space)
行数据

块头(公共和变量)
头部包含了通用块信息,例如块的地址和段的类型(例如表或者索引)

表目录
这部分信息包含了在这个块中该表或该索引的相关信息

行目录
这部分包含了数据块中实际行的信息(包括行数据区域中每行的地址),一旦数据块头部的这个行目录的空间被分配了,
那么即使该行删除了,这段表空间依然不用回收。

 

1.control scn有什么作用
在回滚段头有一个重要的数据结构称为:Control SCN.

undo segment头部的scn


2.关于延迟块清除导致的01555错误,如何进行块清除
oracle会把query scn去和回滚段中事务的提交scn比较,如果没有找到事务结束scn,说明回滚信息已经被覆盖了。
这是就把query scn去和control scn比较,因为control scn是当前该回滚段中所能获得的最小的一个commit scn。
如果quert scn依然小于这个control scn,由于被覆盖的事务的commit scn肯定比回滚段中control scn小,则暗示着
oracle无法知道query scn和commit scn直接的大小关系,就报了01555错误

这个时候,oracle就把这个control scn当做upper bound commit scn.
这是因为,真是的commit scn必然小于这个control scn,而current scn必然远大于这个这个control scn。
所以将commit scn设置为这个control scn必然是安全的

commit scn < control scn(upper bound scn) < current scn

/*
由于要处理系统中的一例ORA-01555错误,今天回顾了两个概念。pub上一个哥们总结的不错,但是他下边总结的不易理解,我特地整理如下:

在进行块清除的时候,如果是一个大事务,就会进行延迟块清除
块清除就是删除所修改数据块上与”锁定”有关的信息,即事务信息

Oracle在事务相关的提交列表中,记录下已修改的块列表,每个列表记录20个块,根据需要可能分配有多个这种列表.
这种块列表有一个上限,就是缓冲区缓存大小的10%.
如果一次修改的块,没有超过了缓冲区缓存大小的10%,并且这些块在内存中,则commit时,会清除块上的事务信息,
否则,就不会理会它,直到下次访问这些块时,再清除块中的事务信息,这就是延迟块清除.
因为这个Select修改了块的事务信息,所以就会产生Redo.

下面是根据ITPUB上的资料和我的理解整理的关于块清除时SCN的填写,以及什么情况产生”快照太旧”的错误.
延迟清除的块的下一个读者,首先根据块中的记录的回滚信息去查找回滚段中记录的commit时的SCN,如果能找到,那么正常清除,会产生redo log,这也是select会产生redo的原因。
但回滚段可能已回绕,找不到提交时的scn了,
但是,从回滚段事务slot中可以得到一个最小的提交scn并且需要清理的事务已经提交肯定小于这个从回滚段中还存在的最小scn,这是因为事务slot是循环使用的,既然已经回绕,那说明当前slot中最小SCN大于需要清理的事务的SCN。
对于回滚段已回绕的情况,即transaction slot中的最小提交SCN大于待清理事务的SCN,有以下两种可能:

如果select 时的scn 大于回滚段事务slot中最小的scn, 也即select时间点在需要清理的事务提交之后,
oracle会给这个块清除的事务分配一个从回滚段中找到的最小事务scn,从而完成块的清除.。这虽然不准确,但是是安全的,
对于数据访问也不构成影响。所以叫 upper bound ,猜测的一个scn的上限。

如果select 的scn 比这个回滚段事务slot里面最小的scn 还要小的话,那么oracle需要构造select那个scn的一致块,如果回滚段事务slot已回绕,
在回滚段里面找不到数据了,oracle 无法构造一致性块,于是ora-01555就出现了,
这个时候oracle 就不知道数据块里面的数据是不是是查询时刻需要的数据.

*/


3.执行计划
统计信息不准
unique index只需要一个表
设计有问题,将表t的列冗余到a表,然后建个符合index

oracle10g用
11g用sql baseline。

4.
建模,中间弄个过度的


5.hash算法用在哪些地方
内存 library cache 内存分成几个桶,每个桶用双向链表连起来
、分区表、hash index


6.如果发现dg出现间断的归档
dg的几个模式,归档断了怎么办
v$archive_gap  --查看丢失的归档
如果归档在primary存在,那么
  register  --alter database register physical logfile '/arch2/1_159_726529113.dbf';
如果归档不存在,需要从归档日志丢失的那时候做增量备份,standby库应用

v$archived_log;  --查看归档日志


7.查看数据库有哪些实例
ps -ef|grep smon


8.分库的认识
最佳实践: 水平切分

按功能分割对我们的帮助很大,但单凭它还不足以得到完全可伸缩的架构。
即使将功能一一解耦,单项功能的资源需求随着时间增加仍然有可能超出单一系统的能力。
我们常常提醒自己,“没有分割就没有伸缩”。在单项功能内部,我们需要能把工作负载分解成许多我们有能力驾驭的小单元,
让每个单元都能维持


9.cache buff chain 的原理,怎么解决
当一个用户进程想要访问Block(569,411):

l  对该Block运用Hash算法,得到Hash值。

l  获得cache buffers chains latch

l  到相应的Hash Bucket中搜寻相应Buffer Header

l  如果找到相应的Buffer Header,然后判断该Buffer的状态,看是否需要构造CR Block,或者Buffer处于pin的状态,最后读取。

l  如果找不到,就从磁盘读入到Buffer Cache中。

我们遇到了latch:cache buffers chains该怎么办?

  1. 不够优化的SQL。大量逻辑读的SQL语句就有可能产生非常严重的latch:cache buffers chains等待,因为每次要访问一个block,就需要获得该latch,由于有大量的逻辑读,那么就增加了latch:cache buffers chains争用的机率。
  2. 热点块争用。


10.library cache pin/lock 的原理,怎么解决
当要对一个过程或者函数进行编译时,需要在library cache中pin该对象。在pin该对象以前,需要获得该对象handle的锁定,如果获取失败,就会产生library cache lock等待。如果成功获取handle的lock,则继续在library cache中pin该对象,如果pin对象失败,则会产生library cache pin等待。

如果是存储过程或者函数,可以这样认为:如果存在librarycache lock等待,则一定存在library cache pin等待;反过来,如果存在library cache pin等待,不一定会存在library cache lock等待;
但如果是表引起的,则一般只有library cache lock等待,则不一定存在library cache pin。

可能发生library cache pin和library cache lock的情况:
1、在存储过程或者函数正在运行时被编译。
2、在存储过程或者函数正在运行时被对它们进行授权、或者移除权限等操作。
3、对某个表执行DDL期间,有另外的会话对该表执行DML或者DDL。
4、PL/SQL对象之间存在复杂的依赖性

用package,这样包体修改包头不需要编译,package依然有效
重新编译、授权、移除权限首先检查是否在使用,
PL/SQL对象降低耦合性


11.log file sync的原理,怎么解决
高log file sync等待事件的3个主要原因。
     ①.高提交频率

            解决方法是简单的消除不必要的提交,事务是工作单元。工作单元应该是全部成功或全部失败。
     ②.缓慢的I/O子系统
        较高的IO吞吐良可以改善log file sync和log file parallel write事件的平均等待时间。频繁的提交会弄乱数据库布局和IO子系统。解决办法是将日志文件放裸设备上或绑定在RAID 0或RAID 0+1中,而不是绑定在RAID 5中。
     ③.过大的日志缓冲区
        过大的日志缓冲区也可能延长log file sync等待。大型的日志缓冲区减少后台写入的数量,允许LGWR变得懒惰,并导致更多的重做条目堆积在日志缓冲区中。同时可以调整参数_LOG_IO_SIZE参数,其默认值是LOG_BUFFER的1/3或1MB,取两者之中较小的值。换句话说,你可以具有较大的日志缓冲区,但较小的_LOG_IO_SIZE将增加后台写入,从而减少log file sync的等待时间。

RAC中需要同步SCN导致

表面看起来需要解决的是IO问题
实际上我们可能要关注: buffer  cache多大,检查点频率多少,日志文件大小和组数量,硬件io是否是瓶颈能否分散io,应用是否存在可以调整的余地(包括优化sql,调整批量运行任务计划等)……
所以你单独给出这么个事件是非常地不充分的,至少也得给个statspack  report,并描述应用特征和软硬件环境特征


12.怎么保持执行计划的稳定性
11g sql baseline
SQL生成一个执行计划
用hint方式生成一个认为正确的执行计划,然后将hash更新到之前的执行计划中

/*
目的:让执行计划走上全表扫描

查询语句:select count(*) from wxh_tbd where object_id=:a
SQL_ID:85f05qy1aq0dr
PLAN_HASH_VALUE:1501268522

步骤一-------------------------创建测试表,根据DBA_OBJECTS创建,OBJECT_ID上有索引
Create table wxh_tbd as select * from dba_objects;
create index t_3 on wxh_tbd(object_id);

步骤二------------------------创建指定SQLID的BASELINE,后面要做修改,由于默认走的索引
declare
  l_pls number;
begin
  l_pls := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id          => '85f05qy1aq0dr',
                                                 plan_hash_value => 1501268522,
                                                 enabled         => 'NO');
end;
/

步骤三--------------------------想办法构造出执行计划为全表扫描的SQL_ID
var a number
exec :a :=1234
select /*+ full(wxh_tbd) */count(*) from wxh_tbd where object_id=:a;
select sql_id ,sql_text from v$sql where sql_text like '%wxh_tbd%';
查出SQL_ID为89143jku5hzcw,PLAN_HASH_VALUE为853361775

步骤四--------------------------确定原始执行计划的 sql_handle
select sql_handle, plan_name, origin, enabled, accepted,fixed,optimizer_cost,sql_text
   from dba_sql_plan_baselines where sql_text like '%count(*) from wxh_tbd %'
   order by last_modified;
SQL_HANDLE:SYS_SQL_ad9f0ff741832bd9                                    
PLAN_NAME:SYS_SQL_PLAN_41832bd9d63f8aa9 

步骤五------------------------与正确的执行计划做关联
declare l_pls number;
begin
  l_pls := DBMS_SPM.load_plans_from_cursor_cache(sql_id          => '89143jku5hzcw', -- hinted_SQL_ID'
                                                 plan_hash_value => 853361775, --hinted_plan_hash_value
                                                 sql_handle      => 'SYS_SQL_ad9f0ff741832bd9' --sql_handle_for_original
                                                 );
end;
/

步骤六--------------------------删除错误的执行计划
declare l_pls number;
begin
  l_pls := DBMS_SPM.DROP_SQL_PLAN_BASELINE(sql_handle => 'SYS_SQL_ad9f0ff741832bd9', --sql_handle_for_original
                                           plan_name  => 'SYS_SQL_PLAN_41832bd9d63f8aa9  ' --sql_plan_name_for_original
                                          
                                           );
end;
/

步骤七----------------------确认是否使用到BASELINE
explain plan for  select count(*) from wxh_tbd where object_id=:a;
select * from table(dbms_xplan.display);
--------------------------------------
| Id  | Operation          | Name    |
--------------------------------------
|   0 | SELECT STATEMENT   |         |
|   1 |  SORT AGGREGATE    |         |
|*  2 |   TABLE ACCESS FULL| WXH_TBD |
--------------------------------------
Note
-----
   - SQL plan baseline "SYS_SQL_PLAN_41832bd9cca3d082" used for this statement
*/

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13932145/viewspace-768824/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2008-04-21

  • 博文量
    1
  • 访问量
    4186