CUBRID Engine  latest
mvcc.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * mvcc.h - Multi-Version Concurrency Control system (at Server).
21  *
22  */
23 #ifndef _MVCC_H_
24 #define _MVCC_H_
25 
26 #ident "$Id$"
27 
28 #include "log_lsa.hpp"
29 #include "mvcc_active_tran.hpp"
30 #include "recovery.h"
31 #include "storage_common.h"
32 #include "thread_compat.hpp"
33 
34 #include <vector>
35 
36 /* MVCC RECORD HEADER */
39 {
40  INT32 mvcc_flag:8; /* MVCC flags */
41  INT32 repid:24; /* representation id */
42  int chn; /* cache coherency number */
43  MVCCID mvcc_ins_id; /* MVCC insert id */
44  MVCCID mvcc_del_id; /* MVCC delete id */
45  LOG_LSA prev_version_lsa; /* log address of previous version */
46 };
47 #define MVCC_REC_HEADER_INITIALIZER \
48 { 0, 0, NULL_CHN, MVCCID_NULL, MVCCID_NULL, LSA_INITIALIZER }
49 
50 /* MVCC Header Macros */
51 #define MVCC_GET_INSID(header) \
52  ((header)->mvcc_ins_id)
53 
54 #define MVCC_SET_INSID(header, mvcc_id) \
55  ((header)->mvcc_ins_id = (mvcc_id))
56 
57 #define MVCC_GET_DELID(header) \
58  ((header)->mvcc_del_id)
59 
60 #define MVCC_SET_DELID(header, mvcc_id) \
61  ((header)->mvcc_del_id = (mvcc_id))
62 
63 #define MVCC_GET_REPID(header) \
64  ((header)->repid)
65 
66 #define MVCC_SET_REPID(header, rep_id) \
67  ((header)->repid = (rep_id))
68 
69 #define MVCC_GET_CHN(header) \
70  ((header)->chn)
71 
72 #define MVCC_SET_CHN(header, chn_) \
73  ((header)->chn = (chn_))
74 
75 #define MVCC_GET_FLAG(header) \
76  ((header)->mvcc_flag)
77 
78 #define MVCC_SET_FLAG(header, flag) \
79  ((header)->mvcc_flag = (flag))
80 
81 #define MVCC_IS_ANY_FLAG_SET(rec_header_p) \
82  (MVCC_IS_FLAG_SET (rec_header_p, OR_MVCC_FLAG_MASK))
83 
84 #define MVCC_IS_FLAG_SET(rec_header_p, flags) \
85  ((rec_header_p)->mvcc_flag & (flags))
86 
87 #define MVCC_IS_HEADER_DELID_VALID(rec_header_p) \
88  (MVCC_IS_FLAG_SET (rec_header_p, OR_MVCC_FLAG_VALID_DELID) \
89  && MVCCID_IS_VALID (MVCC_GET_DELID (rec_header_p)))
90 
91 #define MVCC_IS_HEADER_INSID_NOT_ALL_VISIBLE(rec_header_p) \
92  (MVCC_IS_FLAG_SET (rec_header_p, OR_MVCC_FLAG_VALID_INSID) \
93  && MVCC_GET_INSID (rec_header_p) != MVCCID_ALL_VISIBLE)
94 
95 #define MVCC_SET_FLAG_BITS(rec_header_p, flag) \
96  ((rec_header_p)->mvcc_flag |= (flag))
97 
98 #define MVCC_CLEAR_ALL_FLAG_BITS(rec_header_p) \
99  (MVCC_CLEAR_FLAG_BITS (rec_header_p, OR_MVCC_FLAG_MASK))
100 
101 #define MVCC_CLEAR_FLAG_BITS(rec_header_p, flag) \
102  ((rec_header_p)->mvcc_flag &= ~(flag))
103 
104 /* MVCC Snapshot Macros */
105 #define MVCC_SNAPSHOT_GET_LOWEST_ACTIVE_ID(snapshot) \
106  ((snapshot)->lowest_active_mvccid)
107 
108 #define MVCC_SNAPSHOT_GET_HIGHEST_COMMITTED_ID(snapshot) \
109  ((snapshot)->highest_completed_mvccid)
110 
111 /* MVCC Record Macros */
112 
113 /* Check if record is inserted by current transaction or its children */
114 #define MVCC_IS_REC_INSERTED_BY_ME(thread_p, rec_header_p) \
115  (logtb_is_current_mvccid (thread_p, (rec_header_p)->mvcc_ins_id))
116 
117 /* Check if record is deleted by current transaction or its children */
118 #define MVCC_IS_REC_DELETED_BY_ME(thread_p, rec_header_p) \
119  (logtb_is_current_mvccid (thread_p, (rec_header_p)->mvcc_del_id))
120 
121 /* Check if record was inserted by the transaction identified by mvcc_id */
122 #define MVCC_IS_REC_INSERTED_BY(rec_header_p, mvcc_id) \
123  ((rec_header_p)->mvcc_ins_id == mvcc_id)
124 
125 /* Check if record was deleted by the transaction identified by mvcc_id */
126 #define MVCC_IS_REC_DELETED_BY(rec_header_p, mvcc_id) \
127  ((rec_header_p)->delid_chn.mvcc_del_id == mvcc_id)
128 
129 /* Check if given CHN is up-to-date according to MVCC header:
130  * 1. Given CHN must be non-NULL.
131  * 2. header CHN matches given CHN.
132  */
133 #define MVCC_IS_CHN_UPTODATE(rec_header_p, chn) \
134  (chn != NULL_CHN \
135  && (chn == MVCC_GET_CHN (rec_header_p)))
136 
137 #define MVCC_ID_PRECEDES(id1, id2) ((id1) < (id2))
138 #define MVCC_ID_FOLLOW_OR_EQUAL(id1, id2) ((id1) >= (id2))
139 
140 #define MVCC_IS_HEADER_PREV_VERSION_VALID(rec_header_p) \
141  (MVCC_IS_FLAG_SET (rec_header_p, OR_MVCC_FLAG_VALID_PREV_VERSION) \
142  && !LSA_ISNULL (&MVCC_GET_PREV_VERSION_LSA (rec_header_p)))
143 
144 #define MVCC_SET_PREVIOUS_VERSION_LSA(header, new_lsa) \
145  do \
146  { \
147  (header)->prev_version_lsa.pageid = (new_lsa)->pageid; \
148  (header)->prev_version_lsa.offset = (new_lsa)->offset; \
149  } \
150  while (0)
151 
152 #define MVCC_GET_PREV_VERSION_LSA(header) \
153  ((header)->prev_version_lsa)
154 
156 {
157  TOO_OLD_FOR_SNAPSHOT, /* not visible, deleted by me or deleted by inactive transaction */
158  SNAPSHOT_SATISFIED, /* is visible and valid */
159  TOO_NEW_FOR_SNAPSHOT /* not visible, inserter is still active.
160  * when looking for visible version, if this is the snapshot result, we have to
161  * check previous versions in log (if there are previous versions).
162  */
163 }; /* Possible results by check versions against snapshots. */
166 
168  MVCC_SNAPSHOT * snapshot);
170 {
171  MVCCID lowest_active_mvccid; /* lowest active id */
172  MVCCID highest_completed_mvccid; /* highest mvccid in snapshot */
173 
175 
176  MVCC_SNAPSHOT_FUNC snapshot_fnc; /* the snapshot function */
177 
178  bool valid; /* true, if the snapshot is valid */
179 
180  // *INDENT-OFF*
181  mvcc_snapshot ();
182  void reset ();
183 
184  mvcc_snapshot &operator= (const mvcc_snapshot& snapshot) = delete;
185 
186  void copy_to (mvcc_snapshot & other) const;
187  // *INDENT-ON*
188 };
189 
190 /* MVCC INFO - such structure is attached to each active transaction */
191 typedef struct mvcc_info MVCC_INFO;
192 struct mvcc_info
193 {
194  MVCC_SNAPSHOT snapshot; /* MVCC Snapshot */
195 
196  /* MVCC ID - increase with each transaction that modified data */
198 
199  /* recent_snapshot_lowest_active_mvccid - the lowest active MVCCID computed for the most recent snapshot of current
200  * transaction. This field help to know faster whether an MVCCID is active or not. Thus, mvccid older than this field
201  * are not active anymore */
203 
204  // *INDENT-OFF*
205  std::vector<MVCCID> sub_ids; /* MVCC sub-transaction ID array */
206  // *INDENT-ON*
207  bool is_sub_active; /* true in case that sub-transaction is running */
208 
209  // *INDENT-OFF*
210  mvcc_info ();
211  void init ();
212  void reset ();
213  // *INDENT-ON*
214 };
215 
217 {
218  DELETE_RECORD_INSERT_IN_PROGRESS, /* invisible - created after scan started */
219  DELETE_RECORD_CAN_DELETE, /* is visible and valid - can be deleted */
220  DELETE_RECORD_DELETED, /* deleted by committed transaction */
221  DELETE_RECORD_DELETE_IN_PROGRESS, /* deleted by other in progress transaction */
222  DELETE_RECORD_SELF_DELETED /* deleted by the current transaction */
223 }; /* Heap record satisfies delete result */
225 
227 {
228  VACUUM_RECORD_REMOVE, /* record can be removed completely */
229  VACUUM_RECORD_DELETE_INSID_PREV_VER, /* record insert MVCCID and prev version lsa can be removed */
230  VACUUM_RECORD_CANNOT_VACUUM /* record cannot be vacuumed because: 1. it was already vacuumed. 2. it was recently
231  * inserted. 3. it was recently deleted and has no insert MVCCID. */
232 }; /* Heap record satisfies vacuum result */
234 
235 /* Definitions used to identify MVCC log records. */
236 // TODO - replace with functions
237 
238 /* Is log record for a heap MVCC operation */
239 #define LOG_IS_MVCC_HEAP_OPERATION(rcvindex) \
240  (((rcvindex) == RVHF_MVCC_DELETE_REC_HOME) \
241  || ((rcvindex) == RVHF_MVCC_INSERT) \
242  || ((rcvindex) == RVHF_UPDATE_NOTIFY_VACUUM) \
243  || ((rcvindex) == RVHF_MVCC_DELETE_MODIFY_HOME) \
244  || ((rcvindex) == RVHF_MVCC_NO_MODIFY_HOME) \
245  || ((rcvindex) == RVHF_MVCC_REDISTRIBUTE))
246 
247 /* Is log record for a b-tree MVCC operation */
248 #define LOG_IS_MVCC_BTREE_OPERATION(rcvindex) \
249  ((rcvindex) == RVBT_MVCC_DELETE_OBJECT \
250  || (rcvindex) == RVBT_MVCC_INSERT_OBJECT \
251  || (rcvindex) == RVBT_MVCC_INSERT_OBJECT_UNQ \
252  || (rcvindex) == RVBT_MVCC_NOTIFY_VACUUM)
253 
254 /* Is log record for a MVCC operation */
255 #define LOG_IS_MVCC_OPERATION(rcvindex) \
256  (LOG_IS_MVCC_HEAP_OPERATION (rcvindex) \
257  || LOG_IS_MVCC_BTREE_OPERATION (rcvindex) \
258  || ((rcvindex) == RVES_NOTIFY_VACUUM))
259 
261  MVCC_SNAPSHOT * snapshot);
263  MVCC_REC_HEADER * rec_header,
264  MVCC_SNAPSHOT * snapshot);
266  MVCCID oldest_mvccid);
268 
270  MVCC_SNAPSHOT * snapshot);
271 extern bool mvcc_is_mvcc_disabled_class (const OID * class_oid);
272 
273 #endif /* _MVCC_H_ */
MVCCID recent_snapshot_lowest_active_mvccid
Definition: mvcc.h:202
enum mvcc_satisfies_delete_result MVCC_SATISFIES_DELETE_RESULT
Definition: mvcc.h:224
MVCCID highest_completed_mvccid
Definition: mvcc.h:172
INT32 mvcc_flag
Definition: mvcc.h:40
MVCCID mvcc_ins_id
Definition: mvcc.h:43
bool is_sub_active
Definition: mvcc.h:207
MVCC_SATISFIES_VACUUM_RESULT mvcc_satisfies_vacuum(THREAD_ENTRY *thread_p, MVCC_REC_HEADER *rec_header, MVCCID oldest_mvccid)
Definition: mvcc.c:309
mvcc_satisfies_snapshot_result
Definition: mvcc.h:155
INT32 repid
Definition: mvcc.h:41
bool valid
Definition: mvcc.h:178
MVCCID id
Definition: mvcc.h:197
MVCCID lowest_active_mvccid
Definition: mvcc.h:171
void THREAD_ENTRY
enum mvcc_satisfies_vacuum_result MVCC_SATISFIES_VACUUM_RESULT
Definition: mvcc.h:233
MVCC_SATISFIES_SNAPSHOT_RESULT mvcc_is_not_deleted_for_snapshot(THREAD_ENTRY *thread_p, MVCC_REC_HEADER *rec_header, MVCC_SNAPSHOT *snapshot)
Definition: mvcc.c:268
mvcc_active_tran m_active_mvccs
Definition: mvcc.h:174
mvcc_satisfies_delete_result
Definition: mvcc.h:216
UINT64 MVCCID
MVCC_SATISFIES_SNAPSHOT_RESULT mvcc_satisfies_dirty(THREAD_ENTRY *thread_p, MVCC_REC_HEADER *rec_header, MVCC_SNAPSHOT *snapshot)
Definition: mvcc.c:501
mvcc_satisfies_vacuum_result
Definition: mvcc.h:226
LOG_LSA prev_version_lsa
Definition: mvcc.h:45
MVCC_SNAPSHOT snapshot
Definition: mvcc.h:194
MVCC_SATISFIES_DELETE_RESULT mvcc_satisfies_delete(THREAD_ENTRY *thread_p, MVCC_REC_HEADER *rec_header)
Definition: mvcc.c:377
MVCC_SNAPSHOT_FUNC snapshot_fnc
Definition: mvcc.h:176
enum mvcc_satisfies_snapshot_result MVCC_SATISFIES_SNAPSHOT_RESULT
Definition: mvcc.h:164
bool mvcc_is_mvcc_disabled_class(const OID *class_oid)
Definition: mvcc.c:616
std::vector< MVCCID > sub_ids
Definition: mvcc.h:205
MVCCID mvcc_del_id
Definition: mvcc.h:44
MVCC_SATISFIES_SNAPSHOT_RESULT(* MVCC_SNAPSHOT_FUNC)(THREAD_ENTRY *thread_p, MVCC_REC_HEADER *rec_header, MVCC_SNAPSHOT *snapshot)
Definition: mvcc.h:167
MVCC_SATISFIES_SNAPSHOT_RESULT mvcc_satisfies_snapshot(THREAD_ENTRY *thread_p, MVCC_REC_HEADER *rec_header, MVCC_SNAPSHOT *snapshot)
Definition: mvcc.c:144