mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Many files:
Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log sql/ha_innobase.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log sql/ha_innobase.cc: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/buf/buf0buf.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/dict/dict0dict.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/fil/fil0fil.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/fsp/fsp0fsp.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/ha/ha0ha.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/dict0dict.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/dict0mem.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/dyn0dyn.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/fsp0fsp.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/log0log.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/log0recv.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/trx0sys.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/trx0trx.h: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/include/log0log.ic: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/lock/lock0lock.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/log/log0log.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/log/log0recv.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/mem/mem0dbg.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/row/row0mysql.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/srv/srv0srv.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/srv/srv0start.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/trx/trx0sys.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log innobase/trx/trx0trx.c: Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log
This commit is contained in:
@ -1707,10 +1707,11 @@ buf_print(void)
|
|||||||
|
|
||||||
mutex_enter(&(buf_pool->mutex));
|
mutex_enter(&(buf_pool->mutex));
|
||||||
|
|
||||||
printf("LRU len %lu \n", UT_LIST_GET_LEN(buf_pool->LRU));
|
|
||||||
printf("free len %lu \n", UT_LIST_GET_LEN(buf_pool->free));
|
|
||||||
printf("flush len %lu \n", UT_LIST_GET_LEN(buf_pool->flush_list));
|
|
||||||
printf("buf_pool size %lu \n", size);
|
printf("buf_pool size %lu \n", size);
|
||||||
|
printf("database pages %lu \n", UT_LIST_GET_LEN(buf_pool->LRU));
|
||||||
|
printf("free pages %lu \n", UT_LIST_GET_LEN(buf_pool->free));
|
||||||
|
printf("modified database pages %lu \n",
|
||||||
|
UT_LIST_GET_LEN(buf_pool->flush_list));
|
||||||
|
|
||||||
printf("n pending reads %lu \n", buf_pool->n_pend_reads);
|
printf("n pending reads %lu \n", buf_pool->n_pend_reads);
|
||||||
|
|
||||||
@ -1819,13 +1820,20 @@ buf_print_io(
|
|||||||
mutex_enter(&(buf_pool->mutex));
|
mutex_enter(&(buf_pool->mutex));
|
||||||
|
|
||||||
buf += sprintf(buf,
|
buf += sprintf(buf,
|
||||||
"Free list length %lu \n", UT_LIST_GET_LEN(buf_pool->free));
|
"Buffer pool size %lu\n", size);
|
||||||
buf += sprintf(buf,
|
buf += sprintf(buf,
|
||||||
"LRU list length %lu \n", UT_LIST_GET_LEN(buf_pool->LRU));
|
"Free buffers %lu\n", UT_LIST_GET_LEN(buf_pool->free));
|
||||||
buf += sprintf(buf,
|
buf += sprintf(buf,
|
||||||
"Flush list length %lu \n",
|
"Database pages %lu\n", UT_LIST_GET_LEN(buf_pool->LRU));
|
||||||
|
/*
|
||||||
|
buf += sprintf(buf,
|
||||||
|
"Lock heap buffers %lu\n", buf_pool->n_lock_heap_pages);
|
||||||
|
buf += sprintf(buf,
|
||||||
|
"Hash index buffers %lu\n", buf_pool->n_adaptive_hash_pages);
|
||||||
|
*/
|
||||||
|
buf += sprintf(buf,
|
||||||
|
"Modified db pages %lu\n",
|
||||||
UT_LIST_GET_LEN(buf_pool->flush_list));
|
UT_LIST_GET_LEN(buf_pool->flush_list));
|
||||||
buf += sprintf(buf, "Buffer pool size %lu\n", size);
|
|
||||||
|
|
||||||
buf += sprintf(buf, "Pending reads %lu \n", buf_pool->n_pend_reads);
|
buf += sprintf(buf, "Pending reads %lu \n", buf_pool->n_pend_reads);
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ dict_table_get_index_noninline(
|
|||||||
{
|
{
|
||||||
return(dict_table_get_index(table, name));
|
return(dict_table_get_index(table, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Initializes the autoinc counter. It is not an error to initialize an already
|
Initializes the autoinc counter. It is not an error to initialize an already
|
||||||
initialized counter. */
|
initialized counter. */
|
||||||
@ -270,7 +270,7 @@ void
|
|||||||
dict_table_autoinc_initialize(
|
dict_table_autoinc_initialize(
|
||||||
/*==========================*/
|
/*==========================*/
|
||||||
dict_table_t* table, /* in: table */
|
dict_table_t* table, /* in: table */
|
||||||
ib_longlong value) /* in: value which was assigned to a row */
|
ib_longlong value) /* in: next value to assign to a row */
|
||||||
{
|
{
|
||||||
mutex_enter(&(table->autoinc_mutex));
|
mutex_enter(&(table->autoinc_mutex));
|
||||||
|
|
||||||
@ -281,8 +281,8 @@ dict_table_autoinc_initialize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Gets the next autoinc value, 0 if not yet initialized. If initialized,
|
Gets the next autoinc value (== autoinc counter value), 0 if not yet
|
||||||
increments the counter by 1. */
|
initialized. If initialized, increments the counter by 1. */
|
||||||
|
|
||||||
ib_longlong
|
ib_longlong
|
||||||
dict_table_autoinc_get(
|
dict_table_autoinc_get(
|
||||||
@ -298,8 +298,8 @@ dict_table_autoinc_get(
|
|||||||
|
|
||||||
value = 0;
|
value = 0;
|
||||||
} else {
|
} else {
|
||||||
table->autoinc = table->autoinc + 1;
|
|
||||||
value = table->autoinc;
|
value = table->autoinc;
|
||||||
|
table->autoinc = table->autoinc + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&(table->autoinc_mutex));
|
mutex_exit(&(table->autoinc_mutex));
|
||||||
@ -334,20 +334,43 @@ dict_table_autoinc_read(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Updates the autoinc counter if the value supplied is bigger than the
|
Peeks the autoinc counter value, 0 if not yet initialized. Does not
|
||||||
|
increment the counter. The read not protected by any mutex! */
|
||||||
|
|
||||||
|
ib_longlong
|
||||||
|
dict_table_autoinc_peek(
|
||||||
|
/*====================*/
|
||||||
|
/* out: value of the counter */
|
||||||
|
dict_table_t* table) /* in: table */
|
||||||
|
{
|
||||||
|
ib_longlong value;
|
||||||
|
|
||||||
|
if (!table->autoinc_inited) {
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
} else {
|
||||||
|
value = table->autoinc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
Updates the autoinc counter if the value supplied is equal or bigger than the
|
||||||
current value. If not inited, does nothing. */
|
current value. If not inited, does nothing. */
|
||||||
|
|
||||||
void
|
void
|
||||||
dict_table_autoinc_update(
|
dict_table_autoinc_update(
|
||||||
/*======================*/
|
/*======================*/
|
||||||
|
|
||||||
dict_table_t* table, /* in: table */
|
dict_table_t* table, /* in: table */
|
||||||
ib_longlong value) /* in: value which was assigned to a row */
|
ib_longlong value) /* in: value which was assigned to a row */
|
||||||
{
|
{
|
||||||
mutex_enter(&(table->autoinc_mutex));
|
mutex_enter(&(table->autoinc_mutex));
|
||||||
|
|
||||||
if (table->autoinc_inited) {
|
if (table->autoinc_inited) {
|
||||||
if (value > table->autoinc) {
|
if (value >= table->autoinc) {
|
||||||
table->autoinc = value;
|
table->autoinc = value + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,7 +578,7 @@ fil_read_flushed_lsn_and_arch_log_no(
|
|||||||
ulint arch_log_no;
|
ulint arch_log_no;
|
||||||
|
|
||||||
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
|
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
|
||||||
/* Align the memory for a possibel read from a raw device */
|
/* Align the memory for a possible read from a raw device */
|
||||||
buf = ut_align(buf2, UNIV_PAGE_SIZE);
|
buf = ut_align(buf2, UNIV_PAGE_SIZE);
|
||||||
|
|
||||||
os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
|
os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
|
||||||
|
@ -933,6 +933,36 @@ fsp_header_get_free_limit(
|
|||||||
return(limit);
|
return(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
Gets the size of the tablespace from the tablespace header. If we do not
|
||||||
|
have an auto-extending data file, this should be equal to the size of the
|
||||||
|
data files. If there is an auto-extending data file, this can be smaller. */
|
||||||
|
|
||||||
|
ulint
|
||||||
|
fsp_header_get_tablespace_size(
|
||||||
|
/*===========================*/
|
||||||
|
/* out: size in pages */
|
||||||
|
ulint space) /* in: space id */
|
||||||
|
{
|
||||||
|
fsp_header_t* header;
|
||||||
|
ulint size;
|
||||||
|
mtr_t mtr;
|
||||||
|
|
||||||
|
ut_a(space == 0); /* We have only one log_fsp_current_... variable */
|
||||||
|
|
||||||
|
mtr_start(&mtr);
|
||||||
|
|
||||||
|
mtr_x_lock(fil_space_get_latch(space), &mtr);
|
||||||
|
|
||||||
|
header = fsp_get_space_header(space, &mtr);
|
||||||
|
|
||||||
|
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr);
|
||||||
|
|
||||||
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
|
return(size);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Tries to extend the last data file file if it is defined as auto-extending. */
|
Tries to extend the last data file file if it is defined as auto-extending. */
|
||||||
static
|
static
|
||||||
|
@ -335,6 +335,11 @@ ha_print_info(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += sprintf(buf, "Hash table size %lu, used cells %lu\n",
|
buf += sprintf(buf,
|
||||||
hash_get_n_cells(table), cells);
|
"Hash table size %lu, used cells %lu", hash_get_n_cells(table), cells);
|
||||||
|
|
||||||
|
if (table->heaps == NULL && table->heap != NULL) {
|
||||||
|
buf += sprintf(buf,
|
||||||
|
", node heap has %lu buffer(s)\n", UT_LIST_GET_LEN(table->heap->base));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,17 +96,17 @@ dict_col_get_clust_pos(
|
|||||||
/*===================*/
|
/*===================*/
|
||||||
dict_col_t* col);
|
dict_col_t* col);
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Initializes the autoinc counter. It is not an error to initialize already
|
Initializes the autoinc counter. It is not an error to initialize an already
|
||||||
initialized counter. */
|
initialized counter. */
|
||||||
|
|
||||||
void
|
void
|
||||||
dict_table_autoinc_initialize(
|
dict_table_autoinc_initialize(
|
||||||
/*==========================*/
|
/*==========================*/
|
||||||
dict_table_t* table, /* in: table */
|
dict_table_t* table, /* in: table */
|
||||||
ib_longlong value); /* in: value which was assigned to a row */
|
ib_longlong value); /* in: next value to assign to a row */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Gets the next autoinc value, 0 if not yet initialized. If initialized,
|
Gets the next autoinc value (== autoinc counter value), 0 if not yet
|
||||||
increments the counter by 1. */
|
initialized. If initialized, increments the counter by 1. */
|
||||||
|
|
||||||
ib_longlong
|
ib_longlong
|
||||||
dict_table_autoinc_get(
|
dict_table_autoinc_get(
|
||||||
@ -123,12 +123,22 @@ dict_table_autoinc_read(
|
|||||||
/* out: value of the counter */
|
/* out: value of the counter */
|
||||||
dict_table_t* table); /* in: table */
|
dict_table_t* table); /* in: table */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Updates the autoinc counter if the value supplied is bigger than the
|
Peeks the autoinc counter value, 0 if not yet initialized. Does not
|
||||||
|
increment the counter. The read not protected by any mutex! */
|
||||||
|
|
||||||
|
ib_longlong
|
||||||
|
dict_table_autoinc_peek(
|
||||||
|
/*====================*/
|
||||||
|
/* out: value of the counter */
|
||||||
|
dict_table_t* table); /* in: table */
|
||||||
|
/************************************************************************
|
||||||
|
Updates the autoinc counter if the value supplied is equal or bigger than the
|
||||||
current value. If not inited, does nothing. */
|
current value. If not inited, does nothing. */
|
||||||
|
|
||||||
void
|
void
|
||||||
dict_table_autoinc_update(
|
dict_table_autoinc_update(
|
||||||
/*======================*/
|
/*======================*/
|
||||||
|
|
||||||
dict_table_t* table, /* in: table */
|
dict_table_t* table, /* in: table */
|
||||||
ib_longlong value); /* in: value which was assigned to a row */
|
ib_longlong value); /* in: value which was assigned to a row */
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -388,8 +388,8 @@ struct dict_table_struct{
|
|||||||
/* TRUE if the autoinc counter has been
|
/* TRUE if the autoinc counter has been
|
||||||
inited; MySQL gets the init value by executing
|
inited; MySQL gets the init value by executing
|
||||||
SELECT MAX(auto inc column) */
|
SELECT MAX(auto inc column) */
|
||||||
ib_longlong autoinc;/* autoinc counter value already given to
|
ib_longlong autoinc;/* autoinc counter value to give to the
|
||||||
a row */
|
next inserted row */
|
||||||
ulint magic_n;/* magic number */
|
ulint magic_n;/* magic number */
|
||||||
};
|
};
|
||||||
#define DICT_TABLE_MAGIC_N 76333786
|
#define DICT_TABLE_MAGIC_N 76333786
|
||||||
|
@ -17,7 +17,9 @@ typedef struct dyn_block_struct dyn_block_t;
|
|||||||
typedef dyn_block_t dyn_array_t;
|
typedef dyn_block_t dyn_array_t;
|
||||||
|
|
||||||
|
|
||||||
/* This must be > MLOG_BUF_MARGIN + 30 */
|
/* This is the initial 'payload' size of a dynamic array;
|
||||||
|
this must be > MLOG_BUF_MARGIN + 30! */
|
||||||
|
|
||||||
#define DYN_ARRAY_DATA_SIZE 512
|
#define DYN_ARRAY_DATA_SIZE 512
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -57,6 +57,16 @@ fsp_header_get_free_limit(
|
|||||||
/* out: free limit in megabytes */
|
/* out: free limit in megabytes */
|
||||||
ulint space); /* in: space id */
|
ulint space); /* in: space id */
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
Gets the size of the tablespace from the tablespace header. If we do not
|
||||||
|
have an auto-extending data file, this should be equal to the size of the
|
||||||
|
data files. If there is an auto-extending data file, this can be smaller. */
|
||||||
|
|
||||||
|
ulint
|
||||||
|
fsp_header_get_tablespace_size(
|
||||||
|
/*===========================*/
|
||||||
|
/* out: size in pages */
|
||||||
|
ulint space); /* in: space id */
|
||||||
|
/**************************************************************************
|
||||||
Initializes the space header of a new created space. */
|
Initializes the space header of a new created space. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -431,15 +431,30 @@ log_block_set_data_len(
|
|||||||
byte* log_block, /* in: log block */
|
byte* log_block, /* in: log block */
|
||||||
ulint len); /* in: data length */
|
ulint len); /* in: data length */
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
Gets a log block number stored in the trailer. */
|
Calculates the checksum for a log block. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ulint
|
ulint
|
||||||
log_block_get_trl_no(
|
log_block_calc_checksum(
|
||||||
/*=================*/
|
/*====================*/
|
||||||
/* out: log block number stored in the block
|
/* out: checksum */
|
||||||
trailer */
|
byte* block); /* in: log block */
|
||||||
|
/****************************************************************
|
||||||
|
Gets a log block checksum field value. */
|
||||||
|
UNIV_INLINE
|
||||||
|
ulint
|
||||||
|
log_block_get_checksum(
|
||||||
|
/*===================*/
|
||||||
|
/* out: checksum */
|
||||||
byte* log_block); /* in: log block */
|
byte* log_block); /* in: log block */
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
|
Sets a log block checksum field value. */
|
||||||
|
UNIV_INLINE
|
||||||
|
void
|
||||||
|
log_block_set_checksum(
|
||||||
|
/*===================*/
|
||||||
|
byte* log_block, /* in: log block */
|
||||||
|
ulint checksum); /* in: checksum */
|
||||||
|
/****************************************************************
|
||||||
Gets a log block first mtr log record group offset. */
|
Gets a log block first mtr log record group offset. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ulint
|
ulint
|
||||||
@ -544,10 +559,11 @@ extern log_t* log_sys;
|
|||||||
bytes */
|
bytes */
|
||||||
|
|
||||||
/* Offsets of a log block trailer from the end of the block */
|
/* Offsets of a log block trailer from the end of the block */
|
||||||
#define LOG_BLOCK_TRL_CHECKSUM 4 /* 1 byte checksum of the log block
|
#define LOG_BLOCK_CHECKSUM 4 /* 4 byte checksum of the log block
|
||||||
contents */
|
contents; in InnoDB versions
|
||||||
#define LOG_BLOCK_TRL_NO 3 /* 3 lowest bytes of the log block
|
< 3.23.52 this did not contain the
|
||||||
number */
|
checksum but the same value as
|
||||||
|
.._HDR_NO */
|
||||||
#define LOG_BLOCK_TRL_SIZE 4 /* trailer size in bytes */
|
#define LOG_BLOCK_TRL_SIZE 4 /* trailer size in bytes */
|
||||||
|
|
||||||
/* Offsets for a checkpoint field */
|
/* Offsets for a checkpoint field */
|
||||||
|
@ -169,33 +169,6 @@ log_block_set_checkpoint_no(
|
|||||||
ut_dulint_get_low(no));
|
ut_dulint_get_low(no));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
Gets a log block number stored in the trailer. */
|
|
||||||
UNIV_INLINE
|
|
||||||
ulint
|
|
||||||
log_block_get_trl_no(
|
|
||||||
/*=================*/
|
|
||||||
/* out: log block number stored in the block
|
|
||||||
trailer */
|
|
||||||
byte* log_block) /* in: log block */
|
|
||||||
{
|
|
||||||
return(mach_read_from_3(log_block + OS_FILE_LOG_BLOCK_SIZE
|
|
||||||
- LOG_BLOCK_TRL_NO));
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
Sets the log block number stored in the trailer. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
log_block_set_trl_no(
|
|
||||||
/*=================*/
|
|
||||||
byte* log_block, /* in: log block */
|
|
||||||
ulint n) /* in: log block number */
|
|
||||||
{
|
|
||||||
mach_write_to_3(log_block + OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_NO,
|
|
||||||
n & 0xFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
Converts a lsn to a log block number. */
|
Converts a lsn to a log block number. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
@ -216,6 +189,61 @@ log_block_convert_lsn_to_no(
|
|||||||
return(no + 1);
|
return(no + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
Calculates the checksum for a log block. */
|
||||||
|
UNIV_INLINE
|
||||||
|
ulint
|
||||||
|
log_block_calc_checksum(
|
||||||
|
/*====================*/
|
||||||
|
/* out: checksum */
|
||||||
|
byte* block) /* in: log block */
|
||||||
|
{
|
||||||
|
ulint sum;
|
||||||
|
ulint sh;
|
||||||
|
ulint i;
|
||||||
|
|
||||||
|
sum = 1;
|
||||||
|
sh = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
|
||||||
|
sum = sum & 0x7FFFFFFF;
|
||||||
|
sum += ((ulint)(*(block + i))) << sh;
|
||||||
|
sh++;
|
||||||
|
if (sh > 24) {
|
||||||
|
sh = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
Gets a log block checksum field value. */
|
||||||
|
UNIV_INLINE
|
||||||
|
ulint
|
||||||
|
log_block_get_checksum(
|
||||||
|
/*===================*/
|
||||||
|
/* out: checksum */
|
||||||
|
byte* log_block) /* in: log block */
|
||||||
|
{
|
||||||
|
return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
|
||||||
|
- LOG_BLOCK_CHECKSUM));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
Sets a log block checksum field value. */
|
||||||
|
UNIV_INLINE
|
||||||
|
void
|
||||||
|
log_block_set_checksum(
|
||||||
|
/*===================*/
|
||||||
|
byte* log_block, /* in: log block */
|
||||||
|
ulint checksum) /* in: checksum */
|
||||||
|
{
|
||||||
|
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
|
||||||
|
- LOG_BLOCK_CHECKSUM,
|
||||||
|
checksum);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
Initializes a log block in the log buffer. */
|
Initializes a log block in the log buffer. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
@ -232,7 +260,6 @@ log_block_init(
|
|||||||
no = log_block_convert_lsn_to_no(lsn);
|
no = log_block_convert_lsn_to_no(lsn);
|
||||||
|
|
||||||
log_block_set_hdr_no(log_block, no);
|
log_block_set_hdr_no(log_block, no);
|
||||||
log_block_set_trl_no(log_block, no);
|
|
||||||
|
|
||||||
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
|
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
|
||||||
log_block_set_first_rec_group(log_block, 0);
|
log_block_set_first_rec_group(log_block, 0);
|
||||||
@ -256,7 +283,7 @@ log_block_init_in_old_format(
|
|||||||
|
|
||||||
log_block_set_hdr_no(log_block, no);
|
log_block_set_hdr_no(log_block, no);
|
||||||
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
|
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
|
||||||
- LOG_BLOCK_TRL_NO - 1, no);
|
- LOG_BLOCK_CHECKSUM, no);
|
||||||
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
|
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
|
||||||
log_block_set_first_rec_group(log_block, 0);
|
log_block_set_first_rec_group(log_block, 0);
|
||||||
}
|
}
|
||||||
|
@ -313,6 +313,10 @@ struct recv_sys_struct{
|
|||||||
this lsn */
|
this lsn */
|
||||||
dulint limit_lsn;/* recovery should be made at most up to this
|
dulint limit_lsn;/* recovery should be made at most up to this
|
||||||
lsn */
|
lsn */
|
||||||
|
ibool found_corrupt_log;
|
||||||
|
/* this is set to TRUE if we during log
|
||||||
|
scan find a corrupt log block, or a corrupt
|
||||||
|
log record */
|
||||||
log_group_t* archive_group;
|
log_group_t* archive_group;
|
||||||
/* in archive recovery: the log group whose
|
/* in archive recovery: the log group whose
|
||||||
archive is read */
|
archive is read */
|
||||||
@ -328,6 +332,8 @@ extern ibool recv_recovery_on;
|
|||||||
extern ibool recv_no_ibuf_operations;
|
extern ibool recv_no_ibuf_operations;
|
||||||
extern ibool recv_needed_recovery;
|
extern ibool recv_needed_recovery;
|
||||||
|
|
||||||
|
extern ibool recv_is_making_a_backup;
|
||||||
|
|
||||||
/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
|
/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
|
||||||
times! */
|
times! */
|
||||||
#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024)
|
#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024)
|
||||||
|
@ -257,6 +257,15 @@ void
|
|||||||
trx_sys_print_mysql_binlog_offset(void);
|
trx_sys_print_mysql_binlog_offset(void);
|
||||||
/*===================================*/
|
/*===================================*/
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
Prints to stdout the MySQL binlog info in the system header if the
|
||||||
|
magic number shows it valid. */
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_sys_print_mysql_binlog_offset_from_page(
|
||||||
|
/*========================================*/
|
||||||
|
byte* page); /* in: buffer containing the trx system header page,
|
||||||
|
i.e., page number TRX_SYS_PAGE_NO in the tablespace */
|
||||||
|
/*********************************************************************
|
||||||
Prints to stderr the MySQL master log offset info in the trx system header if
|
Prints to stderr the MySQL master log offset info in the trx system header if
|
||||||
the magic number shows it valid. */
|
the magic number shows it valid. */
|
||||||
|
|
||||||
@ -300,11 +309,11 @@ therefore 256; each slot is currently 8 bytes in size */
|
|||||||
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
|
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
|
||||||
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
|
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
|
||||||
|
|
||||||
/* The offset of the MySQL replication info on the trx system header page;
|
/* The offset of the MySQL replication info in the trx system header;
|
||||||
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
|
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
|
||||||
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
|
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
|
||||||
|
|
||||||
/* The offset of the MySQL binlog offset info on the trx system header page */
|
/* The offset of the MySQL binlog offset info in the trx system header */
|
||||||
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
|
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
|
||||||
#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows
|
#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows
|
||||||
if we have valid data in the
|
if we have valid data in the
|
||||||
|
@ -309,6 +309,9 @@ struct trx_struct{
|
|||||||
of view of concurrency control:
|
of view of concurrency control:
|
||||||
TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
|
TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
|
||||||
... */
|
... */
|
||||||
|
time_t start_time; /* time the trx object was created
|
||||||
|
or the state last time became
|
||||||
|
TRX_ACTIVE */
|
||||||
ibool check_foreigns; /* normally TRUE, but if the user
|
ibool check_foreigns; /* normally TRUE, but if the user
|
||||||
wants to suppress foreign key checks,
|
wants to suppress foreign key checks,
|
||||||
(in table imports, for example) we
|
(in table imports, for example) we
|
||||||
@ -468,6 +471,7 @@ struct trx_struct{
|
|||||||
TRX_QUE_LOCK_WAIT, this points to
|
TRX_QUE_LOCK_WAIT, this points to
|
||||||
the lock request, otherwise this is
|
the lock request, otherwise this is
|
||||||
NULL */
|
NULL */
|
||||||
|
time_t wait_started; /* lock wait started at this time */
|
||||||
UT_LIST_BASE_NODE_T(que_thr_t)
|
UT_LIST_BASE_NODE_T(que_thr_t)
|
||||||
wait_thrs; /* query threads belonging to this
|
wait_thrs; /* query threads belonging to this
|
||||||
trx that are in the QUE_THR_LOCK_WAIT
|
trx that are in the QUE_THR_LOCK_WAIT
|
||||||
|
@ -1565,6 +1565,7 @@ index->table_name);
|
|||||||
}
|
}
|
||||||
|
|
||||||
trx->que_state = TRX_QUE_LOCK_WAIT;
|
trx->que_state = TRX_QUE_LOCK_WAIT;
|
||||||
|
trx->wait_started = time(NULL);
|
||||||
|
|
||||||
ut_a(que_thr_stop(thr));
|
ut_a(que_thr_stop(thr));
|
||||||
|
|
||||||
@ -2961,6 +2962,7 @@ table->name);
|
|||||||
}
|
}
|
||||||
|
|
||||||
trx->que_state = TRX_QUE_LOCK_WAIT;
|
trx->que_state = TRX_QUE_LOCK_WAIT;
|
||||||
|
trx->wait_started = time(NULL);
|
||||||
|
|
||||||
ut_a(que_thr_stop(thr));
|
ut_a(que_thr_stop(thr));
|
||||||
|
|
||||||
@ -3503,6 +3505,10 @@ lock_print_info(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf += sprintf(buf, "Number of sessions %lu\n",
|
||||||
|
UT_LIST_GET_LEN(trx_sys->mysql_trx_list)
|
||||||
|
+ UT_LIST_GET_LEN(trx_sys->trx_list));
|
||||||
|
|
||||||
buf += sprintf(buf, "Trx id counter %lu %lu\n",
|
buf += sprintf(buf, "Trx id counter %lu %lu\n",
|
||||||
ut_dulint_get_high(trx_sys->max_trx_id),
|
ut_dulint_get_high(trx_sys->max_trx_id),
|
||||||
ut_dulint_get_low(trx_sys->max_trx_id));
|
ut_dulint_get_low(trx_sys->max_trx_id));
|
||||||
@ -3587,7 +3593,8 @@ loop:
|
|||||||
|
|
||||||
if (trx->que_state == TRX_QUE_LOCK_WAIT) {
|
if (trx->que_state == TRX_QUE_LOCK_WAIT) {
|
||||||
buf += sprintf(buf,
|
buf += sprintf(buf,
|
||||||
"------------------TRX IS WAITING FOR THE LOCK:\n");
|
"------- TRX HAS BEEN WAITING %lu SEC FOR THIS LOCK TO BE GRANTED:\n",
|
||||||
|
(ulint)difftime(time(NULL), trx->wait_started));
|
||||||
|
|
||||||
if (lock_get_type(trx->wait_lock) == LOCK_REC) {
|
if (lock_get_type(trx->wait_lock) == LOCK_REC) {
|
||||||
lock_rec_print(buf, trx->wait_lock);
|
lock_rec_print(buf, trx->wait_lock);
|
||||||
|
@ -270,7 +270,7 @@ part_loop:
|
|||||||
|
|
||||||
log->lsn = ut_dulint_add(log->lsn, len);
|
log->lsn = ut_dulint_add(log->lsn, len);
|
||||||
|
|
||||||
/* Initialize the next block header and trailer */
|
/* Initialize the next block header */
|
||||||
log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, log->lsn);
|
log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, log->lsn);
|
||||||
} else {
|
} else {
|
||||||
log->lsn = ut_dulint_add(log->lsn, len);
|
log->lsn = ut_dulint_add(log->lsn, len);
|
||||||
@ -1070,28 +1070,16 @@ log_group_file_header_flush(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
Stores a 1-byte checksum to the trailer checksum field of a log block
|
Stores a 4-byte checksum to the trailer checksum field of a log block
|
||||||
before writing it to a log file. This checksum is used in recovery to
|
before writing it to a log file. This checksum is used in recovery to
|
||||||
check the consistency of a log block. The checksum is simply the 8 low
|
check the consistency of a log block. */
|
||||||
bits of 1 + the sum of the bytes in the log block except the trailer bytes. */
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
log_block_store_checksum(
|
log_block_store_checksum(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
byte* block) /* in/out: pointer to a log block */
|
byte* block) /* in/out: pointer to a log block */
|
||||||
{
|
{
|
||||||
ulint i;
|
log_block_set_checksum(block, log_block_calc_checksum(block));
|
||||||
ulint sum;
|
|
||||||
|
|
||||||
sum = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
|
|
||||||
sum += (ulint)(*(block + i));
|
|
||||||
}
|
|
||||||
|
|
||||||
mach_write_to_1(block + OS_FILE_LOG_BLOCK_SIZE
|
|
||||||
- LOG_BLOCK_TRL_CHECKSUM,
|
|
||||||
0xFF & sum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
|
@ -63,7 +63,7 @@ log scan */
|
|||||||
ulint recv_scan_print_counter = 0;
|
ulint recv_scan_print_counter = 0;
|
||||||
|
|
||||||
ibool recv_is_from_backup = FALSE;
|
ibool recv_is_from_backup = FALSE;
|
||||||
|
ibool recv_is_making_a_backup = FALSE;
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
Creates the recovery system. */
|
Creates the recovery system. */
|
||||||
@ -124,6 +124,8 @@ recv_sys_init(
|
|||||||
|
|
||||||
recv_sys->last_block = ut_align(recv_sys->last_block_buf_start,
|
recv_sys->last_block = ut_align(recv_sys->last_block_buf_start,
|
||||||
OS_FILE_LOG_BLOCK_SIZE);
|
OS_FILE_LOG_BLOCK_SIZE);
|
||||||
|
recv_sys->found_corrupt_log = FALSE;
|
||||||
|
|
||||||
mutex_exit(&(recv_sys->mutex));
|
mutex_exit(&(recv_sys->mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,9 +571,9 @@ recv_read_cp_info_for_backup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
Checks the 1-byte checksum to the trailer checksum field of a log block.
|
Checks the 4-byte checksum to the trailer checksum field of a log block.
|
||||||
We also accept a log block in the old format where the checksum field
|
We also accept a log block in the old format < InnoDB-3.23.52 where the
|
||||||
contained the highest byte of the log block number. */
|
checksum field contains the log block number. */
|
||||||
static
|
static
|
||||||
ibool
|
ibool
|
||||||
log_block_checksum_is_ok_or_old_format(
|
log_block_checksum_is_ok_or_old_format(
|
||||||
@ -580,29 +582,12 @@ log_block_checksum_is_ok_or_old_format(
|
|||||||
format of InnoDB version < 3.23.52 */
|
format of InnoDB version < 3.23.52 */
|
||||||
byte* block) /* in: pointer to a log block */
|
byte* block) /* in: pointer to a log block */
|
||||||
{
|
{
|
||||||
ulint i;
|
if (log_block_calc_checksum(block) == log_block_get_checksum(block)) {
|
||||||
ulint sum;
|
|
||||||
|
|
||||||
sum = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
|
|
||||||
sum += (ulint)(*(block + i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* printf("Checksum %lu, byte %lu\n", 0xFF & sum,
|
|
||||||
mach_read_from_1(block + OS_FILE_LOG_BLOCK_SIZE
|
|
||||||
- LOG_BLOCK_TRL_CHECKSUM));
|
|
||||||
*/
|
|
||||||
if (mach_read_from_1(block + OS_FILE_LOG_BLOCK_SIZE
|
|
||||||
- LOG_BLOCK_TRL_CHECKSUM)
|
|
||||||
== (0xFF & sum)) {
|
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((0xFF000000 & log_block_get_hdr_no(block)) >> 24)
|
if (log_block_get_hdr_no(block) == log_block_get_checksum(block)) {
|
||||||
== mach_read_from_1(block + OS_FILE_LOG_BLOCK_SIZE
|
|
||||||
- LOG_BLOCK_TRL_CHECKSUM)) {
|
|
||||||
|
|
||||||
/* We assume the log block is in the format of
|
/* We assume the log block is in the format of
|
||||||
InnoDB version < 3.23.52 and the block is ok */
|
InnoDB version < 3.23.52 and the block is ok */
|
||||||
@ -649,23 +634,20 @@ recv_scan_log_seg_for_backup(
|
|||||||
|
|
||||||
/* fprintf(stderr, "Log block header no %lu\n", no); */
|
/* fprintf(stderr, "Log block header no %lu\n", no); */
|
||||||
|
|
||||||
if ((no & 0xFFFFFF) != log_block_get_trl_no(log_block)
|
if (no != log_block_convert_lsn_to_no(*scanned_lsn)
|
||||||
|| no != log_block_convert_lsn_to_no(*scanned_lsn)
|
|
||||||
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
|
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
|
||||||
/*
|
/*
|
||||||
printf(
|
printf(
|
||||||
"Log block n:o %lu, trailer n:o %lu, scanned lsn n:o %lu\n",
|
"Log block n:o %lu, scanned lsn n:o %lu\n",
|
||||||
no, log_block_get_trl_no(log_block),
|
no, log_block_convert_lsn_to_no(*scanned_lsn));
|
||||||
log_block_convert_lsn_to_no(*scanned_lsn));
|
|
||||||
*/
|
*/
|
||||||
/* Garbage or an incompletely written log block */
|
/* Garbage or an incompletely written log block */
|
||||||
|
|
||||||
log_block += OS_FILE_LOG_BLOCK_SIZE;
|
log_block += OS_FILE_LOG_BLOCK_SIZE;
|
||||||
/*
|
/*
|
||||||
printf(
|
printf(
|
||||||
"Next log block n:o %lu, trailer n:o %lu\n",
|
"Next log block n:o %lu\n",
|
||||||
log_block_get_hdr_no(log_block),
|
log_block_get_hdr_no(log_block));
|
||||||
log_block_get_trl_no(log_block));
|
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -713,7 +695,7 @@ byte*
|
|||||||
recv_parse_or_apply_log_rec_body(
|
recv_parse_or_apply_log_rec_body(
|
||||||
/*=============================*/
|
/*=============================*/
|
||||||
/* out: log record end, NULL if not a complete
|
/* out: log record end, NULL if not a complete
|
||||||
record */
|
record, or a corrupt record */
|
||||||
byte type, /* in: type */
|
byte type, /* in: type */
|
||||||
byte* ptr, /* in: pointer to a buffer */
|
byte* ptr, /* in: pointer to a buffer */
|
||||||
byte* end_ptr,/* in: pointer to the buffer end */
|
byte* end_ptr,/* in: pointer to the buffer end */
|
||||||
@ -794,8 +776,11 @@ recv_parse_or_apply_log_rec_body(
|
|||||||
"InnoDB: is possible that the log scan did not proceed\n"
|
"InnoDB: is possible that the log scan did not proceed\n"
|
||||||
"InnoDB: far enough in recovery. Please run CHECK TABLE\n"
|
"InnoDB: far enough in recovery. Please run CHECK TABLE\n"
|
||||||
"InnoDB: on your InnoDB tables to check that they are ok!\n"
|
"InnoDB: on your InnoDB tables to check that they are ok!\n"
|
||||||
"InnoDB: Corrupt log record type %lu\n",
|
"InnoDB: Corrupt log record type %lu\n, lsn %lu %lu\n",
|
||||||
(ulint)type);
|
(ulint)type, ut_dulint_get_high(recv_sys->recovered_lsn),
|
||||||
|
ut_dulint_get_low(recv_sys->recovered_lsn));
|
||||||
|
|
||||||
|
recv_sys->found_corrupt_log = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(!page || new_ptr);
|
ut_ad(!page || new_ptr);
|
||||||
@ -1399,18 +1384,30 @@ recv_apply_log_recs_for_backup(
|
|||||||
OS_FILE_OPEN,
|
OS_FILE_OPEN,
|
||||||
OS_FILE_READ_WRITE,
|
OS_FILE_READ_WRITE,
|
||||||
&success);
|
&success);
|
||||||
ut_a(success);
|
if (!success) {
|
||||||
|
printf(
|
||||||
|
"InnoDB: Error: cannot open %lu'th data file %s\n", nth_file);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recv_addr = recv_get_fil_addr_struct(0, i);
|
recv_addr = recv_get_fil_addr_struct(0, i);
|
||||||
|
|
||||||
if (recv_addr != NULL) {
|
if (recv_addr != NULL) {
|
||||||
os_file_read(data_file, page,
|
success = os_file_read(data_file, page,
|
||||||
(nth_page_in_file << UNIV_PAGE_SIZE_SHIFT)
|
(nth_page_in_file << UNIV_PAGE_SIZE_SHIFT)
|
||||||
& 0xFFFFFFFF,
|
& 0xFFFFFFFF,
|
||||||
nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT),
|
nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT),
|
||||||
UNIV_PAGE_SIZE);
|
UNIV_PAGE_SIZE);
|
||||||
|
if (!success) {
|
||||||
|
printf(
|
||||||
|
"InnoDB: Error: cannot read page no %lu from %lu'th data file %s\n",
|
||||||
|
nth_page_in_file, nth_file);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
/* We simulate a page read made by the buffer pool,
|
/* We simulate a page read made by the buffer pool,
|
||||||
to make sure recovery works ok. We must init the
|
to make sure recovery works ok. We must init the
|
||||||
block corresponding to buf_pool->frame_zero
|
block corresponding to buf_pool->frame_zero
|
||||||
@ -1425,12 +1422,19 @@ recv_apply_log_recs_for_backup(
|
|||||||
mach_read_from_8(page + FIL_PAGE_LSN),
|
mach_read_from_8(page + FIL_PAGE_LSN),
|
||||||
0, i);
|
0, i);
|
||||||
|
|
||||||
os_file_write(data_files[nth_file],
|
success = os_file_write(data_files[nth_file],
|
||||||
data_file, page,
|
data_file, page,
|
||||||
(nth_page_in_file << UNIV_PAGE_SIZE_SHIFT)
|
(nth_page_in_file << UNIV_PAGE_SIZE_SHIFT)
|
||||||
& 0xFFFFFFFF,
|
& 0xFFFFFFFF,
|
||||||
nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT),
|
nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT),
|
||||||
UNIV_PAGE_SIZE);
|
UNIV_PAGE_SIZE);
|
||||||
|
if (!success) {
|
||||||
|
printf(
|
||||||
|
"InnoDB: Error: cannot write page no %lu to %lu'th data file %s\n",
|
||||||
|
nth_page_in_file, nth_file);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((100 * i) / n_pages_total
|
if ((100 * i) / n_pages_total
|
||||||
@ -1647,7 +1651,7 @@ ulint
|
|||||||
recv_parse_log_rec(
|
recv_parse_log_rec(
|
||||||
/*===============*/
|
/*===============*/
|
||||||
/* out: length of the record, or 0 if the record was
|
/* out: length of the record, or 0 if the record was
|
||||||
not complete */
|
not complete or it was corrupt */
|
||||||
byte* ptr, /* in: pointer to a buffer */
|
byte* ptr, /* in: pointer to a buffer */
|
||||||
byte* end_ptr,/* in: pointer to the buffer end */
|
byte* end_ptr,/* in: pointer to the buffer end */
|
||||||
byte* type, /* out: type */
|
byte* type, /* out: type */
|
||||||
@ -1679,16 +1683,8 @@ recv_parse_log_rec(
|
|||||||
|
|
||||||
new_ptr = mlog_parse_initial_log_record(ptr, end_ptr, type, space,
|
new_ptr = mlog_parse_initial_log_record(ptr, end_ptr, type, space,
|
||||||
page_no);
|
page_no);
|
||||||
|
|
||||||
/* If the operating system writes to the log complete 512-byte
|
|
||||||
blocks, we should not get the warnings below in recovery.
|
|
||||||
A warning means that the header and the trailer appeared ok
|
|
||||||
in a 512-byte block, but in the middle there was something wrong.
|
|
||||||
TODO: (1) add similar warnings in the case there is an incompletely
|
|
||||||
written log record which does not extend to the boundary of a
|
|
||||||
512-byte block. (2) Add a checksum to a log block. */
|
|
||||||
|
|
||||||
if (!new_ptr) {
|
if (!new_ptr) {
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1696,12 +1692,17 @@ recv_parse_log_rec(
|
|||||||
|
|
||||||
if (*space != 0 || *page_no > 0x8FFFFFFF) {
|
if (*space != 0 || *page_no > 0x8FFFFFFF) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: WARNING: the log file may have been corrupt and it\n"
|
"InnoDB: WARNING: the log file may have been corrupt and it\n"
|
||||||
"InnoDB: is possible that the log scan did not proceed\n"
|
"InnoDB: is possible that the log scan did not proceed\n"
|
||||||
"InnoDB: far enough in recovery. Please run CHECK TABLE\n"
|
"InnoDB: far enough in recovery. Please run CHECK TABLE\n"
|
||||||
"InnoDB: on your InnoDB tables to check that they are ok!\n"
|
"InnoDB: on your InnoDB tables to check that they are ok!\n"
|
||||||
"InnoDB: Corrupt log record type %lu, space id %lu, page no %lu\n",
|
"InnoDB: Corrupt log record type %lu, space id %lu, page no %lu\n",
|
||||||
(ulint)(*type), *space, *page_no);
|
"InnoDB: lsn %lu %lu\n",
|
||||||
|
(ulint)(*type), *space, *page_no,
|
||||||
|
ut_dulint_get_high(recv_sys->recovered_lsn),
|
||||||
|
ut_dulint_get_low(recv_sys->recovered_lsn));
|
||||||
|
|
||||||
|
recv_sys->found_corrupt_log = TRUE;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -1790,6 +1791,7 @@ recv_parse_log_recs(
|
|||||||
ulint page_no;
|
ulint page_no;
|
||||||
byte* body;
|
byte* body;
|
||||||
ulint n_recs;
|
ulint n_recs;
|
||||||
|
char err_buf[2500];
|
||||||
|
|
||||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
ut_ad(mutex_own(&(log_sys->mutex)));
|
||||||
ut_ad(!ut_dulint_is_zero(recv_sys->parse_start_lsn));
|
ut_ad(!ut_dulint_is_zero(recv_sys->parse_start_lsn));
|
||||||
@ -1813,7 +1815,18 @@ loop:
|
|||||||
len = recv_parse_log_rec(ptr, end_ptr, &type, &space,
|
len = recv_parse_log_rec(ptr, end_ptr, &type, &space,
|
||||||
&page_no, &body);
|
&page_no, &body);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
|
if (recv_sys->found_corrupt_log) {
|
||||||
|
|
||||||
|
ut_sprintf_buf(err_buf,
|
||||||
|
recv_sys->buf + ut_calc_align_down(
|
||||||
|
recv_sys->recovered_offset,
|
||||||
|
OS_FILE_LOG_BLOCK_SIZE) - 8,
|
||||||
|
OS_FILE_LOG_BLOCK_SIZE + 16);
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: hex dump of a corrupt log segment: %s\n", err_buf);
|
||||||
|
}
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1851,9 +1864,10 @@ loop:
|
|||||||
#ifdef UNIV_LOG_DEBUG
|
#ifdef UNIV_LOG_DEBUG
|
||||||
recv_check_incomplete_log_recs(ptr, len);
|
recv_check_incomplete_log_recs(ptr, len);
|
||||||
#endif
|
#endif
|
||||||
recv_update_replicate(type, space, page_no, body,
|
/* recv_update_replicate(type, space, page_no, body,
|
||||||
ptr + len);
|
ptr + len);
|
||||||
recv_compare_replicate(space, page_no);
|
recv_compare_replicate(space, page_no);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Check that all the records associated with the single mtr
|
/* Check that all the records associated with the single mtr
|
||||||
@ -1867,7 +1881,18 @@ loop:
|
|||||||
&page_no, &body);
|
&page_no, &body);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
|
|
||||||
return(FALSE);
|
if (recv_sys->found_corrupt_log) {
|
||||||
|
ut_sprintf_buf(err_buf,
|
||||||
|
recv_sys->buf + ut_calc_align_down(
|
||||||
|
recv_sys->recovered_offset,
|
||||||
|
OS_FILE_LOG_BLOCK_SIZE) - 8,
|
||||||
|
OS_FILE_LOG_BLOCK_SIZE + 16);
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: hex dump of a corrupt log segment: %s\n", err_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
|
if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
|
||||||
@ -1876,8 +1901,10 @@ loop:
|
|||||||
#ifdef UNIV_LOG_DEBUG
|
#ifdef UNIV_LOG_DEBUG
|
||||||
recv_check_incomplete_log_recs(ptr, len);
|
recv_check_incomplete_log_recs(ptr, len);
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
recv_update_replicate(type, space, page_no,
|
recv_update_replicate(type, space, page_no,
|
||||||
body, ptr + len);
|
body, ptr + len);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_debug_writes) {
|
if (log_debug_writes) {
|
||||||
@ -1941,7 +1968,7 @@ loop:
|
|||||||
page has become identical with the original
|
page has become identical with the original
|
||||||
page */
|
page */
|
||||||
|
|
||||||
recv_compare_replicate(space, page_no);
|
/* recv_compare_replicate(space, page_no); */
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += len;
|
ptr += len;
|
||||||
@ -2095,32 +2122,19 @@ recv_scan_log_recs(
|
|||||||
|
|
||||||
/* fprintf(stderr, "Log block header no %lu\n", no); */
|
/* fprintf(stderr, "Log block header no %lu\n", no); */
|
||||||
|
|
||||||
if ((no & 0xFFFFFF) != log_block_get_trl_no(log_block)
|
if (no != log_block_convert_lsn_to_no(scanned_lsn)
|
||||||
|| no != log_block_convert_lsn_to_no(scanned_lsn)
|
|
||||||
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
|
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
|
||||||
|
|
||||||
if ((no & 0xFFFFFF) == log_block_get_trl_no(log_block)
|
if (no == log_block_convert_lsn_to_no(scanned_lsn)
|
||||||
&& no == log_block_convert_lsn_to_no(scanned_lsn)
|
|
||||||
&& !log_block_checksum_is_ok_or_old_format(
|
&& !log_block_checksum_is_ok_or_old_format(
|
||||||
log_block)) {
|
log_block)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Log block no %lu at lsn %lu %lu has\n"
|
"InnoDB: Log block no %lu at lsn %lu %lu has\n"
|
||||||
"InnoDB: ok header and trailer, but checksum field contains %lu\n",
|
"InnoDB: ok header, but checksum field contains %lu, should be %lu\n",
|
||||||
no, ut_dulint_get_high(scanned_lsn),
|
no, ut_dulint_get_high(scanned_lsn),
|
||||||
ut_dulint_get_low(scanned_lsn),
|
ut_dulint_get_low(scanned_lsn),
|
||||||
mach_read_from_1(log_block
|
log_block_get_checksum(log_block),
|
||||||
+ OS_FILE_LOG_BLOCK_SIZE
|
log_block_calc_checksum(log_block));
|
||||||
- LOG_BLOCK_TRL_CHECKSUM));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((no & 0xFFFFFF)
|
|
||||||
!= log_block_get_trl_no(log_block)) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"InnoDB: Log block with header no %lu at lsn %lu %lu has\n"
|
|
||||||
"InnoDB: trailer no %lu\n",
|
|
||||||
no, ut_dulint_get_high(scanned_lsn),
|
|
||||||
ut_dulint_get_low(scanned_lsn),
|
|
||||||
log_block_get_trl_no(log_block));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Garbage or an incompletely written log block */
|
/* Garbage or an incompletely written log block */
|
||||||
@ -2213,7 +2227,8 @@ recv_scan_log_recs(
|
|||||||
|
|
||||||
*group_scanned_lsn = scanned_lsn;
|
*group_scanned_lsn = scanned_lsn;
|
||||||
|
|
||||||
if (recv_needed_recovery || recv_is_from_backup) {
|
if (recv_needed_recovery
|
||||||
|
|| (recv_is_from_backup && !recv_is_making_a_backup)) {
|
||||||
recv_scan_print_counter++;
|
recv_scan_print_counter++;
|
||||||
|
|
||||||
if (finished || (recv_scan_print_counter % 80 == 0)) {
|
if (finished || (recv_scan_print_counter % 80 == 0)) {
|
||||||
|
@ -666,7 +666,7 @@ mem_print_info_low(
|
|||||||
|
|
||||||
mem_pool_print_info(outfile, mem_comm_pool);
|
mem_pool_print_info(outfile, mem_comm_pool);
|
||||||
|
|
||||||
mem_validate();
|
/* mem_validate(); */
|
||||||
|
|
||||||
/* fclose(outfile); */
|
/* fclose(outfile); */
|
||||||
#endif
|
#endif
|
||||||
|
@ -595,6 +595,11 @@ row_lock_table_autoinc_for_mysql(
|
|||||||
ut_ad(trx);
|
ut_ad(trx);
|
||||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||||
|
|
||||||
|
if (trx->auto_inc_lock) {
|
||||||
|
|
||||||
|
return(DB_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
trx->op_info = "setting auto-inc lock";
|
trx->op_info = "setting auto-inc lock";
|
||||||
|
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
|
@ -2475,12 +2475,23 @@ srv_error_monitor_thread(
|
|||||||
void* arg) /* in: a dummy parameter required by
|
void* arg) /* in: a dummy parameter required by
|
||||||
os_thread_create */
|
os_thread_create */
|
||||||
{
|
{
|
||||||
|
ulint cnt = 0;
|
||||||
|
|
||||||
UT_NOT_USED(arg);
|
UT_NOT_USED(arg);
|
||||||
loop:
|
loop:
|
||||||
srv_error_monitor_active = TRUE;
|
srv_error_monitor_active = TRUE;
|
||||||
|
|
||||||
os_thread_sleep(10000000);
|
cnt++;
|
||||||
|
|
||||||
|
os_thread_sleep(2000000);
|
||||||
|
|
||||||
|
/* mem_print_new_info();
|
||||||
|
|
||||||
|
if (cnt % 10 == 0) {
|
||||||
|
|
||||||
|
mem_print_info();
|
||||||
|
}
|
||||||
|
*/
|
||||||
sync_array_print_long_waits();
|
sync_array_print_long_waits();
|
||||||
|
|
||||||
/* Flush stdout and stderr so that a database user gets their output
|
/* Flush stdout and stderr so that a database user gets their output
|
||||||
|
@ -927,6 +927,8 @@ innobase_start_or_create_for_mysql(void)
|
|||||||
ulint max_arch_log_no;
|
ulint max_arch_log_no;
|
||||||
ibool start_archive;
|
ibool start_archive;
|
||||||
ulint sum_of_new_sizes;
|
ulint sum_of_new_sizes;
|
||||||
|
ulint sum_of_data_file_sizes;
|
||||||
|
ulint tablespace_size_in_header;
|
||||||
ulint err;
|
ulint err;
|
||||||
ulint i;
|
ulint i;
|
||||||
ulint k;
|
ulint k;
|
||||||
@ -1324,7 +1326,33 @@ innobase_start_or_create_for_mysql(void)
|
|||||||
os_thread_create(&srv_master_thread, NULL, thread_ids + 1 +
|
os_thread_create(&srv_master_thread, NULL, thread_ids + 1 +
|
||||||
SRV_MAX_N_IO_THREADS);
|
SRV_MAX_N_IO_THREADS);
|
||||||
/* buf_debug_prints = TRUE; */
|
/* buf_debug_prints = TRUE; */
|
||||||
|
|
||||||
|
sum_of_data_file_sizes = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < srv_n_data_files; i++) {
|
||||||
|
sum_of_data_file_sizes += srv_data_file_sizes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
tablespace_size_in_header = fsp_header_get_tablespace_size(0);
|
||||||
|
|
||||||
|
if (!srv_auto_extend_last_data_file
|
||||||
|
&& sum_of_data_file_sizes != tablespace_size_in_header) {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: Error: tablespace size stored in header is %lu pages, but\n"
|
||||||
|
"InnoDB: the sum of data file sizes is %lu pages\n",
|
||||||
|
tablespace_size_in_header, sum_of_data_file_sizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srv_auto_extend_last_data_file
|
||||||
|
&& sum_of_data_file_sizes < tablespace_size_in_header) {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: Error: tablespace size stored in header is %lu pages, but\n"
|
||||||
|
"InnoDB: the sum of data file sizes is only %lu pages\n",
|
||||||
|
tablespace_size_in_header, sum_of_data_file_sizes);
|
||||||
|
}
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr, " InnoDB: Started\n");
|
fprintf(stderr, " InnoDB: Started\n");
|
||||||
|
|
||||||
|
@ -493,6 +493,34 @@ trx_sys_update_mysql_binlog_offset(
|
|||||||
MLOG_4BYTES, mtr);
|
MLOG_4BYTES, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Prints to stdout the MySQL binlog info in the system header if the
|
||||||
|
magic number shows it valid. */
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_sys_print_mysql_binlog_offset_from_page(
|
||||||
|
/*========================================*/
|
||||||
|
byte* page) /* in: buffer containing the trx system header page,
|
||||||
|
i.e., page number TRX_SYS_PAGE_NO in the tablespace */
|
||||||
|
{
|
||||||
|
trx_sysf_t* sys_header;
|
||||||
|
|
||||||
|
sys_header = page + TRX_SYS;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"ibbackup: Last MySQL binlog file position %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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
Prints to stderr the MySQL binlog offset info in the trx system header if
|
Prints to stderr the MySQL binlog offset info in the trx system header if
|
||||||
the magic number shows it valid. */
|
the magic number shows it valid. */
|
||||||
|
@ -72,6 +72,7 @@ trx_create(
|
|||||||
|
|
||||||
trx->type = TRX_USER;
|
trx->type = TRX_USER;
|
||||||
trx->conc_state = TRX_NOT_STARTED;
|
trx->conc_state = TRX_NOT_STARTED;
|
||||||
|
trx->start_time = time(NULL);
|
||||||
|
|
||||||
trx->check_foreigns = TRUE;
|
trx->check_foreigns = TRUE;
|
||||||
trx->check_unique_secondary = TRUE;
|
trx->check_unique_secondary = TRUE;
|
||||||
@ -516,6 +517,7 @@ trx_start_low(
|
|||||||
if (trx->type == TRX_PURGE) {
|
if (trx->type == TRX_PURGE) {
|
||||||
trx->id = ut_dulint_zero;
|
trx->id = ut_dulint_zero;
|
||||||
trx->conc_state = TRX_ACTIVE;
|
trx->conc_state = TRX_ACTIVE;
|
||||||
|
trx->start_time = time(NULL);
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
@ -539,6 +541,7 @@ trx_start_low(
|
|||||||
trx->rseg = rseg;
|
trx->rseg = rseg;
|
||||||
|
|
||||||
trx->conc_state = TRX_ACTIVE;
|
trx->conc_state = TRX_ACTIVE;
|
||||||
|
trx->start_time = time(NULL);
|
||||||
|
|
||||||
UT_LIST_ADD_FIRST(trx_list, trx_sys->trx_list, trx);
|
UT_LIST_ADD_FIRST(trx_list, trx_sys->trx_list, trx);
|
||||||
|
|
||||||
@ -1465,10 +1468,26 @@ trx_print(
|
|||||||
500 bytes */
|
500 bytes */
|
||||||
trx_t* trx) /* in: transaction */
|
trx_t* trx) /* in: transaction */
|
||||||
{
|
{
|
||||||
buf += sprintf(buf, "TRANSACTION %lu %lu, OS thread id %lu",
|
char* start_of_line;
|
||||||
|
|
||||||
|
buf += sprintf(buf, "TRANSACTION %lu %lu",
|
||||||
ut_dulint_get_high(trx->id),
|
ut_dulint_get_high(trx->id),
|
||||||
ut_dulint_get_low(trx->id),
|
ut_dulint_get_low(trx->id));
|
||||||
(ulint)trx->mysql_thread_id);
|
|
||||||
|
switch (trx->conc_state) {
|
||||||
|
case TRX_NOT_STARTED: buf += sprintf(buf,
|
||||||
|
", not started"); break;
|
||||||
|
case TRX_ACTIVE: buf += sprintf(buf,
|
||||||
|
", ACTIVE %lu sec",
|
||||||
|
(ulint)difftime(time(NULL), trx->start_time)); break;
|
||||||
|
case TRX_COMMITTED_IN_MEMORY: buf += sprintf(buf,
|
||||||
|
", COMMITTED IN MEMORY");
|
||||||
|
break;
|
||||||
|
default: buf += sprintf(buf, " state %lu", trx->conc_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf += sprintf(buf, ", OS thread id %lu",
|
||||||
|
(ulint)trx->mysql_thread_id);
|
||||||
|
|
||||||
if (ut_strlen(trx->op_info) > 0) {
|
if (ut_strlen(trx->op_info) > 0) {
|
||||||
buf += sprintf(buf, " %s", trx->op_info);
|
buf += sprintf(buf, " %s", trx->op_info);
|
||||||
@ -1477,33 +1496,29 @@ trx_print(
|
|||||||
if (trx->type != TRX_USER) {
|
if (trx->type != TRX_USER) {
|
||||||
buf += sprintf(buf, " purge trx");
|
buf += sprintf(buf, " purge trx");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf += sprintf(buf, "\n");
|
||||||
|
|
||||||
switch (trx->conc_state) {
|
start_of_line = buf;
|
||||||
case TRX_NOT_STARTED: buf += sprintf(buf,
|
|
||||||
", not started"); break;
|
|
||||||
case TRX_ACTIVE: buf += sprintf(buf,
|
|
||||||
", active"); break;
|
|
||||||
case TRX_COMMITTED_IN_MEMORY: buf += sprintf(buf,
|
|
||||||
", committed in memory");
|
|
||||||
break;
|
|
||||||
default: buf += sprintf(buf, " state %lu", trx->conc_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (trx->que_state) {
|
switch (trx->que_state) {
|
||||||
case TRX_QUE_RUNNING: buf += sprintf(buf,
|
case TRX_QUE_RUNNING: break;
|
||||||
", runs or sleeps"); break;
|
|
||||||
case TRX_QUE_LOCK_WAIT: buf += sprintf(buf,
|
case TRX_QUE_LOCK_WAIT: buf += sprintf(buf,
|
||||||
", lock wait"); break;
|
"LOCK WAIT "); break;
|
||||||
case TRX_QUE_ROLLING_BACK: buf += sprintf(buf,
|
case TRX_QUE_ROLLING_BACK: buf += sprintf(buf,
|
||||||
", rolling back"); break;
|
"ROLLING BACK "); break;
|
||||||
case TRX_QUE_COMMITTING: buf += sprintf(buf,
|
case TRX_QUE_COMMITTING: buf += sprintf(buf,
|
||||||
", committing"); break;
|
"COMMITTING "); break;
|
||||||
default: buf += sprintf(buf, " que state %lu", trx->que_state);
|
default: buf += sprintf(buf, "que state %lu", trx->que_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 < UT_LIST_GET_LEN(trx->trx_locks)) {
|
if (0 < UT_LIST_GET_LEN(trx->trx_locks) ||
|
||||||
buf += sprintf(buf, ", has %lu lock struct(s)",
|
mem_heap_get_size(trx->lock_heap) > 400) {
|
||||||
UT_LIST_GET_LEN(trx->trx_locks));
|
|
||||||
|
buf += sprintf(buf,
|
||||||
|
"%lu lock struct(s), heap size %lu",
|
||||||
|
UT_LIST_GET_LEN(trx->trx_locks),
|
||||||
|
mem_heap_get_size(trx->lock_heap));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trx->has_search_latch) {
|
if (trx->has_search_latch) {
|
||||||
@ -1515,7 +1530,10 @@ trx_print(
|
|||||||
ut_dulint_get_low(trx->undo_no));
|
ut_dulint_get_low(trx->undo_no));
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += sprintf(buf, "\n");
|
if (buf != start_of_line) {
|
||||||
|
|
||||||
|
buf += sprintf(buf, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (trx->mysql_thd != NULL) {
|
if (trx->mysql_thd != NULL) {
|
||||||
innobase_mysql_print_thd(buf, trx->mysql_thd);
|
innobase_mysql_print_thd(buf, trx->mysql_thd);
|
||||||
|
@ -266,10 +266,39 @@ innobase_mysql_print_thd(
|
|||||||
|
|
||||||
thd = (THD*) input_thd;
|
thd = (THD*) input_thd;
|
||||||
|
|
||||||
|
buf += sprintf(buf, "MySQL thread id %lu, query id %lu",
|
||||||
|
thd->thread_id, thd->query_id);
|
||||||
|
if (thd->host) {
|
||||||
|
buf += sprintf(buf, " %.30s", thd->host);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thd->ip) {
|
||||||
|
buf += sprintf(buf, " %.20s", thd->ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thd->user) {
|
||||||
|
buf += sprintf(buf, " %.20s", thd->user);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thd->proc_info) {
|
||||||
|
buf += sprintf(buf, " %.50s", thd->proc_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thd->query) {
|
||||||
|
buf += sprintf(buf, "\n%.150s", thd->query);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf += sprintf(buf, "\n");
|
||||||
|
|
||||||
|
#ifdef notdefined
|
||||||
|
/* July 30, 2002
|
||||||
|
Revert Monty's changes because they seem to make control
|
||||||
|
characters sometimes appear in the output */
|
||||||
|
|
||||||
/* We can't use value of sprintf() as this is not portable */
|
/* We can't use value of sprintf() as this is not portable */
|
||||||
buf+= my_sprintf(buf,
|
buf+= my_sprintf(buf,
|
||||||
(buf, "MySQL thread id %lu, query id %lu",
|
(buf, "MySQL thread id %lu",
|
||||||
thd->thread_id, thd->query_id));
|
thd->thread_id));
|
||||||
if (thd->host)
|
if (thd->host)
|
||||||
{
|
{
|
||||||
*buf++=' ';
|
*buf++=' ';
|
||||||
@ -296,10 +325,11 @@ innobase_mysql_print_thd(
|
|||||||
|
|
||||||
if (thd->query)
|
if (thd->query)
|
||||||
{
|
{
|
||||||
*buf++=' ';
|
*buf++='\n';
|
||||||
buf=strnmov(buf, thd->query, 150);
|
buf=strnmov(buf, thd->query, 150);
|
||||||
}
|
}
|
||||||
*buf='\n';
|
*buf='\n';
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1414,6 +1444,7 @@ ha_innobase::write_row(
|
|||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
||||||
int error;
|
int error;
|
||||||
longlong auto_inc;
|
longlong auto_inc;
|
||||||
|
longlong dummy;
|
||||||
|
|
||||||
DBUG_ENTER("ha_innobase::write_row");
|
DBUG_ENTER("ha_innobase::write_row");
|
||||||
|
|
||||||
@ -1436,7 +1467,31 @@ ha_innobase::write_row(
|
|||||||
if (table->next_number_field && record == table->record[0]) {
|
if (table->next_number_field && record == table->record[0]) {
|
||||||
/* This is the case where the table has an
|
/* This is the case where the table has an
|
||||||
auto-increment column */
|
auto-increment column */
|
||||||
|
|
||||||
|
/* Initialize the auto-inc counter if it has not been
|
||||||
|
initialized yet */
|
||||||
|
|
||||||
|
if (0 == dict_table_autoinc_peek(prebuilt->table)) {
|
||||||
|
|
||||||
|
/* This call initializes the counter */
|
||||||
|
error = innobase_read_and_init_auto_inc(&dummy);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
/* Deadlock or lock wait timeout */
|
||||||
|
|
||||||
|
goto func_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have to set sql_stat_start to TRUE because
|
||||||
|
the above call probably has called a select, and
|
||||||
|
has reset that flag; row_insert_for_mysql has to
|
||||||
|
know to set the IX intention lock on the table,
|
||||||
|
something it only does at the start of each
|
||||||
|
statement */
|
||||||
|
|
||||||
|
prebuilt->sql_stat_start = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fetch the value the user possibly has set in the
|
/* Fetch the value the user possibly has set in the
|
||||||
autoincrement field */
|
autoincrement field */
|
||||||
|
|
||||||
@ -1469,10 +1524,9 @@ ha_innobase::write_row(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auto_inc != 0) {
|
if (auto_inc != 0) {
|
||||||
/* This call will calculate the max of the
|
/* This call will calculate the max of the current
|
||||||
current value and the value supplied by the user, if
|
value and the value supplied by the user and
|
||||||
the auto_inc counter is already initialized
|
update the counter accordingly */
|
||||||
for the table */
|
|
||||||
|
|
||||||
/* We have to use the transactional lock mechanism
|
/* We have to use the transactional lock mechanism
|
||||||
on the auto-inc counter of the table to ensure
|
on the auto-inc counter of the table to ensure
|
||||||
@ -1512,46 +1566,18 @@ ha_innobase::write_row(
|
|||||||
auto_inc = dict_table_autoinc_get(prebuilt->table);
|
auto_inc = dict_table_autoinc_get(prebuilt->table);
|
||||||
srv_conc_exit_innodb(prebuilt->trx);
|
srv_conc_exit_innodb(prebuilt->trx);
|
||||||
|
|
||||||
/* If auto_inc is now != 0 the autoinc counter
|
/* We can give the new value for MySQL to place in
|
||||||
was already initialized for the table: we can give
|
the field */
|
||||||
the new value for MySQL to place in the field */
|
|
||||||
|
|
||||||
if (auto_inc != 0) {
|
user_thd->next_insert_id = auto_inc;
|
||||||
user_thd->next_insert_id = auto_inc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This call of a handler.cc function places
|
||||||
|
user_thd->next_insert_id to the column value, if the column
|
||||||
|
value was not set by the user */
|
||||||
|
|
||||||
update_auto_increment();
|
update_auto_increment();
|
||||||
|
}
|
||||||
if (auto_inc == 0) {
|
|
||||||
/* The autoinc counter for our table was not yet
|
|
||||||
initialized, initialize it now */
|
|
||||||
|
|
||||||
auto_inc = table->next_number_field->val_int();
|
|
||||||
|
|
||||||
srv_conc_enter_innodb(prebuilt->trx);
|
|
||||||
error = row_lock_table_autoinc_for_mysql(prebuilt);
|
|
||||||
srv_conc_exit_innodb(prebuilt->trx);
|
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
|
||||||
|
|
||||||
error = convert_error_code_to_mysql(error,
|
|
||||||
user_thd);
|
|
||||||
goto func_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
dict_table_autoinc_initialize(prebuilt->table,
|
|
||||||
auto_inc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have to set sql_stat_start to TRUE because
|
|
||||||
update_auto_increment may have called a select, and
|
|
||||||
has reset that flag; row_insert_for_mysql has to
|
|
||||||
know to set the IX intention lock on the table, something
|
|
||||||
it only does at the start of each statement */
|
|
||||||
|
|
||||||
prebuilt->sql_stat_start = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prebuilt->mysql_template == NULL
|
if (prebuilt->mysql_template == NULL
|
||||||
|| prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
|
|| prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
|
||||||
@ -3572,37 +3598,53 @@ ha_innobase::store_lock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Returns the next auto-increment column value for the table. write_row
|
This function initializes the auto-inc counter if it has not been
|
||||||
normally fetches the value from the cache in the data dictionary. This
|
initialized yet. This function does not change the value of the auto-inc
|
||||||
function in used by SHOW TABLE STATUS and when the first insert to the table
|
counter if it already has been initialized. In parameter ret returns
|
||||||
is done after database startup. */
|
the value of the auto-inc counter. */
|
||||||
|
|
||||||
longlong
|
int
|
||||||
ha_innobase::get_auto_increment()
|
ha_innobase::innobase_read_and_init_auto_inc(
|
||||||
/*=============================*/
|
/*=========================================*/
|
||||||
/* out: the next auto-increment column value */
|
/* out: 0 or error code: deadlock or
|
||||||
|
lock wait timeout */
|
||||||
|
longlong* ret) /* out: auto-inc value */
|
||||||
{
|
{
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||||
longlong nr;
|
longlong auto_inc;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
ut_a(prebuilt);
|
||||||
ut_a(prebuilt->trx ==
|
ut_a(prebuilt->trx ==
|
||||||
(trx_t*) current_thd->transaction.all.innobase_tid);
|
(trx_t*) current_thd->transaction.all.innobase_tid);
|
||||||
|
ut_a(prebuilt->table);
|
||||||
|
|
||||||
|
auto_inc = dict_table_autoinc_read(prebuilt->table);
|
||||||
|
|
||||||
/* Also SHOW TABLE STATUS calls this function. Previously, when we did
|
if (auto_inc != 0) {
|
||||||
always read the max autoinc key value, setting x-locks, users were
|
/* Already initialized */
|
||||||
surprised that SHOW TABLE STATUS could end up in a deadlock with
|
*ret = auto_inc;
|
||||||
ordinary SQL queries. We avoid these deadlocks if the auto-inc
|
|
||||||
counter for the table has been initialized by fetching the value
|
return(0);
|
||||||
from the table struct in dictionary cache. */
|
}
|
||||||
|
|
||||||
assert(prebuilt->table);
|
srv_conc_enter_innodb(prebuilt->trx);
|
||||||
|
error = row_lock_table_autoinc_for_mysql(prebuilt);
|
||||||
nr = dict_table_autoinc_read(prebuilt->table);
|
srv_conc_exit_innodb(prebuilt->trx);
|
||||||
|
|
||||||
if (nr != 0) {
|
if (error != DB_SUCCESS) {
|
||||||
|
error = convert_error_code_to_mysql(error, user_thd);
|
||||||
|
|
||||||
return(nr + 1);
|
goto func_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check again if someone has initialized the counter meanwhile */
|
||||||
|
auto_inc = dict_table_autoinc_read(prebuilt->table);
|
||||||
|
|
||||||
|
if (auto_inc != 0) {
|
||||||
|
*ret = auto_inc;
|
||||||
|
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) extra(HA_EXTRA_KEYREAD);
|
(void) extra(HA_EXTRA_KEYREAD);
|
||||||
@ -3622,22 +3664,63 @@ ha_innobase::get_auto_increment()
|
|||||||
|
|
||||||
prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
|
prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
|
||||||
|
|
||||||
prebuilt->trx->mysql_n_tables_locked += 1;
|
prebuilt->trx->mysql_n_tables_locked += 1;
|
||||||
|
|
||||||
error = index_last(table->record[1]);
|
error = index_last(table->record[1]);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
nr = 1;
|
if (error == HA_ERR_END_OF_FILE) {
|
||||||
|
/* The table was empty, initialize to 1 */
|
||||||
|
auto_inc = 1;
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
} else {
|
||||||
|
/* Deadlock or a lock wait timeout */
|
||||||
|
auto_inc = -1;
|
||||||
|
|
||||||
|
goto func_exit;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
nr = (longlong) table->next_number_field->
|
/* Initialize to max(col) + 1 */
|
||||||
|
auto_inc = (longlong) table->next_number_field->
|
||||||
val_int_offset(table->rec_buff_length) + 1;
|
val_int_offset(table->rec_buff_length) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dict_table_autoinc_initialize(prebuilt->table, auto_inc);
|
||||||
|
|
||||||
|
func_exit:
|
||||||
(void) extra(HA_EXTRA_NO_KEYREAD);
|
(void) extra(HA_EXTRA_NO_KEYREAD);
|
||||||
|
|
||||||
index_end();
|
index_end();
|
||||||
|
|
||||||
return(nr);
|
*ret = auto_inc;
|
||||||
|
|
||||||
|
return(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
This function initializes the auto-inc counter if it has not been
|
||||||
|
initialized yet. This function does not change the value of the auto-inc
|
||||||
|
counter if it already has been initialized. Returns the value of the
|
||||||
|
auto-inc counter. */
|
||||||
|
|
||||||
|
longlong
|
||||||
|
ha_innobase::get_auto_increment()
|
||||||
|
/*=============================*/
|
||||||
|
/* out: auto-increment column value, -1 if error
|
||||||
|
(deadlock or lock wait timeout) */
|
||||||
|
{
|
||||||
|
longlong nr;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = innobase_read_and_init_auto_inc(&nr);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_INNOBASE_DB */
|
#endif /* HAVE_INNOBASE_DB */
|
||||||
|
@ -68,6 +68,7 @@ class ha_innobase: public handler
|
|||||||
int update_thd(THD* thd);
|
int update_thd(THD* thd);
|
||||||
int change_active_index(uint keynr);
|
int change_active_index(uint keynr);
|
||||||
int general_fetch(byte* buf, uint direction, uint match_mode);
|
int general_fetch(byte* buf, uint direction, uint match_mode);
|
||||||
|
int innobase_read_and_init_auto_inc(longlong* ret);
|
||||||
|
|
||||||
/* Init values for the class: */
|
/* Init values for the class: */
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user