summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-03-31 14:39:21 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2023-03-31 14:39:21 +0300
commit8912d174f6fa13272f036eaf0075351723c3d30f (patch)
treecc091deb6e422e6695c32bfa02e823ea2a319c40
parent62dc741f12be59db580ef82bc62a9a33f6d1563d (diff)
downloadmariadb-git-8912d174f6fa13272f036eaf0075351723c3d30f.tar.gz
optimize
-rw-r--r--storage/innobase/include/log0recv.h15
-rw-r--r--storage/innobase/log/log0recv.cc77
2 files changed, 51 insertions, 41 deletions
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index 366ab39e543..c809a274b4e 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -282,9 +282,6 @@ private:
List elements are linked via buf_block_t::unzip_LRU. */
UT_LIST_BASE_NODE_T(buf_block_t) blocks;
public:
- /** Check whether the number of read redo log blocks exceeds the maximum.
- @return whether the memory is exhausted */
- inline bool is_memory_exhausted();
/** Apply buffered log to persistent data pages.
@param last_batch whether it is possible to write more redo log */
void apply(bool last_batch);
@@ -317,7 +314,17 @@ public:
inline void add(map::iterator it, lsn_t start_lsn, lsn_t lsn,
const byte *l, size_t len);
- enum parse_mtr_result { OK, PREMATURE_EOF, GOT_EOF };
+ /** Parsing result */
+ enum parse_mtr_result {
+ /** a record was successfully parsed */
+ OK,
+ /** the log ended prematurely (need to read more) */
+ PREMATURE_EOF,
+ /** the end of the log was reached */
+ GOT_EOF,
+ /** we ran out of memory (store=true, if_exists=false) */
+ GOT_OOM
+ };
private:
/** Parse and register one log_t::FORMAT_10_8 mini-transaction.
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index d52546c2b38..148ab4ce55b 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2794,7 +2794,34 @@ recv_sys_t::parse_mtr_result recv_sys_t::parse(source &l, bool if_exists)
l+= log_sys.is_encrypted() ? 4U + 8U : 4U;
ut_ad(l == el);
- return OK;
+ if (!store)
+ return OK;
+
+ if (UNIV_LIKELY(UT_LIST_GET_LEN(blocks) * 3 <
+ (srv_buf_pool_old_size >> srv_page_size_shift)))
+ {
+ if (report(time(nullptr)))
+ {
+ const size_t n= pages.size();
+ sql_print_information("InnoDB: Parsed redo log up to LSN=" LSN_PF
+ "; to recover: %zu pages", lsn, n);
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "Parsed redo log up to LSN=" LSN_PF
+ "; to recover: %zu pages", lsn, n);
+ }
+ return OK;
+ }
+
+ DBUG_PRINT("ib_log",("Ran out of memory and last stored lsn " LSN_PF
+ " last stored offset %zu\n", lsn, offset));
+ if (if_exists)
+ {
+ apply(false);
+ return OK;
+ }
+
+ last_stored_lsn= lsn;
+ return GOT_OOM;
}
template<bool store>
@@ -3570,18 +3597,6 @@ next_free_block:
clear();
}
-/** Check whether the number of read redo log blocks exceeds the maximum.
-@return whether the memory is exhausted */
-inline bool recv_sys_t::is_memory_exhausted()
-{
- if (UT_LIST_GET_LEN(blocks) * 3 <
- (srv_buf_pool_old_size >> srv_page_size_shift))
- return false;
- DBUG_PRINT("ib_log",("Ran out of memory and last stored lsn " LSN_PF
- " last stored offset %zu\n", lsn, offset));
- return true;
-}
-
/** Scan log_t::FORMAT_10_8 log store records to the parsing buffer.
@param last_phase whether changes can be applied to the tablespaces
@return whether rescan is needed (not everything was stored) */
@@ -3674,7 +3689,8 @@ static bool recv_scan_log(bool last_phase)
switch (r) {
case recv_sys_t::PREMATURE_EOF:
goto read_more;
- case recv_sys_t::GOT_EOF:
+ default:
+ ut_ad(r == recv_sys_t::GOT_EOF);
break;
case recv_sys_t::OK:
if (b == FILE_CHECKPOINT + 2 + 8 || (b & 0xf0) == FILE_MODIFY)
@@ -3704,7 +3720,8 @@ static bool recv_scan_log(bool last_phase)
goto read_more;
case recv_sys_t::GOT_EOF:
break;
- case recv_sys_t::OK:
+ default:
+ ut_ad(r == recv_sys_t::OK);
recv_needed_recovery= true;
if (srv_read_only_mode)
{
@@ -3722,28 +3739,14 @@ static bool recv_scan_log(bool last_phase)
skip_the_rest:
while ((r= recv_sys.parse_pmem<false>(false)) == recv_sys_t::OK);
else
- while ((r= recv_sys.parse_pmem<true>(last_phase)) == recv_sys_t::OK)
- if (!recv_sys.is_memory_exhausted())
- {
- if (recv_sys.report(time(nullptr)))
- {
- const size_t n= recv_sys.pages.size();
- sql_print_information("InnoDB: Parsed redo log up to LSN=" LSN_PF
- "; to recover: %zu pages", recv_sys.lsn, n);
- service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
- "Parsed redo log up to LSN=" LSN_PF
- "; to recover: %zu pages",
- recv_sys.lsn, n);
- }
- }
- else if (last_phase)
- recv_sys.apply(false);
- else
- {
- recv_sys.last_stored_lsn= recv_sys.lsn;
- store= false;
- goto skip_the_rest;
- }
+ {
+ while ((r= recv_sys.parse_pmem<true>(last_phase)) == recv_sys_t::OK);
+ if (r == recv_sys_t::GOT_OOM)
+ {
+ store= false;
+ goto skip_the_rest;
+ }
+ }
if (r != recv_sys_t::PREMATURE_EOF)
{