注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

饥民2011

一直在搬砖

 
 
 

日志

 
 
 
 

Oracle 段区块 分配 (1)  

2013-03-27 22:59:33|  分类: Oracle |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
            这篇文章是参考甲骨论老相老师的教学视频
            http://v.youku.com/v_show/id_XNDAwMzYzODI0.html
            所做的学习笔记


             关于段区块的定义以前都将过几次了.
             视频中介绍了两个知识点:
             1. 区(extends)的分配
                         1个段(segment) 被建立后, oracle 如何为其分配新的extends

            2. 段空间管理方式.
                         1个新的extend 被分配到1个segment后, segment就相当于拥有一些空闲空间了, oracle怎么管理这些空间.

               本文讲解的是第1点:


一. 利用em(Enterprise Manager) 演示如何建立1个新的表空间(table space)
           
             step 1,  用sys登录em后, 在服务器那个tab见到有表空间的那个item, 点击入去:
Oracle 段区块 分配 - 饥民 - 饥民2011
 
          
            step 2,  进去后, 这个页面其实是1个管理表空间的页面,可以见到数据库当前表空间的各种信息, 我们要新建1个表空间, 就点击右边的创建按钮.
           
Oracle 段区块 分配 - 饥民 - 饥民2011

         step 3, 下一个页面, 就可以写入新表空间的名字和选择extends的管理方式了,  extends 的管理方式有两种: 本地管理 和 字典管理,  这里老相老师强烈建议选择默认的本地管理方式.
         
Oracle 段区块 分配 - 饥民 - 饥民2011
 
          其实这个区的管理类型会形象下面的区分配方式选项的。
          如上图, 旁边还有类型 和 状态的选项, 按照默认就看可以了.

          一般来讲, 我们知道表空间是用来存放数据文件的虚拟概念. 所以新建1个表空间的同时就必须为其新建1个新的数据文件. 在右下角, 我们点击添加数据文件的按钮.


          step 4.  如下图, 在添加数据文件的页面, 我们必须制定数据文件的文件名和位置。
         
Oracle 段区块 分配 - 饥民 - 饥民2011

              上面有个 重用现有文件的选项, 这个代表如果服务器对应位置已经有当前文件名的文件,就覆盖它, 强烈建议不选。
              自动扩展选项, 这里建议选上, 因为1个数据文件被占满后, 如果我们再执行1个 insert sql语句的话,就很可能会报错,如果选上该选项, 就会自动增加数据文件的大小, 增量的意思就是每次增加多少。

              不过作为dba, 不建议依赖这个功能来自动为dbf文件扩容, 因为每一次扩容,都发生大量的物理IO,就会大大影响对应sql语句的执行速度。而且通常自动扩展后,很快后容易又满了,然后又扩展.. 所以应该经常关注dbf文件的容量, 快满人手去为其增加一段合理的空间。 这个自动扩展只是用来防止报错啦。

              选上必要选项后, 就可以按右下的继续按钮返回了。

              step 5, 返回到先前的页面, 这里点击存储的tab页,就会见到区的分配方式段的管理方式选项

            
Oracle 段区块 分配 - 饥民 - 饥民2011
 
          当我们选择了区是本地管理方式后, 这里区的分配方式有自动和统一大小的选项, 老相老师说两个选项都可以。
          但是segment的管理强烈建议自动, 不要手动

           step 5, 这是我们点击确定。就会执行这个改动, 但是我们强烈建议点击旁边的显示sql按钮。
           通过查看sql语句。 才能真正了解oracle究竟会为你执行什么操作, 避免你的失误操作被执行。           
Oracle 段区块 分配 - 饥民 - 饥民2011
        
            不过, 强烈建议点击显示SQL按钮, 看看sql语句的内容,到底em会为我们执行什么操作, 可以避免你的在em的操作失误被执行。

             step 6, 得到sql语句后, 手动在sqlplus 或 sql developer里执行这段sql就会建立1个新的表空间了。
           
