Commit 177a571e authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-19586 Replace recv_sys_t::addr_hash with a std::map

InnoDB crash recovery buffers redo log records in a hash table.
The function recv_read_in_area() would pick a random hash bucket
and then try to submit read requests for a few nearby pages.
Let us replace the recv_sys.addr_hash with a std::map, which will
automatically be iterated in sorted order.

recv_sys_t::pages: Replaces recv_sys_t::addr_hash, recv_sys_t::n_addrs.

recv_sys_t::recs: Replaces most of recv_addr_t.

recv_t: Encapsulate a raw singly-linked list of records. This reduces
overhead compared to std::forward_list. Storage and cache overhead,
because the next-element pointer also points to the data payload.
Processing overhead, because recv_sys_t::recs_t::last will point to
the last record, so that recv_sys_t::add() can append straight to the
end of the list.

RECV_PROCESSED, RECV_DISCARDED: Remove. When a page is fully processed,
it will be deleted from recv_sys.pages.

recv_sys_t::trim(): Replaces recv_addr_trim().

recv_sys_t::add(): Use page_id_t for identifying pages.

recv_fold(), recv_hash(), recv_get_fil_addr_struct(): Remove.

recv_read_in_area(): Simplify the iteration.
parent 992d2494
...@@ -31,6 +31,7 @@ Created 10/25/1995 Heikki Tuuri ...@@ -31,6 +31,7 @@ Created 10/25/1995 Heikki Tuuri
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
#include "hash0hash.h"
#include "log0recv.h" #include "log0recv.h"
#include "dict0types.h" #include "dict0types.h"
#ifdef UNIV_LINUX #ifdef UNIV_LINUX
......
...@@ -29,7 +29,6 @@ Created 9/20/1997 Heikki Tuuri ...@@ -29,7 +29,6 @@ Created 9/20/1997 Heikki Tuuri
#include "ut0byte.h" #include "ut0byte.h"
#include "buf0types.h" #include "buf0types.h"
#include "hash0hash.h"
#include "log0log.h" #include "log0log.h"
#include "mtr0types.h" #include "mtr0types.h"
...@@ -48,10 +47,10 @@ dberr_t ...@@ -48,10 +47,10 @@ dberr_t
recv_find_max_checkpoint(ulint* max_field) recv_find_max_checkpoint(ulint* max_field)
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Reduces recv_sys.n_addrs for the corrupted page. /** Remove records for a corrupted page.
This function should called when srv_force_recovery > 0. This function should called when srv_force_recovery > 0.
@param[in] bpage buffer pool page */ @param[in] bpage buffer pool page */
void recv_recover_corrupt_page(buf_page_t* bpage); ATTRIBUTE_COLD void recv_recover_corrupt_page(buf_page_t* bpage);
/** Apply any buffered redo log to a page that was just read from a data file. /** Apply any buffered redo log to a page that was just read from a data file.
@param[in,out] bpage buffer pool page */ @param[in,out] bpage buffer pool page */
...@@ -80,13 +79,13 @@ void ...@@ -80,13 +79,13 @@ void
recv_sys_var_init(void); recv_sys_var_init(void);
/*===================*/ /*===================*/
/** Apply the hash table of stored log records to persistent data pages. /** Apply recv_sys.pages to persistent data pages.
@param[in] last_batch whether the change buffer merge will be @param[in] last_batch whether the change buffer merge will be
performed as part of the operation */ performed as part of the operation */
void void
recv_apply_hashed_log_recs(bool last_batch); recv_apply_hashed_log_recs(bool last_batch);
/** Whether to store redo log records to the hash table */ /** Whether to store redo log records in recv_sys.pages */
enum store_t { enum store_t {
/** Do not store redo log records. */ /** Do not store redo log records. */
STORE_NO, STORE_NO,
...@@ -105,8 +104,8 @@ recv_sys.parse_start_lsn is non-zero. ...@@ -105,8 +104,8 @@ recv_sys.parse_start_lsn is non-zero.
@return true if more data added */ @return true if more data added */
bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn); bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn);
/** Parse log records from a buffer and optionally store them to a /** Parse log records from a buffer and optionally store them in recv_sys.pages
hash table to wait merging to file pages. to wait merging to file pages.
@param[in] checkpoint_lsn the LSN of the latest checkpoint @param[in] checkpoint_lsn the LSN of the latest checkpoint
@param[in] store whether to store page operations @param[in] store whether to store page operations
@param[in] apply whether to apply the records @param[in] apply whether to apply the records
...@@ -144,8 +143,12 @@ struct recv_data_t{ ...@@ -144,8 +143,12 @@ struct recv_data_t{
/** Stored log record struct */ /** Stored log record struct */
struct recv_t{ struct recv_t{
mlog_id_t type; /*!< log record type */ /** next record */
ulint len; /*!< log record body length in bytes */ recv_t* next;
/** log record body length in bytes */
uint32_t len;
/** log record type */
mlog_id_t type;
recv_data_t* data; /*!< chain of blocks containing the log record recv_data_t* data; /*!< chain of blocks containing the log record
body */ body */
lsn_t start_lsn;/*!< start lsn of the log segment written by lsn_t start_lsn;/*!< start lsn of the log segment written by
...@@ -156,8 +159,6 @@ struct recv_t{ ...@@ -156,8 +159,6 @@ struct recv_t{
the mtr which generated this log record: NOTE the mtr which generated this log record: NOTE
that this is not necessarily the end lsn of that this is not necessarily the end lsn of
this log record */ this log record */
UT_LIST_NODE_T(recv_t)
rec_list;/*!< list of log records for this page */
}; };
struct recv_dblwr_t { struct recv_dblwr_t {
...@@ -205,7 +206,7 @@ struct recv_sys_t{ ...@@ -205,7 +206,7 @@ struct recv_sys_t{
lsn_t parse_start_lsn; lsn_t parse_start_lsn;
/*!< this is the lsn from which we were able to /*!< this is the lsn from which we were able to
start parsing log records and adding them to start parsing log records and adding them to
the hash table; zero if a suitable pages; zero if a suitable
start point not found yet */ start point not found yet */
lsn_t scanned_lsn; lsn_t scanned_lsn;
/*!< the log data has been scanned up to this /*!< the log data has been scanned up to this
...@@ -234,9 +235,38 @@ struct recv_sys_t{ ...@@ -234,9 +235,38 @@ struct recv_sys_t{
ib_time_t progress_time; ib_time_t progress_time;
mem_heap_t* heap; /*!< memory heap of log records and file mem_heap_t* heap; /*!< memory heap of log records and file
addresses*/ addresses*/
hash_table_t* addr_hash;/*!< hash table of file addresses of pages */
ulint n_addrs;/*!< number of not processed hashed file /** buffered records waiting to be applied to a page */
addresses in the hash table */ struct recs_t
{
/** Recovery state */
enum {
/** not yet processed */
RECV_NOT_PROCESSED,
/** not processed; the page will be reinitialized */
RECV_WILL_NOT_READ,
/** page is being read */
RECV_BEING_READ,
/** log records are being applied on the page */
RECV_BEING_PROCESSED
} state;
/** First log record */
recv_t* log;
/** Last log record */
recv_t* last;
};
using map = std::map<const page_id_t, recs_t,
std::less<const page_id_t>,
ut_allocator<std::pair<const page_id_t,recs_t>>>;
/** buffered records waiting to be applied to pages */
map pages;
/** Process a record that indicates that a tablespace is
being shrunk in size.
@param page_id first page identifier that is not in the file
@param lsn log sequence number of the shrink operation */
inline void trim(const page_id_t page_id, lsn_t lsn);
/** Undo tablespaces for which truncate has been logged /** Undo tablespaces for which truncate has been logged
(indexed by id - srv_undo_space_id_start) */ (indexed by id - srv_undo_space_id_start) */
...@@ -249,7 +279,7 @@ struct recv_sys_t{ ...@@ -249,7 +279,7 @@ struct recv_sys_t{
recv_dblwr_t dblwr; recv_dblwr_t dblwr;
/** Lastly added LSN to the hash table of log records. */ /** Last added LSN to pages. */
lsn_t last_stored_lsn; lsn_t last_stored_lsn;
/** Initialize the redo log recovery subsystem. */ /** Initialize the redo log recovery subsystem. */
...@@ -265,13 +295,12 @@ struct recv_sys_t{ ...@@ -265,13 +295,12 @@ struct recv_sys_t{
/** Store a redo log record for applying. /** Store a redo log record for applying.
@param type record type @param type record type
@param space tablespace identifier @param page_id page identifier
@param page_no page number
@param body record body @param body record body
@param rec_end end of record @param rec_end end of record
@param lsn start LSN of the mini-transaction @param lsn start LSN of the mini-transaction
@param end_lsn end LSN of the mini-transaction */ @param end_lsn end LSN of the mini-transaction */
inline void add(mlog_id_t type, ulint space, ulint page_no, inline void add(mlog_id_t type, const page_id_t page_id,
byte* body, byte* rec_end, lsn_t lsn, byte* body, byte* rec_end, lsn_t lsn,
lsn_t end_lsn); lsn_t end_lsn);
...@@ -301,8 +330,8 @@ otherwise. Note that this is FALSE while a background thread is ...@@ -301,8 +330,8 @@ otherwise. Note that this is FALSE while a background thread is
rolling back incomplete transactions. */ rolling back incomplete transactions. */
extern volatile bool recv_recovery_on; extern volatile bool recv_recovery_on;
/** If the following is TRUE, the buffer pool file pages must be invalidated /** If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if after recovery and no ibuf operations are allowed; this will be set if
the log record hash table becomes too full, and log records must be merged recv_sys.pages becomes too full, and log records must be merged
to file pages already before the recovery is finished: in this case no to file pages already before the recovery is finished: in this case no
ibuf operations are allowed, as they could modify the pages read in the ibuf operations are allowed, as they could modify the pages read in the
buffer pool before the pages have been recovered to the up-to-date state. buffer pool before the pages have been recovered to the up-to-date state.
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment