merge with 3.23.48
BUILD/FINISH.sh: Auto merged BUILD/SETUP.sh: Auto merged BUILD/compile-alpha: Auto merged BUILD/compile-pentium-gcov: Auto merged BUILD/compile-pentium-gprof: Auto merged BUILD/compile-pentium: Auto merged BitKeeper/deleted/.del-my_new.cc: Delete: mysys/my_new.cc Build-tools/Do-compile: Auto merged acconfig.h: Auto merged acinclude.m4: Auto merged Docs/manual.texi: Auto merged bdb/dist/configure.in: Auto merged client/Makefile.am: Auto merged innobase/btr/btr0cur.c: Auto merged innobase/buf/buf0lru.c: Auto merged innobase/dict/dict0crea.c: Auto merged innobase/fil/fil0fil.c: Auto merged innobase/include/srv0srv.h: Auto merged innobase/rem/rem0cmp.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/srv/srv0start.c: Auto merged innobase/trx/trx0purge.c: Auto merged myisam/myisampack.c: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/t/join.test: Auto merged mysys/Makefile.am: Auto merged scripts/Makefile.am: Auto merged sql/ha_innodb.h: Auto merged sql/handler.cc: Auto merged sql/my_lock.c: Auto merged sql/mysqld.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_table.cc: Auto merged support-files/my-huge.cnf.sh: Auto merged support-files/my-large.cnf.sh: Auto merged support-files/my-medium.cnf.sh: Auto merged support-files/my-small.cnf.sh: Auto merged configure.in: merge innobase/row/row0mysql.c: merge innobase/trx/trx0trx.c: merge mysql-test/r/innodb.result: merge mysql-test/r/join.result: merge sql/ha_innodb.cc: merge sql/slave.cc: merge
This commit is contained in:
commit
e0ccdc17a2
@ -3,30 +3,30 @@
|
||||
use Getopt::Long;
|
||||
$opt_distribution=$opt_user=$opt_result=$opt_config_options=$opt_config_env="";
|
||||
$opt_dbd_options=$opt_perl_options=$opt_suffix="";
|
||||
$opt_tmp=$version_suffix="";
|
||||
$opt_tmp=$opt_version_suffix="";
|
||||
$opt_help=$opt_Information=$opt_delete=$opt_debug=$opt_stage=$opt_rsh_mail=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_no_mysqltest=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=0;
|
||||
$opt_innodb=$opt_bdb=0;
|
||||
|
||||
GetOptions("Information","help","distribution=s","user=s","result=s","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip") || usage();
|
||||
GetOptions("Information","help","distribution=s","user=s","result=s","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip","version-suffix=s") || usage();
|
||||
|
||||
usage() if ($opt_help || $opt_Information);
|
||||
usage() if (!$opt_distribution);
|
||||
|
||||
if ($opt_innodb || $opt_bdb)
|
||||
if (($opt_innodb || $opt_bdb) && $opt_version_suffix eq "")
|
||||
{
|
||||
$version_suffix="-max";
|
||||
$opt_version_suffix="-max";
|
||||
}
|
||||
|
||||
chomp($host=`hostname`);
|
||||
$full_host_name=$host;
|
||||
info("Compiling MySQL$version_suffix at $host$suffix, stage: $opt_stage\n");
|
||||
info("Compiling MySQL$opt_version_suffix at $host$suffix, stage: $opt_stage\n");
|
||||
$connect_option= ($opt_tcpip ? "--host=$host" : "");
|
||||
$host =~ /^([^.-]*)/;
|
||||
$host=$1 . $opt_suffix;
|
||||
$email="$opt_user\@mysql.com";
|
||||
$pwd = `pwd`; chomp($pwd);
|
||||
$log="$pwd/Logs/$host$version_suffix.log";
|
||||
$opt_distribution =~ /(mysql-[^\/]*)\.tar/;
|
||||
$log="$pwd/Logs/$host$opt_version_suffix.log";
|
||||
$opt_distribution =~ /(mysql[^\/]*)\.tar/;
|
||||
$ver=$1;
|
||||
$gcc_version=which("gcc");
|
||||
if (defined($gcc_version) && ! $opt_config_env)
|
||||
@ -108,7 +108,7 @@ $|=1;
|
||||
select STDOUT;
|
||||
$|=1;
|
||||
|
||||
safe_cd("$host");
|
||||
safe_cd($host);
|
||||
if ($opt_stage == 0 && ! $opt_use_old_distribution)
|
||||
{
|
||||
safe_system("gunzip < $opt_distribution | $tar xf -");
|
||||
@ -118,6 +118,7 @@ if ($opt_stage == 0 && ! $opt_use_old_distribution)
|
||||
system("touch timestamp; find . -newer timestamp -print | xargs touch; rm -f timestamp");
|
||||
sleep(2);
|
||||
# Ensure that files we don't want to rebuild are newer than other files
|
||||
safe_cd($ver);
|
||||
foreach $name ("configure",
|
||||
"Docs/include.texi",
|
||||
"Docs/*.html", "Docs/manual.txt", "Docs/mysql.info",
|
||||
@ -125,9 +126,11 @@ if ($opt_stage == 0 && ! $opt_use_old_distribution)
|
||||
{
|
||||
system("touch $name");
|
||||
}
|
||||
# Fix some file modes in BDB tables that makes life harder.
|
||||
system("chmod -R u+rw .");
|
||||
}
|
||||
|
||||
safe_cd($ver);
|
||||
safe_cd("$pwd/$host/$ver");
|
||||
if ($opt_stage <= 1)
|
||||
{
|
||||
$opt_config_options.=" --with-low-memory" if ($opt_with_low_memory);
|
||||
@ -156,7 +159,7 @@ if ($opt_stage <= 1)
|
||||
{
|
||||
$opt_config_options.= " --with-innodb"
|
||||
}
|
||||
check_system("$opt_config_env ./configure --prefix=/usr/local/mysql \"--with-comment=Official MySQL$version_suffix binary\" --with-extra-charsets=complex \"--with-server-suffix=$version_suffix\" --enable-thread-safe-client $opt_config_options","Thank you for choosing MySQL");
|
||||
check_system("$opt_config_env ./configure --prefix=/usr/local/mysql \"--with-comment=Official MySQL$opt_version_suffix binary\" --with-extra-charsets=complex \"--with-server-suffix=$opt_version_suffix\" --enable-thread-safe-client $opt_config_options","Thank you for choosing MySQL");
|
||||
if (-d "$pwd/$host/include-mysql")
|
||||
{
|
||||
safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include");
|
||||
@ -209,7 +212,7 @@ if ($opt_stage <= 4 && !$opt_no_test)
|
||||
safe_system("gunzip < $tar_file | $tar xf -");
|
||||
}
|
||||
|
||||
$tar_file =~ /(mysql-[^\/]*)\.tar/;
|
||||
$tar_file =~ /(mysql[^\/]*)\.tar/;
|
||||
$ver=$1;
|
||||
$test_dir="$pwd/$host/test/$ver";
|
||||
$ENV{"LD_LIBRARY_PATH"}= "$test_dir/lib:" . $ENV{"LD_LIBRARY_PATH"};
|
||||
@ -361,6 +364,9 @@ To set up the environment, like 'CC=cc CXX=gcc CXXFLAGS=-O3'
|
||||
--dbd-options 'options'
|
||||
Options for Makefile.PL when configuring msql-mysql-modules.
|
||||
|
||||
--version-suffix suffix
|
||||
Can be used to set a suffix (normally 'com' or '-max') for a distribution
|
||||
|
||||
--with-low-memory
|
||||
Use less memory when compiling.
|
||||
|
||||
|
@ -96,7 +96,7 @@ sub main
|
||||
# remove the 'PUBLIC' file from distribution and copy LICENSE
|
||||
# on the toplevel of the directory instead. file 'PUBLIC' shouldn't
|
||||
# exist in the new mysql distributions, but let's be sure..
|
||||
`rm -f $destdir/PUBLIC`;
|
||||
`rm -f $destdir/PUBLIC $destdir/README`;
|
||||
`cp -p $WD/Docs/LICENSE $destdir/`;
|
||||
|
||||
# fix file copyrights
|
||||
@ -129,7 +129,7 @@ sub fix_usage_copyright
|
||||
foreach my $Cfile (@Cfiles)
|
||||
{
|
||||
chop $Cfile;
|
||||
`replace \"This is free software,\\\\\\nand you are welcome to modify and redistribute it under the GPL license\" \"This is commercial software,\\\\nplease see the file LICENSE for details\" -- $Cfile`;
|
||||
`replace "This is free software," "This is commercial software," "and you are welcome to modify and redistribute it under the GPL license" "please see the file LICENSE for details" -- $Cfile`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48720,6 +48720,7 @@ users use this code as the rest of the code and because of this we are
|
||||
not yet 100% confident in this code.
|
||||
|
||||
@menu
|
||||
* News-3.23.49:: Changes in release 3.23.49
|
||||
* News-3.23.48:: Changes in release 3.23.48
|
||||
* News-3.23.47:: Changes in release 3.23.47
|
||||
* News-3.23.46:: Changes in release 3.23.46
|
||||
@ -48772,14 +48773,64 @@ not yet 100% confident in this code.
|
||||
* News-3.23.0:: Changes in release 3.23.0
|
||||
@end menu
|
||||
|
||||
@node News-3.23.48, News-3.23.47, News-3.23.x, News-3.23.x
|
||||
@node News-3.23.49, News-3.23.48, News-3.23.x, News-3.23.x
|
||||
@appendixsubsec Changes in release 3.23.49
|
||||
@itemize @bullet
|
||||
@item
|
||||
Fixed unlikely caching bug when doing a join without keys. In this case
|
||||
the last used field for a table always returned @code{NULL}.
|
||||
@end itemize
|
||||
|
||||
@node News-3.23.48, News-3.23.47, News-3.23.49, News-3.23.x
|
||||
@appendixsubsec Changes in release 3.23.48
|
||||
@itemize @bullet
|
||||
@item
|
||||
Changed to use @code{autoconf} 2.52 (from @code{autoconf} 2.13)
|
||||
@item
|
||||
Fixed bug in complicated join with @code{const} tables.
|
||||
@item
|
||||
Added internal safety checks for InnoDB.
|
||||
@item
|
||||
Some InnoDB variables was always shown in @code{SHOW VARIABLES} as
|
||||
@code{OFF} on high-byte-first systems (like sparc).
|
||||
@item
|
||||
Fixed problem with one thread using an InnoDB table and another
|
||||
thread doing an @code{ALTER TABLE} on the same table. Before that,
|
||||
mysqld could crash with an assertion failure in row0row.c, line 474.
|
||||
@item
|
||||
Tuned the InnoDB SQL optimizer to favor more often index searches
|
||||
over table scans.
|
||||
@item
|
||||
Fixed a performance problem with InnoDB tables when several large SELECT
|
||||
queries are run concurrently on a multiprocessor Linux computer. Large
|
||||
CPU-bound SELECT queries will now also generally run faster on all
|
||||
platforms.
|
||||
@item
|
||||
If MySQL binlogging is used, InnoDB now prints after crash recovery the
|
||||
latest MySQL binlog name and the offset InnoDB was able to recover
|
||||
to. This is useful, for example, when resynchronizing a master and a
|
||||
slave database in replication.
|
||||
@item
|
||||
Added better error messages to help in installation problems of InnoDB tables.
|
||||
@item
|
||||
One can now recover also MySQL temporary tables which have become
|
||||
orphaned inside the InnoDB tablespace.
|
||||
@item
|
||||
InnoDB now prevents a @code{FOREIGN KEY} declaration where the signedness
|
||||
is not the same in the referencing and referenced integer columns.
|
||||
@item
|
||||
Calling @code{SHOW CREATE TABLE} or @code{SHOW TABLE STATUS} could cause
|
||||
memory corruption and make mysqld to crash. Especially at risk was
|
||||
@code{mysqldump}, because it calls frequently @code{SHOW CREATE TABLE}.
|
||||
@item
|
||||
If inserts to several tables containing an auto-inc column were wrapped
|
||||
inside one @code{LOCK TABLES}, InnoDB asserted in lock0lock.c.
|
||||
@item
|
||||
In 3.23.47 we allowed several @code{NULLS} in a @code{UNIQUE} secondary
|
||||
index for an InnoDB table. But @code{CHECK TABLE} was not relaxed: it
|
||||
reports the table as corrupt. @code{CHECK TABLE} no longer complains in
|
||||
this situation.
|
||||
@item
|
||||
@code{SHOW GRANTS} now shows @code{REFERENCES} instead of @code{REFERENCE}.
|
||||
@end itemize
|
||||
|
||||
|
@ -2552,6 +2552,7 @@ btr_estimate_number_of_different_key_vals(
|
||||
ulint total_external_size = 0;
|
||||
ulint i;
|
||||
ulint j;
|
||||
ulint add_on;
|
||||
mtr_t mtr;
|
||||
|
||||
n_cols = dict_index_get_n_unique(index);
|
||||
@ -2624,8 +2625,25 @@ btr_estimate_number_of_different_key_vals(
|
||||
+ not_empty_flag)
|
||||
/ (BTR_KEY_VAL_ESTIMATE_N_PAGES
|
||||
+ total_external_size);
|
||||
}
|
||||
|
||||
/* If the tree is small, smaller than <
|
||||
10 * BTR_KEY_VAL_ESTIMATE_N_PAGES + total_external_size, then
|
||||
the above estimate is ok. For bigger trees it is common that we
|
||||
do not see any borders between key values in the few pages
|
||||
we pick. But still there may be BTR_KEY_VAL_ESTIMATE_N_PAGES
|
||||
different key values, or even more. Let us try to approximate
|
||||
that: */
|
||||
|
||||
add_on = index->stat_n_leaf_pages /
|
||||
(10 * (BTR_KEY_VAL_ESTIMATE_N_PAGES + total_external_size));
|
||||
|
||||
if (add_on > BTR_KEY_VAL_ESTIMATE_N_PAGES) {
|
||||
add_on = BTR_KEY_VAL_ESTIMATE_N_PAGES;
|
||||
}
|
||||
|
||||
index->stat_n_diff_key_vals[j] += add_on;
|
||||
}
|
||||
|
||||
mem_free(n_diff);
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,6 @@ loop:
|
||||
if (n_iterations > 30) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" ***********************************************\n"
|
||||
"InnoDB: Warning: difficult to find free blocks from\n"
|
||||
"InnoDB: the buffer pool (%lu search iterations)! Consider\n"
|
||||
"InnoDB: increasing the buffer pool size.\n",
|
||||
|
@ -1235,16 +1235,23 @@ loop:
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: foreign constraint creation failed;\n"
|
||||
"InnoDB: Foreign key constraint creation failed:\n"
|
||||
"InnoDB: internal error number %lu\n", error);
|
||||
|
||||
ut_a(error == DB_OUT_OF_FILE_SPACE);
|
||||
if (error == DB_DUPLICATE_KEY) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Duplicate key error in system table %s index %s\n",
|
||||
((dict_index_t*)trx->error_info)->table_name,
|
||||
((dict_index_t*)trx->error_info)->name);
|
||||
|
||||
fprintf(stderr, "InnoDB: tablespace is full\n");
|
||||
|
||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||
|
||||
error = DB_MUST_GET_MORE_FILE_SPACE;
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Maybe the internal data dictionary of InnoDB is\n"
|
||||
"InnoDB: out-of-sync from the .frm files of your tables.\n"
|
||||
"InnoDB: See section 15.1 Troubleshooting data dictionary operations\n"
|
||||
"InnoDB: at http://www.innodb.com/ibman.html\n");
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
@ -1088,7 +1088,15 @@ loop:
|
||||
node = UT_LIST_GET_FIRST(space->chain);
|
||||
|
||||
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) {
|
||||
/* Found! */
|
||||
|
@ -258,6 +258,7 @@ struct recv_sys_struct{
|
||||
extern recv_sys_t* recv_sys;
|
||||
extern ibool recv_recovery_on;
|
||||
extern ibool recv_no_ibuf_operations;
|
||||
extern ibool recv_needed_recovery;
|
||||
|
||||
/* States of recv_addr_struct */
|
||||
#define RECV_NOT_PROCESSED 71
|
||||
|
@ -269,13 +269,24 @@ mem_realloc(
|
||||
ulint n, /* in: desired number of bytes */
|
||||
char* file_name,/* in: file name 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 */
|
||||
|
||||
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
|
||||
the list this is the base node of the list of blocks;
|
||||
in subsequent blocks this is undefined */
|
||||
@ -299,9 +310,11 @@ struct mem_block_info_struct {
|
||||
allocated buffer frame, which can be appended as a
|
||||
free block to the heap, if we need more space;
|
||||
otherwise, this is NULL */
|
||||
ulint magic_n;/* magic number for debugging */
|
||||
char file_name[8];/* file name where the mem heap was created */
|
||||
ulint line; /* line number where the mem heap was created */
|
||||
#ifdef MEM_PERIODIC_CHECK
|
||||
UT_LIST_NODE_T(mem_block_t) mem_block_list;
|
||||
/* List of all mem blocks allocated; protected
|
||||
by the mem_comm_pool mutex */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MEM_BLOCK_MAGIC_N 764741555
|
||||
|
@ -72,6 +72,18 @@ mem_pool_get_reserved(
|
||||
/* out: reserved mmeory in bytes */
|
||||
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. */
|
||||
|
||||
ibool
|
||||
|
@ -251,6 +251,24 @@ row_table_add_foreign_constraints(
|
||||
char* name); /* in: table full name in the normalized form
|
||||
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
|
||||
characters INNODB_MONITOR, then this also stops printing of monitor
|
||||
output by the master thread. */
|
||||
@ -426,7 +444,7 @@ struct row_prebuilt_struct {
|
||||
fetched row in fetch_cache */
|
||||
ulint n_fetch_cached; /* number of not yet fetched rows
|
||||
in fetch_cache */
|
||||
mem_heap_t* blob_heap; /* in SELECTS BLOB fields are copied
|
||||
mem_heap_t* blob_heap; /* in SELECTS BLOB fie lds are copied
|
||||
to this heap */
|
||||
mem_heap_t* old_vers_heap; /* memory heap where a previous
|
||||
version is built in consistent read */
|
||||
|
@ -250,6 +250,12 @@ mutex, for performace reasons). */
|
||||
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
|
||||
(>= 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 */
|
||||
/************************************************************************
|
||||
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. */
|
||||
|
||||
void
|
||||
@ -63,6 +70,13 @@ void
|
||||
trx_free_for_mysql(
|
||||
/*===============*/
|
||||
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
|
||||
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 */
|
||||
};
|
||||
|
||||
#define TRX_MAGIC_N 91118598
|
||||
|
||||
/* 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
|
||||
rolling back after a database recovery */
|
||||
|
||||
struct trx_struct{
|
||||
ulint magic_n;
|
||||
/* All the next fields are protected by the kernel mutex, except the
|
||||
undo logs which are protected by undo_mutex */
|
||||
char* op_info; /* English text describing the
|
||||
|
@ -1020,8 +1020,9 @@ loop:
|
||||
|
||||
if (recv_addr->state == RECV_NOT_PROCESSED) {
|
||||
if (!has_printed) {
|
||||
ut_print_timestamp(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: ");
|
||||
has_printed = TRUE;
|
||||
}
|
||||
|
@ -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
|
||||
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.
|
||||
Allocates a single buffer of memory from the dynamic memory of
|
||||
@ -169,7 +177,19 @@ mem_heap_create_block(
|
||||
7);
|
||||
block->file_name[7]='\0';
|
||||
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_type(block, type);
|
||||
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
|
||||
@ -261,6 +281,13 @@ mem_heap_block_free(
|
||||
|
||||
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;
|
||||
len = block->len;
|
||||
init_block = block->init_block;
|
||||
@ -306,3 +333,30 @@ mem_heap_free_block_free(
|
||||
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 */
|
||||
#define MEM_AREA_MIN_SIZE (2 * MEM_AREA_EXTRA_SIZE)
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
struct mem_pool_struct{
|
||||
byte* buf; /* memory pool */
|
||||
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;
|
||||
|
||||
/************************************************************************
|
||||
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. */
|
||||
UNIV_INLINE
|
||||
@ -240,15 +260,15 @@ mem_pool_fill_free_list(
|
||||
|
||||
if (mem_out_of_mem_err_msg_count % 1000000000 == 0) {
|
||||
/* We do not print the message every time: */
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
|
||||
fprintf(stderr,
|
||||
"Innobase: Warning: out of memory in additional memory pool.\n");
|
||||
fprintf(stderr,
|
||||
"Innobase: Innobase will start allocating memory from the OS.\n");
|
||||
fprintf(stderr,
|
||||
"Innobase: You should restart the database with a bigger value in\n");
|
||||
fprintf(stderr,
|
||||
"Innobase: the MySQL .cnf file for innobase_additional_mem_pool_size.\n");
|
||||
" InnoDB: Out of memory in additional memory pool.\n"
|
||||
"InnoDB: InnoDB will start allocating memory from the OS.\n"
|
||||
"InnoDB: You may get better performance if you configure a bigger\n"
|
||||
"InnoDB: value in the MySQL my.cnf file for\n"
|
||||
"InnoDB: innodb_additional_mem_pool_size.\n");
|
||||
}
|
||||
|
||||
mem_out_of_mem_err_msg_count++;
|
||||
|
@ -113,6 +113,16 @@ cmp_types_are_equal(
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (type1->mtype == DATA_INT
|
||||
&& (type1->prtype & DATA_UNSIGNED)
|
||||
!= (type2->prtype & DATA_UNSIGNED)) {
|
||||
/* The storage format of an unsigned integer is different
|
||||
from a signed integer: in a signed integer we OR
|
||||
0x8000... to the value of positive integers. */
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (type1->mtype == DATA_MYSQL
|
||||
|| type1->mtype == DATA_VARMYSQL) {
|
||||
|
||||
|
@ -26,6 +26,19 @@ Created 9/17/2000 Heikki Tuuri
|
||||
#include "trx0purge.h"
|
||||
#include "lock0lock.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
|
||||
@ -172,10 +185,22 @@ handle_new_error:
|
||||
trx_general_rollback_for_mysql(trx, TRUE, savept);
|
||||
}
|
||||
} 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 */
|
||||
} else if (err == DB_ROW_IS_REFERENCED
|
||||
|| err == DB_NO_REFERENCED_ROW
|
||||
|| 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 */
|
||||
} else if (err == DB_LOCK_WAIT) {
|
||||
|
||||
@ -200,6 +225,12 @@ handle_new_error:
|
||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||
|
||||
} 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 */
|
||||
|
||||
} else if (err == DB_MUST_GET_MORE_FILE_SPACE) {
|
||||
@ -375,13 +406,13 @@ row_update_prebuilt_trx(
|
||||
handle */
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
{
|
||||
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||
if (trx->magic_n != TRX_MAGIC_N) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name %s\n",
|
||||
prebuilt->magic_n, prebuilt->table->name);
|
||||
"InnoDB: Error: trying to use a corrupt\n"
|
||||
"InnoDB: trx handle. Magic n %lu\n",
|
||||
trx->magic_n);
|
||||
|
||||
mem_analyze_corruption((byte*)prebuilt);
|
||||
mem_analyze_corruption((byte*)trx);
|
||||
|
||||
ut_a(0);
|
||||
}
|
||||
@ -1172,8 +1203,11 @@ row_create_table_for_mysql(
|
||||
row_drop_table_for_mysql(table->name, trx, TRUE);
|
||||
} else {
|
||||
ut_a(err == DB_DUPLICATE_KEY);
|
||||
|
||||
ut_print_timestamp(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: and not used DROP TABLE? Have you used DROP DATABASE\n"
|
||||
"InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n"
|
||||
@ -1351,6 +1385,164 @@ row_table_add_foreign_constraints(
|
||||
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
|
||||
characters INNODB_MONITOR, then this also stops printing of monitor
|
||||
@ -1541,9 +1733,10 @@ row_drop_table_for_mysql(
|
||||
|
||||
if (!table) {
|
||||
err = DB_TABLE_NOT_FOUND;
|
||||
ut_print_timestamp(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"
|
||||
"InnoDB: data dictionary though MySQL is trying to drop it.\n"
|
||||
"InnoDB: Have you copied the .frm file of the table to the\n"
|
||||
"InnoDB: MySQL database directory from another database?\n",
|
||||
@ -1551,41 +1744,18 @@ row_drop_table_for_mysql(
|
||||
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 */
|
||||
|
||||
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->table_id = table->id;
|
||||
@ -1622,6 +1792,8 @@ funct_exit:
|
||||
|
||||
trx->op_info = (char *) "";
|
||||
|
||||
srv_wake_master_thread();
|
||||
|
||||
return((int) err);
|
||||
}
|
||||
|
||||
@ -1793,7 +1965,31 @@ row_rename_table_for_mysql(
|
||||
err = trx->error_state;
|
||||
|
||||
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 {
|
||||
ut_a(dict_table_rename_in_cache(table, new_name));
|
||||
}
|
||||
@ -1950,7 +2146,7 @@ row_check_table_for_mysql(
|
||||
ulint ret = DB_SUCCESS;
|
||||
|
||||
prebuilt->trx->op_info = (char *) "checking table";
|
||||
|
||||
|
||||
index = dict_table_get_first_index(table);
|
||||
|
||||
while (index != NULL) {
|
||||
|
@ -20,7 +20,7 @@ Windows 2000 will have something called thread pooling
|
||||
Another possibility could be to use some very fast user space
|
||||
thread library. This might confuse NT though.
|
||||
|
||||
(c) 1995 InnoDB Oy
|
||||
(c) 1995 Innobase Oy
|
||||
|
||||
Created 10/8/1995 Heikki Tuuri
|
||||
*******************************************************/
|
||||
@ -49,6 +49,7 @@ Created 10/8/1995 Heikki Tuuri
|
||||
#include "btr0sea.h"
|
||||
#include "dict0load.h"
|
||||
#include "srv0start.h"
|
||||
#include "row0mysql.h"
|
||||
|
||||
/* Buffer which can be used in printing fatal error messages */
|
||||
char srv_fatal_errbuf[5000];
|
||||
@ -91,8 +92,43 @@ ibool srv_log_archive_on = TRUE;
|
||||
ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */
|
||||
ibool srv_flush_log_at_trx_commit = TRUE;
|
||||
|
||||
byte srv_latin1_ordering[256]; /* The sort order table of the latin1
|
||||
character set */
|
||||
byte srv_latin1_ordering[256] /* The sort order table of the latin1
|
||||
character set. The following table is
|
||||
the MySQL order as of Feb 10th, 2002 */
|
||||
= {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
|
||||
, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
||||
, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
|
||||
, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
||||
, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
|
||||
, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
|
||||
, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
|
||||
, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
|
||||
, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
|
||||
, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
|
||||
, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
|
||||
, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
|
||||
, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
|
||||
, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
|
||||
, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
|
||||
, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
|
||||
, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87
|
||||
, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F
|
||||
, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97
|
||||
, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F
|
||||
, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7
|
||||
, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF
|
||||
, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7
|
||||
, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
|
||||
, 0x41, 0x41, 0x41, 0x41, 0x5C, 0x5B, 0x5C, 0x43
|
||||
, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49
|
||||
, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x5D, 0xD7
|
||||
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xDF
|
||||
, 0x41, 0x41, 0x41, 0x41, 0x5C, 0x5B, 0x5C, 0x43
|
||||
, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49
|
||||
, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x5D, 0xF7
|
||||
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xFF
|
||||
};
|
||||
|
||||
ibool srv_use_native_aio = FALSE;
|
||||
|
||||
@ -1920,17 +1956,12 @@ srv_boot(void)
|
||||
|
||||
srv_init();
|
||||
|
||||
/* Reserve the first slot for the current thread, i.e., the master
|
||||
thread */
|
||||
|
||||
srv_table_reserve_slot(SRV_MASTER);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
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
|
||||
srv_slot_t*
|
||||
srv_table_reserve_slot_for_mysql(void)
|
||||
@ -1940,6 +1971,8 @@ srv_table_reserve_slot_for_mysql(void)
|
||||
srv_slot_t* slot;
|
||||
ulint i;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
|
||||
i = 0;
|
||||
slot = srv_mysql_table + i;
|
||||
|
||||
@ -2361,6 +2394,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. */
|
||||
|
||||
@ -2383,6 +2432,7 @@ srv_master_thread(
|
||||
ulint n_bytes_merged;
|
||||
ulint n_pages_flushed;
|
||||
ulint n_bytes_archived;
|
||||
ulint n_tables_to_drop;
|
||||
ulint n_ios;
|
||||
ulint n_ios_old;
|
||||
ulint n_ios_very_old;
|
||||
@ -2424,7 +2474,11 @@ loop:
|
||||
can drop tables lazily after there no longer are SELECT
|
||||
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) {
|
||||
|
||||
@ -2475,6 +2529,11 @@ loop:
|
||||
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,
|
||||
we assume that there is free disk i/o capacity available, and it
|
||||
makes sense to do a buffer pool flush. */
|
||||
@ -2531,6 +2590,12 @@ background_loop:
|
||||
/* In this loop we run background operations when the server
|
||||
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";
|
||||
|
||||
/* Flush a few oldest pages to make the checkpoint younger */
|
||||
@ -2616,11 +2681,13 @@ background_loop:
|
||||
log_archive_do(FALSE, &n_bytes_archived);
|
||||
|
||||
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;
|
||||
}
|
||||
} 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) {
|
||||
goto background_loop;
|
||||
}
|
||||
@ -2639,6 +2706,12 @@ suspend_thread:
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
||||
if (row_get_background_drop_list_len_low() > 0) {
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
event = srv_suspend_thread();
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
@ -271,13 +271,18 @@ open_or_create_log_file(
|
||||
} else {
|
||||
*log_file_created = TRUE;
|
||||
|
||||
ut_print_timestamp(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);
|
||||
fprintf(stderr, "InnoDB: Setting log file %s size to %lu MB\n",
|
||||
name, srv_log_file_size
|
||||
>> (20 - UNIV_PAGE_SIZE_SHIFT));
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Database physically writes the file full: wait...\n");
|
||||
|
||||
ret = os_file_set_size(name, files[i],
|
||||
srv_calc_low32(srv_log_file_size),
|
||||
srv_calc_high32(srv_log_file_size));
|
||||
@ -456,8 +461,9 @@ open_or_create_data_files(
|
||||
one_created = TRUE;
|
||||
|
||||
if (i > 0) {
|
||||
ut_print_timestamp(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);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
@ -466,8 +472,9 @@ open_or_create_data_files(
|
||||
*create_new_db = TRUE;
|
||||
}
|
||||
|
||||
ut_print_timestamp(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]
|
||||
>> (20 - UNIV_PAGE_SIZE_SHIFT)));
|
||||
|
||||
@ -911,6 +918,12 @@ innobase_start_or_create_for_mysql(void)
|
||||
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);
|
||||
|
||||
if (!srv_log_archive_on) {
|
||||
@ -991,9 +1004,8 @@ innobase_shutdown_for_mysql(void)
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Warning: shutting down a not properly started\n");
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: or created database!\n");
|
||||
" InnoDB: or created database!\n");
|
||||
}
|
||||
|
||||
return(DB_SUCCESS);
|
||||
|
@ -226,9 +226,9 @@ trx_purge_sys_create(void)
|
||||
value */
|
||||
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));
|
||||
|
||||
|
@ -26,9 +26,9 @@ Created 3/26/1996 Heikki Tuuri
|
||||
|
||||
|
||||
/* Copy of the prototype for innobase_mysql_print_thd: this
|
||||
copy must be equal to the one in mysql/sql/ha_innobase.cc ! */
|
||||
void innobase_mysql_print_thd(void* thd);
|
||||
copy must be equal to the one in mysql/sql/ha_innobase.cc ! */
|
||||
|
||||
void innobase_mysql_print_thd(void* thd);
|
||||
|
||||
/* Dummy session used currently in MySQL interface */
|
||||
sess_t* trx_dummy_sess = NULL;
|
||||
@ -64,6 +64,8 @@ trx_create(
|
||||
|
||||
trx = mem_alloc(sizeof(trx_t));
|
||||
|
||||
trx->magic_n = TRX_MAGIC_N;
|
||||
|
||||
trx->op_info = (char *) "";
|
||||
|
||||
trx->type = TRX_USER;
|
||||
@ -157,6 +159,32 @@ trx_allocate_for_mysql(void)
|
||||
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. */
|
||||
|
||||
@ -181,6 +209,11 @@ trx_free(
|
||||
trx_t* trx) /* in, own: trx object */
|
||||
{
|
||||
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);
|
||||
|
||||
mutex_free(&(trx->undo_mutex));
|
||||
@ -242,6 +275,21 @@ trx_free_for_mysql(
|
||||
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.
|
||||
The list is sorted on the trx id so that the biggest id is at the list
|
||||
|
@ -194,3 +194,27 @@ t3.Contractor_ID = '999999' OR
|
||||
t3.Contractor_ID = '1') AND
|
||||
t3.CanRead='1' AND t3.Active='1';
|
||||
drop table t1,t2,t3;
|
||||
|
||||
#
|
||||
# Bug when doing full join and NULL fields.
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
t1_id int(11) default NULL,
|
||||
t2_id int(11) default NULL,
|
||||
type enum('Cost','Percent') default NULL,
|
||||
cost_unit enum('Cost','Unit') default NULL,
|
||||
min_value double default NULL,
|
||||
max_value double default NULL,
|
||||
t3_id int(11) default NULL,
|
||||
item_id int(11) default NULL
|
||||
) TYPE=MyISAM;
|
||||
INSERT INTO t1 VALUES (12,5,'Percent','Cost',-1,0,-1,-1),(14,4,'Percent','Cost',-1,0,-1,-1),(18,5,'Percent','Cost',-1,0,-1,-1),(19,4,'Percent','Cost',-1,0,-1,-1),(20,5,'Percent','Cost',100,-1,22,291),(21,5,'Percent','Cost',100,-1,18,291),(22,1,'Percent','Cost',100,-1,6,291),(23,1,'Percent','Cost',100,-1,21,291),(24,1,'Percent','Cost',100,-1,9,291),(25,1,'Percent','Cost',100,-1,4,291),(26,1,'Percent','Cost',100,-1,20,291),(27,4,'Percent','Cost',100,-1,7,202),(28,1,'Percent','Cost',50,-1,-1,137),(29,2,'Percent','Cost',100,-1,4,354),(30,2,'Percent','Cost',100,-1,9,137),(93,2,'Cost','Cost',-1,10000000,-1,-1);
|
||||
CREATE TABLE t2 (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
name varchar(255) default NULL,
|
||||
PRIMARY KEY (id)
|
||||
) TYPE=MyISAM;
|
||||
INSERT INTO t2 VALUES (1,'s1'),(2,'s2'),(3,'s3'),(4,'s4'),(5,'s5');
|
||||
select t1.*, t2.* from t1, t2 where t2.id=t1.t2_id limit 2;
|
||||
drop table t1,t2;
|
||||
|
168
sql/ha_innodb.cc
168
sql/ha_innodb.cc
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & InnoDB Oy
|
||||
/* Copyright (C) 2000 MySQL AB & InnoDB Oy
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -85,8 +85,8 @@ long innobase_mirrored_log_groups, innobase_log_files_in_group,
|
||||
char *innobase_data_home_dir;
|
||||
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
||||
char *innobase_unix_file_flush_method;
|
||||
bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||
innobase_use_native_aio, innobase_fast_shutdown;
|
||||
my_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||
innobase_use_native_aio, innobase_fast_shutdown;
|
||||
|
||||
/*
|
||||
Set default InnoDB size to 64M, to let users use InnoDB without having
|
||||
@ -235,7 +235,7 @@ convert_error_code_to_mysql(
|
||||
extern "C" {
|
||||
/*****************************************************************
|
||||
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! */
|
||||
|
||||
void
|
||||
@ -304,6 +304,8 @@ check_trx_exists(
|
||||
|
||||
thd->transaction.stmt.innobase_tid =
|
||||
(void*)&innodb_dummy_stmt_trx_handle;
|
||||
} else {
|
||||
ut_a(trx->magic_n == TRX_MAGIC_N);
|
||||
}
|
||||
|
||||
return(trx);
|
||||
@ -841,6 +843,7 @@ innobase_close_connection(
|
||||
whose transaction should be rolled back */
|
||||
{
|
||||
if (NULL != thd->transaction.all.innobase_tid) {
|
||||
|
||||
trx_rollback_for_mysql((trx_t*)
|
||||
(thd->transaction.all.innobase_tid));
|
||||
trx_free_for_mysql((trx_t*)
|
||||
@ -2465,44 +2468,6 @@ ha_innobase::position(
|
||||
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. */
|
||||
@ -2981,9 +2946,9 @@ ha_innobase::records_in_range(
|
||||
|
||||
DBUG_ENTER("records_in_range");
|
||||
|
||||
if (prebuilt->trx) {
|
||||
prebuilt->trx->op_info = (char*) "estimating range size";
|
||||
}
|
||||
/* 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;
|
||||
|
||||
@ -3017,10 +2982,6 @@ ha_innobase::records_in_range(
|
||||
|
||||
my_free((char*) key_val_buff2, MYF(0));
|
||||
|
||||
if (prebuilt->trx) {
|
||||
prebuilt->trx->op_info = (char*) "";
|
||||
}
|
||||
|
||||
DBUG_RETURN((ha_rows) n_rows);
|
||||
}
|
||||
|
||||
@ -3041,10 +3002,9 @@ ha_innobase::estimate_number_of_rows(void)
|
||||
ulonglong estimate;
|
||||
ulonglong data_file_length;
|
||||
|
||||
if (prebuilt->trx) {
|
||||
prebuilt->trx->op_info =
|
||||
(char*) "estimating upper bound of table size";
|
||||
}
|
||||
/* 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");
|
||||
|
||||
@ -3061,10 +3021,6 @@ ha_innobase::estimate_number_of_rows(void)
|
||||
|
||||
estimate = 2 * data_file_length / dict_index_calc_min_rec_len(index);
|
||||
|
||||
if (prebuilt->trx) {
|
||||
prebuilt->trx->op_info = (char*) "";
|
||||
}
|
||||
|
||||
DBUG_RETURN((ha_rows) estimate);
|
||||
}
|
||||
|
||||
@ -3080,10 +3036,12 @@ ha_innobase::scan_time()
|
||||
{
|
||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||
|
||||
/* In the following formula we assume that scanning 10 pages
|
||||
takes the same time as a disk seek: */
|
||||
|
||||
return((double) (prebuilt->table->stat_clustered_index_size / 10));
|
||||
/* Since MySQL seems to favor table scans too much over index
|
||||
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));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@ -3104,9 +3062,9 @@ ha_innobase::info(
|
||||
|
||||
DBUG_ENTER("info");
|
||||
|
||||
if (prebuilt->trx) {
|
||||
prebuilt->trx->op_info = (char*) "calculating table stats";
|
||||
}
|
||||
/* 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;
|
||||
|
||||
@ -3154,25 +3112,17 @@ ha_innobase::info(
|
||||
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) {
|
||||
rec_per_key = 1;
|
||||
}
|
||||
|
||||
/* Since the MySQL optimizer is often too
|
||||
pessimistic in the assumption that a table
|
||||
does not fit in the buffer pool, we
|
||||
increase the attractiveness of indexes
|
||||
by assuming the selectivity of any prefix
|
||||
of an index is 1 / 100 or better.
|
||||
(Actually, we should look at the table
|
||||
size, and if the table is smaller than
|
||||
the buffer pool, we should uniformly
|
||||
increase the attractiveness of indexes,
|
||||
regardless of the estimated selectivity.) */
|
||||
|
||||
if (rec_per_key > records / 100) {
|
||||
rec_per_key = records / 100;
|
||||
}
|
||||
table->key_info[i].rec_per_key[j]
|
||||
= rec_per_key;
|
||||
}
|
||||
@ -3188,15 +3138,13 @@ ha_innobase::info(
|
||||
pointer and cause a seg fault. */
|
||||
|
||||
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(
|
||||
(dict_index_t*)
|
||||
trx_get_error_info(prebuilt->trx));
|
||||
}
|
||||
|
||||
if (prebuilt->trx) {
|
||||
prebuilt->trx->op_info = (char*) "";
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -3217,6 +3165,8 @@ ha_innobase::check(
|
||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||
ulint ret;
|
||||
|
||||
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
|
||||
|
||||
if (prebuilt->mysql_template == NULL) {
|
||||
/* Build the template; we will use a dummy template
|
||||
in index scans done in checking */
|
||||
@ -3250,6 +3200,10 @@ ha_innobase::update_table_comment(
|
||||
char* str = my_malloc(length + 550, MYF(0));
|
||||
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) {
|
||||
return((char*)comment);
|
||||
}
|
||||
@ -3271,6 +3225,53 @@ ha_innobase::update_table_comment(
|
||||
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
|
||||
starts to process an SQL statement, we can use this function to store the
|
||||
@ -3496,5 +3497,4 @@ ha_innobase::get_auto_increment()
|
||||
return(nr);
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_INNOBASE_DB */
|
||||
|
@ -178,8 +178,9 @@ extern long innobase_force_recovery, innobase_thread_concurrency;
|
||||
extern char *innobase_data_home_dir, *innobase_data_file_path;
|
||||
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
||||
extern char *innobase_unix_file_flush_method;
|
||||
extern bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||
innobase_use_native_aio, innobase_fast_shutdown;
|
||||
/* The following variables have to be my_bool for SHOW VARIABLES to work */
|
||||
extern my_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||
innobase_use_native_aio, innobase_fast_shutdown;
|
||||
|
||||
extern TYPELIB innobase_lock_typelib;
|
||||
|
||||
|
@ -222,28 +222,31 @@ int ha_autocommit_or_rollback(THD *thd, int error)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/* This function is called when MySQL writes the log segment of a transaction
|
||||
to the binlog. It is called when the LOCK_log mutex is reserved. Here we
|
||||
communicate to transactional table handlers whta binlog position corresponds
|
||||
to the current transaction. The handler can store it and in recovery print
|
||||
to the user, so that the user knows from what position in the binlog to
|
||||
start possible roll-forward, for example, if the crashed server was a slave
|
||||
in replication. This function also calls the commit of the table handler,
|
||||
because the order of trasnactions in the log of the table handler must be
|
||||
the same as in the binlog. */
|
||||
/*
|
||||
This function is called when MySQL writes the log segment of a
|
||||
transaction to the binlog. It is called when the LOCK_log mutex is
|
||||
reserved. Here we communicate to transactional table handlers whta
|
||||
binlog position corresponds to the current transaction. The handler
|
||||
can store it and in recovery print to the user, so that the user
|
||||
knows from what position in the binlog to start possible
|
||||
roll-forward, for example, if the crashed server was a slave in
|
||||
replication. This function also calls the commit of the table
|
||||
handler, because the order of trasnactions in the log of the table
|
||||
handler must be the same as in the binlog.
|
||||
|
||||
int ha_report_binlog_offset_and_commit(
|
||||
THD *thd, /* in: user thread */
|
||||
char *log_file_name, /* in: latest binlog file name */
|
||||
my_off_t end_offset) /* in: the offset in the binlog file
|
||||
up to which we wrote */
|
||||
arguments:
|
||||
log_file_name: latest binlog file name
|
||||
end_offset: the offset in the binlog file up to which we wrote
|
||||
*/
|
||||
|
||||
int ha_report_binlog_offset_and_commit(THD *thd,
|
||||
char *log_file_name,
|
||||
my_off_t end_offset)
|
||||
{
|
||||
THD_TRANS *trans;
|
||||
int error = 0;
|
||||
|
||||
trans = &thd->transaction.all;
|
||||
|
||||
int error= 0;
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
THD_TRANS *trans;
|
||||
trans = &thd->transaction.all;
|
||||
if (trans->innobase_tid)
|
||||
{
|
||||
if ((error=innobase_report_binlog_offset_and_commit(thd,
|
||||
@ -257,10 +260,10 @@ int ha_report_binlog_offset_and_commit(
|
||||
trans->innodb_active_trans=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
||||
{
|
||||
int error=0;
|
||||
|
@ -26,10 +26,6 @@
|
||||
#include <thr_alarm.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_FCNTL
|
||||
static struct flock lock; /* Must be static for sun-sparc */
|
||||
#endif
|
||||
|
||||
/* Lock a part of a file */
|
||||
|
||||
int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
|
||||
@ -37,24 +33,25 @@ int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
|
||||
thr_alarm_t alarmed;
|
||||
ALARM alarm_buff;
|
||||
uint wait_for_alarm;
|
||||
struct flock m_lock;
|
||||
DBUG_ENTER("my_lock");
|
||||
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
|
||||
fd,locktype,(ulong) start,(ulong) length,MyFlags));
|
||||
if (my_disable_locking)
|
||||
DBUG_RETURN(0); /* purecov: inspected */
|
||||
lock.l_type=(short) locktype;
|
||||
lock.l_whence=0L;
|
||||
lock.l_start=(long) start;
|
||||
lock.l_len=(long) length;
|
||||
m_lock.l_type=(short) locktype;
|
||||
m_lock.l_whence=0L;
|
||||
m_lock.l_start=(long) start;
|
||||
m_lock.l_len=(long) length;
|
||||
wait_for_alarm=(MyFlags & MY_DONT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
|
||||
(uint) 12*60*60);
|
||||
if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */
|
||||
if (fcntl(fd,F_SETLK,&m_lock) != -1) /* Check if we can lock */
|
||||
DBUG_RETURN(0); /* Ok, file locked */
|
||||
DBUG_PRINT("info",("Was locked, trying with alarm"));
|
||||
if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
|
||||
{
|
||||
int value;
|
||||
while ((value=fcntl(fd,F_SETLKW,&lock)) && !thr_got_alarm(&alarmed) &&
|
||||
while ((value=fcntl(fd,F_SETLKW,&m_lock)) && !thr_got_alarm(&alarmed) &&
|
||||
errno == EINTR) ;
|
||||
thr_end_alarm(&alarmed);
|
||||
if (value != -1)
|
||||
|
@ -3309,10 +3309,11 @@ static void use_help(void)
|
||||
static void usage(void)
|
||||
{
|
||||
print_version();
|
||||
puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB, by Monty and others");
|
||||
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
|
||||
puts("and you are welcome to modify and redistribute it under the GPL license\n");
|
||||
puts("Starts the MySQL server\n");
|
||||
puts("\
|
||||
Copyright (C) 2000 MySQL AB, by Monty and others\n\
|
||||
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
|
||||
and you are welcome to modify and redistribute it under the GPL license\n\
|
||||
Starts the MySQL server\n");
|
||||
|
||||
printf("Usage: %s [OPTIONS]\n", my_progname);
|
||||
puts("\n\
|
||||
|
@ -5962,10 +5962,10 @@ SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Fill join cache with packed records
|
||||
** Records are stored in tab->cache.buffer and last record in
|
||||
** last record is stored with pointers to blobs to support very big
|
||||
** records
|
||||
Fill join cache with packed records
|
||||
Records are stored in tab->cache.buffer and last record in
|
||||
last record is stored with pointers to blobs to support very big
|
||||
records
|
||||
******************************************************************************/
|
||||
|
||||
static int
|
||||
@ -6027,7 +6027,7 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
|
||||
if (null_fields && tables[i].table->null_fields)
|
||||
{ /* must copy null bits */
|
||||
copy->str=(char*) tables[i].table->null_flags;
|
||||
copy->length=(tables[i].table->null_fields+7)/8;
|
||||
copy->length=tables[i].table->null_bytes;
|
||||
copy->strip=0;
|
||||
copy->blob_field=0;
|
||||
length+=copy->length;
|
||||
|
@ -825,7 +825,7 @@ bool close_cached_table(THD *thd,TABLE *table)
|
||||
/* Mark all tables that are in use as 'old' */
|
||||
mysql_lock_abort(thd,table); // end threads waiting on lock
|
||||
|
||||
#ifdef REMOVE_LOCKS
|
||||
#if defined(USING_TRANSACTIONS) || defined( __WIN__) || defined( __EMX__) || !defined(OS2)
|
||||
/* Wait until all there are no other threads that has this table open */
|
||||
while (remove_table_from_cache(thd,table->table_cache_key,
|
||||
table->table_name))
|
||||
@ -1674,19 +1674,28 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined( __WIN__) || defined( __EMX__) || defined( OS2)
|
||||
// Win32 can't rename an open table, so we must close the org table!
|
||||
table_name=thd->strdup(table_name); // must be saved
|
||||
if (close_cached_table(thd,table))
|
||||
{ // Aborted
|
||||
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
goto err;
|
||||
}
|
||||
table=0; // Marker for win32 version
|
||||
#else
|
||||
table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore
|
||||
#if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
|
||||
if (table->file->has_transactions())
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
Win32 and InnoDB can't drop a table that is in use, so we must
|
||||
close all the original table at before doing the rename
|
||||
*/
|
||||
table_name=thd->strdup(table_name); // must be saved
|
||||
if (close_cached_table(thd,table))
|
||||
{ // Aborted
|
||||
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
goto err;
|
||||
}
|
||||
table=0; // Marker that table is closed
|
||||
}
|
||||
#if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
|
||||
else
|
||||
table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore
|
||||
#endif
|
||||
|
||||
|
||||
error=0;
|
||||
if (mysql_rename_table(old_db_type,db,table_name,db,old_name))
|
||||
|
Loading…
x
Reference in New Issue
Block a user