什么是子事务?
子事务的使用
test=> BEGIN;BEGINtest=*> SELECT 'Some work is done';?column?-------------------Some work is done(1 row)test=*> SELECT 12 (factorial(0) - 1);ERROR: division by zerotest=!> SELECT 'try to do more work';ERROR: current transaction is aborted, commands ignored until end of transaction blocktest=!> COMMIT;ROLLBACK
test=> BEGIN;BEGINtest=*> SELECT 'Some work is done';?column?-------------------Some work is done(1 row)test=*> SAVEPOINT a;SAVEPOINTtest=*> SELECT 12 (factorial(0) - 1);ERROR: division by zerotest=!> ROLLBACK TO SAVEPOINT a;ROLLBACKtest=*> SELECT 'try to do more work';?column?---------------------try to do more work(1 row)test=*> COMMIT;COMMIT
PL/pgSQL中子事务
BEGINPERFORM 'Some work is done';BEGIN -- a block inside a blockPERFORM 12 (factorial(0) - 1);EXCEPTIONWHEN division_by_zero THENNULL; -- ignore the errorEND;PERFORM 'try to do more work';END;
数据库之间兼容性
性能测试用例
CREATE UNLOGGED TABLE contend (id integer PRIMARY KEY,val integer NOT NULL)WITH (fillfactor='50');INSERT INTO contend (id, val)SELECT i, 0FROM generate_series(1, 10000) AS i;VACUUM (ANALYZE) contend;
BEGIN;PREPARE sel(integer) ASSELECT count(*)FROM contendWHERE id BETWEEN $1 AND $1 + 100;PREPARE upd(integer) ASUPDATE contend SET val = val + 1WHERE id IN ($1, $1 + 10, $1 + 20, $1 + 30);SAVEPOINT a;\set rnd random(1,990)EXECUTE sel(10 * :rnd + :client_id + 1);EXECUTE upd(10 * :rnd + :client_id);SAVEPOINT a;\set rnd random(1,990)EXECUTE sel(10 * :rnd + :client_id + 1);EXECUTE upd(10 * :rnd + :client_id);...SAVEPOINT a;\set rnd random(1,990)EXECUTE sel(10 * :rnd + :client_id + 1);EXECUTE upd(10 * :rnd + :client_id);DEALLOCATE ALL;COMMIT;
性能测试
pgbench -f subtrans.sql -n -c 6 -T 600transaction type: subtrans.sqlscaling factor: 1query mode: simplenumber of clients: 6number of threads: 1duration: 600 snumber of transactions actually processed: 100434latency average = 35.846 mstps = 167.382164 (including connections establishing)tps = 167.383187 (excluding connections establishing)
下面是在测试运行中,使用“perf top --no-children --call-graph=fp --dsos=/usr/pgsql-12/bin/postgres”命令展示的信息
+ 1.86% [.] tbm_iterate+ 1.77% [.] hash_search_with_hash_value1.75% [.] AllocSetAlloc+ 1.36% [.] pg_qsort+ 1.12% [.] base_yyparse+ 1.10% [.] TransactionIdIsCurrentTransactionId+ 0.96% [.] heap_hot_search_buffer+ 0.96% [.] LWLockAttemptLock+ 0.85% [.] HeapTupleSatisfiesVisibility+ 0.82% [.] heap_page_prune+ 0.81% [.] ExecInterpExpr+ 0.80% [.] SearchCatCache1+ 0.79% [.] BitmapHeapNext+ 0.64% [.] LWLockRelease+ 0.62% [.] MemoryContextAllocZeroAligned+ 0.55% [.]_bt_checkkeys0.54% [.] hash_any+ 0.52% [.] _bt_compare0.51% [.] ExecScan
pgbench -f subtrans.sql -n -c 6 -T 600transaction type: subtrans.sqlscaling factor: 1query mode: simplenumber of clients: 6number of threads: 1duration: 600 snumber of transactions actually processed: 41400latency average = 86.965 mstps = 68.993634 (including connections establishing)tps = 68.993993 (excluding connections establishing)
+ 10.59% [.] LWLockAttemptLock+ 7.12% [.] LWLockRelease+ 2.70% [.] LWLockAcquire+ 2.40% [.] SimpleLruReadPage_ReadOnly+ 1.30% [.] TransactionIdIsCurrentTransactionId+ 1.26% [.] tbm_iterate+ 1.22% [.] hash_search_with_hash_value+ 1.08% [.] AllocSetAlloc+ 0.77% [.] heap_hot_search_buffer+ 0.72% [.] pg_qsort+ 0.72% [.] base_yyparse+ 0.66% [.] SubTransGetParent+ 0.62% [.] HeapTupleSatisfiesVisibility+ 0.54% [.] ExecInterpExpr+ 0.51% [.] SearchCatCache1
子事务实现
子事务和可见性
结果分析
分析子事务太多问题
除了查看”perf top”,还有其它指向该问题方向的可疑点:
结论
子事务是一个很好的工具,但是需要合理使用它。如果需要并发,每个事务不要启动超过64个子事务。

文章转载自PostgreSQL中文社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