Oracle 段区块 分配 - 饥民 - 饥民2011
           
 执行:
Oracle 段区块 分配 - 饥民 - 饥民2011
               
老相老师在最后强调:
区管理, 毫无疑问选本地管理... 
段管理, 毫无疑问选自动
更深的知识老相老师表示在优化那里讲.



         

二, 一些用于查看段区块信息的sql语句

2.1 查看某张table对应的段信息
select owner,segment_name,blocks,extents,bytes,segment_type,tablespace_name from
dba_segments where segment_name='EMP';


Oracle 段区块 分配 - 饥民 - 饥民2011
 
注意到 这个表有1个区, 8个 blocks, 占 65536个字节  但是这些数据不一定是实事的.

要得到准确的数据, 就必须执行表分析 如下面的语句:
analyze table tablename compute statistics;             --注意tablename前面的模式名
analyze table tablename compute statistics for all indexes;


在执行上面的查看段信息语句. 就相对准确了.

这个命令更加常用, 功能跟上面的例子差不多的.都是分析有用的
exec dbms_stats.gather_table_stats(SCOTT','EMP');

而利用dba_tables这个视图也可以查看表的存储信息:
select blocks,empty_blocks from dba_tables where table_name = 'EMP';


2.2 查看表的具体存储信息.
包含表行数,使用的块数,空的块数,块的使用率,行迁移和链接的数量,pctfree,pctused的数据,行的平均大小:
 
命令如下:
SELECT table_name,NUM_ROWS, --表中的记录数
BLOCKS, --表中数据所占的数据块数 //高水位线
EMPTY_BLOCKS, --表中的空块数
AVG_SPACE, --数据块中平均的使用空间
CHAIN_CNT, --表中行连接和行迁移的数量
AVG_ROW_LEN --每条记录的平均长度
FROM DBA_TABLES where table_name='EMP'

Oracle 段区块 分配 - 饥民 - 饥民2011


2.3 查看一张表的所有extents信息:
     呢个好简单,就是检索dba_extents视图了.
     例如我选一张数量比较大的表:
      select * from dba_extents where segment_name = 'SOURCE$' order by extent_id;
Oracle 段区块 分配 - 饥民 - 饥民2011
 

如上图.
其中 Partition_name 的意思分区名, 如果是非分区表. 这里的值都是Null
extent_id 就是 这张表的段编号了, 1个编号代表1个段.
block_id 就是这个extent 起始block 编号
blocks 就是block数量了, 注意是连续的block啊
file_id 就是代表这个extent所在的数据文件编号.

也可以看出一些规律, 在oracle 在extents 本地管理,自动大小模式下, 一般对于一张表. 前16个extents 都是8个block的, 当16个extents用完时, oracle就会认为这张表是一张有一定数据量的表, 第17个开始就以128个blocks为单位分配给1个新的 extent了.
当然如果选的是统一大小管理, 就不会出现这个请跨国你.



三, segment的高水位线(high water mark)
       
       3.1 广义的高水位线
           
所谓高水位线就是1个水库和河流, 水位历史到达的最高位. 即使水位降下来, 高水位线的值不变, 除非水位冲破高水位线.

        
         3.2
Oralce的高水位线        
                 我们知道对于一张表来讲, 数据是存放在都应的segment中的, 由于update 和 delete操作的存在, 1个segment里面的数据量可以增加, 也能会减少,  而这个段曾经用过的最后1个编号的block的编号, 就是高水位线.

                  举个例子,  假如某1一张表T1, 那么对应的段就是T1段了,  加入这个段有4个extents, 共32个block, 有1日, 有人插入一段数据到表T1, 32个blocks中的31个被占用了, 而第32个bLock是从没有人用过的, 那么这个段的高水线就是第31个block.

                   这时分配了2个新的extents到这个段中,  这个段就多了 16个空的block, 共有48个block了, 这时高水位线仍然是第31个block.
                   有人又插入一段数据, 这段数据占7个block, 那么这个段被占用红了 38个block, 高水位线就被调整至第38个block!
                   然后他把这段数据删除, 这个段之占用了31个block, 上次的7个block数据被清空. 但是高水位线仍然是第38个block, 并不会降下来.

        
3.3 高水位线的意义
              
高水位线的意义在哪里呢? 其实高水位线是oracle执行全表扫描时会扫描到的位置.  例如上面那个例子,  T1段有48个block, 但是只占用了31个block, 而高水位线在第38个block, 那么全表扫描时就会扫到38个block. 即使其中7个是空的.

                   所以我们知道高水位其实越低越好(越接近当前值), 否则会出现performance问题.


       如下图,  select count(*) from table就是1个全表 扫描动作.
      而高水线会影响逻辑读 和物理读的数量.
           
Oracle 段区块 分配 - 饥民 - 饥民2011
 
         

         3.4 降低高水位线
             
那么高水位线是否只能增大不能减少呢. 不是的, oracle提供降低高水位线的功能,  这个涉及段空间的释放. 老相老师说以后讲优化时再讲.
                  其中1个方法就是先备份这张的表数据到另1个张表. 然后truncate这张表, 就会把高水位先将到0(同时清空数据), 然后把数据insert 回来.




四, oracle的块(blocks)
        
我们知道oracle blocks的默认大小是8kb.
           下面分析下1个block的结构.
 
           4.1 Data Block 的结构。
 
                      

               4.1.1 数据块头(含标准内容和可变内容)
                           数据块头包含基本的Data Block信息,
                            a.
Block的地址
                            b. 属于哪个表空间/段/区  (所属表的信息)
                            c.所属段的类型.(例如,数据段\索引段)
                            d.事务槽 //老相老师说以后讲
                            e. 行目录  //记录行数据区每一行的起始位置.

                            如上图, 可以见到头部信息是存放在1个block的头部的, 而数据行数据是放在尾部的. 空闲的空间会出现在中间.

                            
4.1.2 行数据区   
                
行数据区当然就是用存放表的数据行数据啦
                    对于每1条数据行,  都包括
                    a. 行的头部.  记录一些行的锁信息 很段
                    b. 列1的长度, 列1的值, 列2的长度, 列2的值.........你懂的

                    而每两个邻近的行, 头部和尾部是连接在一起的, 所以在block里, 是没有物理上的行的概念了, 因为所有的行都链接在一起嘛那么怎么区分数据是哪呢, 就是依靠上面头部信息的行目录区, 他记录了具体每1个行的起始位置.

                    假如server Process要访问的1个张表的第8行第4列, 
                     1) 那么它首先会根据执行计划这个行在哪1个block.
                     2) 将这个block整个读入data buffer
                     3) 访问buffer的头部信息, 知道这一行在这个block的起始位置.
                     4) 得到位置后, 他会首先获得列1的长度.  然后根据长度就可以直接跳过列1的数据区,接下來它获得列2的长度,然后又跳过列2的数据, 知道它获得列4的长度, 然后就根据当前位置和长度获得列4的数据()了.

                     所以理论上, 如果我们要访问第10个列, 理论上可以要访问前9个列的长度信息。 所以最好把最经常访问的列放在前面。 不过这个时间差忽略不不计了, 优化的价值很少。


五, 文件系统(linux)的块
                  
可以用如下命令去 查看文件系统块的信息:
                      dumpe2fs /dev/sda1           //当然sdax就根据实际情况了.
如下图:

Oracle 段区块 分配 - 饥民 - 饥民2011
              
可以加到操作系统级别的block size是4kb

当我们手动设置oracle 的blocksize时间,一定要将其设置成操作系统基本blocksize 的整数倍。 否则会访问额外的操作系统block, 导致性能问题, 老
相老师说这个问题在优化时会详细讲



貌似空间不够了 接:

Oracle 段区块 分配(2)



  评论这张
 
阅读(511)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017