mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge
BitKeeper/etc/logging_ok: auto-union BUILD/autorun.sh: Auto merged BitKeeper/etc/config: Auto merged Makefile.am: Auto merged include/my_bitmap.h: Auto merged libmysqld/Makefile.am: Auto merged mysql-test/mysql-test-run.pl: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/grant.result: Auto merged mysql-test/r/ps_6bdb.result: Auto merged mysql-test/r/ps_7ndb.result: Auto merged mysys/Makefile.am: Auto merged mysys/default.c: Auto merged scripts/mysql_create_system_tables.sh: Auto merged scripts/mysql_fix_privilege_tables.sql: Auto merged sql/Makefile.am: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged sql/ha_ndbcluster.h: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item.cc: Auto merged sql/log_event.cc: Auto merged sql/mysql_priv.h: Auto merged sql/opt_range.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_acl.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_delete.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_udf.cc: Auto merged sql/sql_yacc.yy: Auto merged storage/heap/Makefile.am: Auto merged storage/heap/hp_hash.c: Auto merged storage/innobase/btr/btr0btr.c: Auto merged storage/innobase/btr/btr0cur.c: Auto merged storage/innobase/configure.in: Auto merged storage/innobase/fil/fil0fil.c: Auto merged storage/innobase/ibuf/ibuf0ibuf.c: Auto merged storage/innobase/include/os0file.h: Auto merged storage/innobase/include/page0cur.h: Auto merged storage/innobase/include/row0mysql.h: Auto merged storage/innobase/include/srv0srv.h: Auto merged storage/innobase/include/trx0trx.h: Auto merged storage/innobase/include/trx0trx.ic: Auto merged storage/innobase/lock/lock0lock.c: Auto merged storage/innobase/log/log0recv.c: Auto merged storage/innobase/os/os0file.c: Auto merged storage/innobase/page/page0cur.c: Auto merged storage/innobase/page/page0page.c: Auto merged storage/innobase/rem/rem0rec.c: Auto merged storage/innobase/row/row0mysql.c: Auto merged storage/innobase/row/row0sel.c: Auto merged storage/innobase/row/row0upd.c: Auto merged storage/innobase/srv/srv0srv.c: Auto merged storage/innobase/trx/trx0trx.c: Auto merged storage/innobase/trx/trx0undo.c: Auto merged storage/myisam/Makefile.am: Auto merged storage/myisam/mi_create.c: Auto merged storage/myisam/mi_open.c: Auto merged storage/myisam/mi_packrec.c: Auto merged storage/myisam/mi_unique.c: Auto merged storage/myisam/myisampack.c: Auto merged storage/myisammrg/Makefile.am: Auto merged storage/ndb/include/mgmcommon/ConfigRetriever.hpp: Auto merged storage/ndb/include/transporter/TransporterDefinitions.hpp: Auto merged storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: Auto merged storage/ndb/src/mgmsrv/main.cpp: Auto merged storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp: Auto merged storage/ndb/test/ndbapi/create_tab.cpp: Auto merged storage/ndb/test/ndbapi/testBlobs.cpp: Auto merged strings/ctype-big5.c: Auto merged strings/ctype-ucs2.c: Auto merged support-files/mysql.spec.sh: Auto merged configure.in: merge mysql-test/t/disabled.def: merge mysys/my_bitmap.c: SCCS merged sql/ha_federated.cc: merge sql/ha_innodb.cc: merge sql/ha_ndbcluster.cc: merge sql/mysqld.cc: e merge sql/sql_insert.cc: merge sql/sql_lex.h: merge sql/sql_load.cc: merge sql/sql_select.cc: merge e C sql/sql_update.cc: merge sql/table.cc: merge
This commit is contained in:
@ -14,7 +14,7 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
LDADD = libheap.a $(top_srcdir)/mysys/libmysys.a \
|
||||
$(top_srcdir)/dbug/libdbug.a \
|
||||
$(top_srcdir)/strings/libmystrings.a
|
||||
|
@ -552,9 +552,9 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2,
|
||||
if (cs->mbmaxlen > 1)
|
||||
{
|
||||
uint char_length= seg->length / cs->mbmaxlen;
|
||||
char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length);
|
||||
char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length1);
|
||||
set_if_smaller(char_length1, seg->length);
|
||||
char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
|
||||
char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length2);
|
||||
set_if_smaller(char_length2, seg->length);
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ btr_root_get(
|
||||
root_page_no = dict_tree_get_page(tree);
|
||||
|
||||
root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr);
|
||||
ut_a(!!page_is_comp(root) ==
|
||||
ut_a((ibool)!!page_is_comp(root) ==
|
||||
UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp);
|
||||
|
||||
return(root);
|
||||
@ -2014,7 +2014,7 @@ btr_compress(
|
||||
page = btr_cur_get_page(cursor);
|
||||
tree = btr_cur_get_tree(cursor);
|
||||
comp = page_is_comp(page);
|
||||
ut_a(!!comp == cursor->index->table->comp);
|
||||
ut_a((ibool)!!comp == cursor->index->table->comp);
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
|
||||
MTR_MEMO_X_LOCK));
|
||||
@ -2508,7 +2508,7 @@ btr_index_rec_validate(
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(!!page_is_comp(page) != index->table->comp)) {
|
||||
if (UNIV_UNLIKELY((ibool)!!page_is_comp(page) != index->table->comp)) {
|
||||
btr_index_rec_validate_report(page, rec, index);
|
||||
fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n",
|
||||
(ulong) !!page_is_comp(page),
|
||||
|
@ -316,7 +316,9 @@ btr_cur_search_to_nth_level(
|
||||
if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED
|
||||
&& latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ
|
||||
&& !estimate
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
&& mode != PAGE_CUR_LE_OR_EXTENDS
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
&& srv_use_adaptive_hash_indexes
|
||||
&& btr_search_guess_on_hash(index, info, tuple, mode,
|
||||
latch_mode, cursor,
|
||||
@ -390,9 +392,12 @@ btr_cur_search_to_nth_level(
|
||||
page_mode = PAGE_CUR_LE;
|
||||
break;
|
||||
default:
|
||||
ut_ad(mode == PAGE_CUR_L
|
||||
|| mode == PAGE_CUR_LE
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE
|
||||
|| mode == PAGE_CUR_LE_OR_EXTENDS);
|
||||
#else /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE);
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
page_mode = mode;
|
||||
break;
|
||||
}
|
||||
@ -507,7 +512,7 @@ retry_page_get:
|
||||
/* x-latch the page */
|
||||
page = btr_page_get(space,
|
||||
page_no, RW_X_LATCH, mtr);
|
||||
ut_a(!!page_is_comp(page)
|
||||
ut_a((ibool)!!page_is_comp(page)
|
||||
== index->table->comp);
|
||||
}
|
||||
|
||||
@ -1385,7 +1390,7 @@ btr_cur_parse_update_in_place(
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
ut_a(!!page_is_comp(page) == index->table->comp);
|
||||
ut_a((ibool)!!page_is_comp(page) == index->table->comp);
|
||||
rec = page + rec_offset;
|
||||
|
||||
/* We do not need to reserve btr_search_latch, as the page is only
|
||||
|
@ -117,6 +117,13 @@ case "$target" in
|
||||
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
|
||||
esac
|
||||
|
||||
# must go in pair with AR as set by MYSQL_CHECK_AR
|
||||
if test -z "$ARFLAGS"
|
||||
then
|
||||
ARFLAGS="cru"
|
||||
fi
|
||||
AC_SUBST(ARFLAGS)
|
||||
|
||||
AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile dnl
|
||||
buf/Makefile data/Makefile dnl
|
||||
dict/Makefile dyn/Makefile dnl
|
||||
|
@ -3410,9 +3410,9 @@ fil_extend_space_to_desired_size(
|
||||
fil_space_t* space;
|
||||
byte* buf2;
|
||||
byte* buf;
|
||||
ulint buf_size;
|
||||
ulint start_page_no;
|
||||
ulint file_start_page_no;
|
||||
ulint n_pages;
|
||||
ulint offset_high;
|
||||
ulint offset_low;
|
||||
ibool success = TRUE;
|
||||
@ -3437,22 +3437,20 @@ fil_extend_space_to_desired_size(
|
||||
|
||||
fil_node_prepare_for_io(node, system, space);
|
||||
|
||||
/* Extend 1 MB at a time */
|
||||
|
||||
buf2 = mem_alloc(1024 * 1024 + UNIV_PAGE_SIZE);
|
||||
buf = ut_align(buf2, UNIV_PAGE_SIZE);
|
||||
|
||||
memset(buf, '\0', 1024 * 1024);
|
||||
|
||||
start_page_no = space->size;
|
||||
file_start_page_no = space->size - node->size;
|
||||
|
||||
while (start_page_no < size_after_extend) {
|
||||
n_pages = size_after_extend - start_page_no;
|
||||
/* Extend at most 64 pages at a time */
|
||||
buf_size = ut_min(64, size_after_extend - start_page_no)
|
||||
* UNIV_PAGE_SIZE;
|
||||
buf2 = mem_alloc(buf_size + UNIV_PAGE_SIZE);
|
||||
buf = ut_align(buf2, UNIV_PAGE_SIZE);
|
||||
|
||||
if (n_pages > (1024 * 1024) / UNIV_PAGE_SIZE) {
|
||||
n_pages = (1024 * 1024) / UNIV_PAGE_SIZE;
|
||||
}
|
||||
memset(buf, 0, buf_size);
|
||||
|
||||
while (start_page_no < size_after_extend) {
|
||||
ulint n_pages = ut_min(buf_size / UNIV_PAGE_SIZE,
|
||||
size_after_extend - start_page_no);
|
||||
|
||||
offset_high = (start_page_no - file_start_page_no)
|
||||
/ (4096 * ((1024 * 1024) / UNIV_PAGE_SIZE));
|
||||
@ -4034,7 +4032,7 @@ fil_aio_wait(
|
||||
if (os_aio_use_native_aio) {
|
||||
srv_set_io_thread_op_info(segment, "native aio handle");
|
||||
#ifdef WIN_ASYNC_IO
|
||||
ret = os_aio_windows_handle(segment, 0, (void**) &fil_node,
|
||||
ret = os_aio_windows_handle(segment, 0, &fil_node,
|
||||
&message, &type);
|
||||
#elif defined(POSIX_ASYNC_IO)
|
||||
ret = os_aio_posix_handle(segment, &fil_node, &message);
|
||||
|
@ -2810,7 +2810,7 @@ ibuf_insert_to_index_page(
|
||||
ut_ad(ibuf_inside());
|
||||
ut_ad(dtuple_check_typed(entry));
|
||||
|
||||
if (UNIV_UNLIKELY(index->table->comp != !!page_is_comp(page))) {
|
||||
if (UNIV_UNLIKELY(index->table->comp != (ibool)!!page_is_comp(page))) {
|
||||
fputs(
|
||||
"InnoDB: Trying to insert a record from the insert buffer to an index page\n"
|
||||
"InnoDB: but the 'compact' flag does not match!\n", stderr);
|
||||
|
@ -373,7 +373,7 @@ os_file_get_size_as_iblonglong(
|
||||
/* out: size in bytes, -1 if error */
|
||||
os_file_t file); /* in: handle to a file */
|
||||
/***************************************************************************
|
||||
Sets a file size. This function can be used to extend or truncate a file. */
|
||||
Write the specified number of zeros to a newly created file. */
|
||||
|
||||
ibool
|
||||
os_file_set_size(
|
||||
|
@ -26,11 +26,13 @@ Created 10/4/1994 Heikki Tuuri
|
||||
#define PAGE_CUR_GE 2
|
||||
#define PAGE_CUR_L 3
|
||||
#define PAGE_CUR_LE 4
|
||||
#define PAGE_CUR_LE_OR_EXTENDS 5 /* This is a search mode used in
|
||||
/*#define PAGE_CUR_LE_OR_EXTENDS 5*/ /* This is a search mode used in
|
||||
"column LIKE 'abc%' ORDER BY column DESC";
|
||||
we have to find strings which are <= 'abc' or
|
||||
which extend it */
|
||||
#define PAGE_CUR_DBG 6
|
||||
#ifdef UNIV_SEARCH_DEBUG
|
||||
# define PAGE_CUR_DBG 6 /* As PAGE_CUR_LE, but skips search shortcut */
|
||||
#endif /* UNIV_SEARCH_DEBUG */
|
||||
|
||||
#ifdef PAGE_CUR_ADAPT
|
||||
# ifdef UNIV_SEARCH_PERF_STAT
|
||||
|
@ -243,17 +243,27 @@ row_update_for_mysql(
|
||||
the MySQL format */
|
||||
row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
|
||||
handle */
|
||||
|
||||
/*************************************************************************
|
||||
Does an unlock of a row for MySQL. */
|
||||
This can only be used when srv_locks_unsafe_for_binlog is TRUE. Before
|
||||
calling this function we must use trx_reset_new_rec_lock_info() and
|
||||
trx_register_new_rec_lock() to store the information which new record locks
|
||||
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 type.
|
||||
Thus, this implements a 'mini-rollback' that releases the latest record
|
||||
locks we set. */
|
||||
|
||||
int
|
||||
row_unlock_for_mysql(
|
||||
/*=================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
|
||||
row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
|
||||
handle */
|
||||
|
||||
ibool has_latches_on_recs);/* TRUE if called so that we have
|
||||
the latches on the records under pcur
|
||||
and clust_pcur, and we do not need to
|
||||
reposition the cursors. */
|
||||
/*************************************************************************
|
||||
Creates an query graph node of 'update' type to be used in the MySQL
|
||||
interface. */
|
||||
|
@ -182,6 +182,7 @@ extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
|
||||
#define kernel_mutex (*kernel_mutex_temp)
|
||||
|
||||
#define SRV_MAX_N_IO_THREADS 100
|
||||
#define SRV_CONCURRENCY_THRESHOLD 20
|
||||
|
||||
/* Array of English strings describing the current state of an
|
||||
i/o handler thread */
|
||||
|
@ -16,10 +16,39 @@ Created 3/26/1996 Heikki Tuuri
|
||||
#include "que0types.h"
|
||||
#include "mem0mem.h"
|
||||
#include "read0types.h"
|
||||
#include "dict0types.h"
|
||||
#include "trx0xa.h"
|
||||
|
||||
extern ulint trx_n_mysql_transactions;
|
||||
|
||||
/*****************************************************************
|
||||
Resets the new record lock info in a transaction struct. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_reset_new_rec_lock_info(
|
||||
/*========================*/
|
||||
trx_t* trx); /* in: transaction struct */
|
||||
/*****************************************************************
|
||||
Registers that we have set a new record lock on an index. We only have space
|
||||
to store 2 indexes! If this is called to store more than 2 indexes after
|
||||
trx_reset_new_rec_lock_info(), then this function does nothing. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_register_new_rec_lock(
|
||||
/*======================*/
|
||||
trx_t* trx, /* in: transaction struct */
|
||||
dict_index_t* index); /* in: trx sets a new record lock on this
|
||||
index */
|
||||
/*****************************************************************
|
||||
Checks if trx has set a new record lock on an index. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_new_rec_locks_contain(
|
||||
/*======================*/
|
||||
/* out: TRUE if trx has set a new record lock
|
||||
on index */
|
||||
trx_t* trx, /* in: transaction struct */
|
||||
dict_index_t* index); /* in: index */
|
||||
/************************************************************************
|
||||
Releases the search latch if trx has reserved it. */
|
||||
|
||||
@ -495,8 +524,18 @@ struct trx_struct{
|
||||
lock_t* auto_inc_lock; /* possible auto-inc lock reserved by
|
||||
the transaction; note that it is also
|
||||
in the lock list trx_locks */
|
||||
ibool trx_create_lock;/* this is TRUE if we have created a
|
||||
new lock for a record accessed */
|
||||
dict_index_t* new_rec_locks[2];/* these are normally NULL; if
|
||||
srv_locks_unsafe_for_binlog is TRUE,
|
||||
in a cursor search, if we set a new
|
||||
record lock on an index, this is set
|
||||
to point to the index; this is
|
||||
used in releasing the locks under the
|
||||
cursors if we are performing an UPDATE
|
||||
and we determine after retrieving
|
||||
the row that it does not need to be
|
||||
locked; thus, these can be used to
|
||||
implement a 'mini-rollback' that
|
||||
releases the latest record locks */
|
||||
UT_LIST_NODE_T(trx_t)
|
||||
trx_list; /* list of transactions */
|
||||
UT_LIST_NODE_T(trx_t)
|
||||
|
@ -39,4 +39,60 @@ trx_start_if_not_started_low(
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Resets the new record lock info in a transaction struct. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_reset_new_rec_lock_info(
|
||||
/*========================*/
|
||||
trx_t* trx) /* in: transaction struct */
|
||||
{
|
||||
trx->new_rec_locks[0] = NULL;
|
||||
trx->new_rec_locks[1] = NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Registers that we have set a new record lock on an index. We only have space
|
||||
to store 2 indexes! If this is called to store more than 2 indexes after
|
||||
trx_reset_new_rec_lock_info(), then this function does nothing. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_register_new_rec_lock(
|
||||
/*======================*/
|
||||
trx_t* trx, /* in: transaction struct */
|
||||
dict_index_t* index) /* in: trx sets a new record lock on this
|
||||
index */
|
||||
{
|
||||
if (trx->new_rec_locks[0] == NULL) {
|
||||
trx->new_rec_locks[0] = index;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (trx->new_rec_locks[0] == index) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (trx->new_rec_locks[1] != NULL) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
trx->new_rec_locks[1] = index;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Checks if trx has set a new record lock on an index. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_new_rec_locks_contain(
|
||||
/*======================*/
|
||||
/* out: TRUE if trx has set a new record lock
|
||||
on index */
|
||||
trx_t* trx, /* in: transaction struct */
|
||||
dict_index_t* index) /* in: index */
|
||||
{
|
||||
return(trx->new_rec_locks[0] == index
|
||||
|| trx->new_rec_locks[1] == index);
|
||||
}
|
||||
|
@ -956,7 +956,7 @@ lock_rec_has_to_wait(
|
||||
cause waits */
|
||||
|
||||
if ((lock_is_on_supremum || (type_mode & LOCK_GAP))
|
||||
&& !(type_mode & LOCK_INSERT_INTENTION)) {
|
||||
&& !(type_mode & LOCK_INSERT_INTENTION)) {
|
||||
|
||||
/* Gap type locks without LOCK_INSERT_INTENTION flag
|
||||
do not need to wait for anything. This is because
|
||||
@ -1765,10 +1765,7 @@ lock_rec_create(
|
||||
lock_rec_set_nth_bit(lock, heap_no);
|
||||
|
||||
HASH_INSERT(lock_t, hash, lock_sys->rec_hash,
|
||||
lock_rec_fold(space, page_no), lock);
|
||||
/* Note that we have create a new lock */
|
||||
trx->trx_create_lock = TRUE;
|
||||
|
||||
lock_rec_fold(space, page_no), lock);
|
||||
if (type_mode & LOCK_WAIT) {
|
||||
|
||||
lock_set_lock_and_trx_wait(lock, trx);
|
||||
@ -1945,15 +1942,6 @@ lock_rec_add_to_queue(
|
||||
|
||||
if (similar_lock && !somebody_waits && !(type_mode & LOCK_WAIT)) {
|
||||
|
||||
/* If the nth bit of a record lock is already set then we
|
||||
do not set a new lock bit, otherwice we set */
|
||||
|
||||
if (lock_rec_get_nth_bit(similar_lock, heap_no)) {
|
||||
trx->trx_create_lock = FALSE;
|
||||
} else {
|
||||
trx->trx_create_lock = TRUE;
|
||||
}
|
||||
|
||||
lock_rec_set_nth_bit(similar_lock, heap_no);
|
||||
|
||||
return(similar_lock);
|
||||
@ -2005,11 +1993,14 @@ lock_rec_lock_fast(
|
||||
lock = lock_rec_get_first_on_page(rec);
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
trx->trx_create_lock = FALSE;
|
||||
|
||||
if (lock == NULL) {
|
||||
if (!impl) {
|
||||
lock_rec_create(mode, rec, index, trx);
|
||||
|
||||
if (srv_locks_unsafe_for_binlog) {
|
||||
trx_register_new_rec_lock(trx, index);
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
@ -2021,23 +2012,22 @@ lock_rec_lock_fast(
|
||||
}
|
||||
|
||||
if (lock->trx != trx
|
||||
|| lock->type_mode != (mode | LOCK_REC)
|
||||
|| lock_rec_get_n_bits(lock) <= heap_no) {
|
||||
|| lock->type_mode != (mode | LOCK_REC)
|
||||
|| lock_rec_get_n_bits(lock) <= heap_no) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (!impl) {
|
||||
/* If the nth bit of the record lock is already set then we
|
||||
do not set a new lock bit, otherwise we do set */
|
||||
|
||||
/* If the nth bit of a record lock is already set then we
|
||||
do not set a new lock bit, otherwice we set */
|
||||
|
||||
if (lock_rec_get_nth_bit(lock, heap_no)) {
|
||||
trx->trx_create_lock = FALSE;
|
||||
} else {
|
||||
trx->trx_create_lock = TRUE;
|
||||
if (!lock_rec_get_nth_bit(lock, heap_no)) {
|
||||
lock_rec_set_nth_bit(lock, heap_no);
|
||||
if (srv_locks_unsafe_for_binlog) {
|
||||
trx_register_new_rec_lock(trx, index);
|
||||
}
|
||||
}
|
||||
|
||||
lock_rec_set_nth_bit(lock, heap_no);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
@ -2093,12 +2083,19 @@ lock_rec_lock_slow(
|
||||
enough already granted on the record, we have to wait. */
|
||||
|
||||
err = lock_rec_enqueue_waiting(mode, rec, index, thr);
|
||||
|
||||
if (srv_locks_unsafe_for_binlog) {
|
||||
trx_register_new_rec_lock(trx, index);
|
||||
}
|
||||
} else {
|
||||
if (!impl) {
|
||||
/* Set the requested lock on the record */
|
||||
|
||||
lock_rec_add_to_queue(LOCK_REC | mode, rec, index,
|
||||
trx);
|
||||
if (srv_locks_unsafe_for_binlog) {
|
||||
trx_register_new_rec_lock(trx, index);
|
||||
}
|
||||
}
|
||||
|
||||
err = DB_SUCCESS;
|
||||
@ -2436,8 +2433,15 @@ lock_rec_inherit_to_gap(
|
||||
|
||||
lock = lock_rec_get_first(rec);
|
||||
|
||||
/* If srv_locks_unsafe_for_binlog is TRUE, we do not want locks set
|
||||
by an UPDATE or a DELETE to be inherited as gap type locks. But we
|
||||
DO want S-locks set by a consistency constraint to be inherited also
|
||||
then. */
|
||||
|
||||
while (lock != NULL) {
|
||||
if (!lock_rec_get_insert_intention(lock)) {
|
||||
if (!lock_rec_get_insert_intention(lock)
|
||||
&& !(srv_locks_unsafe_for_binlog
|
||||
&& lock_get_mode(lock) == LOCK_X)) {
|
||||
|
||||
lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock)
|
||||
| LOCK_GAP,
|
||||
@ -3069,7 +3073,7 @@ lock_update_insert(
|
||||
lock_rec_inherit_to_gap_if_gap_lock(rec, page_rec_get_next(rec));
|
||||
|
||||
lock_mutex_exit_kernel();
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Updates the lock table when a record is removed. */
|
||||
|
@ -768,7 +768,8 @@ recv_parse_or_apply_log_rec_body(
|
||||
case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
|
||||
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
|
||||
type == MLOG_COMP_REC_INSERT, &index))) {
|
||||
ut_a(!page||!!page_is_comp(page)==index->table->comp);
|
||||
ut_a(!page
|
||||
|| (ibool)!!page_is_comp(page)==index->table->comp);
|
||||
ptr = page_cur_parse_insert_rec(FALSE, ptr, end_ptr,
|
||||
index, page, mtr);
|
||||
}
|
||||
@ -776,7 +777,8 @@ recv_parse_or_apply_log_rec_body(
|
||||
case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
|
||||
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
|
||||
type == MLOG_COMP_REC_CLUST_DELETE_MARK, &index))) {
|
||||
ut_a(!page||!!page_is_comp(page)==index->table->comp);
|
||||
ut_a(!page
|
||||
|| (ibool)!!page_is_comp(page)==index->table->comp);
|
||||
ptr = btr_cur_parse_del_mark_set_clust_rec(ptr,
|
||||
end_ptr, index, page);
|
||||
}
|
||||
@ -796,7 +798,8 @@ recv_parse_or_apply_log_rec_body(
|
||||
case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
|
||||
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
|
||||
type == MLOG_COMP_REC_UPDATE_IN_PLACE, &index))) {
|
||||
ut_a(!page||!!page_is_comp(page)==index->table->comp);
|
||||
ut_a(!page
|
||||
|| (ibool)!!page_is_comp(page)==index->table->comp);
|
||||
ptr = btr_cur_parse_update_in_place(ptr, end_ptr,
|
||||
page, index);
|
||||
}
|
||||
@ -806,7 +809,8 @@ recv_parse_or_apply_log_rec_body(
|
||||
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
|
||||
type == MLOG_COMP_LIST_END_DELETE
|
||||
|| type == MLOG_COMP_LIST_START_DELETE, &index))) {
|
||||
ut_a(!page||!!page_is_comp(page)==index->table->comp);
|
||||
ut_a(!page
|
||||
|| (ibool)!!page_is_comp(page)==index->table->comp);
|
||||
ptr = page_parse_delete_rec_list(type, ptr, end_ptr,
|
||||
index, page, mtr);
|
||||
}
|
||||
@ -814,7 +818,8 @@ recv_parse_or_apply_log_rec_body(
|
||||
case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
|
||||
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
|
||||
type == MLOG_COMP_LIST_END_COPY_CREATED, &index))) {
|
||||
ut_a(!page||!!page_is_comp(page)==index->table->comp);
|
||||
ut_a(!page
|
||||
|| (ibool)!!page_is_comp(page)==index->table->comp);
|
||||
ptr = page_parse_copy_rec_list_to_created_page(ptr,
|
||||
end_ptr, index, page, mtr);
|
||||
}
|
||||
@ -822,7 +827,8 @@ recv_parse_or_apply_log_rec_body(
|
||||
case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
|
||||
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
|
||||
type == MLOG_COMP_PAGE_REORGANIZE, &index))) {
|
||||
ut_a(!page||!!page_is_comp(page)==index->table->comp);
|
||||
ut_a(!page
|
||||
|| (ibool)!!page_is_comp(page)==index->table->comp);
|
||||
ptr = btr_parse_page_reorganize(ptr, end_ptr, index,
|
||||
page, mtr);
|
||||
}
|
||||
@ -855,7 +861,8 @@ recv_parse_or_apply_log_rec_body(
|
||||
case MLOG_REC_DELETE: case MLOG_COMP_REC_DELETE:
|
||||
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
|
||||
type == MLOG_COMP_REC_DELETE, &index))) {
|
||||
ut_a(!page||!!page_is_comp(page)==index->table->comp);
|
||||
ut_a(!page
|
||||
|| (ibool)!!page_is_comp(page)==index->table->comp);
|
||||
ptr = page_cur_parse_delete_rec(ptr, end_ptr,
|
||||
index, page, mtr);
|
||||
}
|
||||
|
@ -1653,7 +1653,7 @@ os_file_get_size_as_iblonglong(
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Sets a file size. This function can be used to extend or truncate a file. */
|
||||
Write the specified number of zeros to a newly created file. */
|
||||
|
||||
ibool
|
||||
os_file_set_size(
|
||||
@ -1666,44 +1666,46 @@ os_file_set_size(
|
||||
size */
|
||||
ulint size_high)/* in: most significant 32 bits of size */
|
||||
{
|
||||
ib_longlong offset;
|
||||
ib_longlong low;
|
||||
ulint n_bytes;
|
||||
ib_longlong current_size;
|
||||
ib_longlong desired_size;
|
||||
ibool ret;
|
||||
byte* buf;
|
||||
byte* buf2;
|
||||
ulint buf_size;
|
||||
|
||||
ut_a(size == (size & 0xFFFFFFFF));
|
||||
|
||||
/* We use a very big 8 MB buffer in writing because Linux may be
|
||||
extremely slow in fsync on 1 MB writes */
|
||||
current_size = 0;
|
||||
desired_size = (ib_longlong)size + (((ib_longlong)size_high) << 32);
|
||||
|
||||
buf2 = ut_malloc(UNIV_PAGE_SIZE * 513);
|
||||
/* Write up to 1 megabyte at a time. */
|
||||
buf_size = ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE))
|
||||
* UNIV_PAGE_SIZE;
|
||||
buf2 = ut_malloc(buf_size + UNIV_PAGE_SIZE);
|
||||
|
||||
/* Align the buffer for possible raw i/o */
|
||||
buf = ut_align(buf2, UNIV_PAGE_SIZE);
|
||||
|
||||
/* Write buffer full of zeros */
|
||||
memset(buf, 0, UNIV_PAGE_SIZE * 512);
|
||||
memset(buf, 0, buf_size);
|
||||
|
||||
offset = 0;
|
||||
low = (ib_longlong)size + (((ib_longlong)size_high) << 32);
|
||||
|
||||
if (low >= (ib_longlong)(100 * 1024 * 1024)) {
|
||||
if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
|
||||
|
||||
fprintf(stderr, "InnoDB: Progress in MB:");
|
||||
}
|
||||
|
||||
while (offset < low) {
|
||||
if (low - offset < UNIV_PAGE_SIZE * 512) {
|
||||
n_bytes = (ulint)(low - offset);
|
||||
} else {
|
||||
n_bytes = UNIV_PAGE_SIZE * 512;
|
||||
}
|
||||
|
||||
while (current_size < desired_size) {
|
||||
ulint n_bytes;
|
||||
|
||||
if (desired_size - current_size < (ib_longlong) buf_size) {
|
||||
n_bytes = (ulint) (desired_size - current_size);
|
||||
} else {
|
||||
n_bytes = buf_size;
|
||||
}
|
||||
|
||||
ret = os_file_write(name, file, buf,
|
||||
(ulint)(offset & 0xFFFFFFFF),
|
||||
(ulint)(offset >> 32),
|
||||
(ulint)(current_size & 0xFFFFFFFF),
|
||||
(ulint)(current_size >> 32),
|
||||
n_bytes);
|
||||
if (!ret) {
|
||||
ut_free(buf2);
|
||||
@ -1711,18 +1713,18 @@ os_file_set_size(
|
||||
}
|
||||
|
||||
/* Print about progress for each 100 MB written */
|
||||
if ((ib_longlong) (offset + n_bytes) / (ib_longlong)(100 * 1024 * 1024)
|
||||
!= offset / (ib_longlong)(100 * 1024 * 1024)) {
|
||||
if ((current_size + n_bytes) / (ib_longlong)(100 * 1024 * 1024)
|
||||
!= current_size / (ib_longlong)(100 * 1024 * 1024)) {
|
||||
|
||||
fprintf(stderr, " %lu00",
|
||||
(ulong) ((offset + n_bytes)
|
||||
(ulong) ((current_size + n_bytes)
|
||||
/ (ib_longlong)(100 * 1024 * 1024)));
|
||||
}
|
||||
|
||||
offset += n_bytes;
|
||||
current_size += n_bytes;
|
||||
}
|
||||
|
||||
if (low >= (ib_longlong)(100 * 1024 * 1024)) {
|
||||
if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
@ -3296,7 +3298,7 @@ os_aio(
|
||||
ibool retval;
|
||||
BOOL ret = TRUE;
|
||||
DWORD len = (DWORD) n;
|
||||
void* dummy_mess1;
|
||||
struct fil_node_struct * dummy_mess1;
|
||||
void* dummy_mess2;
|
||||
ulint dummy_type;
|
||||
#endif
|
||||
|
@ -47,7 +47,6 @@ page_cur_try_search_shortcut(
|
||||
not yet completely matched */
|
||||
page_cur_t* cursor) /* out: page cursor */
|
||||
{
|
||||
int cmp;
|
||||
rec_t* rec;
|
||||
rec_t* next_rec;
|
||||
ulint low_match;
|
||||
@ -79,9 +78,8 @@ page_cur_try_search_shortcut(
|
||||
up_match = low_match;
|
||||
up_bytes = low_bytes;
|
||||
|
||||
cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match,
|
||||
&low_bytes);
|
||||
if (cmp == -1) {
|
||||
if (page_cmp_dtuple_rec_with_match(tuple, rec, offsets,
|
||||
&low_match, &low_bytes) < 0) {
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
@ -89,9 +87,8 @@ page_cur_try_search_shortcut(
|
||||
offsets = rec_get_offsets(next_rec, index, offsets,
|
||||
dtuple_get_n_fields(tuple), &heap);
|
||||
|
||||
cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
|
||||
&up_match, &up_bytes);
|
||||
if (cmp != -1) {
|
||||
if (page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
|
||||
&up_match, &up_bytes) >= 0) {
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
@ -115,7 +112,7 @@ page_cur_try_search_shortcut(
|
||||
ut_a(*ilow_matched_fields == low_match);
|
||||
ut_a(*ilow_matched_bytes == low_bytes);
|
||||
#endif
|
||||
if (next_rec != page_get_supremum_rec(page)) {
|
||||
if (!page_rec_is_supremum(next_rec)) {
|
||||
|
||||
*iup_matched_fields = up_match;
|
||||
*iup_matched_bytes = up_bytes;
|
||||
@ -137,6 +134,7 @@ exit_func:
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
/********************************************************************
|
||||
Checks if the nth field in a record is a character type field which extends
|
||||
the nth field in tuple, i.e., the field is longer or equal in length and has
|
||||
@ -185,6 +183,7 @@ page_cur_rec_field_extends(
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
|
||||
/********************************************************************
|
||||
Searches the right position for a page cursor. */
|
||||
@ -239,10 +238,17 @@ page_cur_search_with_match(
|
||||
&& ilow_matched_fields && ilow_matched_bytes && cursor);
|
||||
ut_ad(dtuple_validate(tuple));
|
||||
ut_ad(dtuple_check_typed(tuple));
|
||||
#ifdef UNIV_DEBUG
|
||||
# ifdef PAGE_CUR_DBG
|
||||
if (mode != PAGE_CUR_DBG)
|
||||
# endif /* PAGE_CUR_DBG */
|
||||
# ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
if (mode != PAGE_CUR_LE_OR_EXTENDS)
|
||||
# endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
ut_ad((mode == PAGE_CUR_L) || (mode == PAGE_CUR_LE)
|
||||
|| (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)
|
||||
|| (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG));
|
||||
|
||||
|| (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE));
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
page_check_dir(page);
|
||||
|
||||
#ifdef PAGE_CUR_ADAPT
|
||||
@ -261,16 +267,18 @@ page_cur_search_with_match(
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*#ifdef UNIV_SEARCH_DEBUG */
|
||||
# ifdef PAGE_CUR_DBG
|
||||
if (mode == PAGE_CUR_DBG) {
|
||||
mode = PAGE_CUR_LE;
|
||||
}
|
||||
/*#endif */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following flag does not work for non-latin1 char sets because
|
||||
cmp_full_field does not tell how many bytes matched */
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
ut_a(mode != PAGE_CUR_LE_OR_EXTENDS);
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
|
||||
/* If mode PAGE_CUR_G is specified, we are trying to position the
|
||||
cursor to answer a query of the form "tuple < X", where tuple is
|
||||
@ -308,33 +316,36 @@ page_cur_search_with_match(
|
||||
cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
|
||||
&cur_matched_fields,
|
||||
&cur_matched_bytes);
|
||||
if (cmp == 1) {
|
||||
if (UNIV_LIKELY(cmp > 0)) {
|
||||
low_slot_match:
|
||||
low = mid;
|
||||
low_matched_fields = cur_matched_fields;
|
||||
low_matched_bytes = cur_matched_bytes;
|
||||
|
||||
} else if (cmp == -1) {
|
||||
} else if (UNIV_LIKELY(cmp /* == -1 */)) {
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
if (mode == PAGE_CUR_LE_OR_EXTENDS
|
||||
&& page_cur_rec_field_extends(tuple, mid_rec,
|
||||
offsets, cur_matched_fields)) {
|
||||
low = mid;
|
||||
low_matched_fields = cur_matched_fields;
|
||||
low_matched_bytes = cur_matched_bytes;
|
||||
} else {
|
||||
up = mid;
|
||||
up_matched_fields = cur_matched_fields;
|
||||
up_matched_bytes = cur_matched_bytes;
|
||||
}
|
||||
|
||||
} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
|
||||
|| mode == PAGE_CUR_LE_OR_EXTENDS) {
|
||||
low = mid;
|
||||
low_matched_fields = cur_matched_fields;
|
||||
low_matched_bytes = cur_matched_bytes;
|
||||
} else {
|
||||
goto low_slot_match;
|
||||
}
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
up_slot_match:
|
||||
up = mid;
|
||||
up_matched_fields = cur_matched_fields;
|
||||
up_matched_bytes = cur_matched_bytes;
|
||||
|
||||
} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
|| mode == PAGE_CUR_LE_OR_EXTENDS
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
) {
|
||||
|
||||
goto low_slot_match;
|
||||
} else {
|
||||
|
||||
goto up_slot_match;
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,32 +371,35 @@ page_cur_search_with_match(
|
||||
cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
|
||||
&cur_matched_fields,
|
||||
&cur_matched_bytes);
|
||||
if (cmp == 1) {
|
||||
if (UNIV_LIKELY(cmp > 0)) {
|
||||
low_rec_match:
|
||||
low_rec = mid_rec;
|
||||
low_matched_fields = cur_matched_fields;
|
||||
low_matched_bytes = cur_matched_bytes;
|
||||
|
||||
} else if (cmp == -1) {
|
||||
} else if (UNIV_LIKELY(cmp /* == -1 */)) {
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
if (mode == PAGE_CUR_LE_OR_EXTENDS
|
||||
&& page_cur_rec_field_extends(tuple, mid_rec,
|
||||
offsets, cur_matched_fields)) {
|
||||
low_rec = mid_rec;
|
||||
low_matched_fields = cur_matched_fields;
|
||||
low_matched_bytes = cur_matched_bytes;
|
||||
} else {
|
||||
up_rec = mid_rec;
|
||||
up_matched_fields = cur_matched_fields;
|
||||
up_matched_bytes = cur_matched_bytes;
|
||||
|
||||
goto low_rec_match;
|
||||
}
|
||||
} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
|
||||
|| mode == PAGE_CUR_LE_OR_EXTENDS) {
|
||||
low_rec = mid_rec;
|
||||
low_matched_fields = cur_matched_fields;
|
||||
low_matched_bytes = cur_matched_bytes;
|
||||
} else {
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
up_rec_match:
|
||||
up_rec = mid_rec;
|
||||
up_matched_fields = cur_matched_fields;
|
||||
up_matched_bytes = cur_matched_bytes;
|
||||
} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
|
||||
#ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||
|| mode == PAGE_CUR_LE_OR_EXTENDS
|
||||
#endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
) {
|
||||
|
||||
goto low_rec_match;
|
||||
} else {
|
||||
|
||||
goto up_rec_match;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,7 +483,7 @@ page_copy_rec_list_end_no_locks(
|
||||
page_cur_move_to_next(&cur1);
|
||||
}
|
||||
|
||||
ut_a(!!page_is_comp(new_page) == index->table->comp);
|
||||
ut_a((ibool)!!page_is_comp(new_page) == index->table->comp);
|
||||
ut_a(page_is_comp(new_page) == page_is_comp(page));
|
||||
ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint)
|
||||
(page_is_comp(new_page)
|
||||
@ -1347,7 +1347,7 @@ page_print_list(
|
||||
ulint* offsets = offsets_;
|
||||
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
|
||||
|
||||
ut_a(!!page_is_comp(page) == index->table->comp);
|
||||
ut_a((ibool)!!page_is_comp(page) == index->table->comp);
|
||||
|
||||
fprintf(stderr,
|
||||
"--------------------------------\n"
|
||||
@ -1741,7 +1741,7 @@ page_validate(
|
||||
ulint* offsets = NULL;
|
||||
ulint* old_offsets = NULL;
|
||||
|
||||
if (!!comp != index->table->comp) {
|
||||
if ((ibool)!!comp != index->table->comp) {
|
||||
fputs("InnoDB: 'compact format' flag mismatch\n", stderr);
|
||||
goto func_exit2;
|
||||
}
|
||||
|
@ -601,30 +601,38 @@ rec_set_nth_field_extern_bit_new(
|
||||
|
||||
/* read the lengths of fields 0..n */
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
ibool is_null;
|
||||
ulint len;
|
||||
field = dict_index_get_nth_field(index, i);
|
||||
type = dict_col_get_type(dict_field_get_col(field));
|
||||
is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL);
|
||||
if (is_null) {
|
||||
/* nullable field => read the null flag */
|
||||
is_null = !!(*nulls & null_mask);
|
||||
if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
|
||||
if (UNIV_UNLIKELY(!(byte) null_mask)) {
|
||||
nulls--;
|
||||
null_mask = 1;
|
||||
}
|
||||
|
||||
if (*nulls & null_mask) {
|
||||
null_mask <<= 1;
|
||||
/* NULL fields cannot be external. */
|
||||
ut_ad(i != ith);
|
||||
continue;
|
||||
}
|
||||
|
||||
null_mask <<= 1;
|
||||
if (null_mask == 0x100)
|
||||
nulls--, null_mask = 1;
|
||||
}
|
||||
if (is_null || field->fixed_len) {
|
||||
/* No length (or extern bit) is stored for
|
||||
fields that are NULL or fixed-length. */
|
||||
if (field->fixed_len) {
|
||||
/* fixed-length fields cannot be external
|
||||
(Fixed-length fields longer than
|
||||
DICT_MAX_COL_PREFIX_LEN will be treated as
|
||||
variable-length ones in dict_index_add_col().) */
|
||||
ut_ad(i != ith);
|
||||
continue;
|
||||
}
|
||||
len = *lens--;
|
||||
lens--;
|
||||
if (dtype_get_len(type) > 255
|
||||
|| dtype_get_mtype(type) == DATA_BLOB) {
|
||||
ulint len = lens[1];
|
||||
if (len & 0x80) { /* 1exxxxxx: 2-byte length */
|
||||
if (i == ith) {
|
||||
if (!val == !(len & 0x20)) {
|
||||
if (!val == !(len & 0x40)) {
|
||||
return; /* no change */
|
||||
}
|
||||
/* toggle the extern bit */
|
||||
@ -823,6 +831,7 @@ rec_convert_dtuple_to_rec_new(
|
||||
byte* lens;
|
||||
ulint len;
|
||||
ulint i;
|
||||
ulint n_node_ptr_field;
|
||||
ulint fixed_len;
|
||||
ulint null_mask = 1;
|
||||
const ulint n_fields = dtuple_get_n_fields(dtuple);
|
||||
@ -831,16 +840,26 @@ rec_convert_dtuple_to_rec_new(
|
||||
ut_ad(index->table->comp);
|
||||
|
||||
ut_ad(n_fields > 0);
|
||||
switch (status) {
|
||||
|
||||
/* Try to ensure that the memset() between the for() loops
|
||||
completes fast. The address is not exact, but UNIV_PREFETCH
|
||||
should never generate a memory fault. */
|
||||
UNIV_PREFETCH_RW(rec - REC_N_NEW_EXTRA_BYTES - n_fields);
|
||||
UNIV_PREFETCH_RW(rec);
|
||||
|
||||
switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
|
||||
case REC_STATUS_ORDINARY:
|
||||
ut_ad(n_fields <= dict_index_get_n_fields(index));
|
||||
n_node_ptr_field = ULINT_UNDEFINED;
|
||||
break;
|
||||
case REC_STATUS_NODE_PTR:
|
||||
ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1);
|
||||
n_node_ptr_field = n_fields - 1;
|
||||
break;
|
||||
case REC_STATUS_INFIMUM:
|
||||
case REC_STATUS_SUPREMUM:
|
||||
ut_ad(n_fields == 1);
|
||||
n_node_ptr_field = ULINT_UNDEFINED;
|
||||
goto init;
|
||||
default:
|
||||
ut_a(0);
|
||||
@ -852,15 +871,18 @@ rec_convert_dtuple_to_rec_new(
|
||||
rec += (index->n_nullable + 7) / 8;
|
||||
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
|
||||
#ifdef UNIV_DEBUG
|
||||
field = dtuple_get_nth_field(dtuple, i);
|
||||
type = dfield_get_type(field);
|
||||
ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
|
||||
ut_ad(dfield_get_len(field) == 4);
|
||||
#endif /* UNIV_DEBUG */
|
||||
goto init;
|
||||
}
|
||||
field = dtuple_get_nth_field(dtuple, i);
|
||||
type = dfield_get_type(field);
|
||||
len = dfield_get_len(field);
|
||||
if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) {
|
||||
fixed_len = 4;
|
||||
ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
|
||||
ut_ad(len == 4);
|
||||
continue;
|
||||
}
|
||||
fixed_len = dict_index_get_nth_field(index, i)->fixed_len;
|
||||
|
||||
if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
|
||||
@ -902,27 +924,33 @@ init:
|
||||
type = dfield_get_type(field);
|
||||
len = dfield_get_len(field);
|
||||
|
||||
if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) {
|
||||
fixed_len = 4;
|
||||
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
|
||||
ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
|
||||
ut_ad(len == 4);
|
||||
goto copy;
|
||||
memcpy(end, dfield_get_data(field), len);
|
||||
break;
|
||||
}
|
||||
fixed_len = dict_index_get_nth_field(index, i)->fixed_len;
|
||||
|
||||
if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
|
||||
/* nullable field */
|
||||
ut_ad(index->n_nullable > 0);
|
||||
|
||||
if (UNIV_UNLIKELY(!(byte) null_mask)) {
|
||||
nulls--;
|
||||
null_mask = 1;
|
||||
}
|
||||
|
||||
ut_ad(*nulls < null_mask);
|
||||
|
||||
/* set the null flag if necessary */
|
||||
if (len == UNIV_SQL_NULL) {
|
||||
*nulls |= null_mask;
|
||||
}
|
||||
null_mask <<= 1;
|
||||
if (null_mask == 0x100)
|
||||
nulls--, null_mask = 1;
|
||||
if (len == UNIV_SQL_NULL)
|
||||
null_mask <<= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
null_mask <<= 1;
|
||||
}
|
||||
/* only nullable fields can be null */
|
||||
ut_ad(len != UNIV_SQL_NULL);
|
||||
@ -942,7 +970,7 @@ init:
|
||||
*lens-- = (byte) len;
|
||||
}
|
||||
}
|
||||
copy:
|
||||
|
||||
memcpy(end, dfield_get_data(field), len);
|
||||
end += len;
|
||||
}
|
||||
@ -1105,7 +1133,6 @@ rec_copy_prefix_to_buf(
|
||||
dtype_t* type;
|
||||
ulint i;
|
||||
ulint prefix_len;
|
||||
ibool is_null;
|
||||
ulint null_mask;
|
||||
ulint status;
|
||||
|
||||
@ -1146,20 +1173,22 @@ rec_copy_prefix_to_buf(
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
field = dict_index_get_nth_field(index, i);
|
||||
type = dict_col_get_type(dict_field_get_col(field));
|
||||
is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL);
|
||||
if (is_null) {
|
||||
if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
|
||||
/* nullable field => read the null flag */
|
||||
is_null = !!(*nulls & null_mask);
|
||||
null_mask <<= 1;
|
||||
if (null_mask == 0x100) {
|
||||
--nulls;
|
||||
UNIV_PREFETCH_R(nulls);
|
||||
if (UNIV_UNLIKELY(!(byte) null_mask)) {
|
||||
nulls--;
|
||||
null_mask = 1;
|
||||
}
|
||||
|
||||
if (*nulls & null_mask) {
|
||||
null_mask <<= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
null_mask <<= 1;
|
||||
}
|
||||
|
||||
if (is_null) {
|
||||
} else if (field->fixed_len) {
|
||||
if (field->fixed_len) {
|
||||
prefix_len += field->fixed_len;
|
||||
} else {
|
||||
ulint len = *lens--;
|
||||
|
@ -1429,51 +1429,106 @@ run_again:
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Does an unlock of a row for MySQL. */
|
||||
This can only be used when srv_locks_unsafe_for_binlog is TRUE. Before
|
||||
calling this function we must use trx_reset_new_rec_lock_info() and
|
||||
trx_register_new_rec_lock() to store the information which new record locks
|
||||
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 type.
|
||||
Thus, this implements a 'mini-rollback' that releases the latest record
|
||||
locks we set. */
|
||||
|
||||
int
|
||||
row_unlock_for_mysql(
|
||||
/*=================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
|
||||
row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
|
||||
handle */
|
||||
ibool has_latches_on_recs)/* TRUE if called so that we have
|
||||
the latches on the records under pcur
|
||||
and clust_pcur, and we do not need to
|
||||
reposition the cursors. */
|
||||
{
|
||||
rec_t* rec;
|
||||
btr_pcur_t* cur = prebuilt->pcur;
|
||||
dict_index_t* index;
|
||||
btr_pcur_t* pcur = prebuilt->pcur;
|
||||
btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
|
||||
trx_t* trx = prebuilt->trx;
|
||||
rec_t* rec;
|
||||
mtr_t mtr;
|
||||
|
||||
ut_ad(prebuilt && trx);
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
|
||||
trx->op_info = "unlock_row";
|
||||
|
||||
if (srv_locks_unsafe_for_binlog) {
|
||||
if (trx->trx_create_lock == TRUE) {
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* Restore a cursor position and find a record */
|
||||
btr_pcur_restore_position(BTR_SEARCH_LEAF, cur, &mtr);
|
||||
rec = btr_pcur_get_rec(cur);
|
||||
if (!srv_locks_unsafe_for_binlog) {
|
||||
|
||||
if (rec) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: calling row_unlock_for_mysql though\n"
|
||||
"InnoDB: srv_locks_unsafe_for_binlog is FALSE.\n");
|
||||
|
||||
lock_rec_reset_and_release_wait(rec);
|
||||
} else {
|
||||
fputs("InnoDB: Error: "
|
||||
"Record for the lock not found\n",
|
||||
stderr);
|
||||
mem_analyze_corruption((byte*) trx);
|
||||
ut_error;
|
||||
}
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
trx->trx_create_lock = FALSE;
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
trx->op_info = "unlock_row";
|
||||
|
||||
index = btr_pcur_get_btr_cur(pcur)->index;
|
||||
|
||||
if (index != NULL && trx_new_rec_locks_contain(trx, index)) {
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* Restore the cursor position and find the record */
|
||||
|
||||
if (!has_latches_on_recs) {
|
||||
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, &mtr);
|
||||
}
|
||||
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
||||
lock_rec_reset_and_release_wait(rec);
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
/* If the search was done through the clustered index, then
|
||||
we have not used clust_pcur at all, and we must NOT try to
|
||||
reset locks on clust_pcur. The values in clust_pcur may be
|
||||
garbage! */
|
||||
|
||||
if (index->type & DICT_CLUSTERED) {
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
}
|
||||
|
||||
index = btr_pcur_get_btr_cur(clust_pcur)->index;
|
||||
|
||||
if (index != NULL && trx_new_rec_locks_contain(trx, index)) {
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* Restore the cursor position and find the record */
|
||||
|
||||
if (!has_latches_on_recs) {
|
||||
btr_pcur_restore_position(BTR_SEARCH_LEAF, clust_pcur,
|
||||
&mtr);
|
||||
}
|
||||
|
||||
rec = btr_pcur_get_rec(clust_pcur);
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
||||
lock_rec_reset_and_release_wait(rec);
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
func_exit:
|
||||
trx->op_info = "";
|
||||
|
||||
return(DB_SUCCESS);
|
||||
|
@ -2784,6 +2784,10 @@ sel_restore_position_for_mysql(
|
||||
process the record the cursor is
|
||||
now positioned on (i.e. we should
|
||||
not go to the next record yet) */
|
||||
ibool* same_user_rec, /* out: TRUE if we were able to restore
|
||||
the cursor on a user record with the
|
||||
same ordering prefix in in the
|
||||
B-tree index */
|
||||
ulint latch_mode, /* in: latch mode wished in
|
||||
restoration */
|
||||
btr_pcur_t* pcur, /* in: cursor whose position
|
||||
@ -2800,6 +2804,8 @@ sel_restore_position_for_mysql(
|
||||
|
||||
success = btr_pcur_restore_position(latch_mode, pcur, mtr);
|
||||
|
||||
*same_user_rec = success;
|
||||
|
||||
if (relative_position == BTR_PCUR_ON) {
|
||||
if (success) {
|
||||
return(FALSE);
|
||||
@ -3064,10 +3070,12 @@ row_search_for_mysql(
|
||||
ulint cnt = 0;
|
||||
#endif /* UNIV_SEARCH_DEBUG */
|
||||
ulint next_offs;
|
||||
ibool same_user_rec;
|
||||
mtr_t mtr;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
|
||||
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
|
||||
|
||||
ut_ad(index && pcur && search_tuple);
|
||||
@ -3138,6 +3146,16 @@ row_search_for_mysql(
|
||||
trx->search_latch_timeout = BTR_SEA_TIMEOUT;
|
||||
}
|
||||
|
||||
/* Reset the new record lock info if we srv_locks_unsafe_for_binlog
|
||||
is set. Then we are able to remove the record locks set here on an
|
||||
individual row. */
|
||||
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
&& prebuilt->select_lock_type != LOCK_NONE) {
|
||||
|
||||
trx_reset_new_rec_lock_info(trx);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/* PHASE 1: Try to pop the row from the prefetch cache */
|
||||
|
||||
@ -3396,8 +3414,9 @@ shortcut_fails_too_big_rec:
|
||||
clust_index = dict_table_get_first_index(index->table);
|
||||
|
||||
if (UNIV_LIKELY(direction != 0)) {
|
||||
if (!sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
|
||||
moves_up, &mtr)) {
|
||||
if (!sel_restore_position_for_mysql(&same_user_rec,
|
||||
BTR_SEARCH_LEAF,
|
||||
pcur, moves_up, &mtr)) {
|
||||
goto next_rec;
|
||||
}
|
||||
|
||||
@ -3659,7 +3678,7 @@ rec_loop:
|
||||
goto normal_return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We are ready to look at a possible new index entry in the result
|
||||
set: the cursor is now placed on a user record */
|
||||
|
||||
@ -3679,6 +3698,7 @@ rec_loop:
|
||||
|| srv_locks_unsafe_for_binlog
|
||||
|| (unique_search && !UNIV_UNLIKELY(rec_get_deleted_flag(
|
||||
rec, page_rec_is_comp(rec))))) {
|
||||
|
||||
goto no_gap_lock;
|
||||
} else {
|
||||
lock_type = LOCK_ORDINARY;
|
||||
@ -3701,7 +3721,7 @@ rec_loop:
|
||||
&& dtuple_get_n_fields_cmp(search_tuple)
|
||||
== dict_index_get_n_unique(index)
|
||||
&& 0 == cmp_dtuple_rec(search_tuple, rec, offsets)) {
|
||||
no_gap_lock:
|
||||
no_gap_lock:
|
||||
lock_type = LOCK_REC_NOT_GAP;
|
||||
}
|
||||
|
||||
@ -3764,6 +3784,7 @@ rec_loop:
|
||||
/* Get the clustered index record if needed */
|
||||
index_rec = rec;
|
||||
ut_ad(index != clust_index);
|
||||
|
||||
goto requires_clust_rec;
|
||||
}
|
||||
}
|
||||
@ -3773,6 +3794,17 @@ rec_loop:
|
||||
/* The record is delete-marked: we can skip it if this is
|
||||
not a consistent read which might see an earlier version
|
||||
of a non-clustered index record */
|
||||
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
&& prebuilt->select_lock_type != LOCK_NONE) {
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@ -3783,7 +3815,8 @@ rec_loop:
|
||||
index_rec = rec;
|
||||
|
||||
if (index != clust_index && prebuilt->need_to_access_clustered) {
|
||||
requires_clust_rec:
|
||||
|
||||
requires_clust_rec:
|
||||
/* Before and after this "if" block, "offsets" will be
|
||||
related to "rec", which may be in a secondary index "index" or
|
||||
the clustered index ("clust_index"). However, after this
|
||||
@ -3816,6 +3849,18 @@ rec_loop:
|
||||
|
||||
/* The record is delete marked: we can skip it */
|
||||
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
&& prebuilt->select_lock_type != LOCK_NONE) {
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -3908,7 +3953,7 @@ got_row:
|
||||
next_rec:
|
||||
/*-------------------------------------------------------------*/
|
||||
/* PHASE 5: Move the cursor to the next index record */
|
||||
|
||||
|
||||
if (UNIV_UNLIKELY(mtr_has_extra_clust_latch)) {
|
||||
/* We must commit mtr if we are moving to the next
|
||||
non-clustered index record, because we could break the
|
||||
@ -3921,8 +3966,9 @@ next_rec:
|
||||
mtr_has_extra_clust_latch = FALSE;
|
||||
|
||||
mtr_start(&mtr);
|
||||
if (sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
|
||||
moves_up, &mtr)) {
|
||||
if (sel_restore_position_for_mysql(&same_user_rec,
|
||||
BTR_SEARCH_LEAF,
|
||||
pcur, moves_up, &mtr)) {
|
||||
#ifdef UNIV_SEARCH_DEBUG
|
||||
cnt++;
|
||||
#endif /* UNIV_SEARCH_DEBUG */
|
||||
@ -3973,11 +4019,34 @@ lock_wait_or_error:
|
||||
thr->lock_state = QUE_THR_LOCK_ROW;
|
||||
|
||||
if (row_mysql_handle_errors(&err, trx, thr, NULL)) {
|
||||
/* It was a lock wait, and it ended */
|
||||
|
||||
thr->lock_state = QUE_THR_LOCK_NOLOCK;
|
||||
mtr_start(&mtr);
|
||||
|
||||
sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
|
||||
moves_up, &mtr);
|
||||
sel_restore_position_for_mysql(&same_user_rec,
|
||||
BTR_SEARCH_LEAF, pcur,
|
||||
moves_up, &mtr);
|
||||
if (srv_locks_unsafe_for_binlog && !same_user_rec) {
|
||||
/* Since we were not able to restore the cursor
|
||||
on the same user record, we cannot use
|
||||
row_unlock_for_mysql() to unlock any records, and
|
||||
we must thus reset the new rec lock info. Since
|
||||
in lock0lock.c we have blocked the inheriting of gap
|
||||
X-locks, we actually do not have any new record locks
|
||||
set in this case.
|
||||
|
||||
Note that if we were able to restore on the 'same'
|
||||
user record, it is still possible that we were actually
|
||||
waiting on a delete-marked record, and meanwhile
|
||||
it was removed by purge and inserted again by some
|
||||
other user. But that is no problem, because in
|
||||
rec_loop we will again try to set a lock, and
|
||||
new_rec_lock_info in trx will be right at the end. */
|
||||
|
||||
trx_reset_new_rec_lock_info(trx);
|
||||
}
|
||||
|
||||
mode = pcur->search_mode;
|
||||
|
||||
goto rec_loop;
|
||||
|
@ -818,7 +818,7 @@ row_upd_build_difference_binary(
|
||||
extern_bit = upd_ext_vec_contains(ext_vec, n_ext_vec, i);
|
||||
|
||||
if (UNIV_UNLIKELY(extern_bit ==
|
||||
!rec_offs_nth_extern(offsets, i))
|
||||
(ibool)!rec_offs_nth_extern(offsets, i))
|
||||
|| !dfield_data_is_binary_equal(dfield, len, data)) {
|
||||
|
||||
upd_field = upd_get_nth_field(update, n_diff);
|
||||
|
@ -260,7 +260,7 @@ semaphore contention and convoy problems can occur withput this restriction.
|
||||
Value 10 should be good if there are less than 4 processors + 4 disks in the
|
||||
computer. Bigger computers need bigger values. */
|
||||
|
||||
ulong srv_thread_concurrency = 8;
|
||||
ulong srv_thread_concurrency = SRV_CONCURRENCY_THRESHOLD;
|
||||
|
||||
os_fast_mutex_t srv_conc_mutex; /* this mutex protects srv_conc data
|
||||
structures */
|
||||
@ -983,12 +983,6 @@ srv_conc_enter_innodb(
|
||||
srv_conc_slot_t* slot = NULL;
|
||||
ulint i;
|
||||
|
||||
if (srv_thread_concurrency >= 500) {
|
||||
/* Disable the concurrency check */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* If trx has 'free tickets' to enter the engine left, then use one
|
||||
such ticket */
|
||||
|
||||
@ -1134,7 +1128,7 @@ srv_conc_force_enter_innodb(
|
||||
trx_t* trx) /* in: transaction object associated with the
|
||||
thread */
|
||||
{
|
||||
if (srv_thread_concurrency >= 500) {
|
||||
if (srv_thread_concurrency >= SRV_CONCURRENCY_THRESHOLD) {
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1160,7 +1154,7 @@ srv_conc_force_exit_innodb(
|
||||
{
|
||||
srv_conc_slot_t* slot = NULL;
|
||||
|
||||
if (srv_thread_concurrency >= 500) {
|
||||
if (srv_thread_concurrency >= SRV_CONCURRENCY_THRESHOLD) {
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1212,11 +1206,6 @@ srv_conc_exit_innodb(
|
||||
trx_t* trx) /* in: transaction object associated with the
|
||||
thread */
|
||||
{
|
||||
if (srv_thread_concurrency >= 500) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (trx->n_tickets_to_enter_innodb > 0) {
|
||||
/* We will pretend the thread is still inside InnoDB though it
|
||||
now leaves the InnoDB engine. In this way we save
|
||||
|
@ -166,6 +166,8 @@ trx_create(
|
||||
memset(&trx->xid, 0, sizeof(trx->xid));
|
||||
trx->xid.formatID = -1;
|
||||
|
||||
trx_reset_new_rec_lock_info(trx);
|
||||
|
||||
return(trx);
|
||||
}
|
||||
|
||||
|
@ -559,14 +559,14 @@ trx_undo_write_xid(
|
||||
const XID* xid, /* in: X/Open XA Transaction Identification */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
mlog_write_ulint(log_hdr + TRX_UNDO_XA_FORMAT, xid->formatID,
|
||||
MLOG_4BYTES, mtr);
|
||||
mlog_write_ulint(log_hdr + TRX_UNDO_XA_FORMAT,
|
||||
(ulint)xid->formatID, MLOG_4BYTES, mtr);
|
||||
|
||||
mlog_write_ulint(log_hdr + TRX_UNDO_XA_TRID_LEN, xid->gtrid_length,
|
||||
MLOG_4BYTES, mtr);
|
||||
mlog_write_ulint(log_hdr + TRX_UNDO_XA_TRID_LEN,
|
||||
(ulint)xid->gtrid_length, MLOG_4BYTES, mtr);
|
||||
|
||||
mlog_write_ulint(log_hdr + TRX_UNDO_XA_BQUAL_LEN, xid->bqual_length,
|
||||
MLOG_4BYTES, mtr);
|
||||
mlog_write_ulint(log_hdr + TRX_UNDO_XA_BQUAL_LEN,
|
||||
(ulint)xid->bqual_length, MLOG_4BYTES, mtr);
|
||||
|
||||
mlog_write_string(log_hdr + TRX_UNDO_XA_XID, (const byte*) xid->data,
|
||||
XIDDATASIZE, mtr);
|
||||
@ -581,18 +581,14 @@ trx_undo_read_xid(
|
||||
trx_ulogf_t* log_hdr,/* in: undo log header */
|
||||
XID* xid) /* out: X/Open XA Transaction Identification */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
xid->formatID = mach_read_from_4(log_hdr + TRX_UNDO_XA_FORMAT);
|
||||
xid->formatID = (long)mach_read_from_4(log_hdr + TRX_UNDO_XA_FORMAT);
|
||||
|
||||
xid->gtrid_length = mach_read_from_4(log_hdr + TRX_UNDO_XA_TRID_LEN);
|
||||
xid->gtrid_length =
|
||||
(long)mach_read_from_4(log_hdr + TRX_UNDO_XA_TRID_LEN);
|
||||
xid->bqual_length =
|
||||
(long)mach_read_from_4(log_hdr + TRX_UNDO_XA_BQUAL_LEN);
|
||||
|
||||
xid->bqual_length = mach_read_from_4(log_hdr + TRX_UNDO_XA_BQUAL_LEN);
|
||||
|
||||
for (i = 0; i < XIDDATASIZE; i++) {
|
||||
xid->data[i] = (char)mach_read_from_1(log_hdr +
|
||||
TRX_UNDO_XA_XID + i);
|
||||
}
|
||||
memcpy(xid->data, log_hdr + TRX_UNDO_XA_XID, XIDDATASIZE);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -17,7 +17,7 @@
|
||||
EXTRA_DIST = mi_test_all.sh mi_test_all.res
|
||||
pkgdata_DATA = mi_test_all mi_test_all.res
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
|
||||
$(top_builddir)/mysys/libmysys.a \
|
||||
$(top_builddir)/dbug/libdbug.a \
|
||||
|
@ -770,10 +770,13 @@ err:
|
||||
|
||||
uint mi_get_pointer_length(ulonglong file_length, uint def)
|
||||
{
|
||||
DBUG_ASSERT(def >= 2 && def <= 7);
|
||||
if (file_length) /* If not default */
|
||||
{
|
||||
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS
|
||||
if (file_length >= (longlong) 1 << 56)
|
||||
def=8;
|
||||
#endif
|
||||
if (file_length >= (longlong) 1 << 48)
|
||||
def=7;
|
||||
if (file_length >= (longlong) 1 << 40)
|
||||
|
@ -78,7 +78,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
int lock_error,kfile,open_mode,save_errno,have_rtree=0;
|
||||
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
|
||||
key_parts,unique_key_parts,fulltext_keys,uniques;
|
||||
char name_buff[FN_REFLEN], org_name [FN_REFLEN], index_name[FN_REFLEN],
|
||||
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
|
||||
data_name[FN_REFLEN];
|
||||
char *disk_cache, *disk_pos, *end_pos;
|
||||
MI_INFO info,*m_info,*old_info;
|
||||
|
@ -416,8 +416,19 @@ static uint find_longest_bitstream(uint16 *table, uint16 *end)
|
||||
}
|
||||
|
||||
|
||||
/* Read record from datafile */
|
||||
/* Returns length of packed record, -1 if error */
|
||||
/*
|
||||
Read record from datafile.
|
||||
|
||||
SYNOPSIS
|
||||
_mi_read_pack_record()
|
||||
info A pointer to MI_INFO.
|
||||
filepos File offset of the record.
|
||||
buf RETURN The buffer to receive the record.
|
||||
|
||||
RETURN
|
||||
0 on success
|
||||
HA_ERR_WRONG_IN_RECORD or -1 on error
|
||||
*/
|
||||
|
||||
int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf)
|
||||
{
|
||||
|
@ -64,7 +64,12 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record,
|
||||
}
|
||||
|
||||
|
||||
/* Calculate a hash for a row */
|
||||
/*
|
||||
Calculate a hash for a row
|
||||
|
||||
TODO
|
||||
Add support for bit fields
|
||||
*/
|
||||
|
||||
ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
|
||||
{
|
||||
@ -126,9 +131,17 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
|
||||
return crc;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns 0 if both rows have equal unique value
|
||||
*/
|
||||
|
||||
/*
|
||||
compare unique key for two rows
|
||||
|
||||
TODO
|
||||
Add support for bit fields
|
||||
|
||||
RETURN
|
||||
0 if both rows have equal unique value
|
||||
# Rows are different
|
||||
*/
|
||||
|
||||
int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
|
||||
my_bool null_are_equal)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
pkglib_LIBRARIES = libmyisammrg.a
|
||||
noinst_HEADERS = myrg_def.h
|
||||
libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
~ConfigRetriever();
|
||||
|
||||
int do_connect(int no_retries, int retry_delay_in_seconds, int verbose);
|
||||
int disconnect();
|
||||
|
||||
/**
|
||||
* Get configuration for current node.
|
||||
|
@ -107,6 +107,12 @@ ConfigRetriever::do_connect(int no_retries,
|
||||
0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
ConfigRetriever::disconnect()
|
||||
{
|
||||
return ndb_mgm_disconnect(m_handle);
|
||||
}
|
||||
|
||||
//****************************************************************************
|
||||
//****************************************************************************
|
||||
//****************************************************************************
|
||||
|
@ -353,7 +353,8 @@ int main(int argc, char** argv)
|
||||
|
||||
g_eventLogger.info("Shutting down server...");
|
||||
glob.socketServer->stopServer();
|
||||
glob.socketServer->stopSessions();
|
||||
glob.mgmObject->get_config_retriever()->disconnect();
|
||||
glob.socketServer->stopSessions(true);
|
||||
g_eventLogger.info("Shutdown complete");
|
||||
return 0;
|
||||
error_end:
|
||||
|
Reference in New Issue
Block a user