1
by brian
clean slate |
1 |
/******************************************************
|
2 |
The transaction
|
|
3 |
||
4 |
(c) 1996 Innobase Oy
|
|
5 |
||
6 |
Created 3/26/1996 Heikki Tuuri
|
|
7 |
*******************************************************/
|
|
8 |
||
9 |
#ifndef trx0trx_h
|
|
10 |
#define trx0trx_h
|
|
11 |
||
12 |
#include "univ.i" |
|
13 |
#include "trx0types.h" |
|
14 |
#include "lock0types.h" |
|
15 |
#include "usr0types.h" |
|
16 |
#include "que0types.h" |
|
17 |
#include "mem0mem.h" |
|
18 |
#include "read0types.h" |
|
19 |
#include "dict0types.h" |
|
20 |
#include "trx0xa.h" |
|
21 |
||
22 |
extern ulint trx_n_mysql_transactions; |
|
23 |
||
24 |
/*****************************************************************
|
|
25 |
Resets the new record lock info in a transaction struct. */
|
|
26 |
UNIV_INLINE
|
|
27 |
void
|
|
28 |
trx_reset_new_rec_lock_info( |
|
29 |
/*========================*/
|
|
30 |
trx_t* trx); /* in: transaction struct */ |
|
31 |
/*****************************************************************
|
|
32 |
Registers that we have set a new record lock on an index. We only have space
|
|
33 |
to store 2 indexes! If this is called to store more than 2 indexes after
|
|
34 |
trx_reset_new_rec_lock_info(), then this function does nothing. */
|
|
35 |
UNIV_INLINE
|
|
36 |
void
|
|
37 |
trx_register_new_rec_lock( |
|
38 |
/*======================*/
|
|
39 |
trx_t* trx, /* in: transaction struct */ |
|
40 |
dict_index_t* index); /* in: trx sets a new record lock on this |
|
41 |
index */
|
|
42 |
/*****************************************************************
|
|
43 |
Checks if trx has set a new record lock on an index. */
|
|
44 |
UNIV_INLINE
|
|
45 |
ibool
|
|
46 |
trx_new_rec_locks_contain( |
|
47 |
/*======================*/
|
|
48 |
/* out: TRUE if trx has set a new record lock
|
|
49 |
on index */
|
|
50 |
trx_t* trx, /* in: transaction struct */ |
|
51 |
dict_index_t* index); /* in: index */ |
|
52 |
/************************************************************************
|
|
53 |
Releases the search latch if trx has reserved it. */
|
|
54 |
||
55 |
void
|
|
56 |
trx_search_latch_release_if_reserved( |
|
57 |
/*=================================*/
|
|
58 |
trx_t* trx); /* in: transaction */ |
|
59 |
/**********************************************************************
|
|
60 |
Set detailed error message for the transaction. */
|
|
61 |
void
|
|
62 |
trx_set_detailed_error( |
|
63 |
/*===================*/
|
|
64 |
trx_t* trx, /* in: transaction struct */ |
|
65 |
const char* msg); /* in: detailed error message */ |
|
66 |
/*****************************************************************
|
|
67 |
Set detailed error message for the transaction from a file. Note that the
|
|
68 |
file is rewinded before reading from it. */
|
|
69 |
||
70 |
void
|
|
71 |
trx_set_detailed_error_from_file( |
|
72 |
/*=============================*/
|
|
73 |
trx_t* trx, /* in: transaction struct */ |
|
74 |
FILE* file); /* in: file to read message from */ |
|
75 |
/********************************************************************
|
|
76 |
Retrieves the error_info field from a trx. */
|
|
77 |
||
78 |
void* |
|
79 |
trx_get_error_info( |
|
80 |
/*===============*/
|
|
81 |
/* out: the error info */
|
|
82 |
trx_t* trx); /* in: trx object */ |
|
83 |
/********************************************************************
|
|
84 |
Creates and initializes a transaction object. */
|
|
85 |
||
86 |
trx_t* |
|
87 |
trx_create( |
|
88 |
/*=======*/
|
|
89 |
/* out, own: the transaction */
|
|
90 |
sess_t* sess); /* in: session or NULL */ |
|
91 |
/************************************************************************
|
|
92 |
Creates a transaction object for MySQL. */
|
|
93 |
||
94 |
trx_t* |
|
95 |
trx_allocate_for_mysql(void); |
|
96 |
/*========================*/
|
|
97 |
/* out, own: transaction object */
|
|
98 |
/************************************************************************
|
|
99 |
Creates a transaction object for background operations by the master thread. */
|
|
100 |
||
101 |
trx_t* |
|
102 |
trx_allocate_for_background(void); |
|
103 |
/*=============================*/
|
|
104 |
/* out, own: transaction object */
|
|
105 |
/************************************************************************
|
|
106 |
Frees a transaction object. */
|
|
107 |
||
108 |
void
|
|
109 |
trx_free( |
|
110 |
/*=====*/
|
|
111 |
trx_t* trx); /* in, own: trx object */ |
|
112 |
/************************************************************************
|
|
113 |
Frees a transaction object for MySQL. */
|
|
114 |
||
115 |
void
|
|
116 |
trx_free_for_mysql( |
|
117 |
/*===============*/
|
|
118 |
trx_t* trx); /* in, own: trx object */ |
|
119 |
/************************************************************************
|
|
120 |
Frees a transaction object of a background operation of the master thread. */
|
|
121 |
||
122 |
void
|
|
123 |
trx_free_for_background( |
|
124 |
/*====================*/
|
|
125 |
trx_t* trx); /* in, own: trx object */ |
|
126 |
/********************************************************************
|
|
127 |
Creates trx objects for transactions and initializes the trx list of
|
|
128 |
trx_sys at database start. Rollback segment and undo log lists must
|
|
129 |
already exist when this function is called, because the lists of
|
|
130 |
transactions to be rolled back or cleaned up are built based on the
|
|
131 |
undo log lists. */
|
|
132 |
||
133 |
void
|
|
134 |
trx_lists_init_at_db_start(void); |
|
135 |
/*============================*/
|
|
136 |
/********************************************************************
|
|
137 |
Starts a new transaction. */
|
|
138 |
||
139 |
ibool
|
|
140 |
trx_start( |
|
141 |
/*======*/
|
|
142 |
/* out: TRUE if success, FALSE if the rollback
|
|
143 |
segment could not support this many transactions */
|
|
144 |
trx_t* trx, /* in: transaction */ |
|
145 |
ulint rseg_id);/* in: rollback segment id; if ULINT_UNDEFINED |
|
146 |
is passed, the system chooses the rollback segment
|
|
147 |
automatically in a round-robin fashion */
|
|
148 |
/********************************************************************
|
|
149 |
Starts a new transaction. */
|
|
150 |
||
151 |
ibool
|
|
152 |
trx_start_low( |
|
153 |
/*==========*/
|
|
154 |
/* out: TRUE */
|
|
155 |
trx_t* trx, /* in: transaction */ |
|
156 |
ulint rseg_id);/* in: rollback segment id; if ULINT_UNDEFINED |
|
157 |
is passed, the system chooses the rollback segment
|
|
158 |
automatically in a round-robin fashion */
|
|
159 |
/*****************************************************************
|
|
160 |
Starts the transaction if it is not yet started. */
|
|
161 |
UNIV_INLINE
|
|
162 |
void
|
|
163 |
trx_start_if_not_started( |
|
164 |
/*=====================*/
|
|
165 |
trx_t* trx); /* in: transaction */ |
|
166 |
/*****************************************************************
|
|
167 |
Starts the transaction if it is not yet started. Assumes we have reserved
|
|
168 |
the kernel mutex! */
|
|
169 |
UNIV_INLINE
|
|
170 |
void
|
|
171 |
trx_start_if_not_started_low( |
|
172 |
/*=========================*/
|
|
173 |
trx_t* trx); /* in: transaction */ |
|
174 |
/*****************************************************************
|
|
175 |
Starts the transaction if it is not yet started. */
|
|
176 |
||
177 |
void
|
|
178 |
trx_start_if_not_started_noninline( |
|
179 |
/*===============================*/
|
|
180 |
trx_t* trx); /* in: transaction */ |
|
181 |
/********************************************************************
|
|
182 |
Commits a transaction. */
|
|
183 |
||
184 |
void
|
|
185 |
trx_commit_off_kernel( |
|
186 |
/*==================*/
|
|
187 |
trx_t* trx); /* in: transaction */ |
|
188 |
/********************************************************************
|
|
189 |
Cleans up a transaction at database startup. The cleanup is needed if
|
|
190 |
the transaction already got to the middle of a commit when the database
|
|
191 |
crashed, andf we cannot roll it back. */
|
|
192 |
||
193 |
void
|
|
194 |
trx_cleanup_at_db_startup( |
|
195 |
/*======================*/
|
|
196 |
trx_t* trx); /* in: transaction */ |
|
197 |
/**************************************************************************
|
|
198 |
Does the transaction commit for MySQL. */
|
|
199 |
||
200 |
ulint
|
|
201 |
trx_commit_for_mysql( |
|
202 |
/*=================*/
|
|
203 |
/* out: 0 or error number */
|
|
204 |
trx_t* trx); /* in: trx handle */ |
|
205 |
/**************************************************************************
|
|
206 |
Does the transaction prepare for MySQL. */
|
|
207 |
||
208 |
ulint
|
|
209 |
trx_prepare_for_mysql( |
|
210 |
/*==================*/
|
|
211 |
/* out: 0 or error number */
|
|
212 |
trx_t* trx); /* in: trx handle */ |
|
213 |
/**************************************************************************
|
|
214 |
This function is used to find number of prepared transactions and
|
|
215 |
their transaction objects for a recovery. */
|
|
216 |
||
217 |
int
|
|
218 |
trx_recover_for_mysql( |
|
219 |
/*==================*/
|
|
220 |
/* out: number of prepared transactions */
|
|
221 |
XID* xid_list, /* in/out: prepared transactions */ |
|
222 |
ulint len); /* in: number of slots in xid_list */ |
|
223 |
/***********************************************************************
|
|
224 |
This function is used to find one X/Open XA distributed transaction
|
|
225 |
which is in the prepared state */
|
|
226 |
trx_t * |
|
227 |
trx_get_trx_by_xid( |
|
228 |
/*===============*/
|
|
229 |
/* out: trx or NULL */
|
|
230 |
XID* xid); /* in: X/Open XA transaction identification */ |
|
231 |
/**************************************************************************
|
|
232 |
If required, flushes the log to disk if we called trx_commit_for_mysql()
|
|
233 |
with trx->flush_log_later == TRUE. */
|
|
234 |
||
235 |
ulint
|
|
236 |
trx_commit_complete_for_mysql( |
|
237 |
/*==========================*/
|
|
238 |
/* out: 0 or error number */
|
|
239 |
trx_t* trx); /* in: trx handle */ |
|
240 |
/**************************************************************************
|
|
241 |
Marks the latest SQL statement ended. */
|
|
242 |
||
243 |
void
|
|
244 |
trx_mark_sql_stat_end( |
|
245 |
/*==================*/
|
|
246 |
trx_t* trx); /* in: trx handle */ |
|
247 |
/************************************************************************
|
|
248 |
Assigns a read view for a consistent read query. All the consistent reads
|
|
249 |
within the same transaction will get the same read view, which is created
|
|
250 |
when this function is first called for a new started transaction. */
|
|
251 |
||
252 |
read_view_t* |
|
253 |
trx_assign_read_view( |
|
254 |
/*=================*/
|
|
255 |
/* out: consistent read view */
|
|
256 |
trx_t* trx); /* in: active transaction */ |
|
257 |
/***************************************************************
|
|
258 |
The transaction must be in the TRX_QUE_LOCK_WAIT state. Puts it to
|
|
259 |
the TRX_QUE_RUNNING state and releases query threads which were
|
|
260 |
waiting for a lock in the wait_thrs list. */
|
|
261 |
||
262 |
void
|
|
263 |
trx_end_lock_wait( |
|
264 |
/*==============*/
|
|
265 |
trx_t* trx); /* in: transaction */ |
|
266 |
/********************************************************************
|
|
267 |
Sends a signal to a trx object. */
|
|
268 |
||
269 |
void
|
|
270 |
trx_sig_send( |
|
271 |
/*=========*/
|
|
272 |
trx_t* trx, /* in: trx handle */ |
|
273 |
ulint type, /* in: signal type */ |
|
274 |
ulint sender, /* in: TRX_SIG_SELF or |
|
275 |
TRX_SIG_OTHER_SESS */
|
|
276 |
que_thr_t* receiver_thr, /* in: query thread which wants the |
|
277 |
reply, or NULL; if type is
|
|
278 |
TRX_SIG_END_WAIT, this must be NULL */
|
|
279 |
trx_savept_t* savept, /* in: possible rollback savepoint, or |
|
280 |
NULL */
|
|
281 |
que_thr_t** next_thr); /* in/out: next query thread to run; |
|
282 |
if the value which is passed in is
|
|
283 |
a pointer to a NULL pointer, then the
|
|
284 |
calling function can start running
|
|
285 |
a new query thread; if the parameter
|
|
286 |
is NULL, it is ignored */
|
|
287 |
/********************************************************************
|
|
288 |
Send the reply message when a signal in the queue of the trx has
|
|
289 |
been handled. */
|
|
290 |
||
291 |
void
|
|
292 |
trx_sig_reply( |
|
293 |
/*==========*/
|
|
294 |
trx_sig_t* sig, /* in: signal */ |
|
295 |
que_thr_t** next_thr); /* in/out: next query thread to run; |
|
296 |
if the value which is passed in is
|
|
297 |
a pointer to a NULL pointer, then the
|
|
298 |
calling function can start running
|
|
299 |
a new query thread */
|
|
300 |
/********************************************************************
|
|
301 |
Removes the signal object from a trx signal queue. */
|
|
302 |
||
303 |
void
|
|
304 |
trx_sig_remove( |
|
305 |
/*===========*/
|
|
306 |
trx_t* trx, /* in: trx handle */ |
|
307 |
trx_sig_t* sig); /* in, own: signal */ |
|
308 |
/********************************************************************
|
|
309 |
Starts handling of a trx signal. */
|
|
310 |
||
311 |
void
|
|
312 |
trx_sig_start_handle( |
|
313 |
/*=================*/
|
|
314 |
trx_t* trx, /* in: trx handle */ |
|
315 |
que_thr_t** next_thr); /* in/out: next query thread to run; |
|
316 |
if the value which is passed in is
|
|
317 |
a pointer to a NULL pointer, then the
|
|
318 |
calling function can start running
|
|
319 |
a new query thread */
|
|
320 |
/********************************************************************
|
|
321 |
Ends signal handling. If the session is in the error state, and
|
|
322 |
trx->graph_before_signal_handling != NULL, returns control to the error
|
|
323 |
handling routine of the graph (currently only returns the control to the
|
|
324 |
graph root which then sends an error message to the client). */
|
|
325 |
||
326 |
void
|
|
327 |
trx_end_signal_handling( |
|
328 |
/*====================*/
|
|
329 |
trx_t* trx); /* in: trx */ |
|
330 |
/*************************************************************************
|
|
331 |
Creates a commit command node struct. */
|
|
332 |
||
333 |
commit_node_t* |
|
334 |
commit_node_create( |
|
335 |
/*===============*/
|
|
336 |
/* out, own: commit node struct */
|
|
337 |
mem_heap_t* heap); /* in: mem heap where created */ |
|
338 |
/***************************************************************
|
|
339 |
Performs an execution step for a commit type node in a query graph. */
|
|
340 |
||
341 |
que_thr_t* |
|
342 |
trx_commit_step( |
|
343 |
/*============*/
|
|
344 |
/* out: query thread to run next, or NULL */
|
|
345 |
que_thr_t* thr); /* in: query thread */ |
|
346 |
||
347 |
/**************************************************************************
|
|
348 |
Prints info about a transaction to the given file. The caller must own the
|
|
349 |
kernel mutex and must have called
|
|
350 |
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
|
|
351 |
or InnoDB cannot meanwhile change the info printed here. */
|
|
352 |
||
353 |
void
|
|
354 |
trx_print( |
|
355 |
/*======*/
|
|
356 |
FILE* f, /* in: output stream */ |
|
357 |
trx_t* trx, /* in: transaction */ |
|
358 |
ulint max_query_len); /* in: max query length to print, or 0 to |
|
359 |
use the default max length */
|
|
360 |
||
361 |
#ifndef UNIV_HOTBACKUP
|
|
362 |
/**************************************************************************
|
|
363 |
Determines if the currently running transaction has been interrupted. */
|
|
364 |
||
365 |
ibool
|
|
366 |
trx_is_interrupted( |
|
367 |
/*===============*/
|
|
368 |
/* out: TRUE if interrupted */
|
|
369 |
trx_t* trx); /* in: transaction */ |
|
370 |
#else /* !UNIV_HOTBACKUP */ |
|
371 |
#define trx_is_interrupted(trx) FALSE
|
|
372 |
#endif /* !UNIV_HOTBACKUP */ |
|
373 |
||
374 |
/***********************************************************************
|
|
375 |
Compares the "weight" (or size) of two transactions. The weight of one
|
|
376 |
transaction is estimated as the number of altered rows + the number of
|
|
377 |
locked rows. Transactions that have edited non-transactional tables are
|
|
378 |
considered heavier than ones that have not. */
|
|
379 |
||
380 |
int
|
|
381 |
trx_weight_cmp( |
|
382 |
/*===========*/
|
|
383 |
/* out: <0, 0 or >0; similar to strcmp(3) */
|
|
384 |
trx_t* a, /* in: the first transaction to be compared */ |
|
385 |
trx_t* b); /* in: the second transaction to be compared */ |
|
386 |
||
387 |
/* Signal to a transaction */
|
|
388 |
struct trx_sig_struct{ |
|
389 |
ulint type; /* signal type */ |
|
390 |
ulint sender; /* TRX_SIG_SELF or |
|
391 |
TRX_SIG_OTHER_SESS */
|
|
392 |
que_thr_t* receiver; /* non-NULL if the sender of the signal |
|
393 |
wants reply after the operation induced
|
|
394 |
by the signal is completed */
|
|
395 |
trx_savept_t savept; /* possible rollback savepoint */ |
|
396 |
UT_LIST_NODE_T(trx_sig_t) |
|
397 |
signals; /* queue of pending signals to the |
|
398 |
transaction */
|
|
399 |
UT_LIST_NODE_T(trx_sig_t) |
|
400 |
reply_signals; /* list of signals for which the sender |
|
401 |
transaction is waiting a reply */
|
|
402 |
};
|
|
403 |
||
404 |
#define TRX_MAGIC_N 91118598
|
|
405 |
||
406 |
/* The transaction handle; every session has a trx object which is freed only
|
|
407 |
when the session is freed; in addition there may be session-less transactions
|
|
408 |
rolling back after a database recovery */
|
|
409 |
||
410 |
struct trx_struct{ |
|
411 |
ulint magic_n; |
|
412 |
/* All the next fields are protected by the kernel mutex, except the
|
|
413 |
undo logs which are protected by undo_mutex */
|
|
414 |
const char* op_info; /* English text describing the |
|
415 |
current operation, or an empty
|
|
416 |
string */
|
|
417 |
unsigned is_purge:1; /* 0=user transaction, 1=purge */ |
|
418 |
ulint conc_state; /* state of the trx from the point |
|
419 |
of view of concurrency control:
|
|
420 |
TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
|
|
421 |
... */
|
|
422 |
time_t start_time; /* time the trx object was created |
|
423 |
or the state last time became
|
|
424 |
TRX_ACTIVE */
|
|
425 |
ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */ |
|
426 |
ibool check_foreigns; /* normally TRUE, but if the user |
|
427 |
wants to suppress foreign key checks,
|
|
428 |
(in table imports, for example) we
|
|
429 |
set this FALSE */
|
|
430 |
ibool check_unique_secondary; |
|
431 |
/* normally TRUE, but if the user
|
|
432 |
wants to speed up inserts by
|
|
433 |
suppressing unique key checks
|
|
434 |
for secondary indexes when we decide
|
|
435 |
if we can use the insert buffer for
|
|
436 |
them, we set this FALSE */
|
|
437 |
dulint id; /* transaction id */ |
|
438 |
XID xid; /* X/Open XA transaction |
|
439 |
identification to identify a
|
|
440 |
transaction branch */
|
|
441 |
ibool support_xa; /* normally we do the XA two-phase |
|
442 |
commit steps, but by setting this to
|
|
443 |
FALSE, one can save CPU time and about
|
|
444 |
150 bytes in the undo log size as then
|
|
445 |
we skip XA steps */
|
|
446 |
dulint no; /* transaction serialization number == |
|
447 |
max trx id when the transaction is
|
|
448 |
moved to COMMITTED_IN_MEMORY state */
|
|
449 |
ibool flush_log_later;/* when we commit the transaction |
|
450 |
in MySQL's binlog write, we will
|
|
451 |
flush the log to disk later in
|
|
452 |
a separate call */
|
|
453 |
ibool must_flush_log_later;/* this flag is set to TRUE in |
|
454 |
trx_commit_off_kernel() if
|
|
455 |
flush_log_later was TRUE, and there
|
|
456 |
were modifications by the transaction;
|
|
457 |
in that case we must flush the log
|
|
458 |
in trx_commit_complete_for_mysql() */
|
|
459 |
dulint commit_lsn; /* lsn at the time of the commit */ |
|
460 |
ibool dict_operation; /* TRUE if the trx is used to create |
|
461 |
a table, create an index, or drop a
|
|
462 |
table. This is a hint that the table
|
|
463 |
may need to be dropped in crash
|
|
464 |
recovery. */
|
|
465 |
dulint table_id; /* table id if the preceding field is |
|
466 |
TRUE */
|
|
467 |
/*------------------------------*/
|
|
468 |
unsigned duplicates:2; /* TRX_DUP_IGNORE | TRX_DUP_REPLACE */ |
|
469 |
unsigned active_trans:2; /* 1 - if a transaction in MySQL |
|
470 |
is active. 2 - if prepare_commit_mutex
|
|
471 |
was taken */
|
|
472 |
void* mysql_thd; /* MySQL thread handle corresponding |
|
473 |
to this trx, or NULL */
|
|
474 |
char** mysql_query_str;/* pointer to the field in mysqld_thd |
|
475 |
which contains the pointer to the
|
|
476 |
current SQL query string */
|
|
477 |
const char* mysql_log_file_name; |
|
478 |
/* if MySQL binlog is used, this field
|
|
479 |
contains a pointer to the latest file
|
|
480 |
name; this is NULL if binlog is not
|
|
481 |
used */
|
|
482 |
ib_longlong mysql_log_offset;/* if MySQL binlog is used, this field |
|
483 |
contains the end offset of the binlog
|
|
484 |
entry */
|
|
485 |
os_thread_id_t mysql_thread_id;/* id of the MySQL thread associated |
|
486 |
with this transaction object */
|
|
487 |
ulint mysql_process_no;/* since in Linux, 'top' reports |
|
488 |
process id's and not thread id's, we
|
|
489 |
store the process number too */
|
|
490 |
/*------------------------------*/
|
|
491 |
ulint n_mysql_tables_in_use; /* number of Innobase tables |
|
492 |
used in the processing of the current
|
|
493 |
SQL statement in MySQL */
|
|
494 |
ulint mysql_n_tables_locked; |
|
495 |
/* how many tables the current SQL
|
|
496 |
statement uses, except those
|
|
497 |
in consistent read */
|
|
498 |
ibool dict_operation_lock_mode; |
|
499 |
/* 0, RW_S_LATCH, or RW_X_LATCH:
|
|
500 |
the latch mode trx currently holds
|
|
501 |
on dict_operation_lock */
|
|
502 |
ibool has_search_latch; |
|
503 |
/* TRUE if this trx has latched the
|
|
504 |
search system latch in S-mode */
|
|
505 |
ulint search_latch_timeout; |
|
506 |
/* If we notice that someone is
|
|
507 |
waiting for our S-lock on the search
|
|
508 |
latch to be released, we wait in
|
|
509 |
row0sel.c for BTR_SEA_TIMEOUT new
|
|
510 |
searches until we try to keep
|
|
511 |
the search latch again over
|
|
512 |
calls from MySQL; this is intended
|
|
513 |
to reduce contention on the search
|
|
514 |
latch */
|
|
515 |
/*------------------------------*/
|
|
516 |
ibool declared_to_be_inside_innodb; |
|
517 |
/* this is TRUE if we have declared
|
|
518 |
this transaction in
|
|
519 |
srv_conc_enter_innodb to be inside the
|
|
520 |
InnoDB engine */
|
|
521 |
ulint n_tickets_to_enter_innodb; |
|
522 |
/* this can be > 0 only when
|
|
523 |
declared_to_... is TRUE; when we come
|
|
524 |
to srv_conc_innodb_enter, if the value
|
|
525 |
here is > 0, we decrement this by 1 */
|
|
526 |
/*------------------------------*/
|
|
527 |
lock_t* auto_inc_lock; /* possible auto-inc lock reserved by |
|
528 |
the transaction; note that it is also
|
|
529 |
in the lock list trx_locks */
|
|
530 |
dict_index_t* new_rec_locks[2];/* these are normally NULL; if |
|
531 |
srv_locks_unsafe_for_binlog is TRUE
|
|
532 |
or session is using READ COMMITTED
|
|
533 |
isolation level,
|
|
534 |
in a cursor search, if we set a new
|
|
535 |
record lock on an index, this is set
|
|
536 |
to point to the index; this is
|
|
537 |
used in releasing the locks under the
|
|
538 |
cursors if we are performing an UPDATE
|
|
539 |
and we determine after retrieving
|
|
540 |
the row that it does not need to be
|
|
541 |
locked; thus, these can be used to
|
|
542 |
implement a 'mini-rollback' that
|
|
543 |
releases the latest record locks */
|
|
544 |
UT_LIST_NODE_T(trx_t) |
|
545 |
trx_list; /* list of transactions */ |
|
546 |
UT_LIST_NODE_T(trx_t) |
|
547 |
mysql_trx_list; /* list of transactions created for |
|
548 |
MySQL */
|
|
549 |
/*------------------------------*/
|
|
550 |
ulint error_state; /* 0 if no error, otherwise error |
|
551 |
number; NOTE That ONLY the thread
|
|
552 |
doing the transaction is allowed to
|
|
553 |
set this field: this is NOT protected
|
|
554 |
by the kernel mutex */
|
|
555 |
void* error_info; /* if the error number indicates a |
|
556 |
duplicate key error, a pointer to
|
|
557 |
the problematic index is stored here */
|
|
558 |
sess_t* sess; /* session of the trx, NULL if none */ |
|
559 |
ulint que_state; /* TRX_QUE_RUNNING, TRX_QUE_LOCK_WAIT, |
|
560 |
... */
|
|
561 |
que_t* graph; /* query currently run in the session, |
|
562 |
or NULL if none; NOTE that the query
|
|
563 |
belongs to the session, and it can
|
|
564 |
survive over a transaction commit, if
|
|
565 |
it is a stored procedure with a COMMIT
|
|
566 |
WORK statement, for instance */
|
|
567 |
ulint n_active_thrs; /* number of active query threads */ |
|
568 |
ibool handling_signals;/* this is TRUE as long as the trx |
|
569 |
is handling signals */
|
|
570 |
que_t* graph_before_signal_handling; |
|
571 |
/* value of graph when signal handling
|
|
572 |
for this trx started: this is used to
|
|
573 |
return control to the original query
|
|
574 |
graph for error processing */
|
|
575 |
trx_sig_t sig; /* one signal object can be allocated |
|
576 |
in this space, avoiding mem_alloc */
|
|
577 |
UT_LIST_BASE_NODE_T(trx_sig_t) |
|
578 |
signals; /* queue of processed or pending |
|
579 |
signals to the trx */
|
|
580 |
UT_LIST_BASE_NODE_T(trx_sig_t) |
|
581 |
reply_signals; /* list of signals sent by the query |
|
582 |
threads of this trx for which a thread
|
|
583 |
is waiting for a reply; if this trx is
|
|
584 |
killed, the reply requests in the list
|
|
585 |
must be canceled */
|
|
586 |
/*------------------------------*/
|
|
587 |
lock_t* wait_lock; /* if trx execution state is |
|
588 |
TRX_QUE_LOCK_WAIT, this points to
|
|
589 |
the lock request, otherwise this is
|
|
590 |
NULL */
|
|
591 |
ibool was_chosen_as_deadlock_victim; |
|
592 |
/* when the transaction decides to wait
|
|
593 |
for a lock, it sets this to FALSE;
|
|
594 |
if another transaction chooses this
|
|
595 |
transaction as a victim in deadlock
|
|
596 |
resolution, it sets this to TRUE */
|
|
597 |
time_t wait_started; /* lock wait started at this time */ |
|
598 |
UT_LIST_BASE_NODE_T(que_thr_t) |
|
599 |
wait_thrs; /* query threads belonging to this |
|
600 |
trx that are in the QUE_THR_LOCK_WAIT
|
|
601 |
state */
|
|
602 |
ulint deadlock_mark; /* a mark field used in deadlock |
|
603 |
checking algorithm */
|
|
604 |
/*------------------------------*/
|
|
605 |
mem_heap_t* lock_heap; /* memory heap for the locks of the |
|
606 |
transaction */
|
|
607 |
UT_LIST_BASE_NODE_T(lock_t) |
|
608 |
trx_locks; /* locks reserved by the transaction */ |
|
609 |
/*------------------------------*/
|
|
610 |
mem_heap_t* global_read_view_heap; |
|
611 |
/* memory heap for the global read
|
|
612 |
view */
|
|
613 |
read_view_t* global_read_view; |
|
614 |
/* consistent read view associated
|
|
615 |
to a transaction or NULL */
|
|
616 |
read_view_t* read_view; /* consistent read view used in the |
|
617 |
transaction or NULL, this read view
|
|
618 |
if defined can be normal read view
|
|
619 |
associated to a transaction (i.e.
|
|
620 |
same as global_read_view) or read view
|
|
621 |
associated to a cursor */
|
|
622 |
/*------------------------------*/
|
|
623 |
UT_LIST_BASE_NODE_T(trx_named_savept_t) |
|
624 |
trx_savepoints; /* savepoints set with SAVEPOINT ..., |
|
625 |
oldest first */
|
|
626 |
/*------------------------------*/
|
|
627 |
mutex_t undo_mutex; /* mutex protecting the fields in this |
|
628 |
section (down to undo_no_arr), EXCEPT
|
|
629 |
last_sql_stat_start, which can be
|
|
630 |
accessed only when we know that there
|
|
631 |
cannot be any activity in the undo
|
|
632 |
logs! */
|
|
633 |
dulint undo_no; /* next undo log record number to |
|
634 |
assign; since the undo log is
|
|
635 |
private for a transaction, this
|
|
636 |
is a simple ascending sequence
|
|
637 |
with no gaps; thus it represents
|
|
638 |
the number of modified/inserted
|
|
639 |
rows in a transaction */
|
|
640 |
trx_savept_t last_sql_stat_start; |
|
641 |
/* undo_no when the last sql statement
|
|
642 |
was started: in case of an error, trx
|
|
643 |
is rolled back down to this undo
|
|
644 |
number; see note at undo_mutex! */
|
|
645 |
trx_rseg_t* rseg; /* rollback segment assigned to the |
|
646 |
transaction, or NULL if not assigned
|
|
647 |
yet */
|
|
648 |
trx_undo_t* insert_undo; /* pointer to the insert undo log, or |
|
649 |
NULL if no inserts performed yet */
|
|
650 |
trx_undo_t* update_undo; /* pointer to the update undo log, or |
|
651 |
NULL if no update performed yet */
|
|
652 |
dulint roll_limit; /* least undo number to undo during |
|
653 |
a rollback */
|
|
654 |
ulint pages_undone; /* number of undo log pages undone |
|
655 |
since the last undo log truncation */
|
|
656 |
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log |
|
657 |
records which are currently processed
|
|
658 |
by a rollback operation */
|
|
659 |
ulint n_autoinc_rows; /* no. of AUTO-INC rows required for |
|
660 |
an SQL statement. This is useful for
|
|
661 |
multi-row INSERTs */
|
|
662 |
/*------------------------------*/
|
|
663 |
char detailed_error[256]; /* detailed error message for last |
|
664 |
error, or empty. */
|
|
665 |
};
|
|
666 |
||
667 |
#define TRX_MAX_N_THREADS 32 /* maximum number of |
|
668 |
concurrent threads running a
|
|
669 |
single operation of a
|
|
670 |
transaction, e.g., a parallel
|
|
671 |
query */
|
|
672 |
/* Transaction concurrency states (trx->conc_state) */
|
|
673 |
#define TRX_NOT_STARTED 1
|
|
674 |
#define TRX_ACTIVE 2
|
|
675 |
#define TRX_COMMITTED_IN_MEMORY 3
|
|
676 |
#define TRX_PREPARED 4 /* Support for 2PC/XA */ |
|
677 |
||
678 |
/* Transaction execution states when trx->conc_state == TRX_ACTIVE */
|
|
679 |
#define TRX_QUE_RUNNING 1 /* transaction is running */ |
|
680 |
#define TRX_QUE_LOCK_WAIT 2 /* transaction is waiting for a lock */ |
|
681 |
#define TRX_QUE_ROLLING_BACK 3 /* transaction is rolling back */ |
|
682 |
#define TRX_QUE_COMMITTING 4 /* transaction is committing */ |
|
683 |
||
684 |
/* Transaction isolation levels (trx->isolation_level) */
|
|
685 |
#define TRX_ISO_READ_UNCOMMITTED 1 /* dirty read: non-locking |
|
686 |
SELECTs are performed so that
|
|
687 |
we do not look at a possible
|
|
688 |
earlier version of a record;
|
|
689 |
thus they are not 'consistent'
|
|
690 |
reads under this isolation
|
|
691 |
level; otherwise like level
|
|
692 |
2 */
|
|
693 |
||
694 |
#define TRX_ISO_READ_COMMITTED 2 /* somewhat Oracle-like |
|
695 |
isolation, except that in
|
|
696 |
range UPDATE and DELETE we
|
|
697 |
must block phantom rows
|
|
698 |
with next-key locks;
|
|
699 |
SELECT ... FOR UPDATE and ...
|
|
700 |
LOCK IN SHARE MODE only lock
|
|
701 |
the index records, NOT the
|
|
702 |
gaps before them, and thus
|
|
703 |
allow free inserting;
|
|
704 |
each consistent read reads its
|
|
705 |
own snapshot */
|
|
706 |
||
707 |
#define TRX_ISO_REPEATABLE_READ 3 /* this is the default; |
|
708 |
all consistent reads in the
|
|
709 |
same trx read the same
|
|
710 |
snapshot;
|
|
711 |
full next-key locking used
|
|
712 |
in locking reads to block
|
|
713 |
insertions into gaps */
|
|
714 |
||
715 |
#define TRX_ISO_SERIALIZABLE 4 /* all plain SELECTs are |
|
716 |
converted to LOCK IN SHARE
|
|
717 |
MODE reads */
|
|
718 |
||
719 |
/* Treatment of duplicate values (trx->duplicates; for example, in inserts).
|
|
720 |
Multiple flags can be combined with bitwise OR. */
|
|
721 |
#define TRX_DUP_IGNORE 1 /* duplicate rows are to be updated */ |
|
722 |
#define TRX_DUP_REPLACE 2 /* duplicate rows are to be replaced */ |
|
723 |
||
724 |
||
725 |
/* Types of a trx signal */
|
|
726 |
#define TRX_SIG_NO_SIGNAL 100
|
|
727 |
#define TRX_SIG_TOTAL_ROLLBACK 1
|
|
728 |
#define TRX_SIG_ROLLBACK_TO_SAVEPT 2
|
|
729 |
#define TRX_SIG_COMMIT 3
|
|
730 |
#define TRX_SIG_ERROR_OCCURRED 4
|
|
731 |
#define TRX_SIG_BREAK_EXECUTION 5
|
|
732 |
||
733 |
/* Sender types of a signal */
|
|
734 |
#define TRX_SIG_SELF 1 /* sent by the session itself, or |
|
735 |
by an error occurring within this
|
|
736 |
session */
|
|
737 |
#define TRX_SIG_OTHER_SESS 2 /* sent by another session (which |
|
738 |
must hold rights to this) */
|
|
739 |
||
740 |
/* Commit command node in a query graph */
|
|
741 |
struct commit_node_struct{ |
|
742 |
que_common_t common; /* node type: QUE_NODE_COMMIT */ |
|
743 |
ulint state; /* node execution state */ |
|
744 |
};
|
|
745 |
||
746 |
/* Commit node states */
|
|
747 |
#define COMMIT_NODE_SEND 1
|
|
748 |
#define COMMIT_NODE_WAIT 2
|
|
749 |
||
750 |
||
751 |
#ifndef UNIV_NONINL
|
|
752 |
#include "trx0trx.ic" |
|
753 |
#endif
|
|
754 |
||
755 |
#endif
|