亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Oracle如何修改壓縮數據

發布時間:2021-11-09 10:58:38 來源:億速云 閱讀:112 作者:小新 欄目:關系型數據庫

這篇文章將為大家詳細講解有關Oracle如何修改壓縮數據,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

我們將看到只有在直接路徑加載、CTAS(create table as select)和"alter table move"時,基礎表壓縮機制才可以生效。同時當表啟用了壓縮時,Oracle會默認的將該表中數據塊的pctfree設置為0,這也暗示了我們基礎壓縮應該作為一種只讀數據的壓縮策略。

當我們查看一個對應塊的dump文件時,會發現Oracle并不是“壓縮”數據,他所做的是在每個塊上創建重復值列表(即字典表),然后通過一些標志來代替那些重復值從而達到塊級別的去重。并且,Oracle可以重新排列塊中的字段順序,從而增加用一個標志來代替多個字段的機會。這告訴我們,Oracle在讀取塊時并不需要“解壓”數據,他需要做的僅僅是通過指針來重構數據,當然這是一個CPU密集型操作。

在這篇文章中,我們將討論如果不遵從只讀原則將會發生什么。然后,我們將會在第三篇文章中探討需要另外授權的OLTP壓縮。如前所述,以下所有示例都來自Oracle 11.2.0.3的實例。

去重與刪除

你可以回憶下上篇文章中,我把一個包含組合標志的數據塊的一行dump出來,然后Oracle遞歸的向上查找這個標志代表的意義,最終確定該組合標志由兩個單獨的標志和兩個額外的字段值組合而成,下面就是我們測試的那行:

tab 1, row 0, @0x1b28

tl: 5 fb: --H-FL-- lb: 0x0 cc: 4

col 0: [ 4] 41 41 41 41

col 1: [10] 41 41 41 41 41 41 41 41 41 41

col 2: [ 2] c1 02

col 3: [10] 20 20 20 20 20 20 20 20 20 31

bindmp: 2c 00 01 04 31

這是我們在查找引用的單個標志的值時所發現的**49號標志**:

Tab 0, row 49, @0x1ed0

tl: 19 fb: --H-FL-- lb: 0x0 cc: 4

col 0: [ 4] 41 41 41 41

col 1: [10] 41 41 41 41 41 41 41 41 41 41

col 2: [ 2] c1 02

col 3: [10] 20 20 20 20 20 20 20 20 20 31

bindmp: 00 08 04 36 40 ca c1 02 d2 20 20 20 20 20 20 20 20 20 31

bindmp中的前5個字節告訴我們這個標志在這個塊中使用了8次(00 08),由4個列組成,然后我們來看看54(0x36)和64(0x40)號標志:

tab 0, row 54, @0x1f74

tl: 7 fb: --H-FL-- lb: 0x0 cc: 1

col 0: [ 4] 41 41 41 41

bindmp: 00 0a cc 41 41 41 41


tab 0, row 64, @0x1f7b

tl: 13 fb: --H-FL-- lb: 0x0 cc: 1

col 0: [10] 41 41 41 41 41 41 41 41 41 41

bindmp: 00 05 d2 41 41 41 41 41 41 41 41 41 41

從上面的dump數據我們可以猜到,如果想要刪除原始行,就必須進行額外的工作。 \

有兩件事必然會發生:

1. 該行必須標志為已刪除(以正常的方式),

2. **49號標志**的“使用計數”也必須減少1。

在刪除一行之后,這里有一個小的片段,首先是行條目本身:

tab 1, row 0, @0x1b28

tl: 2 fb: --HDFL-- lb: 0x2

bindmp: 3c 02

以下是**49號標志**的二進制轉儲,注意,第二個字節:

bindmp: 00 07 04 36 40 ca c1 02 d2 20 20 20 20 20 20 20 20 20 31

所以我們可以意識到,即使是刪除簡單的一行,也會使維護塊數據的工作增加。但是這個標志同時也在塊的其他7行中使用,所以如果我刪除這些行,會發生什么?答案取決于刪除的并發會話數量。如果我使用一個進程來刪除所有8行,在刪除第8行時,Oracle刪除了標志,此時63號標志和64號標志必須更新,以顯示它們缺少了一個依賴項。如果我重復測試使用多個會話來刪除行,并且在每次刪除后不提交,那么我就可以看到一個場景,標志顯示為零,但不會消失。(也有可能我還沒有觀察到的一些后續的塊清理操作將會清除這個狀態的標志。)

