Oracle vs PostgreSQL,研發注意事項(3)- 事務回滾之UPDATE操作解析
Oracle事務的回滾,透過回滾段儲存原有資料實現,但,PG沒有回滾段!以下以Update操作為例,說明PG實現機制上存在的空間暴漲問題。
在執行Update時,Oracle就地更新,如出現原block空間不足的情況,透過link的方式連結至新block上(不精確,大體表述);PG的Update,不是原地更新,而是保留原有資料,透過新增新的tuple(資料行)儲存新增資料,原有資料透過Vacuum機制清理。Vacuum機制需要滿足MVCC(多版本併發控制)的要求,在某些情況下,不會清理“垃圾”資料,在事務繁忙的時候導致會導致資料表空間不斷增長。
--------------------------- Session A
-- 開啟事務
begin;
-- 查詢當前事務
select txid_current();
txid_current
--------------
1500987
(1 row)
-- 什麼都不做,會導致Vacuum不能清理“垃圾”資料
--------------------------- Session B
-- 開啟事務
begin;
select txid_current();
txid_current
--------------
1500988
(1 row)
-- 建立表&插入100資料
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)
-- 提交事務
end;
-- 檢視資料表
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
......
-- 檢視資料佔用空間
\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進行壓力測試,不斷更新資料
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
-- 一段時間後檢視資料佔用空間
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實現機制導致的:如果存在某個事務,在更新資料前開啟,那麼更新資料時前後的資料都要儲存,無論更新多少次都要儲存!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6906/viewspace-2158216/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle vs PostgreSQL,研發注意事項(13) - UPDATE語句OracleSQL
- Oracle vs PostgreSQL,研發注意事項(6)- 事務處理OracleSQL
- Oracle vs PostgreSQL,研發注意事項(2)-DDL語句與事務OracleSQL
- Oracle vs PostgreSQL,研發注意事項(5)- 字元型別OracleSQL字元型別
- Oracle vs PostgreSQL,研發注意事項(12) - NULL與索引OracleSQLNull索引
- Oracle vs PostgreSQL,研發注意事項(7)- 型別轉換OracleSQL型別
- Oracle vs PostgreSQL,研發注意事項(1)-查詢鎖表OracleSQL
- Oracle vs PostgreSQL,研發注意事項(11)- PostgreSQL資料型別轉換規則#3OracleSQL資料型別
- Oracle vs PostgreSQL,研發注意事項(8)- Oracle資料比較規則OracleSQL
- Oracle vs PostgreSQL,研發注意事項(10)- PostgreSQL資料型別轉換規則#2OracleSQL資料型別
- Oracle vs PostgreSQL,研發注意事項(9)- PostgreSQL資料型別轉換規則#1OracleSQL資料型別
- Oracle vs PostgreSQL,研發注意事項(4)- PageSize對資料儲存的影響OracleSQL
- sqlserver遇到回滾事務的操作策略SQLServer
- Oracle使用*的注意事項Oracle
- 客戶端登陸logout操作,事務回滾客戶端Go
- 關於ORACLE大型事務回滾的幾個點Oracle
- Oracle 資料匯出注意事項Oracle
- Oracle臨時表使用注意事項Oracle
- 深入解析 PostgreSQL 系列之併發控制與事務機制SQL
- [Android開發] 注意事項Android
- 關於事務回滾註解@Transactional
- openGauss 子事務併發回滾流程最佳化
- Oracle:記憶體設定注意事項Oracle記憶體
- Oracle 巢狀事務 VS 自治事務Oracle巢狀
- 灑水車操作指南和注意事項
- Latex寫作常用操作和注意事項
- PureComponent 使用注意事項以及原始碼解析原始碼
- netcore後臺任務注意事項NetCore
- RandomAccessFile注意事項randomMac
- @Lombok注意事項Lombok
- vs.net 2003水晶報表部署注意事項
- SQLServer 物件建立注意事項之dboSQLServer物件
- Spring Data JPA中事務回滾意外RollbackExceptionSpringException
- MySQL實現事務的提交和回滾MySql
- 不能回滾的Redis事務還能用嗎Redis
- 【ASM】Oracle asm刪除磁碟組注意事項ASMOracle
- 記在 Hyperf 中多庫連線操作事務注意事項
- PostgreSQL:事務SQL