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));
|
||||
|
||||
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("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);
|
||||
|
||||
@ -1819,13 +1820,20 @@ buf_print_io(
|
||||
mutex_enter(&(buf_pool->mutex));
|
||||
|
||||
buf += sprintf(buf,
|
||||
"Free list length %lu \n", UT_LIST_GET_LEN(buf_pool->free));
|
||||
"Buffer pool size %lu\n", size);
|
||||
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,
|
||||
"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));
|
||||
buf += sprintf(buf, "Buffer pool size %lu\n", size);
|
||||
|
||||
buf += sprintf(buf, "Pending reads %lu \n", buf_pool->n_pend_reads);
|
||||
|
||||
|
@ -270,7 +270,7 @@ void
|
||||
dict_table_autoinc_initialize(
|
||||
/*==========================*/
|
||||
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));
|
||||
|
||||
@ -281,8 +281,8 @@ dict_table_autoinc_initialize(
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Gets the next autoinc value, 0 if not yet initialized. If initialized,
|
||||
increments the counter by 1. */
|
||||
Gets the next autoinc value (== autoinc counter value), 0 if not yet
|
||||
initialized. If initialized, increments the counter by 1. */
|
||||
|
||||
ib_longlong
|
||||
dict_table_autoinc_get(
|
||||
@ -298,8 +298,8 @@ dict_table_autoinc_get(
|
||||
|
||||
value = 0;
|
||||
} else {
|
||||
table->autoinc = table->autoinc + 1;
|
||||
value = table->autoinc;
|
||||
table->autoinc = table->autoinc + 1;
|
||||
}
|
||||
|
||||
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. */
|
||||
|
||||
void
|
||||
dict_table_autoinc_update(
|
||||
/*======================*/
|
||||
|
||||
dict_table_t* table, /* in: table */
|
||||
ib_longlong value) /* in: value which was assigned to a row */
|
||||
{
|
||||
mutex_enter(&(table->autoinc_mutex));
|
||||
|
||||
if (table->autoinc_inited) {
|
||||
if (value > table->autoinc) {
|
||||
table->autoinc = value;
|
||||
if (value >= table->autoinc) {
|
||||
table->autoinc = value + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,7 +578,7 @@ fil_read_flushed_lsn_and_arch_log_no(
|
||||
ulint arch_log_no;
|
||||
|
||||
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);
|
||||
|
||||
os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
|
||||
|
@ -933,6 +933,36 @@ fsp_header_get_free_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. */
|
||||
static
|
||||
|
@ -335,6 +335,11 @@ ha_print_info(
|
||||
}
|
||||
}
|
||||
|
||||
buf += sprintf(buf, "Hash table size %lu, used cells %lu\n",
|
||||
hash_get_n_cells(table), cells);
|
||||
buf += sprintf(buf,
|
||||
"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);
|
||||
/************************************************************************
|
||||
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. */
|
||||
|
||||
void
|
||||
dict_table_autoinc_initialize(
|
||||
/*==========================*/
|
||||
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,
|
||||
increments the counter by 1. */
|
||||
Gets the next autoinc value (== autoinc counter value), 0 if not yet
|
||||
initialized. If initialized, increments the counter by 1. */
|
||||
|
||||
ib_longlong
|
||||
dict_table_autoinc_get(
|
||||
@ -123,12 +123,22 @@ dict_table_autoinc_read(
|
||||
/* out: value of the counter */
|
||||
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. */
|
||||
|
||||
void
|
||||
dict_table_autoinc_update(
|
||||
/*======================*/
|
||||
|
||||
dict_table_t* table, /* in: table */
|
||||
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
|
||||
inited; MySQL gets the init value by executing
|
||||
SELECT MAX(auto inc column) */
|
||||
ib_longlong autoinc;/* autoinc counter value already given to
|
||||
a row */
|
||||
ib_longlong autoinc;/* autoinc counter value to give to the
|
||||
next inserted row */
|
||||
ulint magic_n;/* magic number */
|
||||
};
|
||||
#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;
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -57,6 +57,16 @@ fsp_header_get_free_limit(
|
||||
/* out: free limit in megabytes */
|
||||
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. */
|
||||
|
||||
void
|
||||
|
@ -431,15 +431,30 @@ log_block_set_data_len(
|
||||
byte* log_block, /* in: log block */
|
||||
ulint len); /* in: data length */
|
||||
/****************************************************************
|
||||
Gets a log block number stored in the trailer. */
|
||||
Calculates the checksum for a log block. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
log_block_get_trl_no(
|
||||
/*=================*/
|
||||
/* out: log block number stored in the block
|
||||
trailer */
|
||||
log_block_calc_checksum(
|
||||
/*====================*/
|
||||
/* out: checksum */
|
||||
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 */
|
||||
/****************************************************************
|
||||
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. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
@ -544,10 +559,11 @@ extern log_t* log_sys;
|
||||
bytes */
|
||||
|
||||
/* 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
|
||||
contents */
|
||||
#define LOG_BLOCK_TRL_NO 3 /* 3 lowest bytes of the log block
|
||||
number */
|
||||
#define LOG_BLOCK_CHECKSUM 4 /* 4 byte checksum of the log block
|
||||
contents; in InnoDB versions
|
||||
< 3.23.52 this did not contain the
|
||||
checksum but the same value as
|
||||
.._HDR_NO */
|
||||
#define LOG_BLOCK_TRL_SIZE 4 /* trailer size in bytes */
|
||||
|
||||
/* Offsets for a checkpoint field */
|
||||
|
@ -169,33 +169,6 @@ log_block_set_checkpoint_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. */
|
||||
UNIV_INLINE
|
||||
@ -216,6 +189,61 @@ log_block_convert_lsn_to_no(
|
||||
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. */
|
||||
UNIV_INLINE
|
||||
@ -232,7 +260,6 @@ log_block_init(
|
||||
no = log_block_convert_lsn_to_no(lsn);
|
||||
|
||||
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_first_rec_group(log_block, 0);
|
||||
@ -256,7 +283,7 @@ log_block_init_in_old_format(
|
||||
|
||||
log_block_set_hdr_no(log_block, no);
|
||||
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_first_rec_group(log_block, 0);
|
||||
}
|
||||
|
@ -313,6 +313,10 @@ struct recv_sys_struct{
|
||||
this lsn */
|
||||
dulint limit_lsn;/* recovery should be made at most up to this
|
||||
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;
|
||||
/* in archive recovery: the log group whose
|
||||
archive is read */
|
||||
@ -328,6 +332,8 @@ extern ibool recv_recovery_on;
|
||||
extern ibool recv_no_ibuf_operations;
|
||||
extern ibool recv_needed_recovery;
|
||||
|
||||
extern ibool recv_is_making_a_backup;
|
||||
|
||||
/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
|
||||
times! */
|
||||
#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024)
|
||||
|
@ -257,6 +257,15 @@ 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
|
||||
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_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 */
|
||||
#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_MAGIC_N_FLD 0 /* magic number which shows
|
||||
if we have valid data in the
|
||||
|
@ -309,6 +309,9 @@ struct trx_struct{
|
||||
of view of concurrency control:
|
||||
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
|
||||
wants to suppress foreign key checks,
|
||||
(in table imports, for example) we
|
||||
@ -468,6 +471,7 @@ struct trx_struct{
|
||||
TRX_QUE_LOCK_WAIT, this points to
|
||||
the lock request, otherwise this is
|
||||
NULL */
|
||||
time_t wait_started; /* lock wait started at this time */
|
||||
UT_LIST_BASE_NODE_T(que_thr_t)
|
||||
wait_thrs; /* query threads belonging to this
|
||||
trx that are in the QUE_THR_LOCK_WAIT
|
||||
|
@ -1565,6 +1565,7 @@ index->table_name);
|
||||
}
|
||||
|
||||
trx->que_state = TRX_QUE_LOCK_WAIT;
|
||||
trx->wait_started = time(NULL);
|
||||
|
||||
ut_a(que_thr_stop(thr));
|
||||
|
||||
@ -2961,6 +2962,7 @@ table->name);
|
||||
}
|
||||
|
||||
trx->que_state = TRX_QUE_LOCK_WAIT;
|
||||
trx->wait_started = time(NULL);
|
||||
|
||||
ut_a(que_thr_stop(thr));
|
||||
|
||||
@ -3503,6 +3505,10 @@ lock_print_info(
|
||||
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",
|
||||
ut_dulint_get_high(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) {
|
||||
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) {
|
||||
lock_rec_print(buf, trx->wait_lock);
|
||||
|
@ -270,7 +270,7 @@ part_loop:
|
||||
|
||||
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);
|
||||
} else {
|
||||
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
|
||||
check the consistency of a log block. The checksum is simply the 8 low
|
||||
bits of 1 + the sum of the bytes in the log block except the trailer bytes. */
|
||||
check the consistency of a log block. */
|
||||
static
|
||||
void
|
||||
log_block_store_checksum(
|
||||
/*=====================*/
|
||||
byte* block) /* in/out: pointer to a log block */
|
||||
{
|
||||
ulint i;
|
||||
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);
|
||||
log_block_set_checksum(block, log_block_calc_checksum(block));
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
@ -63,7 +63,7 @@ log scan */
|
||||
ulint recv_scan_print_counter = 0;
|
||||
|
||||
ibool recv_is_from_backup = FALSE;
|
||||
|
||||
ibool recv_is_making_a_backup = FALSE;
|
||||
|
||||
/************************************************************
|
||||
Creates the recovery system. */
|
||||
@ -124,6 +124,8 @@ recv_sys_init(
|
||||
|
||||
recv_sys->last_block = ut_align(recv_sys->last_block_buf_start,
|
||||
OS_FILE_LOG_BLOCK_SIZE);
|
||||
recv_sys->found_corrupt_log = FALSE;
|
||||
|
||||
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.
|
||||
We also accept a log block in the old format where the checksum field
|
||||
contained the highest byte of the log block number. */
|
||||
Checks the 4-byte checksum to the trailer checksum field of a log block.
|
||||
We also accept a log block in the old format < InnoDB-3.23.52 where the
|
||||
checksum field contains the log block number. */
|
||||
static
|
||||
ibool
|
||||
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 */
|
||||
byte* block) /* in: pointer to a log block */
|
||||
{
|
||||
ulint i;
|
||||
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)) {
|
||||
if (log_block_calc_checksum(block) == log_block_get_checksum(block)) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (((0xFF000000 & log_block_get_hdr_no(block)) >> 24)
|
||||
== mach_read_from_1(block + OS_FILE_LOG_BLOCK_SIZE
|
||||
- LOG_BLOCK_TRL_CHECKSUM)) {
|
||||
if (log_block_get_hdr_no(block) == log_block_get_checksum(block)) {
|
||||
|
||||
/* We assume the log block is in the format of
|
||||
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); */
|
||||
|
||||
if ((no & 0xFFFFFF) != log_block_get_trl_no(log_block)
|
||||
|| no != log_block_convert_lsn_to_no(*scanned_lsn)
|
||||
if (no != log_block_convert_lsn_to_no(*scanned_lsn)
|
||||
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
|
||||
/*
|
||||
printf(
|
||||
"Log block n:o %lu, trailer n:o %lu, scanned lsn n:o %lu\n",
|
||||
no, log_block_get_trl_no(log_block),
|
||||
log_block_convert_lsn_to_no(*scanned_lsn));
|
||||
"Log block n:o %lu, scanned lsn n:o %lu\n",
|
||||
no, log_block_convert_lsn_to_no(*scanned_lsn));
|
||||
*/
|
||||
/* Garbage or an incompletely written log block */
|
||||
|
||||
log_block += OS_FILE_LOG_BLOCK_SIZE;
|
||||
/*
|
||||
printf(
|
||||
"Next log block n:o %lu, trailer n:o %lu\n",
|
||||
log_block_get_hdr_no(log_block),
|
||||
log_block_get_trl_no(log_block));
|
||||
"Next log block n:o %lu\n",
|
||||
log_block_get_hdr_no(log_block));
|
||||
*/
|
||||
break;
|
||||
}
|
||||
@ -713,7 +695,7 @@ byte*
|
||||
recv_parse_or_apply_log_rec_body(
|
||||
/*=============================*/
|
||||
/* out: log record end, NULL if not a complete
|
||||
record */
|
||||
record, or a corrupt record */
|
||||
byte type, /* in: type */
|
||||
byte* ptr, /* in: pointer to a buffer */
|
||||
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: far enough in recovery. Please run CHECK TABLE\n"
|
||||
"InnoDB: on your InnoDB tables to check that they are ok!\n"
|
||||
"InnoDB: Corrupt log record type %lu\n",
|
||||
(ulint)type);
|
||||
"InnoDB: Corrupt log record type %lu\n, lsn %lu %lu\n",
|
||||
(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);
|
||||
@ -1399,17 +1384,29 @@ recv_apply_log_recs_for_backup(
|
||||
OS_FILE_OPEN,
|
||||
OS_FILE_READ_WRITE,
|
||||
&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);
|
||||
|
||||
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)
|
||||
& 0xFFFFFFFF,
|
||||
nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT),
|
||||
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,
|
||||
to make sure recovery works ok. We must init the
|
||||
@ -1425,12 +1422,19 @@ recv_apply_log_recs_for_backup(
|
||||
mach_read_from_8(page + FIL_PAGE_LSN),
|
||||
0, i);
|
||||
|
||||
os_file_write(data_files[nth_file],
|
||||
success = os_file_write(data_files[nth_file],
|
||||
data_file, page,
|
||||
(nth_page_in_file << UNIV_PAGE_SIZE_SHIFT)
|
||||
& 0xFFFFFFFF,
|
||||
nth_page_in_file >> (32 - UNIV_PAGE_SIZE_SHIFT),
|
||||
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
|
||||
@ -1647,7 +1651,7 @@ ulint
|
||||
recv_parse_log_rec(
|
||||
/*===============*/
|
||||
/* 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* end_ptr,/* in: pointer to the buffer end */
|
||||
byte* type, /* out: type */
|
||||
@ -1679,16 +1683,8 @@ recv_parse_log_rec(
|
||||
|
||||
new_ptr = mlog_parse_initial_log_record(ptr, end_ptr, type, space,
|
||||
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) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -1701,7 +1697,12 @@ recv_parse_log_rec(
|
||||
"InnoDB: far enough in recovery. Please run CHECK TABLE\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",
|
||||
(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);
|
||||
}
|
||||
@ -1790,6 +1791,7 @@ recv_parse_log_recs(
|
||||
ulint page_no;
|
||||
byte* body;
|
||||
ulint n_recs;
|
||||
char err_buf[2500];
|
||||
|
||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
||||
ut_ad(!ut_dulint_is_zero(recv_sys->parse_start_lsn));
|
||||
@ -1813,6 +1815,17 @@ loop:
|
||||
len = recv_parse_log_rec(ptr, end_ptr, &type, &space,
|
||||
&page_no, &body);
|
||||
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);
|
||||
}
|
||||
@ -1851,9 +1864,10 @@ loop:
|
||||
#ifdef UNIV_LOG_DEBUG
|
||||
recv_check_incomplete_log_recs(ptr, len);
|
||||
#endif
|
||||
recv_update_replicate(type, space, page_no, body,
|
||||
/* recv_update_replicate(type, space, page_no, body,
|
||||
ptr + len);
|
||||
recv_compare_replicate(space, page_no);
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
/* Check that all the records associated with the single mtr
|
||||
@ -1867,6 +1881,17 @@ loop:
|
||||
&page_no, &body);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1876,8 +1901,10 @@ loop:
|
||||
#ifdef UNIV_LOG_DEBUG
|
||||
recv_check_incomplete_log_recs(ptr, len);
|
||||
#endif
|
||||
/*
|
||||
recv_update_replicate(type, space, page_no,
|
||||
body, ptr + len);
|
||||
*/
|
||||
}
|
||||
|
||||
if (log_debug_writes) {
|
||||
@ -1941,7 +1968,7 @@ loop:
|
||||
page has become identical with the original
|
||||
page */
|
||||
|
||||
recv_compare_replicate(space, page_no);
|
||||
/* recv_compare_replicate(space, page_no); */
|
||||
}
|
||||
|
||||
ptr += len;
|
||||
@ -2095,32 +2122,19 @@ recv_scan_log_recs(
|
||||
|
||||
/* fprintf(stderr, "Log block header no %lu\n", no); */
|
||||
|
||||
if ((no & 0xFFFFFF) != log_block_get_trl_no(log_block)
|
||||
|| no != log_block_convert_lsn_to_no(scanned_lsn)
|
||||
if (no != log_block_convert_lsn_to_no(scanned_lsn)
|
||||
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
|
||||
|
||||
if ((no & 0xFFFFFF) == log_block_get_trl_no(log_block)
|
||||
&& no == log_block_convert_lsn_to_no(scanned_lsn)
|
||||
if (no == log_block_convert_lsn_to_no(scanned_lsn)
|
||||
&& !log_block_checksum_is_ok_or_old_format(
|
||||
log_block)) {
|
||||
fprintf(stderr,
|
||||
"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),
|
||||
ut_dulint_get_low(scanned_lsn),
|
||||
mach_read_from_1(log_block
|
||||
+ OS_FILE_LOG_BLOCK_SIZE
|
||||
- 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));
|
||||
log_block_get_checksum(log_block),
|
||||
log_block_calc_checksum(log_block));
|
||||
}
|
||||
|
||||
/* Garbage or an incompletely written log block */
|
||||
@ -2213,7 +2227,8 @@ recv_scan_log_recs(
|
||||
|
||||
*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++;
|
||||
|
||||
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_validate();
|
||||
/* mem_validate(); */
|
||||
|
||||
/* fclose(outfile); */
|
||||
#endif
|
||||
|
@ -595,6 +595,11 @@ row_lock_table_autoinc_for_mysql(
|
||||
ut_ad(trx);
|
||||
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";
|
||||
|
||||
if (node == NULL) {
|
||||
|
@ -2475,12 +2475,23 @@ srv_error_monitor_thread(
|
||||
void* arg) /* in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
{
|
||||
ulint cnt = 0;
|
||||
|
||||
UT_NOT_USED(arg);
|
||||
loop:
|
||||
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();
|
||||
|
||||
/* 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;
|
||||
ibool start_archive;
|
||||
ulint sum_of_new_sizes;
|
||||
ulint sum_of_data_file_sizes;
|
||||
ulint tablespace_size_in_header;
|
||||
ulint err;
|
||||
ulint i;
|
||||
ulint k;
|
||||
@ -1325,6 +1327,32 @@ innobase_start_or_create_for_mysql(void)
|
||||
SRV_MAX_N_IO_THREADS);
|
||||
/* 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);
|
||||
fprintf(stderr, " InnoDB: Started\n");
|
||||
|
||||
|
@ -493,6 +493,34 @@ trx_sys_update_mysql_binlog_offset(
|
||||
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
|
||||
the magic number shows it valid. */
|
||||
|
@ -72,6 +72,7 @@ trx_create(
|
||||
|
||||
trx->type = TRX_USER;
|
||||
trx->conc_state = TRX_NOT_STARTED;
|
||||
trx->start_time = time(NULL);
|
||||
|
||||
trx->check_foreigns = TRUE;
|
||||
trx->check_unique_secondary = TRUE;
|
||||
@ -516,6 +517,7 @@ trx_start_low(
|
||||
if (trx->type == TRX_PURGE) {
|
||||
trx->id = ut_dulint_zero;
|
||||
trx->conc_state = TRX_ACTIVE;
|
||||
trx->start_time = time(NULL);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
@ -539,6 +541,7 @@ trx_start_low(
|
||||
trx->rseg = rseg;
|
||||
|
||||
trx->conc_state = TRX_ACTIVE;
|
||||
trx->start_time = time(NULL);
|
||||
|
||||
UT_LIST_ADD_FIRST(trx_list, trx_sys->trx_list, trx);
|
||||
|
||||
@ -1465,9 +1468,25 @@ trx_print(
|
||||
500 bytes */
|
||||
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_low(trx->id),
|
||||
ut_dulint_get_low(trx->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) {
|
||||
@ -1478,32 +1497,28 @@ trx_print(
|
||||
buf += sprintf(buf, " purge trx");
|
||||
}
|
||||
|
||||
switch (trx->conc_state) {
|
||||
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);
|
||||
}
|
||||
buf += sprintf(buf, "\n");
|
||||
|
||||
start_of_line = buf;
|
||||
|
||||
switch (trx->que_state) {
|
||||
case TRX_QUE_RUNNING: buf += sprintf(buf,
|
||||
", runs or sleeps"); break;
|
||||
case TRX_QUE_RUNNING: break;
|
||||
case TRX_QUE_LOCK_WAIT: buf += sprintf(buf,
|
||||
", lock wait"); break;
|
||||
"LOCK WAIT "); break;
|
||||
case TRX_QUE_ROLLING_BACK: buf += sprintf(buf,
|
||||
", rolling back"); break;
|
||||
"ROLLING BACK "); break;
|
||||
case TRX_QUE_COMMITTING: buf += sprintf(buf,
|
||||
", committing"); break;
|
||||
default: buf += sprintf(buf, " que state %lu", trx->que_state);
|
||||
"COMMITTING "); break;
|
||||
default: buf += sprintf(buf, "que state %lu", trx->que_state);
|
||||
}
|
||||
|
||||
if (0 < UT_LIST_GET_LEN(trx->trx_locks)) {
|
||||
buf += sprintf(buf, ", has %lu lock struct(s)",
|
||||
UT_LIST_GET_LEN(trx->trx_locks));
|
||||
if (0 < UT_LIST_GET_LEN(trx->trx_locks) ||
|
||||
mem_heap_get_size(trx->lock_heap) > 400) {
|
||||
|
||||
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) {
|
||||
@ -1515,7 +1530,10 @@ trx_print(
|
||||
ut_dulint_get_low(trx->undo_no));
|
||||
}
|
||||
|
||||
if (buf != start_of_line) {
|
||||
|
||||
buf += sprintf(buf, "\n");
|
||||
}
|
||||
|
||||
if (trx->mysql_thd != NULL) {
|
||||
innobase_mysql_print_thd(buf, trx->mysql_thd);
|
||||
|
@ -266,10 +266,39 @@ innobase_mysql_print_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 */
|
||||
buf+= my_sprintf(buf,
|
||||
(buf, "MySQL thread id %lu, query id %lu",
|
||||
thd->thread_id, thd->query_id));
|
||||
(buf, "MySQL thread id %lu",
|
||||
thd->thread_id));
|
||||
if (thd->host)
|
||||
{
|
||||
*buf++=' ';
|
||||
@ -296,10 +325,11 @@ innobase_mysql_print_thd(
|
||||
|
||||
if (thd->query)
|
||||
{
|
||||
*buf++=' ';
|
||||
*buf++='\n';
|
||||
buf=strnmov(buf, thd->query, 150);
|
||||
}
|
||||
*buf='\n';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1414,6 +1444,7 @@ ha_innobase::write_row(
|
||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
||||
int error;
|
||||
longlong auto_inc;
|
||||
longlong dummy;
|
||||
|
||||
DBUG_ENTER("ha_innobase::write_row");
|
||||
|
||||
@ -1437,6 +1468,30 @@ ha_innobase::write_row(
|
||||
/* This is the case where the table has an
|
||||
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
|
||||
autoincrement field */
|
||||
|
||||
@ -1469,10 +1524,9 @@ ha_innobase::write_row(
|
||||
}
|
||||
|
||||
if (auto_inc != 0) {
|
||||
/* This call will calculate the max of the
|
||||
current value and the value supplied by the user, if
|
||||
the auto_inc counter is already initialized
|
||||
for the table */
|
||||
/* This call will calculate the max of the current
|
||||
value and the value supplied by the user and
|
||||
update the counter accordingly */
|
||||
|
||||
/* We have to use the transactional lock mechanism
|
||||
on the auto-inc counter of the table to ensure
|
||||
@ -1512,45 +1566,17 @@ ha_innobase::write_row(
|
||||
auto_inc = dict_table_autoinc_get(prebuilt->table);
|
||||
srv_conc_exit_innodb(prebuilt->trx);
|
||||
|
||||
/* If auto_inc is now != 0 the autoinc counter
|
||||
was already initialized for the table: we can give
|
||||
the new value for MySQL to place in the field */
|
||||
/* We can give the new value for MySQL to place in
|
||||
the field */
|
||||
|
||||
if (auto_inc != 0) {
|
||||
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();
|
||||
|
||||
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
|
||||
@ -3572,37 +3598,53 @@ ha_innobase::store_lock(
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Returns the next auto-increment column value for the table. write_row
|
||||
normally fetches the value from the cache in the data dictionary. This
|
||||
function in used by SHOW TABLE STATUS and when the first insert to the table
|
||||
is done after database startup. */
|
||||
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. In parameter ret returns
|
||||
the value of the auto-inc counter. */
|
||||
|
||||
longlong
|
||||
ha_innobase::get_auto_increment()
|
||||
/*=============================*/
|
||||
/* out: the next auto-increment column value */
|
||||
int
|
||||
ha_innobase::innobase_read_and_init_auto_inc(
|
||||
/*=========================================*/
|
||||
/* 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;
|
||||
longlong nr;
|
||||
longlong auto_inc;
|
||||
int error;
|
||||
|
||||
ut_a(prebuilt);
|
||||
ut_a(prebuilt->trx ==
|
||||
(trx_t*) current_thd->transaction.all.innobase_tid);
|
||||
ut_a(prebuilt->table);
|
||||
|
||||
/* Also SHOW TABLE STATUS calls this function. Previously, when we did
|
||||
always read the max autoinc key value, setting x-locks, users were
|
||||
surprised that SHOW TABLE STATUS could end up in a deadlock with
|
||||
ordinary SQL queries. We avoid these deadlocks if the auto-inc
|
||||
counter for the table has been initialized by fetching the value
|
||||
from the table struct in dictionary cache. */
|
||||
auto_inc = dict_table_autoinc_read(prebuilt->table);
|
||||
|
||||
assert(prebuilt->table);
|
||||
if (auto_inc != 0) {
|
||||
/* Already initialized */
|
||||
*ret = auto_inc;
|
||||
|
||||
nr = dict_table_autoinc_read(prebuilt->table);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (nr != 0) {
|
||||
srv_conc_enter_innodb(prebuilt->trx);
|
||||
error = row_lock_table_autoinc_for_mysql(prebuilt);
|
||||
srv_conc_exit_innodb(prebuilt->trx);
|
||||
|
||||
return(nr + 1);
|
||||
if (error != DB_SUCCESS) {
|
||||
error = convert_error_code_to_mysql(error, user_thd);
|
||||
|
||||
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);
|
||||
@ -3627,16 +3669,57 @@ ha_innobase::get_auto_increment()
|
||||
error = index_last(table->record[1]);
|
||||
|
||||
if (error) {
|
||||
nr = 1;
|
||||
if (error == HA_ERR_END_OF_FILE) {
|
||||
/* The table was empty, initialize to 1 */
|
||||
auto_inc = 1;
|
||||
|
||||
error = 0;
|
||||
} else {
|
||||
nr = (longlong) table->next_number_field->
|
||||
/* Deadlock or a lock wait timeout */
|
||||
auto_inc = -1;
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
} else {
|
||||
/* Initialize to max(col) + 1 */
|
||||
auto_inc = (longlong) table->next_number_field->
|
||||
val_int_offset(table->rec_buff_length) + 1;
|
||||
}
|
||||
|
||||
dict_table_autoinc_initialize(prebuilt->table, auto_inc);
|
||||
|
||||
func_exit:
|
||||
(void) extra(HA_EXTRA_NO_KEYREAD);
|
||||
|
||||
index_end();
|
||||
|
||||
*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);
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ class ha_innobase: public handler
|
||||
int update_thd(THD* thd);
|
||||
int change_active_index(uint keynr);
|
||||
int general_fetch(byte* buf, uint direction, uint match_mode);
|
||||
int innobase_read_and_init_auto_inc(longlong* ret);
|
||||
|
||||
/* Init values for the class: */
|
||||
public:
|
||||
|
Reference in New Issue
Block a user