在我提到并發測試之前,我沒有提到任何關于提交或回滾的內容。標志的改變發生在delete這個動作上,并且之后并沒有提交。如果我提交或回滾會發生什么?

在提交時,可能會發生通常的提交清除操作,用提交時的SCN更新事務的ITL插槽(換句話說,沒有新的或特別的事情發生)。在回滾時,數據根據undo信息恢復,任何已經被刪除的標志也將被重新創建,任何相關標志的使用數都會增加。

但重點是,回滾之后,壓縮依然會保留。雖然這些行會在回滾后寫入塊的空閑空間,但在原始塊和回滾后的塊之間還是有一些區別。因為這樣的操作需要塊經過空閑空間碎片的整合操作。所以如果你再次將塊dump出來,你可以看到塊的內容已經被移動了。在我的例子里(刪除了引用49號標志的8行記錄,然后回滾),我看到了如下的區別:

tab 0, row 49, @0x1ed0 -- original position of token 0

tab 0, row 49, @0x134a -- position of token 0 after rollback


tab 1, row 0, @0x1b28 -- original position of row 0

tab 1, row 0, @0x1322 -- position of row 0 after rollback

壓縮與空閑空間

當你刪除然后回滾數據后,行就會移動,這個現象引出了關于空閑空間非常有趣的一點——當你的表是基礎壓縮的時候,默認的pctfree就是0了。沒有空閑空間,但有空間給我在回滾后移動數據用?

我發現Oracle確實會保留一點點空間(大約幾十byte,但對于我測試用例里的兩整行也是絕對足夠了)。這一小部分空間允許Oracle恢復那些已被刪除的行。有些情況,這部分剩余空間甚至能讓你做update操作。

我來微調下我的初始數據集,每一行看起來如下:

 (1000001, 'AAAA', 'AAAAAAAAAA','         1')

第一列是一個序列,第二列從AAAA到EEEE循環,第三列從AAAAAAAAAA到JJJJJJJJJJ循環,最后一列是10個字符,從1-50循環(占位符用"\ "表示)。然后我生成800行數據。由于我創建數據的方法問題,第一個數據塊中有11行數據,第二第三列都是A,所以我需要運行如下sql然后dump表中的第一個塊來觀察發生了什么。

update t1

set

        vc_rep = 'BBBB'

where

        vc_rep = 'AAAA'

and     vc_cycle = 'AAAAAAAAAA'

and     rownum <= 4

;

這證明了這個塊里有足夠的空間來更新這兩行記錄,而且始終在同一個塊里,但是我的行還是發生了遷移。這里有這個數據塊中某行在操作前后的dump數據對比:

tab 1, row 0, @0x1bb8 -- before

tl: 11 fb: --H-FL-- lb: 0x0 cc: 4

col 0: [ 4] 41 41 41 41

col 1: [10] 41 41 41 41 41 41 41 41 41 41

col 2: [10] 20 20 20 20 20 20 20 20 20 31

col 3: [ 5] c4 02 01 01 02

bindmp: 2c 00 02 03 1b cd c4 02 01 01 02


tab 1, row 0, @0x4f3 -- after

tl: 37 fb: --H-FL-- lb: 0x2 cc: 4

col 0: [ 4] 42 42 42 42

col 1: [10] 41 41 41 41 41 41 41 41 41 41

col 2: [10] 20 20 20 20 20 20 20 20 20 31

col 3: [ 5] c4 02 01 01 02

bindmp: 2c 02 04 00 cc 42 42 42 42 d2 41 41 41 41 41 41 41 41 41 41 d2 20 20 20 20 20 20 20 20 20 31 cd c4 02 01 01 02

在update操作后,Oracle將該行擴展成了完整的四列數據。有兩個標志在字典表中,可以被用來替換更新的這行記錄的前兩個字段。但是Oracle并沒有去試圖尋找并使用這些標志。所以,這么看來,好像update壓縮的數據就會造成整體的混亂,一行壓縮的記錄可能會擴展的及其巨大,微不足道的那點空閑空間無法裝下這些數據,最終引發了行的遷移。

雖然我們現在看來,當出現擴展的行以及遷移的行之后,數據會有點混亂。但當我們執行回滾操作時,Oracle會把這些混亂清理干凈,而且剩余的行也都會在原始壓縮的、未遷移的位置。

