summaryrefslogtreecommitdiff
path: root/src/include/gtm/gtm_txn.h
blob: ee3d0a1f0b072e1a17e24a3cd50b0aafb23b208f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*-------------------------------------------------------------------------
 *
 * gtm_txn.h
 *
 *
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 * Portions Copyright (c) 2010-2012 Postgres-XC Development Group
 *
 * $PostgreSQL$
 *
 *-------------------------------------------------------------------------
 */
#ifndef _GTM_TXN_H
#define _GTM_TXN_H

#include "gtm/libpq-be.h"
#include "gtm/gtm_c.h"
#include "gtm/gtm_gxid.h"
#include "gtm/gtm_lock.h"
#include "gtm/gtm_list.h"
#include "gtm/stringinfo.h"


typedef int XidStatus;

#define TRANSACTION_STATUS_IN_PROGRESS      0x00
#define TRANSACTION_STATUS_COMMITTED        0x01
#define TRANSACTION_STATUS_ABORTED          0x02

struct GTM_RestoreContext;

/* gtm/main/gtm_txn.c */
extern GlobalTransactionId GTM_GetGlobalTransactionId(GTM_TransactionHandle handle);
extern GlobalTransactionId GTM_ReadNewGlobalTransactionId(void);
extern void GTM_SetNextGlobalTransactionId(GlobalTransactionId gxid);
extern void GTM_SetControlXid(GlobalTransactionId gxid);
extern void GTM_SetShuttingDown(void);

/* for restoration point backup (gtm/main/gtm_backup.c) */
extern void GTM_WriteRestorePointXid(FILE *f);
extern void GTM_WriteRestorePointVersion(FILE *f);
extern void GTM_RestoreStart(FILE *ctlf, struct GTM_RestoreContext *context);
extern void GTM_SaveTxnInfo(FILE *ctlf);
extern void GTM_RestoreTxnInfo(FILE *ctlf, GlobalTransactionId next_gxid,
						struct GTM_RestoreContext *context, bool force_xid);


/* States of the GTM component */
typedef enum GTM_States
{
	GTM_STARTING,
	GTM_RUNNING,
	GTM_SHUTTING_DOWN
} GTM_States;

/* Global transaction states at the GTM */
typedef enum GTM_TransactionStates
{
	GTM_TXN_STARTING,
	GTM_TXN_IN_PROGRESS,
	GTM_TXN_PREPARE_IN_PROGRESS,
	GTM_TXN_PREPARED,
	GTM_TXN_COMMIT_IN_PROGRESS,
	GTM_TXN_COMMITTED,
	GTM_TXN_ABORT_IN_PROGRESS,
	GTM_TXN_ABORTED
} GTM_TransactionStates;

#define GTM_MAX_SESSION_ID_LEN			64

/* Information about a global transaction tracked by the GTM */
typedef struct GTM_TransactionInfo
{
	GTM_TransactionHandle	gti_handle;
	uint32					gti_client_id;
	char					gti_global_session_id[GTM_MAX_SESSION_ID_LEN];
	bool					gti_in_use;
	GlobalTransactionId		gti_gxid;
	GTM_TransactionStates	gti_state;
	GlobalTransactionId		gti_xmin;
	GTM_IsolationLevel		gti_isolevel;
	bool					gti_readonly;
	GTMProxy_ConnID			gti_proxy_client_id;
	char					*nodestring; /* List of nodes prepared */
	char					*gti_gid;

	GTM_SnapshotData		gti_current_snapshot;
	bool					gti_snapshot_set;

	GTM_RWLock				gti_lock;
	bool					gti_vacuum;
	gtm_List				*gti_created_seqs;
	gtm_List				*gti_dropped_seqs;
	gtm_List				*gti_altered_seqs;
} GTM_TransactionInfo;

/* By default a GID length is limited to 256 bits in PostgreSQL */
#define GTM_MAX_GID_LEN					256
#define GTM_MAX_NODESTRING_LEN			1024
#define GTM_CheckTransactionHandle(x)	((x) >= 0 && (x) < GTM_MAX_GLOBAL_TRANSACTIONS)
#define GTM_IsTransSerializable(x)		((x)->gti_isolevel == GTM_ISOLATION_SERIALIZABLE)

