mirror of
https://github.com/MariaDB/server.git
synced 2026-05-14 19:07:15 +02:00
Merge 10.5 into 10.6
This commit is contained in:
commit
101da87228
22 changed files with 647 additions and 455 deletions
|
|
@ -672,6 +672,16 @@ private:
|
|||
/** Count of how manyfold this block is currently bufferfixed. */
|
||||
Atomic_counter<uint32_t> buf_fix_count_;
|
||||
|
||||
/** log sequence number of the START of the log entry written of the
|
||||
oldest modification to this block which has not yet been written
|
||||
to the data file;
|
||||
|
||||
0 if no modifications are pending;
|
||||
1 if no modifications are pending, but the block is in buf_pool.flush_list;
|
||||
2 if modifications are pending, but the block is not in buf_pool.flush_list
|
||||
(because id().space() is the temporary tablespace). */
|
||||
Atomic_counter<lsn_t> oldest_modification_;
|
||||
|
||||
/** type of pending I/O operation; protected by buf_pool.mutex
|
||||
if in_LRU_list */
|
||||
Atomic_relaxed<buf_io_fix> io_fix_;
|
||||
|
|
@ -721,12 +731,6 @@ public:
|
|||
or if state() is BUF_BLOCK_MEMORY or BUF_BLOCK_REMOVE_HASH. */
|
||||
UT_LIST_NODE_T(buf_page_t) list;
|
||||
|
||||
private:
|
||||
/** log sequence number of the START of the log entry written of the
|
||||
oldest modification to this block which has not yet been written
|
||||
to the data file; 0 if no modifications are pending. */
|
||||
Atomic_counter<lsn_t> oldest_modification_;
|
||||
public:
|
||||
/** @name LRU replacement algorithm fields.
|
||||
Protected by buf_pool.mutex. */
|
||||
/* @{ */
|
||||
|
|
@ -841,12 +845,19 @@ public:
|
|||
inline void set_io_fix(buf_io_fix io_fix);
|
||||
inline void set_corrupt_id();
|
||||
|
||||
/** @return the oldest modification */
|
||||
/** @return the log sequence number of the oldest pending modification
|
||||
@retval 0 if the block is not in buf_pool.flush_list
|
||||
@retval 1 if the block is in buf_pool.flush_list but not modified
|
||||
@retval 2 if the block belongs to the temporary tablespace and
|
||||
has unwritten changes */
|
||||
lsn_t oldest_modification() const { return oldest_modification_; }
|
||||
/** Set oldest_modification when adding to buf_pool.flush_list */
|
||||
inline void set_oldest_modification(lsn_t lsn);
|
||||
/** Clear oldest_modification when removing from buf_pool.flush_list */
|
||||
inline void clear_oldest_modification();
|
||||
/** Note that a block is no longer dirty, while not removing
|
||||
it from buf_pool.flush_list */
|
||||
inline void clear_oldest_modification(bool temporary);
|
||||
|
||||
/** Notify that a page in a temporary tablespace has been modified. */
|
||||
void set_temp_modified()
|
||||
|
|
@ -854,7 +865,7 @@ public:
|
|||
ut_ad(fsp_is_system_temporary(id().space()));
|
||||
ut_ad(state() == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(!oldest_modification());
|
||||
oldest_modification_= 1;
|
||||
oldest_modification_= 2;
|
||||
}
|
||||
|
||||
/** Prepare to release a file page to buf_pool.free. */
|
||||
|
|
@ -1462,23 +1473,24 @@ public:
|
|||
inline buf_block_t *block_from_ahi(const byte *ptr) const;
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** @return the block that was made dirty the longest time ago */
|
||||
const buf_page_t *get_oldest_modified() const
|
||||
{
|
||||
mysql_mutex_assert_owner(&flush_list_mutex);
|
||||
const buf_page_t *bpage= UT_LIST_GET_LAST(flush_list);
|
||||
ut_ad(!bpage || !fsp_is_system_temporary(bpage->id().space()));
|
||||
ut_ad(!bpage || bpage->oldest_modification());
|
||||
return bpage;
|
||||
}
|
||||
|
||||
/**
|
||||
@return the smallest oldest_modification lsn for any page
|
||||
@retval empty_lsn if all modified persistent pages have been flushed */
|
||||
lsn_t get_oldest_modification(lsn_t empty_lsn) const
|
||||
lsn_t get_oldest_modification(lsn_t empty_lsn)
|
||||
{
|
||||
const buf_page_t *bpage= get_oldest_modified();
|
||||
return bpage ? bpage->oldest_modification() : empty_lsn;
|
||||
mysql_mutex_assert_owner(&flush_list_mutex);
|
||||
while (buf_page_t *bpage= UT_LIST_GET_LAST(flush_list))
|
||||
{
|
||||
ut_ad(!fsp_is_system_temporary(bpage->id().space()));
|
||||
lsn_t lsn= bpage->oldest_modification();
|
||||
if (lsn != 1)
|
||||
{
|
||||
ut_ad(lsn > 2);
|
||||
return lsn;
|
||||
}
|
||||
delete_from_flush_list(bpage);
|
||||
}
|
||||
return empty_lsn;
|
||||
}
|
||||
|
||||
/** Determine if a buffer block was created by chunk_t::create().
|
||||
|
|
@ -1692,15 +1704,18 @@ public:
|
|||
|
||||
/** Buffer pool mutex */
|
||||
MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t mutex;
|
||||
/** Number of pending LRU flush. */
|
||||
Atomic_counter<ulint> n_flush_LRU;
|
||||
/** Number of pending LRU flush; protected by mutex. */
|
||||
ulint n_flush_LRU_;
|
||||
/** broadcast when n_flush_LRU reaches 0; protected by mutex */
|
||||
pthread_cond_t done_flush_LRU;
|
||||
/** Number of pending flush_list flush. */
|
||||
Atomic_counter<ulint> n_flush_list;
|
||||
/** Number of pending flush_list flush; protected by mutex */
|
||||
ulint n_flush_list_;
|
||||
/** broadcast when n_flush_list reaches 0; protected by mutex */
|
||||
pthread_cond_t done_flush_list;
|
||||
|
||||
TPOOL_SUPPRESS_TSAN ulint n_flush_LRU() const { return n_flush_LRU_; }
|
||||
TPOOL_SUPPRESS_TSAN ulint n_flush_list() const { return n_flush_list_; }
|
||||
|
||||
/** @name General fields */
|
||||
/* @{ */
|
||||
ulint curr_pool_size; /*!< Current pool size in bytes */
|
||||
|
|
@ -1875,8 +1890,8 @@ public:
|
|||
last_activity_count= activity_count;
|
||||
}
|
||||
|
||||
// n_flush_LRU + n_flush_list is approximately COUNT(io_fix()==BUF_IO_WRITE)
|
||||
// in flush_list
|
||||
// n_flush_LRU() + n_flush_list()
|
||||
// is approximately COUNT(io_fix()==BUF_IO_WRITE) in flush_list
|
||||
|
||||
unsigned freed_page_clock;/*!< a sequence number used
|
||||
to count the number of buffer
|
||||
|
|
@ -1961,13 +1976,35 @@ public:
|
|||
/** @return whether any I/O is pending */
|
||||
bool any_io_pending() const
|
||||
{
|
||||
return n_pend_reads || n_flush_LRU || n_flush_list;
|
||||
return n_pend_reads || n_flush_LRU() || n_flush_list();
|
||||
}
|
||||
/** @return total amount of pending I/O */
|
||||
ulint io_pending() const
|
||||
{
|
||||
return n_pend_reads + n_flush_LRU + n_flush_list;
|
||||
return n_pend_reads + n_flush_LRU() + n_flush_list();
|
||||
}
|
||||
|
||||
private:
|
||||
/** Remove a block from the flush list. */
|
||||
inline void delete_from_flush_list_low(buf_page_t *bpage);
|
||||
/** Remove a block from flush_list.
|
||||
@param bpage buffer pool page
|
||||
@param clear whether to invoke buf_page_t::clear_oldest_modification() */
|
||||
void delete_from_flush_list(buf_page_t *bpage, bool clear);
|
||||
public:
|
||||
/** Remove a block from flush_list.
|
||||
@param bpage buffer pool page */
|
||||
void delete_from_flush_list(buf_page_t *bpage)
|
||||
{ delete_from_flush_list(bpage, true); }
|
||||
|
||||
/** Insert a modified block into the flush list.
|
||||
@param block modified block
|
||||
@param lsn start LSN of the mini-transaction that modified the block */
|
||||
void insert_into_flush_list(buf_block_t *block, lsn_t lsn);
|
||||
|
||||
/** Free a page whose underlying file page has been freed. */
|
||||
inline void release_freed_page(buf_page_t *bpage);
|
||||
|
||||
private:
|
||||
/** Temporary memory for page_compressed and encrypted I/O */
|
||||
struct io_buf_t
|
||||
|
|
@ -2080,7 +2117,7 @@ inline void buf_page_t::set_corrupt_id()
|
|||
switch (oldest_modification()) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
ut_ad(fsp_is_system_temporary(id().space()));
|
||||
ut_d(oldest_modification_= 0); /* for buf_LRU_block_free_non_file_page() */
|
||||
break;
|
||||
|
|
@ -2106,7 +2143,7 @@ inline void buf_page_t::set_corrupt_id()
|
|||
inline void buf_page_t::set_oldest_modification(lsn_t lsn)
|
||||
{
|
||||
mysql_mutex_assert_owner(&buf_pool.flush_list_mutex);
|
||||
ut_ad(!oldest_modification());
|
||||
ut_ad(oldest_modification() <= 1);
|
||||
oldest_modification_= lsn;
|
||||
}
|
||||
|
||||
|
|
@ -2121,13 +2158,27 @@ inline void buf_page_t::clear_oldest_modification()
|
|||
oldest_modification_= 0;
|
||||
}
|
||||
|
||||
/** Note that a block is no longer dirty, while not removing
|
||||
it from buf_pool.flush_list */
|
||||
inline void buf_page_t::clear_oldest_modification(bool temporary)
|
||||
{
|
||||
mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex);
|
||||
ut_ad(temporary == fsp_is_system_temporary(id().space()));
|
||||
ut_ad(io_fix_ == BUF_IO_WRITE);
|
||||
ut_ad(temporary ? oldest_modification() == 2 : oldest_modification() > 2);
|
||||
oldest_modification_= !temporary;
|
||||
}
|
||||
|
||||
/** @return whether the block is modified and ready for flushing */
|
||||
inline bool buf_page_t::ready_for_flush() const
|
||||
{
|
||||
mysql_mutex_assert_owner(&buf_pool.mutex);
|
||||
ut_ad(in_LRU_list);
|
||||
ut_a(in_file());
|
||||
return oldest_modification() && io_fix_ == BUF_IO_NONE;
|
||||
ut_ad(fsp_is_system_temporary(id().space())
|
||||
? oldest_modification() == 2
|
||||
: oldest_modification() > 2);
|
||||
return io_fix_ == BUF_IO_NONE;
|
||||
}
|
||||
|
||||
/** @return whether the block can be relocated in memory.
|
||||
|
|
@ -2204,7 +2255,7 @@ MEMORY: is not in free list, LRU list, or flush list, nor page
|
|||
hash table
|
||||
FILE_PAGE: space and offset are defined, is in page hash table
|
||||
if io_fix == BUF_IO_WRITE,
|
||||
buf_pool.n_flush_LRU > 0 || buf_pool.n_flush_list > 0
|
||||
buf_pool.n_flush_LRU() || buf_pool.n_flush_list()
|
||||
|
||||
(1) if buf_fix_count == 0, then
|
||||
is in LRU list, not in free list
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2021, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -56,12 +56,6 @@ the list as they age towards the tail of the LRU.
|
|||
@param id tablespace identifier */
|
||||
void buf_flush_remove_pages(ulint id);
|
||||
|
||||
/** Try to flush all the dirty pages that belong to a given tablespace.
|
||||
@param id tablespace identifier
|
||||
@return number dirty pages that there were for this tablespace */
|
||||
ulint buf_flush_dirty_pages(ulint id)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/*******************************************************************//**
|
||||
Relocates a buffer control block on the flush_list.
|
||||
Note that it is assumed that the contents of bpage has already been
|
||||
|
|
@ -95,10 +89,23 @@ buf_flush_init_for_writing(
|
|||
|
||||
/** Write out dirty blocks from buf_pool.flush_list.
|
||||
@param max_n wished maximum mumber of blocks flushed
|
||||
@param lsn buf_pool.get_oldest_modification(LSN_MAX) target (0=LRU flush)
|
||||
@param lsn buf_pool.get_oldest_modification(LSN_MAX) target
|
||||
@return the number of processed pages
|
||||
@retval 0 if a batch of the same type (lsn==0 or lsn!=0) is already running */
|
||||
ulint buf_flush_lists(ulint max_n, lsn_t lsn);
|
||||
@retval 0 if a buf_pool.flush_list batch is already running */
|
||||
ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, lsn_t lsn= LSN_MAX);
|
||||
|
||||
/** Try to flush dirty pages that belong to a given tablespace.
|
||||
@param space tablespace
|
||||
@param n_flushed number of pages written
|
||||
@return whether the flush for some pages might not have been initiated */
|
||||
bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed= nullptr)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Write out dirty blocks from buf_pool.LRU.
|
||||
@param max_n wished maximum mumber of blocks flushed
|
||||
@return the number of processed pages
|
||||
@retval 0 if a buf_pool.LRU batch is already running */
|
||||
ulint buf_flush_LRU(ulint max_n);
|
||||
|
||||
/** Wait until a flush batch ends.
|
||||
@param lru true=buf_pool.LRU; false=buf_pool.flush_list */
|
||||
|
|
@ -106,9 +113,10 @@ void buf_flush_wait_batch_end(bool lru);
|
|||
/** Wait until all persistent pages are flushed up to a limit.
|
||||
@param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */
|
||||
ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn);
|
||||
/** If innodb_flush_sync=ON, initiate a furious flush.
|
||||
@param lsn buf_pool.get_oldest_modification(LSN_MAX) target */
|
||||
void buf_flush_ahead(lsn_t lsn);
|
||||
/** Initiate more eager page flushing if the log checkpoint age is too old.
|
||||
@param lsn buf_pool.get_oldest_modification(LSN_MAX) target
|
||||
@param furious true=furious flushing, false=limit to innodb_io_capacity */
|
||||
ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious);
|
||||
|
||||
/********************************************************************//**
|
||||
This function should be called at a mini-transaction commit, if a page was
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2019, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2019, 2021, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -26,17 +26,7 @@ Created 11/5/1995 Heikki Tuuri
|
|||
|
||||
#include "assume_aligned.h"
|
||||
#include "buf0buf.h"
|
||||
#include "mtr0mtr.h"
|
||||
#include "srv0srv.h"
|
||||
#include "fsp0types.h"
|
||||
|
||||
/********************************************************************//**
|
||||
Inserts a modified block into the flush list. */
|
||||
void
|
||||
buf_flush_insert_into_flush_list(
|
||||
/*=============================*/
|
||||
buf_block_t* block, /*!< in/out: block which is modified */
|
||||
lsn_t lsn); /*!< in: oldest modification */
|
||||
|
||||
/********************************************************************//**
|
||||
This function should be called at a mini-transaction commit, if a page was
|
||||
|
|
@ -52,8 +42,7 @@ buf_flush_note_modification(
|
|||
lsn_t end_lsn) /*!< in: end lsn of the mtr that
|
||||
modified this block */
|
||||
{
|
||||
ut_ad(!srv_read_only_mode
|
||||
|| fsp_is_system_temporary(block->page.id().space()));
|
||||
ut_ad(!srv_read_only_mode);
|
||||
ut_ad(block->page.state() == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(block->page.buf_fix_count());
|
||||
ut_ad(mach_read_from_8(block->frame + FIL_PAGE_LSN) <= end_lsn);
|
||||
|
|
@ -65,12 +54,12 @@ buf_flush_note_modification(
|
|||
|
||||
const lsn_t oldest_modification = block->page.oldest_modification();
|
||||
|
||||
if (oldest_modification) {
|
||||
if (oldest_modification > 1) {
|
||||
ut_ad(oldest_modification <= start_lsn);
|
||||
} else if (!fsp_is_system_temporary(block->page.id().space())) {
|
||||
buf_flush_insert_into_flush_list(block, start_lsn);
|
||||
} else {
|
||||
} else if (fsp_is_system_temporary(block->page.id().space())) {
|
||||
block->page.set_temp_modified();
|
||||
} else {
|
||||
buf_pool.insert_into_flush_list(block, start_lsn);
|
||||
}
|
||||
|
||||
srv_stats.buf_pool_write_requests.inc();
|
||||
|
|
|
|||
|
|
@ -588,6 +588,17 @@ public:
|
|||
@return number of buffer count added by this mtr */
|
||||
uint32_t get_fix_count(const buf_block_t *block) const;
|
||||
|
||||
/** type of page flushing is needed during commit() */
|
||||
enum page_flush_ahead
|
||||
{
|
||||
/** no need to trigger page cleaner */
|
||||
PAGE_FLUSH_NO= 0,
|
||||
/** asynchronous flushing is needed */
|
||||
PAGE_FLUSH_ASYNC,
|
||||
/** furious flushing is needed */
|
||||
PAGE_FLUSH_SYNC
|
||||
};
|
||||
|
||||
private:
|
||||
/** Log a write of a byte string to a page.
|
||||
@param block buffer page
|
||||
|
|
@ -621,7 +632,7 @@ private:
|
|||
/** Append the redo log records to the redo log buffer.
|
||||
@param len number of bytes to write
|
||||
@return {start_lsn,flush_ahead} */
|
||||
inline std::pair<lsn_t,bool> finish_write(ulint len);
|
||||
inline std::pair<lsn_t,page_flush_ahead> finish_write(ulint len);
|
||||
|
||||
/** Release the resources */
|
||||
inline void release_resources();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -32,7 +32,7 @@ inline bool mtr_t::is_block_dirtied(const buf_block_t *block)
|
|||
{
|
||||
ut_ad(block->page.state() == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(block->page.buf_fix_count());
|
||||
return !block->page.oldest_modification();
|
||||
return block->page.oldest_modification() <= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1111,10 +1111,9 @@ void os_aio_free();
|
|||
@retval DB_IO_ERROR on I/O error */
|
||||
dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n);
|
||||
|
||||
/** Waits until there are no pending writes in os_aio_write_array. There can
|
||||
be other, synchronous, pending writes. */
|
||||
void
|
||||
os_aio_wait_until_no_pending_writes();
|
||||
/** Wait until there are no pending asynchronous writes.
|
||||
Only used on FLUSH TABLES...FOR EXPORT. */
|
||||
void os_aio_wait_until_no_pending_writes();
|
||||
|
||||
/** Wait until all pending asynchronous reads have completed. */
|
||||
void os_aio_wait_until_no_pending_reads();
|
||||
|
|
|
|||
|
|
@ -756,9 +756,6 @@ struct export_var_t{
|
|||
ulint innodb_os_log_fsyncs; /*!< n_log_flushes */
|
||||
ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */
|
||||
ulint innodb_os_log_pending_fsyncs; /*!< n_pending_log_flushes */
|
||||
ulint innodb_pages_created; /*!< buf_pool.stat.n_pages_created */
|
||||
ulint innodb_pages_read; /*!< buf_pool.stat.n_pages_read*/
|
||||
ulint innodb_pages_written; /*!< buf_pool.stat.n_pages_written */
|
||||
ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */
|
||||
ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */
|
||||
int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue