当前位置:网站首页>PostgreSQL source code (60) transaction system summary

PostgreSQL source code (60) transaction system summary

2022-07-07 07:12:00 mingjie73

relevant

《Postgresql Source code (23)Clog The use of Slru Page elimination mechanism 》

《Postgresql Source code (27) Why does the transaction commit pass delayChkpt Blocking checkpoint》

《Postgresql Source code (59) Business ID Summary of value taking and judgment rules 》

To recapitulate PG Transaction management system :

  • PG The transaction processing in can be divided into two parts according to the functions provided : Basic transaction state management 、 Sub transaction state management .

  • PG The transaction system of can be summed up in one sentence : User commands trigger state machine functions, resulting in transaction state flow , Call the underlying transaction processing function to work according to the corresponding state during flow .

1 State machine flow system

User commands trigger state machine functions, resulting in transaction state flow , Call the underlying transaction processing function to work according to the corresponding state during flow .

State machine flow function

12 A state machine flow function , It can be divided into three categories .

  • Package all single lines SQL Two functions of ( Get into SQL front StartTransactionCommand、SQL After execution CommitTransactionCommand), No matter what you do begin、 still select 1, I will walk through these two functions . It is equivalent to the passive flow of transaction state .
b StartTransactionCommand
b CommitTransactionCommand
  • Transaction block processing function , Corresponding to user transaction commands , stay PortalRun It calls , Active circulation transaction status .
//  System internal call rollback 
b AbortCurrentTransaction
//  User execution begin
b BeginTransactionBlock
//  User execution commit
b EndTransactionBlock
//  User execution rollback、abort
b UserAbortTransactionBlock
  • Sub transaction status flow .
b DefineSavepoint
b ReleaseSavepoint
b RollbackToSavepoint
b BeginInternalSubTransaction
b RollbackAndReleaseCurrentSubTransaction
b AbortOutOfAnyTransaction

The underlying transaction processing function

When the state machine flows, it will call the underlying function to work , There are two types of functions

  • Basic transaction function
//  Called when the transaction is started , Configure transaction status , Apply for resources 
StartTransaction
//  The normal commit of a transaction is to call 
CommitTransaction
//  Called when the transaction is rolled back , First tune AbortTransaction, In tune CleanupTransaction
CleanupTransaction
//  Called when the transaction is rolled back 
AbortTransaction
  • Sub transaction function
StartSubTransaction
CommitSubTransaction
AbortSubTransaction
CleanupSubTransaction
Inner transaction processing function
Outer state machine flow function
StartTransaction
CommitTransaction
CleanupTransaction
AbortTransaction
StartTransactionCommand
CommitTransactionCommand

2 What does the underlying transaction function do ?

