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(
/*========================*/
fil_addr_t node_addr); /*!< in: file address of the history
list node of the log */
/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
/** Create the global purge system data structure. */
void
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*/
/********************************************************************//**
Frees the global purge system control structure. */
trx_purge_sys_create();
/** Free the global purge system data structure. */
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
update undo log segment from the rseg slot if it is too big for reuse. */
......
......@@ -117,13 +117,9 @@ trx_rseg_header_create(
ulint rseg_slot_no,
mtr_t* mtr);
/*********************************************************************//**
Creates the memory copies for rollback segments and initializes the
rseg array in trx_sys at a database startup. */
/** Initialize the rollback segments in memory at database startup. */
void
trx_rseg_array_init(
/*================*/
purge_pq_t* purge_queue); /*!< in: rseg queue */
trx_rseg_array_init();
/** Free a rollback segment in memory. */
void
......
/*****************************************************************************
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
the terms of the GNU General Public License as published by the Free Software
......@@ -61,13 +62,9 @@ bool
trx_sys_hdr_page(
const page_id_t& page_id);
/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
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);
/*==========================*/
/** Initialize the transaction system main-memory data structures. */
void trx_sys_init_at_db_start();
/*****************************************************************//**
Creates the trx_sys instance and initializes purge_queue and mutex. */
void
......
......@@ -143,15 +143,9 @@ trx_disconnect_plain(trx_t* trx);
void
trx_disconnect_prepared(trx_t* trx);
/****************************************************************//**
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. */
/** Initialize (resurrect) transactions at startup. */
void
trx_lists_init_at_db_start(void);
/*============================*/
trx_lists_init_at_db_start();
/*************************************************************//**
Starts the transaction if it is not yet started. */
......
......@@ -1449,7 +1449,6 @@ innobase_start_or_create_for_mysql(void)
dberr_t err = DB_SUCCESS;
ulint srv_n_log_files_found = srv_n_log_files;
mtr_t mtr;
purge_pq_t* purge_queue;
char logfilename[10000];
char* logfile0 = NULL;
size_t dirnamelen;
......@@ -2137,13 +2136,7 @@ innobase_start_or_create_for_mysql(void)
All the remaining rollback segments will be created later,
after the double write buffer has been created. */
trx_sys_create_sys_pages();
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);
trx_sys_init_at_db_start();
err = dict_create();
......@@ -2228,7 +2221,7 @@ innobase_start_or_create_for_mysql(void)
}
/* 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) {
/* Apply the hashed log records to the
......@@ -2309,16 +2302,10 @@ innobase_start_or_create_for_mysql(void)
" a startup if you are trying to"
" recover a badly corrupt database.";
UT_DELETE(purge_queue);
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
are initialized in trx_sys_init_at_db_start(). */
......
......@@ -208,16 +208,9 @@ trx_purge_graph_build(
return(fork);
}
/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
/** Create the global purge system data structure. */
void
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 */
trx_purge_sys_create()
{
purge_sys = static_cast<trx_purge_t*>(
ut_zalloc_nokey(sizeof(*purge_sys)));
......@@ -232,15 +225,18 @@ trx_purge_sys_create(
new (&purge_sys->done) purge_iter_t;
#endif /* UNIV_DEBUG */
/* Take ownership of purge_queue, we are responsible for freeing it. */
purge_sys->purge_queue = purge_queue;
purge_sys->purge_queue = UT_NEW_NOKEY(purge_pq_t());
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,
&purge_sys->latch, SYNC_PURGE_LATCH);
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();
......@@ -257,22 +253,16 @@ trx_purge_sys_create(
purge_sys->trx->op_info = "purge trx";
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();
trx_sys->mvcc->clone_oldest_view(&purge_sys->view);
purge_sys->view_active = true;
purge_sys->rseg_iter = UT_NEW_NOKEY(TrxUndoRsegsIterator(purge_sys));
}
/************************************************************************
Frees the global purge system control structure. */
/** Free the global purge system data structure. */
void
trx_purge_sys_close(void)
/*======================*/
trx_purge_sys_close()
{
que_graph_free(purge_sys->query);
......
......@@ -262,18 +262,11 @@ trx_rseg_mem_create(
return(rseg);
}
/********************************************************************
Creates the memory copies for the rollback segments and initializes the
rseg array in trx_sys at a database startup. */
static
/** Initialize the rollback segments in memory at database startup. */
void
trx_rseg_create_instance(
/*=====================*/
purge_pq_t* purge_queue) /*!< in/out: rseg queue */
trx_rseg_array_init()
{
ulint i;
for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
ulint page_no;
mtr_t mtr;
......@@ -303,7 +296,7 @@ trx_rseg_create_instance(
rseg = trx_rseg_mem_create(
i, space, page_no, page_size,
purge_queue, rseg_array, &mtr);
purge_sys->purge_queue, rseg_array, &mtr);
ut_a(rseg->id == i);
} else {
......@@ -380,19 +373,6 @@ trx_rseg_create(
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.
The last space id will be the sentinel value ULINT_UNDEFINED. The array
......
......@@ -60,7 +60,7 @@ struct file_format_t {
};
/** The transaction system */
trx_sys_t* trx_sys = NULL;
trx_sys_t* trx_sys;
/** List of animal names representing file format. */
static const char* file_format_name_map[] = {
......@@ -578,29 +578,14 @@ trx_sysf_create(
ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO);
}
/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
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)
/*==========================*/
/** Initialize the transaction system main-memory data structures. */
void
trx_sys_init_at_db_start()
{
purge_pq_t* purge_queue;
trx_sysf_t* sys_header;
ib_uint64_t rows_to_undo = 0;
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
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
......@@ -661,7 +646,9 @@ trx_sys_init_at_db_start(void)
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(
}
}
/****************************************************************//**
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. */
/** Initialize (resurrect) transactions at startup. */
void
trx_lists_init_at_db_start(void)
/*============================*/
trx_lists_init_at_db_start()
{
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
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