Below is the list of changes that have just been committed into a local
5.1 repository of alexi. When alexi does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2078 06/01/25 15:45:39 aivanov@stripped +19 -0
Merge mysql.com:/home/alexi/dev/mysql-5.0-oldrev
into mysql.com:/home/alexi/dev/mysql-5.1-merge
storage/innobase/trx/trx0trx.c
1.62 06/01/25 15:45:29 aivanov@stripped +1 -2
Null merged
storage/innobase/row/row0sel.c
1.100 06/01/25 15:45:29 aivanov@stripped +5 -6
Null merged
storage/innobase/row/row0mysql.c
1.120 06/01/25 15:45:29 aivanov@stripped +3 -13
Null merged
storage/innobase/row/row0ins.c
1.75 06/01/25 15:45:29 aivanov@stripped +0 -9
Null merged
storage/innobase/os/os0file.c
1.112 06/01/25 15:45:29 aivanov@stripped +40 -72
Null merged
storage/innobase/lock/lock0lock.c
1.65 06/01/25 15:45:29 aivanov@stripped +0 -70
Null merged
storage/innobase/include/row0mysql.h
1.46 06/01/25 15:45:29 aivanov@stripped +2 -3
Null merged
storage/innobase/include/os0file.h
1.43 06/01/25 15:45:29 aivanov@stripped +2 -3
Null merged
storage/innobase/include/data0type.ic
1.28 06/01/25 15:45:29 aivanov@stripped +15 -24
Null merged
storage/innobase/include/data0type.h
1.23 06/01/25 15:45:29 aivanov@stripped +1 -2
Null merged
sql/sql_select.cc
1.383 06/01/25 15:45:28 aivanov@stripped +0 -0
Auto merged
sql/item_cmpfunc.cc
1.190 06/01/25 15:45:28 aivanov@stripped +0 -0
Auto merged
sql/ha_innodb.cc
1.251 06/01/25 15:45:28 aivanov@stripped +56 -95
Null merged
mysql-test/t/ps.test
1.58 06/01/25 15:45:28 aivanov@stripped +0 -30
Null merged
5.0: Konstantin 06/01/14 (to be hand-transfered to 5.1)
mysql-test/t/innodb.test
1.124 06/01/25 15:45:28 aivanov@stripped +1 -180
Null merged
mysql-test/r/ps.result
1.59 06/01/25 15:45:28 aivanov@stripped +0 -34
Null merged
5.0: Konstantin 06/01/14 (to be hand-transfered to 5.1)
mysql-test/r/innodb.result
1.155 06/01/25 15:45:28 aivanov@stripped +1 -305
Null merged
VC++Files/sql/mysqld.vcproj
1.8 06/01/25 15:45:28 aivanov@stripped +0 -75
Null merged
5.0: changes by Knielsen 06/01/16 (to be hand-transfered to 5.1)
storage/innobase/include/lock0lock.h
1.26 06/01/25 15:30:31 aivanov@stripped +0 -12
Auto merged
storage/innobase/trx/trx0trx.c
1.54.8.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/trx/trx0trx.c -> storage/innobase/trx/trx0trx.c
storage/innobase/row/row0sel.c
1.92.5.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/row/row0sel.c -> storage/innobase/row/row0sel.c
storage/innobase/row/row0mysql.c
1.103.12.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/row/row0mysql.c -> storage/innobase/row/row0mysql.c
storage/innobase/row/row0ins.c
1.65.10.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/row/row0ins.c -> storage/innobase/row/row0ins.c
storage/innobase/os/os0file.c
1.103.7.3 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/os/os0file.c -> storage/innobase/os/os0file.c
storage/innobase/lock/lock0lock.c
1.55.7.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/lock/lock0lock.c -> storage/innobase/lock/lock0lock.c
storage/innobase/include/row0mysql.h
1.39.5.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/include/row0mysql.h -> storage/innobase/include/row0mysql.h
storage/innobase/include/os0file.h
1.34.7.3 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/include/os0file.h -> storage/innobase/include/os0file.h
storage/innobase/include/lock0lock.h
1.21.3.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/include/lock0lock.h -> storage/innobase/include/lock0lock.h
storage/innobase/include/data0type.ic
1.24.3.2 06/01/25 14:06:26 aivanov@stripped +0 -0
Merge rename: innobase/include/data0type.ic -> storage/innobase/include/data0type.ic
storage/innobase/include/data0type.h
1.20.2.2 06/01/25 14:06:25 aivanov@stripped +0 -0
Merge rename: innobase/include/data0type.h -> storage/innobase/include/data0type.h
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: aivanov
# Host: mysql.creware.com
# Root: /home/alexi/dev/mysql-5.1-merge/RESYNC
--- 1.189/sql/item_cmpfunc.cc 2006-01-16 16:26:26 +03:00
+++ 1.190/sql/item_cmpfunc.cc 2006-01-25 15:45:28 +03:00
@@ -3059,6 +3059,12 @@
return FALSE;
}
+void Item_func_like::cleanup()
+{
+ canDoTurboBM= FALSE;
+ Item_bool_func2::cleanup();
+}
+
#ifdef USE_REGEX
bool
--- 1.382/sql/sql_select.cc 2006-01-18 13:56:19 +03:00
+++ 1.383/sql/sql_select.cc 2006-01-25 15:45:28 +03:00
@@ -2961,6 +2961,56 @@
/*
+ Add to KEY_FIELD array all 'ref' access candidates within nested join
+
+ SYNPOSIS
+ add_key_fields_for_nj()
+ nested_join_table IN Nested join pseudo-table to process
+ end INOUT End of the key field array
+ and_level INOUT And-level
+
+ DESCRIPTION
+ This function populates KEY_FIELD array with entries generated from the
+ ON condition of the given nested join, and does the same for nested joins
+ contained within this nested join.
+
+ NOTES
+ We can add accesses to the tables that are direct children of this nested
+ join (1), and are not inner tables w.r.t their neighbours (2).
+
+ Example for #1 (outer brackets pair denotes nested join this function is
+ invoked for):
+ ... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond
+ Example for #2:
+ ... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond
+ In examples 1-2 for condition cond, we can add 'ref' access candidates to
+ t1 only.
+ Example #3:
+ ... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond
+ Here we can add 'ref' access candidates for t1 and t2, but not for t3.
+*/
+
+static void add_key_fields_for_nj(TABLE_LIST *nested_join_table,
+ KEY_FIELD **end, uint *and_level)
+{
+ List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list);
+ table_map tables= 0;
+ TABLE_LIST *table;
+ DBUG_ASSERT(nested_join_table->nested_join);
+
+ while ((table= li++))
+ {
+ if (table->nested_join)
+ add_key_fields_for_nj(table, end, and_level);
+ else
+ if (!table->on_expr)
+ tables |= table->table->map;
+ }
+ add_key_fields(end, and_level, nested_join_table->on_expr, tables);
+}
+
+
+/*
Update keyuse array with all possible keys we can use to fetch rows
SYNOPSIS
@@ -3024,23 +3074,21 @@
into account as well.
*/
if (*join_tab[i].on_expr_ref)
- {
add_key_fields(&end,&and_level,*join_tab[i].on_expr_ref,
join_tab[i].table->map);
- }
- else
+ }
+
+ /* Process ON conditions for the nested joins */
+ {
+ List_iterator<TABLE_LIST> li(*join_tab->join->join_list);
+ TABLE_LIST *table;
+ while ((table= li++))
{
- TABLE_LIST *tab= join_tab[i].table->pos_in_table_list;
- TABLE_LIST *embedding= tab->embedding;
- if (embedding)
- {
- NESTED_JOIN *nested_join= embedding->nested_join;
- if (nested_join->join_list.head() == tab)
- add_key_fields(&end, &and_level, embedding->on_expr,
- nested_join->used_tables);
- }
+ if (table->nested_join)
+ add_key_fields_for_nj(table, &end, &and_level);
}
}
+
/* fill keyuse with found key parts */
for ( ; field != end ; field++)
add_key_part(keyuse,field);
--- 1.20.2.1/innobase/include/data0type.h 2006-01-16 14:03:54 +03:00
+++ 1.23/storage/innobase/include/data0type.h 2006-01-25 15:45:29 +03:00
@@ -13,7 +13,6 @@
extern ulint data_mysql_default_charset_coll;
#define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8
-#define DATA_MYSQL_BINARY_CHARSET_COLL 63
/* SQL data type struct */
typedef struct dtype_struct dtype_t;
@@ -312,7 +311,7 @@
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- const dtype_t* type); /* in: type */
+ dtype_t* type); /* in: type */
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE
--- 1.24.3.1/innobase/include/data0type.ic 2006-01-16 14:03:55 +03:00
+++ 1.28/storage/innobase/include/data0type.ic 2006-01-25 15:45:29 +03:00
@@ -188,35 +188,26 @@
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- const dtype_t* type) /* in: type */
+ dtype_t* type) /* in: type */
{
- switch (type->mtype) {
- case DATA_FIXBINARY:
- case DATA_BINARY:
- if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
- == DATA_MYSQL_BINARY_CHARSET_COLL)) {
- /* Starting from 5.0.18, do not pad
- VARBINARY or BINARY columns. */
- return(ULINT_UNDEFINED);
- }
- /* Fall through */
- case DATA_CHAR:
- case DATA_VARCHAR:
- case DATA_MYSQL:
- case DATA_VARMYSQL:
+ if (type->mtype == DATA_CHAR
+ || type->mtype == DATA_VARCHAR
+ || type->mtype == DATA_BINARY
+ || type->mtype == DATA_FIXBINARY
+ || type->mtype == DATA_MYSQL
+ || type->mtype == DATA_VARMYSQL
+ || (type->mtype == DATA_BLOB
+ && (type->prtype & DATA_BINARY_TYPE) == 0)) {
+
/* Space is the padding character for all char and binary
strings, and starting from 5.0.3, also for TEXT strings. */
- return(0x20);
- case DATA_BLOB:
- if ((type->prtype & DATA_BINARY_TYPE) == 0) {
- return(0x20);
- }
- /* Fall through */
- default:
- /* No padding specified */
- return(ULINT_UNDEFINED);
+ return((ulint)' ');
}
+
+ /* No padding specified */
+
+ return(ULINT_UNDEFINED);
}
/**************************************************************************
--- 1.34.7.2/innobase/include/os0file.h 2006-01-16 14:03:55 +03:00
+++ 1.43/storage/innobase/include/os0file.h 2006-01-25 15:45:29 +03:00
@@ -91,10 +91,9 @@
#define OS_FILE_NOT_FOUND 71
#define OS_FILE_DISK_FULL 72
#define OS_FILE_ALREADY_EXISTS 73
-#define OS_FILE_PATH_ERROR 74
-#define OS_FILE_AIO_RESOURCES_RESERVED 75 /* wait for OS aio resources
+#define OS_FILE_AIO_RESOURCES_RESERVED 74 /* wait for OS aio resources
to become available again */
-#define OS_FILE_ERROR_NOT_SPECIFIED 76
+#define OS_FILE_ERROR_NOT_SPECIFIED 75
/* Types for aio operations */
#define OS_FILE_READ 10
@@ -188,7 +187,7 @@
FILE*
os_file_create_tmpfile(void);
/*========================*/
- /* out: temporary file handle, or NULL on error */
+ /* out: temporary file handle (never NULL) */
/***************************************************************************
The os_file_opendir() function opens a directory stream corresponding to the
directory named by the dirname argument. The directory stream is positioned
--- 1.39.5.1/innobase/include/row0mysql.h 2006-01-16 14:03:55 +03:00
+++ 1.46/storage/innobase/include/row0mysql.h 2006-01-25 15:45:29 +03:00
@@ -250,9 +250,8 @@
really were set. This function removes a newly set lock under prebuilt->pcur,
and also under prebuilt->clust_pcur. Currently, this is only used and tested
in the case of an UPDATE or a DELETE statement, where the row lock is of the
-LOCK_X or LOCK_S type.
-
-Thus, this implements a 'mini-rollback' that releases the latest record
+LOCK_X type.
+Thus, this implements a 'mini-rollback' that releases the latest record
locks we set. */
int
@@ -613,6 +612,31 @@
that was decided in ha_innodb.cc,
::store_lock(), ::external_lock(),
etc. */
+ ulint row_read_type; /* ROW_READ_WITH_LOCKS if row locks
+ should be the obtained for records
+ under an UPDATE or DELETE cursor.
+ If innodb_locks_unsafe_for_binlog
+ is TRUE, this can be set to
+ ROW_READ_TRY_SEMI_CONSISTENT, so that
+ if the row under an UPDATE or DELETE
+ cursor was locked by another
+ transaction, InnoDB will resort
+ to reading the last committed value
+ ('semi-consistent read'). Then,
+ this field will be set to
+ ROW_READ_DID_SEMI_CONSISTENT to
+ indicate that. If the row does not
+ match the WHERE condition, MySQL will
+ invoke handler::unlock_row() to
+ clear the flag back to
+ ROW_READ_TRY_SEMI_CONSISTENT and
+ to simply skip the row. If
+ the row matches, the next call to
+ row_search_for_mysql() will lock
+ the row.
+ This eliminates lock waits in some
+ cases; note that this breaks
+ serializability. */
ulint mysql_prefix_len;/* byte offset of the end of
the last requested column */
ulint mysql_row_len; /* length in bytes of a row in the
@@ -657,6 +681,11 @@
/* Values for hint_need_to_fetch_extra_cols */
#define ROW_RETRIEVE_PRIMARY_KEY 1
#define ROW_RETRIEVE_ALL_COLS 2
+
+/* Values for row_read_type */
+#define ROW_READ_WITH_LOCKS 0
+#define ROW_READ_TRY_SEMI_CONSISTENT 1
+#define ROW_READ_DID_SEMI_CONSISTENT 2
#ifndef UNIV_NONINL
--- 1.55.7.1/innobase/lock/lock0lock.c 2006-01-16 14:03:55 +03:00
+++ 1.65/storage/innobase/lock/lock0lock.c 2006-01-25 15:45:29 +03:00
@@ -1705,7 +1705,7 @@
lock_t*
lock_rec_create(
/*============*/
- /* out: created lock, NULL if out of memory */
+ /* out: created lock */
ulint type_mode,/* in: lock mode and wait flag, type is
ignored and replaced by LOCK_REC */
rec_t* rec, /* in: record on page */
@@ -1746,11 +1746,6 @@
n_bytes = 1 + n_bits / 8;
lock = mem_heap_alloc(trx->lock_heap, sizeof(lock_t) + n_bytes);
-
- if (UNIV_UNLIKELY(lock == NULL)) {
-
- return(NULL);
- }
UT_LIST_ADD_LAST(trx_locks, trx->trx_locks, lock);
@@ -1886,8 +1881,7 @@
lock_t*
lock_rec_add_to_queue(
/*==================*/
- /* out: lock where the bit was set, NULL if out
- of memory */
+ /* out: lock where the bit was set */
ulint type_mode,/* in: lock mode, wait, gap etc. flags;
type is ignored and replaced by LOCK_REC */
rec_t* rec, /* in: record on page */
@@ -3405,8 +3399,7 @@
lock_t*
lock_table_create(
/*==============*/
- /* out, own: new lock object, or NULL if
- out of memory */
+ /* out, own: new lock object */
dict_table_t* table, /* in: database table in dictionary cache */
ulint type_mode,/* in: lock mode possibly ORed with
LOCK_WAIT */
@@ -3432,11 +3425,6 @@
lock = mem_heap_alloc(trx->lock_heap, sizeof(lock_t));
}
- if (lock == NULL) {
-
- return(NULL);
- }
-
UT_LIST_ADD_LAST(trx_locks, trx->trx_locks, lock);
lock->type_mode = type_mode | LOCK_TABLE;
@@ -3773,9 +3761,8 @@
rec_t* rec, /* in: record */
ulint lock_mode) /* in: LOCK_S or LOCK_X */
{
- lock_t* lock;
- lock_t* release_lock = NULL;
- ulint heap_no;
+ lock_t* lock;
+ ulint heap_no;
ut_ad(trx && rec);
@@ -3785,23 +3772,21 @@
lock = lock_rec_get_first(rec);
- /* Find the last lock with the same lock_mode and transaction
- from the record. */
+ /* Remove the record lock */
while (lock != NULL) {
if (lock->trx == trx && lock_get_mode(lock) == lock_mode) {
- release_lock = lock;
ut_a(!lock_get_wait(lock));
+
+ lock_rec_reset_nth_bit(lock, heap_no);
+
+ break;
}
lock = lock_rec_get_next(rec, lock);
}
- /* If a record lock is found, release the record lock */
-
- if (UNIV_LIKELY(release_lock != NULL)) {
- lock_rec_reset_nth_bit(release_lock, heap_no);
- } else {
+ if (UNIV_UNLIKELY(lock == NULL)) {
mutex_exit(&kernel_mutex);
ut_print_timestamp(stderr);
fprintf(stderr,
--- 1.103.7.2/innobase/os/os0file.c 2006-01-16 14:03:55 +03:00
+++ 1.112/storage/innobase/os/os0file.c 2006-01-25 15:45:29 +03:00
@@ -160,12 +160,15 @@
ibool os_has_said_disk_full = FALSE;
-/* The mutex protecting the following counts of pending I/O operations */
+/* The mutex protecting the following counts of pending pread and pwrite
+operations */
static os_mutex_t os_file_count_mutex;
ulint os_file_n_pending_preads = 0;
ulint os_file_n_pending_pwrites = 0;
-ulint os_n_pending_writes = 0;
-ulint os_n_pending_reads = 0;
+
+/* These are not protected by any mutex */
+ulint os_n_pending_writes = 0;
+ulint os_n_pending_reads = 0;
/***************************************************************************
Gets the operating system version. Currently works only on Windows. */
@@ -311,8 +314,6 @@
return(OS_FILE_NOT_FOUND);
} else if (err == EEXIST) {
return(OS_FILE_ALREADY_EXISTS);
- } else if (err == EXDEV || err == ENOTDIR || err == EISDIR) {
- return(OS_FILE_PATH_ERROR);
} else {
return(100 + err);
}
@@ -362,8 +363,7 @@
return(TRUE);
- } else if (err == OS_FILE_ALREADY_EXISTS
- || err == OS_FILE_PATH_ERROR) {
+ } else if (err == OS_FILE_ALREADY_EXISTS) {
return(FALSE);
} else {
@@ -467,8 +467,7 @@
return(TRUE);
- } else if (err == OS_FILE_ALREADY_EXISTS
- || err == OS_FILE_PATH_ERROR) {
+ } else if (err == OS_FILE_ALREADY_EXISTS) {
return(FALSE);
} else {
@@ -1906,14 +1905,12 @@
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads++;
- os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
n_bytes = pread(file, buf, (ssize_t)n, offs);
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads--;
- os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
return(n_bytes);
@@ -1923,10 +1920,6 @@
ssize_t ret;
ulint i;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads++;
- os_mutex_exit(os_file_count_mutex);
-
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -1935,17 +1928,15 @@
ret_offset = lseek(file, offs, SEEK_SET);
if (ret_offset < 0) {
- ret = -1;
- } else {
- ret = read(file, buf, (ssize_t)n);
+ os_mutex_exit(os_file_seek_mutexes[i]);
+
+ return(-1);
}
+
+ ret = read(file, buf, (ssize_t)n);
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
return(ret);
}
#endif
@@ -1990,14 +1981,12 @@
#if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD)
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_pwrites++;
- os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
ret = pwrite(file, buf, (ssize_t)n, offs);
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_pwrites--;
- os_n_pending_writes--;
os_mutex_exit(os_file_count_mutex);
# ifdef UNIV_DO_FLUSH
@@ -2019,10 +2008,6 @@
off_t ret_offset;
ulint i;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes++;
- os_mutex_exit(os_file_count_mutex);
-
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -2031,9 +2016,9 @@
ret_offset = lseek(file, offs, SEEK_SET);
if (ret_offset < 0) {
- ret = -1;
+ os_mutex_exit(os_file_seek_mutexes[i]);
- goto func_exit;
+ return(-1);
}
ret = write(file, buf, (ssize_t)n);
@@ -2051,13 +2036,8 @@
}
# endif /* UNIV_DO_FLUSH */
-func_exit:
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
-
return(ret);
}
#endif
@@ -2102,13 +2082,9 @@
low = (DWORD) offset;
high = (DWORD) offset_high;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads++;
- os_mutex_exit(os_file_count_mutex);
-
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
+
os_mutex_enter(os_file_seek_mutexes[i]);
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
@@ -2117,21 +2093,17 @@
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
goto error_handling;
}
+ os_n_pending_reads++;
+
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+ os_n_pending_reads--;
+
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
if (ret && len == n) {
return(TRUE);
}
@@ -2142,8 +2114,12 @@
os_bytes_read_since_printout += n;
try_again:
+ os_n_pending_reads++;
+
ret = os_file_pread(file, buf, n, offset, offset_high);
+ os_n_pending_reads--;
+
if ((ulint)ret == n) {
return(TRUE);
@@ -2217,10 +2193,6 @@
low = (DWORD) offset;
high = (DWORD) offset_high;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads++;
- os_mutex_exit(os_file_count_mutex);
-
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -2232,21 +2204,17 @@
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
goto error_handling;
}
+ os_n_pending_reads++;
+
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+ os_n_pending_reads--;
+
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
if (ret && len == n) {
return(TRUE);
}
@@ -2257,8 +2225,12 @@
os_bytes_read_since_printout += n;
try_again:
+ os_n_pending_reads++;
+
ret = os_file_pread(file, buf, n, offset, offset_high);
+ os_n_pending_reads--;
+
if ((ulint)ret == n) {
return(TRUE);
@@ -2338,10 +2310,6 @@
low = (DWORD) offset;
high = (DWORD) offset_high;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes++;
- os_mutex_exit(os_file_count_mutex);
-
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -2353,10 +2321,6 @@
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
-
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2371,8 +2335,12 @@
return(FALSE);
}
+ os_n_pending_writes++;
+
ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
+ os_n_pending_writes--;
+
/* Always do fsync to reduce the probability that when the OS crashes,
a database page is only partially physically written to disk. */
@@ -2384,10 +2352,6 @@
os_mutex_exit(os_file_seek_mutexes[i]);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
-
if (ret && len == n) {
return(TRUE);
@@ -2438,7 +2402,11 @@
#else
ssize_t ret;
+ os_n_pending_writes++;
+
ret = os_file_pwrite(file, buf, n, offset, offset_high);
+
+ os_n_pending_writes--;
if ((ulint)ret == n) {
--- 1.65.10.1/innobase/row/row0ins.c 2006-01-16 14:03:55 +03:00
+++ 1.75/storage/innobase/row/row0ins.c 2006-01-25 15:45:29 +03:00
@@ -549,15 +549,6 @@
default:
ut_error;
case 1:
- if (UNIV_UNLIKELY(
- dtype_get_charset_coll(
- dtype_get_prtype(type))
- == DATA_MYSQL_BINARY_CHARSET_COLL)) {
- /* Do not pad BINARY
- columns. */
- return(ULINT_UNDEFINED);
- }
-
/* space=0x20 */
memset(pad_start, 0x20,
pad_end - pad_start);
@@ -597,21 +588,20 @@
trx_t* trx, /* in: transaction */
dict_foreign_t* foreign) /* in: foreign key constraint */
{
- mutex_enter(&srv_misc_tmpfile_mutex);
- rewind(srv_misc_tmpfile);
+
+ FILE* tf = os_file_create_tmpfile();
+
+ if (tf) {
+ ut_print_name(tf, trx, foreign->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(tf, trx,
+ foreign, FALSE);
+
+ trx_set_detailed_error_from_file(trx, tf);
- if (os_file_set_eof(srv_misc_tmpfile)) {
- ut_print_name(srv_misc_tmpfile, trx,
- foreign->foreign_table_name);
- dict_print_info_on_foreign_key_in_create_format(
- srv_misc_tmpfile,
- trx, foreign, FALSE);
- trx_set_detailed_error_from_file(trx, srv_misc_tmpfile);
+ fclose(tf);
} else {
- trx_set_detailed_error(trx, "temp file operation failed");
+ trx_set_detailed_error(trx, "temp file creation failed");
}
-
- mutex_exit(&srv_misc_tmpfile_mutex);
}
/*************************************************************************
@@ -719,7 +709,7 @@
}
if (rec) {
- rec_print(ef, rec, foreign->referenced_index);
+ rec_print(ef, rec, foreign->foreign_index);
}
putc('\n', ef);
--- 1.103.12.1/innobase/row/row0mysql.c 2006-01-16 14:03:55 +03:00
+++ 1.120/storage/innobase/row/row0mysql.c 2006-01-25 15:45:29 +03:00
@@ -626,6 +626,8 @@
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = 99999999;
+ prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
+
prebuilt->sel_graph = NULL;
prebuilt->search_tuple = dtuple_create(heap,
@@ -1436,9 +1438,8 @@
really were set. This function removes a newly set lock under prebuilt->pcur,
and also under prebuilt->clust_pcur. Currently, this is only used and tested
in the case of an UPDATE or a DELETE statement, where the row lock is of the
-LOCK_X or LOCK_S type.
-
-Thus, this implements a 'mini-rollback' that releases the latest record
+LOCK_X type.
+Thus, this implements a 'mini-rollback' that releases the latest record
locks we set. */
int
@@ -1475,14 +1476,7 @@
index = btr_pcur_get_btr_cur(pcur)->index;
- if (UNIV_UNLIKELY(index == NULL)) {
- fprintf(stderr,
-"InnoDB: Error: Index is not set for persistent cursor.\n");
- ut_print_buf(stderr, (const byte*)pcur, sizeof(btr_pcur_t));
- ut_error;
- }
-
- if (trx_new_rec_locks_contain(trx, index)) {
+ if (index != NULL && trx_new_rec_locks_contain(trx, index)) {
mtr_start(&mtr);
@@ -2132,7 +2126,7 @@
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
- err = dict_load_foreigns(name, TRUE);
+ err = dict_load_foreigns(name, trx->check_foreigns);
}
if (err != DB_SUCCESS) {
@@ -3490,7 +3484,8 @@
const char* name) /* in: table name in the form
'database/tablename' */
{
- return(strstr(name, "/#sql") != NULL);
+ /* return(strstr(name, "/#sql") != NULL); */
+ return(strstr(name, "/@0023sql") != NULL);
}
/*************************************************************************
@@ -3590,8 +3585,7 @@
mem_heap_t* heap = NULL;
const char** constraints_to_drop = NULL;
ulint n_constraints_to_drop = 0;
- ibool recovering_temp_table = FALSE;
- ibool old_is_tmp, new_is_tmp;
+ ibool recovering_temp_table = FALSE;
ulint len;
ulint i;
ibool success;
@@ -3631,9 +3625,6 @@
trx->op_info = "renaming table";
trx_start_if_not_started(trx);
- old_is_tmp = row_is_mysql_tmp_table_name(old_name);
- new_is_tmp = row_is_mysql_tmp_table_name(new_name);
-
if (row_mysql_is_recovered_tmp_table(new_name)) {
recovering_temp_table = TRUE;
@@ -3680,7 +3671,7 @@
len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4
+ ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\'');
- if (new_is_tmp) {
+ if (row_is_mysql_tmp_table_name(new_name)) {
db_name_len = dict_get_db_name_len(old_name) + 1;
/* MySQL is doing an ALTER TABLE command and it renames the
@@ -3833,7 +3824,7 @@
the table is stored in a single-table tablespace */
success = dict_table_rename_in_cache(table, new_name,
- !new_is_tmp);
+ !row_is_mysql_tmp_table_name(new_name));
if (!success) {
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, FALSE, NULL);
@@ -3850,16 +3841,19 @@
goto funct_exit;
}
- /* We only want to switch off some of the type checking in
- an ALTER, not in a RENAME. */
-
- err = dict_load_foreigns(new_name,
- old_is_tmp ? trx->check_foreigns : TRUE);
+ err = dict_load_foreigns(new_name, trx->check_foreigns);
- if (err != DB_SUCCESS) {
- ut_print_timestamp(stderr);
+ if (row_is_mysql_tmp_table_name(old_name)) {
+
+ /* MySQL is doing an ALTER TABLE command and it
+ renames the created temporary table to the name
+ of the original table. In the ALTER TABLE we maybe
+ created some FOREIGN KEY constraints for the temporary
+ table. But we want to load also the foreign key
+ constraint definitions for the original table name. */
- if (old_is_tmp) {
+ if (err != DB_SUCCESS) {
+ ut_print_timestamp(stderr);
fputs(" InnoDB: Error: in ALTER TABLE ",
stderr);
ut_print_name(stderr, trx, new_name);
@@ -3867,23 +3861,36 @@
"InnoDB: has or is referenced in foreign key constraints\n"
"InnoDB: which are not compatible with the new table definition.\n",
stderr);
- } else {
+
+ ut_a(dict_table_rename_in_cache(table,
+ old_name, FALSE));
+ trx->error_state = DB_SUCCESS;
+ trx_general_rollback_for_mysql(trx, FALSE,
+ NULL);
+ trx->error_state = DB_SUCCESS;
+ }
+ } else {
+ if (err != DB_SUCCESS) {
+
+ ut_print_timestamp(stderr);
+
fputs(
" InnoDB: Error: in RENAME TABLE table ",
stderr);
ut_print_name(stderr, trx, new_name);
fputs("\n"
- "InnoDB: is referenced in foreign key constraints\n"
- "InnoDB: which are not compatible with the new table definition.\n",
+ "InnoDB: is referenced in foreign key constraints\n"
+ "InnoDB: which are not compatible with the new table definition.\n",
stderr);
- }
-
- ut_a(dict_table_rename_in_cache(table,
+
+ ut_a(dict_table_rename_in_cache(table,
old_name, FALSE));
- trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE,
- NULL);
- trx->error_state = DB_SUCCESS;
+
+ trx->error_state = DB_SUCCESS;
+ trx_general_rollback_for_mysql(trx, FALSE,
+ NULL);
+ trx->error_state = DB_SUCCESS;
+ }
}
}
funct_exit:
--- 1.92.5.1/innobase/row/row0sel.c 2006-01-16 14:03:55 +03:00
+++ 1.100/storage/innobase/row/row0sel.c 2006-01-25 15:45:29 +03:00
@@ -536,6 +536,41 @@
}
/*************************************************************************
+Builds the last committed version of a clustered index record for a
+semi-consistent read. */
+static
+ulint
+row_sel_build_committed_vers_for_mysql(
+/*===================================*/
+ /* out: DB_SUCCESS or error code */
+ dict_index_t* clust_index, /* in: clustered index */
+ row_prebuilt_t* prebuilt, /* in: prebuilt struct */
+ rec_t* rec, /* in: record in a clustered index */
+ ulint** offsets, /* in/out: offsets returned by
+ rec_get_offsets(rec, clust_index) */
+ mem_heap_t** offset_heap, /* in/out: memory heap from which
+ the offsets are allocated */
+ rec_t** old_vers, /* out: old version, or NULL if the
+ record does not exist in the view:
+ i.e., it was freshly inserted
+ afterwards */
+ mtr_t* mtr) /* in: mtr */
+{
+ ulint err;
+
+ if (prebuilt->old_vers_heap) {
+ mem_heap_empty(prebuilt->old_vers_heap);
+ } else {
+ prebuilt->old_vers_heap = mem_heap_create(200);
+ }
+
+ err = row_vers_build_for_semi_consistent_read(rec, mtr, clust_index,
+ offsets, offset_heap,
+ prebuilt->old_vers_heap, old_vers);
+ return(err);
+}
+
+/*************************************************************************
Tests the conditions which determine when the index segment we are searching
through has been exhausted. */
UNIV_INLINE
@@ -2771,8 +2806,8 @@
func_exit:
*out_rec = clust_rec;
- if (prebuilt->select_lock_type != LOCK_NONE) {
- /* We may use the cursor in unlock: store its position */
+ if (prebuilt->select_lock_type == LOCK_X) {
+ /* We may use the cursor in update: store its position */
btr_pcur_store_position(prebuilt->clust_pcur, mtr);
}
@@ -3066,7 +3101,6 @@
rec_t* rec;
rec_t* result_rec;
rec_t* clust_rec;
- rec_t* old_vers;
ulint err = DB_SUCCESS;
ibool unique_search = FALSE;
ibool unique_search_from_clust_index = FALSE;
@@ -3077,6 +3111,11 @@
locking SELECT, and the isolation
level is <= TRX_ISO_READ_COMMITTED,
then this is set to FALSE */
+ ibool did_semi_consistent_read = FALSE;
+ /* if the returned record was locked
+ and we did a semi-consistent read
+ (fetch the newest committed version),
+ then this is set to TRUE */
#ifdef UNIV_SEARCH_DEBUG
ulint cnt = 0;
#endif /* UNIV_SEARCH_DEBUG */
@@ -3163,7 +3202,7 @@
trx->search_latch_timeout = BTR_SEA_TIMEOUT;
}
- /* Reset the new record lock info if we srv_locks_unsafe_for_binlog
+ /* Reset the new record lock info if srv_locks_unsafe_for_binlog
is set. Then we are able to remove the record locks set here on an
individual row. */
@@ -3431,9 +3470,28 @@
clust_index = dict_table_get_first_index(index->table);
if (UNIV_LIKELY(direction != 0)) {
- if (!sel_restore_position_for_mysql(&same_user_rec,
- BTR_SEARCH_LEAF,
- pcur, moves_up, &mtr)) {
+ ibool need_to_process = sel_restore_position_for_mysql(
+ &same_user_rec, BTR_SEARCH_LEAF,
+ pcur, moves_up, &mtr);
+
+ if (UNIV_UNLIKELY(need_to_process)) {
+ if (UNIV_UNLIKELY(prebuilt->row_read_type
+ == ROW_READ_DID_SEMI_CONSISTENT)) {
+ /* We did a semi-consistent read,
+ but the record was removed in
+ the meantime. */
+ prebuilt->row_read_type
+ = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
+ } else if (UNIV_LIKELY(prebuilt->row_read_type
+ != ROW_READ_DID_SEMI_CONSISTENT)) {
+
+ /* The cursor was positioned on the record
+ that we returned previously. If we need
+ to repeat a semi-consistent read as a
+ pessimistic locking read, the record
+ cannot be skipped. */
+
goto next_rec;
}
@@ -3751,7 +3809,64 @@
prebuilt->select_lock_type,
lock_type, thr);
- if (err != DB_SUCCESS) {
+ switch (err) {
+ rec_t* old_vers;
+ case DB_SUCCESS:
+ break;
+ case DB_LOCK_WAIT:
+ if (UNIV_LIKELY(prebuilt->row_read_type
+ != ROW_READ_TRY_SEMI_CONSISTENT)
+ || index != clust_index) {
+
+ goto lock_wait_or_error;
+ }
+
+ /* The following call returns 'offsets'
+ associated with 'old_vers' */
+ err = row_sel_build_committed_vers_for_mysql(
+ clust_index, prebuilt, rec,
+ &offsets, &heap,
+ &old_vers, &mtr);
+
+ if (err != DB_SUCCESS) {
+
+ goto lock_wait_or_error;
+ }
+
+ mutex_enter(&kernel_mutex);
+ if (trx->was_chosen_as_deadlock_victim) {
+ mutex_exit(&kernel_mutex);
+
+ goto lock_wait_or_error;
+ }
+ if (UNIV_LIKELY(trx->wait_lock != NULL)) {
+ lock_cancel_waiting_and_release(
+ trx->wait_lock);
+ trx_reset_new_rec_lock_info(trx);
+ } else {
+ mutex_exit(&kernel_mutex);
+
+ /* The lock was granted while we were
+ searching for the last committed version.
+ Do a normal locking read. */
+
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ err = DB_SUCCESS;
+ break;
+ }
+ mutex_exit(&kernel_mutex);
+
+ if (old_vers == NULL) {
+ /* The row was not yet committed */
+
+ goto next_rec;
+ }
+
+ did_semi_consistent_read = TRUE;
+ rec = old_vers;
+ break;
+ default:
goto lock_wait_or_error;
}
@@ -3775,6 +3890,7 @@
&& !lock_clust_rec_cons_read_sees(rec, index,
offsets, trx->read_view)) {
+ rec_t* old_vers;
/* The following call returns 'offsets'
associated with 'old_vers' */
err = row_sel_build_prev_vers_for_mysql(
@@ -3821,14 +3937,13 @@
/* The record is delete-marked: we can skip it */
if (srv_locks_unsafe_for_binlog
- && prebuilt->select_lock_type != LOCK_NONE) {
+ && prebuilt->select_lock_type != LOCK_NONE
+ && !did_semi_consistent_read) {
/* No need to keep a lock on a delete-marked record
if we do not want to use next-key locking. */
row_unlock_for_mysql(prebuilt, TRUE);
-
- trx_reset_new_rec_lock_info(trx);
}
goto next_rec;
@@ -3882,8 +3997,6 @@
locking. */
row_unlock_for_mysql(prebuilt, TRUE);
-
- trx_reset_new_rec_lock_info(trx);
}
goto next_rec;
@@ -3972,9 +4085,9 @@
/* We have an optimization to save CPU time: if this is a consistent
read on a unique condition on the clustered index, then we do not
store the pcur position, because any fetch next or prev will anyway
- return 'end of file'. Exceptions are locking reads and the MySQL
- HANDLER command where the user can move the cursor with PREV or NEXT
- even after a unique search. */
+ return 'end of file'. An exception is the MySQL HANDLER command
+ where the user can move the cursor with PREV or NEXT even after
+ a unique search. */
if (!unique_search_from_clust_index
|| prebuilt->select_lock_type != LOCK_NONE
@@ -3990,6 +4103,19 @@
goto normal_return;
next_rec:
+ /* Reset the old and new "did semi-consistent read" flags. */
+ if (UNIV_UNLIKELY(prebuilt->row_read_type
+ == ROW_READ_DID_SEMI_CONSISTENT)) {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
+ did_semi_consistent_read = FALSE;
+
+ if (UNIV_UNLIKELY(srv_locks_unsafe_for_binlog)
+ && prebuilt->select_lock_type != LOCK_NONE) {
+
+ trx_reset_new_rec_lock_info(trx);
+ }
+
/*-------------------------------------------------------------*/
/* PHASE 5: Move the cursor to the next index record */
@@ -4042,8 +4168,14 @@
goto rec_loop;
lock_wait_or_error:
- /*-------------------------------------------------------------*/
+ /* Reset the old and new "did semi-consistent read" flags. */
+ if (UNIV_UNLIKELY(prebuilt->row_read_type
+ == ROW_READ_DID_SEMI_CONSISTENT)) {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
+ did_semi_consistent_read = FALSE;
+ /*-------------------------------------------------------------*/
btr_pcur_store_position(pcur, &mtr);
mtr_commit(&mtr);
@@ -4125,6 +4257,20 @@
trx->op_info = "";
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
+ }
+
+ /* Set or reset the "did semi-consistent read" flag on return.
+ The flag did_semi_consistent_read is set if and only if
+ the record being returned was fetched with a semi-consistent read. */
+ ut_ad(prebuilt->row_read_type != ROW_READ_WITH_LOCKS
+ || !did_semi_consistent_read);
+
+ if (UNIV_UNLIKELY(prebuilt->row_read_type != ROW_READ_WITH_LOCKS)) {
+ if (UNIV_UNLIKELY(did_semi_consistent_read)) {
+ prebuilt->row_read_type = ROW_READ_DID_SEMI_CONSISTENT;
+ } else {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
}
return(err);
}
--- 1.54.8.1/innobase/trx/trx0trx.c 2006-01-16 14:03:55 +03:00
+++ 1.62/storage/innobase/trx/trx0trx.c 2006-01-25 15:45:29 +03:00
@@ -794,8 +794,7 @@
in trx sys header if MySQL binlogging is on or the database
server is a MySQL replication slave */
- if (trx->mysql_log_file_name
- && trx->mysql_log_file_name[0] != '\0') {
+ if (trx->mysql_log_file_name) {
trx_sys_update_mysql_binlog_offset(
trx->mysql_log_file_name,
trx->mysql_log_offset,
| Thread |
|---|
| • bk commit into 5.1 tree (aivanov:1.2078) | Alex Ivanov | 25 Jan |