Commit a4f279a2 authored by marko's avatar marko

branches/innodb+: Merge revisions 3579:3599 from branches/zip:

  ------------------------------------------------------------------------
  r3589 | marko | 2008-12-18 15:24:44 +0200 (Thu, 18 Dec 2008) | 2 lines

  branches/zip: ha_innodb.cc: Do not include some unnecessary MySQL
  header files.
  ------------------------------------------------------------------------
  r3594 | marko | 2008-12-19 13:58:13 +0200 (Fri, 19 Dec 2008) | 4 lines

  branches/zip: HASH_INSERT, HASH_DELETE: Add explicit type conversions,
  so that the macros will expand to valid C++.  Unlike C++, C allows
  implicit type conversions from void* to other pointer types.
  ------------------------------------------------------------------------
  r3597 | marko | 2008-12-22 12:27:16 +0200 (Mon, 22 Dec 2008) | 3 lines

  branches/zip: Pass the caller's file name and line number to
  row_mysql_lock_data_dictionary(), row_mysql_freeze_data_dictionary(),
  to better track down locking issues that involve dict_operation_lock.
  ------------------------------------------------------------------------
  r3599 | marko | 2008-12-22 15:41:47 +0200 (Mon, 22 Dec 2008) | 36 lines

  branches/zip: Merge revisions 3479:3598 from branches/5.1:

    ------------------------------------------------------------------------
    r3588 | inaam | 2008-12-18 14:26:54 +0200 (Thu, 18 Dec 2008) | 8 lines

    branches/5.1

    It is a bug in unused code. If we don't calculate the hash value when
    calculating the mutex number then two pages which map to same hash
    value can get two different mutex numbers.

    Approved by: Marko
    ------------------------------------------------------------------------
    r3590 | marko | 2008-12-18 15:33:36 +0200 (Thu, 18 Dec 2008) | 11 lines

    branches/5.1: When converting a record to MySQL format, copy the default
    column values for columns that are SQL NULL.  This addresses failures in
    row-based replication (Bug #39648).

    row_prebuilt_t: Add default_rec, for the default values of the columns in
    MySQL format.

    row_sel_store_mysql_rec(): Use prebuilt->default_rec instead of
    padding columns.

    rb://64 approved by Heikki Tuuri
    ------------------------------------------------------------------------
    r3598 | marko | 2008-12-22 15:28:03 +0200 (Mon, 22 Dec 2008) | 6 lines

    branches/5.1: ibuf_delete_rec(): When the record cannot be found and
    the tablespace has been dropped, commit the mini-transaction, so that
    InnoDB will not hold the insert buffer tree latch in exclusive mode,
    causing a potential deadlock.  This bug was introduced in the fix of
    Bug #27276 in r2924.
    ------------------------------------------------------------------------
  ------------------------------------------------------------------------
parent 5da5707b
...@@ -26,13 +26,10 @@ ...@@ -26,13 +26,10 @@
#endif #endif
#include <mysql_priv.h> #include <mysql_priv.h>
#include <mysqld_error.h>
#include <m_ctype.h> #include <m_ctype.h>
#include <hash.h> #include <hash.h>
#include <myisampack.h>
#include <mysys_err.h> #include <mysys_err.h>
#include <my_sys.h>
#include <mysql/plugin.h> #include <mysql/plugin.h>
/* Include necessary InnoDB headers */ /* Include necessary InnoDB headers */
...@@ -2987,6 +2984,8 @@ ha_innobase::open( ...@@ -2987,6 +2984,8 @@ ha_innobase::open(
prebuilt = row_create_prebuilt(ib_table); prebuilt = row_create_prebuilt(ib_table);
prebuilt->mysql_row_len = table->s->reclength; prebuilt->mysql_row_len = table->s->reclength;
prebuilt->default_rec = table->s->default_values;
ut_ad(prebuilt->default_rec);
/* Looks like MySQL-3.23 sometimes has primary key number != 0 */ /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
......
...@@ -3829,7 +3829,7 @@ ibuf_delete_rec( ...@@ -3829,7 +3829,7 @@ ibuf_delete_rec(
/* The tablespace has been dropped. It is possible /* The tablespace has been dropped. It is possible
that another thread has deleted the insert buffer that another thread has deleted the insert buffer
entry. Do not complain. */ entry. Do not complain. */
goto func_exit; goto commit_and_exit;
} }
fprintf(stderr, fprintf(stderr,
...@@ -3872,6 +3872,7 @@ ibuf_delete_rec( ...@@ -3872,6 +3872,7 @@ ibuf_delete_rec(
#endif #endif
ibuf_size_update(root, mtr); ibuf_size_update(root, mtr);
commit_and_exit:
btr_pcur_commit_specify_mtr(pcur, mtr); btr_pcur_commit_specify_mtr(pcur, mtr);
func_exit: func_exit:
......
...@@ -94,7 +94,7 @@ do {\ ...@@ -94,7 +94,7 @@ do {\
\ \
while (struct3333->NAME != NULL) {\ while (struct3333->NAME != NULL) {\
\ \
struct3333 = struct3333->NAME;\ struct3333 = (TYPE*) struct3333->NAME;\
}\ }\
\ \
struct3333->NAME = DATA;\ struct3333->NAME = DATA;\
...@@ -125,11 +125,11 @@ do {\ ...@@ -125,11 +125,11 @@ do {\
HASH_ASSERT_VALID(DATA->NAME);\ HASH_ASSERT_VALID(DATA->NAME);\
cell3333->node = DATA->NAME;\ cell3333->node = DATA->NAME;\
} else {\ } else {\
struct3333 = cell3333->node;\ struct3333 = (TYPE*) cell3333->node;\
\ \
while (struct3333->NAME != DATA) {\ while (struct3333->NAME != DATA) {\
\ \
struct3333 = struct3333->NAME;\ struct3333 = (TYPE*) struct3333->NAME;\
ut_a(struct3333);\ ut_a(struct3333);\
}\ }\
\ \
......
...@@ -71,7 +71,8 @@ hash_get_mutex_no( ...@@ -71,7 +71,8 @@ hash_get_mutex_no(
ulint fold) /* in: fold */ ulint fold) /* in: fold */
{ {
ut_ad(ut_is_2pow(table->n_mutexes)); ut_ad(ut_is_2pow(table->n_mutexes));
return(ut_2pow_remainder(fold, table->n_mutexes)); return(ut_2pow_remainder(hash_calc_hash(fold, table),
table->n_mutexes));
} }
/**************************************************************** /****************************************************************
......
...@@ -302,31 +302,39 @@ Locks the data dictionary exclusively for performing a table create or other ...@@ -302,31 +302,39 @@ Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */ data dictionary modification operation. */
UNIV_INTERN UNIV_INTERN
void void
row_mysql_lock_data_dictionary( row_mysql_lock_data_dictionary_func(
/*===========================*/ /*================================*/
trx_t* trx); /* in: transaction */ trx_t* trx, /* in/out: transaction */
const char* file, /* in: file name */
ulint line); /* in: line number */
#define row_mysql_lock_data_dictionary(trx) \
row_mysql_lock_data_dictionary_func(trx, __FILE__, __LINE__)
/************************************************************************* /*************************************************************************
Unlocks the data dictionary exclusive lock. */ Unlocks the data dictionary exclusive lock. */
UNIV_INTERN UNIV_INTERN
void void
row_mysql_unlock_data_dictionary( row_mysql_unlock_data_dictionary(
/*=============================*/ /*=============================*/
trx_t* trx); /* in: transaction */ trx_t* trx); /* in/out: transaction */
/************************************************************************* /*************************************************************************
Locks the data dictionary in shared mode from modifications, for performing Locks the data dictionary in shared mode from modifications, for performing
foreign key check, rollback, or other operation invisible to MySQL. */ foreign key check, rollback, or other operation invisible to MySQL. */
UNIV_INTERN UNIV_INTERN
void void
row_mysql_freeze_data_dictionary( row_mysql_freeze_data_dictionary_func(
/*=============================*/ /*==================================*/
trx_t* trx); /* in: transaction */ trx_t* trx, /* in/out: transaction */
const char* file, /* in: file name */
ulint line); /* in: line number */
#define row_mysql_freeze_data_dictionary(trx) \
row_mysql_freeze_data_dictionary_func(trx, __FILE__, __LINE__)
/************************************************************************* /*************************************************************************
Unlocks the data dictionary shared lock. */ Unlocks the data dictionary shared lock. */
UNIV_INTERN UNIV_INTERN
void void
row_mysql_unfreeze_data_dictionary( row_mysql_unfreeze_data_dictionary(
/*===============================*/ /*===============================*/
trx_t* trx); /* in: transaction */ trx_t* trx); /* in/out: transaction */
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
/************************************************************************* /*************************************************************************
Creates a table for MySQL. If the name of the table ends in Creates a table for MySQL. If the name of the table ends in
...@@ -609,6 +617,8 @@ struct row_prebuilt_struct { ...@@ -609,6 +617,8 @@ struct row_prebuilt_struct {
byte* ins_upd_rec_buff;/* buffer for storing data converted byte* ins_upd_rec_buff;/* buffer for storing data converted
to the Innobase format from the MySQL to the Innobase format from the MySQL
format */ format */
const byte* default_rec; /* the default values of all columns
(a "default row") in MySQL format */
ulint hint_need_to_fetch_extra_cols; ulint hint_need_to_fetch_extra_cols;
/* normally this is set to 0; if this /* normally this is set to 0; if this
is set to ROW_RETRIEVE_PRIMARY_KEY, is set to ROW_RETRIEVE_PRIMARY_KEY,
......
...@@ -1634,13 +1634,15 @@ Locks the data dictionary in shared mode from modifications, for performing ...@@ -1634,13 +1634,15 @@ Locks the data dictionary in shared mode from modifications, for performing
foreign key check, rollback, or other operation invisible to MySQL. */ foreign key check, rollback, or other operation invisible to MySQL. */
UNIV_INTERN UNIV_INTERN
void void
row_mysql_freeze_data_dictionary( row_mysql_freeze_data_dictionary_func(
/*=============================*/ /*==================================*/
trx_t* trx) /* in: transaction */ trx_t* trx, /* in/out: transaction */
const char* file, /* in: file name */
ulint line) /* in: line number */
{ {
ut_a(trx->dict_operation_lock_mode == 0); ut_a(trx->dict_operation_lock_mode == 0);
rw_lock_s_lock(&dict_operation_lock); rw_lock_s_lock_func(&dict_operation_lock, 0, file, line);
trx->dict_operation_lock_mode = RW_S_LATCH; trx->dict_operation_lock_mode = RW_S_LATCH;
} }
...@@ -1651,7 +1653,7 @@ UNIV_INTERN ...@@ -1651,7 +1653,7 @@ UNIV_INTERN
void void
row_mysql_unfreeze_data_dictionary( row_mysql_unfreeze_data_dictionary(
/*===============================*/ /*===============================*/
trx_t* trx) /* in: transaction */ trx_t* trx) /* in/out: transaction */
{ {
ut_a(trx->dict_operation_lock_mode == RW_S_LATCH); ut_a(trx->dict_operation_lock_mode == RW_S_LATCH);
...@@ -1665,9 +1667,11 @@ Locks the data dictionary exclusively for performing a table create or other ...@@ -1665,9 +1667,11 @@ Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */ data dictionary modification operation. */
UNIV_INTERN UNIV_INTERN
void void
row_mysql_lock_data_dictionary( row_mysql_lock_data_dictionary_func(
/*===========================*/ /*================================*/
trx_t* trx) /* in: transaction */ trx_t* trx, /* in/out: transaction */
const char* file, /* in: file name */
ulint line) /* in: line number */
{ {
ut_a(trx->dict_operation_lock_mode == 0 ut_a(trx->dict_operation_lock_mode == 0
|| trx->dict_operation_lock_mode == RW_X_LATCH); || trx->dict_operation_lock_mode == RW_X_LATCH);
...@@ -1675,7 +1679,7 @@ row_mysql_lock_data_dictionary( ...@@ -1675,7 +1679,7 @@ row_mysql_lock_data_dictionary(
/* Serialize data dictionary operations with dictionary mutex: /* Serialize data dictionary operations with dictionary mutex:
no deadlocks or lock waits can occur then in these operations */ no deadlocks or lock waits can occur then in these operations */
rw_lock_x_lock(&dict_operation_lock); rw_lock_x_lock_func(&dict_operation_lock, 0, file, line);
trx->dict_operation_lock_mode = RW_X_LATCH; trx->dict_operation_lock_mode = RW_X_LATCH;
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
...@@ -1687,7 +1691,7 @@ UNIV_INTERN ...@@ -1687,7 +1691,7 @@ UNIV_INTERN
void void
row_mysql_unlock_data_dictionary( row_mysql_unlock_data_dictionary(
/*=============================*/ /*=============================*/
trx_t* trx) /* in: transaction */ trx_t* trx) /* in/out: transaction */
{ {
ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
......
...@@ -2670,6 +2670,7 @@ row_sel_store_mysql_rec( ...@@ -2670,6 +2670,7 @@ row_sel_store_mysql_rec(
ulint i; ulint i;
ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->mysql_template);
ut_ad(prebuilt->default_rec);
ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_offs_validate(rec, NULL, offsets));
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
...@@ -2757,58 +2758,14 @@ row_sel_store_mysql_rec( ...@@ -2757,58 +2758,14 @@ row_sel_store_mysql_rec(
&= ~(byte) templ->mysql_null_bit_mask; &= ~(byte) templ->mysql_null_bit_mask;
} }
} else { } else {
/* MySQL seems to assume the field for an SQL NULL /* MySQL assumes that the field for an SQL
value is set to zero or space. Not taking this into NULL value is set to the default value. */
account caused seg faults with NULL BLOB fields, and
bug number 154 in the MySQL bug database: GROUP BY
and DISTINCT could treat NULL values inequal. */
int pad_char;
mysql_rec[templ->mysql_null_byte_offset] mysql_rec[templ->mysql_null_byte_offset]
|= (byte) templ->mysql_null_bit_mask; |= (byte) templ->mysql_null_bit_mask;
switch (templ->type) { memcpy(mysql_rec + templ->mysql_col_offset,
case DATA_VARCHAR: prebuilt->default_rec + templ->mysql_col_offset,
case DATA_BINARY: templ->mysql_col_len);
case DATA_VARMYSQL:
if (templ->mysql_type
== DATA_MYSQL_TRUE_VARCHAR) {
/* This is a >= 5.0.3 type
true VARCHAR. Zero the field. */
pad_char = 0x00;
break;
}
/* Fall through */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_MYSQL:
/* MySQL pads all string types (except
BLOB, TEXT and true VARCHAR) with space. */
if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
/* Treat UCS2 as a special case. */
byte* d = mysql_rec
+ templ->mysql_col_offset;
len = templ->mysql_col_len;
/* There are two UCS2 bytes per char,
so the length has to be even. */
ut_a(!(len & 1));
/* Pad with 0x0020. */
while (len) {
*d++ = 0x00;
*d++ = 0x20;
len -= 2;
}
continue;
}
pad_char = 0x20;
break;
default:
pad_char = 0x00;
break;
}
ut_ad(!pad_char || templ->mbminlen == 1);
memset(mysql_rec + templ->mysql_col_offset,
pad_char, templ->mysql_col_len);
} }
} }
......
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