天天看點

存儲結構

OLTP:線上業務處理裡系統

(如銀行前台,存資料,讀資料 跟資料庫互動操作)

OLAP:線上資料分析系統

(隻能讀資料出來,不能寫.如資料倉庫,

 源資料是在 OLTP上通過ETL抽取出來)

作業系統塊 ext3 為4k

oracle 塊為系統塊的整數倍 預設8k

檢視系統塊大小

[oracle@sq ~]$ getconf PAGESIZE

4096

檢視資料庫預設塊(8k)

SQL> show parameter block

----------------------------------------------

查詢目前使用者下所有段

SQL> select * from user_segments

1.SQL> create table t11(id number(5));

2.檢視表占用的段

SQL> select * from user_segments t where t.segment_name='T11';

結果: BYTES = 65536 (預設占64k)  (建立一個表占有一個段)

3.

SQL> insert into t11 values(11);

/多次

SQL> insert into t11 select * from t11;

2048 rows created.

4.檢視區

SQL> select * from user_extents t where t.segment_name='TA';

結果 :EXTENT_ID =0(為隻占用了一個區 0為區号)

5.再次執行

6.重新檢視區

結果會有多個區出現 ID從0開始

(如插入資料過多,我們會發現 每個區的BLOCKS數量會從8個 變化到128個

oracle認為資料量太大,每個區變為128個塊)

------------------------------------------------

回收

1.

SQL> select count(*) from t11;

  COUNT(*)

----------

   1048576

SQL> delete from t11;

SQL> commit;

2.檢視區

select * from user_extents t where t.segment_name='T11';

(發現占用的區并沒有少,其實裡面都是空的)

3.重新寫入資料

1048576 rows created.(跟删除)

4.再次檢視區

(發現也沒有增加區,說明新資料使用的是之前的空白區)

5.

SQL> set autotrace traceonly(跟蹤)

SQL> select * from t11;

27894  consistent gets (27894 次邏輯讀)

SQL> delete from t11 where rownum<=1000000;(删除100w條資料)

6.

1679  consistent gets(已經沒有多少資料,但還要很多的邏輯讀,因為

會掃描表中所有區塊,包括空白區)

7.

SQL> alter table t11 move;(移動表,就是清空所有空白區)

8.

 4  consistent gets(邏輯讀4 空白區已經沒有了)

SQL> select * from user_extents t where t.segment_name='T11';

(發現隻剩了一個區)

----------------------------------------------------

小表可以用小塊

9i 開始 允許不同的表空使用 不同的塊大小

SQL> create tablespace testnblock

  2  datafile '/u01/app/oracle/oradata/orcl/testnblock.dbf' size 10M

  3  blocksize 16k;

create tablespace testnblock

*

ERROR at line 1:

ORA-29339: tablespace block size 16384 does not match configured block sizes

SQL> alter system set db_16k_cache_size = 10M;

System altered.

Tablespace created.

我們可以設定不同的大小  2,4,8,16,32(32位系統不支援32k)

SQL> show parameter db_block_size (預設為8k)

mysql 預設塊16k  db2 預設塊4k

資料倉庫應該 用大點的塊

--------------------------

SQL> create table ab as select * from dba_objects;

SQL> analyze table ab compute statistics;(分析表)

SQL> select avg_row_len from user_tables where table_name='AB';

(檢視平均行長度,機關位元組,一個塊 至少能存儲一行)

------------------------

檢視錯誤資訊

SQL> ! oerr ora 00382

----------------------------

pctfree 塊中空閑的空間

友善後續的修改工作 

修改中如原有塊空間不夠 會建立新塊,原有塊會建立個指針指向新塊,

那麼這種操作會讀兩次i/o.

SQL> alter table t1 pctfree 0;(沒有空閑 老的資料不變)

SQL> alter table t1 move pctfree 0;(移動重新排,老資料塊也變化)

-------------------------------------

SQL> create table tab_rc

  2  (name01 char(1000),

  3  name02 char(1000),

  4  name03 char(100))

  5  pctfree 0;

