1 /*****************************************************************************
2 
3 Copyright (c) 1997, 2019, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 
25 *****************************************************************************/
26 
27 /** @file include/row0undo.h
28  Row undo
29 
30  Created 1/8/1997 Heikki Tuuri
31  *******************************************************/
32 
33 #ifndef row0undo_h
34 #define row0undo_h
35 
36 #include "btr0pcur.h"
37 #include "btr0types.h"
38 #include "dict0types.h"
39 #include "mtr0mtr.h"
40 #include "que0types.h"
41 #include "row0types.h"
42 #include "trx0sys.h"
43 #include "trx0types.h"
44 #include "univ.i"
45 
46 /** Converts an implict lock on the record to explict in case of partial
47  rollback.
48 @param[in]	cursor		cursor to record
49 @param[in]	node		undo node */
50 void row_convert_impl_to_expl_if_needed(btr_cur_t *cursor, undo_node_t *node);
51 
52 /** Creates a row undo node to a query graph.
53 @param[in]	trx		 transaction
54 @param[in]	parent		 parent node, i.e., a thr node
55 @param[in]	heap		 memory heap where created
56 @param[in]	partial_rollback true if partial rollback
57 @return		undo node */
58 undo_node_t *row_undo_node_create(trx_t *trx, que_thr_t *parent,
59                                   mem_heap_t *heap, bool partial_rollback);
60 
61 /** Looks for the clustered index record when node has the row reference.
62  The pcur in node is used in the search. If found, stores the row to node,
63  and stores the position of pcur, and detaches it. The pcur must be closed
64  by the caller in any case.
65  @return true if found; NOTE the node->pcur must be closed by the
66  caller, regardless of the return value */
67 bool row_undo_search_clust_to_pcur(
68     undo_node_t *node) /*!< in/out: row undo node */
69     MY_ATTRIBUTE((warn_unused_result));
70 /** Undoes a row operation in a table. This is a high-level function used
71  in SQL execution graphs.
72  @return query thread to run next or NULL */
73 que_thr_t *row_undo_step(que_thr_t *thr); /*!< in: query thread */
74 
75 /* A single query thread will try to perform the undo for all successive
76 versions of a clustered index record, if the transaction has modified it
77 several times during the execution which is rolled back. It may happen
78 that the task is transferred to another query thread, if the other thread
79 is assigned to handle an undo log record in the chain of different versions
80 of the record, and the other thread happens to get the x-latch to the
81 clustered index record at the right time.
82         If a query thread notices that the clustered index record it is looking
83 for is missing, or the roll ptr field in the record doed not point to the
84 undo log record the thread was assigned to handle, then it gives up the undo
85 task for that undo log record, and fetches the next. This situation can occur
86 just in the case where the transaction modified the same record several times
87 and another thread is currently doing the undo for successive versions of
88 that index record. */
89 
90 /** Execution state of an undo node */
91 enum undo_exec {
92   UNDO_NODE_FETCH_NEXT = 1, /*!< we should fetch the next
93                             undo log record */
94   UNDO_NODE_INSERT,         /*!< undo a fresh insert of a
95                             row to a table */
96   UNDO_NODE_MODIFY          /*!< undo a modify operation
97                             (DELETE or UPDATE) on a row
98                             of a table */
99 };
100 
101 /** Undo node structure */
102 struct undo_node_t {
103   que_common_t common;      /*!< node type: QUE_NODE_UNDO */
104   enum undo_exec state;     /*!< node execution state */
105   trx_t *trx;               /*!< trx for which undo is done */
106   roll_ptr_t roll_ptr;      /*!< roll pointer to undo log record */
107   trx_undo_rec_t *undo_rec; /*!< undo log record */
108   undo_no_t undo_no;        /*!< undo number of the record */
109   ulint rec_type;           /*!< undo log record type: TRX_UNDO_INSERT_REC,
110                            ... */
111   trx_id_t new_trx_id;      /*!< trx id to restore to clustered index
112                         record */
113   btr_pcur_t pcur;          /*!< persistent cursor used in searching the
114                             clustered index record */
115   dict_table_t *table;      /*!< table where undo is done */
116   ulint cmpl_info;          /*!< compiler analysis of an update */
117   upd_t *update;            /*!< update vector for a clustered index
118                             record */
119   dtuple_t *ref;            /*!< row reference to the next row to handle */
120   dtuple_t *row;            /*!< a copy (also fields copied to heap) of the
121                             row to handle */
122   row_ext_t *ext;           /*!< NULL, or prefixes of the externally
123                             stored columns of the row */
124   dtuple_t *undo_row;       /*!< NULL, or the row after undo */
125   row_ext_t *undo_ext;      /*!< NULL, or prefixes of the externally
126                            stored columns of undo_row */
127   dict_index_t *index;      /*!< the next index whose record should be
128                             handled */
129   mem_heap_t *heap;         /*!< memory heap used as auxiliary storage for
130                             row; this must be emptied after undo is tried
131                             on a row */
132   bool partial;             /*!< true if partial rollback */
133 };
134 
135 #endif
136