Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
0c87ad9f
Commit
0c87ad9f
authored
Jan 28, 2002
by
heikki@donna.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Many files:
Merge InnoDB-.48
parent
d927ff75
Changes
26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
985 additions
and
287 deletions
+985
-287
innobase/dict/dict0dict.c
innobase/dict/dict0dict.c
+32
-0
innobase/dict/dict0mem.c
innobase/dict/dict0mem.c
+3
-0
innobase/include/dict0dict.h
innobase/include/dict0dict.h
+14
-0
innobase/include/dict0mem.h
innobase/include/dict0mem.h
+6
-0
innobase/include/mem0dbg.h
innobase/include/mem0dbg.h
+13
-1
innobase/include/mem0mem.h
innobase/include/mem0mem.h
+33
-64
innobase/include/mem0mem.ic
innobase/include/mem0mem.ic
+26
-31
innobase/include/que0que.h
innobase/include/que0que.h
+5
-0
innobase/include/row0mysql.h
innobase/include/row0mysql.h
+7
-0
innobase/include/srv0srv.h
innobase/include/srv0srv.h
+20
-6
innobase/include/trx0sys.h
innobase/include/trx0sys.h
+34
-1
innobase/include/trx0trx.h
innobase/include/trx0trx.h
+22
-0
innobase/log/log0recv.c
innobase/log/log0recv.c
+15
-5
innobase/mem/mem0dbg.c
innobase/mem/mem0dbg.c
+93
-1
innobase/mem/mem0mem.c
innobase/mem/mem0mem.c
+17
-15
innobase/pars/lexyy.c
innobase/pars/lexyy.c
+1
-1
innobase/que/que0que.c
innobase/que/que0que.c
+37
-3
innobase/rem/rem0rec.c
innobase/rem/rem0rec.c
+11
-0
innobase/row/row0mysql.c
innobase/row/row0mysql.c
+186
-37
innobase/row/row0sel.c
innobase/row/row0sel.c
+11
-0
innobase/srv/srv0srv.c
innobase/srv/srv0srv.c
+113
-11
innobase/sync/sync0arr.c
innobase/sync/sync0arr.c
+11
-0
innobase/trx/trx0sys.c
innobase/trx/trx0sys.c
+110
-1
innobase/trx/trx0trx.c
innobase/trx/trx0trx.c
+13
-0
innobase/trx/trx0undo.c
innobase/trx/trx0undo.c
+13
-6
sql/ha_innobase.cc
sql/ha_innobase.cc
+139
-104
No files found.
innobase/dict/dict0dict.c
View file @
0c87ad9f
...
...
@@ -195,6 +195,38 @@ dict_mutex_exit_for_mysql(void)
mutex_exit
(
&
(
dict_sys
->
mutex
));
}
/************************************************************************
Increments the count of open MySQL handles to a table. */
void
dict_table_increment_handle_count
(
/*==============================*/
dict_table_t
*
table
)
/* in: table */
{
mutex_enter
(
&
(
dict_sys
->
mutex
));
table
->
n_mysql_handles_opened
++
;
mutex_exit
(
&
(
dict_sys
->
mutex
));
}
/************************************************************************
Decrements the count of open MySQL handles to a table. */
void
dict_table_decrement_handle_count
(
/*==============================*/
dict_table_t
*
table
)
/* in: table */
{
mutex_enter
(
&
(
dict_sys
->
mutex
));
ut_a
(
table
->
n_mysql_handles_opened
>
0
);
table
->
n_mysql_handles_opened
--
;
mutex_exit
(
&
(
dict_sys
->
mutex
));
}
/************************************************************************
Gets the nth column of a table. */
...
...
innobase/dict/dict0mem.c
View file @
0c87ad9f
...
...
@@ -59,6 +59,9 @@ dict_mem_table_create(
table
->
n_def
=
0
;
table
->
n_cols
=
n_cols
+
DATA_N_SYS_COLS
;
table
->
mem_fix
=
0
;
table
->
n_mysql_handles_opened
=
0
;
table
->
cached
=
FALSE
;
table
->
cols
=
mem_heap_alloc
(
heap
,
(
n_cols
+
DATA_N_SYS_COLS
)
...
...
innobase/include/dict0dict.h
View file @
0c87ad9f
...
...
@@ -26,6 +26,20 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0byte.h"
#include "trx0types.h"
/************************************************************************
Increments the count of open MySQL handles to a table. */
void
dict_table_increment_handle_count
(
/*==============================*/
dict_table_t
*
table
);
/* in: table */
/************************************************************************
Decrements the count of open MySQL handles to a table. */
void
dict_table_decrement_handle_count
(
/*==============================*/
dict_table_t
*
table
);
/* in: table */
/**************************************************************************
Inits the data dictionary module. */
...
...
innobase/include/dict0mem.h
View file @
0c87ad9f
...
...
@@ -307,6 +307,12 @@ struct dict_table_struct{
ulint
mem_fix
;
/* count of how many times the table
and its indexes has been fixed in memory;
currently NOT used */
ulint
n_mysql_handles_opened
;
/* count of how many handles MySQL has opened
to this table; dropping of the table is
NOT allowed until this count gets to zero;
MySQL does NOT itself check the number of
open handles at drop */
ibool
cached
;
/* TRUE if the table object has been added
to the dictionary cache */
lock_t
*
auto_inc_lock
;
/* a buffer for an auto-inc lock
...
...
innobase/include/mem0dbg.h
View file @
0c87ad9f
...
...
@@ -10,11 +10,14 @@ Created 6/9/1994 Heikki Tuuri
/* In the debug version each allocated field is surrounded with
check fields whose sizes are given below */
#ifdef UNIV_MEM_DEBUG
#define MEM_FIELD_HEADER_SIZE ut_calc_align(2 * sizeof(ulint),\
UNIV_MEM_ALIGNMENT)
#define MEM_FIELD_TRAILER_SIZE sizeof(ulint)
#else
#define MEM_FIELD_HEADER_SIZE 0
#endif
#define MEM_BLOCK_MAGIC_N 764741
/* Space needed when allocating for a user a field of
length N. The space is allocated only in multiples of
...
...
@@ -115,3 +118,12 @@ ibool
mem_validate
(
void
);
/*===============*/
/* out: TRUE if ok */
/****************************************************************
Tries to find neigboring memory allocation blocks and dumps to stderr
the neighborhood of a given pointer. */
void
mem_analyze_corruption
(
/*===================*/
byte
*
ptr
);
/* in: pointer to place of possible corruption */
innobase/include/mem0mem.h
View file @
0c87ad9f
...
...
@@ -61,58 +61,41 @@ mem_init(
/******************************************************************
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
#ifdef UNIV_MEM_DEBUG
#define mem_heap_create(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_DYNAMIC,\
IB__FILE__, __LINE__)
#else
#define mem_heap_create(N) mem_heap_create_func(N, NULL, MEM_HEAP_DYNAMIC)
#endif
/******************************************************************
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
#ifdef UNIV_MEM_DEBUG
#define mem_heap_create_in_buffer(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_BUFFER,\
IB__FILE__, __LINE__)
#else
#define mem_heap_create_in_buffer(N) mem_heap_create_func(N, NULL,\
MEM_HEAP_BUFFER)
#endif
/******************************************************************
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
#ifdef UNIV_MEM_DEBUG
#define mem_heap_create_in_btr_search(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_BTR_SEARCH |\
MEM_HEAP_BUFFER,\
IB__FILE__, __LINE__)
#else
#define mem_heap_create_in_btr_search(N) mem_heap_create_func(N, NULL,\
MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER)
#endif
/******************************************************************
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. */
#ifdef UNIV_MEM_DEBUG
#define mem_heap_fast_create(N, B) mem_heap_create_func(\
(N), (B), MEM_HEAP_DYNAMIC,\
IB__FILE__, __LINE__)
#else
#define mem_heap_fast_create(N, B) mem_heap_create_func(N, (B),\
MEM_HEAP_DYNAMIC)
#endif
/******************************************************************
Use this macro instead of the corresponding function! Macro for memory
heap freeing. */
#ifdef UNIV_MEM_DEBUG
#define mem_heap_free(heap) mem_heap_free_func(\
(heap), IB__FILE__, __LINE__)
#else
#define mem_heap_free(heap) mem_heap_free_func(heap)
#endif
/*********************************************************************
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap which allocates memory from dynamic space. For debugging
...
...
@@ -139,11 +122,9 @@ mem_heap_create_func(
block is not unintentionally erased
(if allocated in the stack), before
the memory heap is explicitly freed. */
ulint
type
/* in: MEM_HEAP_DYNAMIC or MEM_HEAP_BUFFER */
#ifdef UNIV_MEM_DEBUG
,
char
*
file_name
,
/* in: file name where created */
ulint
type
,
/* in: MEM_HEAP_DYNAMIC or MEM_HEAP_BUFFER */
char
*
file_name
,
/* in: file name where created */
ulint
line
/* in: line where created */
#endif
);
/*********************************************************************
NOTE: Use the corresponding macro instead of this function.
...
...
@@ -152,11 +133,9 @@ UNIV_INLINE
void
mem_heap_free_func
(
/*===============*/
mem_heap_t
*
heap
/* in, own: heap to be freed */
#ifdef UNIV_MEM_DEBUG
,
char
*
file_name
,
/* in: file name where freed */
ulint
line
/* in: line where freed */
#endif
mem_heap_t
*
heap
,
/* in, own: heap to be freed */
char
*
file_name
,
/* in: file name where freed */
ulint
line
/* in: line where freed */
);
/*******************************************************************
Allocates n bytes of memory from a memory heap. */
...
...
@@ -220,25 +199,18 @@ UNIV_INLINE
ulint
mem_heap_get_size
(
/*==============*/
mem_heap_t
*
heap
);
/* in: heap */
mem_heap_t
*
heap
);
/* in: heap */
/******************************************************************
Use this macro instead of the corresponding function!
Macro for memory buffer allocation */
#ifdef UNIV_MEM_DEBUG
#define mem_alloc(N) mem_alloc_func(\
(N), IB__FILE__, __LINE__)
#else
#define mem_alloc(N) mem_alloc_func(N)
#endif
#define mem_alloc(N) mem_alloc_func((N), IB__FILE__, __LINE__)
/******************************************************************
Use this macro instead of the corresponding function!
Macro for memory buffer allocation */
#ifdef UNIV_MEM_DEBUG
#define mem_alloc_noninline(N) mem_alloc_func_noninline(\
(N), IB__FILE__, __LINE__)
#else
#define mem_alloc_noninline(N) mem_alloc_func_noninline(N)
#endif
/*******************************************************************
NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of
...
...
@@ -250,11 +222,9 @@ mem_alloc_func(
/*===========*/
/* out, own: free storage, NULL
if did not succeed */
ulint
n
/* in: desired number of bytes */
#ifdef UNIV_MEM_DEBUG
,
char
*
file_name
,
/* in: file name where created */
ulint
line
/* in: line where created */
#endif
ulint
n
,
/* in: desired number of bytes */
char
*
file_name
,
/* in: file name where created */
ulint
line
/* in: line where created */
);
/*******************************************************************
NOTE: Use the corresponding macro instead of this function.
...
...
@@ -267,21 +237,15 @@ mem_alloc_func_noninline(
/*=====================*/
/* out, own: free storage, NULL if did not
succeed */
ulint
n
/* in: desired number of bytes */
#ifdef UNIV_MEM_DEBUG
,
char
*
file_name
,
/* in: file name where created */
ulint
n
,
/* in: desired number of bytes */
char
*
file_name
,
/* in: file name where created */
ulint
line
/* in: line where created */
#endif
);
/******************************************************************
Use this macro instead of the corresponding function!
Macro for memory buffer freeing */
#ifdef UNIV_MEM_DEBUG
#define mem_free(PTR) mem_free_func(\
(PTR), IB__FILE__, __LINE__)
#else
#define mem_free(PTR) mem_free_func(PTR)
#endif
#define mem_free(PTR) mem_free_func((PTR), IB__FILE__, __LINE__)
/*******************************************************************
NOTE: Use the corresponding macro instead of this function.
Frees a single buffer of storage from
...
...
@@ -290,11 +254,9 @@ UNIV_INLINE
void
mem_free_func
(
/*==========*/
void
*
ptr
/* in, own: buffer to be freed */
#ifdef UNIV_MEM_DEBUG
,
char
*
file_name
,
/* in: file name where created */
ulint
line
/* in: line where created */
#endif
void
*
ptr
,
/* in, own: buffer to be freed */
char
*
file_name
,
/* in: file name where created */
ulint
line
/* in: line where created */
);
/*******************************************************************
Implements realloc. */
...
...
@@ -304,7 +266,9 @@ mem_realloc(
/*========*/
/* out, own: free storage, NULL if did not succeed */
void
*
buf
,
/* in: pointer to an old buffer */
ulint
n
);
/* in: desired number of bytes */
ulint
n
,
/* in: desired number of bytes */
char
*
file_name
,
/* in: file name where called */
ulint
line
);
/* in: line where called */
/*#######################################################################*/
...
...
@@ -336,8 +300,13 @@ struct mem_block_info_struct {
free block to the heap, if we need more space;
otherwise, this is NULL */
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 */
};
#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)
...
...
innobase/include/mem0mem.ic
View file @
0c87ad9f
...
...
@@ -24,8 +24,10 @@ mem_heap_create_block(
if init_block is not NULL, its size in bytes */
void* init_block, /* in: init block in fast create, type must be
MEM_HEAP_DYNAMIC */
ulint type
);
/* in: type of heap: MEM_HEAP_DYNAMIC or
ulint type
,
/* in: type of heap: MEM_HEAP_DYNAMIC or
MEM_HEAP_BUFFER */
char* file_name,/* in: file name where created */
ulint line); /* in: line where created */
/**********************************************************************
Frees a block from a memory heap. */
...
...
@@ -392,21 +394,20 @@ mem_heap_create_func(
block is not unintentionally erased
(if allocated in the stack), before
the memory heap is explicitly freed. */
ulint type /* in: MEM_HEAP_DYNAMIC, or MEM_HEAP_BUFFER
ulint type
,
/* in: MEM_HEAP_DYNAMIC, or MEM_HEAP_BUFFER
possibly ORed to MEM_HEAP_BTR_SEARCH */
#ifdef UNIV_MEM_DEBUG
,char* file_name, /* in: file name where created */
char* file_name, /* in: file name where created */
ulint line /* in: line where created */
#endif
)
{
mem_block_t* block;
if (n > 0) {
block = mem_heap_create_block(NULL, n, init_block, type);
block = mem_heap_create_block(NULL, n, init_block, type,
file_name, line);
} else {
block = mem_heap_create_block(NULL, MEM_BLOCK_START_SIZE,
init_block, typ
e);
init_block, type, file_name, lin
e);
}
ut_ad(block);
...
...
@@ -438,11 +439,9 @@ UNIV_INLINE
void
mem_heap_free_func(
/*===============*/
mem_heap_t* heap /* in, own: heap to be freed */
#ifdef UNIV_MEM_DEBUG
,char* file_name, /* in: file name where freed */
mem_heap_t* heap, /* in, own: heap to be freed */
char* file_name, /* in: file name where freed */
ulint line /* in: line where freed */
#endif
)
{
mem_block_t* block;
...
...
@@ -488,14 +487,12 @@ mem_alloc_func(
/*===========*/
/* out, own: free storage, NULL if did not
succeed */
ulint n /* in: desired number of bytes */
#ifdef UNIV_MEM_DEBUG
,char* file_name, /* in: file name where created */
ulint n, /* in: desired number of bytes */
char* file_name, /* in: file name where created */
ulint line /* in: line where created */
#endif
)
{
#ifndef UNIV_MEM_DEBUG
#ifdef notdefined
void* buf;
buf = mem_area_alloc(n, mem_comm_pool);
...
...
@@ -505,7 +502,7 @@ mem_alloc_func(
#endif
return(buf);
#else
#else
mem_heap_t* heap;
void* buf;
...
...
@@ -524,11 +521,11 @@ mem_alloc_func(
buf = mem_heap_alloc(heap, n);
ut_a
d
((byte*)heap == (byte*)buf - MEM_BLOCK_HEADER_SIZE
ut_a((byte*)heap == (byte*)buf - MEM_BLOCK_HEADER_SIZE
- MEM_FIELD_HEADER_SIZE);
return(buf);
#endif
#endif
}
/*******************************************************************
...
...
@@ -539,26 +536,22 @@ UNIV_INLINE
void
mem_free_func(
/*==========*/
void* ptr /* in, own: buffer to be freed */
#ifdef UNIV_MEM_DEBUG
,char* file_name, /* in: file name where created */
void* ptr, /* in, own: buffer to be freed */
char* file_name, /* in: file name where created */
ulint line /* in: line where created */
#endif
)
{
#ifndef UNIV_MEM_DEBUG
#ifdef notdefined
mem_area_free(ptr, mem_comm_pool);
#else
#else
mem_heap_t* heap;
heap = (mem_heap_t*)((byte*)ptr - MEM_BLOCK_HEADER_SIZE
- MEM_FIELD_HEADER_SIZE);
mem_heap_free_func(heap, file_name, line);
#endif
#endif
}
/*********************************************************************
...
...
@@ -567,7 +560,7 @@ UNIV_INLINE
ulint
mem_heap_get_size(
/*==============*/
mem_heap_t* heap) /* in: heap */
mem_heap_t*
heap) /* in: heap */
{
mem_block_t* block;
ulint size = 0;
...
...
@@ -597,9 +590,11 @@ mem_realloc(
/*========*/
/* out, own: free storage, NULL if did not succeed */
void* buf, /* in: pointer to an old buffer */
ulint n) /* in: desired number of bytes */
ulint n, /* in: desired number of bytes */
char* file_name,/* in: file name where called */
ulint line) /* in: line where called */
{
mem_free(buf);
return(mem_alloc
(n
));
return(mem_alloc
_func(n, file_name, line
));
}
innobase/include/que0que.h
View file @
0c87ad9f
...
...
@@ -327,6 +327,8 @@ mutex with the exceptions named below */
struct
que_thr_struct
{
que_common_t
common
;
/* type: QUE_NODE_THR */
ulint
magic_n
;
/* magic number to catch memory
corruption */
que_node_t
*
child
;
/* graph child node */
que_t
*
graph
;
/* graph where this node belongs */
ibool
is_active
;
/* TRUE if the thread has been set
...
...
@@ -357,6 +359,9 @@ struct que_thr_struct{
thus far */
};
#define QUE_THR_MAGIC_N 8476583
#define QUE_THR_MAGIC_FREED 123461526
/* Query graph fork node: its fields are protected by the kernel mutex */
struct
que_fork_struct
{
que_common_t
common
;
/* type: QUE_NODE_FORK */
...
...
innobase/include/row0mysql.h
View file @
0c87ad9f
...
...
@@ -323,11 +323,18 @@ struct mysql_row_templ_struct {
/* After fetching this many rows, we start caching them in fetch_cache */
#define MYSQL_FETCH_CACHE_THRESHOLD 4
#define ROW_PREBUILT_ALLOCATED 78540783
#define ROW_PREBUILT_FREED 26423527
/* A struct for (sometimes lazily) prebuilt structures in an Innobase table
handle used within MySQL; these are used to save CPU time. */
struct
row_prebuilt_struct
{
ulint
magic_n
;
/* this magic number is set to
ROW_PREBUILT_ALLOCATED when created
and to ROW_PREBUILT_FREED when the
struct has been freed; used in
debugging */
dict_table_t
*
table
;
/* Innobase table handle */
trx_t
*
trx
;
/* current transaction handle */
ibool
sql_stat_start
;
/* TRUE when we start processing of
...
...
innobase/include/srv0srv.h
View file @
0c87ad9f
...
...
@@ -17,6 +17,8 @@ Created 10/10/1995 Heikki Tuuri
#include "que0types.h"
#include "trx0types.h"
/* Buffer which can be used in printing fatal error messages */
extern
char
srv_fatal_errbuf
[];
/* When this event is set the lock timeout and InnoDB monitor
thread starts running */
...
...
@@ -261,15 +263,27 @@ This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
void
srv_conc_force_enter_innodb
(
void
);
/*=============================*/
srv_conc_force_enter_innodb
(
/*========================*/
trx_t
*
trx
);
/* in: transaction object associated with the
thread */
/*************************************************************************
This must be called when a thread exits InnoDB
. This must also be called
when a thread goes to wait for a lock
. */
This must be called when a thread exits InnoDB
in a lock wait or at the
end of an SQL statement
. */
void
srv_conc_exit_innodb
(
void
);
/*======================*/
srv_conc_force_exit_innodb
(
/*=======================*/
trx_t
*
trx
);
/* in: transaction object associated with the
thread */
/*************************************************************************
This must be called when a thread exits InnoDB. */
void
srv_conc_exit_innodb
(
/*=================*/
trx_t
*
trx
);
/* in: transaction object associated with the
thread */
/*******************************************************************
Puts a MySQL OS thread to wait for a lock to be released. */
...
...
innobase/include/trx0sys.h
View file @
0c87ad9f
...
...
@@ -218,6 +218,22 @@ trx_in_trx_list(
/*============*/
/* out: TRUE if is in */
trx_t
*
in_trx
);
/* in: trx */
/*********************************************************************
Updates the offset information about the end of the MySQL binlog entry
which corresponds to the transaction just being committed. */
void
trx_sys_update_mysql_binlog_offset
(
/*===============================*/
trx_t
*
trx
,
/* in: transaction being committed */
mtr_t
*
mtr
);
/* in: mtr */
/*********************************************************************
Prints to stderr the MySQL binlog offset info in the trx system header if
the magic number shows it valid. */
void
trx_sys_print_mysql_binlog_offset
(
void
);
/*===================================*/
/* The automatically created system rollback segment has this id */
#define TRX_SYS_SYSTEM_RSEG_ID 0
...
...
@@ -236,7 +252,7 @@ therefore 256 */
/* Transaction system header; protected by trx_sys->mutex */
/*-------------------------------------------------------------*/
#define TRX_SYS_TRX_ID_STORE 0
/*
T
he maximum trx id or trx number
#define TRX_SYS_TRX_ID_STORE 0
/*
t
he maximum trx id or trx number
modulo TRX_SYS_TRX_ID_UPDATE_MARGIN
written to a file page by any
transaction; the assignment of
...
...
@@ -252,6 +268,23 @@ therefore 256 */
segment specification slots */
/*-------------------------------------------------------------*/
#define TRX_SYS_MYSQL_LOG_NAME_LEN 32
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
/* The offset of the MySQL binlog offset info on the trx system header page */
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 300)
#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0
/* magic number which shows
if we have valid data in the
MySQL binlog info; the value
is ..._MAGIC_N if yes */
#define TRX_SYS_MYSQL_LOG_NAME 4
/* MySQL log file name */
#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH (4 + TRX_SYS_MYSQL_LOG_NAME_LEN)
/* high 4 bytes of the offset
within that file */
#define TRX_SYS_MYSQL_LOG_OFFSET_LOW (8 + TRX_SYS_MYSQL_LOG_NAME_LEN)
/* low 4 bytes of the offset
within that file */
/* The offset of the doublewrite buffer header on the trx system header page */
#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
/*-------------------------------------------------------------*/
...
...
innobase/include/trx0trx.h
View file @
0c87ad9f
...
...
@@ -290,10 +290,20 @@ struct trx_struct{
table */
dulint
table_id
;
/* table id if the preceding field is
TRUE */
/*------------------------------*/
void
*
mysql_thd
;
/* MySQL thread handle corresponding
to this trx, or NULL */
char
*
mysql_log_file_name
;
/* If MySQL binlog is used, this field
contains a pointer to the latest file
name; this is NULL if binlog is not
used */
ib_longlong
mysql_log_offset
;
/* If MySQL binlog is used, this field
contains the end offset of the binlog
entry */
os_thread_id_t
mysql_thread_id
;
/* id of the MySQL thread associated
with this transaction object */
/*------------------------------*/
ulint
n_mysql_tables_in_use
;
/* number of Innobase tables
used in the processing of the current
SQL statement in MySQL */
...
...
@@ -314,6 +324,18 @@ struct trx_struct{
calls from MySQL; this is intended
to reduce contention on the search
latch */
/*------------------------------*/
ibool
declared_to_be_inside_innodb
;
/* this is TRUE if we have declared
this transaction in
srv_conc_enter_innodb to be inside the
InnoDB engine */
ulint
n_tickets_to_enter_innodb
;
/* this can be > 0 only when
declared_to_... is TRUE; when we come
to srv_conc_innodb_enter, if the value
here is > 0, we decrement this by 1 */
/*------------------------------*/
lock_t
*
auto_inc_lock
;
/* possible auto-inc lock reserved by
the transaction; note that it is also
in the lock list trx_locks */
...
...
innobase/log/log0recv.c
View file @
0c87ad9f
...
...
@@ -51,6 +51,8 @@ recv_sys_t* recv_sys = NULL;
ibool
recv_recovery_on
=
FALSE
;
ibool
recv_recovery_from_backup_on
=
FALSE
;
ibool
recv_needed_recovery
=
FALSE
;
/* 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
the log record hash table becomes too full, and log records must be merged
...
...
@@ -1020,7 +1022,7 @@ recv_apply_hashed_log_recs(
if
(
!
has_printed
)
{
fprintf
(
stderr
,
"InnoDB: Starting an apply batch of log records to the database...
\n
"
"InnoDB: Progress in percents:"
);
"InnoDB: Progress in percents:
"
);
has_printed
=
TRUE
;
}
...
...
@@ -2032,12 +2034,16 @@ recv_recovery_from_checkpoint_start(
if
(
ut_dulint_cmp
(
checkpoint_lsn
,
max_flushed_lsn
)
!=
0
||
ut_dulint_cmp
(
checkpoint_lsn
,
min_flushed_lsn
)
!=
0
)
{
recv_needed_recovery
=
TRUE
;
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
"
InnoDB: Database was not shut down normally.
\n
"
"InnoDB: Starting recovery from log files...
\n
"
);
"
InnoDB: Database was not shut down normally.
\n
"
"InnoDB: Starting recovery from log files...
\n
"
);
fprintf
(
stderr
,
"InnoDB: Starting log scan based on checkpoint at
\n
"
"InnoDB: log sequence number %lu %lu
\n
"
,
"InnoDB: Starting log scan based on checkpoint at
\n
"
"InnoDB: log sequence number %lu %lu
\n
"
,
ut_dulint_get_high
(
checkpoint_lsn
),
ut_dulint_get_low
(
checkpoint_lsn
));
}
...
...
@@ -2199,6 +2205,10 @@ recv_recovery_from_checkpoint_finish(void)
"InnoDB: Log records applied to the database
\n
"
);
}
if
(
recv_needed_recovery
)
{
trx_sys_print_mysql_binlog_offset
();
}
/* Free the resources of the recovery system */
recv_recovery_on
=
FALSE
;
...
...
innobase/mem/mem0dbg.c
View file @
0c87ad9f
...
...
@@ -808,7 +808,7 @@ mem_validate_no_assert(void)
}
mutex_exit
(
&
mem_hash_mutex
);
return
(
error
);
#else
...
...
@@ -832,3 +832,95 @@ mem_validate(void)
return
(
TRUE
);
}
/****************************************************************
Tries to find neigboring memory allocation blocks and dumps to stderr
the neighborhood of a given pointer. */
void
mem_analyze_corruption
(
/*===================*/
byte
*
ptr
)
/* in: pointer to place of possible corruption */
{
byte
*
p
;
ulint
i
;
ulint
dist
;
ut_sprintf_buf
(
srv_fatal_errbuf
,
ptr
-
250
,
500
);
fprintf
(
stderr
,
"InnoDB: Apparent memory corruption: mem dump %s
\n
"
,
srv_fatal_errbuf
);
fprintf
(
stderr
,
"InnoDB: Scanning backward trying to find previous allocated mem blocks
\n
"
);
p
=
ptr
;
dist
=
0
;
for
(
i
=
0
;
i
<
10
;
i
++
)
{
for
(;;)
{
if
(((
ulint
)
p
)
%
4
==
0
)
{
if
(
*
((
ulint
*
)
p
)
==
MEM_BLOCK_MAGIC_N
)
{
fprintf
(
stderr
,
"Mem block at - %lu, file %s, line %lu
\n
"
,
dist
,
p
+
sizeof
(
ulint
),
*
(
ulint
*
)(
p
+
8
+
sizeof
(
ulint
)));
break
;
}
if
(
*
((
ulint
*
)
p
)
==
MEM_FREED_BLOCK_MAGIC_N
)
{
fprintf
(
stderr
,
"Freed mem block at - %lu, file %s, line %lu
\n
"
,
dist
,
p
+
sizeof
(
ulint
),
*
(
ulint
*
)(
p
+
8
+
sizeof
(
ulint
)));
break
;
}
}
p
--
;
dist
++
;
}
p
--
;
dist
++
;
}
fprintf
(
stderr
,
"InnoDB: Scanning forward trying to find next allocated mem blocks
\n
"
);
p
=
ptr
;
dist
=
0
;
for
(
i
=
0
;
i
<
10
;
i
++
)
{
for
(;;)
{
if
(((
ulint
)
p
)
%
4
==
0
)
{
if
(
*
((
ulint
*
)
p
)
==
MEM_BLOCK_MAGIC_N
)
{
fprintf
(
stderr
,
"Mem block at + %lu, file %s, line %lu
\n
"
,
dist
,
p
+
sizeof
(
ulint
),
*
(
ulint
*
)(
p
+
8
+
sizeof
(
ulint
)));
break
;
}
if
(
*
((
ulint
*
)
p
)
==
MEM_FREED_BLOCK_MAGIC_N
)
{
fprintf
(
stderr
,
"Freed mem block at + %lu, file %s, line %lu
\n
"
,
dist
,
p
+
sizeof
(
ulint
),
*
(
ulint
*
)(
p
+
8
+
sizeof
(
ulint
)));
break
;
}
}
p
++
;
dist
++
;
}
p
++
;
dist
++
;
}
}
innobase/mem/mem0mem.c
View file @
0c87ad9f
...
...
@@ -14,8 +14,9 @@ Created 6/9/1994 Heikki Tuuri
#include "mach0data.h"
#include "buf0buf.h"
#include "mem0dbg.c"
#include "btr0sea.h"
#include "srv0srv.h"
#include "mem0dbg.c"
/*
THE MEMORY MANAGEMENT
...
...
@@ -85,18 +86,12 @@ mem_alloc_func_noninline(
/*=====================*/
/* out, own: free storage, NULL if did not
succeed */
ulint
n
/* in: desired number of bytes */
#ifdef UNIV_MEM_DEBUG
,
char
*
file_name
,
/* in: file name where created */
ulint
n
,
/* in: desired number of bytes */
char
*
file_name
,
/* in: file name where created */
ulint
line
/* in: line where created */
#endif
)
{
return
(
mem_alloc_func
(
n
#ifdef UNIV_MEM_DEBUG
,
file_name
,
line
#endif
));
return
(
mem_alloc_func
(
n
,
file_name
,
line
));
}
/*******************************************************************
...
...
@@ -113,8 +108,10 @@ mem_heap_create_block(
if init_block is not NULL, its size in bytes */
void
*
init_block
,
/* in: init block in fast create, type must be
MEM_HEAP_DYNAMIC */
ulint
type
)
/* in: type of heap: MEM_HEAP_DYNAMIC, or
ulint
type
,
/* in: type of heap: MEM_HEAP_DYNAMIC, or
MEM_HEAP_BUFFER possibly ORed to MEM_HEAP_BTR_SEARCH */
char
*
file_name
,
/* in: file name where created */
ulint
line
)
/* in: line where created */
{
mem_block_t
*
block
;
ulint
len
;
...
...
@@ -164,7 +161,11 @@ mem_heap_create_block(
}
block
->
magic_n
=
MEM_BLOCK_MAGIC_N
;
ut_memcpy
(
&
(
block
->
file_name
),
file_name
+
ut_strlen
(
file_name
)
-
7
,
7
);
block
->
file_name
[
7
]
=
'\0'
;
block
->
line
=
line
;
mem_block_set_len
(
block
,
len
);
mem_block_set_type
(
block
,
type
);
mem_block_set_free
(
block
,
MEM_BLOCK_HEADER_SIZE
);
...
...
@@ -223,8 +224,8 @@ mem_heap_add_block(
new_size
=
n
;
}
new_block
=
mem_heap_create_block
(
heap
,
new_size
,
NULL
,
heap
->
type
);
new_block
=
mem_heap_create_block
(
heap
,
new_size
,
NULL
,
heap
->
type
,
heap
->
file_name
,
heap
->
line
);
if
(
new_block
==
NULL
)
{
return
(
NULL
);
...
...
@@ -255,7 +256,8 @@ mem_heap_block_free(
type
=
heap
->
type
;
len
=
block
->
len
;
init_block
=
block
->
init_block
;
block
->
magic_n
=
MEM_FREED_BLOCK_MAGIC_N
;
#ifdef UNIV_MEM_DEBUG
/* In the debug version we set the memory to a random combination
of hex 0xDE and 0xAD. */
...
...
innobase/pars/lexyy.c
View file @
0c87ad9f
...
...
@@ -7373,7 +7373,7 @@ void *ptr;
unsigned
int
size
;
#endif
{
return
(
void
*
)
mem_realloc
(
ptr
,
size
);
return
(
void
*
)
mem_realloc
(
ptr
,
size
,
__FILE__
,
__LINE__
);
}
#ifdef YY_USE_PROTOS
...
...
innobase/que/que0que.c
View file @
0c87ad9f
...
...
@@ -183,6 +183,8 @@ que_thr_create(
thr
->
common
.
type
=
QUE_NODE_THR
;
thr
->
common
.
parent
=
parent
;
thr
->
magic_n
=
QUE_THR_MAGIC_N
;
thr
->
graph
=
parent
->
graph
;
thr
->
state
=
QUE_THR_COMMAND_WAIT
;
...
...
@@ -485,7 +487,6 @@ que_graph_free_recursive(
tab_node_t
*
cre_tab
;
ind_node_t
*
cre_ind
;
if
(
node
==
NULL
)
{
return
;
...
...
@@ -509,6 +510,16 @@ que_graph_free_recursive(
thr
=
node
;
if
(
thr
->
magic_n
!=
QUE_THR_MAGIC_N
)
{
fprintf
(
stderr
,
"que_thr struct appears corrupt; magic n %lu
\n
"
,
thr
->
magic_n
);
mem_analyze_corruption
((
byte
*
)
thr
);
ut_a
(
0
);
}
thr
->
magic_n
=
QUE_THR_MAGIC_FREED
;
que_graph_free_recursive
(
thr
->
child
);
break
;
...
...
@@ -606,6 +617,10 @@ que_graph_free_recursive(
break
;
default:
fprintf
(
stderr
,
"que_node struct appears corrupt; type %lu
\n
"
,
que_node_get_type
(
node
));
mem_analyze_corruption
((
byte
*
)
node
);
ut_a
(
0
);
}
}
...
...
@@ -1068,20 +1083,29 @@ que_thr_stop_for_mysql(
mutex_exit
(
&
kernel_mutex
);
}
/**************************************************************************
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction if thr was
not active. */
void
que_thr_move_to_run_state_for_mysql
(
/*================================*/
que_thr_t
*
thr
,
/* in: an query thread */
trx_t
*
trx
)
/* in: transaction */
{
if
(
thr
->
magic_n
!=
QUE_THR_MAGIC_N
)
{
fprintf
(
stderr
,
"que_thr struct appears corrupt; magic n %lu
\n
"
,
thr
->
magic_n
);
mem_analyze_corruption
((
byte
*
)
thr
);
ut_a
(
0
);
}
if
(
!
thr
->
is_active
)
{
(
thr
->
graph
)
->
n_active_thrs
++
;
thr
->
graph
->
n_active_thrs
++
;
trx
->
n_active_thrs
++
;
...
...
@@ -1097,6 +1121,7 @@ que_thr_move_to_run_state_for_mysql(
/**************************************************************************
A patch for MySQL used to 'stop' a dummy query thread used in MySQL
select, when there is no error or lock wait. */
void
que_thr_stop_for_mysql_no_error
(
/*============================*/
...
...
@@ -1105,6 +1130,15 @@ que_thr_stop_for_mysql_no_error(
{
ut_ad
(
thr
->
state
==
QUE_THR_RUNNING
);
if
(
thr
->
magic_n
!=
QUE_THR_MAGIC_N
)
{
fprintf
(
stderr
,
"que_thr struct appears corrupt; magic n %lu
\n
"
,
thr
->
magic_n
);
mem_analyze_corruption
((
byte
*
)
thr
);
ut_a
(
0
);
}
thr
->
state
=
QUE_THR_COMPLETED
;
thr
->
is_active
=
FALSE
;
...
...
innobase/rem/rem0rec.c
View file @
0c87ad9f
...
...
@@ -105,6 +105,17 @@ rec_get_nth_field(
ut_ad
(
rec
&&
len
);
ut_ad
(
n
<
rec_get_n_fields
(
rec
));
if
(
n
>
1024
)
{
fprintf
(
stderr
,
"Error: trying to access field %lu in rec
\n
"
,
n
);
ut_a
(
0
);
}
if
(
rec
==
NULL
)
{
fprintf
(
stderr
,
"Error: rec is NULL pointer
\n
"
);
ut_a
(
0
);
}
if
(
rec_get_1byte_offs_flag
(
rec
))
{
os
=
rec_1_get_field_start_offs
(
rec
,
n
);
...
...
innobase/row/row0mysql.c
View file @
0c87ad9f
...
...
@@ -242,10 +242,14 @@ row_create_prebuilt(
ulint
ref_len
;
ulint
i
;
dict_table_increment_handle_count
(
table
);
heap
=
mem_heap_create
(
128
);
prebuilt
=
mem_heap_alloc
(
heap
,
sizeof
(
row_prebuilt_t
));
prebuilt
->
magic_n
=
ROW_PREBUILT_ALLOCATED
;
prebuilt
->
table
=
table
;
prebuilt
->
trx
=
NULL
;
...
...
@@ -294,7 +298,7 @@ row_create_prebuilt(
prebuilt
->
blob_heap
=
NULL
;
prebuilt
->
old_vers_heap
=
NULL
;
return
(
prebuilt
);
}
...
...
@@ -308,6 +312,19 @@ row_prebuilt_free(
{
ulint
i
;
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: table handle. Magic n %lu, table name %s
\n
"
,
prebuilt
->
magic_n
,
prebuilt
->
table
->
name
);
mem_analyze_corruption
((
byte
*
)
prebuilt
);
ut_a
(
0
);
}
prebuilt
->
magic_n
=
ROW_PREBUILT_FREED
;
btr_pcur_free_for_mysql
(
prebuilt
->
pcur
);
btr_pcur_free_for_mysql
(
prebuilt
->
clust_pcur
);
...
...
@@ -341,6 +358,8 @@ row_prebuilt_free(
}
}
dict_table_decrement_handle_count
(
prebuilt
->
table
);
mem_heap_free
(
prebuilt
->
heap
);
}
...
...
@@ -356,6 +375,28 @@ row_update_prebuilt_trx(
handle */
trx_t
*
trx
)
/* in: transaction handle */
{
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: table handle. Magic n %lu, table name %s
\n
"
,
prebuilt
->
magic_n
,
prebuilt
->
table
->
name
);
mem_analyze_corruption
((
byte
*
)
prebuilt
);
ut_a
(
0
);
}
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
"InnoDB: Error: trying to use a corrupt
\n
"
"InnoDB: table handle. Magic n %lu, table name %s
\n
"
,
prebuilt
->
magic_n
,
prebuilt
->
table
->
name
);
mem_analyze_corruption
((
byte
*
)
prebuilt
);
ut_a
(
0
);
}
prebuilt
->
trx
=
trx
;
if
(
prebuilt
->
ins_graph
)
{
...
...
@@ -563,6 +604,17 @@ row_insert_for_mysql(
ut_ad
(
trx
);
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: table handle. Magic n %lu, table name %s
\n
"
,
prebuilt
->
magic_n
,
prebuilt
->
table
->
name
);
mem_analyze_corruption
((
byte
*
)
prebuilt
);
ut_a
(
0
);
}
if
(
srv_created_new_raw
||
srv_force_recovery
)
{
fprintf
(
stderr
,
"InnoDB: A new raw disk partition was initialized or
\n
"
...
...
@@ -748,6 +800,17 @@ row_update_for_mysql(
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
UT_NOT_USED
(
mysql_rec
);
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: table handle. Magic n %lu, table name %s
\n
"
,
prebuilt
->
magic_n
,
prebuilt
->
table
->
name
);
mem_analyze_corruption
((
byte
*
)
prebuilt
);
ut_a
(
0
);
}
if
(
srv_created_new_raw
||
srv_force_recovery
)
{
fprintf
(
stderr
,
"InnoDB: A new raw disk partition was initialized or
\n
"
...
...
@@ -782,38 +845,6 @@ row_update_for_mysql(
generated for the table: MySQL does not know anything about
the row id used as the clustered index key */
#ifdef notdefined
/* We have to search for the correct cursor position */
ref_len
=
dict_index_get_n_unique
(
clust_index
);
heap
=
mem_heap_create
(
450
);
row_tuple
=
dtuple_create
(
heap
,
dict_table_get_n_cols
(
table
));
dict_table_copy_types
(
row_tuple
,
table
);
if
(
prebuilt
->
ins_upd_rec_buff
==
NULL
)
{
prebuilt
->
ins_upd_rec_buff
=
mem_heap_alloc
(
prebuilt
->
heap
,
prebuilt
->
mysql_row_len
);
}
row_mysql_convert_row_to_innobase
(
row_tuple
,
prebuilt
,
mysql_rec
);
search_tuple
=
dtuple_create
(
heap
,
ref_len
);
row_build_row_ref_from_row
(
search_tuple
,
table
,
row_tuple
);
mtr_start
(
&
mtr
);
btr_pcur_open_with_no_init
(
clust_index
,
search_tuple
,
PAGE_CUR_LE
,
BTR_SEARCH_LEAF
,
node
->
pcur
,
0
,
&
mtr
);
btr_pcur_store_position
(
node
->
pcur
,
&
mtr
);
mtr_commit
(
&
mtr
);
mem_heap_free
(
heap
);
#endif
savept
=
trx_savept_take
(
trx
);
thr
=
que_fork_get_first_thr
(
prebuilt
->
upd_graph
);
...
...
@@ -922,6 +953,50 @@ row_get_mysql_key_number_for_index(
return
(
i
);
}
/*************************************************************************
Recovers an orphaned tmp table inside InnoDB by renaming it. In the table
name #sql becomes rsql, and "_recover_innodb_tmp_table" is catenated to
the end of name. table->name should be of the form
"dbname/rsql..._recover_innodb_tmp_table". This renames a table whose
name is "#sql..." */
static
int
row_mysql_recover_tmp_table
(
/*========================*/
/* out: error code or DB_SUCCESS */
dict_table_t
*
table
,
/* in: table definition */
trx_t
*
trx
)
/* in: transaction handle */
{
char
*
ptr
;
char
old_name
[
1000
];
ut_memcpy
(
old_name
,
table
->
name
,
ut_strlen
(
table
->
name
)
+
1
);
ptr
=
old_name
;
for
(;;)
{
if
(
ptr
>=
old_name
+
ut_strlen
(
table
->
name
)
-
6
)
{
trx_commit_for_mysql
(
trx
);
return
(
DB_ERROR
);
}
if
(
0
==
ut_memcmp
(
ptr
,
"/rsql"
,
5
))
{
ptr
++
;
*
ptr
=
'#'
;
break
;
}
ptr
++
;
}
old_name
[
ut_strlen
(
table
->
name
)
-
ut_strlen
(
"_recover_innodb_tmp_table"
)]
=
'\0'
;
return
(
row_rename_table_for_mysql
(
old_name
,
table
->
name
,
trx
));
}
/*************************************************************************
Does a table creation operation for MySQL. If the name of the created
table ends to characters INNODB_MONITOR, then this also starts
...
...
@@ -976,6 +1051,24 @@ row_create_table_for_mysql(
namelen
=
ut_strlen
(
table
->
name
);
keywordlen
=
ut_strlen
(
"_recover_innodb_tmp_table"
);
if
(
namelen
>=
keywordlen
&&
0
==
ut_memcmp
(
table
->
name
+
namelen
-
keywordlen
,
"_recover_innodb_tmp_table"
,
keywordlen
))
{
/* MySQL prevents accessing of tables whose name begins
with #sql, that is temporary tables. If mysqld crashes in
the middle of an ALTER TABLE, we may get an orphaned
#sql-table in the tablespace. We have here a special
mechanism to recover such tables by renaming them to
rsql... */
return
(
row_mysql_recover_tmp_table
(
table
,
trx
));
}
namelen
=
ut_strlen
(
table
->
name
);
keywordlen
=
ut_strlen
(
"innodb_monitor"
);
if
(
namelen
>=
keywordlen
...
...
@@ -1118,6 +1211,8 @@ row_create_index_for_mysql(
ind_node_t
*
node
;
mem_heap_t
*
heap
;
que_thr_t
*
thr
;
ulint
namelen
;
ulint
keywordlen
;
ulint
err
;
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
...
...
@@ -1126,6 +1221,18 @@ row_create_index_for_mysql(
trx_start_if_not_started
(
trx
);
namelen
=
ut_strlen
(
index
->
table_name
);
keywordlen
=
ut_strlen
(
"_recover_innodb_tmp_table"
);
if
(
namelen
>=
keywordlen
&&
0
==
ut_memcmp
(
index
->
table_name
+
namelen
-
keywordlen
,
"_recover_innodb_tmp_table"
,
keywordlen
))
{
return
(
DB_SUCCESS
);
}
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
...
...
@@ -1189,6 +1296,8 @@ row_table_add_foreign_constraints(
char
*
name
)
/* in: table full name in the normalized form
database_name/table_name */
{
ulint
namelen
;
ulint
keywordlen
;
ulint
err
;
ut_a
(
sql_string
);
...
...
@@ -1197,6 +1306,18 @@ row_table_add_foreign_constraints(
trx_start_if_not_started
(
trx
);
namelen
=
ut_strlen
(
name
);
keywordlen
=
ut_strlen
(
"_recover_innodb_tmp_table"
);
if
(
namelen
>=
keywordlen
&&
0
==
ut_memcmp
(
name
+
namelen
-
keywordlen
,
"_recover_innodb_tmp_table"
,
keywordlen
))
{
return
(
DB_SUCCESS
);
}
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
...
...
@@ -1251,6 +1372,7 @@ row_drop_table_for_mysql(
ulint
len
;
ulint
namelen
;
ulint
keywordlen
;
ulint
rounds
=
0
;
char
buf
[
10000
];
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
...
...
@@ -1427,11 +1549,38 @@ row_drop_table_for_mysql(
/* Remove any locks there are on the table or its records */
lock_reset_all_on_table
(
table
);
loop:
if
(
table
->
n_mysql_handles_opened
>
0
)
{
rw_lock_s_unlock
(
&
(
purge_sys
->
purge_is_running
));
rw_lock_x_unlock
(
&
(
dict_foreign_key_check_lock
));
mutex_exit
(
&
(
dict_sys
->
mutex
));
if
(
rounds
>
60
)
{
fprintf
(
stderr
,
"InnoDB: waiting for queries to table %s to end before dropping it
\n
"
,
name
);
}
os_thread_sleep
(
1000000
);
mutex_enter
(
&
(
dict_sys
->
mutex
));
rw_lock_x_lock
(
&
(
dict_foreign_key_check_lock
));
rw_lock_s_lock
(
&
(
purge_sys
->
purge_is_running
));
/* TODO: check that MySQL prevents users from accessing the table
after this function row_drop_table_for_mysql has been called:
otherwise anyone with an open handle to the table could, for example,
come to read the table! Monty said that it prevents. */
rounds
++
;
if
(
rounds
>
120
)
{
fprintf
(
stderr
,
"InnoDB: Warning: queries to table %s have not ended but we continue anyway
\n
"
,
name
);
}
else
{
goto
loop
;
}
}
trx
->
dict_operation
=
TRUE
;
trx
->
table_id
=
table
->
id
;
...
...
innobase/row/row0sel.c
View file @
0c87ad9f
...
...
@@ -2492,6 +2492,17 @@ row_search_for_mysql(
ut_ad
(
sync_thread_levels_empty_gen
(
FALSE
));
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: table handle. Magic n %lu, table name %s
\n
"
,
prebuilt
->
magic_n
,
prebuilt
->
table
->
name
);
mem_analyze_corruption
((
byte
*
)
prebuilt
);
ut_a
(
0
);
}
/* printf("Match mode %lu\n search tuple ", match_mode);
dtuple_print(search_tuple);
...
...
innobase/srv/srv0srv.c
View file @
0c87ad9f
...
...
@@ -50,6 +50,9 @@ Created 10/8/1995 Heikki Tuuri
#include "dict0load.h"
#include "srv0start.h"
/* Buffer which can be used in printing fatal error messages */
char
srv_fatal_errbuf
[
5000
];
/* The following counter is incremented whenever there is some user activity
in the server */
ulint
srv_activity_count
=
0
;
...
...
@@ -132,6 +135,9 @@ lint srv_conc_n_threads = 0; /* number of OS threads currently
thread increments this, but a thread
waiting for a lock decrements this
temporarily */
ulint
srv_conc_n_waiting_threads
=
0
;
/* number of OS threads waiting in the
FIFO for a permission to enter InnoDB
*/
typedef
struct
srv_conc_slot_struct
srv_conc_slot_t
;
struct
srv_conc_slot_struct
{
...
...
@@ -152,6 +158,11 @@ UT_LIST_BASE_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue of threads
waiting to get in */
srv_conc_slot_t
srv_conc_slots
[
OS_THREAD_MAX_N
];
/* array of wait
slots */
/* Number of times a thread is allowed to enter InnoDB within the same
SQL query after it has once got the ticket at srv_conc_enter_innodb */
#define SRV_FREE_TICKETS_TO_ENTER 500
/*-----------------------*/
/* If the following is set TRUE then we do not run purge and insert buffer
merge to completion before shutdown */
...
...
@@ -1627,6 +1638,8 @@ srv_general_init(void)
thr_local_init
();
}
/*======================= InnoDB Server FIFO queue =======================*/
/*************************************************************************
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
...
...
@@ -1640,11 +1653,29 @@ srv_conc_enter_innodb(
srv_conc_slot_t
*
slot
;
ulint
i
;
if
(
srv_thread_concurrency
>=
500
)
{
/* Disable the concurrency check */
return
;
}
/* If trx has 'free tickets' to enter the engine left, then use one
such ticket */
if
(
trx
->
n_tickets_to_enter_innodb
>
0
)
{
trx
->
n_tickets_to_enter_innodb
--
;
return
;
}
os_fast_mutex_lock
(
&
srv_conc_mutex
);
if
(
srv_conc_n_threads
<
(
lint
)
srv_thread_concurrency
)
{
srv_conc_n_threads
++
;
srv_conc_n_threads
++
;
trx
->
declared_to_be_inside_innodb
=
TRUE
;
trx
->
n_tickets_to_enter_innodb
=
SRV_FREE_TICKETS_TO_ENTER
;
os_fast_mutex_unlock
(
&
srv_conc_mutex
);
return
;
...
...
@@ -1665,6 +1696,8 @@ srv_conc_enter_innodb(
thread enter */
srv_conc_n_threads
++
;
trx
->
declared_to_be_inside_innodb
=
TRUE
;
trx
->
n_tickets_to_enter_innodb
=
0
;
os_fast_mutex_unlock
(
&
srv_conc_mutex
);
...
...
@@ -1684,6 +1717,8 @@ srv_conc_enter_innodb(
os_event_reset
(
slot
->
event
);
srv_conc_n_waiting_threads
++
;
os_fast_mutex_unlock
(
&
srv_conc_mutex
);
/* Go to wait for the event; when a thread leaves InnoDB it will
...
...
@@ -1693,6 +1728,8 @@ srv_conc_enter_innodb(
os_fast_mutex_lock
(
&
srv_conc_mutex
);
srv_conc_n_waiting_threads
--
;
/* NOTE that the thread which released this thread already
incremented the thread counter on behalf of this thread */
...
...
@@ -1700,6 +1737,9 @@ srv_conc_enter_innodb(
UT_LIST_REMOVE
(
srv_conc_queue
,
srv_conc_queue
,
slot
);
trx
->
declared_to_be_inside_innodb
=
TRUE
;
trx
->
n_tickets_to_enter_innodb
=
SRV_FREE_TICKETS_TO_ENTER
;
os_fast_mutex_unlock
(
&
srv_conc_mutex
);
}
...
...
@@ -1708,29 +1748,52 @@ This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
void
srv_conc_force_enter_innodb
(
void
)
/*=============================*/
srv_conc_force_enter_innodb
(
/*========================*/
trx_t
*
trx
)
/* in: transaction object associated with the
thread */
{
if
(
srv_thread_concurrency
>=
500
)
{
return
;
}
os_fast_mutex_lock
(
&
srv_conc_mutex
);
srv_conc_n_threads
++
;
trx
->
declared_to_be_inside_innodb
=
TRUE
;
trx
->
n_tickets_to_enter_innodb
=
0
;
os_fast_mutex_unlock
(
&
srv_conc_mutex
);
}
/*************************************************************************
This must be called when a thread exits InnoDB
. This must also be called
when a thread goes to wait for a lock
. */
This must be called when a thread exits InnoDB
in a lock wait or at the
end of an SQL statement
. */
void
srv_conc_exit_innodb
(
void
)
/*======================*/
srv_conc_force_exit_innodb
(
/*=======================*/
trx_t
*
trx
)
/* in: transaction object associated with the
thread */
{
srv_conc_slot_t
*
slot
=
NULL
;
if
(
srv_thread_concurrency
>=
500
)
{
return
;
}
if
(
trx
->
declared_to_be_inside_innodb
==
FALSE
)
{
return
;
}
os_fast_mutex_lock
(
&
srv_conc_mutex
);
srv_conc_n_threads
--
;
trx
->
declared_to_be_inside_innodb
=
FALSE
;
trx
->
n_tickets_to_enter_innodb
=
0
;
if
(
srv_conc_n_threads
<
(
lint
)
srv_thread_concurrency
)
{
/* Look for a slot where a thread is waiting and no other
...
...
@@ -1759,6 +1822,38 @@ srv_conc_exit_innodb(void)
}
}
/*************************************************************************
This must be called when a thread exits InnoDB. */
void
srv_conc_exit_innodb
(
/*=================*/
trx_t
*
trx
)
/* in: transaction object associated with the
thread */
{
srv_conc_slot_t
*
slot
=
NULL
;
if
(
srv_thread_concurrency
>=
500
)
{
return
;
}
if
(
trx
->
n_tickets_to_enter_innodb
>
0
)
{
/* We will pretend the thread is still inside InnoDB though it
now leaves the InnoDB engine. In this way we save
a lot of semaphore operations. srv_conc_force_exit_innodb is
used to declare the thread definitely outside InnoDB. It
should be called when there is a lock wait or an SQL statement
ends. */
return
;
}
srv_conc_force_exit_innodb
(
trx
);
}
/*========================================================================*/
/*************************************************************************
Normalizes init parameter values to use units we use inside InnoDB. */
static
...
...
@@ -1905,7 +2000,7 @@ srv_suspend_mysql_thread(
other thread holding a lock which this thread waits for must be
allowed to enter, sooner or later */
srv_conc_
exit_innodb
(
);
srv_conc_
force_exit_innodb
(
thr_get_trx
(
thr
)
);
/* Wait for the release */
...
...
@@ -1913,7 +2008,7 @@ srv_suspend_mysql_thread(
/* Return back inside InnoDB */
srv_conc_force_enter_innodb
();
srv_conc_force_enter_innodb
(
thr_get_trx
(
thr
)
);
mutex_enter
(
&
kernel_mutex
);
...
...
@@ -2052,8 +2147,9 @@ srv_lock_timeout_and_monitor_thread(
"ROW OPERATIONS
\n
"
"--------------
\n
"
);
printf
(
"%ld queries inside InnoDB; main thread: %s
\n
"
,
srv_conc_n_threads
,
srv_main_thread_op_info
);
"%ld queries inside InnoDB, %ld queries in queue; main thread: %s
\n
"
,
srv_conc_n_threads
,
srv_conc_n_waiting_threads
,
srv_main_thread_op_info
);
printf
(
"Number of rows inserted %lu, updated %lu, deleted %lu, read %lu
\n
"
,
srv_n_rows_inserted
,
...
...
@@ -2315,6 +2411,12 @@ srv_master_thread(
srv_main_thread_op_info
=
"sleeping"
;
os_thread_sleep
(
1000000
);
/* ALTER TABLE in MySQL requires on Unix that the table handler
can drop tables lazily after there no longer are SELECT
queries to them. */
/* row_drop_tables_for_mysql_in_background(); */
if
(
srv_force_recovery
>=
SRV_FORCE_NO_BACKGROUND
)
{
goto
suspend_thread
;
...
...
innobase/sync/sync0arr.c
View file @
0c87ad9f
...
...
@@ -913,6 +913,17 @@ sync_array_print_long_waits(void)
noticed
=
TRUE
;
}
if
(
cell
->
wait_object
!=
NULL
&&
difftime
(
time
(
NULL
),
cell
->
reservation_time
)
>
420
)
{
fprintf
(
stderr
,
"InnoDB: Error: semaphore wait has lasted > 420 seconds
\n
"
"InnoDB: We intentionally crash the server, because it appears to be hung.
\n
"
);
ut_a
(
0
);
}
}
if
(
noticed
)
{
...
...
innobase/trx/trx0sys.c
View file @
0c87ad9f
...
...
@@ -389,6 +389,115 @@ trx_sys_flush_max_trx_id(void)
mtr_commit
(
&
mtr
);
}
/*********************************************************************
Updates the offset information about the end of the MySQL binlog entry
which corresponds to the transaction just being committed. */
void
trx_sys_update_mysql_binlog_offset
(
/*===============================*/
trx_t
*
trx
,
/* in: transaction being committed */
mtr_t
*
mtr
)
/* in: mtr */
{
trx_sysf_t
*
sys_header
;
char
namebuf
[
TRX_SYS_MYSQL_LOG_NAME_LEN
];
ut_ad
(
mutex_own
(
&
kernel_mutex
));
ut_ad
(
trx
->
mysql_log_file_name
);
memset
(
namebuf
,
' '
,
TRX_SYS_MYSQL_LOG_NAME_LEN
-
1
);
namebuf
[
TRX_SYS_MYSQL_LOG_NAME_LEN
-
1
]
=
'\0'
;
/* Copy the whole MySQL log file name to the buffer, or only the
last characters, if it does not fit */
if
(
ut_strlen
(
trx
->
mysql_log_file_name
)
>
TRX_SYS_MYSQL_LOG_NAME_LEN
-
1
)
{
ut_memcpy
(
namebuf
,
trx
->
mysql_log_file_name
+
ut_strlen
(
trx
->
mysql_log_file_name
)
-
(
TRX_SYS_MYSQL_LOG_NAME_LEN
-
1
),
TRX_SYS_MYSQL_LOG_NAME_LEN
-
1
);
}
else
{
ut_memcpy
(
namebuf
,
trx
->
mysql_log_file_name
,
1
+
ut_strlen
(
trx
->
mysql_log_file_name
));
}
namebuf
[
TRX_SYS_MYSQL_LOG_NAME_LEN
-
1
]
=
'\0'
;
sys_header
=
trx_sysf_get
(
mtr
);
if
(
mach_read_from_4
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
)
!=
TRX_SYS_MYSQL_LOG_MAGIC_N
)
{
mlog_write_ulint
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
,
TRX_SYS_MYSQL_LOG_MAGIC_N
,
MLOG_4BYTES
,
mtr
);
}
if
(
0
!=
ut_memcmp
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_NAME
,
namebuf
,
TRX_SYS_MYSQL_LOG_NAME_LEN
))
{
mlog_write_string
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_NAME
,
namebuf
,
TRX_SYS_MYSQL_LOG_NAME_LEN
,
mtr
);
}
if
(
mach_read_from_4
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_OFFSET_HIGH
)
>
0
||
(
trx
->
mysql_log_offset
>>
32
)
>
0
)
{
mlog_write_ulint
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_OFFSET_HIGH
,
(
ulint
)(
trx
->
mysql_log_offset
>>
32
),
MLOG_4BYTES
,
mtr
);
}
mlog_write_ulint
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_OFFSET_LOW
,
(
ulint
)(
trx
->
mysql_log_offset
&
0xFFFFFFFF
),
MLOG_4BYTES
,
mtr
);
trx
->
mysql_log_file_name
=
NULL
;
}
/*********************************************************************
Prints to stderr the MySQL binlog offset info in the trx system header if
the magic number shows it valid. */
void
trx_sys_print_mysql_binlog_offset
(
void
)
/*===================================*/
{
trx_sysf_t
*
sys_header
;
mtr_t
mtr
;
mtr_start
(
&
mtr
);
sys_header
=
trx_sysf_get
(
&
mtr
);
if
(
mach_read_from_4
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
)
!=
TRX_SYS_MYSQL_LOG_MAGIC_N
)
{
mtr_commit
(
&
mtr
);
return
;
}
fprintf
(
stderr
,
"InnoDB: Last MySQL binlog file offset %lu %lu, file name %s
\n
"
,
mach_read_from_4
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_OFFSET_HIGH
),
mach_read_from_4
(
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_OFFSET_LOW
),
sys_header
+
TRX_SYS_MYSQL_LOG_INFO
+
TRX_SYS_MYSQL_LOG_NAME
);
mtr_commit
(
&
mtr
);
}
/********************************************************************
Looks for a free slot for a rollback segment in the trx system file copy. */
...
...
@@ -519,7 +628,7 @@ trx_sys_init_at_db_start(void)
"InnoDB: %lu uncommitted transaction(s) which must be rolled back
\n
"
,
UT_LIST_GET_LEN
(
trx_sys
->
trx_list
));
fprintf
(
stderr
,
"Trx id counter is %lu %lu
\n
"
,
fprintf
(
stderr
,
"
InnoDB:
Trx id counter is %lu %lu
\n
"
,
ut_dulint_get_high
(
trx_sys
->
max_trx_id
),
ut_dulint_get_low
(
trx_sys
->
max_trx_id
));
}
...
...
innobase/trx/trx0trx.c
View file @
0c87ad9f
...
...
@@ -76,6 +76,9 @@ trx_create(
trx
->
n_mysql_tables_in_use
=
0
;
trx
->
mysql_n_tables_locked
=
0
;
trx
->
mysql_log_file_name
=
NULL
;
trx
->
mysql_log_offset
=
0
;
trx
->
ignore_duplicates_in_insert
=
FALSE
;
mutex_create
(
&
(
trx
->
undo_mutex
));
...
...
@@ -111,6 +114,9 @@ trx_create(
trx
->
has_search_latch
=
FALSE
;
trx
->
search_latch_timeout
=
BTR_SEA_TIMEOUT
;
trx
->
declared_to_be_inside_innodb
=
FALSE
;
trx
->
n_tickets_to_enter_innodb
=
0
;
trx
->
auto_inc_lock
=
NULL
;
trx
->
read_view_heap
=
mem_heap_create
(
256
);
...
...
@@ -568,6 +574,13 @@ trx_commit_off_kernel(
mutex_exit
(
&
(
rseg
->
mutex
));
/* Update the latest MySQL binlog name and offset info
in trx sys header if MySQL binlogging is on */
if
(
trx
->
mysql_log_file_name
)
{
trx_sys_update_mysql_binlog_offset
(
trx
,
&
mtr
);
}
/* If we did not take the shortcut, the following call
commits the mini-transaction, making the whole transaction
committed in the file-based world at this log sequence number;
...
...
innobase/trx/trx0undo.c
View file @
0c87ad9f
...
...
@@ -1310,9 +1310,10 @@ trx_undo_mem_init_for_reuse(
{
ut_ad
(
mutex_own
(
&
((
undo
->
rseg
)
->
mutex
)));
if
(
undo
->
id
>=
TRX_RSEG_N_SLOTS
)
{
fprintf
(
stderr
,
"InnoDB: Error: undo->id is %lu
\n
"
,
undo
->
id
);
if
(
undo
->
id
>=
TRX_RSEG_N_SLOTS
)
{
fprintf
(
stderr
,
"InnoDB: Error: undo->id is %lu
\n
"
,
undo
->
id
);
mem_analyze_corruption
((
byte
*
)
undo
);
ut_a
(
0
);
}
...
...
@@ -1399,7 +1400,7 @@ trx_undo_create(
/************************************************************************
Reuses a cached undo log. */
UNIV_INLINE
static
trx_undo_t
*
trx_undo_reuse_cached
(
/*==================*/
...
...
@@ -1442,6 +1443,12 @@ trx_undo_reuse_cached(
ut_ad
(
undo
->
size
==
1
);
ut_ad
(
undo
->
hdr_page_no
==
undo
->
top_page_no
);
if
(
undo
->
id
>=
TRX_RSEG_N_SLOTS
)
{
fprintf
(
stderr
,
"InnoDB: Error: undo->id is %lu
\n
"
,
undo
->
id
);
mem_analyze_corruption
((
byte
*
)
undo
);
ut_a
(
0
);
}
undo_page
=
trx_undo_page_get
(
undo
->
space
,
undo
->
hdr_page_no
,
mtr
);
if
(
type
==
TRX_UNDO_INSERT
)
{
...
...
@@ -1572,8 +1579,8 @@ trx_undo_set_state_at_finish(
ut_ad
(
trx
&&
undo
&&
mtr
);
if
(
undo
->
id
>=
TRX_RSEG_N_SLOTS
)
{
fprintf
(
stderr
,
"InnoDB: Error: undo->id is %lu
\n
"
,
undo
->
id
);
fprintf
(
stderr
,
"InnoDB: Error: undo->id is %lu
\n
"
,
undo
->
id
);
mem_analyze_corruption
((
byte
*
)
undo
);
ut_a
(
0
);
}
...
...
sql/ha_innobase.cc
View file @
0c87ad9f
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment