Commit f7f40816 authored by marko's avatar marko

branches/innodb+: Merge revisions 2986:3152 from branches/zip:

  ------------------------------------------------------------------------
  r3036 | marko | 2008-11-12 12:34:30 +0200 (Wed, 12 Nov 2008) | 4 lines

  branches/zip: dtuple_validate(): When UNIV_DEBUG_VALGRIND is defined,
  rely solely on the UNIV_MEM_ASSERT_RW() check and disable the for loop
  that would only cause additional noise.
  ------------------------------------------------------------------------
  r3037 | marko | 2008-11-12 13:52:57 +0200 (Wed, 12 Nov 2008) | 6 lines

  branches/zip: row_vers_impl_x_locked_off_kernel(): Remove compilation
  warnings about prev_trx_id and vers_del being possibly uninitialized,
  by handling the case prev_version == NULL in a single if block.

  rb://45 approved by Inaam Rana.
  ------------------------------------------------------------------------
  r3131 | michael | 2008-11-17 14:56:56 +0200 (Mon, 17 Nov 2008) | 9 lines

  branches/zip:

  rb://53

  Improve innodb_supports_xa system variable handling and
  reduces the number of retrievals of the value from MySQL.

  Approved by: Marko, over IM
  ------------------------------------------------------------------------
  r3132 | michael | 2008-11-17 16:02:01 +0200 (Mon, 17 Nov 2008) | 5 lines

  branches/zip: rb://53

  Final version of rb://53, fixes the styling of a comment, makes
  the definition and the declaration of thd_supports_xa() identical commentwise.
  ------------------------------------------------------------------------
  r3141 | marko | 2008-11-19 16:39:55 +0200 (Wed, 19 Nov 2008) | 1 line

  branches/zip: buf_LRU_free_block(): Clarify the function comment.
  ------------------------------------------------------------------------
  r3144 | marko | 2008-11-20 11:39:49 +0200 (Thu, 20 Nov 2008) | 2 lines

  branches/zip: rec_get_nth_field_offs_old(): Add UNIV_UNLIKELY hints
  to assertion-like tests.
  ------------------------------------------------------------------------
  r3145 | marko | 2008-11-20 12:22:40 +0200 (Thu, 20 Nov 2008) | 20 lines

  branches/zip: Always check for "row too large" when executing SQL to create
  an index or table.  We have to skip this check when loading table definitions
  from the data dictionary, because we could otherwise refuse to load old
  tables (even uncompressed ones).  This addresses Issue #119.

  The first "row too large" check was implemented in MySQL 5.0.3
  to address MySQL Bug #5682.  In the InnoDB Plugin 1.0.2, a more
  accurate check was implemented in innodb_strict_mode.  We now
  make the check unconditional.

  dict_create_index_step(): Pass strict=TRUE to dict_index_add_to_cache().

  trx_is_strict(), thd_is_strict(): Remove.

  innodb-zip.test: Test in innodb_strict_mode=OFF.

  innodb_bug36169.test: Ensure that none of the tables can be created.

  rb://56 approved by Sunny Bains.
  ------------------------------------------------------------------------
  r3148 | marko | 2008-11-20 13:27:27 +0200 (Thu, 20 Nov 2008) | 3 lines

  branches/zip: rec_print_old(), rec_print_comp(): Dump each field in a
  separate line, so that the dumps can be read and compared more easily.
  ------------------------------------------------------------------------
