summaryrefslogtreecommitdiff
path: root/storage/innobase/srv/srv0srv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/srv/srv0srv.cc')
-rw-r--r--storage/innobase/srv/srv0srv.cc585
1 files changed, 344 insertions, 241 deletions
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 30e0698eab9..4c5753ac40e 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -39,8 +39,6 @@ Created 10/8/1995 Heikki Tuuri
*******************************************************/
/* Dummy comment */
-#include "m_string.h" /* for my_sys.h */
-#include "my_sys.h" /* DEBUG_SYNC_C */
#include "srv0srv.h"
#include "ut0mem.h"
@@ -61,6 +59,7 @@ Created 10/8/1995 Heikki Tuuri
#include "btr0sea.h"
#include "dict0load.h"
#include "dict0boot.h"
+#include "dict0stats_bg.h" /* dict_stats_event */
#include "srv0start.h"
#include "row0mysql.h"
#include "ha_prototypes.h"
@@ -72,10 +71,6 @@ Created 10/8/1995 Heikki Tuuri
#include "mysql/plugin.h"
#include "mysql/service_thd_wait.h"
-/* The following counter is incremented whenever there is some user activity
-in the server */
-UNIV_INTERN ulint srv_activity_count = 0;
-
/* The following is the maximum allowed duration of a lock wait. */
UNIV_INTERN ulint srv_fatal_semaphore_wait_threshold = 600;
@@ -88,6 +83,8 @@ UNIV_INTERN ibool srv_error_monitor_active = FALSE;
UNIV_INTERN ibool srv_buf_dump_thread_active = FALSE;
+UNIV_INTERN ibool srv_dict_stats_thread_active = FALSE;
+
UNIV_INTERN const char* srv_main_thread_op_info = "";
/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
@@ -106,6 +103,9 @@ UNIV_INTERN char* srv_undo_dir = NULL;
/** The number of tablespaces to use for rollback segments. */
UNIV_INTERN ulong srv_undo_tablespaces = 8;
+/** The number of UNDO tablespaces that are open and ready to use. */
+UNIV_INTERN ulint srv_undo_tablespaces_open = 8;
+
/* The number of rollback segments to use */
UNIV_INTERN ulong srv_undo_logs = 1;
@@ -113,6 +113,10 @@ UNIV_INTERN ulong srv_undo_logs = 1;
UNIV_INTERN char* srv_arch_dir = NULL;
#endif /* UNIV_LOG_ARCHIVE */
+/** Set if InnoDB must operate in read-only mode. We don't do any
+recovery and open all tables in RO mode instead of RW mode. We don't
+sync the max trx id to disk either. */
+UNIV_INTERN my_bool srv_read_only_mode;
/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
UNIV_INTERN my_bool srv_file_per_table;
@@ -130,6 +134,10 @@ UNIV_INTERN ulint srv_max_file_format_at_startup = UNIV_FORMAT_MAX;
/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
UNIV_INTERN ibool srv_locks_unsafe_for_binlog = FALSE;
+/** Sort buffer size in index creation */
+UNIV_INTERN ulong srv_sort_buf_size = 1048576;
+/** Maximum modification log file size for online index creation */
+UNIV_INTERN unsigned long long srv_online_max_size;
/* If this flag is TRUE, then we will use the native aio of the
OS (provided we compiled Innobase with it in), otherwise we will
@@ -172,15 +180,16 @@ the user from forgetting the 'newraw' keyword to my.cnf */
UNIV_INTERN ibool srv_created_new_raw = FALSE;
-UNIV_INTERN char** srv_log_group_home_dirs = NULL;
+UNIV_INTERN char* srv_log_group_home_dir = NULL;
-UNIV_INTERN ulint srv_n_log_groups = ULINT_MAX;
-UNIV_INTERN ulint srv_n_log_files = ULINT_MAX;
+UNIV_INTERN ulong srv_n_log_files = SRV_N_LOG_FILES_MAX;
/* size in database pages */
UNIV_INTERN ib_uint64_t srv_log_file_size = IB_UINT64_MAX;
+UNIV_INTERN ib_uint64_t srv_log_file_size_requested;
/* size in database pages */
UNIV_INTERN ulint srv_log_buffer_size = ULINT_MAX;
UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
+UNIV_INTERN uint srv_flush_log_at_timeout = 1;
UNIV_INTERN ulong srv_page_size = UNIV_PAGE_SIZE_DEF;
UNIV_INTERN ulong srv_page_size_shift = UNIV_PAGE_SIZE_SHIFT_DEF;
@@ -213,7 +222,7 @@ UNIV_INTERN ulong srv_n_page_hash_locks = 16;
/** Scan depth for LRU flush batch i.e.: number of blocks scanned*/
UNIV_INTERN ulong srv_LRU_scan_depth = 1024;
/** whether or not to flush neighbors of a block */
-UNIV_INTERN my_bool srv_flush_neighbors = TRUE;
+UNIV_INTERN ulong srv_flush_neighbors = 1;
/* previously requested size */
UNIV_INTERN ulint srv_buf_pool_old_size;
/* current size in kilobytes */
@@ -258,7 +267,8 @@ UNIV_INTERN ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
UNIV_INTERN ulint srv_max_n_open_files = 300;
/* Number of IO operations per second the server can do */
-UNIV_INTERN ulong srv_io_capacity = 400;
+UNIV_INTERN ulong srv_io_capacity = 200;
+UNIV_INTERN ulong srv_max_io_capacity = 400;
/* The InnoDB main thread tries to keep the ratio of modified pages
in the buffer pool to all database pages in the buffer pool smaller than
@@ -266,76 +276,49 @@ the following number. But it is not guaranteed that the value stays below
that during a time of heavy update/insert activity. */
UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 75;
+UNIV_INTERN ulong srv_max_dirty_pages_pct_lwm = 50;
+
+/* This is the percentage of log capacity at which adaptive flushing,
+if enabled, will kick in. */
+UNIV_INTERN ulong srv_adaptive_flushing_lwm = 10;
+
+/* Number of iterations over which adaptive flushing is averaged. */
+UNIV_INTERN ulong srv_flushing_avg_loops = 30;
/* The number of purge threads to use.*/
-UNIV_INTERN ulong srv_n_purge_threads = 1;
+UNIV_INTERN ulong srv_n_purge_threads = 1;
/* the number of pages to purge in one batch */
-UNIV_INTERN ulong srv_purge_batch_size = 20;
-
-/* variable counts amount of data read in total (in bytes) */
-UNIV_INTERN ulint srv_data_read = 0;
+UNIV_INTERN ulong srv_purge_batch_size = 20;
/* Internal setting for "innodb_stats_method". Decides how InnoDB treats
NULL value when collecting statistics. By default, it is set to
SRV_STATS_NULLS_EQUAL(0), ie. all NULL value are treated equal */
-ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
-
-/* here we count the amount of data written in total (in bytes) */
-UNIV_INTERN ulint srv_data_written = 0;
-
-/* the number of the log write requests done */
-UNIV_INTERN ulint srv_log_write_requests = 0;
-
-/* the number of physical writes to the log performed */
-UNIV_INTERN ulint srv_log_writes = 0;
-
-/* amount of data written to the log files in bytes */
-UNIV_INTERN lsn_t srv_os_log_written = 0;
+UNIV_INTERN ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
-/* amount of writes being done to the log files */
-UNIV_INTERN ulint srv_os_log_pending_writes = 0;
-
-/* we increase this counter, when there we don't have enough space in the
-log buffer and have to flush it */
-UNIV_INTERN ulint srv_log_waits = 0;
-
-/* this variable counts the amount of times, when the doublewrite buffer
-was flushed */
-UNIV_INTERN ulint srv_dblwr_writes = 0;
-
-/* here we store the number of pages that have been flushed to the
-doublewrite buffer */
-UNIV_INTERN ulint srv_dblwr_pages_written = 0;
-
-/* in this variable we store the number of write requests issued */
-UNIV_INTERN ulint srv_buf_pool_write_requests = 0;
-
-/* here we store the number of times when we had to wait for a free page
-in the buffer pool. It happens when the buffer pool is full and we need
-to make a flush, in order to be able to read or create a page. */
-UNIV_INTERN ulint srv_buf_pool_wait_free = 0;
-
-/* variable to count the number of pages that were written from buffer
-pool to the disk */
-UNIV_INTERN ulint srv_buf_pool_flushed = 0;
-
-/** Number of buffer pool reads that led to the
-reading of a disk page */
-UNIV_INTERN ulint srv_buf_pool_reads = 0;
+UNIV_INTERN srv_stats_t srv_stats;
/* structure to pass status variables to MySQL */
-UNIV_INTERN export_struc export_vars;
-
-/* If the following is != 0 we do not allow inserts etc. This protects
-the user from forgetting the innodb_force_recovery keyword to my.cnf */
-
-UNIV_INTERN ulint srv_force_recovery = 0;
+UNIV_INTERN export_var_t export_vars;
+
+/** Normally 0. When nonzero, skip some phases of crash recovery,
+starting from SRV_FORCE_IGNORE_CORRUPT, so that data can be recovered
+by SELECT or mysqldump. When this is nonzero, we do not allow any user
+modifications to the data. */
+UNIV_INTERN ulong srv_force_recovery;
+#ifndef DBUG_OFF
+/** Inject a crash at different steps of the recovery process.
+This is for testing and debugging only. */
+UNIV_INTERN ulong srv_force_recovery_crash;
+#endif /* !DBUG_OFF */
/** Print all user-level transactions deadlocks to mysqld stderr */
UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE;
+/** Enable INFORMATION_SCHEMA.innodb_cmp_per_index */
+UNIV_INTERN my_bool srv_cmp_per_index_enabled = FALSE;
+
/* If the following is set to 1 then we do not run purge and insert buffer
merge to completion before shutdown. If it is set to 2, do not even flush the
buffer pool to data files at the shutdown: we effectively 'crash'
@@ -352,21 +335,23 @@ this many index pages, there are 2 ways to calculate statistics:
* quick transient stats, that are used if persistent stats for the given
table/index are not found in the innodb database */
UNIV_INTERN unsigned long long srv_stats_transient_sample_pages = 8;
+UNIV_INTERN my_bool srv_stats_persistent = TRUE;
UNIV_INTERN unsigned long long srv_stats_persistent_sample_pages = 20;
+UNIV_INTERN my_bool srv_stats_auto_recalc = TRUE;
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
-UNIV_INTERN ibool srv_use_atomic_writes = FALSE;
-#ifdef HAVE_POSIX_FALLOCATE
-UNIV_INTERN ibool srv_use_posix_fallocate = TRUE;
-#endif
-
/** doublewrite buffer is 1MB is size i.e.: it can hold 128 16K pages.
The following parameter is the size of the buffer that is used for
batch flushing i.e.: LRU flushing and flush_list flushing. The rest
of the pages are used for single page flushing. */
UNIV_INTERN ulong srv_doublewrite_batch_size = 120;
+UNIV_INTERN ibool srv_use_atomic_writes = FALSE;
+#ifdef HAVE_POSIX_FALLOCATE
+UNIV_INTERN ibool srv_use_posix_fallocate = TRUE;
+#endif
+
UNIV_INTERN ulong srv_replication_delay = 0;
/*-------------------------------------------*/
@@ -382,11 +367,6 @@ UNIV_INTERN ibool srv_print_log_io = FALSE;
UNIV_INTERN ibool srv_print_latch_waits = FALSE;
#endif /* UNIV_DEBUG */
-UNIV_INTERN ulint srv_n_rows_inserted = 0;
-UNIV_INTERN ulint srv_n_rows_updated = 0;
-UNIV_INTERN ulint srv_n_rows_deleted = 0;
-UNIV_INTERN ulint srv_n_rows_read = 0;
-
static ulint srv_n_rows_inserted_old = 0;
static ulint srv_n_rows_updated_old = 0;
static ulint srv_n_rows_deleted_old = 0;
@@ -411,58 +391,58 @@ UNIV_INTERN const char* srv_io_thread_function[SRV_MAX_N_IO_THREADS];
UNIV_INTERN time_t srv_last_monitor_time;
-UNIV_INTERN mutex_t srv_innodb_monitor_mutex;
+UNIV_INTERN ib_mutex_t srv_innodb_monitor_mutex;
-/* Mutex for locking srv_monitor_file */
-UNIV_INTERN mutex_t srv_monitor_file_mutex;
+/* Mutex for locking srv_monitor_file. Not created if srv_read_only_mode */
+UNIV_INTERN ib_mutex_t srv_monitor_file_mutex;
#ifdef UNIV_PFS_MUTEX
# ifndef HAVE_ATOMIC_BUILTINS
/* Key to register server_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t server_mutex_key;
# endif /* !HAVE_ATOMIC_BUILTINS */
-/* Key to register srv_innodb_monitor_mutex with performance schema */
+/** Key to register srv_innodb_monitor_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t srv_innodb_monitor_mutex_key;
-/* Key to register srv_monitor_file_mutex with performance schema */
+/** Key to register srv_monitor_file_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t srv_monitor_file_mutex_key;
-/* Key to register srv_dict_tmpfile_mutex with performance schema */
+/** Key to register srv_dict_tmpfile_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t srv_dict_tmpfile_mutex_key;
-/* Key to register the mutex with performance schema */
+/** Key to register the mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
-/* Key to register srv_sys_t::mutex with performance schema */
+/** Key to register srv_sys_t::mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t srv_sys_mutex_key;
-/* Key to register srv_sys_t::tasks_mutex with performance schema */
+/** Key to register srv_sys_t::tasks_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t srv_sys_tasks_mutex_key;
#endif /* UNIV_PFS_MUTEX */
-/* Temporary file for innodb monitor output */
+/** Temporary file for innodb monitor output */
UNIV_INTERN FILE* srv_monitor_file;
-/* Mutex for locking srv_dict_tmpfile.
+/** Mutex for locking srv_dict_tmpfile. Not created if srv_read_only_mode.
This mutex has a very high rank; threads reserving it should not
be holding any InnoDB latches. */
-UNIV_INTERN mutex_t srv_dict_tmpfile_mutex;
-/* Temporary file for output from the data dictionary */
+UNIV_INTERN ib_mutex_t srv_dict_tmpfile_mutex;
+/** Temporary file for output from the data dictionary */
UNIV_INTERN FILE* srv_dict_tmpfile;
-/* Mutex for locking srv_misc_tmpfile.
+/** Mutex for locking srv_misc_tmpfile. Not created if srv_read_only_mode.
This mutex has a very low rank; threads reserving it should not
acquire any further latches or sleep before releasing this one. */
-UNIV_INTERN mutex_t srv_misc_tmpfile_mutex;
-/* Temporary file for miscellanous diagnostic output */
+UNIV_INTERN ib_mutex_t srv_misc_tmpfile_mutex;
+/** Temporary file for miscellanous diagnostic output */
UNIV_INTERN FILE* srv_misc_tmpfile;
UNIV_INTERN ulint srv_main_thread_process_no = 0;
UNIV_INTERN ulint srv_main_thread_id = 0;
-/* The following count work done by srv_master_thread. */
+/* The following counts are used by the srv_master_thread. */
-/* Iterations of the loop bounded by 'srv_active' label. */
-static ulint srv_main_active_loops = 0;
-/* Iterations of the loop bounded by the 'srv_idle' label. */
-static ulint srv_main_idle_loops = 0;
-/* Iterations of the loop bounded by the 'srv_shutdown' label. */
-static ulint srv_main_shutdown_loops = 0;
-/* Log writes involving flush. */
-static ulint srv_log_writes_and_flush = 0;
+/** Iterations of the loop bounded by 'srv_active' label. */
+static ulint srv_main_active_loops = 0;
+/** Iterations of the loop bounded by the 'srv_idle' label. */
+static ulint srv_main_idle_loops = 0;
+/** Iterations of the loop bounded by the 'srv_shutdown' label. */
+static ulint srv_main_shutdown_loops = 0;
+/** Log writes involving flush. */
+static ulint srv_log_writes_and_flush = 0;
/* This is only ever touched by the master thread. It records the
time when the last flush of log file has happened. The master
@@ -491,7 +471,8 @@ current_time % 5 != 0. */
} while (0)
/** Test if the system mutex is owned. */
-#define srv_sys_mutex_own() mutex_own(&srv_sys->mutex)
+#define srv_sys_mutex_own() (mutex_own(&srv_sys->mutex) \
+ && !srv_read_only_mode)
/** Release the system mutex. */
#define srv_sys_mutex_exit() do { \
@@ -499,7 +480,7 @@ current_time % 5 != 0. */
} while (0)
#define fetch_lock_wait_timeout(trx) \
- ((trx)->lock.allowed_to_wait \
+ ((trx)->lock.allowed_to_wait \
? thd_lock_wait_timeout((trx)->mysql_thd) \
: 0)
@@ -575,35 +556,32 @@ suspending the master thread and utility threads when they have nothing
to do. The thread table can be seen as an analogue to the process table
in a traditional Unix implementation. */
-/** The server system */
-typedef struct srv_sys_struct srv_sys_t;
-
/** The server system struct */
-struct srv_sys_struct{
- mutex_t tasks_mutex; /*!< variable protecting the
+struct srv_sys_t{
+ ib_mutex_t tasks_mutex; /*!< variable protecting the
tasks queue */
UT_LIST_BASE_NODE_T(que_thr_t)
tasks; /*!< task queue */
- mutex_t mutex; /*!< variable protecting the
-
+ ib_mutex_t mutex; /*!< variable protecting the
fields below. */
ulint n_sys_threads; /*!< size of the sys_threads
array */
- srv_table_t* sys_threads; /*!< server thread table */
+ srv_slot_t* sys_threads; /*!< server thread table */
ulint n_threads_active[SRV_MASTER + 1];
/*!< number of threads active
in a thread class */
- ulint activity_count; /*!< For tracking server
+ srv_stats_t::ulint_ctr_1_t
+ activity_count; /*!< For tracking server
activity */
};
#ifndef HAVE_ATOMIC_BUILTINS
/** Mutex protecting some server global variables. */
-UNIV_INTERN mutex_t server_mutex;
+UNIV_INTERN ib_mutex_t server_mutex;
#endif /* !HAVE_ATOMIC_BUILTINS */
static srv_sys_t* srv_sys = NULL;
@@ -663,6 +641,18 @@ srv_set_io_thread_op_info(
srv_io_thread_op_info[i] = str;
}
+/*********************************************************************//**
+Resets the info describing an i/o thread current state. */
+UNIV_INTERN
+void
+srv_reset_io_thread_op_info()
+/*=========================*/
+{
+ for (ulint i = 0; i < UT_ARR_SIZE(srv_io_thread_op_info); ++i) {
+ srv_io_thread_op_info[i] = "not started yet";
+ }
+}
+
#ifdef UNIV_DEBUG
/*********************************************************************//**
Validates the type of a thread table slot.
@@ -763,6 +753,8 @@ srv_suspend_thread_low(
/*===================*/
srv_slot_t* slot) /*!< in/out: thread slot */
{
+
+ ut_ad(!srv_read_only_mode);
ut_ad(srv_sys_mutex_own());
ut_ad(slot->in_use);
@@ -922,9 +914,8 @@ void
srv_init(void)
/*==========*/
{
- ulint i;
- ulint srv_sys_sz;
- ulint n_sys_threads;
+ ulint n_sys_threads = 0;
+ ulint srv_sys_sz = sizeof(*srv_sys);
#ifndef HAVE_ATOMIC_BUILTINS
mutex_create(server_mutex_key, &server_mutex, SYNC_ANY_LATCH);
@@ -933,38 +924,55 @@ srv_init(void)
mutex_create(srv_innodb_monitor_mutex_key,
&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
- /* Number of purge threads + master thread */
- n_sys_threads = srv_n_purge_threads + 1;
+ if (!srv_read_only_mode) {
- srv_sys_sz = sizeof(*srv_sys) + (n_sys_threads * sizeof(srv_slot_t));
+ /* Number of purge threads + master thread */
+ n_sys_threads = srv_n_purge_threads + 1;
+
+ srv_sys_sz += n_sys_threads * sizeof(*srv_sys->sys_threads);
+ }
srv_sys = static_cast<srv_sys_t*>(mem_zalloc(srv_sys_sz));
- mutex_create(srv_sys_mutex_key, &srv_sys->mutex, SYNC_THREADS);
+ srv_sys->n_sys_threads = n_sys_threads;
+
+ if (!srv_read_only_mode) {
- mutex_create(srv_sys_tasks_mutex_key,
- &srv_sys->tasks_mutex, SYNC_ANY_LATCH);
+ mutex_create(srv_sys_mutex_key, &srv_sys->mutex, SYNC_THREADS);
- srv_sys->n_sys_threads = n_sys_threads;
- srv_sys->sys_threads = (srv_slot_t*) &srv_sys[1];
+ mutex_create(srv_sys_tasks_mutex_key,
+ &srv_sys->tasks_mutex, SYNC_ANY_LATCH);
- for (i = 0; i < srv_sys->n_sys_threads; i++) {
- srv_slot_t* slot;
+ srv_sys->sys_threads = (srv_slot_t*) &srv_sys[1];
- slot = srv_sys->sys_threads + i;
+ for (ulint i = 0; i < srv_sys->n_sys_threads; ++i) {
+ srv_slot_t* slot = &srv_sys->sys_threads[i];
- slot->event = os_event_create(NULL);
+ slot->event = os_event_create();
- ut_a(slot->event);
- }
+ ut_a(slot->event);
+ }
+
+ srv_error_event = os_event_create();
- srv_error_event = os_event_create(NULL);
+ srv_monitor_event = os_event_create();
- srv_monitor_event = os_event_create(NULL);
+ srv_buf_dump_event = os_event_create();
- srv_buf_dump_event = os_event_create("buf_dump_event");
+ UT_LIST_INIT(srv_sys->tasks);
+ }
- UT_LIST_INIT(srv_sys->tasks);
+ /* page_zip_stat_per_index_mutex is acquired from:
+ 1. page_zip_compress() (after SYNC_FSP)
+ 2. page_zip_decompress()
+ 3. i_s_cmp_per_index_fill_low() (where SYNC_DICT is acquired)
+ 4. innodb_cmp_per_index_update(), no other latches
+ since we do not acquire any other latches while holding this mutex,
+ it can have very low level. We pick SYNC_ANY_LATCH for it. */
+
+ mutex_create(
+ page_zip_stat_per_index_mutex_key,
+ &page_zip_stat_per_index_mutex, SYNC_ANY_LATCH);
/* Create dummy indexes for infimum and supremum records */
@@ -994,8 +1002,10 @@ srv_free(void)
trx_i_s_cache_free(trx_i_s_cache);
- os_event_free(srv_buf_dump_event);
- srv_buf_dump_event = NULL;
+ if (!srv_read_only_mode) {
+ os_event_free(srv_buf_dump_event);
+ srv_buf_dump_event = NULL;
+ }
}
/*********************************************************************//**
@@ -1017,10 +1027,9 @@ srv_general_init(void)
}
/*********************************************************************//**
-Normalizes init parameter values to use units we use inside InnoDB.
-@return DB_SUCCESS or error code */
+Normalizes init parameter values to use units we use inside InnoDB. */
static
-ulint
+void
srv_normalize_init_values(void)
/*===========================*/
{
@@ -1042,28 +1051,19 @@ srv_normalize_init_values(void)
srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
-
- return(DB_SUCCESS);
}
/*********************************************************************//**
-Boots the InnoDB server.
-@return DB_SUCCESS or error code */
+Boots the InnoDB server. */
UNIV_INTERN
-ulint
+void
srv_boot(void)
/*==========*/
{
- ulint err;
-
/* Transform the init parameter values given by MySQL to
use units we use inside InnoDB: */
- err = srv_normalize_init_values();
-
- if (err != DB_SUCCESS) {
- return(err);
- }
+ srv_normalize_init_values();
/* Initialize synchronization primitives, memory management, and thread
local storage */
@@ -1073,8 +1073,7 @@ srv_boot(void)
/* Initialize this module */
srv_init();
-
- return(DB_SUCCESS);
+ srv_mon_create();
}
/******************************************************************//**
@@ -1097,10 +1096,10 @@ srv_refresh_innodb_monitor_stats(void)
buf_refresh_io_stats_all();
- srv_n_rows_inserted_old = srv_n_rows_inserted;
- srv_n_rows_updated_old = srv_n_rows_updated;
- srv_n_rows_deleted_old = srv_n_rows_deleted;
- srv_n_rows_read_old = srv_n_rows_read;
+ srv_n_rows_inserted_old = srv_stats.n_rows_inserted;
+ srv_n_rows_updated_old = srv_stats.n_rows_updated;
+ srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
+ srv_n_rows_read_old = srv_stats.n_rows_read;
mutex_exit(&srv_innodb_monitor_mutex);
}
@@ -1165,7 +1164,7 @@ srv_printf_innodb_monitor(
mutex_enter(&dict_foreign_err_mutex);
- if (ftell(dict_foreign_err_file) != 0L) {
+ if (!srv_read_only_mode && ftell(dict_foreign_err_file) != 0L) {
fputs("------------------------\n"
"LATEST FOREIGN KEY ERROR\n"
"------------------------\n", file);
@@ -1278,26 +1277,26 @@ srv_printf_innodb_monitor(
"Number of rows inserted " ULINTPF
", updated " ULINTPF ", deleted " ULINTPF
", read " ULINTPF "\n",
- srv_n_rows_inserted,
- srv_n_rows_updated,
- srv_n_rows_deleted,
- srv_n_rows_read);
+ (ulint) srv_stats.n_rows_inserted,
+ (ulint) srv_stats.n_rows_updated,
+ (ulint) srv_stats.n_rows_deleted,
+ (ulint) srv_stats.n_rows_read);
fprintf(file,
"%.2f inserts/s, %.2f updates/s,"
" %.2f deletes/s, %.2f reads/s\n",
- (srv_n_rows_inserted - srv_n_rows_inserted_old)
+ ((ulint) srv_stats.n_rows_inserted - srv_n_rows_inserted_old)
/ time_elapsed,
- (srv_n_rows_updated - srv_n_rows_updated_old)
+ ((ulint) srv_stats.n_rows_updated - srv_n_rows_updated_old)
/ time_elapsed,
- (srv_n_rows_deleted - srv_n_rows_deleted_old)
+ ((ulint) srv_stats.n_rows_deleted - srv_n_rows_deleted_old)
/ time_elapsed,
- (srv_n_rows_read - srv_n_rows_read_old)
+ ((ulint) srv_stats.n_rows_read - srv_n_rows_read_old)
/ time_elapsed);
- srv_n_rows_inserted_old = srv_n_rows_inserted;
- srv_n_rows_updated_old = srv_n_rows_updated;
- srv_n_rows_deleted_old = srv_n_rows_deleted;
- srv_n_rows_read_old = srv_n_rows_read;
+ srv_n_rows_inserted_old = srv_stats.n_rows_inserted;
+ srv_n_rows_updated_old = srv_stats.n_rows_updated;
+ srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
+ srv_n_rows_read_old = srv_stats.n_rows_read;
fputs("----------------------------\n"
"END OF INNODB MONITOR OUTPUT\n"
@@ -1327,84 +1326,156 @@ srv_export_innodb_status(void)
mutex_enter(&srv_innodb_monitor_mutex);
- export_vars.innodb_data_pending_reads
- = os_n_pending_reads;
- export_vars.innodb_data_pending_writes
- = os_n_pending_writes;
- export_vars.innodb_data_pending_fsyncs
- = fil_n_pending_log_flushes
+ export_vars.innodb_data_pending_reads =
+ os_n_pending_reads;
+
+ export_vars.innodb_data_pending_writes =
+ os_n_pending_writes;
+
+ export_vars.innodb_data_pending_fsyncs =
+ fil_n_pending_log_flushes
+ fil_n_pending_tablespace_flushes;
+
export_vars.innodb_data_fsyncs = os_n_fsyncs;
- export_vars.innodb_data_read = srv_data_read;
+
+ export_vars.innodb_data_read = srv_stats.data_read;
+
export_vars.innodb_data_reads = os_n_file_reads;
+
export_vars.innodb_data_writes = os_n_file_writes;
- export_vars.innodb_data_written = srv_data_written;
+
+ export_vars.innodb_data_written = srv_stats.data_written;
+
export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
- export_vars.innodb_buffer_pool_write_requests
- = srv_buf_pool_write_requests;
- export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
- export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
- export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
- export_vars.innodb_buffer_pool_read_ahead_rnd
- = stat.n_ra_pages_read_rnd;
- export_vars.innodb_buffer_pool_read_ahead
- = stat.n_ra_pages_read;
- export_vars.innodb_buffer_pool_read_ahead_evicted
- = stat.n_ra_pages_evicted;
+
+ export_vars.innodb_buffer_pool_write_requests =
+ srv_stats.buf_pool_write_requests;
+
+ export_vars.innodb_buffer_pool_wait_free =
+ srv_stats.buf_pool_wait_free;
+
+ export_vars.innodb_buffer_pool_pages_flushed =
+ srv_stats.buf_pool_flushed;
+
+ export_vars.innodb_buffer_pool_reads = srv_stats.buf_pool_reads;
+
+ export_vars.innodb_buffer_pool_read_ahead_rnd =
+ stat.n_ra_pages_read_rnd;
+
+ export_vars.innodb_buffer_pool_read_ahead =
+ stat.n_ra_pages_read;
+
+ export_vars.innodb_buffer_pool_read_ahead_evicted =
+ stat.n_ra_pages_evicted;
+
export_vars.innodb_buffer_pool_pages_data = LRU_len;
+
export_vars.innodb_buffer_pool_bytes_data =
buf_pools_list_size.LRU_bytes
+ buf_pools_list_size.unzip_LRU_bytes;
+
export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
+
export_vars.innodb_buffer_pool_bytes_dirty =
buf_pools_list_size.flush_list_bytes;
+
export_vars.innodb_buffer_pool_pages_free = free_len;
+
#ifdef UNIV_DEBUG
- export_vars.innodb_buffer_pool_pages_latched
- = buf_get_latched_pages_number();
+ export_vars.innodb_buffer_pool_pages_latched =
+ buf_get_latched_pages_number();
#endif /* UNIV_DEBUG */
export_vars.innodb_buffer_pool_pages_total = buf_pool_get_n_pages();
- export_vars.innodb_buffer_pool_pages_misc
- = buf_pool_get_n_pages() - LRU_len - free_len;
+ export_vars.innodb_buffer_pool_pages_misc =
+ buf_pool_get_n_pages() - LRU_len - free_len;
+
#ifdef HAVE_ATOMIC_BUILTINS
export_vars.innodb_have_atomic_builtins = 1;
#else
export_vars.innodb_have_atomic_builtins = 0;
#endif
export_vars.innodb_page_size = UNIV_PAGE_SIZE;
- export_vars.innodb_log_waits = srv_log_waits;
- export_vars.innodb_os_log_written = srv_os_log_written;
+
+ export_vars.innodb_log_waits = srv_stats.log_waits;
+
+ export_vars.innodb_os_log_written = srv_stats.os_log_written;
+
export_vars.innodb_os_log_fsyncs = fil_n_log_flushes;
+
export_vars.innodb_os_log_pending_fsyncs = fil_n_pending_log_flushes;
- export_vars.innodb_os_log_pending_writes = srv_os_log_pending_writes;
- export_vars.innodb_log_write_requests = srv_log_write_requests;
- export_vars.innodb_log_writes = srv_log_writes;
- export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
- export_vars.innodb_dblwr_writes = srv_dblwr_writes;
+
+ export_vars.innodb_os_log_pending_writes =
+ srv_stats.os_log_pending_writes;
+
+ export_vars.innodb_log_write_requests = srv_stats.log_write_requests;
+
+ export_vars.innodb_log_writes = srv_stats.log_writes;
+
+ export_vars.innodb_dblwr_pages_written =
+ srv_stats.dblwr_pages_written;
+
+ export_vars.innodb_dblwr_writes = srv_stats.dblwr_writes;
+
export_vars.innodb_pages_created = stat.n_pages_created;
+
export_vars.innodb_pages_read = stat.n_pages_read;
+
export_vars.innodb_pages_written = stat.n_pages_written;
- export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
- export_vars.innodb_row_lock_current_waits
- = srv_n_lock_wait_current_count;
- export_vars.innodb_row_lock_time = srv_n_lock_wait_time / 1000;
- if (srv_n_lock_wait_count > 0) {
+
+ export_vars.innodb_row_lock_waits = srv_stats.n_lock_wait_count;
+
+ export_vars.innodb_row_lock_current_waits =
+ srv_stats.n_lock_wait_current_count;
+
+ export_vars.innodb_row_lock_time = srv_stats.n_lock_wait_time / 1000;
+
+ if (srv_stats.n_lock_wait_count > 0) {
+
export_vars.innodb_row_lock_time_avg = (ulint)
- (srv_n_lock_wait_time / 1000 / srv_n_lock_wait_count);
+ (srv_stats.n_lock_wait_time
+ / 1000 / srv_stats.n_lock_wait_count);
+
} else {
export_vars.innodb_row_lock_time_avg = 0;
}
- export_vars.innodb_row_lock_time_max
- = srv_n_lock_max_wait_time / 1000;
- export_vars.innodb_rows_read = srv_n_rows_read;
- export_vars.innodb_rows_inserted = srv_n_rows_inserted;
- export_vars.innodb_rows_updated = srv_n_rows_updated;
- export_vars.innodb_rows_deleted = srv_n_rows_deleted;
+
+ export_vars.innodb_row_lock_time_max =
+ lock_sys->n_lock_max_wait_time / 1000;
+
+ export_vars.innodb_rows_read = srv_stats.n_rows_read;
+
+ export_vars.innodb_rows_inserted = srv_stats.n_rows_inserted;
+
+ export_vars.innodb_rows_updated = srv_stats.n_rows_updated;
+
+ export_vars.innodb_rows_deleted = srv_stats.n_rows_deleted;
+
export_vars.innodb_num_open_files = fil_n_file_opened;
- export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
+
+ export_vars.innodb_truncated_status_writes =
+ srv_truncated_status_writes;
+
export_vars.innodb_available_undo_logs = srv_available_undo_logs;
+#ifdef UNIV_DEBUG
+ if (purge_sys->done.trx_no == 0
+ || trx_sys->rw_max_trx_id < purge_sys->done.trx_no - 1) {
+ export_vars.innodb_purge_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_trx_id_age =
+ trx_sys->rw_max_trx_id - purge_sys->done.trx_no + 1;
+ }
+
+ if (!purge_sys->view
+ || trx_sys->rw_max_trx_id < purge_sys->view->up_limit_id) {
+ export_vars.innodb_purge_view_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_view_trx_id_age =
+ trx_sys->rw_max_trx_id - purge_sys->view->up_limit_id;
+ }
+#endif /* UNIV_DEBUG */
+
mutex_exit(&srv_innodb_monitor_mutex);
}
@@ -1428,14 +1499,16 @@ DECLARE_THREAD(srv_monitor_thread)(
ulint mutex_skipped;
ibool last_srv_print_monitor;
+ ut_ad(!srv_read_only_mode);
+
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Lock timeout thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
-#endif
+#endif /* UNIV_DEBUG_THREAD_CREATION */
#ifdef UNIV_PFS_THREAD
pfs_register_thread(srv_monitor_thread_key);
-#endif
+#endif /* UNIV_PFS_THREAD */
srv_monitor_active = TRUE;
UT_NOT_USED(arg);
@@ -1484,7 +1557,10 @@ loop:
}
- if (srv_innodb_status) {
+ /* We don't create the temp files or associated
+ mutexes in read-only-mode */
+
+ if (!srv_read_only_mode && srv_innodb_status) {
mutex_enter(&srv_monitor_file_mutex);
rewind(srv_monitor_file);
if (!srv_printf_innodb_monitor(srv_monitor_file,
@@ -1601,16 +1677,18 @@ DECLARE_THREAD(srv_error_monitor_thread)(
const void* sema = NULL;
const void* old_sema = NULL;
+ ut_ad(!srv_read_only_mode);
+
old_lsn = srv_start_lsn;
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Error monitor thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
-#endif
+#endif /* UNIV_DEBUG_THREAD_CREATION */
#ifdef UNIV_PFS_THREAD
pfs_register_thread(srv_error_monitor_thread_key);
-#endif
+#endif /* UNIV_PFS_THREAD */
srv_error_monitor_active = TRUE;
loop:
@@ -1644,9 +1722,6 @@ loop:
eviction policy. */
buf_LRU_stat_update();
- /* Update the statistics collected for flush rate policy. */
- buf_flush_stat_update();
-
/* In case mutex_exit is not a memory barrier, it is
theoretically possible some threads are left waiting though
the semaphore is already released. Wake up those threads: */
@@ -1704,7 +1779,7 @@ void
srv_inc_activity_count(void)
/*========================*/
{
- ++srv_sys->activity_count;
+ srv_sys->activity_count.inc();
}
/**********************************************************************//**
@@ -1717,12 +1792,15 @@ srv_thread_type
srv_get_active_thread_type(void)
/*============================*/
{
- ulint i;
srv_thread_type ret = SRV_NONE;
+ if (srv_read_only_mode) {
+ return(SRV_NONE);
+ }
+
srv_sys_mutex_enter();
- for (i = SRV_WORKER; i <= SRV_MASTER; ++i) {
+ for (ulint i = SRV_WORKER; i <= SRV_MASTER; ++i) {
if (srv_sys->n_threads_active[i] != 0) {
ret = static_cast<srv_thread_type>(i);
break;
@@ -1734,6 +1812,7 @@ srv_get_active_thread_type(void)
/* Check only on shutdown. */
if (ret == SRV_NONE
&& srv_shutdown_state != SRV_SHUTDOWN_NONE
+ && trx_purge_state() != PURGE_STATE_DISABLED
&& trx_purge_state() != PURGE_STATE_EXIT) {
ret = SRV_PURGE;
@@ -1753,20 +1832,25 @@ srv_any_background_threads_are_active(void)
{
const char* thread_active = NULL;
- if (srv_error_monitor_active) {
+ if (srv_read_only_mode) {
+ return(NULL);
+ } else if (srv_error_monitor_active) {
thread_active = "srv_error_monitor_thread";
- } else if (srv_lock_timeout_active) {
+ } else if (lock_sys->timeout_thread_active) {
thread_active = "srv_lock_timeout thread";
} else if (srv_monitor_active) {
thread_active = "srv_monitor_thread";
} else if (srv_buf_dump_thread_active) {
thread_active = "buf_dump_thread";
+ } else if (srv_dict_stats_thread_active) {
+ thread_active = "dict_stats_thread";
}
os_event_set(srv_error_event);
os_event_set(srv_monitor_event);
- os_event_set(srv_timeout_event);
os_event_set(srv_buf_dump_event);
+ os_event_set(lock_sys->timeout_event);
+ os_event_set(dict_stats_event);
return(thread_active);
}
@@ -1782,6 +1866,10 @@ void
srv_active_wake_master_thread(void)
/*===============================*/
{
+ if (srv_read_only_mode) {
+ return;
+ }
+
ut_ad(!srv_sys_mutex_own());
srv_inc_activity_count();
@@ -1883,7 +1971,8 @@ srv_sync_log_buffer_in_background(void)
time_t current_time = time(NULL);
srv_main_thread_op_info = "flushing log";
- if (difftime(current_time, srv_last_log_flush_time) >= 1) {
+ if (difftime(current_time, srv_last_log_flush_time)
+ >= srv_flush_log_at_timeout) {
log_buffer_sync_in_background(TRUE);
srv_last_log_flush_time = current_time;
srv_log_writes_and_flush++;
@@ -2000,7 +2089,7 @@ srv_master_do_active_tasks(void)
/* Do an ibuf merge */
srv_main_thread_op_info = "doing insert buffer merge";
counter_time = ut_time_us(NULL);
- ibuf_contract_in_background(FALSE);
+ ibuf_contract_in_background(0, FALSE);
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time);
@@ -2092,7 +2181,7 @@ srv_master_do_idle_tasks(void)
/* Do an ibuf merge */
counter_time = ut_time_us(NULL);
srv_main_thread_op_info = "doing insert buffer merge";
- ibuf_contract_in_background(TRUE);
+ ibuf_contract_in_background(0, TRUE);
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time);
@@ -2139,6 +2228,8 @@ srv_master_do_shutdown_tasks(
ulint n_bytes_merged = 0;
ulint n_tables_to_drop = 0;
+ ut_ad(!srv_read_only_mode);
+
++srv_main_shutdown_loops;
ut_a(srv_shutdown_state > 0);
@@ -2166,7 +2257,7 @@ srv_master_do_shutdown_tasks(
/* Do an ibuf merge */
srv_main_thread_op_info = "doing insert buffer merge";
- n_bytes_merged = ibuf_contract_in_background(TRUE);
+ n_bytes_merged = ibuf_contract_in_background(0, TRUE);
/* Flush logs if needed */
srv_sync_log_buffer_in_background();
@@ -2214,14 +2305,16 @@ DECLARE_THREAD(srv_master_thread)(
ulint old_activity_count = srv_get_activity_count();
ib_time_t last_print_time;
+ ut_ad(!srv_read_only_mode);
+
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
-#endif
+#endif /* UNIV_DEBUG_THREAD_CREATION */
#ifdef UNIV_PFS_THREAD
pfs_register_thread(srv_master_thread_key);
-#endif
+#endif /* UNIV_PFS_THREAD */
srv_main_thread_process_no = os_proc_get_number();
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
@@ -2314,6 +2407,7 @@ srv_task_execute(void)
{
que_thr_t* thr = NULL;
+ ut_ad(!srv_read_only_mode);
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
mutex_enter(&srv_sys->tasks_mutex);
@@ -2352,6 +2446,7 @@ DECLARE_THREAD(srv_worker_thread)(
{
srv_slot_t* slot;
+ ut_ad(!srv_read_only_mode);
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
#ifdef UNIV_DEBUG_THREAD_CREATION
@@ -2432,6 +2527,7 @@ srv_do_purge(
ulint old_activity_count = srv_get_activity_count();
ut_a(n_threads > 0);
+ ut_ad(!srv_read_only_mode);
/* Purge until there are no more records to purge and there is
no change in configuration or server state. If the user has
@@ -2478,7 +2574,7 @@ srv_do_purge(
n_pages_purged = trx_purge(
n_use_threads, srv_purge_batch_size, false);
- if (!(count++ % TRX_SYS_N_RSEGS) || n_pages_purged == 0) {
+ if (!(count++ % TRX_SYS_N_RSEGS)) {
/* Force a truncate of the history list. */
trx_purge(1, srv_purge_batch_size, true);
}
@@ -2501,14 +2597,9 @@ srv_purge_coordinator_suspend(
ulint rseg_history_len) /*!< in: history list length
before last purge */
{
+ ut_ad(!srv_read_only_mode);
ut_a(slot->type == SRV_PURGE);
- rw_lock_x_lock(&purge_sys->latch);
-
- purge_sys->running = false;
-
- rw_lock_x_unlock(&purge_sys->latch);
-
bool stop = false;
/** Maximum wait time on the purge event, in micro-seconds. */
@@ -2518,6 +2609,12 @@ srv_purge_coordinator_suspend(
ulint ret;
ib_int64_t sig_count = srv_suspend_thread(slot);
+ rw_lock_x_lock(&purge_sys->latch);
+
+ purge_sys->running = false;
+
+ rw_lock_x_unlock(&purge_sys->latch);
+
/* We don't wait right away on the the non-timed wait because
we want to signal the thread that wants to suspend purge. */
@@ -2528,8 +2625,8 @@ srv_purge_coordinator_suspend(
ret = os_event_wait_time_low(
slot->event, SRV_PURGE_MAX_TIMEOUT, sig_count);
} else {
- /* We don't want to waste time waiting if the
- history list has increased by the time we get here
+ /* We don't want to waste time waiting, if the
+ history list increased by the time we got here,
unless purge has been stopped. */
ret = 0;
}
@@ -2596,6 +2693,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
srv_slot_t* slot;
ulint n_total_purged = ULINT_UNDEFINED;
+ ut_ad(!srv_read_only_mode);
ut_a(srv_n_purge_threads >= 1);
ut_a(trx_purge_state() == PURGE_STATE_INIT);
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
@@ -2703,6 +2801,7 @@ srv_que_task_enqueue_low(
/*=====================*/
que_thr_t* thr) /*!< in: query thread */
{
+ ut_ad(!srv_read_only_mode);
mutex_enter(&srv_sys->tasks_mutex);
UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
@@ -2722,6 +2821,8 @@ srv_get_task_queue_length(void)
{
ulint n_tasks;
+ ut_ad(!srv_read_only_mode);
+
mutex_enter(&srv_sys->tasks_mutex);
n_tasks = UT_LIST_GET_LEN(srv_sys->tasks);
@@ -2738,6 +2839,8 @@ void
srv_purge_wakeup(void)
/*==================*/
{
+ ut_ad(!srv_read_only_mode);
+
if (srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
srv_release_threads(SRV_PURGE, 1);