mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 11:27:39 +02:00
Fixed BUG#19542 "InnoDB doesn't increase the Handler_read_prev couter".
Fixed BUG#19609 "Case sensitivity of innodb_data_file_path gives stupid error".
Fixed BUG#19727 "InnoDB crashed server and crashed tables are ot recoverable".
Also:
* Remove remnants of the obsolete concept of memoryfixing tables and indexes.
* Remove unused dict_table_LRU_trim().
* Remove unused 'trx' parameter from dict_table_get_on_id_low(),
dict_table_get(), dict_table_get_and_increment_handle_count().
* Add a normal linked list implementation.
* Add a work queue implementation.
* Add 'level' parameter to mutex_create() and rw_lock_create().
Remove mutex_set_level() and rw_lock_set_level().
* Rename SYNC_LEVEL_NONE to SYNC_LEVEL_VARYING.
* Add support for bound ids in InnoDB's parser.
* Define UNIV_BTR_DEBUG for enabling consistency checks of
FIL_PAGE_NEXT and FIL_PAGE_PREV when accessing sibling
pages of B-tree indexes.
btr_validate_level(): Check the validity of the doubly linked
list formed by FIL_PAGE_NEXT and FIL_PAGE_PREV.
* Adapt InnoDB to the new tablename to filename encoding in MySQL 5.1.
ut_print_name(), ut_print_name1(): Add parameter 'table_id' for
distinguishing names of tables from other identifiers.
New: innobase_convert_from_table_id(), innobase_convert_from_id(),
innobase_convert_from_filename(), innobase_get_charset.
dict_accept(), dict_scan_id(), dict_scan_col(), dict_scan_table_name(),
dict_skip_word(), dict_create_foreign_constraints_low(): Add
parameter 'cs' so that isspace() can be replaced with my_isspace(),
whose operation depends on the connection character set.
dict_scan_id(): Convert identifier to UTF-8.
dict_str_starts_with_keyword(): New extern function, to replace
dict_accept() in row_search_for_mysql().
mysql_get_identifier_quote_char(): Replaced with innobase_print_identifier().
ha_innobase::create(): Remove the thd->convert_strin() call. Pass the
statement to InnoDB in the connection character set and let InnoDB
convert the identifier to UTF-8.
* Add max_row_size to dict_table_t.
* btr0cur.c
btr_copy_externally_stored_field(): Only set the 'offset' variable
when needed.
* buf0buf.c
buf_page_io_complete(): Write to the error log if the page number or
the space id o the disk do not match those in memory. Also write to
the error log if a page was read from the doublewrite buffer. The
doublewrite buffer should be only read by the lower-level function
fil_io() at database startup.
* dict0dict.c
dict_scan_table_name(): Remove fallback to differently encoded name
when the table is not found. The encoding is handled at a higher level.
* ha_innodb.cc
Increment statistic counter in ha_innobase::index_prev() (bug 19542).
Add innobase_convert_string wrapper function and a new file
ha_prototypes.h.
innobase_print_identifier(): Remove TODO comment before calling
get_quote_char_for_identifier(). That function apparently assumes
the identifier to be encoded in UTF-8.
* ibuf0ibuf.c|h
ibuf_count_get(), ibuf_counts[], ibuf_count_inited(): Define these
only #ifdef UNIV_IBUF_DEBUG. Previously, when compiled without
UNIV_IBUF_DEBUG, invoking ibuf_count_get() would crash InnoDB.
The function is only being called #ifdef UNIV_IBUF_DEBUG.
* innodb.result
Adjust the results for changes in the foreign key error messages.
* mem0mem.c|h
New: mem_heap_dup(), mem_heap_printf(), mem_heap_cat().
* os0file.c
Check the page trailers also after writing to disk. This improves
chances of diagnosing bug 18886.
os_file_check_page_trailers(): New function for checking that the
two copies of the LSN stamped on the page match.
os_aio_simulated_handle(): Call os_file_check_page_trailers()
before and after os_file_write().
* row0mysql.c
Move trx_commit_for_mysql(trx) calls before calls to
row_mysql_unlock_data_dictionary(trx) (bug 19727).
* row0sel.c
row_fetch_print(): Handle SQL NULL values without crashing.
row_sel_store_mysql_rec(): Remove useless call to rec_get_nth_field
when handling an externally stored column.
Fetch externally stored fields when using InnoDB's internal SQL
parser.
Optimize BLOB selects by using prebuilt->blob_heap directly instead
of first reading BLOB data to a temporary heap and then copying it
to prebuilt->blob_heap.
* srv0srv.c
srv_master_thread(): Remove unreachable code.
* srv0start.c
srv_parse_data_file_paths_and_sizes(): Accept lower-case 'm' and
'g' as abbreviations of megabyte and gigabyte (bug 19609).
srv_parse_megabytes(): New fuction.
* ut0dbg.c|h
Implement InnoDB assertions (ut_a and ut_error) with abort() when
the code is compiled with GCC 3 or later on other platforms than
Windows or Netware. Also disable the variable ut_dbg_stop_threads
and the function ut_dbg_stop_thread() i this case, unless
UNIV_SYC_DEBUG is defined. This should allow the compiler to
generate more compact code for assertions.
* ut0list.c|h
Add ib_list_create_heap().
423 lines
15 KiB
C
423 lines
15 KiB
C
/******************************************************
|
|
The memory management
|
|
|
|
(c) 1994, 1995 Innobase Oy
|
|
|
|
Created 6/9/1994 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#ifndef mem0mem_h
|
|
#define mem0mem_h
|
|
|
|
#include "univ.i"
|
|
#include "ut0mem.h"
|
|
#include "ut0byte.h"
|
|
#include "ut0ut.h"
|
|
#include "ut0rnd.h"
|
|
#include "sync0sync.h"
|
|
#include "ut0lst.h"
|
|
#include "mach0data.h"
|
|
|
|
/* -------------------- MEMORY HEAPS ----------------------------- */
|
|
|
|
/* The info structure stored at the beginning of a heap block */
|
|
typedef struct mem_block_info_struct mem_block_info_t;
|
|
|
|
/* A block of a memory heap consists of the info structure
|
|
followed by an area of memory */
|
|
typedef mem_block_info_t mem_block_t;
|
|
|
|
/* A memory heap is a nonempty linear list of memory blocks */
|
|
typedef mem_block_t mem_heap_t;
|
|
|
|
/* Types of allocation for memory heaps: DYNAMIC means allocation from the
|
|
dynamic memory pool of the C compiler, BUFFER means allocation from the
|
|
buffer pool; the latter method is used for very big heaps */
|
|
|
|
#define MEM_HEAP_DYNAMIC 0 /* the most common type */
|
|
#define MEM_HEAP_BUFFER 1
|
|
#define MEM_HEAP_BTR_SEARCH 2 /* this flag can optionally be
|
|
ORed to MEM_HEAP_BUFFER, in which
|
|
case heap->free_block is used in
|
|
some cases for memory allocations,
|
|
and if it's NULL, the memory
|
|
allocation functions can return
|
|
NULL. */
|
|
|
|
/* The following start size is used for the first block in the memory heap if
|
|
the size is not specified, i.e., 0 is given as the parameter in the call of
|
|
create. The standard size is the maximum (payload) size of the blocks used for
|
|
allocations of small buffers. */
|
|
|
|
#define MEM_BLOCK_START_SIZE 64
|
|
#define MEM_BLOCK_STANDARD_SIZE 8000
|
|
|
|
/* If a memory heap is allowed to grow into the buffer pool, the following
|
|
is the maximum size for a single allocated buffer: */
|
|
#define MEM_MAX_ALLOC_IN_BUF (UNIV_PAGE_SIZE - 200)
|
|
|
|
/**********************************************************************
|
|
Initializes the memory system. */
|
|
|
|
void
|
|
mem_init(
|
|
/*=====*/
|
|
ulint size); /* in: common pool size in bytes */
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function! Macro for memory
|
|
heap creation. */
|
|
|
|
#define mem_heap_create(N) mem_heap_create_func(\
|
|
(N), NULL, MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function! Macro for memory
|
|
heap creation. */
|
|
|
|
#define mem_heap_create_in_buffer(N) mem_heap_create_func(\
|
|
(N), NULL, MEM_HEAP_BUFFER, __FILE__, __LINE__)
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function! Macro for memory
|
|
heap creation. */
|
|
|
|
#define mem_heap_create_in_btr_search(N) mem_heap_create_func(\
|
|
(N), NULL, MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER,\
|
|
__FILE__, __LINE__)
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function! Macro for fast
|
|
memory heap creation. An initial block of memory B is given by the
|
|
caller, N is its size, and this memory block is not freed by
|
|
mem_heap_free. See the parameter comment in mem_heap_create_func below. */
|
|
|
|
#define mem_heap_fast_create(N, B) mem_heap_create_func(\
|
|
(N), (B), MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
|
|
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function! Macro for memory
|
|
heap freeing. */
|
|
|
|
#define mem_heap_free(heap) mem_heap_free_func(\
|
|
(heap), __FILE__, __LINE__)
|
|
/*********************************************************************
|
|
NOTE: Use the corresponding macros instead of this function. Creates a
|
|
memory heap. For debugging purposes, takes also the file name and line as
|
|
arguments. */
|
|
UNIV_INLINE
|
|
mem_heap_t*
|
|
mem_heap_create_func(
|
|
/*=================*/
|
|
/* out, own: memory heap, NULL if
|
|
did not succeed (only possible for
|
|
MEM_HEAP_BTR_SEARCH type heaps)*/
|
|
ulint n, /* in: desired start block size,
|
|
this means that a single user buffer
|
|
of size n will fit in the block,
|
|
0 creates a default size block;
|
|
if init_block is not NULL, n tells
|
|
its size in bytes */
|
|
void* init_block, /* in: if very fast creation is
|
|
wanted, the caller can reserve some
|
|
memory from its stack, for example,
|
|
and pass it as the the initial block
|
|
to the heap: then no OS call of malloc
|
|
is needed at the creation. CAUTION:
|
|
the caller must make sure the initial
|
|
block is not unintentionally erased
|
|
(if allocated in the stack), before
|
|
the memory heap is explicitly freed. */
|
|
ulint type, /* in: heap type */
|
|
const char* file_name, /* in: file name where created */
|
|
ulint line); /* in: line where created */
|
|
/*********************************************************************
|
|
NOTE: Use the corresponding macro instead of this function. Frees the space
|
|
occupied by a memory heap. In the debug version erases the heap memory
|
|
blocks. */
|
|
UNIV_INLINE
|
|
void
|
|
mem_heap_free_func(
|
|
/*===============*/
|
|
mem_heap_t* heap, /* in, own: heap to be freed */
|
|
const char* file_name, /* in: file name where freed */
|
|
ulint line); /* in: line where freed */
|
|
/*******************************************************************
|
|
Allocates n bytes of memory from a memory heap. */
|
|
UNIV_INLINE
|
|
void*
|
|
mem_heap_alloc(
|
|
/*===========*/
|
|
/* out: allocated storage, NULL if did not
|
|
succeed (only possible for
|
|
MEM_HEAP_BTR_SEARCH type heaps) */
|
|
mem_heap_t* heap, /* in: memory heap */
|
|
ulint n); /* in: number of bytes; if the heap is allowed
|
|
to grow into the buffer pool, this must be
|
|
<= MEM_MAX_ALLOC_IN_BUF */
|
|
/*********************************************************************
|
|
Returns a pointer to the heap top. */
|
|
UNIV_INLINE
|
|
byte*
|
|
mem_heap_get_heap_top(
|
|
/*==================*/
|
|
/* out: pointer to the heap top */
|
|
mem_heap_t* heap); /* in: memory heap */
|
|
/*********************************************************************
|
|
Frees the space in a memory heap exceeding the pointer given. The
|
|
pointer must have been acquired from mem_heap_get_heap_top. The first
|
|
memory block of the heap is not freed. */
|
|
UNIV_INLINE
|
|
void
|
|
mem_heap_free_heap_top(
|
|
/*===================*/
|
|
mem_heap_t* heap, /* in: heap from which to free */
|
|
byte* old_top);/* in: pointer to old top of heap */
|
|
/*********************************************************************
|
|
Empties a memory heap. The first memory block of the heap is not freed. */
|
|
UNIV_INLINE
|
|
void
|
|
mem_heap_empty(
|
|
/*===========*/
|
|
mem_heap_t* heap); /* in: heap to empty */
|
|
/*********************************************************************
|
|
Returns a pointer to the topmost element in a memory heap.
|
|
The size of the element must be given. */
|
|
UNIV_INLINE
|
|
void*
|
|
mem_heap_get_top(
|
|
/*=============*/
|
|
/* out: pointer to the topmost element */
|
|
mem_heap_t* heap, /* in: memory heap */
|
|
ulint n); /* in: size of the topmost element */
|
|
/*********************************************************************
|
|
Frees the topmost element in a memory heap.
|
|
The size of the element must be given. */
|
|
UNIV_INLINE
|
|
void
|
|
mem_heap_free_top(
|
|
/*==============*/
|
|
mem_heap_t* heap, /* in: memory heap */
|
|
ulint n); /* in: size of the topmost element */
|
|
/*********************************************************************
|
|
Returns the space in bytes occupied by a memory heap. */
|
|
UNIV_INLINE
|
|
ulint
|
|
mem_heap_get_size(
|
|
/*==============*/
|
|
mem_heap_t* heap); /* in: heap */
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function!
|
|
Macro for memory buffer allocation */
|
|
|
|
#define mem_alloc(N) mem_alloc_func((N), __FILE__, __LINE__)
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function!
|
|
Macro for memory buffer allocation */
|
|
|
|
#define mem_alloc_noninline(N) mem_alloc_func_noninline(\
|
|
(N), __FILE__, __LINE__)
|
|
/*******************************************************************
|
|
NOTE: Use the corresponding macro instead of this function.
|
|
Allocates a single buffer of memory from the dynamic memory of
|
|
the C compiler. Is like malloc of C. The buffer must be freed
|
|
with mem_free. */
|
|
UNIV_INLINE
|
|
void*
|
|
mem_alloc_func(
|
|
/*===========*/
|
|
/* out, own: free storage */
|
|
ulint n, /* in: desired number of bytes */
|
|
const char* file_name, /* in: file name where created */
|
|
ulint line /* in: line where created */
|
|
);
|
|
/*******************************************************************
|
|
NOTE: Use the corresponding macro instead of this function.
|
|
Allocates a single buffer of memory from the dynamic memory of
|
|
the C compiler. Is like malloc of C. The buffer must be freed
|
|
with mem_free. */
|
|
|
|
void*
|
|
mem_alloc_func_noninline(
|
|
/*=====================*/
|
|
/* out, own: free storage */
|
|
ulint n, /* in: desired number of bytes */
|
|
const char* file_name, /* in: file name where created */
|
|
ulint line /* in: line where created */
|
|
);
|
|
/******************************************************************
|
|
Use this macro instead of the corresponding function!
|
|
Macro for memory buffer freeing */
|
|
|
|
#define mem_free(PTR) mem_free_func((PTR), __FILE__, __LINE__)
|
|
/*******************************************************************
|
|
NOTE: Use the corresponding macro instead of this function.
|
|
Frees a single buffer of storage from
|
|
the dynamic memory of C compiler. Similar to free of C. */
|
|
UNIV_INLINE
|
|
void
|
|
mem_free_func(
|
|
/*==========*/
|
|
void* ptr, /* in, own: buffer to be freed */
|
|
const char* file_name, /* in: file name where created */
|
|
ulint line /* in: line where created */
|
|
);
|
|
|
|
/**************************************************************************
|
|
Duplicates a NUL-terminated string. */
|
|
UNIV_INLINE
|
|
char*
|
|
mem_strdup(
|
|
/*=======*/
|
|
/* out, own: a copy of the string,
|
|
must be deallocated with mem_free */
|
|
const char* str); /* in: string to be copied */
|
|
/**************************************************************************
|
|
Makes a NUL-terminated copy of a nonterminated string. */
|
|
UNIV_INLINE
|
|
char*
|
|
mem_strdupl(
|
|
/*========*/
|
|
/* out, own: a copy of the string,
|
|
must be deallocated with mem_free */
|
|
const char* str, /* in: string to be copied */
|
|
ulint len); /* in: length of str, in bytes */
|
|
|
|
/**************************************************************************
|
|
Makes a NUL-terminated quoted copy of a NUL-terminated string. */
|
|
UNIV_INLINE
|
|
char*
|
|
mem_strdupq(
|
|
/*========*/
|
|
/* out, own: a quoted copy of the string,
|
|
must be deallocated with mem_free */
|
|
const char* str, /* in: string to be copied */
|
|
char q); /* in: quote character */
|
|
|
|
/**************************************************************************
|
|
Duplicates a NUL-terminated string, allocated from a memory heap. */
|
|
|
|
char*
|
|
mem_heap_strdup(
|
|
/*============*/
|
|
/* out, own: a copy of the string */
|
|
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
|
const char* str); /* in: string to be copied */
|
|
/**************************************************************************
|
|
Makes a NUL-terminated copy of a nonterminated string,
|
|
allocated from a memory heap. */
|
|
UNIV_INLINE
|
|
char*
|
|
mem_heap_strdupl(
|
|
/*=============*/
|
|
/* out, own: a copy of the string */
|
|
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
|
const char* str, /* in: string to be copied */
|
|
ulint len); /* in: length of str, in bytes */
|
|
|
|
/**************************************************************************
|
|
Concatenate two strings and return the result, using a memory heap. */
|
|
|
|
char*
|
|
mem_heap_strcat(
|
|
/*============*/
|
|
/* out, own: the result */
|
|
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
|
const char* s1, /* in: string 1 */
|
|
const char* s2); /* in: string 2 */
|
|
|
|
/**************************************************************************
|
|
Duplicate a block of data, allocated from a memory heap. */
|
|
|
|
void*
|
|
mem_heap_dup(
|
|
/*=========*/
|
|
/* out, own: a copy of the data */
|
|
mem_heap_t* heap, /* in: memory heap where copy is allocated */
|
|
const void* data, /* in: data to be copied */
|
|
ulint len); /* in: length of data, in bytes */
|
|
|
|
/**************************************************************************
|
|
Concatenate two memory blocks and return the result, using a memory heap. */
|
|
|
|
void*
|
|
mem_heap_cat(
|
|
/*=========*/
|
|
/* out, own: the result */
|
|
mem_heap_t* heap, /* in: memory heap where result is allocated */
|
|
const void* b1, /* in: block 1 */
|
|
ulint len1, /* in: length of b1, in bytes */
|
|
const void* b2, /* in: block 2 */
|
|
ulint len2); /* in: length of b2, in bytes */
|
|
|
|
/********************************************************************
|
|
A simple (s)printf replacement that dynamically allocates the space for the
|
|
formatted string from the given heap. This supports a very limited set of
|
|
the printf syntax: types 's' and 'u' and length modifier 'l' (which is
|
|
required for the 'u' type). */
|
|
|
|
char*
|
|
mem_heap_printf(
|
|
/*============*/
|
|
/* out: heap-allocated formatted string */
|
|
mem_heap_t* heap, /* in: memory heap */
|
|
const char* format, /* in: format string */
|
|
...) __attribute__ ((format (printf, 2, 3)));
|
|
|
|
#ifdef MEM_PERIODIC_CHECK
|
|
/**********************************************************************
|
|
Goes through the list of all allocated mem blocks, checks their magic
|
|
numbers, and reports possible corruption. */
|
|
|
|
void
|
|
mem_validate_all_blocks(void);
|
|
/*=========================*/
|
|
#endif
|
|
|
|
/*#######################################################################*/
|
|
|
|
/* The info header of a block in a memory heap */
|
|
|
|
struct mem_block_info_struct {
|
|
ulint magic_n;/* magic number for debugging */
|
|
char file_name[8];/* file name where the mem heap was created */
|
|
ulint line; /* line number where the mem heap was created */
|
|
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the
|
|
the list this is the base node of the list of blocks;
|
|
in subsequent blocks this is undefined */
|
|
UT_LIST_NODE_T(mem_block_t) list; /* This contains pointers to next
|
|
and prev in the list. The first block allocated
|
|
to the heap is also the first block in this list,
|
|
though it also contains the base node of the list. */
|
|
ulint len; /* physical length of this block in bytes */
|
|
ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or
|
|
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
|
|
ibool init_block; /* TRUE if this is the first block used in fast
|
|
creation of a heap: the memory will be freed
|
|
by the creator, not by mem_heap_free */
|
|
ulint free; /* offset in bytes of the first free position for
|
|
user data in the block */
|
|
ulint start; /* the value of the struct field 'free' at the
|
|
creation of the block */
|
|
byte* free_block;
|
|
/* if the MEM_HEAP_BTR_SEARCH bit is set in type,
|
|
and this is the heap root, this can contain an
|
|
allocated buffer frame, which can be appended as a
|
|
free block to the heap, if we need more space;
|
|
otherwise, this is NULL */
|
|
#ifdef MEM_PERIODIC_CHECK
|
|
UT_LIST_NODE_T(mem_block_t) mem_block_list;
|
|
/* List of all mem blocks allocated; protected
|
|
by the mem_comm_pool mutex */
|
|
#endif
|
|
};
|
|
|
|
#define MEM_BLOCK_MAGIC_N 764741555
|
|
#define MEM_FREED_BLOCK_MAGIC_N 547711122
|
|
|
|
/* Header size for a memory heap block */
|
|
#define MEM_BLOCK_HEADER_SIZE ut_calc_align(sizeof(mem_block_info_t),\
|
|
UNIV_MEM_ALIGNMENT)
|
|
#include "mem0dbg.h"
|
|
|
|
#ifndef UNIV_NONINL
|
|
#include "mem0mem.ic"
|
|
#endif
|
|
|
|
#endif
|