Skip to content

Commit 1afc682

Browse files
committed
MDEV-36024 preparation: Shrink mtr_buf_t
mtr_t::get_log_size(): Remove. mtr_t::crc32c(): New function: compute CRC-32C and determine the size, including the sequence byte and the CRC-32C. mtr_t::encrypt(): Return the size, similar to crc32c(). mtr_t::log_file_op(): Return the size written. fil_name_write(): Remove. Let us invoke mtr_t::log_file_op() directly. fil_names_clear(): Keep track of the available size without invoking mtr_t::get_log_size(). mtr_buf_t::m_size: Remove. mtr_buf_t::list_t: Use ilist instead of sized_ilist. mtr_buf_t::for_each_block(): Remove. Let us allow iteration via begin() and end(), without any lambda function objects.
1 parent ad44e1b commit 1afc682

File tree

5 files changed

+87
-141
lines changed

5 files changed

+87
-141
lines changed

storage/innobase/fil/fil0fil.cc

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,12 +1423,15 @@ fil_space_t *fil_space_t::get(uint32_t id) noexcept
14231423
@param type file operation
14241424
@param first_page_no first page number in the file
14251425
@param path file path
1426-
@param new_path new file path for type=FILE_RENAME */
1427-
inline void mtr_t::log_file_op(mfile_type_t type, uint32_t space_id,
1428-
const char *path, const char *new_path)
1426+
@param new_path new file path for type=FILE_RENAME
1427+
@return number of bytes written */
1428+
inline size_t mtr_t::log_file_op(mfile_type_t type, uint32_t space_id,
1429+
const char *path, const char *new_path)
1430+
noexcept
14291431
{
14301432
ut_ad((new_path != nullptr) == (type == FILE_RENAME));
14311433
ut_ad(!(byte(type) & 15));
1434+
ut_ad(!is_predefined_tablespace(space_id));
14321435

14331436
/* fil_name_parse() requires that there be at least one path
14341437
separator and that the file path end with ".ibd". */
@@ -1437,7 +1440,7 @@ inline void mtr_t::log_file_op(mfile_type_t type, uint32_t space_id,
14371440

14381441
m_modifications= true;
14391442
if (!is_logged())
1440-
return;
1443+
return 0;
14411444
m_last= nullptr;
14421445

14431446
const size_t len= strlen(path);
@@ -1469,25 +1472,16 @@ inline void mtr_t::log_file_op(mfile_type_t type, uint32_t space_id,
14691472

14701473
m_log.close(end);
14711474

1472-
if (new_path)
1475+
if (new_len)
14731476
{
14741477
ut_ad(strchr(new_path, '/'));
14751478
m_log.push(reinterpret_cast<const byte*>(path), uint32_t(len + 1));
14761479
m_log.push(reinterpret_cast<const byte*>(new_path), uint32_t(new_len - 1));
14771480
}
14781481
else
14791482
m_log.push(reinterpret_cast<const byte*>(path), uint32_t(len));
1480-
}
14811483

1482-
/** Write FILE_MODIFY for a file.
1483-
@param[in] space_id tablespace id
1484-
@param[in] name tablespace file name
1485-
@param[in,out] mtr mini-transaction */
1486-
static void fil_name_write(uint32_t space_id, const char *name,
1487-
mtr_t *mtr)
1488-
{
1489-
ut_ad(!is_predefined_tablespace(space_id));
1490-
mtr->log_file_op(FILE_MODIFY, space_id, name);
1484+
return end - log_ptr + len + new_len;
14911485
}
14921486

14931487
fil_space_t *fil_space_t::drop(uint32_t id, pfs_os_file_t *detached_handle)
@@ -2986,9 +2980,8 @@ ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write() noexcept
29862980

29872981
mtr_t mtr;
29882982
mtr.start();
2989-
fil_name_write(m_user_space->id,
2990-
UT_LIST_GET_FIRST(m_user_space->chain)->name,
2991-
&mtr);
2983+
mtr.log_file_op(FILE_MODIFY, m_user_space->id,
2984+
UT_LIST_GET_FIRST(m_user_space->chain)->name);
29922985
mtr.commit_files();
29932986
}
29942987

@@ -3005,14 +2998,18 @@ ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn) noexcept
30052998
ut_ad(log_sys.is_latest());
30062999

30073000
mtr.start();
3001+
constexpr size_t budget = recv_sys.MTR_SIZE_MAX - (3 + 5);
3002+
size_t budget_left = budget;
30083003

