当访问频率非常高的数据块称为热块(hot block),当很多用户一起去访问某几个数据块时,就会导致一些 Latch 争用。最常见 Latch 争用是:
- buffer busy waits
- cache buffer chain
这两个 Latch 争用分别发生在访问数据块的不同时刻。
当一个会话需要去访问一个内存块时,它首先要去一个像链表的结构中去检索这个数据块是否存在在内存中,会话访问这个链表时需要获得一个 Latch,如果获得失败,就会产生 Latch cache buffer chains 等待,导致这个等待的原因是访问相同数据块的会话太多或者这个列表太长(如果读到内存中的数据块太多,需要管理数据块的 hash 列表就会很长,这样会话扫描列表的时间就会增加,持有 cache buffer chain latch 的时间就会变长,其他会话获得这个 Latch 的机会就会降低,等待就会增加)。
当一个会话需要访问一个数据块,而这个数据块正在被另一个用户从磁盘读取到内存中或者这个数据块正在被另一个会话修改时,当前会话就需要等待,就会产生一个 buffer busy waits 等待。
产生这些 Latch 争用的直接原因是太多的会话去访问相同的数据块导致热块问题,造成热块的原因可能是数据库设置导致或重复执行SQL 频繁访问一些相同数据块导致。
热块产生的原因,按数据块类型,可以分为如下类型,不同热块类型处理的方式不同。
- 表数据块
- 索引数据块
- 索引根数据块
- 文件头数据块
表数据块
比如在 OLTP 系统中,一些小表,会出现某些数据块被频繁查询或修改的操作,此时,这些被频繁访问数据块就会成为热块,导致内存中的 Latch 争用。
可以看到 t 表,每个数据块平均存放70行左右。
《在64-bit RHEL5上安装Oracle 11gR2》
文档说明:本文档综合Red Hat Enterprise Linux 5 (RHEL5)操作系统安装及Oracle Database 11g Release 2的安装。文档内容适合在测试服务器上安装Oracle数据库以供实验、测试使用,对于生产数据库,部分参数需要DBA根据生产环境手工调试。若在生产环境安装RHEL操作系统和Oracle数据库,请按照公司规章制度和实际情况或者参考官方文档来规划。
以下为操作系统及数据库安装步骤及说明。
文档目的:有好几个非DBA的同事问我怎么在Linux下安装Oracle 11G很多人觉得简单,可并不是所有人都这么认为。
概述
此文档内容涉及RHEL5操作系统安装及Oracle Database 11gR2的安装。我们将安装64bitRHEL操作系统及Oracle 64-bit数据库。
官方安装文档可供参考:
64-bit(x86_64)Oracle Database安装文档
Oracle Database Installation Guide 11g Release 2 (11.2) for Linux
场景如下:
create or replace type list_obj is table of number;
--创建表结构
create table test(
name varchar2(30) primary key check(regexp_like(name,'^([a-z]|[0-9]|_)+$')),
id number not null,
version_list list_obj
) nested table version_list store as version_list;
场景说明:类型 list_obj 相当一个元素为数字的列表。表 test 有三个字段,字段 name 为主键限制只能使用小写字母、数字、下划线组成的字符串;字段 id 是数字,限制为非空;字段 version_list 是类型为 list_obj 的嵌套表。
操作1:
insert into test(name, id) values('mophee', 1);
查询结果如下:
目前 version_list 为空(注意,是 null),现在我们需要开始维护该字段:往 name='mophee' 的记录插入一个版本号20130403112459。语句如下:
insert into table(select version_list from test where name='mophee') values(20130403112459);
执行以上 insert 语句就报错了!
原因是什么?version_list 字段目前是 NULL,以上insert语句试图做这个动作:table(NULL),也就是要将NULL对象化成一个表。这事有违常理,ORACLE干不了!
那么怎么解决呢?version_list 字段之所以为NULL,是因为我们根本没对它进行初始化。那么,在insert之前先对其初始化不久能解决问题了吗?
方法一:在往 test 表 insert 的时候使用如下语句
insert into test(name, id, version_list) values('mophee', 1, list_obj());
方法二:在往 version_list 插入版本号之前先对其进行初始化
update test set version_list=list_obj() where name='mophee';
看下图:
这是在 pl/sql developer下的查询输出,注意 version_list 列数据单元格的背景色(与上方图片对比一下)已经不是淡黄色(此时字段值为null)!虽然查看 version_list 字段的内部内容依旧是没有一条记录,但是意义上是不一样的——初始化之前是 null,初始化之后才是 list_obj 对象。
完毕!
本文链接