/* Array of all global transactions tracked by the GTM */
typedef struct GTM_Transactions
{
	uint32				gt_txn_count;
	GTM_States			gt_gtm_state;

	GTM_RWLock			gt_XidGenLock;

	/*
	 * These fields are protected by XidGenLock
	 */
	GlobalTransactionId gt_nextXid;		/* next XID to assign */
	GlobalTransactionId gt_backedUpXid;	/* backed up, restoration point */

	GlobalTransactionId gt_oldestXid;	/* cluster-wide minimum datfrozenxid */
	GlobalTransactionId gt_xidVacLimit;	/* start forcing autovacuums here */
	GlobalTransactionId gt_xidWarnLimit; /* start complaining here */
	GlobalTransactionId gt_xidStopLimit; /* refuse to advance nextXid beyond here */
	GlobalTransactionId gt_xidWrapLimit; /* where the world ends */

	/*
	 * These fields are protected by TransArrayLock.
	 */
	GlobalTransactionId gt_latestCompletedXid;	/* newest XID that has committed or
										 		 * aborted */

	GlobalTransactionId	gt_recent_global_xmin;

	int32				gt_lastslot;
	GTM_TransactionInfo	gt_transactions_array[GTM_MAX_GLOBAL_TRANSACTIONS];
	gtm_List			*gt_open_transactions;

	GTM_RWLock			gt_TransArrayLock;
} GTM_Transactions;

extern GTM_Transactions	GTMTransactions;

/*
 * Two hash tables will be maintained to quickly find the
 * GTM_TransactionInfo block given either the GXID or the GTM_TransactionHandle.
 *
 * XXX seems we don't actually have the hash tables, and we simply lookup the
 * transactions by index (handle) or by walking through open transactions and
 * checking the GXID.
 */

GTM_TransactionInfo *GTM_HandleToTransactionInfo(GTM_TransactionHandle handle);
GTM_TransactionHandle GTM_GXIDToHandle(GlobalTransactionId gxid);

/* Transaction Control */
void GTM_InitTxnManager(void);
void GTM_RemoveAllTransInfos(uint32 client_id, int backend_id);
uint32 GTM_GetLastClientIdentifier(void);

/* processing of messages in gtm_txn.c */
void ProcessBeginTransactionCommand(Port *myport, StringInfo message);
void ProcessBkupBeginTransactionCommand(Port *myport, StringInfo message);
void ProcessBeginTransactionGetGXIDCommand(Port *myport, StringInfo message);
void ProcessCommitTransactionCommand(Port *myport, StringInfo message, bool is_backup);
void ProcessCommitTransactionCommandMulti(Port *myport, StringInfo message, bool is_backup);
void ProcessCommitPreparedTransactionCommand(Port *myport, StringInfo message, bool is_backup);
void ProcessRollbackTransactionCommand(Port *myport, StringInfo message, bool is_backup);
void ProcessStartPreparedTransactionCommand(Port *myport, StringInfo message, bool is_backup);
void ProcessPrepareTransactionCommand(Port *myport, StringInfo message, bool is_backup);
void ProcessGetGIDDataTransactionCommand(Port *myport, StringInfo message);
void ProcessGetGXIDTransactionCommand(Port *myport, StringInfo message);
void ProcessGXIDListCommand(Port *myport, StringInfo message);
void ProcessGetNextGXIDTransactionCommand(Port *myport, StringInfo message);
void ProcessReportXminCommand(Port *myport, StringInfo message, bool is_backup);

void ProcessBeginTransactionGetGXIDAutovacuumCommand(Port *myport, StringInfo message);
void ProcessBkupBeginTransactionGetGXIDAutovacuumCommand(Port *myport, StringInfo message);

void ProcessBeginTransactionGetGXIDCommandMulti(Port *myport, StringInfo message);
void ProcessRollbackTransactionCommandMulti(Port *myport, StringInfo message, bool is_backup) ;

void ProcessBkupBeginTransactionGetGXIDCommand(Port *myport, StringInfo message);
void ProcessBkupBeginTransactionGetGXIDCommandMulti(Port *myport, StringInfo message);


/*
 * In gtm_snap.c
 */
void ProcessGetSnapshotCommand(Port *myport, StringInfo message, bool get_gxid);
void ProcessGetSnapshotCommandMulti(Port *myport, StringInfo message);
void GTM_RememberDroppedSequence(GlobalTransactionId gxid, void *seq);
void GTM_ForgetCreatedSequence(GlobalTransactionId gxid, void *seq);
void GTM_RememberCreatedSequence(GlobalTransactionId gxid, void *seq);
void GTM_RememberAlteredSequence(GlobalTransactionId gxid, void *seq);

#endif