Commit 7a30d86e authored by Marko Mäkelä's avatar Marko Mäkelä

Simplify InnoDB startup.

InnoDB needs to collect transactions from the persistent data files
in trx_rseg_array_init() before trx_lists_init_at_db_start() is
executed. But there is no need to create purge_sys->purge_queue
separately from purge_sys.

trx_sys_init_at_db_start(): Change the return type to void.
Remove the direct call to trx_rseg_array_init(). It will be called
by trx_lists_init_at_db_start(), which we are calling.
Initialize the purge system read view.

trx_lists_init_at_db_start(): Call trx_purge_sys_create(), which will
invoke trx_rseg_array_init() to read the undo log segments.

trx_purge_sys_create(): Remove the parameters. Do not initialize
the purge system read view, because trx_sys->rw_trx_list has not
been recovered yet. The purge_sys->view will be initialized at
the end of trx_sys_init_at_db_start().

trx_rseg_array_init(): Remove the parameter. Use purge_sys->purge_queue
directly.

innobase_start_or_create_for_mysql(): Remove the local variable
purge_queue. Do not call trx_purge_sys_create(), because it will be
called by trx_sys_init_at_db_start().
parent 15bdfeeb
...@@ -54,19 +54,12 @@ trx_purge_get_log_from_hist( ...@@ -54,19 +54,12 @@ trx_purge_get_log_from_hist(
/*========================*/ /*========================*/
fil_addr_t node_addr); /*!< in: file address of the history fil_addr_t node_addr); /*!< in: file address of the history
list node of the log */ list node of the log */
/********************************************************************//** /** Create the global purge system data structure. */
Creates the global purge system control structure and inits the history
mutex. */
void void
trx_purge_sys_create( trx_purge_sys_create();
/*=================*/ /** Free the global purge system data structure. */
ulint n_purge_threads,/*!< in: number of purge threads */
purge_pq_t* purge_queue); /*!< in/own: UNDO log min binary heap*/
/********************************************************************//**
Frees the global purge system control structure. */
void void
trx_purge_sys_close(void); trx_purge_sys_close();
/*======================*/
/************************************************************************ /************************************************************************
Adds the update undo log as the first log in the history list. Removes the Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */ update undo log segment from the rseg slot if it is too big for reuse. */
......
...@@ -117,13 +117,9 @@ trx_rseg_header_create( ...@@ -117,13 +117,9 @@ trx_rseg_header_create(
ulint rseg_slot_no, ulint rseg_slot_no,
mtr_t* mtr); mtr_t* mtr);
/*********************************************************************//** /** Initialize the rollback segments in memory at database startup. */
Creates the memory copies for rollback segments and initializes the
rseg array in trx_sys at a database startup. */
void void
trx_rseg_array_init( trx_rseg_array_init();
/*================*/
purge_pq_t* purge_queue); /*!< in: rseg queue */
/** Free a rollback segment in memory. */ /** Free a rollback segment in memory. */
void void
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -61,13 +62,9 @@ bool ...@@ -61,13 +62,9 @@ bool
trx_sys_hdr_page( trx_sys_hdr_page(
const page_id_t& page_id); const page_id_t& page_id);
/*****************************************************************//** /** Initialize the transaction system main-memory data structures. */
Creates and initializes the central memory structures for the transaction void trx_sys_init_at_db_start();
system. This is called when the database is started.
@return min binary heap of rsegs to purge */
purge_pq_t*
trx_sys_init_at_db_start(void);
/*==========================*/
/*****************************************************************//** /*****************************************************************//**
Creates the trx_sys instance and initializes purge_queue and mutex. */ Creates the trx_sys instance and initializes purge_queue and mutex. */
void void
......
...@@ -143,15 +143,9 @@ trx_disconnect_plain(trx_t* trx); ...@@ -143,15 +143,9 @@ trx_disconnect_plain(trx_t* trx);
void void
trx_disconnect_prepared(trx_t* trx); trx_disconnect_prepared(trx_t* trx);
/****************************************************************//** /** Initialize (resurrect) transactions at startup. */
Creates trx objects for transactions and initializes the trx list of
trx_sys at database start. Rollback segment and undo log lists must
already exist when this function is called, because the lists of
transactions to be rolled back or cleaned up are built based on the
undo log lists. */
void void
trx_lists_init_at_db_start(void); trx_lists_init_at_db_start();
/*============================*/
/*************************************************************//** /*************************************************************//**
Starts the transaction if it is not yet started. */ Starts the transaction if it is not yet started. */
......
...@@ -1449,7 +1449,6 @@ innobase_start_or_create_for_mysql(void) ...@@ -1449,7 +1449,6 @@ innobase_start_or_create_for_mysql(void)
dberr_t err = DB_SUCCESS; dberr_t err = DB_SUCCESS;
ulint srv_n_log_files_found = srv_n_log_files; ulint srv_n_log_files_found = srv_n_log_files;
mtr_t mtr; mtr_t mtr;
purge_pq_t* purge_queue;
char logfilename[10000]; char logfilename[10000];
char* logfile0 = NULL; char* logfile0 = NULL;
size_t dirnamelen; size_t dirnamelen;
...@@ -2137,13 +2136,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -2137,13 +2136,7 @@ innobase_start_or_create_for_mysql(void)
All the remaining rollback segments will be created later, All the remaining rollback segments will be created later,
after the double write buffer has been created. */ after the double write buffer has been created. */
trx_sys_create_sys_pages(); trx_sys_create_sys_pages();
trx_sys_init_at_db_start();
purge_queue = trx_sys_init_at_db_start();
/* The purge system needs to create the purge view and
therefore requires that the trx_sys is inited. */
trx_purge_sys_create(srv_n_purge_threads, purge_queue);
err = dict_create(); err = dict_create();
...@@ -2228,7 +2221,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -2228,7 +2221,7 @@ innobase_start_or_create_for_mysql(void)
} }
/* This must precede recv_apply_hashed_log_recs(true). */ /* This must precede recv_apply_hashed_log_recs(true). */
purge_queue = trx_sys_init_at_db_start(); trx_sys_init_at_db_start();
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
/* Apply the hashed log records to the /* Apply the hashed log records to the
...@@ -2309,16 +2302,10 @@ innobase_start_or_create_for_mysql(void) ...@@ -2309,16 +2302,10 @@ innobase_start_or_create_for_mysql(void)
" a startup if you are trying to" " a startup if you are trying to"
" recover a badly corrupt database."; " recover a badly corrupt database.";
UT_DELETE(purge_queue);
return(srv_init_abort(DB_ERROR)); return(srv_init_abort(DB_ERROR));
} }
} }
/* The purge system needs to create the purge view and
therefore requires that the trx_sys is inited. */
trx_purge_sys_create(srv_n_purge_threads, purge_queue);
/* recv_recovery_from_checkpoint_finish needs trx lists which /* recv_recovery_from_checkpoint_finish needs trx lists which
are initialized in trx_sys_init_at_db_start(). */ are initialized in trx_sys_init_at_db_start(). */
......
...@@ -208,16 +208,9 @@ trx_purge_graph_build( ...@@ -208,16 +208,9 @@ trx_purge_graph_build(
return(fork); return(fork);
} }
/********************************************************************//** /** Create the global purge system data structure. */
Creates the global purge system control structure and inits the history
mutex. */
void void
trx_purge_sys_create( trx_purge_sys_create()
/*=================*/
ulint n_purge_threads, /*!< in: number of purge
threads */
purge_pq_t* purge_queue) /*!< in, own: UNDO log min
binary heap */
{ {
purge_sys = static_cast<trx_purge_t*>( purge_sys = static_cast<trx_purge_t*>(
ut_zalloc_nokey(sizeof(*purge_sys))); ut_zalloc_nokey(sizeof(*purge_sys)));
...@@ -232,15 +225,18 @@ trx_purge_sys_create( ...@@ -232,15 +225,18 @@ trx_purge_sys_create(
new (&purge_sys->done) purge_iter_t; new (&purge_sys->done) purge_iter_t;
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/* Take ownership of purge_queue, we are responsible for freeing it. */ purge_sys->purge_queue = UT_NEW_NOKEY(purge_pq_t());
purge_sys->purge_queue = purge_queue; ut_a(purge_sys->purge_queue != NULL);
if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
trx_rseg_array_init();
}
rw_lock_create(trx_purge_latch_key, rw_lock_create(trx_purge_latch_key,
&purge_sys->latch, SYNC_PURGE_LATCH); &purge_sys->latch, SYNC_PURGE_LATCH);
mutex_create(LATCH_ID_PURGE_SYS_PQ, &purge_sys->pq_mutex); mutex_create(LATCH_ID_PURGE_SYS_PQ, &purge_sys->pq_mutex);
ut_a(n_purge_threads > 0); ut_a(srv_n_purge_threads > 0);
purge_sys->sess = sess_open(); purge_sys->sess = sess_open();
...@@ -257,22 +253,16 @@ trx_purge_sys_create( ...@@ -257,22 +253,16 @@ trx_purge_sys_create(
purge_sys->trx->op_info = "purge trx"; purge_sys->trx->op_info = "purge trx";
purge_sys->query = trx_purge_graph_build( purge_sys->query = trx_purge_graph_build(
purge_sys->trx, n_purge_threads); purge_sys->trx, srv_n_purge_threads);
new(&purge_sys->view) ReadView(); new(&purge_sys->view) ReadView();
trx_sys->mvcc->clone_oldest_view(&purge_sys->view);
purge_sys->view_active = true;
purge_sys->rseg_iter = UT_NEW_NOKEY(TrxUndoRsegsIterator(purge_sys)); purge_sys->rseg_iter = UT_NEW_NOKEY(TrxUndoRsegsIterator(purge_sys));
} }
/************************************************************************ /** Free the global purge system data structure. */
Frees the global purge system control structure. */
void void
trx_purge_sys_close(void) trx_purge_sys_close()
/*======================*/
{ {
que_graph_free(purge_sys->query); que_graph_free(purge_sys->query);
......
...@@ -262,18 +262,11 @@ trx_rseg_mem_create( ...@@ -262,18 +262,11 @@ trx_rseg_mem_create(
return(rseg); return(rseg);
} }
/******************************************************************** /** Initialize the rollback segments in memory at database startup. */
Creates the memory copies for the rollback segments and initializes the
rseg array in trx_sys at a database startup. */
static
void void
trx_rseg_create_instance( trx_rseg_array_init()
/*=====================*/
purge_pq_t* purge_queue) /*!< in/out: rseg queue */
{ {
ulint i; for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
ulint page_no; ulint page_no;
mtr_t mtr; mtr_t mtr;
...@@ -303,7 +296,7 @@ trx_rseg_create_instance( ...@@ -303,7 +296,7 @@ trx_rseg_create_instance(
rseg = trx_rseg_mem_create( rseg = trx_rseg_mem_create(
i, space, page_no, page_size, i, space, page_no, page_size,
purge_queue, rseg_array, &mtr); purge_sys->purge_queue, rseg_array, &mtr);
ut_a(rseg->id == i); ut_a(rseg->id == i);
} else { } else {
...@@ -380,19 +373,6 @@ trx_rseg_create( ...@@ -380,19 +373,6 @@ trx_rseg_create(
return(rseg); return(rseg);
} }
/*********************************************************************//**
Creates the memory copies for rollback segments and initializes the
rseg array in trx_sys at a database startup. */
void
trx_rseg_array_init(
/*================*/
purge_pq_t* purge_queue) /*!< in: rseg queue */
{
trx_sys->rseg_history_len = 0;
trx_rseg_create_instance(purge_queue);
}
/******************************************************************** /********************************************************************
Get the number of unique rollback tablespaces in use except space id 0. Get the number of unique rollback tablespaces in use except space id 0.
The last space id will be the sentinel value ULINT_UNDEFINED. The array The last space id will be the sentinel value ULINT_UNDEFINED. The array
......
...@@ -60,7 +60,7 @@ struct file_format_t { ...@@ -60,7 +60,7 @@ struct file_format_t {
}; };
/** The transaction system */ /** The transaction system */
trx_sys_t* trx_sys = NULL; trx_sys_t* trx_sys;
/** List of animal names representing file format. */ /** List of animal names representing file format. */
static const char* file_format_name_map[] = { static const char* file_format_name_map[] = {
...@@ -578,29 +578,14 @@ trx_sysf_create( ...@@ -578,29 +578,14 @@ trx_sysf_create(
ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO); ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO);
} }
/*****************************************************************//** /** Initialize the transaction system main-memory data structures. */
Creates and initializes the central memory structures for the transaction void
system. This is called when the database is started. trx_sys_init_at_db_start()
@return min binary heap of rsegs to purge */
purge_pq_t*
trx_sys_init_at_db_start(void)
/*==========================*/
{ {
purge_pq_t* purge_queue;
trx_sysf_t* sys_header; trx_sysf_t* sys_header;
ib_uint64_t rows_to_undo = 0; ib_uint64_t rows_to_undo = 0;
const char* unit = ""; const char* unit = "";
/* We create the min binary heap here and pass ownership to
purge when we init the purge sub-system. Purge is responsible
for freeing the binary heap. */
purge_queue = UT_NEW_NOKEY(purge_pq_t());
ut_a(purge_queue != NULL);
if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
trx_rseg_array_init(purge_queue);
}
/* VERY important: after the database is started, max_trx_id value is /* VERY important: after the database is started, max_trx_id value is
divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the 'if' in divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the 'if' in
trx_sys_get_new_trx_id will evaluate to TRUE when the function trx_sys_get_new_trx_id will evaluate to TRUE when the function
...@@ -661,7 +646,9 @@ trx_sys_init_at_db_start(void) ...@@ -661,7 +646,9 @@ trx_sys_init_at_db_start(void)
trx_sys_mutex_exit(); trx_sys_mutex_exit();
return(purge_queue); trx_sys->mvcc->clone_oldest_view(&purge_sys->view);
purge_sys->view_active = true;
} }
/*****************************************************************//** /*****************************************************************//**
......
...@@ -1007,17 +1007,15 @@ trx_resurrect_update( ...@@ -1007,17 +1007,15 @@ trx_resurrect_update(
} }
} }
/****************************************************************//** /** Initialize (resurrect) transactions at startup. */
Creates trx objects for transactions and initializes the trx list of
trx_sys at database start. Rollback segment and undo log lists must
already exist when this function is called, because the lists of
transactions to be rolled back or cleaned up are built based on the
undo log lists. */
void void
trx_lists_init_at_db_start(void) trx_lists_init_at_db_start()
/*============================*/
{ {
ut_a(srv_is_being_started); ut_a(srv_is_being_started);
ut_ad(!srv_was_started);
ut_ad(!purge_sys);
trx_purge_sys_create();
/* Look from the rollback segments if there exist undo logs for /* Look from the rollback segments if there exist undo logs for
transactions. */ transactions. */
......
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