mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Many files:
Small improvements row0mysql.c: Small improvements + fix the ALTER TABLE problem by introducing a lazy drop table it can use ha_innobase.cc: Some fine-tuning of optimization sql/ha_innobase.cc: Some fine-tuning of optimization innobase/include/log0recv.h: Small improvements innobase/include/mem0mem.h: Small improvements innobase/include/mem0pool.h: Small improvements innobase/include/row0mysql.h: Small improvements innobase/include/srv0srv.h: Small improvements innobase/include/trx0trx.h: Small improvements innobase/buf/buf0lru.c: Small improvements innobase/fil/fil0fil.c: Small improvements innobase/log/log0recv.c: Small improvements innobase/mem/mem0mem.c: Small improvements innobase/mem/mem0pool.c: Small improvements innobase/row/row0mysql.c: Small improvements + fix the ALTER TABLE problem by introducing a lazy drop table it can use innobase/srv/srv0srv.c: Small improvements innobase/srv/srv0start.c: Small improvements innobase/trx/trx0purge.c: Small improvements innobase/trx/trx0trx.c: Small improvements
This commit is contained in:
@ -242,7 +242,6 @@ loop:
|
|||||||
if (n_iterations > 30) {
|
if (n_iterations > 30) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" ***********************************************\n"
|
|
||||||
"InnoDB: Warning: difficult to find free blocks from\n"
|
"InnoDB: Warning: difficult to find free blocks from\n"
|
||||||
"InnoDB: the buffer pool (%lu search iterations)! Consider\n"
|
"InnoDB: the buffer pool (%lu search iterations)! Consider\n"
|
||||||
"InnoDB: increasing the buffer pool size.\n",
|
"InnoDB: increasing the buffer pool size.\n",
|
||||||
|
@ -1088,7 +1088,15 @@ loop:
|
|||||||
node = UT_LIST_GET_FIRST(space->chain);
|
node = UT_LIST_GET_FIRST(space->chain);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ut_a(node);
|
if (node == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: Error: trying to access page number %lu in space %lu\n"
|
||||||
|
"InnoDB: which is outside the tablespace bounds.\n"
|
||||||
|
"InnoDB: Byte offset %lu, len %lu, i/o type %lu\n",
|
||||||
|
block_offset, space_id, byte_offset, len, type);
|
||||||
|
|
||||||
|
ut_a(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (node->size > block_offset) {
|
if (node->size > block_offset) {
|
||||||
/* Found! */
|
/* Found! */
|
||||||
|
@ -258,6 +258,7 @@ struct recv_sys_struct{
|
|||||||
extern recv_sys_t* recv_sys;
|
extern recv_sys_t* recv_sys;
|
||||||
extern ibool recv_recovery_on;
|
extern ibool recv_recovery_on;
|
||||||
extern ibool recv_no_ibuf_operations;
|
extern ibool recv_no_ibuf_operations;
|
||||||
|
extern ibool recv_needed_recovery;
|
||||||
|
|
||||||
/* States of recv_addr_struct */
|
/* States of recv_addr_struct */
|
||||||
#define RECV_NOT_PROCESSED 71
|
#define RECV_NOT_PROCESSED 71
|
||||||
|
@ -269,13 +269,24 @@ mem_realloc(
|
|||||||
ulint n, /* in: desired number of bytes */
|
ulint n, /* in: desired number of bytes */
|
||||||
char* file_name,/* in: file name where called */
|
char* file_name,/* in: file name where called */
|
||||||
ulint line); /* in: line where called */
|
ulint line); /* in: line where called */
|
||||||
|
#ifdef MEM_PERIODIC_CHECK
|
||||||
|
/**********************************************************************
|
||||||
|
Goes through the list of all allocated mem blocks, checks their magic
|
||||||
|
numbers, and reports possible corruption. */
|
||||||
|
|
||||||
|
void
|
||||||
|
mem_validate_all_blocks(void);
|
||||||
|
/*=========================*/
|
||||||
|
#endif
|
||||||
|
|
||||||
/*#######################################################################*/
|
/*#######################################################################*/
|
||||||
|
|
||||||
/* The info header of a block in a memory heap */
|
/* The info header of a block in a memory heap */
|
||||||
|
|
||||||
struct mem_block_info_struct {
|
struct mem_block_info_struct {
|
||||||
|
ulint magic_n;/* magic number for debugging */
|
||||||
|
char file_name[8];/* file name where the mem heap was created */
|
||||||
|
ulint line; /* line number where the mem heap was created */
|
||||||
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the
|
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the
|
||||||
the list this is the base node of the list of blocks;
|
the list this is the base node of the list of blocks;
|
||||||
in subsequent blocks this is undefined */
|
in subsequent blocks this is undefined */
|
||||||
@ -299,9 +310,11 @@ struct mem_block_info_struct {
|
|||||||
allocated buffer frame, which can be appended as a
|
allocated buffer frame, which can be appended as a
|
||||||
free block to the heap, if we need more space;
|
free block to the heap, if we need more space;
|
||||||
otherwise, this is NULL */
|
otherwise, this is NULL */
|
||||||
ulint magic_n;/* magic number for debugging */
|
#ifdef MEM_PERIODIC_CHECK
|
||||||
char file_name[8];/* file name where the mem heap was created */
|
UT_LIST_NODE_T(mem_block_t) mem_block_list;
|
||||||
ulint line; /* line number where the mem heap was created */
|
/* List of all mem blocks allocated; protected
|
||||||
|
by the mem_comm_pool mutex */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MEM_BLOCK_MAGIC_N 764741555
|
#define MEM_BLOCK_MAGIC_N 764741555
|
||||||
|
@ -72,6 +72,18 @@ mem_pool_get_reserved(
|
|||||||
/* out: reserved mmeory in bytes */
|
/* out: reserved mmeory in bytes */
|
||||||
mem_pool_t* pool); /* in: memory pool */
|
mem_pool_t* pool); /* in: memory pool */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
Reserves the mem pool mutex. */
|
||||||
|
|
||||||
|
void
|
||||||
|
mem_pool_mutex_enter(void);
|
||||||
|
/*======================*/
|
||||||
|
/************************************************************************
|
||||||
|
Releases the mem pool mutex. */
|
||||||
|
|
||||||
|
void
|
||||||
|
mem_pool_mutex_exit(void);
|
||||||
|
/*=====================*/
|
||||||
|
/************************************************************************
|
||||||
Validates a memory pool. */
|
Validates a memory pool. */
|
||||||
|
|
||||||
ibool
|
ibool
|
||||||
|
@ -251,6 +251,24 @@ row_table_add_foreign_constraints(
|
|||||||
char* name); /* in: table full name in the normalized form
|
char* name); /* in: table full name in the normalized form
|
||||||
database_name/table_name */
|
database_name/table_name */
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
The master thread in srv0srv.c calls this regularly to drop tables which
|
||||||
|
we must drop in background after queries to them have ended. Such lazy
|
||||||
|
dropping of tables is needed in ALTER TABLE on Unix. */
|
||||||
|
|
||||||
|
ulint
|
||||||
|
row_drop_tables_for_mysql_in_background(void);
|
||||||
|
/*=========================================*/
|
||||||
|
/* out: how many tables dropped
|
||||||
|
+ remaining tables in list */
|
||||||
|
/*************************************************************************
|
||||||
|
Get the background drop list length. NOTE: the caller must own the kernel
|
||||||
|
mutex! */
|
||||||
|
|
||||||
|
ulint
|
||||||
|
row_get_background_drop_list_len_low(void);
|
||||||
|
/*======================================*/
|
||||||
|
/* out: how many tables in list */
|
||||||
|
/*************************************************************************
|
||||||
Drops a table for MySQL. If the name of the dropped table ends to
|
Drops a table for MySQL. If the name of the dropped table ends to
|
||||||
characters INNODB_MONITOR, then this also stops printing of monitor
|
characters INNODB_MONITOR, then this also stops printing of monitor
|
||||||
output by the master thread. */
|
output by the master thread. */
|
||||||
|
@ -249,6 +249,12 @@ mutex, for performace reasons). */
|
|||||||
void
|
void
|
||||||
srv_active_wake_master_thread(void);
|
srv_active_wake_master_thread(void);
|
||||||
/*===============================*/
|
/*===============================*/
|
||||||
|
/***********************************************************************
|
||||||
|
Wakes up the master thread if it is suspended or being suspended. */
|
||||||
|
|
||||||
|
void
|
||||||
|
srv_wake_master_thread(void);
|
||||||
|
/*========================*/
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Puts an OS thread to wait if there are too many concurrent threads
|
Puts an OS thread to wait if there are too many concurrent threads
|
||||||
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
|
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
|
||||||
|
@ -50,6 +50,13 @@ trx_allocate_for_mysql(void);
|
|||||||
/*========================*/
|
/*========================*/
|
||||||
/* out, own: transaction object */
|
/* out, own: transaction object */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
Creates a transaction object for background operations by the master thread. */
|
||||||
|
|
||||||
|
trx_t*
|
||||||
|
trx_allocate_for_background(void);
|
||||||
|
/*=============================*/
|
||||||
|
/* out, own: transaction object */
|
||||||
|
/************************************************************************
|
||||||
Frees a transaction object. */
|
Frees a transaction object. */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -63,6 +70,13 @@ void
|
|||||||
trx_free_for_mysql(
|
trx_free_for_mysql(
|
||||||
/*===============*/
|
/*===============*/
|
||||||
trx_t* trx); /* in, own: trx object */
|
trx_t* trx); /* in, own: trx object */
|
||||||
|
/************************************************************************
|
||||||
|
Frees a transaction object of a background operation of the master thread. */
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_free_for_background(
|
||||||
|
/*====================*/
|
||||||
|
trx_t* trx); /* in, own: trx object */
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
Creates trx objects for transactions and initializes the trx list of
|
Creates trx objects for transactions and initializes the trx list of
|
||||||
trx_sys at database start. Rollback segment and undo log lists must
|
trx_sys at database start. Rollback segment and undo log lists must
|
||||||
@ -266,11 +280,14 @@ struct trx_sig_struct{
|
|||||||
transaction is waiting a reply */
|
transaction is waiting a reply */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TRX_MAGIC_N 91118598
|
||||||
|
|
||||||
/* The transaction handle; every session has a trx object which is freed only
|
/* The transaction handle; every session has a trx object which is freed only
|
||||||
when the session is freed; in addition there may be session-less transactions
|
when the session is freed; in addition there may be session-less transactions
|
||||||
rolling back after a database recovery */
|
rolling back after a database recovery */
|
||||||
|
|
||||||
struct trx_struct{
|
struct trx_struct{
|
||||||
|
ulint magic_n;
|
||||||
/* All the next fields are protected by the kernel mutex, except the
|
/* All the next fields are protected by the kernel mutex, except the
|
||||||
undo logs which are protected by undo_mutex */
|
undo logs which are protected by undo_mutex */
|
||||||
char* op_info; /* English text describing the
|
char* op_info; /* English text describing the
|
||||||
|
@ -1020,6 +1020,7 @@ loop:
|
|||||||
|
|
||||||
if (recv_addr->state == RECV_NOT_PROCESSED) {
|
if (recv_addr->state == RECV_NOT_PROCESSED) {
|
||||||
if (!has_printed) {
|
if (!has_printed) {
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Starting an apply batch of log records to the database...\n"
|
" InnoDB: Starting an apply batch of log records to the database...\n"
|
||||||
"InnoDB: Progress in percents: ");
|
"InnoDB: Progress in percents: ");
|
||||||
|
@ -75,6 +75,14 @@ After freeing, all the blocks in the heap are set to random bytes
|
|||||||
to help us discover errors which result from the use of
|
to help us discover errors which result from the use of
|
||||||
buffers in an already freed heap. */
|
buffers in an already freed heap. */
|
||||||
|
|
||||||
|
#ifdef MEM_PERIODIC_CHECK
|
||||||
|
|
||||||
|
ibool mem_block_list_inited;
|
||||||
|
/* List of all mem blocks allocated; protected by the mem_comm_pool mutex */
|
||||||
|
UT_LIST_BASE_NODE_T(mem_block_t) mem_block_list;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
NOTE: Use the corresponding macro instead of this function.
|
NOTE: Use the corresponding macro instead of this function.
|
||||||
Allocates a single buffer of memory from the dynamic memory of
|
Allocates a single buffer of memory from the dynamic memory of
|
||||||
@ -170,6 +178,18 @@ mem_heap_create_block(
|
|||||||
block->file_name[7]='\0';
|
block->file_name[7]='\0';
|
||||||
block->line = line;
|
block->line = line;
|
||||||
|
|
||||||
|
#ifdef MEM_PERIODIC_CHECK
|
||||||
|
mem_pool_mutex_enter();
|
||||||
|
|
||||||
|
if (!mem_block_list_inited) {
|
||||||
|
mem_block_list_inited = TRUE;
|
||||||
|
UT_LIST_INIT(mem_block_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
UT_LIST_ADD_LAST(mem_block_list, mem_block_list, block);
|
||||||
|
|
||||||
|
mem_pool_mutex_exit();
|
||||||
|
#endif
|
||||||
mem_block_set_len(block, len);
|
mem_block_set_len(block, len);
|
||||||
mem_block_set_type(block, type);
|
mem_block_set_type(block, type);
|
||||||
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
|
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
|
||||||
@ -261,6 +281,13 @@ mem_heap_block_free(
|
|||||||
|
|
||||||
UT_LIST_REMOVE(list, heap->base, block);
|
UT_LIST_REMOVE(list, heap->base, block);
|
||||||
|
|
||||||
|
#ifdef MEM_PERIODIC_CHECK
|
||||||
|
mem_pool_mutex_enter();
|
||||||
|
|
||||||
|
UT_LIST_REMOVE(mem_block_list, mem_block_list, block);
|
||||||
|
|
||||||
|
mem_pool_mutex_exit();
|
||||||
|
#endif
|
||||||
type = heap->type;
|
type = heap->type;
|
||||||
len = block->len;
|
len = block->len;
|
||||||
init_block = block->init_block;
|
init_block = block->init_block;
|
||||||
@ -306,3 +333,30 @@ mem_heap_free_block_free(
|
|||||||
heap->free_block = NULL;
|
heap->free_block = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MEM_PERIODIC_CHECK
|
||||||
|
/**********************************************************************
|
||||||
|
Goes through the list of all allocated mem blocks, checks their magic
|
||||||
|
numbers, and reports possible corruption. */
|
||||||
|
|
||||||
|
void
|
||||||
|
mem_validate_all_blocks(void)
|
||||||
|
/*=========================*/
|
||||||
|
{
|
||||||
|
mem_block_t* block;
|
||||||
|
|
||||||
|
mem_pool_mutex_enter();
|
||||||
|
|
||||||
|
block = UT_LIST_GET_FIRST(mem_block_list);
|
||||||
|
|
||||||
|
while (block) {
|
||||||
|
if (block->magic_n != MEM_BLOCK_MAGIC_N) {
|
||||||
|
mem_analyze_corruption((byte*)block);
|
||||||
|
}
|
||||||
|
|
||||||
|
block = UT_LIST_GET_NEXT(mem_block_list, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_pool_mutex_exit();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -78,9 +78,9 @@ pool, and after that its locks will grow into the buffer pool. */
|
|||||||
/* The smallest memory area total size */
|
/* The smallest memory area total size */
|
||||||
#define MEM_AREA_MIN_SIZE (2 * MEM_AREA_EXTRA_SIZE)
|
#define MEM_AREA_MIN_SIZE (2 * MEM_AREA_EXTRA_SIZE)
|
||||||
|
|
||||||
|
|
||||||
/* Data structure for a memory pool. The space is allocated using the buddy
|
/* Data structure for a memory pool. The space is allocated using the buddy
|
||||||
algorithm, where free list i contains areas of size 2 to power i. */
|
algorithm, where free list i contains areas of size 2 to power i. */
|
||||||
|
|
||||||
struct mem_pool_struct{
|
struct mem_pool_struct{
|
||||||
byte* buf; /* memory pool */
|
byte* buf; /* memory pool */
|
||||||
ulint size; /* memory common pool size */
|
ulint size; /* memory common pool size */
|
||||||
@ -98,6 +98,26 @@ mem_pool_t* mem_comm_pool = NULL;
|
|||||||
|
|
||||||
ulint mem_out_of_mem_err_msg_count = 0;
|
ulint mem_out_of_mem_err_msg_count = 0;
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
Reserves the mem pool mutex. */
|
||||||
|
|
||||||
|
void
|
||||||
|
mem_pool_mutex_enter(void)
|
||||||
|
/*======================*/
|
||||||
|
{
|
||||||
|
mutex_enter(&(mem_comm_pool->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
Releases the mem pool mutex. */
|
||||||
|
|
||||||
|
void
|
||||||
|
mem_pool_mutex_exit(void)
|
||||||
|
/*=====================*/
|
||||||
|
{
|
||||||
|
mutex_exit(&(mem_comm_pool->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Returns memory area size. */
|
Returns memory area size. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
@ -241,14 +261,14 @@ mem_pool_fill_free_list(
|
|||||||
if (mem_out_of_mem_err_msg_count % 1000000000 == 0) {
|
if (mem_out_of_mem_err_msg_count % 1000000000 == 0) {
|
||||||
/* We do not print the message every time: */
|
/* We do not print the message every time: */
|
||||||
|
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Innobase: Warning: out of memory in additional memory pool.\n");
|
" InnoDB: Out of memory in additional memory pool.\n"
|
||||||
fprintf(stderr,
|
"InnoDB: InnoDB will start allocating memory from the OS.\n"
|
||||||
"Innobase: Innobase will start allocating memory from the OS.\n");
|
"InnoDB: You may get better performance if you configure a bigger\n"
|
||||||
fprintf(stderr,
|
"InnoDB: value in the MySQL my.cnf file for\n"
|
||||||
"Innobase: You should restart the database with a bigger value in\n");
|
"InnoDB: innodb_additional_mem_pool_size.\n");
|
||||||
fprintf(stderr,
|
|
||||||
"Innobase: the MySQL .cnf file for innobase_additional_mem_pool_size.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_out_of_mem_err_msg_count++;
|
mem_out_of_mem_err_msg_count++;
|
||||||
|
@ -26,6 +26,19 @@ Created 9/17/2000 Heikki Tuuri
|
|||||||
#include "trx0purge.h"
|
#include "trx0purge.h"
|
||||||
#include "lock0lock.h"
|
#include "lock0lock.h"
|
||||||
#include "rem0cmp.h"
|
#include "rem0cmp.h"
|
||||||
|
#include "log0log.h"
|
||||||
|
|
||||||
|
/* List of tables we should drop in background. ALTER TABLE in MySQL requires
|
||||||
|
that the table handler can drop the table in background when there are no
|
||||||
|
queries to it any more. Protected by the kernel mutex. */
|
||||||
|
typedef struct row_mysql_drop_struct row_mysql_drop_t;
|
||||||
|
struct row_mysql_drop_struct{
|
||||||
|
char* table_name;
|
||||||
|
UT_LIST_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
|
||||||
|
ibool row_mysql_drop_list_inited = FALSE;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Reads a MySQL format variable-length field (like VARCHAR) length and
|
Reads a MySQL format variable-length field (like VARCHAR) length and
|
||||||
@ -172,10 +185,22 @@ handle_new_error:
|
|||||||
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
||||||
}
|
}
|
||||||
} else if (err == DB_TOO_BIG_RECORD) {
|
} else if (err == DB_TOO_BIG_RECORD) {
|
||||||
|
if (savept) {
|
||||||
|
/* Roll back the latest, possibly incomplete
|
||||||
|
insertion or update */
|
||||||
|
|
||||||
|
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
||||||
|
}
|
||||||
/* MySQL will roll back the latest SQL statement */
|
/* MySQL will roll back the latest SQL statement */
|
||||||
} else if (err == DB_ROW_IS_REFERENCED
|
} else if (err == DB_ROW_IS_REFERENCED
|
||||||
|| err == DB_NO_REFERENCED_ROW
|
|| err == DB_NO_REFERENCED_ROW
|
||||||
|| err == DB_CANNOT_ADD_CONSTRAINT) {
|
|| err == DB_CANNOT_ADD_CONSTRAINT) {
|
||||||
|
if (savept) {
|
||||||
|
/* Roll back the latest, possibly incomplete
|
||||||
|
insertion or update */
|
||||||
|
|
||||||
|
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
||||||
|
}
|
||||||
/* MySQL will roll back the latest SQL statement */
|
/* MySQL will roll back the latest SQL statement */
|
||||||
} else if (err == DB_LOCK_WAIT) {
|
} else if (err == DB_LOCK_WAIT) {
|
||||||
|
|
||||||
@ -200,6 +225,12 @@ handle_new_error:
|
|||||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||||
|
|
||||||
} else if (err == DB_OUT_OF_FILE_SPACE) {
|
} else if (err == DB_OUT_OF_FILE_SPACE) {
|
||||||
|
if (savept) {
|
||||||
|
/* Roll back the latest, possibly incomplete
|
||||||
|
insertion or update */
|
||||||
|
|
||||||
|
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
||||||
|
}
|
||||||
/* MySQL will roll back the latest SQL statement */
|
/* MySQL will roll back the latest SQL statement */
|
||||||
|
|
||||||
} else if (err == DB_MUST_GET_MORE_FILE_SPACE) {
|
} else if (err == DB_MUST_GET_MORE_FILE_SPACE) {
|
||||||
@ -375,13 +406,13 @@ row_update_prebuilt_trx(
|
|||||||
handle */
|
handle */
|
||||||
trx_t* trx) /* in: transaction handle */
|
trx_t* trx) /* in: transaction handle */
|
||||||
{
|
{
|
||||||
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
if (trx->magic_n != TRX_MAGIC_N) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: trying to free a corrupt\n"
|
"InnoDB: Error: trying to use a corrupt\n"
|
||||||
"InnoDB: table handle. Magic n %lu, table name %s\n",
|
"InnoDB: trx handle. Magic n %lu\n",
|
||||||
prebuilt->magic_n, prebuilt->table->name);
|
trx->magic_n);
|
||||||
|
|
||||||
mem_analyze_corruption((byte*)prebuilt);
|
mem_analyze_corruption((byte*)trx);
|
||||||
|
|
||||||
ut_a(0);
|
ut_a(0);
|
||||||
}
|
}
|
||||||
@ -1170,6 +1201,9 @@ row_create_table_for_mysql(
|
|||||||
row_drop_table_for_mysql(table->name, trx, TRUE);
|
row_drop_table_for_mysql(table->name, trx, TRUE);
|
||||||
} else {
|
} else {
|
||||||
ut_a(err == DB_DUPLICATE_KEY);
|
ut_a(err == DB_DUPLICATE_KEY);
|
||||||
|
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Error: table %s already exists in InnoDB internal\n"
|
" InnoDB: Error: table %s already exists in InnoDB internal\n"
|
||||||
"InnoDB: data dictionary. Have you deleted the .frm file\n"
|
"InnoDB: data dictionary. Have you deleted the .frm file\n"
|
||||||
@ -1349,6 +1383,164 @@ row_table_add_foreign_constraints(
|
|||||||
return((int) err);
|
return((int) err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Drops a table for MySQL as a background operation. MySQL relies on Unix
|
||||||
|
in ALTER TABLE to the fact that the table handler does not remove the
|
||||||
|
table before all handles to it has been removed. Furhermore, the MySQL's
|
||||||
|
call to drop table must be non-blocking. Therefore we do the drop table
|
||||||
|
as a background operation, which is taken care of by the master thread
|
||||||
|
in srv0srv.c. */
|
||||||
|
static
|
||||||
|
int
|
||||||
|
row_drop_table_for_mysql_in_background(
|
||||||
|
/*===================================*/
|
||||||
|
/* out: error code or DB_SUCCESS */
|
||||||
|
char* name) /* in: table name */
|
||||||
|
{
|
||||||
|
ulint error;
|
||||||
|
trx_t* trx;
|
||||||
|
|
||||||
|
trx = trx_allocate_for_background();
|
||||||
|
|
||||||
|
/* fprintf(stderr, "InnoDB: Dropping table %s in background drop list\n",
|
||||||
|
name); */
|
||||||
|
/* Drop the table in InnoDB */
|
||||||
|
|
||||||
|
error = row_drop_table_for_mysql(name, trx, FALSE);
|
||||||
|
|
||||||
|
if (error != DB_SUCCESS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: Error: Dropping table %s in background drop list failed\n",
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush the log to reduce probability that the .frm files and
|
||||||
|
the InnoDB data dictionary get out-of-sync if the user runs
|
||||||
|
with innodb_flush_log_at_trx_commit = 0 */
|
||||||
|
|
||||||
|
log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
|
||||||
|
|
||||||
|
trx_commit_for_mysql(trx);
|
||||||
|
|
||||||
|
trx_free_for_background(trx);
|
||||||
|
|
||||||
|
return(DB_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
The master thread in srv0srv.c calls this regularly to drop tables which
|
||||||
|
we must drop in background after queries to them have ended. Such lazy
|
||||||
|
dropping of tables is needed in ALTER TABLE on Unix. */
|
||||||
|
|
||||||
|
ulint
|
||||||
|
row_drop_tables_for_mysql_in_background(void)
|
||||||
|
/*=========================================*/
|
||||||
|
/* out: how many tables dropped
|
||||||
|
+ remaining tables in list */
|
||||||
|
{
|
||||||
|
row_mysql_drop_t* drop;
|
||||||
|
dict_table_t* table;
|
||||||
|
ulint n_tables;
|
||||||
|
ulint n_tables_dropped = 0;
|
||||||
|
loop:
|
||||||
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
|
if (!row_mysql_drop_list_inited) {
|
||||||
|
|
||||||
|
UT_LIST_INIT(row_mysql_drop_list);
|
||||||
|
row_mysql_drop_list_inited = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
drop = UT_LIST_GET_FIRST(row_mysql_drop_list);
|
||||||
|
|
||||||
|
n_tables = UT_LIST_GET_LEN(row_mysql_drop_list);
|
||||||
|
|
||||||
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
|
if (drop == NULL) {
|
||||||
|
|
||||||
|
return(n_tables + n_tables_dropped);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_enter(&(dict_sys->mutex));
|
||||||
|
table = dict_table_get_low(drop->table_name);
|
||||||
|
mutex_exit(&(dict_sys->mutex));
|
||||||
|
|
||||||
|
if (table->n_mysql_handles_opened > 0) {
|
||||||
|
|
||||||
|
return(n_tables + n_tables_dropped);
|
||||||
|
}
|
||||||
|
|
||||||
|
n_tables_dropped++;
|
||||||
|
|
||||||
|
row_drop_table_for_mysql_in_background(drop->table_name);
|
||||||
|
|
||||||
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
|
UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop);
|
||||||
|
|
||||||
|
mem_free(drop->table_name);
|
||||||
|
|
||||||
|
mem_free(drop);
|
||||||
|
|
||||||
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Get the background drop list length. NOTE: the caller must own the kernel
|
||||||
|
mutex! */
|
||||||
|
|
||||||
|
ulint
|
||||||
|
row_get_background_drop_list_len_low(void)
|
||||||
|
/*======================================*/
|
||||||
|
/* out: how many tables in list */
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
|
||||||
|
if (!row_mysql_drop_list_inited) {
|
||||||
|
|
||||||
|
UT_LIST_INIT(row_mysql_drop_list);
|
||||||
|
row_mysql_drop_list_inited = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(UT_LIST_GET_LEN(row_mysql_drop_list));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Adds a table to the list of tables which the master thread drops in
|
||||||
|
background. We need this on Unix because in ALTER TABLE MySQL may call
|
||||||
|
drop table even if the table has running queries on it. */
|
||||||
|
static
|
||||||
|
void
|
||||||
|
row_add_table_to_background_drop_list(
|
||||||
|
/*==================================*/
|
||||||
|
dict_table_t* table) /* in: table */
|
||||||
|
{
|
||||||
|
row_mysql_drop_t* drop;
|
||||||
|
|
||||||
|
drop = mem_alloc(sizeof(row_mysql_drop_t));
|
||||||
|
|
||||||
|
drop->table_name = mem_alloc(1 + ut_strlen(table->name));
|
||||||
|
|
||||||
|
ut_memcpy(drop->table_name, table->name, 1 + ut_strlen(table->name));
|
||||||
|
|
||||||
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
|
if (!row_mysql_drop_list_inited) {
|
||||||
|
|
||||||
|
UT_LIST_INIT(row_mysql_drop_list);
|
||||||
|
row_mysql_drop_list_inited = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
|
||||||
|
|
||||||
|
/* fprintf(stderr, "InnoDB: Adding table %s to background drop list\n",
|
||||||
|
drop->table_name); */
|
||||||
|
mutex_exit(&kernel_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Drops a table for MySQL. If the name of the dropped table ends to
|
Drops a table for MySQL. If the name of the dropped table ends to
|
||||||
characters INNODB_MONITOR, then this also stops printing of monitor
|
characters INNODB_MONITOR, then this also stops printing of monitor
|
||||||
@ -1536,6 +1728,7 @@ row_drop_table_for_mysql(
|
|||||||
|
|
||||||
if (!table) {
|
if (!table) {
|
||||||
err = DB_TABLE_NOT_FOUND;
|
err = DB_TABLE_NOT_FOUND;
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Error: table %s does not exist in the InnoDB internal\n"
|
" InnoDB: Error: table %s does not exist in the InnoDB internal\n"
|
||||||
@ -1546,41 +1739,18 @@ row_drop_table_for_mysql(
|
|||||||
goto funct_exit;
|
goto funct_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (table->n_mysql_handles_opened > 0) {
|
||||||
|
|
||||||
|
row_add_table_to_background_drop_list(table);
|
||||||
|
|
||||||
|
err = DB_SUCCESS;
|
||||||
|
|
||||||
|
goto funct_exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove any locks there are on the table or its records */
|
/* Remove any locks there are on the table or its records */
|
||||||
|
|
||||||
lock_reset_all_on_table(table);
|
lock_reset_all_on_table(table);
|
||||||
loop:
|
|
||||||
if (table->n_mysql_handles_opened > 0) {
|
|
||||||
rw_lock_s_unlock(&(purge_sys->purge_is_running));
|
|
||||||
|
|
||||||
rw_lock_x_unlock(&(dict_foreign_key_check_lock));
|
|
||||||
|
|
||||||
mutex_exit(&(dict_sys->mutex));
|
|
||||||
|
|
||||||
if (rounds > 60) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"InnoDB: waiting for queries to table %s to end before dropping it\n",
|
|
||||||
name);
|
|
||||||
}
|
|
||||||
|
|
||||||
os_thread_sleep(1000000);
|
|
||||||
|
|
||||||
mutex_enter(&(dict_sys->mutex));
|
|
||||||
|
|
||||||
rw_lock_x_lock(&(dict_foreign_key_check_lock));
|
|
||||||
|
|
||||||
rw_lock_s_lock(&(purge_sys->purge_is_running));
|
|
||||||
|
|
||||||
rounds++;
|
|
||||||
|
|
||||||
if (rounds > 120) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"InnoDB: Warning: queries to table %s have not ended but we continue anyway\n",
|
|
||||||
name);
|
|
||||||
} else {
|
|
||||||
goto loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trx->dict_operation = TRUE;
|
trx->dict_operation = TRUE;
|
||||||
trx->table_id = table->id;
|
trx->table_id = table->id;
|
||||||
@ -1617,6 +1787,8 @@ funct_exit:
|
|||||||
|
|
||||||
trx->op_info = "";
|
trx->op_info = "";
|
||||||
|
|
||||||
|
srv_wake_master_thread();
|
||||||
|
|
||||||
return((int) err);
|
return((int) err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1788,7 +1960,31 @@ row_rename_table_for_mysql(
|
|||||||
err = trx->error_state;
|
err = trx->error_state;
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
row_mysql_handle_errors(&err, trx, thr, NULL);
|
if (err == DB_DUPLICATE_KEY) {
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
" InnoDB: Error: table %s exists in the InnoDB internal data\n"
|
||||||
|
"InnoDB: dictionary though MySQL is trying rename table %s to it.\n"
|
||||||
|
"InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n",
|
||||||
|
new_name, old_name);
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: If table %s is a temporary table #sql..., then it can be that\n"
|
||||||
|
"InnoDB: there are still queries running on the table, and it will be\n"
|
||||||
|
"InnoDB: dropped automatically when the queries end.\n", new_name);
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: You can drop the orphaned table inside InnoDB by\n"
|
||||||
|
"InnoDB: creating an InnoDB table with the same name in another\n"
|
||||||
|
"InnoDB: database and moving the .frm file to the current database.\n"
|
||||||
|
"InnoDB: Then MySQL thinks the table exists, and DROP TABLE will\n"
|
||||||
|
"InnoDB: succeed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
trx->error_state = DB_SUCCESS;
|
||||||
|
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||||
|
trx->error_state = DB_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
ut_a(dict_table_rename_in_cache(table, new_name));
|
ut_a(dict_table_rename_in_cache(table, new_name));
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ Windows 2000 will have something called thread pooling
|
|||||||
Another possibility could be to use some very fast user space
|
Another possibility could be to use some very fast user space
|
||||||
thread library. This might confuse NT though.
|
thread library. This might confuse NT though.
|
||||||
|
|
||||||
(c) 1995 InnoDB Oy
|
(c) 1995 Innobase Oy
|
||||||
|
|
||||||
Created 10/8/1995 Heikki Tuuri
|
Created 10/8/1995 Heikki Tuuri
|
||||||
*******************************************************/
|
*******************************************************/
|
||||||
@ -49,6 +49,7 @@ Created 10/8/1995 Heikki Tuuri
|
|||||||
#include "btr0sea.h"
|
#include "btr0sea.h"
|
||||||
#include "dict0load.h"
|
#include "dict0load.h"
|
||||||
#include "srv0start.h"
|
#include "srv0start.h"
|
||||||
|
#include "row0mysql.h"
|
||||||
|
|
||||||
/* Buffer which can be used in printing fatal error messages */
|
/* Buffer which can be used in printing fatal error messages */
|
||||||
char srv_fatal_errbuf[5000];
|
char srv_fatal_errbuf[5000];
|
||||||
@ -1911,17 +1912,12 @@ srv_boot(void)
|
|||||||
|
|
||||||
srv_init();
|
srv_init();
|
||||||
|
|
||||||
/* Reserve the first slot for the current thread, i.e., the master
|
|
||||||
thread */
|
|
||||||
|
|
||||||
srv_table_reserve_slot(SRV_MASTER);
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Reserves a slot in the thread table for the current MySQL OS thread.
|
Reserves a slot in the thread table for the current MySQL OS thread.
|
||||||
NOTE! The server mutex has to be reserved by the caller! */
|
NOTE! The kernel mutex has to be reserved by the caller! */
|
||||||
static
|
static
|
||||||
srv_slot_t*
|
srv_slot_t*
|
||||||
srv_table_reserve_slot_for_mysql(void)
|
srv_table_reserve_slot_for_mysql(void)
|
||||||
@ -1931,6 +1927,8 @@ srv_table_reserve_slot_for_mysql(void)
|
|||||||
srv_slot_t* slot;
|
srv_slot_t* slot;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
slot = srv_mysql_table + i;
|
slot = srv_mysql_table + i;
|
||||||
|
|
||||||
@ -2352,6 +2350,22 @@ srv_active_wake_master_thread(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Wakes up the master thread if it is suspended or being suspended. */
|
||||||
|
|
||||||
|
void
|
||||||
|
srv_wake_master_thread(void)
|
||||||
|
/*========================*/
|
||||||
|
{
|
||||||
|
srv_activity_count++;
|
||||||
|
|
||||||
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
|
srv_release_threads(SRV_MASTER, 1);
|
||||||
|
|
||||||
|
mutex_exit(&kernel_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
The master thread controlling the server. */
|
The master thread controlling the server. */
|
||||||
|
|
||||||
@ -2374,6 +2388,7 @@ srv_master_thread(
|
|||||||
ulint n_bytes_merged;
|
ulint n_bytes_merged;
|
||||||
ulint n_pages_flushed;
|
ulint n_pages_flushed;
|
||||||
ulint n_bytes_archived;
|
ulint n_bytes_archived;
|
||||||
|
ulint n_tables_to_drop;
|
||||||
ulint n_ios;
|
ulint n_ios;
|
||||||
ulint n_ios_old;
|
ulint n_ios_old;
|
||||||
ulint n_ios_very_old;
|
ulint n_ios_very_old;
|
||||||
@ -2415,7 +2430,11 @@ loop:
|
|||||||
can drop tables lazily after there no longer are SELECT
|
can drop tables lazily after there no longer are SELECT
|
||||||
queries to them. */
|
queries to them. */
|
||||||
|
|
||||||
/* row_drop_tables_for_mysql_in_background(); */
|
srv_main_thread_op_info = "doing background drop tables";
|
||||||
|
|
||||||
|
row_drop_tables_for_mysql_in_background();
|
||||||
|
|
||||||
|
srv_main_thread_op_info = "";
|
||||||
|
|
||||||
if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
|
if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
|
||||||
|
|
||||||
@ -2465,6 +2484,11 @@ loop:
|
|||||||
printf("Master thread wakes up!\n");
|
printf("Master thread wakes up!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MEM_PERIODIC_CHECK
|
||||||
|
/* Check magic numbers of every allocated mem block once in 10
|
||||||
|
seconds */
|
||||||
|
mem_validate_all_blocks();
|
||||||
|
#endif
|
||||||
/* If there were less than 200 i/os during the 10 second period,
|
/* If there were less than 200 i/os during the 10 second period,
|
||||||
we assume that there is free disk i/o capacity available, and it
|
we assume that there is free disk i/o capacity available, and it
|
||||||
makes sense to do a buffer pool flush. */
|
makes sense to do a buffer pool flush. */
|
||||||
@ -2521,6 +2545,12 @@ background_loop:
|
|||||||
/* In this loop we run background operations when the server
|
/* In this loop we run background operations when the server
|
||||||
is quiet and we also come here about once in 10 seconds */
|
is quiet and we also come here about once in 10 seconds */
|
||||||
|
|
||||||
|
srv_main_thread_op_info = "doing background drop tables";
|
||||||
|
|
||||||
|
n_tables_to_drop = row_drop_tables_for_mysql_in_background();
|
||||||
|
|
||||||
|
srv_main_thread_op_info = "";
|
||||||
|
|
||||||
srv_main_thread_op_info = "flushing buffer pool pages";
|
srv_main_thread_op_info = "flushing buffer pool pages";
|
||||||
|
|
||||||
/* Flush a few oldest pages to make the checkpoint younger */
|
/* Flush a few oldest pages to make the checkpoint younger */
|
||||||
@ -2604,11 +2634,13 @@ background_loop:
|
|||||||
log_archive_do(FALSE, &n_bytes_archived);
|
log_archive_do(FALSE, &n_bytes_archived);
|
||||||
|
|
||||||
if (srv_fast_shutdown && srv_shutdown_state > 0) {
|
if (srv_fast_shutdown && srv_shutdown_state > 0) {
|
||||||
if (n_pages_flushed + n_bytes_archived != 0) {
|
if (n_tables_to_drop + n_pages_flushed
|
||||||
|
+ n_bytes_archived != 0) {
|
||||||
|
|
||||||
goto background_loop;
|
goto background_loop;
|
||||||
}
|
}
|
||||||
} else if (n_pages_purged + n_bytes_merged + n_pages_flushed
|
} else if (n_tables_to_drop +
|
||||||
|
n_pages_purged + n_bytes_merged + n_pages_flushed
|
||||||
+ n_bytes_archived != 0) {
|
+ n_bytes_archived != 0) {
|
||||||
goto background_loop;
|
goto background_loop;
|
||||||
}
|
}
|
||||||
@ -2627,6 +2659,12 @@ suspend_thread:
|
|||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
|
if (row_get_background_drop_list_len_low() > 0) {
|
||||||
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
|
||||||
event = srv_suspend_thread();
|
event = srv_suspend_thread();
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
@ -270,6 +270,8 @@ open_or_create_log_file(
|
|||||||
} else {
|
} else {
|
||||||
*log_file_created = TRUE;
|
*log_file_created = TRUE;
|
||||||
|
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Log file %s did not exist: new to be created\n",
|
" InnoDB: Log file %s did not exist: new to be created\n",
|
||||||
name);
|
name);
|
||||||
@ -277,6 +279,9 @@ open_or_create_log_file(
|
|||||||
name, srv_log_file_size
|
name, srv_log_file_size
|
||||||
>> (20 - UNIV_PAGE_SIZE_SHIFT));
|
>> (20 - UNIV_PAGE_SIZE_SHIFT));
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"InnoDB: Database physically writes the file full: wait...\n");
|
||||||
|
|
||||||
ret = os_file_set_size(name, files[i],
|
ret = os_file_set_size(name, files[i],
|
||||||
srv_calc_low32(srv_log_file_size),
|
srv_calc_low32(srv_log_file_size),
|
||||||
srv_calc_high32(srv_log_file_size));
|
srv_calc_high32(srv_log_file_size));
|
||||||
@ -454,6 +459,7 @@ open_or_create_data_files(
|
|||||||
one_created = TRUE;
|
one_created = TRUE;
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Data file %s did not exist: new to be created\n",
|
" InnoDB: Data file %s did not exist: new to be created\n",
|
||||||
name);
|
name);
|
||||||
@ -464,6 +470,7 @@ open_or_create_data_files(
|
|||||||
*create_new_db = TRUE;
|
*create_new_db = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Setting file %s size to %lu MB\n",
|
" InnoDB: Setting file %s size to %lu MB\n",
|
||||||
name, (srv_data_file_sizes[i]
|
name, (srv_data_file_sizes[i]
|
||||||
@ -905,6 +912,12 @@ innobase_start_or_create_for_mysql(void)
|
|||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (recv_needed_recovery) {
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
|
fprintf(stderr,
|
||||||
|
" InnoDB: Flushing modified pages from the buffer pool...\n");
|
||||||
|
}
|
||||||
|
|
||||||
log_make_checkpoint_at(ut_dulint_max, TRUE);
|
log_make_checkpoint_at(ut_dulint_max, TRUE);
|
||||||
|
|
||||||
if (!srv_log_archive_on) {
|
if (!srv_log_archive_on) {
|
||||||
@ -983,7 +996,6 @@ innobase_shutdown_for_mysql(void)
|
|||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Warning: shutting down a not properly started\n");
|
" InnoDB: Warning: shutting down a not properly started\n");
|
||||||
ut_print_timestamp(stderr);
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: or created database!\n");
|
" InnoDB: or created database!\n");
|
||||||
}
|
}
|
||||||
|
@ -226,9 +226,9 @@ trx_purge_sys_create(void)
|
|||||||
value */
|
value */
|
||||||
purge_sys->sess = sess_open(com_endpoint, (byte*)"purge_system", 13);
|
purge_sys->sess = sess_open(com_endpoint, (byte*)"purge_system", 13);
|
||||||
|
|
||||||
purge_sys->trx = (purge_sys->sess)->trx;
|
purge_sys->trx = purge_sys->sess->trx;
|
||||||
|
|
||||||
(purge_sys->trx)->type = TRX_PURGE;
|
purge_sys->trx->type = TRX_PURGE;
|
||||||
|
|
||||||
ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));
|
ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
|
|
||||||
/* Copy of the prototype for innobase_mysql_print_thd: this
|
/* Copy of the prototype for innobase_mysql_print_thd: this
|
||||||
copy must be equal to the one in mysql/sql/ha_innobase.cc ! */
|
copy must be equal to the one in mysql/sql/ha_innobase.cc ! */
|
||||||
void innobase_mysql_print_thd(void* thd);
|
|
||||||
|
|
||||||
|
void innobase_mysql_print_thd(void* thd);
|
||||||
|
|
||||||
/* Dummy session used currently in MySQL interface */
|
/* Dummy session used currently in MySQL interface */
|
||||||
sess_t* trx_dummy_sess = NULL;
|
sess_t* trx_dummy_sess = NULL;
|
||||||
@ -64,6 +64,8 @@ trx_create(
|
|||||||
|
|
||||||
trx = mem_alloc(sizeof(trx_t));
|
trx = mem_alloc(sizeof(trx_t));
|
||||||
|
|
||||||
|
trx->magic_n = TRX_MAGIC_N;
|
||||||
|
|
||||||
trx->op_info = "";
|
trx->op_info = "";
|
||||||
|
|
||||||
trx->type = TRX_USER;
|
trx->type = TRX_USER;
|
||||||
@ -157,6 +159,32 @@ trx_allocate_for_mysql(void)
|
|||||||
return(trx);
|
return(trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
Creates a transaction object for background operations by the master thread. */
|
||||||
|
|
||||||
|
trx_t*
|
||||||
|
trx_allocate_for_background(void)
|
||||||
|
/*=============================*/
|
||||||
|
/* out, own: transaction object */
|
||||||
|
{
|
||||||
|
trx_t* trx;
|
||||||
|
|
||||||
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
|
/* Open a dummy session */
|
||||||
|
|
||||||
|
if (!trx_dummy_sess) {
|
||||||
|
trx_dummy_sess = sess_open(NULL, (byte*)"Dummy sess",
|
||||||
|
ut_strlen("Dummy sess"));
|
||||||
|
}
|
||||||
|
|
||||||
|
trx = trx_create(trx_dummy_sess);
|
||||||
|
|
||||||
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
|
return(trx);
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Releases the search latch if trx has reserved it. */
|
Releases the search latch if trx has reserved it. */
|
||||||
|
|
||||||
@ -181,6 +209,11 @@ trx_free(
|
|||||||
trx_t* trx) /* in, own: trx object */
|
trx_t* trx) /* in, own: trx object */
|
||||||
{
|
{
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
|
||||||
|
ut_a(trx->magic_n == TRX_MAGIC_N);
|
||||||
|
|
||||||
|
trx->magic_n = 11112222;
|
||||||
|
|
||||||
ut_a(trx->conc_state == TRX_NOT_STARTED);
|
ut_a(trx->conc_state == TRX_NOT_STARTED);
|
||||||
|
|
||||||
mutex_free(&(trx->undo_mutex));
|
mutex_free(&(trx->undo_mutex));
|
||||||
@ -242,6 +275,21 @@ trx_free_for_mysql(
|
|||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
Frees a transaction object of a background operation of the master thread. */
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_free_for_background(
|
||||||
|
/*====================*/
|
||||||
|
trx_t* trx) /* in, own: trx object */
|
||||||
|
{
|
||||||
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
|
trx_free(trx);
|
||||||
|
|
||||||
|
mutex_exit(&kernel_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
Inserts the trx handle in the trx system trx list in the right position.
|
Inserts the trx handle in the trx system trx list in the right position.
|
||||||
The list is sorted on the trx id so that the biggest id is at the list
|
The list is sorted on the trx id so that the biggest id is at the list
|
||||||
|
@ -229,7 +229,7 @@ convert_error_code_to_mysql(
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
Prints info of a THD object (== user session thread) to the
|
Prints info of a THD object (== user session thread) to the
|
||||||
standatd output. NOTE that mysql/innobase/trx/trx0trx.c must contain
|
standard output. NOTE that mysql/innobase/trx/trx0trx.c must contain
|
||||||
the prototype for this function! */
|
the prototype for this function! */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -298,6 +298,8 @@ check_trx_exists(
|
|||||||
|
|
||||||
thd->transaction.stmt.innobase_tid =
|
thd->transaction.stmt.innobase_tid =
|
||||||
(void*)&innodb_dummy_stmt_trx_handle;
|
(void*)&innodb_dummy_stmt_trx_handle;
|
||||||
|
} else {
|
||||||
|
ut_a(trx->magic_n == TRX_MAGIC_N);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(trx);
|
return(trx);
|
||||||
@ -835,6 +837,7 @@ innobase_close_connection(
|
|||||||
whose transaction should be rolled back */
|
whose transaction should be rolled back */
|
||||||
{
|
{
|
||||||
if (NULL != thd->transaction.all.innobase_tid) {
|
if (NULL != thd->transaction.all.innobase_tid) {
|
||||||
|
|
||||||
trx_rollback_for_mysql((trx_t*)
|
trx_rollback_for_mysql((trx_t*)
|
||||||
(thd->transaction.all.innobase_tid));
|
(thd->transaction.all.innobase_tid));
|
||||||
trx_free_for_mysql((trx_t*)
|
trx_free_for_mysql((trx_t*)
|
||||||
@ -2435,44 +2438,6 @@ ha_innobase::position(
|
|||||||
ref_stored_len = len;
|
ref_stored_len = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
Tells something additional to the handler about how to do things. */
|
|
||||||
|
|
||||||
int
|
|
||||||
ha_innobase::extra(
|
|
||||||
/*===============*/
|
|
||||||
/* out: 0 or error number */
|
|
||||||
enum ha_extra_function operation)
|
|
||||||
/* in: HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE */
|
|
||||||
{
|
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
|
||||||
|
|
||||||
switch (operation) {
|
|
||||||
case HA_EXTRA_RESET:
|
|
||||||
case HA_EXTRA_RESET_STATE:
|
|
||||||
prebuilt->read_just_key = 0;
|
|
||||||
break;
|
|
||||||
case HA_EXTRA_NO_KEYREAD:
|
|
||||||
prebuilt->read_just_key = 0;
|
|
||||||
break;
|
|
||||||
case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
|
|
||||||
prebuilt->in_update_remember_pos = FALSE;
|
|
||||||
break;
|
|
||||||
case HA_EXTRA_KEYREAD:
|
|
||||||
prebuilt->read_just_key = 1;
|
|
||||||
break;
|
|
||||||
default:/* Do nothing */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ha_innobase::reset(void)
|
|
||||||
{
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
Creates a table definition to an InnoDB database. */
|
Creates a table definition to an InnoDB database. */
|
||||||
static
|
static
|
||||||
@ -2953,6 +2918,10 @@ ha_innobase::records_in_range(
|
|||||||
|
|
||||||
DBUG_ENTER("records_in_range");
|
DBUG_ENTER("records_in_range");
|
||||||
|
|
||||||
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
|
before calling this function, the trx field in prebuilt can be
|
||||||
|
obsolete! */
|
||||||
|
|
||||||
active_index = keynr;
|
active_index = keynr;
|
||||||
|
|
||||||
key = table->key_info + active_index;
|
key = table->key_info + active_index;
|
||||||
@ -2985,6 +2954,10 @@ ha_innobase::records_in_range(
|
|||||||
|
|
||||||
my_free((char*) key_val_buff2, MYF(0));
|
my_free((char*) key_val_buff2, MYF(0));
|
||||||
|
|
||||||
|
if (prebuilt->trx) {
|
||||||
|
prebuilt->trx->op_info = "";
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN((ha_rows) n_rows);
|
DBUG_RETURN((ha_rows) n_rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3005,6 +2978,10 @@ ha_innobase::estimate_number_of_rows(void)
|
|||||||
ulonglong estimate;
|
ulonglong estimate;
|
||||||
ulonglong data_file_length;
|
ulonglong data_file_length;
|
||||||
|
|
||||||
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
|
before calling this function, the trx field in prebuilt can be
|
||||||
|
obsolete! */
|
||||||
|
|
||||||
DBUG_ENTER("info");
|
DBUG_ENTER("info");
|
||||||
|
|
||||||
index = dict_table_get_first_index_noninline(prebuilt->table);
|
index = dict_table_get_first_index_noninline(prebuilt->table);
|
||||||
@ -3035,10 +3012,12 @@ ha_innobase::scan_time()
|
|||||||
{
|
{
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||||
|
|
||||||
/* In the following formula we assume that scanning 10 pages
|
/* Since MySQL seems to favor table scans too much over index
|
||||||
takes the same time as a disk seek: */
|
searches, we pretend that a sequential read takes the same time
|
||||||
|
as a random disk read, that is, we do not divide the following
|
||||||
|
by 10, which would be physically realistic. */
|
||||||
|
|
||||||
return((double) (prebuilt->table->stat_clustered_index_size / 10));
|
return((double) (prebuilt->table->stat_clustered_index_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@ -3059,6 +3038,10 @@ ha_innobase::info(
|
|||||||
|
|
||||||
DBUG_ENTER("info");
|
DBUG_ENTER("info");
|
||||||
|
|
||||||
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
|
before calling this function, the trx field in prebuilt can be
|
||||||
|
obsolete! */
|
||||||
|
|
||||||
ib_table = prebuilt->table;
|
ib_table = prebuilt->table;
|
||||||
|
|
||||||
if (flag & HA_STATUS_TIME) {
|
if (flag & HA_STATUS_TIME) {
|
||||||
@ -3105,6 +3088,13 @@ ha_innobase::info(
|
|||||||
index->stat_n_diff_key_vals[j + 1]);
|
index->stat_n_diff_key_vals[j + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Since MySQL seems to favor table scans
|
||||||
|
too much over index searches, we pretend
|
||||||
|
index selectivity is 2 times better than
|
||||||
|
our estimate: */
|
||||||
|
|
||||||
|
rec_per_key = rec_per_key / 2;
|
||||||
|
|
||||||
if (rec_per_key == 0) {
|
if (rec_per_key == 0) {
|
||||||
rec_per_key = 1;
|
rec_per_key = 1;
|
||||||
}
|
}
|
||||||
@ -3124,6 +3114,8 @@ ha_innobase::info(
|
|||||||
pointer and cause a seg fault. */
|
pointer and cause a seg fault. */
|
||||||
|
|
||||||
if (flag & HA_STATUS_ERRKEY) {
|
if (flag & HA_STATUS_ERRKEY) {
|
||||||
|
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
|
||||||
|
|
||||||
errkey = (unsigned int) row_get_mysql_key_number_for_index(
|
errkey = (unsigned int) row_get_mysql_key_number_for_index(
|
||||||
(dict_index_t*)
|
(dict_index_t*)
|
||||||
trx_get_error_info(prebuilt->trx));
|
trx_get_error_info(prebuilt->trx));
|
||||||
@ -3149,6 +3141,8 @@ ha_innobase::check(
|
|||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||||
ulint ret;
|
ulint ret;
|
||||||
|
|
||||||
|
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
|
||||||
|
|
||||||
if (prebuilt->mysql_template == NULL) {
|
if (prebuilt->mysql_template == NULL) {
|
||||||
/* Build the template; we will use a dummy template
|
/* Build the template; we will use a dummy template
|
||||||
in index scans done in checking */
|
in index scans done in checking */
|
||||||
@ -3182,6 +3176,10 @@ ha_innobase::update_table_comment(
|
|||||||
char* str = my_malloc(length + 550, MYF(0));
|
char* str = my_malloc(length + 550, MYF(0));
|
||||||
char* pos;
|
char* pos;
|
||||||
|
|
||||||
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
|
before calling this function, the trx field in prebuilt can be
|
||||||
|
obsolete! */
|
||||||
|
|
||||||
if (!str) {
|
if (!str) {
|
||||||
return((char*)comment);
|
return((char*)comment);
|
||||||
}
|
}
|
||||||
@ -3203,6 +3201,53 @@ ha_innobase::update_table_comment(
|
|||||||
return(str);
|
return(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Tells something additional to the handler about how to do things. */
|
||||||
|
|
||||||
|
int
|
||||||
|
ha_innobase::extra(
|
||||||
|
/*===============*/
|
||||||
|
/* out: 0 or error number */
|
||||||
|
enum ha_extra_function operation)
|
||||||
|
/* in: HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE */
|
||||||
|
{
|
||||||
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||||
|
|
||||||
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
|
before calling this function, the trx field in prebuilt can be
|
||||||
|
obsolete! */
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case HA_EXTRA_RESET:
|
||||||
|
case HA_EXTRA_RESET_STATE:
|
||||||
|
prebuilt->read_just_key = 0;
|
||||||
|
break;
|
||||||
|
case HA_EXTRA_NO_KEYREAD:
|
||||||
|
prebuilt->read_just_key = 0;
|
||||||
|
break;
|
||||||
|
case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
|
||||||
|
prebuilt->in_update_remember_pos = FALSE;
|
||||||
|
break;
|
||||||
|
case HA_EXTRA_KEYREAD:
|
||||||
|
prebuilt->read_just_key = 1;
|
||||||
|
break;
|
||||||
|
default:/* Do nothing */
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
????????????? */
|
||||||
|
|
||||||
|
int
|
||||||
|
ha_innobase::reset(void)
|
||||||
|
/*====================*/
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
As MySQL will execute an external lock for every new table it uses when it
|
As MySQL will execute an external lock for every new table it uses when it
|
||||||
starts to process an SQL statement, we can use this function to store the
|
starts to process an SQL statement, we can use this function to store the
|
||||||
@ -3427,5 +3472,4 @@ ha_innobase::get_auto_increment()
|
|||||||
return(nr);
|
return(nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_INNOBASE_DB */
|
#endif /* HAVE_INNOBASE_DB */
|
||||||
|
Reference in New Issue
Block a user