diff options
Diffstat (limited to 'sql/ha_innodb.cc')
-rw-r--r-- | sql/ha_innodb.cc | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 8b0cbe87562..d978327f2ce 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -827,6 +827,7 @@ ha_innobase::ha_innobase(TABLE_SHARE *table_arg) HA_CAN_INDEX_BLOBS | HA_CAN_SQL_HANDLER | HA_NOT_EXACT_COUNT | + HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS | HA_PRIMARY_KEY_IN_READ_INDEX | HA_CAN_GEOMETRY | HA_TABLE_SCAN_ON_INDEX), @@ -3052,6 +3053,9 @@ ha_innobase::store_key_val_for_row( continue; } + /* In a column prefix index, we may need to truncate + the stored value: */ + cs = key_part->field->charset(); src_start = record + key_part->offset; @@ -3068,7 +3072,11 @@ ha_innobase::store_key_val_for_row( memcpy(buff, src_start, len); buff+=len; - /* Pad the unused space with spaces */ + /* Pad the unused space with spaces. Note that no + padding is ever needed for UCS-2 because in MySQL, + all UCS2 characters are 2 bytes, as MySQL does not + support surrogate pairs, which are needed to represent + characters in the range U+10000 to U+10FFFF. */ if (len < key_part->length) { len = key_part->length - len; @@ -3791,9 +3799,9 @@ ha_innobase::delete_row( } /************************************************************************** -Removes a new lock set on a row. This can be called after a row has been read -in the processing of an UPDATE or a DELETE query, if the option -innodb_locks_unsafe_for_binlog is set. */ +Removes a new lock set on a row, if it was not read optimistically. This can +be called after a row has been read in the processing of an UPDATE or a DELETE +query, if the option innodb_locks_unsafe_for_binlog is set. */ void ha_innobase::unlock_row(void) @@ -3803,7 +3811,7 @@ ha_innobase::unlock_row(void) DBUG_ENTER("ha_innobase::unlock_row"); - if (last_query_id != user_thd->query_id) { + if (UNIV_UNLIKELY(last_query_id != user_thd->query_id)) { ut_print_timestamp(stderr); sql_print_error("last_query_id is %lu != user_thd_query_id is " "%lu", (ulong) last_query_id, @@ -3811,9 +3819,45 @@ ha_innobase::unlock_row(void) mem_analyze_corruption((byte *) prebuilt->trx); ut_error; } - - if (srv_locks_unsafe_for_binlog) { + + switch (prebuilt->row_read_type) { + case ROW_READ_WITH_LOCKS: + if (!srv_locks_unsafe_for_binlog) { + break; + } + /* fall through */ + case ROW_READ_TRY_SEMI_CONSISTENT: row_unlock_for_mysql(prebuilt, FALSE); + break; + case ROW_READ_DID_SEMI_CONSISTENT: + prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT; + break; + } + + DBUG_VOID_RETURN; +} + +/* See handler.h and row0mysql.h for docs on this function. */ +bool +ha_innobase::was_semi_consistent_read(void) +/*=======================================*/ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + + return(prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT); +} + +/* See handler.h and row0mysql.h for docs on this function. */ +void +ha_innobase::try_semi_consistent_read(bool yes) +/*===========================================*/ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + + if (yes && srv_locks_unsafe_for_binlog) { + prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT; + } else { + prebuilt->row_read_type = ROW_READ_WITH_LOCKS; } } @@ -4328,6 +4372,13 @@ ha_innobase::rnd_init( err = change_active_index(primary_key); } + /* Don't use semi-consistent read in random row reads (by position). + This means we must disable semi_consistent_read if scan is false */ + + if (!scan) { + try_semi_consistent_read(0); + } + start_of_scan = 1; return(err); |