summaryrefslogtreecommitdiff
path: root/storage/xtradb/row/row0mysql.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/row/row0mysql.cc')
-rw-r--r--storage/xtradb/row/row0mysql.cc112
1 files changed, 95 insertions, 17 deletions
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 8f270cfbfd0..713d184b400 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -31,6 +31,8 @@ Created 9/17/2000 Heikki Tuuri
#endif
#include "ha_prototypes.h"
+
+#include <sql_const.h>
#include "row0ins.h"
#include "row0merge.h"
#include "row0sel.h"
@@ -62,7 +64,6 @@ Created 9/17/2000 Heikki Tuuri
#include "row0import.h"
#include "m_string.h"
#include "my_sys.h"
-#include "ha_prototypes.h"
#include <algorithm>
/** Provide optional 4.x backwards compatibility for 5.0 and above */
@@ -711,8 +712,10 @@ row_create_prebuilt(
row_prebuilt_t* prebuilt;
mem_heap_t* heap;
dict_index_t* clust_index;
+ dict_index_t* temp_index;
dtuple_t* ref;
ulint ref_len;
+ uint srch_key_len = 0;
ulint search_tuple_n_fields;
search_tuple_n_fields = 2 * dict_table_get_n_cols(table);
@@ -724,6 +727,14 @@ row_create_prebuilt(
ref_len = dict_index_get_n_unique(clust_index);
+
+ /* Maximum size of the buffer needed for conversion of INTs from
+ little endian format to big endian format in an index. An index
+ can have maximum 16 columns (MAX_REF_PARTS) in it. Therfore
+ Max size for PK: 16 * 8 bytes (BIGINT's size) = 128 bytes
+ Max size Secondary index: 16 * 8 bytes + PK = 256 bytes. */
+#define MAX_SRCH_KEY_VAL_BUFFER 2* (8 * MAX_REF_PARTS)
+
#define PREBUILT_HEAP_INITIAL_SIZE \
( \
sizeof(*prebuilt) \
@@ -752,10 +763,38 @@ row_create_prebuilt(
+ sizeof(que_thr_t) \
)
+ /* Calculate size of key buffer used to store search key in
+ InnoDB format. MySQL stores INTs in little endian format and
+ InnoDB stores INTs in big endian format with the sign bit
+ flipped. All other field types are stored/compared the same
+ in MySQL and InnoDB, so we must create a buffer containing
+ the INT key parts in InnoDB format.We need two such buffers
+ since both start and end keys are used in records_in_range(). */
+
+ for (temp_index = dict_table_get_first_index(table); temp_index;
+ temp_index = dict_table_get_next_index(temp_index)) {
+ DBUG_EXECUTE_IF("innodb_srch_key_buffer_max_value",
+ ut_a(temp_index->n_user_defined_cols
+ == MAX_REF_PARTS););
+ uint temp_len = 0;
+ for (uint i = 0; i < temp_index->n_uniq; i++) {
+ if (temp_index->fields[i].col->mtype == DATA_INT) {
+ temp_len +=
+ temp_index->fields[i].fixed_len;
+ }
+ }
+ srch_key_len = max(srch_key_len,temp_len);
+ }
+
+ ut_a(srch_key_len <= MAX_SRCH_KEY_VAL_BUFFER);
+
+ DBUG_EXECUTE_IF("innodb_srch_key_buffer_max_value",
+ ut_a(srch_key_len == MAX_SRCH_KEY_VAL_BUFFER););
+
/* We allocate enough space for the objects that are likely to
be created later in order to minimize the number of malloc()
calls */
- heap = mem_heap_create(PREBUILT_HEAP_INITIAL_SIZE);
+ heap = mem_heap_create(PREBUILT_HEAP_INITIAL_SIZE + 2 * srch_key_len);
prebuilt = static_cast<row_prebuilt_t*>(
mem_heap_zalloc(heap, sizeof(*prebuilt)));
@@ -768,6 +807,18 @@ row_create_prebuilt(
prebuilt->sql_stat_start = TRUE;
prebuilt->heap = heap;
+ prebuilt->srch_key_val_len = srch_key_len;
+ if (prebuilt->srch_key_val_len) {
+ prebuilt->srch_key_val1 = static_cast<byte*>(
+ mem_heap_alloc(prebuilt->heap,
+ 2 * prebuilt->srch_key_val_len));
+ prebuilt->srch_key_val2 = prebuilt->srch_key_val1 +
+ prebuilt->srch_key_val_len;
+ } else {
+ prebuilt->srch_key_val1 = NULL;
+ prebuilt->srch_key_val2 = NULL;
+ }
+
btr_pcur_reset(&prebuilt->pcur);
btr_pcur_reset(&prebuilt->clust_pcur);
@@ -1055,8 +1106,11 @@ row_update_statistics_if_needed(
since the last time a statistics batch was run.
We calculate statistics at most every 16th round, since we may have
a counter table which is very small and updated very often. */
+ ib_uint64_t threshold= 16 + n_rows / 16; /* 6.25% */
+ if (srv_stats_modified_counter)
+ threshold= ut_min(srv_stats_modified_counter, threshold);
- if (counter > 16 + n_rows / 16 /* 6.25% */) {
+ if (counter > threshold) {
ut_ad(!mutex_own(&dict_sys->mutex));
/* this will reset table->stat_modified_counter to 0 */
@@ -1396,7 +1450,11 @@ error_exit:
if (UNIV_LIKELY(!(trx->fake_changes))) {
- srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_inserted.add((size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ }
/* Not protected by dict_table_stats_lock() for performance
reasons, we would rather get garbage in stat_n_rows (which is
@@ -1794,9 +1852,19 @@ run_again:
with a latch. */
dict_table_n_rows_dec(prebuilt->table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ }
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ }
}
/* We update table statistics only if it is a DELETE or UPDATE
@@ -1860,7 +1928,7 @@ row_unlock_for_mysql(
trx_id_t rec_trx_id;
mtr_t mtr;
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
/* Restore the cursor position and find the record */
@@ -2025,9 +2093,19 @@ run_again:
with a latch. */
dict_table_n_rows_dec(table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ }
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_updated.add(
+ (size_t)trx->id, 1);
+ } else {
+ srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ }
}
row_update_statistics_if_needed(table);
@@ -2215,23 +2293,23 @@ err_exit:
/* The lock timeout monitor thread also takes care
of InnoDB monitor prints */
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_lock_monitor)) {
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_tablespace_monitor)) {
srv_print_innodb_tablespace_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
} else if (STR_EQ(table_name, table_name_len,
S_innodb_table_monitor)) {
srv_print_innodb_table_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ os_event_set(srv_monitor_event);
#ifdef UNIV_MEM_DEBUG
} else if (STR_EQ(table_name, table_name_len,
S_innodb_mem_validate)) {
@@ -2854,7 +2932,7 @@ row_discard_tablespace_foreign_key_checks(
/* Check if the table is referenced by foreign key constraints from
some other table (not the table itself) */
- dict_foreign_set::iterator it
+ dict_foreign_set::const_iterator it
= std::find_if(table->referenced_set.begin(),
table->referenced_set.end(),
dict_foreign_different_tables());
@@ -3427,7 +3505,7 @@ row_truncate_table_for_mysql(
index = dict_table_get_next_index(index);
} while (index);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
fsp_header_init(space,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
@@ -3456,7 +3534,7 @@ row_truncate_table_for_mysql(
sys_index = dict_table_get_first_index(dict_sys->sys_indexes);
dict_index_copy_types(tuple, sys_index, 1);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF, &pcur, &mtr);
for (;;) {
@@ -3503,7 +3581,7 @@ row_truncate_table_for_mysql(
a page in this mini-transaction, and the rest of
this loop could latch another index page. */
mtr_commit(&mtr);
- mtr_start(&mtr);
+ mtr_start_trx(&mtr, trx);
btr_pcur_restore_position(BTR_MODIFY_LEAF,
&pcur, &mtr);
}