所以update操作到底能造成多么糟糕的影響?回答這個問題之前,我們可以先看下我所做的update操作。我修改了一個標志可以代替的值,而且該值在很多行中都存在。但如果我修改了一個標志無法代替的值呢?Oracle還會因為這個update來擴展這行記錄嗎?答案是否定的。如果我們修改了ID(序列類型,不重復,無法標志化)的值。下面是修改前會的dump數據對比:

tab 1, row 0, @0x1bb8 -- before

tl: 11 fb: --H-FL-- lb: 0x0 cc: 4

col 0: [ 4] 41 41 41 41

col 1: [10] 41 41 41 41 41 41 41 41 41 41

col 2: [10] 20 20 20 20 20 20 20 20 20 31

col 3: [ 5] c4 02 01 01 02

bindmp: 2c 00 02 03 1b cd c4 02 01 01 02


tab 1, row 0, @0x1bb8 -- after

tl: 10 fb: --H-FL-- lb: 0x2 cc: 4

col 0: [ 4] 41 41 41 41

col 1: [10] 41 41 41 41 41 41 41 41 41 41

col 2: [10] 20 20 20 20 20 20 20 20 20 31

col 3: [ 4] c3 64 64 64

bindmp: 2c 02 02 03 1b cc c3 64 64 64

update操作后的數據依然在原來的位置,并未發生遷移。但是請注意該行由一個可代表前三行的標志和一個實際的值組成。行擴展并未發生。

我初始測試的那行數據實際上整行都可以被一個標志所代替。如果我更新一個被多個標志組合起來的行中的某個標志化的字段會怎樣?Oracle并不會擴展整行——它只會擴展update操作影響的那列的數據。這里是操作前后的dump數據:

tab 1, row 18, @0x1ac2

tl: 13 fb: --H-FL-- lb: 0x0 cc: 4

col 0: [ 4] 44 44 44 44

col 1: [10] 58 58 58 58 58 58 58 58 58 58

col 2: [10] 20 20 20 20 20 20 20 20 33 34

col 3: [ 5] c4 02 01 01 14

bindmp: 2c 00 04 03 32 37 45 cd c4 02 01 01 14


tab 1, row 18, @0x1ab8

tl: 23 fb: --H-FL-- lb: 0x2 cc: 4

col 0: [ 4] 44 44 44 44

col 1: [10] 59 59 59 59 59 59 59 59 59 59

col 2: [10] 20 20 20 20 20 20 20 20 33 34

col 3: [ 5] c4 02 01 01 14

bindmp: 2c 02 04 00 32 d2 59 59 59 59 59 59 59 59 59 59 45 cd c4 02 01 01 14

在這個測試的最開始,dump數據就表明了這行由三個獨立的標志(0x32, 0x37和0x45)和一個實際數值組成。我將第一列的值‘XXXXXXXXXX’更新為‘YYYYYYYYYY’,正如你所見,最后一塊dump數據依然包含標志0x32和0x45,但是標志0x37已經被實際值所替換掉。你也可以看到行的長度增加了10字節(從13b增加到23b),這意味著Oracle不得不把它移動到那很小的一部分空閑空間中,所以最終行的地址發生了變化。

所以當你試圖更新基礎表壓縮中的數據時,Oracle可能將標志擴展為實際值,但它會盡可能的做最小化的擴展。即使數據在壓縮后pctfree為0的情況下數據塊中依然有一小部分空間。所以雖然你可以在不造成大量擴展以及行遷移的情況下做一些極小量的update操作,但這些副作用幾乎不可能被預知。

如果你確實需要對已壓縮的數據做一些小量的維護操作,就需要對實際數據做足夠多的測試來尋找最合適的pctfree的值,以將行遷移率控制在可接受的范圍。

關于“Oracle如何修改壓縮數據”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安新县| 太谷县| 巩义市| 小金县| 曲周县| 南开区| 嘉峪关市| 加查县| 黄陵县| 揭东县| 荆门市| 佳木斯市| 鄂托克旗| 麻阳| 武平县| 乃东县| 乌兰浩特市| 汝阳县| 望谟县| 阿合奇县| 遂川县| 兴业县| 丁青县| 安西县| 内丘县| 常山县| 大渡口区| 和政县| 临桂县| 砚山县| 海阳市| 长丰县| 家居| 什邡市| 泰顺县| 鄂托克前旗| 盖州市| 徐闻县| 壶关县| 安阳市| 壤塘县|