30 # ifndef UNIV_HOTBACKUP
34 UNIV_INTERN
mutex_t mem_hash_mutex;
38 UNIV_INTERN mysql_pfs_key_t mem_hash_mutex_key;
47 static ulint mem_n_created_heaps = 0;
48 static ulint mem_n_allocations = 0;
49 static ulint mem_total_allocated_memory = 0;
50 UNIV_INTERN ulint mem_current_allocated_memory = 0;
51 static ulint mem_max_allocated_memory = 0;
52 # ifndef UNIV_HOTBACKUP
53 static ulint mem_last_print_info = 0;
54 static ibool mem_hash_initialized = FALSE;
58 #define MEM_HASH_SIZE 997
62 typedef struct mem_hash_node_struct mem_hash_node_t;
63 struct mem_hash_node_struct {
67 const
char* file_name;
77 static mem_hash_cell_t mem_hash_table[MEM_HASH_SIZE];
80 static mem_hash_cell_t mem_all_list_base;
86 mem_hash_get_nth_cell(ulint i);
92 mem_hash_get_nth_cell(ulint i)
94 ut_a(i < MEM_HASH_SIZE);
96 return(&(mem_hash_table[i]));
102 mem_field_header_set_len(byte* field, ulint len)
109 mem_field_header_get_len(byte* field)
116 mem_field_header_set_check(byte* field, ulint check)
123 mem_field_header_get_check(byte* field)
130 mem_field_trailer_set_check(byte* field, ulint check)
137 mem_field_trailer_get_check(byte* field)
140 + mem_field_header_get_len(field)));
144 #ifndef UNIV_HOTBACKUP
153 #ifdef UNIV_MEM_DEBUG
158 ut_a(FALSE == mem_hash_initialized);
160 mutex_create(mem_hash_mutex_key, &mem_hash_mutex, SYNC_MEM_HASH);
162 for (i = 0; i < MEM_HASH_SIZE; i++) {
168 mem_hash_initialized = TRUE;
171 if (UNIV_LIKELY(srv_use_sys_malloc)) {
191 #ifdef UNIV_MEM_DEBUG
192 mutex_free(&mem_hash_mutex);
193 mem_hash_initialized = FALSE;
198 #ifdef UNIV_MEM_DEBUG
211 usr_buf = buf + MEM_FIELD_HEADER_SIZE;
219 mem_field_header_set_len(usr_buf, n);
223 mem_field_header_set_check(usr_buf, rnd);
224 mem_field_trailer_set_check(usr_buf, rnd);
228 mutex_enter(&mem_hash_mutex);
230 mem_total_allocated_memory += n;
231 mem_current_allocated_memory += n;
234 if (mem_current_allocated_memory > mem_max_allocated_memory) {
235 mem_max_allocated_memory = mem_current_allocated_memory;
238 mutex_exit(&mem_hash_mutex);
243 mem_init_buf(usr_buf, n);
258 usr_buf = buf + MEM_FIELD_HEADER_SIZE;
260 mutex_enter(&mem_hash_mutex);
261 mem_current_allocated_memory -= n;
262 mutex_exit(&mem_hash_mutex);
265 ut_ad(n == (ulint)mem_field_header_get_len(usr_buf));
270 mem_erase_buf(buf, MEM_SPACE_NEEDED(n));
285 UNIV_MEM_ASSERT_W(buf, n);
287 for (ptr = buf; ptr < buf + n; ptr++) {
296 UNIV_MEM_INVALID(buf, n);
311 UNIV_MEM_ASSERT_W(buf, n);
313 for (ptr = buf; ptr < buf + n; ptr++) {
321 UNIV_MEM_FREE(buf, n);
332 const char* file_name,
335 mem_hash_node_t* new_node;
338 ut_ad(mem_heap_check(heap));
340 mutex_enter(&mem_hash_mutex);
345 new_node =
ut_malloc(
sizeof(mem_hash_node_t));
347 new_node->heap = heap;
348 new_node->file_name = file_name;
349 new_node->line = line;
350 new_node->nth_heap = mem_n_created_heaps;
357 mem_n_created_heaps++;
359 mutex_exit(&mem_hash_mutex);
375 const char* file_name,
378 mem_hash_node_t* node;
383 ut_ad(mem_heap_check(heap));
385 mutex_enter(&mem_hash_mutex);
392 while (node != NULL) {
393 if (node->heap == heap) {
403 "Memory heap or buffer freed in %s line %lu"
415 mem_heap_validate_or_print(node->heap, NULL, FALSE, &error, &size,
419 "Inconsistency in memory heap or"
420 " buffer n:o %lu created\n"
421 "in %s line %lu and tried to free in %s line %lu.\n"
422 "Hex dump of 400 bytes around memory heap"
423 " first block start:\n",
428 fputs(
"\nDump of the mem heap:\n", stderr);
429 mem_heap_validate_or_print(node->heap, NULL, TRUE, &error,
437 mem_current_allocated_memory -= size;
439 mutex_exit(&mem_hash_mutex);
443 #if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
452 mem_heap_validate_or_print(
477 ulint block_count = 0;
479 #ifdef UNIV_MEM_DEBUG
487 if (us_size != NULL) {
490 if (ph_size != NULL) {
493 if (n_blocks != NULL) {
500 if (block->magic_n != MEM_BLOCK_MAGIC_N) {
505 fputs(
"Memory heap:", stderr);
508 while (block != NULL) {
509 phys_len += mem_block_get_len(block);
511 if ((block->
type == MEM_HEAP_BUFFER)
512 && (mem_block_get_len(block) > UNIV_PAGE_SIZE)) {
515 "InnoDB: Error: mem block %p"
516 " length %lu > UNIV_PAGE_SIZE\n",
518 (ulong) mem_block_get_len(block));
524 #ifdef UNIV_MEM_DEBUG
528 fprintf(stderr,
" Block %ld:", block_count);
531 field = (byte*)block + mem_block_get_start(block);
533 if (top && (field == top)) {
538 while (field < (byte*)block + mem_block_get_free(block)) {
543 user_field = field + MEM_FIELD_HEADER_SIZE;
545 len = mem_field_header_get_len(user_field);
553 check_field = mem_field_header_get_check(user_field);
556 != mem_field_trailer_get_check(user_field)) {
560 "InnoDB: Error: block %lx mem"
561 " field %lx len %lu\n"
562 "InnoDB: header check field is"
563 " %lx but trailer %lx\n",
565 (ulint)field, len, check_field,
566 mem_field_trailer_get_check(
573 field = field + MEM_SPACE_NEEDED(len);
575 if (top && (field == top)) {
585 if (field != (byte*)block + mem_block_get_free(block)) {
589 "InnoDB: Error: block %lx end of"
591 "InnoDB: but block free at %lx\n",
592 (ulint)block, (ulint)field,
594 + mem_block_get_free(block)));
604 #ifdef UNIV_MEM_DEBUG
607 if (us_size != NULL) {
608 *us_size = total_len;
610 if (ph_size != NULL) {
613 if (n_blocks != NULL) {
614 *n_blocks = block_count;
632 ut_ad(mem_heap_check(heap));
634 mem_heap_validate_or_print(heap, NULL, TRUE, &error,
635 &us_size, &phys_size, &n_blocks);
637 "\nheap type: %lu; size: user size %lu;"
638 " physical size %lu; blocks %lu.\n",
639 (ulong) heap->
type, (ulong) us_size,
640 (ulong) phys_size, (ulong) n_blocks);
658 ut_ad(mem_heap_check(heap));
660 mem_heap_validate_or_print(heap, NULL, FALSE, &error, &us_size,
661 &phys_size, &n_blocks);
663 mem_heap_print(heap);
682 ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
688 #ifdef UNIV_MEM_DEBUG
697 mem_hash_node_t* node;
698 ulint heap_count = 0;
703 mutex_enter(&mem_hash_mutex);
705 for (i = 0; i < MEM_HASH_SIZE; i++) {
708 while (node != NULL) {
714 mutex_exit(&mem_hash_mutex);
716 if (heap_count == 0) {
717 # ifndef UNIV_HOTBACKUP
732 mem_validate_no_assert(
void)
735 mem_hash_node_t* node;
739 ulint total_allocated_mem = 0;
744 # ifndef UNIV_HOTBACKUP
748 mutex_enter(&mem_hash_mutex);
750 for (i = 0; i < MEM_HASH_SIZE; i++) {
754 while (node != NULL) {
757 mem_heap_validate_or_print(node->heap, NULL,
760 &ph_size, &n_blocks);
764 "\nERROR!!!!!!!!!!!!!!!!!!!"
765 "!!!!!!!!!!!!!!!!!!!!!!!\n\n"
766 "Inconsistency in memory heap"
767 " or buffer created\n"
772 mutex_exit(&mem_hash_mutex);
777 total_allocated_mem += allocated_mem;
782 if ((n_heaps == 0) && (mem_current_allocated_memory != 0)) {
786 if (mem_total_allocated_memory < mem_current_allocated_memory) {
790 if (mem_max_allocated_memory > mem_total_allocated_memory) {
794 if (mem_n_created_heaps < n_heaps) {
798 mutex_exit(&mem_hash_mutex);
811 ut_a(!mem_validate_no_assert());
830 fputs(
"InnoDB: Apparent memory corruption: mem dump ", stderr);
833 fputs(
"\nInnoDB: Scanning backward trying to find"
834 " previous allocated mem blocks\n", stderr);
839 for (i = 0; i < 10; i++) {
841 if (((ulint)p) % 4 == 0) {
843 if (*((ulint*)p) == MEM_BLOCK_MAGIC_N) {
845 "Mem block at - %lu,"
846 " file %s, line %lu\n",
856 if (*((ulint*)p) == MEM_FREED_BLOCK_MAGIC_N) {
858 "Freed mem block at - %lu,"
859 " file %s, line %lu\n",
879 "InnoDB: Scanning forward trying to find next"
880 " allocated mem blocks\n");
885 for (i = 0; i < 10; i++) {
887 if (((ulint)p) % 4 == 0) {
889 if (*((ulint*)p) == MEM_BLOCK_MAGIC_N) {
891 "Mem block at + %lu, file %s,"
902 if (*((ulint*)p) == MEM_FREED_BLOCK_MAGIC_N) {
904 "Freed mem block at + %lu,"
905 " file %s, line %lu\n",
925 #ifndef UNIV_HOTBACKUP
937 #ifdef UNIV_MEM_DEBUG
938 mem_hash_node_t* node;
942 ulint total_allocated_mem = 0;
952 fprintf(outfile,
"\n");
954 "________________________________________________________\n");
955 fprintf(outfile,
"MEMORY ALLOCATION INFORMATION\n\n");
957 #ifndef UNIV_MEM_DEBUG
964 "Sorry, non-debug version cannot give more memory info\n");
970 mutex_enter(&mem_hash_mutex);
972 fprintf(outfile,
"LIST OF CREATED HEAPS AND ALLOCATED BUFFERS: \n\n");
975 fprintf(outfile,
"AFTER THE LAST PRINT INFO\n");
980 while (node != NULL) {
983 if (!print_all && node->nth_heap < mem_last_print_info) {
988 mem_heap_validate_or_print(node->heap, NULL,
989 FALSE, &error, &allocated_mem,
990 &ph_size, &n_blocks);
991 total_allocated_mem += allocated_mem;
994 "%lu: file %s line %lu of size %lu phys.size %lu"
995 " with %lu blocks, type %lu\n",
998 allocated_mem, ph_size, n_blocks,
1004 fprintf(outfile,
"\n");
1006 fprintf(outfile,
"Current allocated memory : %lu\n",
1007 mem_current_allocated_memory);
1008 fprintf(outfile,
"Current allocated heaps and buffers : %lu\n",
1010 fprintf(outfile,
"Cumulative allocated memory : %lu\n",
1011 mem_total_allocated_memory);
1012 fprintf(outfile,
"Maximum allocated memory : %lu\n",
1013 mem_max_allocated_memory);
1014 fprintf(outfile,
"Cumulative created heaps and buffers : %lu\n",
1015 mem_n_created_heaps);
1016 fprintf(outfile,
"Cumulative number of allocations : %lu\n",
1019 mem_last_print_info = mem_n_created_heaps;
1021 mutex_exit(&mem_hash_mutex);
1039 mem_print_info_low(TRUE);
1050 mem_print_info_low(FALSE);
#define UT_LIST_GET_NEXT(NAME, N)
UNIV_INTERN mem_pool_t * mem_pool_create(ulint size)
UNIV_INLINE void mach_write_to_4(byte *b, ulint n)
UNIV_INLINE ulint ut_hash_ulint(ulint key, ulint table_size)
UNIV_INTERN ibool mem_pool_validate(mem_pool_t *pool)
UNIV_INTERN void ut_print_buf(FILE *file, const void *buf, ulint len)
UNIV_INTERN void mem_close(void)
UNIV_INTERN void * ut_malloc(ulint n)
UNIV_INTERN void mem_print_info(void)
typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t
#define UT_LIST_REMOVE(NAME, BASE, N)
UNIV_INTERN void mem_pool_print_info(FILE *outfile, mem_pool_t *pool)
const char * innobase_basename(const char *path_name)
UNIV_INLINE ulint ut_rnd_gen_ulint(void)
#define UT_LIST_NODE_T(TYPE)
#define UT_LIST_ADD_LAST(NAME, BASE, N)
#define UT_LIST_GET_FIRST(BASE)
UNIV_INTERN void mem_init(ulint size)
UNIV_INTERN ulint mem_pool_get_reserved(mem_pool_t *pool)
UNIV_INTERN void ut_free(void *ptr)
#define UT_LIST_INIT(BASE)
#define UT_LIST_ADD_FIRST(NAME, BASE, N)
mem_pool_t * mem_comm_pool
UNIV_INLINE ulint mach_read_from_4(const byte *b) __attribute__((nonnull
UNIV_INTERN void mem_pool_free(mem_pool_t *pool)
UNIV_INTERN void mem_analyze_corruption(void *ptr)
UNIV_INTERN void mem_print_new_info(void)
UNIV_INLINE ibool ut_rnd_gen_ibool(void)