summaryrefslogtreecommitdiff
path: root/storage/innobase/buf/buf0flu.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/buf/buf0flu.cc')
-rw-r--r--storage/innobase/buf/buf0flu.cc112
1 files changed, 75 insertions, 37 deletions
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index ac06bc5bb4e..dec0292a088 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1488,7 +1488,7 @@ void buf_flush_wait_batch_end(bool lru)
@param lsn buf_pool.get_oldest_modification(LSN_MAX) target
@return the number of processed pages
@retval 0 if a buf_pool.flush_list batch is already running */
-ulint buf_flush_list(ulint max_n, lsn_t lsn)
+static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, lsn_t lsn= LSN_MAX)
{
ut_ad(lsn);
@@ -1780,6 +1780,30 @@ ATTRIBUTE_COLD void log_make_checkpoint()
while (!log_checkpoint());
}
+/** Wait for all dirty pages up to an LSN to be written out.
+NOTE: The calling thread is not allowed to hold any buffer page latches! */
+static void buf_flush_wait(lsn_t lsn)
+{
+ ut_ad(lsn <= log_sys.get_lsn());
+
+ while (buf_pool.get_oldest_modification(lsn) < lsn)
+ {
+ if (buf_flush_sync_lsn < lsn)
+ {
+ buf_flush_sync_lsn= lsn;
+ buf_pool.page_cleaner_set_idle(false);
+ pthread_cond_signal(&buf_pool.do_flush_list);
+ }
+ my_cond_wait(&buf_pool.done_flush_list,
+ &buf_pool.flush_list_mutex.m_mutex);
+ }
+
+ /* Wait for the checkpoint. */
+ while (buf_flush_sync_lsn)
+ my_cond_wait(&buf_pool.done_flush_list,
+ &buf_pool.flush_list_mutex.m_mutex);
+}
+
/** 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)
@@ -1796,9 +1820,9 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
if (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn)
{
+ MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
#if 1 /* FIXME: remove this, and guarantee that the page cleaner serves us */
- if (UNIV_UNLIKELY(!buf_page_cleaner_is_active)
- ut_d(|| innodb_page_cleaner_disabled_debug))
+ if (UNIV_UNLIKELY(!buf_page_cleaner_is_active))
{
do
{
@@ -1811,35 +1835,21 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
MONITOR_FLUSH_SYNC_COUNT,
MONITOR_FLUSH_SYNC_PAGES, n_pages);
}
- MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
mysql_mutex_lock(&buf_pool.flush_list_mutex);
}
while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn);
-
- goto try_checkpoint;
}
+ else
#endif
- if (buf_flush_sync_lsn < sync_lsn)
- {
- buf_flush_sync_lsn= sync_lsn;
- pthread_cond_signal(&buf_pool.do_flush_list);
- }
-
- do
{
- tpool::tpool_wait_begin();
thd_wait_begin(nullptr, THD_WAIT_DISKIO);
- my_cond_wait(&buf_pool.done_flush_list,
- &buf_pool.flush_list_mutex.m_mutex);
- thd_wait_end(nullptr);
+ tpool::tpool_wait_begin();
+ buf_flush_wait(sync_lsn);
tpool::tpool_wait_end();
-
- MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
+ thd_wait_end(nullptr);
}
- while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn);
}
-try_checkpoint:
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
if (UNIV_UNLIKELY(log_sys.last_checkpoint_lsn < sync_lsn))
@@ -1872,8 +1882,11 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious)
{
mysql_mutex_lock(&buf_pool.flush_list_mutex);
if (limit < lsn)
+ {
limit= lsn;
- pthread_cond_signal(&buf_pool.do_flush_list);
+ buf_pool.page_cleaner_set_idle(false);
+ pthread_cond_signal(&buf_pool.do_flush_list);
+ }
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
}
}
@@ -1907,10 +1920,6 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn)
MONITOR_FLUSH_SYNC_PAGES, n_flushed);
}
- /* Attempt to perform a log checkpoint upon completing each batch. */
- if (recv_recovery_is_on())
- recv_sys.apply(true);
-
switch (srv_file_flush_method) {
case SRV_NOSYNC:
case SRV_O_DIRECT_NO_FSYNC:
@@ -1927,7 +1936,8 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn)
mysql_mutex_unlock(&log_sys.flush_order_mutex);
const lsn_t checkpoint_lsn= measure ? measure : newest_lsn;
- if (checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT)
+ if (!recv_recovery_is_on() &&
+ checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT)
{
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
log_checkpoint_low(checkpoint_lsn, newest_lsn);
@@ -1951,7 +1961,7 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn)
else if (measure >= buf_flush_async_lsn)
buf_flush_async_lsn= 0;
- /* wake up buf_flush_wait_flushed() */
+ /* wake up buf_flush_wait() */
pthread_cond_broadcast(&buf_pool.done_flush_list);
lsn= std::max(lsn, target);
@@ -2209,7 +2219,7 @@ furious_flush:
if (UNIV_UNLIKELY(lsn_limit != 0))
{
buf_flush_sync_lsn= 0;
- /* wake up buf_flush_wait_flushed() */
+ /* wake up buf_flush_wait() */
pthread_cond_broadcast(&buf_pool.done_flush_list);
}
unemployed:
@@ -2279,7 +2289,7 @@ unemployed:
if (UNIV_UNLIKELY(lsn_limit != 0))
{
n_flushed= buf_flush_list(srv_max_io_capacity, lsn_limit);
- /* wake up buf_flush_wait_flushed() */
+ /* wake up buf_flush_wait() */
pthread_cond_broadcast(&buf_pool.done_flush_list);
goto try_checkpoint;
}
@@ -2384,6 +2394,7 @@ ATTRIBUTE_COLD void buf_flush_page_cleaner_init()
std::thread(buf_flush_page_cleaner).detach();
}
+#if defined(HAVE_SYSTEMD) && !defined(EMBEDDED_LIBRARY)
/** @return the number of dirty pages in the buffer pool */
static ulint buf_flush_list_length()
{
@@ -2392,6 +2403,7 @@ static ulint buf_flush_list_length()
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
return len;
}
+#endif
/** Flush the buffer pool on shutdown. */
ATTRIBUTE_COLD void buf_flush_buffer_pool()
@@ -2402,13 +2414,15 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool()
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"Waiting to flush the buffer pool");
- while (buf_pool.n_flush_list() || buf_flush_list_length())
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+
+ while (buf_pool.get_oldest_modification(0))
{
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
buf_flush_list(srv_max_io_capacity);
- timespec abstime;
-
if (buf_pool.n_flush_list())
{
+ timespec abstime;
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"Waiting to flush " ULINTPF " pages",
buf_flush_list_length());
@@ -2419,22 +2433,46 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool()
&abstime);
mysql_mutex_unlock(&buf_pool.mutex);
}
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
}
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
ut_ad(!buf_pool.any_io_pending());
}
+/** Synchronously flush dirty blocks during recv_sys_t::apply().
+NOTE: The calling thread is not allowed to hold any buffer page latches! */
+void buf_flush_sync_batch(lsn_t lsn)
+{
+ thd_wait_begin(nullptr, THD_WAIT_DISKIO);
+ tpool::tpool_wait_begin();
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ buf_flush_wait(lsn);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ tpool::tpool_wait_end();
+ thd_wait_end(nullptr);
+}
+
/** Synchronously flush dirty blocks.
NOTE: The calling thread is not allowed to hold any buffer page latches! */
void buf_flush_sync()
{
+ if (recv_recovery_is_on())
+ recv_sys.apply(true);
+
+ thd_wait_begin(nullptr, THD_WAIT_DISKIO);
+ tpool::tpool_wait_begin();
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
for (;;)
{
- const ulint n_flushed= buf_flush_list(srv_max_io_capacity);
- buf_flush_wait_batch_end_acquiring_mutex(false);
- if (!n_flushed && !buf_flush_list_length())
- return;
+ const lsn_t lsn= log_sys.get_lsn();
+ buf_flush_wait(lsn);
+ if (lsn == log_sys.get_lsn())
+ break;
}
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ tpool::tpool_wait_end();
+ thd_wait_end(nullptr);
}
#ifdef UNIV_DEBUG