1 /***************************************************************************** 2 3 Copyright (c) 1995, 2020, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2012, Facebook Inc. 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, version 2.0, as published by the 8 Free Software Foundation. 9 10 This program is also distributed with certain software (including but not 11 limited to OpenSSL) that is licensed under separate terms, as designated in a 12 particular file or component or in included license documentation. The authors 13 of MySQL hereby grant you an additional permission to link the program and 14 your derivative works with the separately licensed software that they have 15 included with MySQL. 16 17 This program is distributed in the hope that it will be useful, but WITHOUT 18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 20 for more details. 21 22 You should have received a copy of the GNU General Public License along with 23 this program; if not, write to the Free Software Foundation, Inc., 24 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 25 26 *****************************************************************************/ 27 28 /** @file include/mtr0mtr.h 29 Mini-transaction buffer 30 31 Created 11/26/1995 Heikki Tuuri 32 *******************************************************/ 33 34 #ifndef mtr0mtr_h 35 #define mtr0mtr_h 36 37 #include <stddef.h> 38 39 #include "univ.i" 40 41 #include "buf0types.h" 42 #include "dyn0buf.h" 43 #include "fil0fil.h" 44 #include "log0types.h" 45 #include "mtr0types.h" 46 #include "srv0srv.h" 47 #include "trx0types.h" 48 49 /** Start a mini-transaction. */ 50 #define mtr_start(m) (m)->start() 51 52 /** Start a synchronous mini-transaction */ 53 #define mtr_start_sync(m) (m)->start(true) 54 55 /** Start an asynchronous read-only mini-transaction */ 56 #define mtr_start_ro(m) (m)->start(true, true) 57 58 /** Commit a mini-transaction. */ 59 #define mtr_commit(m) (m)->commit() 60 61 /** Set and return a savepoint in mtr. 62 @return savepoint */ 63 #define mtr_set_savepoint(m) (m)->get_savepoint() 64 65 /** Release the (index tree) s-latch stored in an mtr memo after a 66 savepoint. */ 67 #define mtr_release_s_latch_at_savepoint(m, s, l) \ 68 (m)->release_s_latch_at_savepoint((s), (l)) 69 70 /** Get the logging mode of a mini-transaction. 71 @return logging mode: MTR_LOG_NONE, ... */ 72 #define mtr_get_log_mode(m) (m)->get_log_mode() 73 74 /** Change the logging mode of a mini-transaction. 75 @return old mode */ 76 #define mtr_set_log_mode(m, d) (m)->set_log_mode((d)) 77 78 /** Get the flush observer of a mini-transaction. 79 @return flush observer object */ 80 #define mtr_get_flush_observer(m) (m)->get_flush_observer() 81 82 /** Set the flush observer of a mini-transaction. */ 83 #define mtr_set_flush_observer(m, d) (m)->set_flush_observer((d)) 84 85 /** Read 1 - 4 bytes from a file page buffered in the buffer pool. 86 @return value read */ 87 #define mtr_read_ulint(p, t, m) (m)->read_ulint((p), (t)) 88 89 /** Release an object in the memo stack. 90 @return true if released */ 91 #define mtr_memo_release(m, o, t) (m)->memo_release((o), (t)) 92 93 #ifdef UNIV_DEBUG 94 95 /** Check if memo contains the given item ignore if table is intrinsic 96 @return true if contains or table is intrinsic. */ 97 #define mtr_is_block_fix(m, o, t, table) \ 98 (mtr_memo_contains(m, o, t) || table->is_intrinsic()) 99 100 /** Check if memo contains the given page ignore if table is intrinsic 101 @return true if contains or table is intrinsic. */ 102 #define mtr_is_page_fix(m, p, t, table) \ 103 (mtr_memo_contains_page(m, p, t) || table->is_intrinsic()) 104 105 /** Check if memo contains the given item. 106 @return true if contains */ 107 #define mtr_memo_contains(m, o, t) (m)->memo_contains((m)->get_memo(), (o), (t)) 108 109 /** Check if memo contains the given page. 110 @return true if contains */ 111 #define mtr_memo_contains_page(m, p, t) \ 112 (m)->memo_contains_page_flagged((p), (t)) 113 #endif /* UNIV_DEBUG */ 114 115 /** Print info of an mtr handle. */ 116 #define mtr_print(m) (m)->print() 117 118 /** Return the log object of a mini-transaction buffer. 119 @return log */ 120 #define mtr_get_log(m) (m)->get_log() 121 122 /** Push an object to an mtr memo stack. */ 123 #define mtr_memo_push(m, o, t) (m)->memo_push(o, t) 124 125 /** Lock an rw-lock in s-mode. */ 126 #define mtr_s_lock(l, m) (m)->s_lock((l), __FILE__, __LINE__) 127 128 /** Lock an rw-lock in x-mode. */ 129 #define mtr_x_lock(l, m) (m)->x_lock((l), __FILE__, __LINE__) 130 131 /** Lock a tablespace in x-mode. */ 132 #define mtr_x_lock_space(s, m) (m)->x_lock_space((s), __FILE__, __LINE__) 133 134 /** Lock an rw-lock in sx-mode. */ 135 #define mtr_sx_lock(l, m) (m)->sx_lock((l), __FILE__, __LINE__) 136 137 #define mtr_memo_contains_flagged(m, p, l) (m)->memo_contains_flagged((p), (l)) 138 139 #define mtr_memo_contains_page_flagged(m, p, l) \ 140 (m)->memo_contains_page_flagged((p), (l)) 141 142 #define mtr_release_block_at_savepoint(m, s, b) \ 143 (m)->release_block_at_savepoint((s), (b)) 144 145 #define mtr_block_sx_latch_at_savepoint(m, s, b) \ 146 (m)->sx_latch_at_savepoint((s), (b)) 147 148 #define mtr_block_x_latch_at_savepoint(m, s, b) \ 149 (m)->x_latch_at_savepoint((s), (b)) 150 151 /** Check if a mini-transaction is dirtying a clean page. 152 @param b block being x-fixed 153 @return true if the mtr is dirtying a clean page. */ 154 #define mtr_block_dirtied(b) mtr_t::is_block_dirtied((b)) 155 156 /** Forward declaration of a tablespace object */ 157 struct fil_space_t; 158 159 /** Mini-transaction memo stack slot. */ 160 struct mtr_memo_slot_t { 161 /** pointer to the object */ 162 void *object; 163 164 /** type of the stored object (MTR_MEMO_S_LOCK, ...) */ 165 ulint type; 166 }; 167 168 /** Mini-transaction handle and buffer */ 169 struct mtr_t { 170 /** State variables of the mtr */ 171 struct Impl { 172 /** memo stack for locks etc. */ 173 mtr_buf_t m_memo; 174 175 /** mini-transaction log */ 176 mtr_buf_t m_log; 177 178 /** true if mtr has made at least one buffer pool page dirty */ 179 bool m_made_dirty; 180 181 /** true if inside ibuf changes */ 182 bool m_inside_ibuf; 183 184 /** true if the mini-transaction modified buffer pool pages */ 185 bool m_modifications; 186 187 /** true if mtr is forced to NO_LOG mode because redo logging is 188 disabled globally. In this case, mtr increments the global counter 189 at ::start and must decrement it back at ::commit. */ 190 bool m_marked_nolog; 191 192 /** Shard index used for incrementing global counter at ::start. We need 193 to use the same shard while decrementing counter at ::commit. */ 194 size_t m_shard_index; 195 196 /** Count of how many page initial log records have been 197 written to the mtr log */ 198 ib_uint32_t m_n_log_recs; 199 200 /** specifies which operations should be logged; default 201 value MTR_LOG_ALL */ 202 mtr_log_t m_log_mode; 203 204 /** State of the transaction */ 205 mtr_state_t m_state; 206 207 /** Flush Observer */ 208 FlushObserver *m_flush_observer; 209 210 #ifdef UNIV_DEBUG 211 /** For checking corruption. */ 212 ulint m_magic_n; 213 214 #endif /* UNIV_DEBUG */ 215 216 /** Owning mini-transaction */ 217 mtr_t *m_mtr; 218 }; 219 220 #ifndef UNIV_HOTBACKUP 221 /** mtr global logging */ 222 class Logging { 223 public: 224 /** mtr global redo logging state. 225 Enable Logging : 226 [ENABLED] -> [ENABLED_RESTRICT] -> [DISABLED] 227 228 Disable Logging : 229 [DISABLED] -> [ENABLED_RESTRICT] -> [ENABLED_DBLWR] -> [ENABLED] */ 230 231 enum State : uint32_t { 232 /* Redo Logging is enabled. Server is crash safe. */ 233 ENABLED, 234 /* Redo logging is enabled. All non-logging mtr are finished with the 235 pages flushed to disk. Double write is enabled. Some pages could be 236 still getting written to disk without double-write. Not safe to crash. */ 237 ENABLED_DBLWR, 238 /* Redo logging is enabled but there could be some mtrs still running 239 in no logging mode. Redo archiving and clone are not allowed to start. 240 No double-write */ 241 ENABLED_RESTRICT, 242 /* Redo logging is disabled and all new mtrs would not generate any redo. 243 Redo archiving and clone are not allowed. */ 244 DISABLED 245 }; 246 247 /** Initialize logging state at server start up. */ initmtr_t248 void init() { 249 m_state.store(ENABLED); 250 /* We use sharded counter and force sequentially consistent counting 251 which is the general default for c++ atomic operation. If we try to 252 optimize it further specific to current operations, we could use 253 Release-Acquire ordering i.e. std::memory_order_release during counting 254 and std::memory_order_acquire while checking for the count. However, 255 sharding looks to be good enough for now and we should go for non default 256 memory ordering only with some visible proof for improvement. */ 257 m_count_nologging_mtr.set_order(std::memory_order_seq_cst); 258 Counter::clear(m_count_nologging_mtr); 259 } 260 261 /** Disable mtr redo logging. Server is crash unsafe without logging. 262 @param[in] thd server connection THD 263 @return mysql error code. */ 264 int disable(THD *thd); 265 266 /** Enable mtr redo logging. Ensure that the server is crash safe 267 before returning. 268 @param[in] thd server connection THD 269 @return mysql error code. */ 270 int enable(THD *thd); 271 272 /** Mark a no-logging mtr to indicate that it would not generate redo log 273 and system is crash unsafe. 274 @return true iff logging is disabled and mtr is marked. */ mark_mtrmtr_t275 bool mark_mtr(size_t index) { 276 /* Have initial check to avoid incrementing global counter for regular 277 case when redo logging is enabled. */ 278 if (is_disabled()) { 279 /* Increment counter to restrict state change DISABLED to ENABLED. */ 280 Counter::inc(m_count_nologging_mtr, index); 281 282 /* Check if the no-logging is still disabled. At this point, if we 283 find the state disabled, it is no longer possible for the state move 284 back to enabled till the mtr finishes and we unmark the mtr. */ 285 if (is_disabled()) { 286 return (true); 287 } 288 Counter::dec(m_count_nologging_mtr, index); 289 } 290 return (false); 291 } 292 293 /** unmark a no logging mtr. */ unmark_mtrmtr_t294 void unmark_mtr(size_t index) { 295 ut_ad(!is_enabled()); 296 ut_ad(Counter::total(m_count_nologging_mtr) > 0); 297 Counter::dec(m_count_nologging_mtr, index); 298 } 299 300 /* @return flush loop count for faster response when logging is disabled. */ get_nolog_flush_loopmtr_t301 uint32_t get_nolog_flush_loop() const { return (NOLOG_MAX_FLUSH_LOOP); } 302 303 /** @return true iff redo logging is enabled and server is crash safe. */ is_enabledmtr_t304 bool is_enabled() const { return (m_state.load() == ENABLED); } 305 306 /** @return true iff redo logging is disabled and new mtrs are not going 307 to generate redo log. */ is_disabledmtr_t308 bool is_disabled() const { return (m_state.load() == DISABLED); } 309 310 /** @return true iff we can skip data page double write. */ dblwr_disabledmtr_t311 bool dblwr_disabled() const { 312 auto state = m_state.load(); 313 return (state == DISABLED || state == ENABLED_RESTRICT); 314 } 315 316 /* Force faster flush loop for quicker adaptive flush response when logging 317 is disabled. When redo logging is disabled the system operates faster with 318 dirty pages generated at much faster rate. */ 319 static constexpr uint32_t NOLOG_MAX_FLUSH_LOOP = 5; 320 321 private: 322 /** Wait till all no-logging mtrs are finished. 323 @return mysql error code. */ 324 int wait_no_log_mtr(THD *thd); 325 326 private: 327 /** Global redo logging state. */ 328 std::atomic<State> m_state; 329 330 using Shards = Counter::Shards<128>; 331 332 /** Number of no logging mtrs currently running. */ 333 Shards m_count_nologging_mtr; 334 }; 335 336 /** Check if redo logging is disabled globally and mark 337 the global counter till mtr ends. */ 338 void check_nolog_and_mark(); 339 340 /** Check if the mtr has marked the global no log counter and 341 unmark it. */ 342 void check_nolog_and_unmark(); 343 #endif /* !UNIV_HOTBACKUP */ 344 mtr_tmtr_t345 mtr_t() { 346 m_impl.m_state = MTR_STATE_INIT; 347 m_impl.m_marked_nolog = false; 348 m_impl.m_shard_index = 0; 349 } 350 ~mtr_tmtr_t351 ~mtr_t() { 352 #ifdef UNIV_DEBUG 353 switch (m_impl.m_state) { 354 case MTR_STATE_ACTIVE: 355 ut_ad(m_impl.m_memo.size() == 0); 356 break; 357 case MTR_STATE_INIT: 358 case MTR_STATE_COMMITTED: 359 break; 360 case MTR_STATE_COMMITTING: 361 ut_error; 362 } 363 #endif /* UNIV_DEBUG */ 364 #ifndef UNIV_HOTBACKUP 365 /* Safety check in case mtr is not committed. */ 366 if (m_impl.m_state != MTR_STATE_INIT) { 367 check_nolog_and_unmark(); 368 } 369 #endif /* !UNIV_HOTBACKUP */ 370 } 371 372 /** Start a mini-transaction. 373 @param sync true if it is a synchronous mini-transaction 374 @param read_only true if read only mini-transaction */ 375 void start(bool sync = true, bool read_only = false); 376 377 /** @return whether this is an asynchronous mini-transaction. */ is_asyncmtr_t378 bool is_async() const { return (!m_sync); } 379 380 /** Request a future commit to be synchronous. */ set_syncmtr_t381 void set_sync() { m_sync = true; } 382 383 /** Commit the mini-transaction. */ 384 void commit(); 385 386 /** Return current size of the buffer. 387 @return savepoint */ get_savepointmtr_t388 ulint get_savepoint() const MY_ATTRIBUTE((warn_unused_result)) { 389 ut_ad(is_active()); 390 ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); 391 392 return (m_impl.m_memo.size()); 393 } 394 395 /** Release the (index tree) s-latch stored in an mtr memo after a 396 savepoint. 397 @param savepoint value returned by @see set_savepoint. 398 @param lock latch to release */ 399 inline void release_s_latch_at_savepoint(ulint savepoint, rw_lock_t *lock); 400 401 /** Release the block in an mtr memo after a savepoint. */ 402 inline void release_block_at_savepoint(ulint savepoint, buf_block_t *block); 403 404 /** SX-latch a not yet latched block after a savepoint. */ 405 inline void sx_latch_at_savepoint(ulint savepoint, buf_block_t *block); 406 407 /** X-latch a not yet latched block after a savepoint. */ 408 inline void x_latch_at_savepoint(ulint savepoint, buf_block_t *block); 409 410 /** Get the logging mode. 411 @return logging mode */ 412 inline mtr_log_t get_log_mode() const MY_ATTRIBUTE((warn_unused_result)); 413 414 /** Change the logging mode. 415 @param mode logging mode 416 @return old mode */ 417 mtr_log_t set_log_mode(mtr_log_t mode); 418 419 /** Read 1 - 4 bytes from a file page buffered in the buffer pool. 420 @param ptr pointer from where to read 421 @param type MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES 422 @return value read */ 423 inline uint32_t read_ulint(const byte *ptr, mlog_id_t type) const 424 MY_ATTRIBUTE((warn_unused_result)); 425 426 /** Locks a rw-latch in S mode. 427 NOTE: use mtr_s_lock(). 428 @param lock rw-lock 429 @param file file name from where called 430 @param line line number in file */ 431 inline void s_lock(rw_lock_t *lock, const char *file, ulint line); 432 433 /** Locks a rw-latch in X mode. 434 NOTE: use mtr_x_lock(). 435 @param lock rw-lock 436 @param file file name from where called 437 @param line line number in file */ 438 inline void x_lock(rw_lock_t *lock, const char *file, ulint line); 439 440 /** Locks a rw-latch in X mode. 441 NOTE: use mtr_sx_lock(). 442 @param lock rw-lock 443 @param file file name from where called 444 @param line line number in file */ 445 inline void sx_lock(rw_lock_t *lock, const char *file, ulint line); 446 447 /** Acquire a tablespace X-latch. 448 NOTE: use mtr_x_lock_space(). 449 @param[in] space tablespace instance 450 @param[in] file file name from where called 451 @param[in] line line number in file */ 452 void x_lock_space(fil_space_t *space, const char *file, ulint line); 453 454 /** Release an object in the memo stack. 455 @param object object 456 @param type object type: MTR_MEMO_S_LOCK, ... */ 457 void memo_release(const void *object, ulint type); 458 459 /** Release a page latch. 460 @param[in] ptr pointer to within a page frame 461 @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */ 462 void release_page(const void *ptr, mtr_memo_type_t type); 463 464 /** Note that the mini-transaction has modified data. */ set_modifiedmtr_t465 void set_modified() { m_impl.m_modifications = true; } 466 467 /** Set the state to not-modified. This will not log the 468 changes. This is only used during redo log apply, to avoid 469 logging the changes. */ discard_modificationsmtr_t470 void discard_modifications() { m_impl.m_modifications = false; } 471 472 /** Get the LSN of commit(). 473 @return the commit LSN 474 @retval 0 if the transaction only modified temporary tablespaces or logging 475 is disabled globally. */ commit_lsnmtr_t476 lsn_t commit_lsn() const MY_ATTRIBUTE((warn_unused_result)) { 477 ut_ad(has_committed()); 478 ut_ad(m_impl.m_log_mode == MTR_LOG_ALL); 479 return (m_commit_lsn); 480 } 481 482 /** Note that we are inside the change buffer code. */ enter_ibufmtr_t483 void enter_ibuf() { m_impl.m_inside_ibuf = true; } 484 485 /** Note that we have exited from the change buffer code. */ exit_ibufmtr_t486 void exit_ibuf() { m_impl.m_inside_ibuf = false; } 487 488 /** @return true if we are inside the change buffer code */ is_inside_ibufmtr_t489 bool is_inside_ibuf() const MY_ATTRIBUTE((warn_unused_result)) { 490 return (m_impl.m_inside_ibuf); 491 } 492 493 /* 494 @return true if the mini-transaction is active */ is_activemtr_t495 bool is_active() const MY_ATTRIBUTE((warn_unused_result)) { 496 return (m_impl.m_state == MTR_STATE_ACTIVE); 497 } 498 499 /** Get flush observer 500 @return flush observer */ get_flush_observermtr_t501 FlushObserver *get_flush_observer() const MY_ATTRIBUTE((warn_unused_result)) { 502 return (m_impl.m_flush_observer); 503 } 504 505 /** Set flush observer 506 @param[in] observer flush observer */ set_flush_observermtr_t507 void set_flush_observer(FlushObserver *observer) { 508 ut_ad(observer == nullptr || m_impl.m_log_mode == MTR_LOG_NO_REDO); 509 510 m_impl.m_flush_observer = observer; 511 } 512 513 #ifdef UNIV_DEBUG 514 /** Check if memo contains the given item. 515 @param memo memo stack 516 @param object object to search 517 @param type type of object 518 @return true if contains */ 519 static bool memo_contains(mtr_buf_t *memo, const void *object, ulint type) 520 MY_ATTRIBUTE((warn_unused_result)); 521 522 /** Check if memo contains the given item. 523 @param ptr object to search 524 @param flags specify types of object (can be ORred) of 525 MTR_MEMO_PAGE_S_FIX ... values 526 @return true if contains */ 527 bool memo_contains_flagged(const void *ptr, ulint flags) const 528 MY_ATTRIBUTE((warn_unused_result)); 529 530 /** Check if memo contains the given page. 531 @param[in] ptr pointer to within buffer frame 532 @param[in] flags specify types of object with OR of 533 MTR_MEMO_PAGE_S_FIX... values 534 @return the block 535 @retval NULL if not found */ 536 buf_block_t *memo_contains_page_flagged(const byte *ptr, ulint flags) const 537 MY_ATTRIBUTE((warn_unused_result)); 538 539 /** Mark the given latched page as modified. 540 @param[in] ptr pointer to within buffer frame */ 541 void memo_modify_page(const byte *ptr); 542 543 /** Print info of an mtr handle. */ 544 void print() const; 545 546 /** @return true if the mini-transaction has committed */ has_committedmtr_t547 bool has_committed() const MY_ATTRIBUTE((warn_unused_result)) { 548 return (m_impl.m_state == MTR_STATE_COMMITTED); 549 } 550 551 /** @return true if the mini-transaction is committing */ is_committingmtr_t552 bool is_committing() const { 553 return (m_impl.m_state == MTR_STATE_COMMITTING); 554 } 555 556 /** @return true if mini-transaction contains modifications. */ has_modificationsmtr_t557 bool has_modifications() const MY_ATTRIBUTE((warn_unused_result)) { 558 return (m_impl.m_modifications); 559 } 560 561 /** @return the memo stack */ get_memomtr_t562 const mtr_buf_t *get_memo() const MY_ATTRIBUTE((warn_unused_result)) { 563 return (&m_impl.m_memo); 564 } 565 566 /** @return the memo stack */ get_memomtr_t567 mtr_buf_t *get_memo() MY_ATTRIBUTE((warn_unused_result)) { 568 return (&m_impl.m_memo); 569 } 570 571 /** Computes the number of bytes that would be written to the redo 572 log if mtr was committed right now (excluding headers of log blocks). 573 @return number of bytes of the colllected log records increased 574 by 1 if MLOG_MULTI_REC_END would already be required */ get_expected_log_sizemtr_t575 size_t get_expected_log_size() const { 576 return (m_impl.m_log.size() + (m_impl.m_n_log_recs > 1 ? 1 : 0)); 577 } 578 579 void wait_for_flush(); 580 #endif /* UNIV_DEBUG */ 581 582 /** @return true if a record was added to the mini-transaction */ is_dirtymtr_t583 bool is_dirty() const MY_ATTRIBUTE((warn_unused_result)) { 584 return (m_impl.m_made_dirty); 585 } 586 587 /** Note that a record has been added to the log */ added_recmtr_t588 void added_rec() { ++m_impl.m_n_log_recs; } 589 590 /** Get the buffered redo log of this mini-transaction. 591 @return redo log */ get_logmtr_t592 const mtr_buf_t *get_log() const MY_ATTRIBUTE((warn_unused_result)) { 593 ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); 594 595 return (&m_impl.m_log); 596 } 597 598 /** Get the buffered redo log of this mini-transaction. 599 @return redo log */ get_logmtr_t600 mtr_buf_t *get_log() MY_ATTRIBUTE((warn_unused_result)) { 601 ut_ad(m_impl.m_magic_n == MTR_MAGIC_N); 602 603 return (&m_impl.m_log); 604 } 605 606 /** Push an object to an mtr memo stack. 607 @param object object 608 @param type object type: MTR_MEMO_S_LOCK, ... */ 609 inline void memo_push(void *object, mtr_memo_type_t type); 610 611 /** Check if this mini-transaction is dirtying a clean page. 612 @param block block being x-fixed 613 @return true if the mtr is dirtying a clean page. */ 614 static bool is_block_dirtied(const buf_block_t *block) 615 MY_ATTRIBUTE((warn_unused_result)); 616 617 /** Matrix to check if a mode update request should be ignored. */ 618 static bool s_mode_update[MTR_LOG_MODE_MAX][MTR_LOG_MODE_MAX]; 619 620 #ifdef UNIV_DEBUG 621 /** For checking invalid mode update requests. */ 622 static bool s_mode_update_valid[MTR_LOG_MODE_MAX][MTR_LOG_MODE_MAX]; 623 #endif /* UNIV_DEBUG */ 624 625 #ifndef UNIV_HOTBACKUP 626 /** Instance level logging information for all mtrs. */ 627 static Logging s_logging; 628 #endif /* !UNIV_HOTBACKUP */ 629 630 private: 631 Impl m_impl; 632 633 /** LSN at commit time */ 634 lsn_t m_commit_lsn; 635 636 /** true if it is synchronous mini-transaction */ 637 bool m_sync; 638 639 class Command; 640 641 friend class Command; 642 }; 643 644 #ifndef UNIV_HOTBACKUP 645 #ifdef UNIV_DEBUG 646 647 /** Reserves space in the log buffer and writes a single MLOG_TEST. 648 @param[in,out] log redo log 649 @param[in] payload number of extra bytes within the record, 650 not greater than 1024 651 @return end_lsn pointing to the first byte after the written record */ 652 lsn_t mtr_commit_mlog_test(log_t &log, size_t payload = 0); 653 654 /** Reserves space in the log buffer and writes a single MLOG_TEST. 655 Adjusts size of the payload in the record, in order to fill the current 656 block up to its boundary. If nothing else is happening in parallel, 657 we could expect to see afterwards: 658 (cur_lsn + space_left) % OS_FILE_LOG_BLOCK_SIZE == LOG_BLOCK_HDR_SIZE, 659 where cur_lsn = log_get_lsn(log). 660 @param[in,out] log redo log 661 @param[in] space_left extra bytes left to the boundary of block, 662 must be not greater than 496 */ 663 void mtr_commit_mlog_test_filling_block(log_t &log, size_t space_left = 0); 664 665 #endif /* UNIV_DEBUG */ 666 #endif /* !UNIV_HOTBACKUP */ 667 668 #include "mtr0mtr.ic" 669 670 #endif /* mtr0mtr_h */ 671