1 /***************************************************************************** 2 3 Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2017, 2021, MariaDB Corporation. 5 6 This program is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free Software 8 Foundation; version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along with 15 this program; if not, write to the Free Software Foundation, Inc., 16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA 17 18 *****************************************************************************/ 19 20 /**************************************************//** 21 @file include/row0log.h 22 Modification log for online index creation and online table rebuild 23 24 Created 2011-05-26 Marko Makela 25 *******************************************************/ 26 27 #ifndef row0log_h 28 #define row0log_h 29 30 #include "que0types.h" 31 #include "mtr0types.h" 32 #include "row0types.h" 33 #include "rem0types.h" 34 #include "data0types.h" 35 #include "trx0types.h" 36 37 class ut_stage_alter_t; 38 39 extern Atomic_counter<ulint> onlineddl_rowlog_rows; 40 extern ulint onlineddl_rowlog_pct_used; 41 extern ulint onlineddl_pct_progress; 42 43 /******************************************************//** 44 Allocate the row log for an index and flag the index 45 for online creation. 46 @retval true if success, false if not */ 47 bool 48 row_log_allocate( 49 /*=============*/ 50 const trx_t* trx, /*!< in: the ALTER TABLE transaction */ 51 dict_index_t* index, /*!< in/out: index */ 52 dict_table_t* table, /*!< in/out: new table being rebuilt, 53 or NULL when creating a secondary index */ 54 bool same_pk,/*!< in: whether the definition of the 55 PRIMARY KEY has remained the same */ 56 const dtuple_t* defaults, 57 /*!< in: default values of 58 added, changed columns, or NULL */ 59 const ulint* col_map,/*!< in: mapping of old column 60 numbers to new ones, or NULL if !table */ 61 const char* path, /*!< in: where to create temporary file */ 62 const TABLE* old_table, /*!< in:table definition before alter */ 63 bool allow_not_null) /*!< in: allow null to non-null 64 conversion */ 65 MY_ATTRIBUTE((nonnull(1), warn_unused_result)); 66 67 /******************************************************//** 68 Free the row log for an index that was being created online. */ 69 void 70 row_log_free( 71 /*=========*/ 72 row_log_t* log) /*!< in,own: row log */ 73 MY_ATTRIBUTE((nonnull)); 74 75 /******************************************************//** 76 Free the row log for an index on which online creation was aborted. */ 77 UNIV_INLINE 78 void 79 row_log_abort_sec( 80 /*==============*/ 81 dict_index_t* index) /*!< in/out: index (x-latched) */ 82 MY_ATTRIBUTE((nonnull)); 83 84 /******************************************************//** 85 Try to log an operation to a secondary index that is 86 (or was) being created. 87 @retval true if the operation was logged or can be ignored 88 @retval false if online index creation is not taking place */ 89 UNIV_INLINE 90 bool 91 row_log_online_op_try( 92 /*==================*/ 93 dict_index_t* index, /*!< in/out: index, S or X latched */ 94 const dtuple_t* tuple, /*!< in: index tuple */ 95 trx_id_t trx_id) /*!< in: transaction ID for insert, 96 or 0 for delete */ 97 MY_ATTRIBUTE((nonnull, warn_unused_result)); 98 /******************************************************//** 99 Logs an operation to a secondary index that is (or was) being created. */ 100 void 101 row_log_online_op( 102 /*==============*/ 103 dict_index_t* index, /*!< in/out: index, S or X latched */ 104 const dtuple_t* tuple, /*!< in: index tuple */ 105 trx_id_t trx_id) /*!< in: transaction ID for insert, 106 or 0 for delete */ 107 ATTRIBUTE_COLD __attribute__((nonnull)); 108 109 /******************************************************//** 110 Gets the error status of the online index rebuild log. 111 @return DB_SUCCESS or error code */ 112 dberr_t 113 row_log_table_get_error( 114 /*====================*/ 115 const dict_index_t* index) /*!< in: clustered index of a table 116 that is being rebuilt online */ 117 MY_ATTRIBUTE((nonnull, warn_unused_result)); 118 119 /** Check whether a virtual column is indexed in the new table being 120 created during alter table 121 @param[in] index cluster index 122 @param[in] v_no virtual column number 123 @return true if it is indexed, else false */ 124 bool 125 row_log_col_is_indexed( 126 const dict_index_t* index, 127 ulint v_no); 128 129 /******************************************************//** 130 Logs a delete operation to a table that is being rebuilt. 131 This will be merged in row_log_table_apply_delete(). */ 132 void 133 row_log_table_delete( 134 /*=================*/ 135 const rec_t* rec, /*!< in: clustered index leaf page record, 136 page X-latched */ 137 dict_index_t* index, /*!< in/out: clustered index, S-latched 138 or X-latched */ 139 const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */ 140 const byte* sys) /*!< in: DB_TRX_ID,DB_ROLL_PTR that should 141 be logged, or NULL to use those in rec */ 142 ATTRIBUTE_COLD __attribute__((nonnull(1,2,3))); 143 144 /******************************************************//** 145 Logs an update operation to a table that is being rebuilt. 146 This will be merged in row_log_table_apply_update(). */ 147 void 148 row_log_table_update( 149 /*=================*/ 150 const rec_t* rec, /*!< in: clustered index leaf page record, 151 page X-latched */ 152 dict_index_t* index, /*!< in/out: clustered index, S-latched 153 or X-latched */ 154 const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index) */ 155 const dtuple_t* old_pk);/*!< in: row_log_table_get_pk() 156 before the update */ 157 158 /******************************************************//** 159 Constructs the old PRIMARY KEY and DB_TRX_ID,DB_ROLL_PTR 160 of a table that is being rebuilt. 161 @return tuple of PRIMARY KEY,DB_TRX_ID,DB_ROLL_PTR in the rebuilt table, 162 or NULL if the PRIMARY KEY definition does not change */ 163 const dtuple_t* 164 row_log_table_get_pk( 165 /*=================*/ 166 const rec_t* rec, /*!< in: clustered index leaf page record, 167 page X-latched */ 168 dict_index_t* index, /*!< in/out: clustered index, S-latched 169 or X-latched */ 170 const rec_offs* offsets,/*!< in: rec_get_offsets(rec,index), 171 or NULL */ 172 byte* sys, /*!< out: DB_TRX_ID,DB_ROLL_PTR for 173 row_log_table_delete(), or NULL */ 174 mem_heap_t** heap) /*!< in/out: memory heap where allocated */ 175 ATTRIBUTE_COLD __attribute__((nonnull(1,2,5), warn_unused_result)); 176 177 /******************************************************//** 178 Logs an insert to a table that is being rebuilt. 179 This will be merged in row_log_table_apply_insert(). */ 180 void 181 row_log_table_insert( 182 /*=================*/ 183 const rec_t* rec, /*!< in: clustered index leaf page record, 184 page X-latched */ 185 dict_index_t* index, /*!< in/out: clustered index, S-latched 186 or X-latched */ 187 const rec_offs* offsets);/*!< in: rec_get_offsets(rec,index) */ 188 /******************************************************//** 189 Notes that a BLOB is being freed during online ALTER TABLE. */ 190 void 191 row_log_table_blob_free( 192 /*====================*/ 193 dict_index_t* index, /*!< in/out: clustered index, X-latched */ 194 ulint page_no)/*!< in: starting page number of the BLOB */ 195 ATTRIBUTE_COLD __attribute__((nonnull)); 196 /******************************************************//** 197 Notes that a BLOB is being allocated during online ALTER TABLE. */ 198 void 199 row_log_table_blob_alloc( 200 /*=====================*/ 201 dict_index_t* index, /*!< in/out: clustered index, X-latched */ 202 ulint page_no)/*!< in: starting page number of the BLOB */ 203 ATTRIBUTE_COLD __attribute__((nonnull)); 204 205 /** Apply the row_log_table log to a table upon completing rebuild. 206 @param[in] thr query graph 207 @param[in] old_table old table 208 @param[in,out] table MySQL table (for reporting duplicates) 209 @param[in,out] stage performance schema accounting object, used by 210 ALTER TABLE. stage->begin_phase_log_table() will be called initially and then 211 stage->inc() will be called for each block of log that is applied. 212 @param[in] new_table Altered table 213 @return DB_SUCCESS, or error code on failure */ 214 dberr_t 215 row_log_table_apply( 216 que_thr_t* thr, 217 dict_table_t* old_table, 218 struct TABLE* table, 219 ut_stage_alter_t* stage, 220 dict_table_t* new_table) 221 MY_ATTRIBUTE((warn_unused_result)); 222 223 /******************************************************//** 224 Get the latest transaction ID that has invoked row_log_online_op() 225 during online creation. 226 @return latest transaction ID, or 0 if nothing was logged */ 227 trx_id_t 228 row_log_get_max_trx( 229 /*================*/ 230 dict_index_t* index) /*!< in: index, must be locked */ 231 MY_ATTRIBUTE((nonnull, warn_unused_result)); 232 233 /** Apply the row log to the index upon completing index creation. 234 @param[in] trx transaction (for checking if the operation was 235 interrupted) 236 @param[in,out] index secondary index 237 @param[in,out] table MySQL table (for reporting duplicates) 238 @param[in,out] stage performance schema accounting object, used by 239 ALTER TABLE. stage->begin_phase_log_index() will be called initially and then 240 stage->inc() will be called for each block of log that is applied. 241 @return DB_SUCCESS, or error code on failure */ 242 dberr_t 243 row_log_apply( 244 const trx_t* trx, 245 dict_index_t* index, 246 struct TABLE* table, 247 ut_stage_alter_t* stage) 248 MY_ATTRIBUTE((warn_unused_result)); 249 250 /** Get the n_core_fields of online log for the index 251 @param index index whose n_core_fields of log to be accessed 252 @return number of n_core_fields */ 253 unsigned row_log_get_n_core_fields(const dict_index_t *index); 254 255 #ifdef HAVE_PSI_STAGE_INTERFACE 256 /** Estimate how much work is to be done by the log apply phase 257 of an ALTER TABLE for this index. 258 @param[in] index index whose log to assess 259 @return work to be done by log-apply in abstract units 260 */ 261 ulint 262 row_log_estimate_work( 263 const dict_index_t* index); 264 #endif /* HAVE_PSI_STAGE_INTERFACE */ 265 266 #include "row0log.inl" 267 268 #endif /* row0log.h */ 269