Commit 4abd402b authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

merge with 3.23.48

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