StartTransaction

  1. Get vxid( from backendid and localid Combination value ) Represents a virtual transaction id( Writing hasn't happened yet , Cannot assign real xid)
  2. use vxid register MyProc, After registration, you can find vxid lock , Indicates that the transaction started
  3. The transaction status flows to TRANS_INPROGRESS
StartTransaction
  // vxid = {backendId = 3, localTransactionId = 76407}
  GetNextLocalTransactionId
  VirtualXactLockTableInsert
  ...
  s->state = TRANS_INPROGRESS;
  ...

CommitTransaction( There are write operations in the transaction )

Assigned transactions ID Scene

  1. Transaction status flow TRANS_COMMIT
  2. Open for checkpoint The critical area of :MyProc->delayChkpt = true(《Postgresql Source code (27) Why does the transaction commit pass delayChkpt Blocking checkpoint》
  3. Write commit Transaction log for 、 Brush the transaction log
  4. Write clog( Don't brush )TransactionIdCommitTree
  5. clear ProcArray Medium xid Information
  6. Clean up other
  7. Transaction status flow TRANS_DEFAULT
CommitTransaction
  s->state = TRANS_COMMIT
  RecordTransactionCommit
    [START_CRIT_SECTION]
    [[MyProc->delayChkpt = true]]
    XactLogCommitRecord
    XLogFlush
    TransactionIdCommitTree
    [[MyProc->delayChkpt = false]]
    [END_CRIT_SECTION]
  ProcArrayEndTransaction
    //  Can get the lock and clean it normally , Can't get the lock and add list It's waiting to be cleaned up later 
    LWLockConditionalAcquire(ProcArrayLock, LW_EXCLUSIVE)
      //  Normal cleaning : clear MyProc and ProcGlobal It records xid Information 
      ProcArrayEndTransactionInternal
  ...
  //  clear 
  ...
  s->state = TRANS_DEFAULT

CommitTransaction( There is no write operation in the transaction )

Unassigned transaction ID

  1. Transaction status flow TRANS_COMMIT
  2. clear
  3. Transaction status flow TRANS_DEFAULT
CommitTransaction
  s->state = TRANS_COMMIT
  RecordTransactionCommit // do nothing
  //  clear 
  s->state = TRANS_DEFAULT

3 Business ID Distribute

Before you really want to write data , Would call GetCurrentTransactionId, such as heap_insert.

  1. Take a new one xid
  2. Configuration to MyProc->xid
  3. Configuration to ProcGlobal->xids[MyProc->pgxactoff]
  4. xid Lock XactLockTableInsert
TransactionId
GetCurrentTransactionId(void)
{
    
	TransactionState s = CurrentTransactionState;

	if (!FullTransactionIdIsValid(s->fullTransactionId))
		AssignTransactionId(s);
	return XidFromFullTransactionId(s->fullTransactionId);
}

If not assigned , perform AssignTransactionId Take a new one xid Assigned to TransactionState. Refer to this article (《Postgresql Source code (59) Business ID Summary of value taking and judgment rules 》

AssignTransactionId
  ...
  GetNewTransactionId
    ...
    MyProc->xid = xid;
    ProcGlobal->xids[MyProc->pgxactoff] = xid;
    ...
  XactLockTableInsert
  ...

4 Sub transaction system

Example :

drop table t1;
create table t1 (c1 int, c2 int);
begin;
insert into t1 values (1,1);
savepoint a;
insert into t1 values (2,1);
savepoint b;
insert into t1 values (3,1);

Here are some differences with ordinary affairs :

State of affairs : Sub transactions will make CurrentTransactionState It has a multi-layer structure , Used between parent Connect .

p *CurrentTransactionState
$39 = {fullTransactionId = {value = 4000071}, subTransactionId = 3, name = 0x199ca60 "b", savepointLevel = 0, 
  state = TRANS_INPROGRESS, blockState = TBLOCK_SUBINPROGRESS, nestingLevel = 3, gucNestLevel = 3, 
  curTransactionContext = 0x19de090, curTransactionOwner = 0x192a458, childXids = 0x0, nChildXids = 0, maxChildXids = 0, 
  prevUser = 10, prevSecContext = 0, prevXactReadOnly = false, startedInRecovery = false, didLogXid = false, 
  parallelModeLevel = 0, chain = false, assigned = false, parent = 0x199c558}

p *CurrentTransactionState->parent
$40 = {fullTransactionId = {value = 4000070}, subTransactionId = 2, name = 0x199c6c0 "a", savepointLevel = 0, 
  state = TRANS_INPROGRESS, blockState = TBLOCK_SUBINPROGRESS, nestingLevel = 2, gucNestLevel = 2, 
  curTransactionContext = 0x19d7200, curTransactionOwner = 0x19164c8, childXids = 0x0, nChildXids = 0, maxChildXids = 0, 
  prevUser = 10, prevSecContext = 0, prevXactReadOnly = false, startedInRecovery = false, didLogXid = true, parallelModeLevel = 0, 
  chain = false, assigned = false, parent = 0xe6a940 <TopTransactionStateData>}

p *CurrentTransactionState->parent->parent
$41 = {fullTransactionId = {value = 4000069}, subTransactionId = 1, name = 0x0, savepointLevel = 0, state = TRANS_INPROGRESS, 
  blockState = TBLOCK_INPROGRESS, nestingLevel = 1, gucNestLevel = 1, curTransactionContext = 0x199c400, 
  curTransactionOwner = 0x191e3e8, childXids = 0x0, nChildXids = 0, maxChildXids = 0, prevUser = 10, prevSecContext = 0, 
  prevXactReadOnly = false, startedInRecovery = false, didLogXid = true, parallelModeLevel = 0, chain = false, assigned = false, 
  parent = 0x0}

Allocating transactions ID when , Each sub transaction will get its own XID.

AssignTransactionId
      ...
  		SubTransSetParent(XidFromFullTransactionId(s->fullTransactionId),
						  XidFromFullTransactionId(s->parent->fullTransactionId));

And put yourself on a higher level xid It was recorded that subtrans in (SLRU Page and CLOG The same mechanism is used , This article is part of 《Postgresql Source code (23)Clog The use of Slru Page elimination mechanism 》).

Sub transaction commit

  1. In addition to the above (CommitTransaction( There are write operations in the transaction )) The steps mentioned
  2. Writing CLOG when , It is different from the case without sub transactions
  3. If there are no sub transactions , direct writing CLOG that will do
  4. When there are sub transactions
    1. Writing CLOG First of all, the sub business XID To configure SUB_COMMITTED State to CLOG in
    2. And then the father XID Configure the submission status of
    3. And then we can deal with the sub business XID The state of the from SUB_COMMITTED Become submitted ( Similar to a two-stage submission )
CommitTransaction
  RecordTransactionCommit
    TransactionIdCommitTree
      TransactionIdSetTreeStatus
        //  One CLOG The page is all done 
        TransactionIdSetPageStatus
          TransactionIdSetPageStatusInternal
            //  every last subxid All configured TRANSACTION_STATUS_SUB_COMMITTED
            for
              TransactionIdSetStatusBit
            //  Configure 
            TransactionIdSetStatusBit
            //  Then configure the submission of sub transactions 
            for
              TransactionIdSetStatusBit
原网站

版权声明
本文为[mingjie73]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207070205187457.html