parent 0f25be38
......@@ -1287,9 +1287,15 @@ buf_LRU_make_block_old(
/**********************************************************************
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well. If this function
returns BUF_LRU_FREED, it will not temporarily release
buf_pool_mutex. */
page, the descriptor object will be freed as well.
NOTE: If this function returns BUF_LRU_FREED, it will not temporarily
release buf_pool_mutex. Furthermore, the page frame will no longer be
accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
buf_page_get_mutex() may be held when calling this function. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
......
......@@ -26,8 +26,10 @@ Created 5/30/1994 Heikki Tuuri
for error checking */
UNIV_INTERN byte data_error;
# ifndef UNIV_DEBUG_VALGRIND
/* this is used to fool the compiler in dtuple_validate */
UNIV_INTERN ulint data_dummy;
# endif /* !UNIV_DEBUG_VALGRIND */
#endif /* UNIV_DEBUG */
/*************************************************************************
......@@ -232,11 +234,9 @@ dtuple_validate(
const dtuple_t* tuple) /* in: tuple */
{
const dfield_t* field;
const byte* data;
ulint n_fields;
ulint len;
ulint i;
ulint j;
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
......@@ -252,8 +252,9 @@ dtuple_validate(
if (!dfield_is_null(field)) {
data = dfield_get_data(field);
UNIV_MEM_ASSERT_RW(data, len);
const byte* data = dfield_get_data(field);
#ifndef UNIV_DEBUG_VALGRIND
ulint j;
for (j = 0; j < len; j++) {
......@@ -262,6 +263,9 @@ dtuple_validate(
code */
data++;
}
#endif /* !UNIV_DEBUG_VALGRIND */
UNIV_MEM_ASSERT_RW(data, len);
}
}
......
......@@ -1079,7 +1079,7 @@ dict_create_index_step(
dulint index_id = node->index->id;
err = dict_index_add_to_cache(node->table, node->index,
FIL_NULL, trx_is_strict(trx));
FIL_NULL, TRUE);
node->index = dict_index_get_if_in_cache_low(index_id);
ut_a(!node->index == (err != DB_SUCCESS));
......
......@@ -608,15 +608,17 @@ thd_is_select(
}
/**********************************************************************
Returns true if the thread is executing in innodb_strict_mode. */
Returns true if the thread supports XA,
global value of innodb_supports_xa if thd is NULL. */
extern "C" UNIV_INTERN
ibool
thd_is_strict(
/*==========*/
/* out: true if thd is in strict mode */
void* thd) /* in: thread handle (THD*) */
thd_supports_xa(
/*============*/
/* out: true if thd has XA support */
void* thd) /* in: thread handle (THD*), or NULL to query
the global innodb_supports_xa */
{
return(THDVAR((THD*) thd, strict_mode));
return(THDVAR((THD*) thd, support_xa));
}
/**********************************************************************
......@@ -1238,9 +1240,6 @@ check_trx_exists(
trx->mysql_thd = thd;
trx->mysql_query_str = thd_query(thd);
/* Update the info whether we should skip XA steps that eat
CPU time */
trx->support_xa = THDVAR(thd, support_xa);
} else {
if (trx->magic_n != TRX_MAGIC_N) {
mem_analyze_corruption(trx);
......@@ -2299,9 +2298,6 @@ innobase_commit(
trx = check_trx_exists(thd);
/* Update the info whether we should skip XA steps that eat CPU time */
trx->support_xa = THDVAR(thd, support_xa);
/* Since we will reserve the kernel mutex, we have to release
the search system latch first to obey the latching order. */
......@@ -2428,9 +2424,6 @@ innobase_rollback(
trx = check_trx_exists(thd);
/* Update the info whether we should skip XA steps that eat CPU time */
trx->support_xa = THDVAR(thd, support_xa);
/* Release a possible FIFO ticket and search latch. Since we will
reserve the kernel mutex, we have to release the search system latch
first to obey the latching order. */
......@@ -8843,7 +8836,10 @@ innobase_xa_prepare(
trx->active_trans = 2;
}
if (!THDVAR(thd, support_xa)) {
/* we use support_xa value as it was seen at transaction start
time, not the current session variable value. Any possible changes
to the session variable take effect only in the next transaction */
if (!trx->support_xa) {
return(0);
}
......
......@@ -87,9 +87,15 @@ buf_LRU_insert_zip_clean(
/**********************************************************************
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well. If this function
returns BUF_LRU_FREED, it will not temporarily release
buf_pool_mutex. */
page, the descriptor object will be freed as well.
NOTE: If this function returns BUF_LRU_FREED, it will not temporarily
release buf_pool_mutex. Furthermore, the page frame will no longer be
accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
buf_page_get_mutex() may be held when calling this function. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
......
......@@ -207,13 +207,15 @@ innobase_get_charset(
void* mysql_thd); /* in: MySQL thread handle */
/**********************************************************************
Returns true if the thread is executing in innodb_strict_mode. */
Returns true if the thread supports XA,
global value of innodb_supports_xa if thd is NULL. */
ibool
thd_is_strict(
/*==========*/
/* out: true if thd is in strict mode */
void* thd); /* in: thread handle (THD*) */
thd_supports_xa(
/*============*/
/* out: true if thd supports XA */
void* thd); /* in: thread handle (THD*), or NULL to query
the global innodb_supports_xa */
/**********************************************************************
Returns the lock wait timeout for the current connection. */
......
......@@ -407,15 +407,6 @@ trx_is_interrupted(
#define trx_is_interrupted(trx) FALSE
#endif /* !UNIV_HOTBACKUP */
/**************************************************************************
Determines if the currently running transaction is in innodb_strict_mode. */
UNIV_INTERN
ibool
trx_is_strict(
/*==========*/
/* out: TRUE if strict */
trx_t* trx); /* in: transaction */
/***********************************************************************
Calculates the "weight" of a transaction. The weight of one transaction
is estimated as the number of altered rows + the number of locked rows.
......
......@@ -122,7 +122,7 @@ table_schema table_name row_format
test t1 Compressed
test t2 Compact
drop table t1,t2;
SET SESSION innodb_strict_mode = on;
SET SESSION innodb_strict_mode = off;
CREATE TABLE t1(
c TEXT NOT NULL, d TEXT NOT NULL,
PRIMARY KEY (c(767),d(767)))
......
......@@ -84,7 +84,8 @@ SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
drop table t1,t2;
SET SESSION innodb_strict_mode = on;
# The following should fail even in non-strict mode.
SET SESSION innodb_strict_mode = off;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE t1(
c TEXT NOT NULL, d TEXT NOT NULL,
......
......@@ -22,6 +22,7 @@ SET GLOBAL innodb_file_per_table=ON;
# Generating 10 tables
# Creating a table with 94 columns and 24 indexes
DROP TABLE IF EXISTS `table0`;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE IF NOT EXISTS `table0`
(`col0` BOOL,
`col1` BOOL,
......@@ -145,6 +146,7 @@ KEY `idx23` (`col7`(163),`col31`,`col71`,`col14`)
# Creating a table with 10 columns and 32 indexes
DROP TABLE IF EXISTS `table1`;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE IF NOT EXISTS `table1`
(`col0` CHAR (113),
`col1` FLOAT,
......@@ -192,6 +194,7 @@ KEY `idx31` (`col4`(1),`col0`)
# Creating a table with 141 columns and 18 indexes
DROP TABLE IF EXISTS `table2`;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE IF NOT EXISTS `table2`
(`col0` BOOL,
`col1` MEDIUMINT,
......@@ -356,6 +359,7 @@ KEY `idx17` (`col24`(250),`col7`,`col92`,`col45`)
# Creating a table with 199 columns and 1 indexes
DROP TABLE IF EXISTS `table3`;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE IF NOT EXISTS `table3`
(`col0` SMALLINT,
`col1` SET ('test1','test2','test3'),
......@@ -561,6 +565,7 @@ KEY `idx0` (`col39`,`col23`)
# Creating a table with 133 columns and 16 indexes
DROP TABLE IF EXISTS `table4`;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE IF NOT EXISTS `table4`
(`col0` VARCHAR (60),
`col1` NUMERIC,
......@@ -715,6 +720,7 @@ KEY `idx15` (`col4`(246),`col130`,`col115`,`col3`(141))
# Creating a table with 176 columns and 13 indexes
DROP TABLE IF EXISTS `table5`;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE IF NOT EXISTS `table5`
(`col0` MEDIUMTEXT,
`col1` VARCHAR (90),
......@@ -910,6 +916,7 @@ KEY `idx12` (`col24`)
# Creating a table with 179 columns and 46 indexes
DROP TABLE IF EXISTS `table6`;
-- error ER_TOO_BIG_ROWSIZE
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE IF NOT EXISTS `table6`
(`col0` ENUM ('test1','test2','test3'),
`col1` MEDIUMBLOB,
......
......@@ -681,13 +681,13 @@ rec_get_nth_field_offs_old(
ut_ad(rec && len);
ut_ad(n < rec_get_n_fields_old(rec));
if (n > REC_MAX_N_FIELDS) {
if (UNIV_UNLIKELY(n > REC_MAX_N_FIELDS)) {
fprintf(stderr, "Error: trying to access field %lu in rec\n",
(ulong) n);
ut_error;
}
if (rec == NULL) {
if (UNIV_UNLIKELY(rec == NULL)) {
fputs("Error: rec is NULL pointer\n", stderr);
ut_error;
}
......@@ -1599,11 +1599,11 @@ rec_print_old(
fprintf(file, " SQL NULL, size %lu ",
rec_get_nth_field_size(rec, i));
}
putc(';', file);
putc('\n', file);
}
putc('\n', file);
rec_validate_old(rec);
}
......@@ -1642,9 +1642,8 @@ rec_print_comp(
fputs(" SQL NULL", file);
}
putc(';', file);
putc('\n', file);
}
putc('\n', file);
}
/*******************************************************************
......
......@@ -48,16 +48,13 @@ row_vers_impl_x_locked_off_kernel(
rec_t* clust_rec;
ulint* clust_offsets;
rec_t* version;
rec_t* prev_version;
dulint trx_id;
dulint prev_trx_id;
mem_heap_t* heap;
mem_heap_t* heap2;
dtuple_t* row;
dtuple_t* entry = NULL; /* assignment to eliminate compiler
warning */
trx_t* trx;
ulint vers_del;
ulint rec_del;
ulint err;
mtr_t mtr;
......@@ -141,6 +138,11 @@ row_vers_impl_x_locked_off_kernel(
version = clust_rec;
for (;;) {
rec_t* prev_version;
ulint vers_del;
row_ext_t* ext;
dulint prev_trx_id;
mutex_exit(&kernel_mutex);
/* While we retrieve an earlier version of clust_rec, we
......@@ -157,66 +159,63 @@ row_vers_impl_x_locked_off_kernel(
heap, &prev_version);
mem_heap_free(heap2); /* free version and clust_offsets */
if (prev_version) {
row_ext_t* ext;
if (prev_version == NULL) {
mutex_enter(&kernel_mutex);
if (!trx_is_active(trx_id)) {
/* Transaction no longer active: no
implicit x-lock */
clust_offsets = rec_get_offsets(
prev_version, clust_index, NULL,
ULINT_UNDEFINED, &heap);
vers_del = rec_get_deleted_flag(prev_version,
comp);
prev_trx_id = row_get_rec_trx_id(prev_version,
clust_index,
clust_offsets);
/* If the trx_id and prev_trx_id are
different and if the prev_version is marked
deleted then the prev_trx_id must have
already committed for the trx_id to be able to
modify the row. Therefore, prev_trx_id cannot
hold any implicit lock. */
if (0 != ut_dulint_cmp(trx_id, prev_trx_id)
&& vers_del) {
mutex_enter(&kernel_mutex);
break;
}
/* The stack of versions is locked by mtr.
Thus, it is safe to fetch the prefixes for
externally stored columns. */
row = row_build(ROW_COPY_POINTERS, clust_index,
prev_version, clust_offsets,
NULL, &ext, heap);
entry = row_build_index_entry(row, ext, index, heap);
/* entry may be NULL if a record was inserted
in place of a deleted record, and the BLOB
pointers of the new record were not
initialized yet. But in that case,
prev_version should be NULL. */
ut_a(entry);
}
/* If the transaction is still active,
clust_rec must be a fresh insert, because no
previous version was found. */
ut_ad(err == DB_SUCCESS);
mutex_enter(&kernel_mutex);
/* It was a freshly inserted version: there is an
implicit x-lock on rec */
if (!trx_is_active(trx_id)) {
/* Transaction no longer active: no implicit x-lock */
trx = trx_get_on_id(trx_id);
break;
}
/* If the transaction is still active, the previous version
of clust_rec must be accessible if not a fresh insert; we
may assert the following: */
clust_offsets = rec_get_offsets(prev_version, clust_index,
NULL, ULINT_UNDEFINED, &heap);
ut_ad(err == DB_SUCCESS);
vers_del = rec_get_deleted_flag(prev_version, comp);
prev_trx_id = row_get_rec_trx_id(prev_version, clust_index,
clust_offsets);
if (prev_version == NULL) {
/* It was a freshly inserted version: there is an
implicit x-lock on rec */
/* If the trx_id and prev_trx_id are different and if
the prev_version is marked deleted then the
prev_trx_id must have already committed for the trx_id
to be able to modify the row. Therefore, prev_trx_id
cannot hold any implicit lock. */
if (vers_del && 0 != ut_dulint_cmp(trx_id, prev_trx_id)) {
trx = trx_get_on_id(trx_id);
mutex_enter(&kernel_mutex);
break;
}
/* The stack of versions is locked by mtr. Thus, it
is safe to fetch the prefixes for externally stored
columns. */
row = row_build(ROW_COPY_POINTERS, clust_index, prev_version,
clust_offsets, NULL, &ext, heap);
entry = row_build_index_entry(row, ext, index, heap);
/* entry may be NULL if a record was inserted in place
of a deleted record, and the BLOB pointers of the new
record were not initialized yet. But in that case,
prev_version should be NULL. */
ut_a(entry);
mutex_enter(&kernel_mutex);
if (!trx_is_active(trx_id)) {
/* Transaction no longer active: no implicit x-lock */
break;
}
......@@ -226,6 +225,11 @@ row_vers_impl_x_locked_off_kernel(
if prev_version would require rec to be in a different
state. */
/* The previous version of clust_rec must be
accessible, because the transaction is still active
and clust_rec was not a fresh insert. */
ut_ad(err == DB_SUCCESS);
/* We check if entry and rec are identified in the alphabetical
ordering */
if (0 == cmp_dtuple_rec(entry, rec, offsets)) {
......
......@@ -34,22 +34,6 @@ UNIV_INTERN sess_t* trx_dummy_sess = NULL;
the kernel mutex */
UNIV_INTERN ulint trx_n_mysql_transactions = 0;
/**************************************************************************
Determines if the currently running transaction is in innodb_strict_mode. */
UNIV_INTERN
ibool
trx_is_strict(
/*==========*/
/* out: TRUE if strict */
trx_t* trx) /* in: transaction */
{
#ifndef UNIV_HOTBACKUP
return(trx && trx->mysql_thd && thd_is_strict(trx->mysql_thd));
#else /* UNIV_HOTBACKUP */
return(FALSE);
#endif /* UNIV_HOTBACKUP */
}
/*****************************************************************
Set detailed error message for the transaction. */
UNIV_INTERN
......@@ -694,6 +678,14 @@ trx_start(
{
ibool ret;
/* Update the info whether we should skip XA steps that eat CPU time
For the duration of the transaction trx->support_xa is not reread
from thd so any changes in the value take effect in the next
transaction. This is to avoid a scenario where some undo
generated by a transaction, has XA stuff, and other undo,
generated by the same transaction, doesn't. */
trx->support_xa = thd_supports_xa(trx->mysql_thd);
mutex_enter(&kernel_mutex);
ret = trx_start_low(trx, rseg_id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment