Oracle vs PostgreSQL,研發(fā)注意事項(3)- 事務(wù)回滾之UPDATE操作解析

Oracle事務(wù)的回滾,通過回滾段保存原有數(shù)據(jù)實現(xiàn),但,PG沒有回滾段!以下以Update操作為例,說明PG實現(xiàn)機制上存在的空間暴漲問題。

在執(zhí)行Update時,Oracle就地更新,如出現(xiàn)原block空間不足的情況,通過link的方式鏈接至新block上(不精確,大體表述);PG的Update,不是原地更新,而是保留原有數(shù)據(jù),通過新增新的tuple(數(shù)據(jù)行)保存新增數(shù)據(jù),原有數(shù)據(jù)通過Vacuum機制清理。Vacuum機制需要滿足MVCC(多版本并發(fā)控制)的要求,在某些情況下,不會清理“垃圾”數(shù)據(jù),在事務(wù)繁忙的時候?qū)е聲?dǎo)致數(shù)據(jù)表空間不斷增長。

--------------------------- Session A

-- 開啟事務(wù)

begin;

-- 查詢當(dāng)前事務(wù)

select txid_current();

txid_current

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

? ? ? 1500987

(1 row)

-- 什么都不做,會導(dǎo)致Vacuum不能清理“垃圾”數(shù)據(jù)

--------------------------- Session B

-- 開啟事務(wù)

begin;

select txid_current();

txid_current

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

? ? ? 1500988

(1 row)

-- 創(chuàng)建表&插入100數(shù)據(jù)

drop table if exists t1;

create table t1(id int,c1 varchar(50));

insert into t1 select generate_series(1,100),'#TESTDATA#';

------------------- 以上操作省略輸出

select txid_current();

txid_current

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

? ? ? 1500988

(1 row)

-- 提交事務(wù)

end;

-- 查看數(shù)據(jù)表

select ctid, xmin, xmax, cmin, cmax,id from t1;

testdb=# select ctid, xmin, xmax, cmin, cmax,id from t1;

? ctid? |? xmin? | xmax | cmin | cmax | id?

---------+---------+------+------+------+-----

(0,1)? | 1500988 |? ? 0 |? ? 4 |? ? 4 |? 1

(0,2)? | 1500988 |? ? 0 |? ? 4 |? ? 4 |? 2

(0,3)? | 1500988 |? ? 0 |? ? 4 |? ? 4 |? 3

(0,4)? | 1500988 |? ? 0 |? ? 4 |? ? 4 |? 4

......

-- 查看數(shù)據(jù)占用空間

\set v_tablename t1

SELECT pg_size_pretty( pg_total_relation_size(:'v_tablename') );

testdb=# SELECT pg_size_pretty( pg_total_relation_size(:'v_tablename') );

pg_size_pretty

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

8192 bytes

(1 row)


-- 使用pgbench進行壓力測試,不斷更新數(shù)據(jù)

cat update.sql

\set rowid random(1,100)

begin;

update t1 set c1=c1||:rowid where id= :rowid;

end;

pgbench -c 2 -C -f ./update.sql -j 1 -n -T 600 -U xdb testdb


-- 一段時間后查看數(shù)據(jù)占用空間

SELECT pg_size_pretty( pg_total_relation_size(:'v_tablename') );

testdb=# SELECT pg_size_pretty( pg_total_relation_size(:'v_tablename') );

pg_size_pretty

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

? 1344 kB

(1 row)

從原來的8192 Bytes變成了1344 KB,空間“暴漲”。

究其原因,是因為PG的MVCC實現(xiàn)機制導(dǎo)致的:如果存在某個事務(wù),在更新數(shù)據(jù)前開啟,那么更新數(shù)據(jù)時前后的數(shù)據(jù)都要存儲,無論更新多少次都要存儲!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,914評論 0 13
  • Oracle數(shù)據(jù)庫,查詢語句不會鎖表,但PostgreSQL在開啟事務(wù)后,查詢數(shù)據(jù)表會鎖表,在試圖DROP/TRU...
    EthanHe閱讀 1,218評論 2 2
  • 內(nèi)容簡介 有一只100萬年也不死的貓,它死了100萬次,又活了100萬次。有100萬個人寵愛過它,有100萬個...
    寂寞找煙抽閱讀 238評論 0 1
  • 形式:線上 議題:親子關(guān)系 案主的兒子上初三,目前厭學(xué),這個周直接沒有上學(xué)。想看看孩子不愛上學(xué)到底卡在哪兒了呢? ...
    宓兒_2b3e閱讀 346評論 0 1
  • 一 四五歲的小海子天天和一群小伙伴在街道里瘋玩,到了吃飯時候,總會有某個孩子的家長扯著大嗓門喊:梅子...
    海藍(lán)26閱讀 1,492評論 7 5

友情鏈接更多精彩內(nèi)容