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,研發注意事項(12) - NULL與索引OracleSQLNull索引
- Oracle vs PostgreSQL,研發注意事項(5)- 字元型別OracleSQL字元型別
- 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
- ORACLE 死事務的回滾Oracle
- sqlserver遇到回滾事務的操作策略SQLServer
- oracle檢視回滾的事務Oracle
- SQL Server 事務及回滾事務SQLServer
- java 事務提交/回滾Java
- Shrink操作的注意事項
- zt_Oracle事務rollback回滾時間估算Oracle
- @Transactional spring 配置事務 注意事項Spring
- Spring事務回滾情況Spring
- 深入解析 PostgreSQL 系列之併發控制與事務機制SQL
- 客戶端登陸logout操作,事務回滾客戶端Go
- Spring中@Transactional事務回滾例項及原始碼Spring原始碼
- Oracle使用*的注意事項Oracle
- 關於ORACLE大型事務回滾的幾個點Oracle
- 關於事務回滾註解@Transactional
- ios開發注意事項iOS
- oracle必須注意事務Oracle
- 【C++注意事項】3 引用C++
- oracle 轉pg 的注意事項Oracle
- oracle移植到mysql注意事項OracleMySql
- PostgreSQL:事務SQL
- openGauss 子事務併發回滾流程最佳化
- Unity3d遊戲開發注意事項Unity3D遊戲開發
- 不能回滾的Redis事務還能用嗎Redis
- MySQL實現事務的提交和回滾MySql
- JDBC 事務(二)回滾到儲存點JDBC