30093004
for (auto it = fil_system.named_spaces.begin();
30103005
it != fil_system.named_spaces.end(); ) {
3011-
if (mtr.get_log_size() + strlen(it->chain.start->name)
3012-
>= recv_sys.MTR_SIZE_MAX - (3 + 5)) {
3006+
const char* const name = it->chain.start->name;
3007+
3008+
if (strlen(name) >= budget_left) {
30133009
/* Prevent log parse buffer overflow */
30143010
mtr.commit_files();
30153011
mtr.start();
3012+
budget_left = budget;
30163013
}
30173014

30183015
auto next = std::next(it);
@@ -3033,8 +3030,9 @@ ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn) noexcept
30333030
where max_lsn turned nonzero), we could avoid the
30343031
fil_names_write() call if min_lsn > lsn. */
30353032
ut_ad(UT_LIST_GET_LEN((*it).chain) == 1);
3036-
fil_name_write((*it).id, UT_LIST_GET_FIRST((*it).chain)->name,
3037-
&mtr);
3033+
size_t s = mtr.log_file_op(FILE_MODIFY, (*it).id, name);
3034+
ut_ad(s <= budget_left);
3035+
budget_left -= s;
30383036
it = next;
30393037
}
30403038

storage/innobase/include/dyn0buf.h

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,12 @@ class mtr_buf_t {
155155
friend class mtr_buf_t;
156156
};
157157

158-
typedef sized_ilist<block_t> list_t;
158+
typedef ilist<block_t> list_t;
159159

160160
/** Default constructor */
161161
mtr_buf_t()
162162
:
163-
m_heap(),
164-
m_size()
163+
m_heap()
165164
{
166165
push_back(&m_first_block);
167166
}
@@ -183,11 +182,10 @@ class mtr_buf_t {
183182
m_list.clear();
184183
m_list.push_back(m_first_block);
185184
} else {
185+
ut_ad(front() == &m_first_block);
186+
ut_ad(back() == &m_first_block);
186187
m_first_block.init();
187-
ut_ad(m_list.size() == 1);
188188
}
189-
190-
m_size = 0;
191189
}
192190

193191
/**
@@ -217,13 +215,7 @@ class mtr_buf_t {
217215
void close(const byte* ptr)
218216
{
219217
ut_ad(!m_list.empty());
220-
block_t* block = back();
221-
222-
m_size -= block->used();
223-
224-
block->close(ptr);
225-
226-
m_size += block->used();
218+
back()->close(ptr);
227219
}
228220

229221
/**
@@ -241,8 +233,6 @@ class mtr_buf_t {
241233

242234
block = has_space(size) ? back() : add_block();
243235

244-
m_size += size;
245-
246236
/* See ISO C++03 14.2/4 for why "template" is required. */
247237

248238
return(block->template push<Type>(size));
@@ -264,41 +254,8 @@ class mtr_buf_t {
264254
}
265255
}
266256

267-
/**
268-
Returns the size of the total stored data.
269-
@return data size in bytes */
270-
ulint size() const
271-
MY_ATTRIBUTE((warn_unused_result))
272-
{
273-
#ifdef UNIV_DEBUG
274-
ulint total_size = 0;
275-
276-
for (list_t::iterator it = m_list.begin(), end = m_list.end();
277-
it != end; ++it) {
278-
total_size += it->used();
279-
}
280-
281-
ut_ad(total_size == m_size);
282-
#endif /* UNIV_DEBUG */
283-
return(m_size);
284-
}
285-
286-
/**
287-
Iterate over each block and call the functor.
288-
@return false if iteration was terminated. */
289-
template <typename Functor>
290-
bool for_each_block(const Functor& functor) const
291-
{
292-
for (list_t::iterator it = m_list.begin(), end = m_list.end();
293-
it != end; ++it) {
294-
295-
if (!functor(&*it)) {
296-
return false;
297-
}
298-
}
299-
300-
return(true);
301-
}
257+
list_t::const_iterator begin() const { return m_list.begin(); }
258+
list_t::const_iterator end() const { return m_list.end(); }
302259

