1
0
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:
Satya B
2009-11-30 17:02:05 +05:30
parent cefd968ddd
commit a1092e9b66
48 changed files with 1003 additions and 159 deletions

View File

@@ -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 */

View File

@@ -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.