mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
Applying InnoDB Plugin 1.0.6 snapshot,part 1. Fixes BUG#45992 and BUG#46656
Detailed revision comments: r6130 | marko | 2009-11-02 11:42:56 +0200 (Mon, 02 Nov 2009) | 9 lines branches/zip: Free all resources at shutdown. Set pointers to NULL, so that Valgrind will not complain about freed data structures that are reachable via pointers. This addresses Bug #45992 and Bug #46656. This patch is mostly based on changes copied from branches/embedded-1.0, mainly c5432, c3439, c3134, c2994, c2978, but also some other code was copied. Some added cleanup code is specific to MySQL/InnoDB. rb://199 approved by Sunny Bains
This commit is contained in:
@@ -771,8 +771,6 @@ void
|
||||
log_init(void)
|
||||
/*==========*/
|
||||
{
|
||||
byte* buf;
|
||||
|
||||
log_sys = mem_alloc(sizeof(log_t));
|
||||
|
||||
mutex_create(&log_sys->mutex, SYNC_LOG);
|
||||
@@ -787,8 +785,8 @@ log_init(void)
|
||||
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
|
||||
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
|
||||
|
||||
buf = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
|
||||
log_sys->buf = ut_align(buf, OS_FILE_LOG_BLOCK_SIZE);
|
||||
log_sys->buf_ptr = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
|
||||
log_sys->buf = ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE);
|
||||
|
||||
log_sys->buf_size = LOG_BUFFER_SIZE;
|
||||
|
||||
@@ -833,9 +831,9 @@ log_init(void)
|
||||
|
||||
rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
log_sys->checkpoint_buf
|
||||
= ut_align(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),
|
||||
OS_FILE_LOG_BLOCK_SIZE);
|
||||
log_sys->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
|
||||
log_sys->checkpoint_buf = ut_align(log_sys->checkpoint_buf_ptr,
|
||||
OS_FILE_LOG_BLOCK_SIZE);
|
||||
memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
|
||||
/*----------------------------*/
|
||||
|
||||
@@ -918,23 +916,33 @@ log_group_init(
|
||||
group->lsn_offset = LOG_FILE_HDR_SIZE;
|
||||
group->n_pending_writes = 0;
|
||||
|
||||
group->file_header_bufs_ptr = mem_alloc(sizeof(byte*) * n_files);
|
||||
group->file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
group->archive_file_header_bufs_ptr = mem_alloc(
|
||||
sizeof(byte*) * n_files);
|
||||
group->archive_file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
for (i = 0; i < n_files; i++) {
|
||||
*(group->file_header_bufs + i) = ut_align(
|
||||
mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
|
||||
group->file_header_bufs_ptr[i] = mem_alloc(
|
||||
LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
|
||||
|
||||
group->file_header_bufs[i] = ut_align(
|
||||
group->file_header_bufs_ptr[i],
|
||||
OS_FILE_LOG_BLOCK_SIZE);
|
||||
|
||||
memset(*(group->file_header_bufs + i), '\0',
|
||||
LOG_FILE_HDR_SIZE);
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
*(group->archive_file_header_bufs + i) = ut_align(
|
||||
mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
|
||||
group->archive_file_header_bufs_ptr[i] = mem_alloc(
|
||||
LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
|
||||
|
||||
group->archive_file_header_bufs[i] = ut_align(
|
||||
group->archive_file_header_bufs_ptr[i],
|
||||
OS_FILE_LOG_BLOCK_SIZE);
|
||||
|
||||
memset(*(group->archive_file_header_bufs + i), '\0',
|
||||
LOG_FILE_HDR_SIZE);
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
@@ -947,8 +955,9 @@ log_group_init(
|
||||
group->archived_offset = 0;
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
group->checkpoint_buf = ut_align(
|
||||
mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE);
|
||||
group->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
|
||||
group->checkpoint_buf = ut_align(group->checkpoint_buf_ptr,
|
||||
OS_FILE_LOG_BLOCK_SIZE);
|
||||
|
||||
memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
|
||||
|
||||
@@ -3364,4 +3373,95 @@ log_refresh_stats(void)
|
||||
log_sys->n_log_ios_old = log_sys->n_log_ios;
|
||||
log_sys->last_printout_time = time(NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Closes a log group. */
|
||||
static
|
||||
void
|
||||
log_group_close(
|
||||
/*===========*/
|
||||
log_group_t* group) /* in,own: log group to close */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < group->n_files; i++) {
|
||||
mem_free(group->file_header_bufs_ptr[i]);
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
mem_free(group->archive_file_header_bufs_ptr[i]);
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
}
|
||||
|
||||
mem_free(group->file_header_bufs_ptr);
|
||||
mem_free(group->file_header_bufs);
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
mem_free(group->archive_file_header_bufs_ptr);
|
||||
mem_free(group->archive_file_header_bufs);
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
mem_free(group->checkpoint_buf_ptr);
|
||||
|
||||
mem_free(group);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
Shutdown the log system but do not release all the memory. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_shutdown(void)
|
||||
/*==============*/
|
||||
{
|
||||
log_group_t* group;
|
||||
|
||||
group = UT_LIST_GET_FIRST(log_sys->log_groups);
|
||||
|
||||
while (UT_LIST_GET_LEN(log_sys->log_groups) > 0) {
|
||||
log_group_t* prev_group = group;
|
||||
|
||||
group = UT_LIST_GET_NEXT(log_groups, group);
|
||||
UT_LIST_REMOVE(log_groups, log_sys->log_groups, prev_group);
|
||||
|
||||
log_group_close(prev_group);
|
||||
}
|
||||
|
||||
mem_free(log_sys->buf_ptr);
|
||||
log_sys->buf_ptr = NULL;
|
||||
log_sys->buf = NULL;
|
||||
mem_free(log_sys->checkpoint_buf_ptr);
|
||||
log_sys->checkpoint_buf_ptr = NULL;
|
||||
log_sys->checkpoint_buf = NULL;
|
||||
|
||||
os_event_free(log_sys->no_flush_event);
|
||||
os_event_free(log_sys->one_flushed_event);
|
||||
|
||||
rw_lock_free(&log_sys->checkpoint_lock);
|
||||
|
||||
mutex_free(&log_sys->mutex);
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
rw_lock_free(&log_sys->archive_lock);
|
||||
os_event_create(log_sys->archiving_on);
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
#ifdef UNIV_LOG_DEBUG
|
||||
recv_sys_debug_free();
|
||||
#endif
|
||||
|
||||
recv_sys_close();
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
Free the log system data structures. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_mem_free(void)
|
||||
/*==============*/
|
||||
{
|
||||
if (log_sys != NULL) {
|
||||
recv_sys_mem_free();
|
||||
mem_free(log_sys);
|
||||
|
||||
log_sys = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
@@ -69,15 +69,15 @@ UNIV_INTERN recv_sys_t* recv_sys = NULL;
|
||||
/** TRUE when applying redo log records during crash recovery; FALSE
|
||||
otherwise. Note that this is FALSE while a background thread is
|
||||
rolling back incomplete transactions. */
|
||||
UNIV_INTERN ibool recv_recovery_on = FALSE;
|
||||
UNIV_INTERN ibool recv_recovery_on;
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
/** TRUE when applying redo log records from an archived log file */
|
||||
UNIV_INTERN ibool recv_recovery_from_backup_on = FALSE;
|
||||
UNIV_INTERN ibool recv_recovery_from_backup_on;
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/** TRUE when recv_init_crash_recovery() has been called. */
|
||||
UNIV_INTERN ibool recv_needed_recovery = FALSE;
|
||||
UNIV_INTERN ibool recv_needed_recovery;
|
||||
# ifdef UNIV_DEBUG
|
||||
/** TRUE if writing to the redo log (mtr_commit) is forbidden.
|
||||
Protected by log_sys->mutex. */
|
||||
@@ -87,7 +87,7 @@ UNIV_INTERN ibool recv_no_log_write = FALSE;
|
||||
/** TRUE if buf_page_is_corrupted() should check if the log sequence
|
||||
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
|
||||
recv_recovery_from_checkpoint_start_func(). */
|
||||
UNIV_INTERN ibool recv_lsn_checks_on = FALSE;
|
||||
UNIV_INTERN ibool recv_lsn_checks_on;
|
||||
|
||||
/** There are two conditions under which we scan the logs, the first
|
||||
is normal startup and the second is when we do a recovery from an
|
||||
@@ -97,7 +97,7 @@ startup. If we find log entries that were written after the last checkpoint
|
||||
we know that the server was not cleanly shutdown. We must then initialize
|
||||
the crash recovery environment before attempting to store these entries in
|
||||
the log hash table. */
|
||||
static ibool recv_log_scan_is_startup_type = FALSE;
|
||||
static ibool recv_log_scan_is_startup_type;
|
||||
|
||||
/** If the following is TRUE, the buffer pool file pages must be invalidated
|
||||
after recovery and no ibuf operations are allowed; this becomes TRUE if
|
||||
@@ -108,7 +108,7 @@ buffer pool before the pages have been recovered to the up-to-date state.
|
||||
|
||||
TRUE means that recovery is running and no operations on the log files
|
||||
are allowed yet: the variable name is misleading. */
|
||||
UNIV_INTERN ibool recv_no_ibuf_operations = FALSE;
|
||||
UNIV_INTERN ibool recv_no_ibuf_operations;
|
||||
/** TRUE when the redo log is being backed up */
|
||||
# define recv_is_making_a_backup FALSE
|
||||
/** TRUE when recovering from a backed up redo log file */
|
||||
@@ -116,30 +116,30 @@ UNIV_INTERN ibool recv_no_ibuf_operations = FALSE;
|
||||
#else /* !UNIV_HOTBACKUP */
|
||||
# define recv_needed_recovery FALSE
|
||||
/** TRUE when the redo log is being backed up */
|
||||
UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
|
||||
UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
|
||||
/** TRUE when recovering from a backed up redo log file */
|
||||
UNIV_INTERN ibool recv_is_from_backup = FALSE;
|
||||
# define buf_pool_get_curr_size() (5 * 1024 * 1024)
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/** The following counter is used to decide when to print info on
|
||||
log scan */
|
||||
static ulint recv_scan_print_counter = 0;
|
||||
static ulint recv_scan_print_counter;
|
||||
|
||||
/** The type of the previous parsed redo log record */
|
||||
static ulint recv_previous_parsed_rec_type = 999999;
|
||||
static ulint recv_previous_parsed_rec_type;
|
||||
/** The offset of the previous parsed redo log record */
|
||||
static ulint recv_previous_parsed_rec_offset = 0;
|
||||
static ulint recv_previous_parsed_rec_offset;
|
||||
/** The 'multi' flag of the previous parsed redo log record */
|
||||
static ulint recv_previous_parsed_rec_is_multi = 0;
|
||||
static ulint recv_previous_parsed_rec_is_multi;
|
||||
|
||||
/** Maximum page number encountered in the redo log */
|
||||
UNIV_INTERN ulint recv_max_parsed_page_no = 0;
|
||||
UNIV_INTERN ulint recv_max_parsed_page_no;
|
||||
|
||||
/** This many frames must be left free in the buffer pool when we scan
|
||||
the log and store the scanned log records in the buffer pool: we will
|
||||
use these free frames to read in pages when we start applying the
|
||||
log records to the database. */
|
||||
UNIV_INTERN ulint recv_n_pool_free_frames = 256;
|
||||
UNIV_INTERN ulint recv_n_pool_free_frames;
|
||||
|
||||
/** The maximum lsn we see for a page during the recovery process. If this
|
||||
is bigger than the lsn we are able to scan up to, that is an indication that
|
||||
@@ -170,7 +170,8 @@ recv_sys_create(void)
|
||||
return;
|
||||
}
|
||||
|
||||
recv_sys = mem_alloc(sizeof(recv_sys_t));
|
||||
recv_sys = mem_alloc(sizeof(*recv_sys));
|
||||
memset(recv_sys, 0x0, sizeof(*recv_sys));
|
||||
|
||||
mutex_create(&recv_sys->mutex, SYNC_RECV);
|
||||
|
||||
@@ -179,6 +180,106 @@ recv_sys_create(void)
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Release recovery system mutexes. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_sys_close(void)
|
||||
/*================*/
|
||||
{
|
||||
if (recv_sys != NULL) {
|
||||
if (recv_sys->addr_hash != NULL) {
|
||||
hash_table_free(recv_sys->addr_hash);
|
||||
}
|
||||
|
||||
if (recv_sys->heap != NULL) {
|
||||
mem_heap_free(recv_sys->heap);
|
||||
}
|
||||
|
||||
if (recv_sys->buf != NULL) {
|
||||
ut_free(recv_sys->buf);
|
||||
}
|
||||
|
||||
if (recv_sys->last_block_buf_start != NULL) {
|
||||
mem_free(recv_sys->last_block_buf_start);
|
||||
}
|
||||
|
||||
mutex_free(&recv_sys->mutex);
|
||||
|
||||
mem_free(recv_sys);
|
||||
recv_sys = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Frees the recovery system memory. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_sys_mem_free(void)
|
||||
/*===================*/
|
||||
{
|
||||
if (recv_sys != NULL) {
|
||||
if (recv_sys->addr_hash != NULL) {
|
||||
hash_table_free(recv_sys->addr_hash);
|
||||
}
|
||||
|
||||
if (recv_sys->heap != NULL) {
|
||||
mem_heap_free(recv_sys->heap);
|
||||
}
|
||||
|
||||
if (recv_sys->buf != NULL) {
|
||||
ut_free(recv_sys->buf);
|
||||
}
|
||||
|
||||
if (recv_sys->last_block_buf_start != NULL) {
|
||||
mem_free(recv_sys->last_block_buf_start);
|
||||
}
|
||||
|
||||
mem_free(recv_sys);
|
||||
recv_sys = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
Reset the state of the recovery system variables. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_sys_var_init(void)
|
||||
/*===================*/
|
||||
{
|
||||
recv_lsn_checks_on = FALSE;
|
||||
|
||||
recv_n_pool_free_frames = 256;
|
||||
|
||||
recv_recovery_on = FALSE;
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
recv_recovery_from_backup_on = FALSE;
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
recv_needed_recovery = FALSE;
|
||||
|
||||
recv_lsn_checks_on = FALSE;
|
||||
|
||||
recv_log_scan_is_startup_type = FALSE;
|
||||
|
||||
recv_no_ibuf_operations = FALSE;
|
||||
|
||||
recv_scan_print_counter = 0;
|
||||
|
||||
recv_previous_parsed_rec_type = 999999;
|
||||
|
||||
recv_previous_parsed_rec_offset = 0;
|
||||
|
||||
recv_previous_parsed_rec_is_multi = 0;
|
||||
|
||||
recv_max_parsed_page_no = 0;
|
||||
|
||||
recv_n_pool_free_frames = 256;
|
||||
|
||||
recv_max_page_lsn = 0;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
Inits the recovery system for a recovery operation. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
@@ -253,8 +354,8 @@ recv_sys_empty_hash(void)
|
||||
Frees the recovery system. */
|
||||
static
|
||||
void
|
||||
recv_sys_free(void)
|
||||
/*===============*/
|
||||
recv_sys_debug_free(void)
|
||||
/*=====================*/
|
||||
{
|
||||
mutex_enter(&(recv_sys->mutex));
|
||||
|
||||
@@ -263,8 +364,10 @@ recv_sys_free(void)
|
||||
ut_free(recv_sys->buf);
|
||||
mem_free(recv_sys->last_block_buf_start);
|
||||
|
||||
recv_sys->addr_hash = NULL;
|
||||
recv_sys->buf = NULL;
|
||||
recv_sys->heap = NULL;
|
||||
recv_sys->addr_hash = NULL;
|
||||
recv_sys->last_block_buf_start = NULL;
|
||||
|
||||
mutex_exit(&(recv_sys->mutex));
|
||||
}
|
||||
@@ -3149,7 +3252,7 @@ recv_recovery_from_checkpoint_finish(void)
|
||||
recv_recovery_on = FALSE;
|
||||
|
||||
#ifndef UNIV_LOG_DEBUG
|
||||
recv_sys_free();
|
||||
recv_sys_debug_free();
|
||||
#endif
|
||||
/* Roll back any recovered data dictionary transactions, so
|
||||
that the data dictionary tables will be free of any locks.
|
||||
|
Reference in New Issue
Block a user