303260
/**
304261
@return the first block */
@@ -377,9 +334,6 @@ class mtr_buf_t {
377334
/** Allocated blocks */
378335
list_t m_list;
379336

380-
/** Total size used by all blocks */
381-
ulint m_size;
382-
383337
/** The default block, should always be the first element. This
384338
is for backwards compatibility and to avoid an extra heap allocation
385339
for small REDO log records */

storage/innobase/include/mtr0mtr.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,8 @@ struct mtr_t {
435435
m_memo.emplace_back(mtr_memo_slot_t{object, type});
436436
}
437437

438-
/** @return the size of the log is empty */
439-
size_t get_log_size() const { return m_log.size(); }
440438
/** @return whether the log and memo are empty */
441-
bool is_empty() const { return !get_savepoint() && !get_log_size(); }
439+
bool is_empty() const { return !get_savepoint() && m_log.empty(); }
442440

443441
/** Write an OPT_PAGE_CHECKSUM record. */
444442
inline void page_checksum(const buf_page_t &bpage);
@@ -618,10 +616,11 @@ struct mtr_t {
618616
@param type file operation
619617
@param space_id tablespace identifier
620618
@param path file path
621-
@param new_path new file path for type=FILE_RENAME */
622-
inline void log_file_op(mfile_type_t type, uint32_t space_id,
623-
const char *path,
624-
const char *new_path= nullptr);
619+
@param new_path new file path for type=FILE_RENAME
620+
@return number of bytes written */
621+
inline size_t log_file_op(mfile_type_t type, uint32_t space_id,
622+
const char *path,
623+
const char *new_path= nullptr) noexcept;
625624

626625
/** Add freed page numbers to freed_pages */
627626
void add_freed_offset(fil_space_t *space, uint32_t page)
@@ -692,8 +691,13 @@ struct mtr_t {
692691
tablespace was modified for the first time since fil_names_clear(). */
693692
ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void name_write() noexcept;
694693

695-
/** Encrypt the log */
696-
ATTRIBUTE_NOINLINE void encrypt();
694+
/** Encrypt the log
695+
@return the total size in bytes, excluding the 8-byte nonce */
696+
ATTRIBUTE_NOINLINE size_t encrypt() noexcept;
697+
698+
/** Calculate m_crc of m_log.
699+
@return the total size in bytes, including the 5-byte trailer and CRC-32C */
700+
ATTRIBUTE_NOINLINE size_t crc32c() noexcept;
697701

698702
/** Commit the mini-transaction log.
699703
@tparam pmem log_sys.is_mmap()

storage/innobase/log/log0crypt.cc

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -558,11 +558,10 @@ static size_t log_encrypt_buf(byte iv[MY_AES_BLOCK_SIZE],
558558
return 0;
559559
}
560560

561-
/** Encrypt the log */
562-
ATTRIBUTE_NOINLINE void mtr_t::encrypt()
561+
ATTRIBUTE_NOINLINE size_t mtr_t::encrypt() noexcept
563562
{
564563
ut_ad(log_sys.format == log_t::FORMAT_ENC_10_8);
565-
ut_ad(m_log.size());
564+
ut_ad(!m_log.empty());
566565

567566
alignas(8) byte iv[MY_AES_BLOCK_SIZE];
568567

@@ -572,35 +571,36 @@ ATTRIBUTE_NOINLINE void mtr_t::encrypt()
572571
byte *dst= static_cast<byte*>(alloca(srv_page_size));
573572
mach_write_to_8(iv, m_commit_lsn);
574573
mtr_buf_t::block_t *start= nullptr;
575-
size_t size= 0, start_size= 0;
574+
size_t size= 0, start_size= 0, log_size= 5;
576575
m_crc= 0;
577576

578-
m_log.for_each_block([&](mtr_buf_t::block_t *b)
577+
for (mtr_buf_t::block_t &b : m_log)
579578
{
580579
ut_ad(t - tmp + size <= srv_page_size);
581-
byte *buf= b->begin();
580+
log_size+= b.used();
581+
byte *buf= b.begin();
582582
if (!start)
583583
{
584584
parse:
585585
ut_ad(t == tmp);
586-
size= log_encrypt_buf(iv, t, buf, b->end());
586+
size= log_encrypt_buf(iv, t, buf, b.end());
587587
if (!size)
588588
{
589589
ut_ad(t == tmp);
590590
start_size= 0;
591591
}
592592
else
593593
{
594-
start= b;
594+
start= &b;
595595
start_size= t - tmp;
596596
}
597-
m_crc= my_crc32c(m_crc, buf, b->end() - buf - start_size);
597+
m_crc= my_crc32c(m_crc, buf, b.end() - buf - start_size);
598598
}
599-
else if (size > b->used())
599+
else if (size > b.used())
600600
{
601-
::memcpy(t, buf, b->used());
602-
t+= b->used();
603-
size-= b->used();
601+
::memcpy(t, buf, b.used());
602+
t+= b.used();
603+
size-= b.used();
604604
}
605605
else
606606
{
@@ -620,22 +620,22 @@ ATTRIBUTE_NOINLINE void mtr_t::encrypt()
620620
/* Copy the encrypted data back to the log snippets. */
621621
::memcpy(start->end() - start_size, dst, start_size);
622622
t= dst + start_size;
623-
for (ilist<mtr_buf_t::block_t>::iterator i(start); &*++i != b;)
623+
for (ilist<mtr_buf_t::block_t>::iterator i(start); &*++i != &b;)
624624
{
625625
const size_t l{i->used()};
626626
::memcpy(i->begin(), t, l);
627627
t+= l;
628628
}
629-
::memcpy(b->begin(), t, size);
629+
::memcpy(b.begin(), t, size);
630630
ut_ad(t + size == dst + len);
631631
t= tmp;
632632
start= nullptr;
633633
goto parse;
634634
}
635-
return true;
636-
});
635+
}
637636

638637
ut_ad(t == tmp);
639638
ut_ad(!start);
640639
ut_ad(!size);
640+
return log_size;
641641
}

0 commit comments

Comments
 (0)