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;
|
use Getopt::Long;
|
||||||
$opt_distribution=$opt_user=$opt_result=$opt_config_options=$opt_config_env="";
|
$opt_distribution=$opt_user=$opt_result=$opt_config_options=$opt_config_env="";
|
||||||
$opt_dbd_options=$opt_perl_options=$opt_suffix="";
|
$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_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;
|
$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_help || $opt_Information);
|
||||||
usage() if (!$opt_distribution);
|
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`);
|
chomp($host=`hostname`);
|
||||||
$full_host_name=$host;
|
$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" : "");
|
$connect_option= ($opt_tcpip ? "--host=$host" : "");
|
||||||
$host =~ /^([^.-]*)/;
|
$host =~ /^([^.-]*)/;
|
||||||
$host=$1 . $opt_suffix;
|
$host=$1 . $opt_suffix;
|
||||||
$email="$opt_user\@mysql.com";
|
$email="$opt_user\@mysql.com";
|
||||||
$pwd = `pwd`; chomp($pwd);
|
$pwd = `pwd`; chomp($pwd);
|
||||||
$log="$pwd/Logs/$host$version_suffix.log";
|
$log="$pwd/Logs/$host$opt_version_suffix.log";
|
||||||
$opt_distribution =~ /(mysql-[^\/]*)\.tar/;
|
$opt_distribution =~ /(mysql[^\/]*)\.tar/;
|
||||||
$ver=$1;
|
$ver=$1;
|
||||||
$gcc_version=which("gcc");
|
$gcc_version=which("gcc");
|
||||||
if (defined($gcc_version) && ! $opt_config_env)
|
if (defined($gcc_version) && ! $opt_config_env)
|
||||||
@ -108,7 +108,7 @@ $|=1;
|
|||||||
select STDOUT;
|
select STDOUT;
|
||||||
$|=1;
|
$|=1;
|
||||||
|
|
||||||
safe_cd("$host");
|
safe_cd($host);
|
||||||
if ($opt_stage == 0 && ! $opt_use_old_distribution)
|
if ($opt_stage == 0 && ! $opt_use_old_distribution)
|
||||||
{
|
{
|
||||||
safe_system("gunzip < $opt_distribution | $tar xf -");
|
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");
|
system("touch timestamp; find . -newer timestamp -print | xargs touch; rm -f timestamp");
|
||||||
sleep(2);
|
sleep(2);
|
||||||
# Ensure that files we don't want to rebuild are newer than other files
|
# Ensure that files we don't want to rebuild are newer than other files
|
||||||
|
safe_cd($ver);
|
||||||
foreach $name ("configure",
|
foreach $name ("configure",
|
||||||
"Docs/include.texi",
|
"Docs/include.texi",
|
||||||
"Docs/*.html", "Docs/manual.txt", "Docs/mysql.info",
|
"Docs/*.html", "Docs/manual.txt", "Docs/mysql.info",
|
||||||
@ -125,9 +126,11 @@ if ($opt_stage == 0 && ! $opt_use_old_distribution)
|
|||||||
{
|
{
|
||||||
system("touch $name");
|
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)
|
if ($opt_stage <= 1)
|
||||||
{
|
{
|
||||||
$opt_config_options.=" --with-low-memory" if ($opt_with_low_memory);
|
$opt_config_options.=" --with-low-memory" if ($opt_with_low_memory);
|
||||||
@ -156,7 +159,7 @@ if ($opt_stage <= 1)
|
|||||||
{
|
{
|
||||||
$opt_config_options.= " --with-innodb"
|
$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")
|
if (-d "$pwd/$host/include-mysql")
|
||||||
{
|
{
|
||||||
safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include");
|
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 -");
|
safe_system("gunzip < $tar_file | $tar xf -");
|
||||||
}
|
}
|
||||||
|
|
||||||
$tar_file =~ /(mysql-[^\/]*)\.tar/;
|
$tar_file =~ /(mysql[^\/]*)\.tar/;
|
||||||
$ver=$1;
|
$ver=$1;
|
||||||
$test_dir="$pwd/$host/test/$ver";
|
$test_dir="$pwd/$host/test/$ver";
|
||||||
$ENV{"LD_LIBRARY_PATH"}= "$test_dir/lib:" . $ENV{"LD_LIBRARY_PATH"};
|
$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'
|
--dbd-options 'options'
|
||||||
Options for Makefile.PL when configuring msql-mysql-modules.
|
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
|
--with-low-memory
|
||||||
Use less memory when compiling.
|
Use less memory when compiling.
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ sub main
|
|||||||
# remove the 'PUBLIC' file from distribution and copy LICENSE
|
# remove the 'PUBLIC' file from distribution and copy LICENSE
|
||||||
# on the toplevel of the directory instead. file 'PUBLIC' shouldn't
|
# on the toplevel of the directory instead. file 'PUBLIC' shouldn't
|
||||||
# exist in the new mysql distributions, but let's be sure..
|
# 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/`;
|
`cp -p $WD/Docs/LICENSE $destdir/`;
|
||||||
|
|
||||||
# fix file copyrights
|
# fix file copyrights
|
||||||
@ -129,7 +129,7 @@ sub fix_usage_copyright
|
|||||||
foreach my $Cfile (@Cfiles)
|
foreach my $Cfile (@Cfiles)
|
||||||
{
|
{
|
||||||
chop $Cfile;
|
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.
|
not yet 100% confident in this code.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
|
* News-3.23.49:: Changes in release 3.23.49
|
||||||
* News-3.23.48:: Changes in release 3.23.48
|
* News-3.23.48:: Changes in release 3.23.48
|
||||||
* News-3.23.47:: Changes in release 3.23.47
|
* News-3.23.47:: Changes in release 3.23.47
|
||||||
* News-3.23.46:: Changes in release 3.23.46
|
* 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
|
* News-3.23.0:: Changes in release 3.23.0
|
||||||
@end menu
|
@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
|
@appendixsubsec Changes in release 3.23.48
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
Changed to use @code{autoconf} 2.52 (from @code{autoconf} 2.13)
|
||||||
|
@item
|
||||||
Fixed bug in complicated join with @code{const} tables.
|
Fixed bug in complicated join with @code{const} tables.
|
||||||
@item
|
@item
|
||||||
Added internal safety checks for InnoDB.
|
Added internal safety checks for InnoDB.
|
||||||
@item
|
@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}.
|
@code{SHOW GRANTS} now shows @code{REFERENCES} instead of @code{REFERENCE}.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
@ -2552,6 +2552,7 @@ btr_estimate_number_of_different_key_vals(
|
|||||||
ulint total_external_size = 0;
|
ulint total_external_size = 0;
|
||||||
ulint i;
|
ulint i;
|
||||||
ulint j;
|
ulint j;
|
||||||
|
ulint add_on;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
n_cols = dict_index_get_n_unique(index);
|
n_cols = dict_index_get_n_unique(index);
|
||||||
@ -2624,8 +2625,25 @@ btr_estimate_number_of_different_key_vals(
|
|||||||
+ not_empty_flag)
|
+ not_empty_flag)
|
||||||
/ (BTR_KEY_VAL_ESTIMATE_N_PAGES
|
/ (BTR_KEY_VAL_ESTIMATE_N_PAGES
|
||||||
+ total_external_size);
|
+ 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);
|
mem_free(n_diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,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",
|
||||||
|
@ -1235,16 +1235,23 @@ loop:
|
|||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: foreign constraint creation failed;\n"
|
"InnoDB: Foreign key constraint creation failed:\n"
|
||||||
"InnoDB: internal error number %lu\n", error);
|
"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");
|
fprintf(stderr, "%s\n", buf);
|
||||||
|
|
||||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
fprintf(stderr,
|
||||||
|
"InnoDB: Maybe the internal data dictionary of InnoDB is\n"
|
||||||
error = DB_MUST_GET_MORE_FILE_SPACE;
|
"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);
|
return(error);
|
||||||
}
|
}
|
||||||
|
@ -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. */
|
||||||
@ -426,7 +444,7 @@ struct row_prebuilt_struct {
|
|||||||
fetched row in fetch_cache */
|
fetched row in fetch_cache */
|
||||||
ulint n_fetch_cached; /* number of not yet fetched rows
|
ulint n_fetch_cached; /* number of not yet fetched rows
|
||||||
in fetch_cache */
|
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 */
|
to this heap */
|
||||||
mem_heap_t* old_vers_heap; /* memory heap where a previous
|
mem_heap_t* old_vers_heap; /* memory heap where a previous
|
||||||
version is built in consistent read */
|
version is built in consistent read */
|
||||||
|
@ -250,6 +250,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,8 +1020,9 @@ 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: ");
|
||||||
has_printed = TRUE;
|
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
|
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
|
||||||
@ -169,7 +177,19 @@ mem_heap_create_block(
|
|||||||
7);
|
7);
|
||||||
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
|
||||||
@ -240,15 +260,15 @@ 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++;
|
||||||
|
@ -113,6 +113,16 @@ cmp_types_are_equal(
|
|||||||
return(FALSE);
|
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
|
if (type1->mtype == DATA_MYSQL
|
||||||
|| type1->mtype == DATA_VARMYSQL) {
|
|| type1->mtype == DATA_VARMYSQL) {
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
@ -1172,8 +1203,11 @@ 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"
|
||||||
"InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
|
"InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
|
||||||
"InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n"
|
"InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n"
|
||||||
@ -1351,6 +1385,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
|
||||||
@ -1541,9 +1733,10 @@ 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"
|
||||||
"InnoDB: data dictionary though MySQL is trying to drop it.\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: Have you copied the .frm file of the table to the\n"
|
||||||
"InnoDB: MySQL database directory from another database?\n",
|
"InnoDB: MySQL database directory from another database?\n",
|
||||||
@ -1551,41 +1744,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;
|
||||||
@ -1622,6 +1792,8 @@ funct_exit:
|
|||||||
|
|
||||||
trx->op_info = (char *) "";
|
trx->op_info = (char *) "";
|
||||||
|
|
||||||
|
srv_wake_master_thread();
|
||||||
|
|
||||||
return((int) err);
|
return((int) err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1793,7 +1965,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));
|
||||||
}
|
}
|
||||||
@ -1950,7 +2146,7 @@ row_check_table_for_mysql(
|
|||||||
ulint ret = DB_SUCCESS;
|
ulint ret = DB_SUCCESS;
|
||||||
|
|
||||||
prebuilt->trx->op_info = (char *) "checking table";
|
prebuilt->trx->op_info = (char *) "checking table";
|
||||||
|
|
||||||
index = dict_table_get_first_index(table);
|
index = dict_table_get_first_index(table);
|
||||||
|
|
||||||
while (index != NULL) {
|
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
|
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];
|
||||||
@ -91,8 +92,43 @@ ibool srv_log_archive_on = TRUE;
|
|||||||
ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */
|
ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */
|
||||||
ibool srv_flush_log_at_trx_commit = TRUE;
|
ibool srv_flush_log_at_trx_commit = TRUE;
|
||||||
|
|
||||||
byte srv_latin1_ordering[256]; /* The sort order table of the latin1
|
byte srv_latin1_ordering[256] /* The sort order table of the latin1
|
||||||
character set */
|
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;
|
ibool srv_use_native_aio = FALSE;
|
||||||
|
|
||||||
@ -1920,17 +1956,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)
|
||||||
@ -1940,6 +1971,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;
|
||||||
|
|
||||||
@ -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. */
|
The master thread controlling the server. */
|
||||||
|
|
||||||
@ -2383,6 +2432,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;
|
||||||
@ -2424,7 +2474,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) {
|
||||||
|
|
||||||
@ -2475,6 +2529,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. */
|
||||||
@ -2531,6 +2590,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 */
|
||||||
@ -2616,11 +2681,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;
|
||||||
}
|
}
|
||||||
@ -2639,6 +2706,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);
|
||||||
|
@ -271,13 +271,18 @@ 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);
|
||||||
fprintf(stderr, "InnoDB: Setting log file %s size to %lu MB\n",
|
fprintf(stderr, "InnoDB: Setting log file %s size to %lu MB\n",
|
||||||
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));
|
||||||
@ -456,8 +461,9 @@ 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);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -466,8 +472,9 @@ 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]
|
||||||
>> (20 - UNIV_PAGE_SIZE_SHIFT)));
|
>> (20 - UNIV_PAGE_SIZE_SHIFT)));
|
||||||
|
|
||||||
@ -911,6 +918,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) {
|
||||||
@ -991,9 +1004,8 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ 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 = (char *) "";
|
trx->op_info = (char *) "";
|
||||||
|
|
||||||
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
|
||||||
|
@ -194,3 +194,27 @@ t3.Contractor_ID = '999999' OR
|
|||||||
t3.Contractor_ID = '1') AND
|
t3.Contractor_ID = '1') AND
|
||||||
t3.CanRead='1' AND t3.Active='1';
|
t3.CanRead='1' AND t3.Active='1';
|
||||||
drop table t1,t2,t3;
|
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
|
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
|
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_data_home_dir;
|
||||||
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
||||||
char *innobase_unix_file_flush_method;
|
char *innobase_unix_file_flush_method;
|
||||||
bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
my_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||||
innobase_use_native_aio, innobase_fast_shutdown;
|
innobase_use_native_aio, innobase_fast_shutdown;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set default InnoDB size to 64M, to let users use InnoDB without having
|
Set default InnoDB size to 64M, to let users use InnoDB without having
|
||||||
@ -235,7 +235,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
|
||||||
@ -304,6 +304,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);
|
||||||
@ -841,6 +843,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*)
|
||||||
@ -2465,44 +2468,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. */
|
||||||
@ -2981,9 +2946,9 @@ ha_innobase::records_in_range(
|
|||||||
|
|
||||||
DBUG_ENTER("records_in_range");
|
DBUG_ENTER("records_in_range");
|
||||||
|
|
||||||
if (prebuilt->trx) {
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
prebuilt->trx->op_info = (char*) "estimating range size";
|
before calling this function, the trx field in prebuilt can be
|
||||||
}
|
obsolete! */
|
||||||
|
|
||||||
active_index = keynr;
|
active_index = keynr;
|
||||||
|
|
||||||
@ -3017,10 +2982,6 @@ 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 = (char*) "";
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN((ha_rows) n_rows);
|
DBUG_RETURN((ha_rows) n_rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3041,10 +3002,9 @@ ha_innobase::estimate_number_of_rows(void)
|
|||||||
ulonglong estimate;
|
ulonglong estimate;
|
||||||
ulonglong data_file_length;
|
ulonglong data_file_length;
|
||||||
|
|
||||||
if (prebuilt->trx) {
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
prebuilt->trx->op_info =
|
before calling this function, the trx field in prebuilt can be
|
||||||
(char*) "estimating upper bound of table size";
|
obsolete! */
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_ENTER("info");
|
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);
|
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);
|
DBUG_RETURN((ha_rows) estimate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3080,10 +3036,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
|
||||||
return((double) (prebuilt->table->stat_clustered_index_size / 10));
|
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");
|
DBUG_ENTER("info");
|
||||||
|
|
||||||
if (prebuilt->trx) {
|
/* Warning: since it is not sure that MySQL calls external_lock
|
||||||
prebuilt->trx->op_info = (char*) "calculating table stats";
|
before calling this function, the trx field in prebuilt can be
|
||||||
}
|
obsolete! */
|
||||||
|
|
||||||
ib_table = prebuilt->table;
|
ib_table = prebuilt->table;
|
||||||
|
|
||||||
@ -3154,25 +3112,17 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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]
|
table->key_info[i].rec_per_key[j]
|
||||||
= rec_per_key;
|
= rec_per_key;
|
||||||
}
|
}
|
||||||
@ -3188,15 +3138,13 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prebuilt->trx) {
|
|
||||||
prebuilt->trx->op_info = (char*) "";
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3217,6 +3165,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 */
|
||||||
@ -3250,6 +3200,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);
|
||||||
}
|
}
|
||||||
@ -3271,6 +3225,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
|
||||||
@ -3496,5 +3497,4 @@ ha_innobase::get_auto_increment()
|
|||||||
return(nr);
|
return(nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_INNOBASE_DB */
|
#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_data_home_dir, *innobase_data_file_path;
|
||||||
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
||||||
extern char *innobase_unix_file_flush_method;
|
extern char *innobase_unix_file_flush_method;
|
||||||
extern bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
/* The following variables have to be my_bool for SHOW VARIABLES to work */
|
||||||
innobase_use_native_aio, innobase_fast_shutdown;
|
extern my_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||||
|
innobase_use_native_aio, innobase_fast_shutdown;
|
||||||
|
|
||||||
extern TYPELIB innobase_lock_typelib;
|
extern TYPELIB innobase_lock_typelib;
|
||||||
|
|
||||||
|
@ -222,28 +222,31 @@ int ha_autocommit_or_rollback(THD *thd, int error)
|
|||||||
DBUG_RETURN(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
|
This function is called when MySQL writes the log segment of a
|
||||||
communicate to transactional table handlers whta binlog position corresponds
|
transaction to the binlog. It is called when the LOCK_log mutex is
|
||||||
to the current transaction. The handler can store it and in recovery print
|
reserved. Here we communicate to transactional table handlers whta
|
||||||
to the user, so that the user knows from what position in the binlog to
|
binlog position corresponds to the current transaction. The handler
|
||||||
start possible roll-forward, for example, if the crashed server was a slave
|
can store it and in recovery print to the user, so that the user
|
||||||
in replication. This function also calls the commit of the table handler,
|
knows from what position in the binlog to start possible
|
||||||
because the order of trasnactions in the log of the table handler must be
|
roll-forward, for example, if the crashed server was a slave in
|
||||||
the same as in the binlog. */
|
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(
|
arguments:
|
||||||
THD *thd, /* in: user thread */
|
log_file_name: latest binlog file name
|
||||||
char *log_file_name, /* in: latest binlog file name */
|
end_offset: the offset in the binlog file up to which we wrote
|
||||||
my_off_t end_offset) /* in: 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;
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
trans = &thd->transaction.all;
|
|
||||||
|
|
||||||
#ifdef HAVE_INNOBASE_DB
|
#ifdef HAVE_INNOBASE_DB
|
||||||
|
THD_TRANS *trans;
|
||||||
|
trans = &thd->transaction.all;
|
||||||
if (trans->innobase_tid)
|
if (trans->innobase_tid)
|
||||||
{
|
{
|
||||||
if ((error=innobase_report_binlog_offset_and_commit(thd,
|
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;
|
trans->innodb_active_trans=0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
||||||
{
|
{
|
||||||
int error=0;
|
int error=0;
|
||||||
|
@ -26,10 +26,6 @@
|
|||||||
#include <thr_alarm.h>
|
#include <thr_alarm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL
|
|
||||||
static struct flock lock; /* Must be static for sun-sparc */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Lock a part of a file */
|
/* Lock a part of a file */
|
||||||
|
|
||||||
int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
|
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;
|
thr_alarm_t alarmed;
|
||||||
ALARM alarm_buff;
|
ALARM alarm_buff;
|
||||||
uint wait_for_alarm;
|
uint wait_for_alarm;
|
||||||
|
struct flock m_lock;
|
||||||
DBUG_ENTER("my_lock");
|
DBUG_ENTER("my_lock");
|
||||||
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
|
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
|
||||||
fd,locktype,(ulong) start,(ulong) length,MyFlags));
|
fd,locktype,(ulong) start,(ulong) length,MyFlags));
|
||||||
if (my_disable_locking)
|
if (my_disable_locking)
|
||||||
DBUG_RETURN(0); /* purecov: inspected */
|
DBUG_RETURN(0); /* purecov: inspected */
|
||||||
lock.l_type=(short) locktype;
|
m_lock.l_type=(short) locktype;
|
||||||
lock.l_whence=0L;
|
m_lock.l_whence=0L;
|
||||||
lock.l_start=(long) start;
|
m_lock.l_start=(long) start;
|
||||||
lock.l_len=(long) length;
|
m_lock.l_len=(long) length;
|
||||||
wait_for_alarm=(MyFlags & MY_DONT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
|
wait_for_alarm=(MyFlags & MY_DONT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
|
||||||
(uint) 12*60*60);
|
(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_RETURN(0); /* Ok, file locked */
|
||||||
DBUG_PRINT("info",("Was locked, trying with alarm"));
|
DBUG_PRINT("info",("Was locked, trying with alarm"));
|
||||||
if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
|
if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
|
||||||
{
|
{
|
||||||
int value;
|
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) ;
|
errno == EINTR) ;
|
||||||
thr_end_alarm(&alarmed);
|
thr_end_alarm(&alarmed);
|
||||||
if (value != -1)
|
if (value != -1)
|
||||||
|
@ -3309,10 +3309,11 @@ static void use_help(void)
|
|||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
print_version();
|
print_version();
|
||||||
puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB, by Monty and others");
|
puts("\
|
||||||
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
|
Copyright (C) 2000 MySQL AB, by Monty and others\n\
|
||||||
puts("and you are welcome to modify and redistribute it under the GPL license\n");
|
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
|
||||||
puts("Starts the MySQL server\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);
|
printf("Usage: %s [OPTIONS]\n", my_progname);
|
||||||
puts("\n\
|
puts("\n\
|
||||||
|
@ -5962,10 +5962,10 @@ SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length)
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Fill join cache with packed records
|
Fill join cache with packed records
|
||||||
** Records are stored in tab->cache.buffer and last record in
|
Records are stored in tab->cache.buffer and last record in
|
||||||
** last record is stored with pointers to blobs to support very big
|
last record is stored with pointers to blobs to support very big
|
||||||
** records
|
records
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static int
|
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)
|
if (null_fields && tables[i].table->null_fields)
|
||||||
{ /* must copy null bits */
|
{ /* must copy null bits */
|
||||||
copy->str=(char*) tables[i].table->null_flags;
|
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->strip=0;
|
||||||
copy->blob_field=0;
|
copy->blob_field=0;
|
||||||
length+=copy->length;
|
length+=copy->length;
|
||||||
|
@ -825,7 +825,7 @@ bool close_cached_table(THD *thd,TABLE *table)
|
|||||||
/* Mark all tables that are in use as 'old' */
|
/* Mark all tables that are in use as 'old' */
|
||||||
mysql_lock_abort(thd,table); // end threads waiting on lock
|
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 */
|
/* Wait until all there are no other threads that has this table open */
|
||||||
while (remove_table_from_cache(thd,table->table_cache_key,
|
while (remove_table_from_cache(thd,table->table_cache_key,
|
||||||
table->table_name))
|
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)
|
#if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
|
||||||
// Win32 can't rename an open table, so we must close the org table!
|
if (table->file->has_transactions())
|
||||||
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
|
|
||||||
#endif
|
#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;
|
error=0;
|
||||||
if (mysql_rename_table(old_db_type,db,table_name,db,old_name))
|
if (mysql_rename_table(old_db_type,db,table_name,db,old_name))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user