SQL> insert into tab_rc(name01,name02) values('c','c');

(插入4次  塊中有8000位元組資料)

SQL> update tab_rc set name03='c';

(更新4行 多出400位元組)

analyze table tab_rc compute statistics;(分析表)

select t.table_name,t.chain_cnt from user_tables t;

(結果 對應鍊為1)

--------------------------------------------------------------

select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from tab_rc;

(第一列為資料檔案号,第二列為塊号)

oradebug setmypid;

alter system dump datafile 1 block 59626;

SQL> oradebug tracefile_name;

/oracle/app/admin/TEST/udump/test_ora_4772.trc

more /oracle/app/admin/TEST/udump/test_ora_4772.trc

(nrid:  0x0100008c.0      此參數不為0,則代表行遷移)

分析塊參數

SQL> create table ab (id int,name varchar2(10));

SQL> insert into ab values(123,'zs');

SQL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from ab;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)

------------------------------------ ------------------------------------

                                   1                                59610

SQL> oradebug setmypid;

SQL> alter system dump datafile 1 block 59610;

/oracle/app/admin/TEST/udump/test_ora_9426.trc

[oracle@oracle111 ~]$ more /oracle/app/admin/TEST/udump/test_ora_9426.trc

1.塊頭部

flg:0x01 (建立塊)0x2(資料塊延遲清洗推進scn和seq) 0X04(設定校驗和) 0x08(臨時塊)

type:0x06(表/索引塊)

frmt:  0x01(v7)  0x02(v8)

2.ITL (事務槽)

seg/obj :(object_id 十六進制表示)

csc: 0x00.15a3ea --cleanoutSCN,塊清除時的SCN

itc: 2   --ITL槽的數量

flg: E   --指用的是ASSM,如果是O表示用的是free list

typ: 1 - DATA   --事務型的資料塊(并且:資料塊頭的type:0x06),存放表和索引資料。

3.使用者資料頭

bdba: 0x01800087  -- 資料塊的位址

tsiz: 0x1f98  --top of size 塊的總大小即8088個位元組

hsiz: 0x14   --Data header size 資料頭大小即20個位元組

ntab=1     --叫表數:表示這個塊的資料在一個表(如果是聚簇表就有可能是2或2以上)

nrow=1     --叫行數:表示這個表有一行資料

fsbo=0x14   -- Free space begin offset  叫起始空間:可以存放資料空間的起始位置(即定義了資料層中空閑空間的起始offset)

fseo=0x1f8c  -- Free space end offset  叫結束空間:可以存放資料空間的結束位置(即定義了資料層中空閑空間的結束offset)

avsp=0x1f78  --Available space for new entries  叫空閑空間:定義了資料層中空閑空間的位元組數

tosp=0x1f78  --Total space   叫最終空閑空間:定義了ITL中事務送出後,資料層中空閑空間的位元組數

0xe:pti[0]      nrow=1  offs=0  --Table directory,整個表的開始,共一行資料 ,定義了該表在行索引中使用的插槽數

0x12:pri[0]     offs=0x1f8c      --Row index,叫行索引,定義了該塊中包含的所有行資料的位置

4.使用者資料

tab 0, row 0, @0x1f8c      --第一個表第一行的位置 ,定義了該表在行索引中的起始插槽号

tl: 12 fb: --H-FL-- lb: 0x1  cc: 2  --行頭,tl: 12行長度12個位元組,

fb: (Flag byte)--H-FL指H(Head piece of row)F(First data piece) L(Last data piece)

lb: 0x1 --Lock byte和上面的ITL的lck相對應,表示這行是否被lock了

cc: 2 --表示有兩列,即這個表有兩個字段

col  0: [ 2]  c1 02 --第一行的第一個字段長度和值

col  1: [ 5]  41 41 41 41 41 --第一行的第二個字段長度和值

     本文轉自陳繼松 51CTO部落格,原文連結:http://blog.51cto.com/chenjisong/1737383,如需轉載請自行聯系原作者