mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
MDEV-30657 InnoDB: Not applying UNDO_APPEND due to corruption
This almost completely reverts
commit acd23da4c2 and
retains a safe optimization:
recv_sys_t::parse(): Remove any old redo log records for the
truncated tablespace, to free up memory earlier.
If recovery consists of multiple batches, then recv_sys_t::apply()
will must invoke recv_sys_t::trim() again to avoid wrongly
applying old log records to an already truncated undo tablespace.
This commit is contained in:
parent
192427e37d
commit
5300c0fb76
2 changed files with 21 additions and 7 deletions
|
|
@ -266,9 +266,15 @@ private:
|
|||
@param lsn log sequence number of the shrink operation */
|
||||
inline void trim(const page_id_t page_id, lsn_t lsn);
|
||||
|
||||
/** Truncated undo tablespace size for which truncate has been logged
|
||||
(indexed by page_id_t::space() - srv_undo_space_id_start), or 0 */
|
||||
unsigned truncated_undo_spaces[127];
|
||||
/** Undo tablespaces for which truncate has been logged
|
||||
(indexed by page_id_t::space() - srv_undo_space_id_start) */
|
||||
struct trunc
|
||||
{
|
||||
/** log sequence number of FILE_CREATE, or 0 if none */
|
||||
lsn_t lsn;
|
||||
/** truncated size of the tablespace, or 0 if not truncated */
|
||||
unsigned pages;
|
||||
} truncated_undo_spaces[127];
|
||||
|
||||
public:
|
||||
/** The contents of the doublewrite buffer */
|
||||
|
|
|
|||
|
|
@ -1952,7 +1952,8 @@ same_page:
|
|||
/* The entire undo tablespace will be reinitialized by
|
||||
innodb_undo_log_truncate=ON. Discard old log for all pages. */
|
||||
trim({space_id, 0}, recovered_lsn);
|
||||
truncated_undo_spaces[space_id - srv_undo_space_id_start]= page_no;
|
||||
truncated_undo_spaces[space_id - srv_undo_space_id_start]=
|
||||
{ recovered_lsn, page_no };
|
||||
if (undo_space_trunc)
|
||||
undo_space_trunc(space_id);
|
||||
#endif
|
||||
|
|
@ -2677,15 +2678,22 @@ void recv_sys_t::apply(bool last_batch)
|
|||
|
||||
for (auto id= srv_undo_tablespaces_open; id--;)
|
||||
{
|
||||
if (unsigned pages= truncated_undo_spaces[id])
|
||||
const trunc& t= truncated_undo_spaces[id];
|
||||
if (t.lsn)
|
||||
{
|
||||
if (fil_space_t *space= fil_space_get(id + srv_undo_space_id_start))
|
||||
/* The entire undo tablespace will be reinitialized by
|
||||
innodb_undo_log_truncate=ON. Discard old log for all pages.
|
||||
Even though we recv_sys_t::parse() already invoked trim(),
|
||||
this will be needed in case recovery consists of multiple batches
|
||||
(there was an invocation with !last_batch). */
|
||||
trim({id + srv_undo_space_id_start, 0}, t.lsn);
|
||||
if (fil_space_t *space = fil_space_get(id + srv_undo_space_id_start))
|
||||
{
|
||||
ut_ad(UT_LIST_GET_LEN(space->chain) == 1);
|
||||
fil_node_t *file= UT_LIST_GET_FIRST(space->chain);
|
||||
ut_ad(file->is_open());
|
||||
os_file_truncate(file->name, file->handle,
|
||||
os_offset_t{pages} << srv_page_size_shift, true);
|
||||
os_offset_t{t.pages} << srv_page_size_shift, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue