diff options
Diffstat (limited to 'innobase/row')
-rw-r--r-- | innobase/row/row0ins.c | 93 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 165 | ||||
-rw-r--r-- | innobase/row/row0purge.c | 6 | ||||
-rw-r--r-- | innobase/row/row0row.c | 59 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 19 | ||||
-rw-r--r-- | innobase/row/row0undo.c | 2 | ||||
-rw-r--r-- | innobase/row/row0upd.c | 23 | ||||
-rw-r--r-- | innobase/row/row0vers.c | 8 | ||||
-rw-r--r-- | innobase/row/ts/makefile | 16 | ||||
-rw-r--r-- | innobase/row/ts/tstcur.c | 1087 |
10 files changed, 195 insertions, 1283 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index c89f41f69ad..fc1f7a19d53 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -38,7 +38,7 @@ This prototype is copied from /mysql/sql/ha_innodb.cc. Invalidates the MySQL query cache for the table. NOTE that the exact prototype of this function has to be in /innobase/row/row0ins.c! */ - +extern void innobase_invalidate_query_cache( /*============================*/ @@ -80,9 +80,9 @@ ins_node_create( node->trx_id = ut_dulint_zero; node->entry_sys_heap = mem_heap_create(128); - - node->magic_n = INS_NODE_MAGIC_N; - +#ifdef UNIV_DEBUG + node->magic_n = INS_NODE_MAGIC_N; +#endif /* UNIV_DEBUG */ return(node); } @@ -194,6 +194,7 @@ ins_node_set_new_row( ins_node_t* node, /* in: insert node */ dtuple_t* row) /* in: new row (or first row) for the node */ { + ut_ad(node->magic_n == INS_NODE_MAGIC_N); node->state = INS_NODE_SET_IX_LOCK; node->index = NULL; node->entry = NULL; @@ -682,14 +683,6 @@ row_ins_foreign_check_on_constraint( (DICT_FOREIGN_ON_DELETE_CASCADE | DICT_FOREIGN_ON_DELETE_SET_NULL))) { - /* No action is defined: return a foreign key error if - NO ACTION is not specified */ - - if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { - - return(DB_SUCCESS); - } - row_ins_foreign_report_err((char*)"Trying to delete", thr, foreign, btr_pcur_get_rec(pcur), entry); @@ -703,14 +696,6 @@ row_ins_foreign_check_on_constraint( /* This is an UPDATE */ - /* No action is defined: return a foreign key error if - NO ACTION is not specified */ - - if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { - - return(DB_SUCCESS); - } - row_ins_foreign_report_err((char*)"Trying to update", thr, foreign, btr_pcur_get_rec(pcur), entry); @@ -871,7 +856,7 @@ row_ins_foreign_check_on_constraint( "InnoDB: Make a detailed bug report and send it\n"); fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); - ut_a(0); + ut_error; */ err = DB_SUCCESS; @@ -1047,8 +1032,10 @@ row_ins_check_foreign_constraint( mtr_t mtr; run_again: +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_SHARED)); - +#endif /* UNIV_SYNC_DEBUG */ + err = DB_SUCCESS; if (thr_get_trx(thr)->check_foreigns == FALSE) { @@ -1365,58 +1352,6 @@ row_ins_check_foreign_constraints( return(DB_SUCCESS); } -/************************************************************************* -Reports a UNIQUE key error to dict_unique_err_buf so that SHOW INNODB -STATUS can print it. */ -static -void -row_ins_unique_report_err( -/*======================*/ - que_thr_t* thr, /* in: query thread */ - rec_t* rec, /* in: a record in the index */ - dtuple_t* entry, /* in: index entry to insert in the index */ - dict_index_t* index) /* in: index */ -{ - UT_NOT_USED(thr); - UT_NOT_USED(rec); - UT_NOT_USED(entry); - UT_NOT_USED(index); - -#ifdef notdefined - /* Disable reporting to test if the slowdown of REPLACE in 4.0.13 was - caused by this! */ - - char* buf = dict_unique_err_buf; - - /* The foreign err mutex protects also dict_unique_err_buf */ - - mutex_enter(&dict_foreign_err_mutex); - - ut_sprintf_timestamp(buf); - sprintf(buf + strlen(buf), " Transaction:\n"); - trx_print(buf + strlen(buf), thr_get_trx(thr)); - - sprintf(buf + strlen(buf), -"Unique key constraint fails for table %.500s.\n", index->table_name); - sprintf(buf + strlen(buf), -"Trying to add in index %.500s (%lu fields unique) tuple:\n", index->name, - dict_index_get_n_unique(index)); - - dtuple_sprintf(buf + strlen(buf), 1000, entry); - - sprintf(buf + strlen(buf), -"\nBut there is already a record:\n"); - - rec_sprintf(buf + strlen(buf), 1000, rec); - - sprintf(buf + strlen(buf), "\n"); - - ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); - - mutex_exit(&dict_foreign_err_mutex); -#endif -} - /******************************************************************* Checks if a unique key violation to rec would occur at the index entry insert. */ @@ -1547,8 +1482,6 @@ row_ins_scan_sec_index_for_duplicate( if (cmp == 0) { if (row_ins_dupl_error_with_rec(rec, entry, index)) { - row_ins_unique_report_err(thr, rec, entry, - index); err = DB_DUPLICATE_KEY; thr_get_trx(thr)->error_info = index; @@ -1643,8 +1576,6 @@ row_ins_duplicate_error_in_clust( if (row_ins_dupl_error_with_rec(rec, entry, cursor->index)) { trx->error_info = cursor->index; - row_ins_unique_report_err(thr, rec, entry, - cursor->index); return(DB_DUPLICATE_KEY); } } @@ -1667,9 +1598,6 @@ row_ins_duplicate_error_in_clust( if (row_ins_dupl_error_with_rec(rec, entry, cursor->index)) { trx->error_info = cursor->index; - - row_ins_unique_report_err(thr, rec, entry, - cursor->index); return(DB_DUPLICATE_KEY); } } @@ -2115,6 +2043,7 @@ row_ins( ulint err; ut_ad(node && thr); + ut_ad(node->magic_n == INS_NODE_MAGIC_N); if (node->state == INS_NODE_ALLOC_ROW_ID) { @@ -2179,7 +2108,7 @@ row_ins_step( trx_start_if_not_started(trx); node = thr->run_node; - + ut_ad(node->magic_n == INS_NODE_MAGIC_N); ut_ad(que_node_get_type(node) == QUE_NODE_INSERT); parent = que_node_get_parent(node); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index cf7a3efcdfc..49e5aeac2e4 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -287,7 +287,7 @@ handle_new_error: } else { fprintf(stderr, "InnoDB: unknown error code %lu\n", (ulong) err); - ut_a(0); + ut_error; } if (trx->error_state != DB_SUCCESS) { @@ -402,7 +402,7 @@ row_prebuilt_free( mem_analyze_corruption((byte*)prebuilt); - ut_a(0); + ut_error; } prebuilt->magic_n = ROW_PREBUILT_FREED; @@ -450,7 +450,7 @@ row_prebuilt_free( mem_analyze_corruption( prebuilt->fetch_cache[i]); - ut_a(0); + ut_error; } mem_free((prebuilt->fetch_cache[i]) - 4); @@ -482,7 +482,7 @@ row_update_prebuilt_trx( mem_analyze_corruption((byte*)trx); - ut_a(0); + ut_error; } if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) { @@ -493,7 +493,7 @@ row_update_prebuilt_trx( mem_analyze_corruption((byte*)prebuilt); - ut_a(0); + ut_error; } prebuilt->trx = trx; @@ -720,7 +720,7 @@ row_insert_for_mysql( mem_analyze_corruption((byte*)prebuilt); - ut_a(0); + ut_error; } if (srv_created_new_raw || srv_force_recovery) { @@ -936,7 +936,7 @@ row_update_for_mysql( mem_analyze_corruption((byte*)prebuilt); - ut_a(0); + ut_error; } if (srv_created_new_raw || srv_force_recovery) { @@ -1289,9 +1289,11 @@ row_create_table_for_mysql( ulint err; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(mutex_own(&(dict_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); if (srv_created_new_raw) { fprintf(stderr, @@ -1408,10 +1410,12 @@ row_create_table_for_mysql( "UNIV_MEM_DEBUG defined in univ.i and the server must be\n" "quiet because allocation from a mem heap is not protected\n" "by any semaphore.\n"); - +#ifdef UNIV_MEM_DEBUG ut_a(mem_validate()); - printf("Memory validated\n"); +#else /* UNIV_MEM_DEBUG */ + puts("Memory NOT validated (recompile with UNIV_MEM_DEBUG)"); +#endif /* UNIV_MEM_DEBUG */ } heap = mem_heap_create(512); @@ -1422,8 +1426,7 @@ row_create_table_for_mysql( thr = pars_complete_graph_for_exec(node, trx, heap); - ut_a(thr == que_fork_start_command(que_node_get_parent(thr), - SESS_COMM_EXECUTE, 0)); + ut_a(thr == que_fork_start_command(que_node_get_parent(thr))); que_run_threads(thr); err = trx->error_state; @@ -1494,8 +1497,10 @@ row_create_index_for_mysql( ulint err; ulint i, j; +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); ut_ad(mutex_own(&(dict_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); trx->op_info = (char *) "creating index"; @@ -1550,8 +1555,7 @@ row_create_index_for_mysql( thr = pars_complete_graph_for_exec(node, trx, heap); - ut_a(thr == que_fork_start_command(que_node_get_parent(thr), - SESS_COMM_EXECUTE, 0)); + ut_a(thr == que_fork_start_command(que_node_get_parent(thr))); que_run_threads(thr); err = trx->error_state; @@ -1602,8 +1606,10 @@ row_table_add_foreign_constraints( ulint keywordlen; ulint err; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ ut_a(sql_string); trx->op_info = (char *) "adding foreign keys"; @@ -1774,7 +1780,9 @@ row_get_background_drop_list_len_low(void) /*======================================*/ /* out: how many tables in list */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); +#endif /* UNIV_SYNC_DEBUG */ if (!row_mysql_drop_list_inited) { @@ -1926,7 +1934,7 @@ row_discard_tablespace_for_mysql( graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - ut_a(thr = que_fork_start_command(graph, SESS_COMM_EXECUTE, 0)); + ut_a(thr = que_fork_start_command(graph)); que_run_threads(thr); @@ -2085,6 +2093,7 @@ row_drop_table_for_mysql( char* name, /* in: table name */ trx_t* trx) /* in: transaction handle */ { + dict_foreign_t* foreign; dict_table_t* table; ulint space_id; que_thr_t* thr; @@ -2252,8 +2261,10 @@ row_drop_table_for_mysql( locked_dictionary = TRUE; } +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ graph = pars_sql(buf); @@ -2282,6 +2293,38 @@ row_drop_table_for_mysql( goto funct_exit; } + /* Check if the table is referenced by foreign key constraints from + some other table (not the table itself) */ + + foreign = UT_LIST_GET_FIRST(table->referenced_list); + + while (foreign && foreign->foreign_table == table) { + foreign = UT_LIST_GET_NEXT(referenced_list, foreign); + } + + if (foreign && trx->check_foreigns) { + char* buf = dict_foreign_err_buf; + + /* We only allow dropping a referenced table if + FOREIGN_KEY_CHECKS is set to 0 */ + + err = DB_CANNOT_DROP_CONSTRAINT; + + mutex_enter(&dict_foreign_err_mutex); + ut_sprintf_timestamp(buf); + + sprintf(buf + strlen(buf), + " Cannot drop table %.500s\n", name); + sprintf(buf + strlen(buf), +"because it is referenced by %.500s\n", foreign->foreign_table_name); + + ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); + + mutex_exit(&dict_foreign_err_mutex); + + goto funct_exit; + } + if (table->n_mysql_handles_opened > 0) { ut_print_timestamp(stderr); @@ -2321,7 +2364,7 @@ row_drop_table_for_mysql( trx->dict_operation = TRUE; trx->table_id = table->id; - ut_a(thr = que_fork_start_command(graph, SESS_COMM_EXECUTE, 0)); + ut_a(thr = que_fork_start_command(graph)); que_run_threads(thr); @@ -2334,7 +2377,7 @@ row_drop_table_for_mysql( row_mysql_handle_errors(&err, trx, thr, NULL); - ut_a(0); + ut_error; } else { space_id = table->space; dict_table_remove_from_cache(table); @@ -2469,7 +2512,7 @@ row_is_mysql_tmp_table_name( { ulint i; - for (i = 0; i <= ut_strlen(name) - 5; i++) { + for (i = 0; i + 5 <= ut_strlen(name); i++) { if (ut_memcmp(name + i, (char*)"/#sql", 5) == 0) { return(TRUE); @@ -2505,6 +2548,7 @@ row_rename_table_for_mysql( ulint keywordlen; ulint len; ulint i; + char* db_name; ibool success; char buf[2 * OS_FILE_MAX_PATH]; @@ -2593,6 +2637,15 @@ row_rename_table_for_mysql( "PROCEDURE RENAME_TABLE_PROC () IS\n" "new_table_name CHAR;\n" "old_table_name CHAR;\n" + "gen_constr_prefix CHAR;\n" + "new_db_name CHAR;\n" + "foreign_id CHAR;\n" + "new_foreign_id CHAR;\n" + "old_db_name_len INT;\n" + "old_t_name_len INT;\n" + "new_db_name_len INT;\n" + "id_len INT;\n" + "found INT;\n" "BEGIN\n" "new_table_name :='"; @@ -2619,32 +2672,94 @@ row_rename_table_for_mysql( } str3 = mem_heap_alloc(heap, - 1000 + 500 * n_constraints_to_drop); + 1000 + 1000 * n_constraints_to_drop); *str3 = '\0'; sprintf(str3, "';\n" "UPDATE SYS_TABLES SET NAME = new_table_name\n" "WHERE NAME = old_table_name;\n"); + db_name = mem_heap_alloc(heap, 1 + dict_get_db_name_len( + old_name)); + ut_memcpy(db_name, old_name, dict_get_db_name_len(old_name)); + db_name[dict_get_db_name_len(old_name)] = '\0'; + + /* Internally, old format < 4.0.18 constraints have as the + constraint id <number>_<number>, while new format constraints + have <databasename>/<constraintname>. */ + for (i = 0; i < n_constraints_to_drop; i++) { + sprintf(str3 + strlen(str3), - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s';\n" - "DELETE FROM SYS_FOREIGN WHERE ID = '%s';\n", + "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s/%s';\n" + "DELETE FROM SYS_FOREIGN WHERE ID = '%s/%s';\n", + db_name, constraints_to_drop[i], + db_name, constraints_to_drop[i]); + + if (!ut_str_contains(constraints_to_drop[i], '/')) { + /* If this happens to be an old format + constraint, let us delete it. Since all new + format constraints contain '/', it does no + harm to run these DELETEs anyway. */ + + sprintf(str3 + strlen(str3), + "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s';\n" + "DELETE FROM SYS_FOREIGN WHERE ID = '%s';\n", constraints_to_drop[i], constraints_to_drop[i]); + } } sprintf(str3 + strlen(str3), "END;\n"); - ut_a(strlen(str3) < 1000 + 500 * n_constraints_to_drop); + ut_a(strlen(str3) < 1000 + 1000 * n_constraints_to_drop); } else { str3 = (char*) "';\n" "UPDATE SYS_TABLES SET NAME = new_table_name\n" "WHERE NAME = old_table_name;\n" - "UPDATE SYS_FOREIGN SET FOR_NAME = new_table_name\n" - "WHERE FOR_NAME = old_table_name;\n" + "found := 1;\n" + "old_db_name_len := INSTR(old_table_name, '/') - 1;\n" + "new_db_name_len := INSTR(new_table_name, '/') - 1;\n" + "new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n" + "old_t_name_len := LENGTH(old_table_name);\n" + "gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO foreign_id\n" + " FROM SYS_FOREIGN\n" + " WHERE FOR_NAME = old_table_name;\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE\n" + " UPDATE SYS_FOREIGN\n" + " SET FOR_NAME = new_table_name\n" + " WHERE ID = foreign_id;\n" + " id_len := LENGTH(foreign_id);\n" + " IF (INSTR(foreign_id, '/') > 0) THEN\n" + " IF (INSTR(foreign_id,\n" + " gen_constr_prefix) > 0)\n" + " THEN\n" + " new_foreign_id :=\n" + " CONCAT(new_table_name,\n" + " SUBSTR(foreign_id, old_t_name_len,\n" + " id_len - old_t_name_len));\n" + " ELSE\n" + " new_foreign_id :=\n" + " CONCAT(new_db_name,\n" + " SUBSTR(foreign_id,\n" + " old_db_name_len,\n" + " id_len - old_db_name_len));\n" + " END IF;\n" + " UPDATE SYS_FOREIGN\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " UPDATE SYS_FOREIGN_COLS\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " END IF;\n" + " END IF;\n" + "END LOOP;\n" "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" "WHERE REF_NAME = old_table_name;\n" "END;\n"; @@ -2679,7 +2794,7 @@ row_rename_table_for_mysql( graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - ut_a(thr = que_fork_start_command(graph, SESS_COMM_EXECUTE, 0)); + ut_a(thr = que_fork_start_command(graph)); que_run_threads(thr); diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index d5895f20461..a409b64f8e4 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -140,7 +140,7 @@ row_purge_remove_clust_if_poss_low( } else if (err == DB_OUT_OF_FILE_SPACE) { success = FALSE; } else { - ut_a(0); + ut_error; } } @@ -266,7 +266,7 @@ row_purge_remove_sec_if_poss_low( } else if (err == DB_OUT_OF_FILE_SPACE) { success = FALSE; } else { - ut_a(0); + ut_error; } } } @@ -447,8 +447,10 @@ skip_secondaries: data_field = buf_page_get(0, page_no, RW_X_LATCH, &mtr) + offset + internal_offset; +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(buf_frame_align(data_field), SYNC_TRX_UNDO_PAGE); +#endif /* UNIV_SYNC_DEBUG */ data_field_len = ufield->new_val.len; diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 6c0c6c04cd5..6820cb5bccd 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -236,61 +236,6 @@ row_build( return(row); } -#ifdef notdefined -/*********************************************************************** -An inverse function to dict_row_build_index_entry. Builds a row from a -record in a clustered index. */ - -void -row_build_to_tuple( -/*===============*/ - dtuple_t* row, /* in/out: row built; see the NOTE below! */ - dict_index_t* index, /* in: clustered index */ - rec_t* rec) /* in: record in the clustered index; - NOTE: the data fields in the row will point - directly into this record, therefore, - the buffer page of this record must be - at least s-latched and the latch held - as long as the row dtuple is used! - NOTE 2: does not work with externally - stored fields! */ -{ - dict_table_t* table; - ulint n_fields; - ulint i; - dfield_t* dfield; - byte* field; - ulint len; - ulint row_len; - dict_col_t* col; - - ut_ad(index && rec); - ut_ad(index->type & DICT_CLUSTERED); - - table = index->table; - row_len = dict_table_get_n_cols(table); - - dtuple_set_info_bits(row, rec_get_info_bits(rec)); - - n_fields = dict_index_get_n_fields(index); - - ut_ad(n_fields == rec_get_n_fields(rec)); - - dict_table_copy_types(row, table); - - for (i = 0; i < n_fields; i++) { - - col = dict_field_get_col(dict_index_get_nth_field(index, i)); - dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); - field = rec_get_nth_field(rec, i, &len); - - dfield_set_data(dfield, field, len); - } - - ut_ad(dtuple_check_typed(row)); -} -#endif - /*********************************************************************** Converts an index record to a typed data tuple. NOTE that externally stored (often big) fields are NOT copied to heap. */ @@ -461,7 +406,7 @@ row_build_row_ref_in_tuple( if (!table) { fprintf(stderr, "InnoDB: table %s for index %s not found\n", index->table_name, index->name); - ut_a(0); + ut_error; } clust_index = dict_table_get_first_index(table); @@ -470,7 +415,7 @@ row_build_row_ref_in_tuple( fprintf(stderr, "InnoDB: clust index for table %s for index %s not found\n", index->table_name, index->name); - ut_a(0); + ut_error; } ref_len = dict_index_get_n_unique(clust_index); diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 57de309c090..4f70cea2058 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -930,7 +930,9 @@ row_sel_try_search_shortcut( ut_ad(node->read_view); ut_ad(plan->unique_search); ut_ad(!plan->must_get_clust); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ row_sel_open_pcur(node, plan, TRUE, mtr); @@ -2080,7 +2082,7 @@ row_sel_store_row_id_to_prebuilt( (ulong) len, index->table_name, index->name, (ulong) dict_index_get_sys_col_pos(index, DATA_ROW_ID), err_buf); - ut_a(0); + ut_error; } ut_memcpy(prebuilt->row_id, data, len); @@ -2770,7 +2772,7 @@ row_search_for_mysql( mem_analyze_corruption((byte*)prebuilt); - ut_a(0); + ut_error; } if (trx->n_mysql_tables_in_use == 0) { @@ -2831,7 +2833,7 @@ row_search_for_mysql( if (direction != prebuilt->fetch_direction) { if (prebuilt->n_fetch_cached > 0) { - ut_a(0); + ut_error; /* TODO: scrollable cursor: restore cursor to the place of the latest returned row, or better: prevent caching for a scroll @@ -2886,7 +2888,16 @@ row_search_for_mysql( if (match_mode == ROW_SEL_EXACT && index->type & DICT_UNIQUE && dtuple_get_n_fields(search_tuple) - == dict_index_get_n_unique(index)) { + == dict_index_get_n_unique(index) + && (index->type & DICT_CLUSTERED + || !dtuple_contains_null(search_tuple))) { + + /* Note above that a UNIQUE secondary index can contain many + rows with the same key value if one of the columns is the SQL + null. A clustered index under MySQL can never contain null + columns because we demand that all the columns in primary key + are non-null. */ + unique_search = TRUE; /* Even if the condition is unique, MySQL seems to try to diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index f223bb5eed5..613d0a3b890 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -334,7 +334,7 @@ row_undo_step( exit(1); } - ut_a(0); + ut_error; return(NULL); } diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index b9e9b8c15c9..f8739b65c2f 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -77,8 +77,8 @@ index record. This is only used in foreign key checks and we can assume that index does not contain column prefixes. */ static ibool -row_upd_changes_first_fields( -/*=========================*/ +row_upd_changes_first_fields_binary( +/*================================*/ /* out: TRUE if changes */ dtuple_t* entry, /* in: old value of index entry */ dict_index_t* index, /* in: index of entry */ @@ -196,7 +196,7 @@ row_upd_check_references_constraints( if (foreign->referenced_index == index && (node->is_delete - || row_upd_changes_first_fields(entry, index, + || row_upd_changes_first_fields_binary(entry, index, node->update, foreign->n_fields))) { if (foreign->foreign_table == NULL) { @@ -287,7 +287,9 @@ upd_node_create( node->select = NULL; node->heap = mem_heap_create(128); - node->magic_n = UPD_NODE_MAGIC_N; +#ifdef UNIV_DEBUG + node->magic_n = UPD_NODE_MAGIC_N; +#endif /* UNIV_DEBUG */ node->cmpl_info = 0; @@ -1048,8 +1050,8 @@ index record. This is only used in foreign key checks and we can assume that index does not contain column prefixes. */ static ibool -row_upd_changes_first_fields( -/*=========================*/ +row_upd_changes_first_fields_binary( +/*================================*/ /* out: TRUE if changes */ dtuple_t* entry, /* in: index entry */ dict_index_t* index, /* in: index of entry */ @@ -1074,15 +1076,16 @@ row_upd_changes_first_fields( col = dict_field_get_col(ind_field); col_pos = dict_col_get_clust_pos(col); + ut_a(ind_field->prefix_len == 0); + for (j = 0; j < n_upd_fields; j++) { upd_field = upd_get_nth_field(update, j); if (col_pos == upd_field->field_no - && (ind_field->prefix_len > 0 - || 0 != cmp_dfield_dfield( + && !dfield_datas_are_binary_equal( dtuple_get_nth_field(entry, i), - &(upd_field->new_val)))) { + &(upd_field->new_val))) { return(TRUE); } } @@ -1804,6 +1807,7 @@ row_upd_step( trx_start_if_not_started(trx); node = thr->run_node; + ut_ad(node->magic_n == UPD_NODE_MAGIC_N); sel_node = node->select; @@ -1923,6 +1927,7 @@ row_upd_in_place_in_select( node = que_node_get_parent(sel_node); + ut_ad(node->magic_n == UPD_NODE_MAGIC_N); ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE); pcur = node->pcur; diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index fca56389e45..bc17ede89e3 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -60,8 +60,10 @@ row_vers_impl_x_locked_off_kernel( ulint err; mtr_t mtr; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ mutex_exit(&kernel_mutex); @@ -254,7 +256,9 @@ row_vers_must_preserve_del_marked( mtr_t* mtr) /* in: mtr holding the latch on the clustered index record; it will also hold the latch on purge_view */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ mtr_s_lock(&(purge_sys->latch), mtr); @@ -302,7 +306,9 @@ row_vers_old_has_index_entry( ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX) || mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_S_FIX)); +#ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ mtr_s_lock(&(purge_sys->latch), mtr); clust_index = dict_table_get_first_index(index->table); @@ -411,7 +417,9 @@ row_vers_build_for_consistent_read( ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX) || mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_S_FIX)); +#ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(!read_view_sees_trx_id(view, row_get_rec_trx_id(rec, index))); rw_lock_s_lock(&(purge_sys->latch)); diff --git a/innobase/row/ts/makefile b/innobase/row/ts/makefile deleted file mode 100644 index 589db50d4ed..00000000000 --- a/innobase/row/ts/makefile +++ /dev/null @@ -1,16 +0,0 @@ - - - -include ..\..\makefile.i - -tstcur: ..\tcur.lib tstcur.c - $(CCOM) $(CFL) -I.. -I..\.. ..\tcur.lib ..\..\trx.lib ..\..\btr.lib ..\..\fut.lib ..\..\fsp.lib ..\..\page.lib ..\..\dyn.lib ..\..\mtr.lib ..\..\log.lib ..\..\rem.lib ..\..\fil.lib ..\..\buf.lib ..\..\dict.lib ..\..\data.lib ..\..\mach.lib ..\..\ha.lib ..\..\ut.lib ..\..\sync.lib ..\..\mem.lib ..\..\os.lib tstcur.c $(LFL) - - - - - - - - - diff --git a/innobase/row/ts/tstcur.c b/innobase/row/ts/tstcur.c deleted file mode 100644 index f5a5eb1f9f3..00000000000 --- a/innobase/row/ts/tstcur.c +++ /dev/null @@ -1,1087 +0,0 @@ -/************************************************************************ -Test for the index system - -(c) 1994-1996 Innobase Oy - -Created 2/16/1996 Heikki Tuuri -*************************************************************************/ - -#include "sync0sync.h" -#include "ut0mem.h" -#include "mem0mem.h" -#include "data0data.h" -#include "data0type.h" -#include "dict0dict.h" -#include "buf0buf.h" -#include "os0file.h" -#include "fil0fil.h" -#include "fsp0fsp.h" -#include "rem0rec.h" -#include "rem0cmp.h" -#include "mtr0mtr.h" -#include "log0log.h" -#include "page0page.h" -#include "page0cur.h" -#include "trx0trx.h" -#include "dict0boot.h" -#include "trx0sys.h" -#include "dict0crea.h" -#include "btr0btr.h" -#include "btr0pcur.h" -#include "rem0rec.h" -#include "..\tcur0ins.h" - -os_file_t files[1000]; - -mutex_t ios_mutex; -ulint ios; -ulint n[10]; - -mutex_t incs_mutex; -ulint incs; - -byte bigbuf[1000000]; - -#define N_SPACES 1 -#define N_FILES 1 -#define FILE_SIZE 4000 /* must be > 512 */ -#define POOL_SIZE 1000 -#define COUNTER_OFFSET 1500 - -#define LOOP_SIZE 150 -#define N_THREADS 5 - - -ulint zero = 0; - -buf_block_t* bl_arr[POOL_SIZE]; - -/************************************************************************ -Io-handler thread function. */ - -ulint -handler_thread( -/*===========*/ - void* arg) -{ - ulint segment; - void* mess; - ulint i; - bool ret; - - segment = *((ulint*)arg); - - printf("Io handler thread %lu starts\n", segment); - - for (i = 0;; i++) { - ret = fil_aio_wait(segment, &mess); - ut_a(ret); - - buf_page_io_complete((buf_block_t*)mess); - - mutex_enter(&ios_mutex); - ios++; - mutex_exit(&ios_mutex); - - } - - return(0); -} - -/************************************************************************* -Creates the files for the file system test and inserts them to -the file system. */ - -void -create_files(void) -/*==============*/ -{ - bool ret; - ulint i, k; - char name[20]; - os_thread_t thr[5]; - os_thread_id_t id[5]; - - printf("--------------------------------------------------------\n"); - printf("Create or open database files\n"); - - strcpy(name, "tsfile00"); - - for (k = 0; k < N_SPACES; k++) { - for (i = 0; i < N_FILES; i++) { - - name[6] = (char)((ulint)'0' + k); - name[7] = (char)((ulint)'0' + i); - - files[i] = os_file_create(name, OS_FILE_CREATE, - OS_FILE_TABLESPACE, &ret); - - if (ret == FALSE) { - ut_a(os_file_get_last_error() == - OS_FILE_ALREADY_EXISTS); - - files[i] = os_file_create( - name, OS_FILE_OPEN, - OS_FILE_TABLESPACE, &ret); - - ut_a(ret); - } - - ret = os_file_close(files[i]); - ut_a(ret); - - if (i == 0) { - fil_space_create(name, k, OS_FILE_TABLESPACE); - } - - ut_a(fil_validate()); - - fil_node_create(name, FILE_SIZE, k); - } - } - - ios = 0; - - mutex_create(&ios_mutex); - - for (i = 0; i < 5; i++) { - n[i] = i; - - thr[i] = os_thread_create(handler_thread, n + i, id + i); - } -} - -/************************************************************************ -Inits space header of space 0. */ - -void -init_space(void) -/*============*/ -{ - mtr_t mtr; - - printf("Init space header\n"); - - mtr_start(&mtr); - - fsp_header_init(0, FILE_SIZE * N_FILES, &mtr); - - mtr_commit(&mtr); -} - -/********************************************************************* -Test for index page. */ - -void -test1(void) -/*=======*/ -{ - dtuple_t* tuple; - mem_heap_t* heap; - mem_heap_t* heap2; - ulint rnd = 0; - dict_index_t* index; - dict_table_t* table; - byte buf[16]; - ulint i, j; - ulint tm, oldtm; - trx_t* trx; -/* dict_tree_t* tree;*/ - btr_pcur_t pcur; - btr_pcur_t pcur2; - mtr_t mtr; - mtr_t mtr2; - byte* field; - ulint len; - dtuple_t* search_tuple; - dict_tree_t* index_tree; - rec_t* rec; - - UT_NOT_USED(len); - UT_NOT_USED(field); - UT_NOT_USED(pcur2); -/* - printf("\n\n\nPress 2 x enter to start test\n"); - - while (EOF == getchar()) { - - } - - getchar(); -*/ - printf("-------------------------------------------------\n"); - printf("TEST 1. CREATE TABLE WITH 3 COLUMNS AND WITH 3 INDEXES\n"); - - heap = mem_heap_create(1024); - heap2 = mem_heap_create(1024); - - trx = trx_start(ULINT_UNDEFINED); - - table = dict_mem_table_create("TS_TABLE1", 0, 3); - - dict_mem_table_add_col(table, "COL1", DATA_VARCHAR, - DATA_ENGLISH, 10, 0); - dict_mem_table_add_col(table, "COL2", DATA_VARCHAR, - DATA_ENGLISH, 10, 0); - dict_mem_table_add_col(table, "COL3", DATA_VARCHAR, - DATA_ENGLISH, 100, 0); - - ut_a(TRUE == dict_create_table(table, trx)); - - index = dict_mem_index_create("TS_TABLE1", "IND1", 75046, - DICT_CLUSTERED, 2); - - dict_mem_index_add_field(index, "COL1", 0); - dict_mem_index_add_field(index, "COL2", 0); - - ut_a(mem_heap_validate(index->heap)); - - ut_a(TRUE == dict_create_index(index, trx)); - - trx_commit(trx); - - trx = trx_start(ULINT_UNDEFINED); - - index = dict_mem_index_create("TS_TABLE1", "IND2", 0, DICT_UNIQUE, 1); - - dict_mem_index_add_field(index, "COL2", 0); - - ut_a(mem_heap_validate(index->heap)); - - ut_a(TRUE == dict_create_index(index, trx)); - - trx_commit(trx); - - trx = trx_start(ULINT_UNDEFINED); - - index = dict_mem_index_create("TS_TABLE1", "IND3", 0, DICT_UNIQUE, 1); - - dict_mem_index_add_field(index, "COL2", 0); - - ut_a(mem_heap_validate(index->heap)); - - ut_a(TRUE == dict_create_index(index, trx)); - - trx_commit(trx); -/* - tree = dict_index_get_tree(dict_table_get_first_index(table)); - - btr_print_tree(tree, 10); -*/ - dict_table_print(table); - - /*---------------------------------------------------------*/ -/* - printf("\n\n\nPress 2 x enter to continue test\n"); - - while (EOF == getchar()) { - - } - getchar(); -*/ - printf("-------------------------------------------------\n"); - printf("TEST 2. INSERT 1 ROW TO THE TABLE\n"); - - trx = trx_start(ULINT_UNDEFINED); - - tuple = dtuple_create(heap, 3); - - table = dict_table_get("TS_TABLE1", trx); - - dtuple_gen_test_tuple3(tuple, 0, buf); - tcur_insert(tuple, table, heap2, trx); - - trx_commit(trx); -/* - tree = dict_index_get_tree(dict_table_get_first_index(table)); - - btr_print_tree(tree, 10); -*/ -/* - printf("\n\n\nPress 2 x enter to continue test\n"); - - while (EOF == getchar()) { - - } - getchar(); -*/ - printf("-------------------------------------------------\n"); - printf("TEST 3. INSERT MANY ROWS TO THE TABLE IN A SINGLE TRX\n"); - - rnd = 0; - oldtm = ut_clock(); - - trx = trx_start(ULINT_UNDEFINED); - for (i = 0; i < 300 * UNIV_DBC * UNIV_DBC; i++) { - - if (i % 5000 == 0) { - /* dict_table_print(table); - buf_print(); - buf_LRU_print(); - printf("%lu rows inserted\n", i); */ - } - - table = dict_table_get("TS_TABLE1", trx); - - if (i == 2180) { - rnd = rnd % 200000; - } - - rnd = (rnd + 1) % 200000; - - dtuple_gen_test_tuple3(tuple, rnd, buf); - - tcur_insert(tuple, table, heap2, trx); - - mem_heap_empty(heap2); - - if (i % 4 == 3) { - } - } - trx_commit(trx); - - tm = ut_clock(); - printf("Wall time for test %lu milliseconds\n", tm - oldtm); - printf("%lu rows inserted\n", i); -/* - printf("\n\n\nPress 2 x enter to continue test\n"); - - while (EOF == getchar()) { - - } - getchar(); -*/ - printf("-------------------------------------------------\n"); - printf("TEST 4. PRINT PART OF CONTENTS OF EACH INDEX TREE\n"); - -/* - mem_print_info(); -*/ - -/* - tree = dict_index_get_tree(dict_table_get_first_index(table)); - - btr_print_tree(tree, 10); - - tree = dict_index_get_tree(dict_table_get_next_index( - dict_table_get_first_index(table))); - - btr_print_tree(tree, 5); -*/ -/* - printf("\n\n\nPress 2 x enter to continue test\n"); - - while (EOF == getchar()) { - - } - getchar(); -*/ -/* mem_print_info(); */ - - os_thread_sleep(5000000); - - for (j = 0; j < 5; j++) { - printf("-------------------------------------------------\n"); - printf("TEST 5. CALCULATE THE JOIN OF THE TABLE WITH ITSELF\n"); - - i = 0; - - oldtm = ut_clock(); - - mtr_start(&mtr); - - index_tree = dict_index_get_tree(UT_LIST_GET_FIRST(table->indexes)); - - search_tuple = dtuple_create(heap, 2); - - dtuple_gen_search_tuple3(search_tuple, i, buf); - - btr_pcur_open(index_tree, search_tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); - - ut_a(btr_pcur_move_to_next(&pcur, &mtr)); - - while (!btr_pcur_is_after_last_in_tree(&pcur, &mtr)) { - - if (i % 20000 == 0) { - printf("%lu rows joined\n", i); - } - - index_tree = dict_index_get_tree( - UT_LIST_GET_FIRST(table->indexes)); - - rec = btr_pcur_get_rec(&pcur); - - rec_copy_prefix_to_dtuple(search_tuple, rec, 2, heap2); - - mtr_start(&mtr2); - - btr_pcur_open(index_tree, search_tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur2, &mtr2); - - btr_pcur_move_to_next(&pcur2, &mtr2); - - rec = btr_pcur_get_rec(&pcur2); - - field = rec_get_nth_field(rec, 1, &len); - - ut_a(len == 8); - - ut_a(ut_memcmp(field, dfield_get_data( - dtuple_get_nth_field(search_tuple, 1)), - len) == 0); - - btr_pcur_close(&pcur2, &mtr); - - mem_heap_empty(heap2); - - mtr_commit(&mtr2); - - btr_pcur_store_position(&pcur, &mtr); - mtr_commit(&mtr); - - mtr_start(&mtr); - - btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); - - btr_pcur_move_to_next(&pcur, &mtr); - i++; - } - - btr_pcur_close(&pcur, &mtr); - mtr_commit(&mtr); - - tm = ut_clock(); - printf("Wall time for test %lu milliseconds\n", tm - oldtm); - printf("%lu rows joined\n", i); - } - - oldtm = ut_clock(); - -/* - printf("\n\n\nPress 2 x enter to continue test\n"); - - while (EOF == getchar()) { - - } - getchar(); -*/ - printf("-------------------------------------------------\n"); - printf("TEST 6. INSERT MANY ROWS TO THE TABLE IN SEPARATE TRXS\n"); - - rnd = 200000; - - for (i = 0; i < 350; i++) { - - if (i % 4 == 0) { - } - trx = trx_start(ULINT_UNDEFINED); - - table = dict_table_get("TS_TABLE1", trx); - - if (i == 2180) { - rnd = rnd % 200000; - } - - rnd = (rnd + 1) % 200000; - - dtuple_gen_test_tuple3(tuple, rnd, buf); - - tcur_insert(tuple, table, heap2, trx); - - trx_commit(trx); - - mem_heap_empty(heap2); - if (i % 4 == 3) { - } - } - - tm = ut_clock(); - printf("Wall time for test %lu milliseconds\n", tm - oldtm); - printf("%lu rows inserted in %lu transactions\n", i, i); -/* - printf("\n\n\nPress 2 x enter to continue test\n"); - - while (EOF == getchar()) { - - } - getchar(); -*/ - printf("-------------------------------------------------\n"); - printf("TEST 7. PRINT MEMORY ALLOCATION INFO\n"); - - mem_print_info(); -/* - printf("\n\n\nPress 2 x enter to continue test\n"); - - while (EOF == getchar()) { - - } - getchar(); -*/ - printf("-------------------------------------------------\n"); - printf("TEST 8. PRINT SEMAPHORE INFO\n"); - - sync_print(); - - - -#ifdef notdefined - rnd = 90000; - - oldtm = ut_clock(); - - for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { - - mtr_start(&mtr); - - if (i == 50000) { - rnd = rnd % 200000; - } - - rnd = (rnd + 595659561) % 200000; - - dtuple_gen_test_tuple3(tuple, rnd, buf); - - btr_pcur_open(tree, tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &cursor, &mtr); - - mtr_commit(&mtr); - } - - tm = ut_clock(); - printf("Wall time for test %lu milliseconds\n", tm - oldtm); - - rnd = 0; - - oldtm = ut_clock(); - - for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { - - mtr_start(&mtr); - - rnd = (rnd + 35608971) % 200000 + 1; - - dtuple_gen_test_tuple3(tuple, rnd, buf); - - mtr_commit(&mtr); - } - - tm = ut_clock(); - printf("Wall time for test %lu milliseconds\n", tm - oldtm); - -/* btr_print_tree(tree, 3); */ - -#endif - mem_heap_free(heap); -} - - -#ifdef notdefined - - mtr_start(&mtr); - - block = buf_page_create(0, 5, &mtr); - buf_page_x_lock(block, &mtr); - - frame = buf_block_get_frame(block); - - page = page_create(frame, &mtr); - - for (i = 0; i < 512; i++) { - - rnd = (rnd + 534671) % 512; - - if (i % 27 == 0) { - ut_a(page_validate(page, index)); - } - - dtuple_gen_test_tuple(tuple, rnd); - -/* dtuple_print(tuple);*/ - - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - - ut_a(rec); - - rec_validate(rec); -/* page_print_list(page, 151); */ - } - -/* page_print_list(page, 151); */ - - ut_a(page_validate(page, index)); - ut_a(page_get_n_recs(page) == 512); - - for (i = 0; i < 512; i++) { - - rnd = (rnd + 7771) % 512; - - if (i % 27 == 0) { - ut_a(page_validate(page, index)); - } - - dtuple_gen_test_tuple(tuple, rnd); - -/* dtuple_print(tuple);*/ - - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - page_cur_delete_rec(&cursor, &mtr); - - ut_a(rec); - - rec_validate(rec); -/* page_print_list(page, 151); */ - } - - ut_a(page_get_n_recs(page) == 0); - - ut_a(page_validate(page, index)); - page = page_create(frame, &mtr); - - rnd = 311; - - for (i = 0; i < 512; i++) { - - rnd = (rnd + 1) % 512; - - if (i % 27 == 0) { - ut_a(page_validate(page, index)); - } - - dtuple_gen_test_tuple(tuple, rnd); - -/* dtuple_print(tuple);*/ - - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - - ut_a(rec); - - rec_validate(rec); -/* page_print_list(page, 151); */ - } - - ut_a(page_validate(page, index)); - ut_a(page_get_n_recs(page) == 512); - - rnd = 217; - - for (i = 0; i < 512; i++) { - - rnd = (rnd + 1) % 512; - - if (i % 27 == 0) { - ut_a(page_validate(page, index)); - } - - dtuple_gen_test_tuple(tuple, rnd); - -/* dtuple_print(tuple);*/ - - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - page_cur_delete_rec(&cursor, &mtr); - - ut_a(rec); - - rec_validate(rec); -/* page_print_list(page, 151); */ - } - - ut_a(page_validate(page, index)); - ut_a(page_get_n_recs(page) == 0); - page = page_create(frame, &mtr); - - rnd = 291; - - for (i = 0; i < 512; i++) { - - rnd = (rnd - 1) % 512; - - if (i % 27 == 0) { - ut_a(page_validate(page, index)); - } - - dtuple_gen_test_tuple(tuple, rnd); - -/* dtuple_print(tuple);*/ - - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - - ut_a(rec); - - rec_validate(rec); -/* page_print_list(page, 151); */ - } - - ut_a(page_validate(page, index)); - ut_a(page_get_n_recs(page) == 512); - - rnd = 277; - - for (i = 0; i < 512; i++) { - - rnd = (rnd - 1) % 512; - - if (i % 27 == 0) { - ut_a(page_validate(page, index)); - } - - dtuple_gen_test_tuple(tuple, rnd); - -/* dtuple_print(tuple);*/ - - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - page_cur_delete_rec(&cursor, &mtr); - - ut_a(rec); - - rec_validate(rec); -/* page_print_list(page, 151); */ - } - - ut_a(page_validate(page, index)); - ut_a(page_get_n_recs(page) == 0); - - mtr_commit(&mtr); - mem_heap_free(heap); -} - -/********************************************************************* -Test for index page. */ - -void -test2(void) -/*=======*/ -{ - page_t* page; - dtuple_t* tuple; - mem_heap_t* heap; - ulint i, j; - ulint rnd = 0; - rec_t* rec; - page_cur_t cursor; - dict_index_t* index; - dict_table_t* table; - buf_block_t* block; - buf_frame_t* frame; - ulint tm, oldtm; - byte buf[8]; - mtr_t mtr; - - printf("-------------------------------------------------\n"); - printf("TEST 2. Speed test\n"); - - oldtm = ut_clock(); - - for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { - ut_memcpy(bigbuf, bigbuf + 800, 800); - } - - tm = ut_clock(); - printf("Wall time for %lu mem copys of 800 bytes %lu millisecs\n", - i, tm - oldtm); - - oldtm = ut_clock(); - - rnd = 0; - for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { - ut_memcpy(bigbuf + rnd, bigbuf + rnd + 800, 800); - rnd += 1600; - if (rnd > 995000) { - rnd = 0; - } - } - - tm = ut_clock(); - printf("Wall time for %lu mem copys of 800 bytes %lu millisecs\n", - i, tm - oldtm); - - heap = mem_heap_create(0); - - table = dict_table_create("TS_TABLE2", 2); - - dict_table_add_col(table, "COL1", DATA_VARCHAR, DATA_ENGLISH, 10, 0); - dict_table_add_col(table, "COL2", DATA_VARCHAR, DATA_ENGLISH, 10, 0); - - ut_a(0 == dict_table_publish(table)); - - index = dict_index_create("TS_TABLE2", "IND2", 0, 2, 0); - - dict_index_add_field(index, "COL1", 0); - dict_index_add_field(index, "COL2", 0); - - ut_a(0 == dict_index_publish(index)); - - index = dict_index_get("TS_TABLE2", "IND2"); - ut_a(index); - - tuple = dtuple_create(heap, 2); - - oldtm = ut_clock(); - - rnd = 677; - for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { - - mtr_start(&mtr); - - block = buf_page_create(0, 5, &mtr); - buf_page_x_lock(block, &mtr); - - frame = buf_block_get_frame(block); - - page = page_create(frame, &mtr); - - for (j = 0; j < 250; j++) { - rnd = (rnd + 54841) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - ut_a(rec); - } - mtr_commit(&mtr); - } - - tm = ut_clock(); - printf("Wall time for insertion of %lu recs %lu milliseconds\n", - i * j, tm - oldtm); - - mtr_start(&mtr); - - block = buf_page_get(0, 5, &mtr); - buf_page_s_lock(block, &mtr); - - page = buf_block_get_frame(block); - ut_a(page_validate(page, index)); - mtr_commit(&mtr); - - oldtm = ut_clock(); - - rnd = 677; - for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { - mtr_start(&mtr); - - block = buf_page_create(0, 5, &mtr); - buf_page_x_lock(block, &mtr); - - frame = buf_block_get_frame(block); - - page = page_create(frame, &mtr); - - for (j = 0; j < 250; j++) { - rnd = (rnd + 54841) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - } - mtr_commit(&mtr); - } - - tm = ut_clock(); - printf( - "Wall time for %lu empty loops with page create %lu milliseconds\n", - i * j, tm - oldtm); - - oldtm = ut_clock(); - - for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { - - mtr_start(&mtr); - - block = buf_page_create(0, 5, &mtr); - buf_page_x_lock(block, &mtr); - - frame = buf_block_get_frame(block); - - page = page_create(frame, &mtr); - - rnd = 100; - for (j = 0; j < 250; j++) { - rnd = (rnd + 1) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - ut_a(rec); - } - mtr_commit(&mtr); - } - - tm = ut_clock(); - printf( - "Wall time for sequential insertion of %lu recs %lu milliseconds\n", - i * j, tm - oldtm); - - - oldtm = ut_clock(); - - for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { - mtr_start(&mtr); - - block = buf_page_create(0, 5, &mtr); - buf_page_x_lock(block, &mtr); - - frame = buf_block_get_frame(block); - - page = page_create(frame, &mtr); - - rnd = 500; - for (j = 0; j < 250; j++) { - rnd = (rnd - 1) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - ut_a(rec); - } - mtr_commit(&mtr); - } - - tm = ut_clock(); - printf( - "Wall time for descend. seq. insertion of %lu recs %lu milliseconds\n", - i * j, tm - oldtm); - - oldtm = ut_clock(); - - for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { - mtr_start(&mtr); - - block = buf_page_create(0, 5, &mtr); - buf_page_x_lock(block, &mtr); - - frame = buf_block_get_frame(block); - - page = page_create(frame, &mtr); - - rnd = 677; - - for (j = 0; j < 250; j++) { - rnd = (rnd + 54841) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - ut_a(rec); - } - - rnd = 677; - for (j = 0; j < 250; j++) { - rnd = (rnd + 54841) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - page_cur_delete_rec(&cursor, &mtr); - } - ut_a(page_get_n_recs(page) == 0); - - mtr_commit(&mtr); - } - - tm = ut_clock(); - printf("Wall time for insert and delete of %lu recs %lu milliseconds\n", - i * j, tm - oldtm); - - mtr_start(&mtr); - - block = buf_page_create(0, 5, &mtr); - buf_page_x_lock(block, &mtr); - - frame = buf_block_get_frame(block); - - page = page_create(frame, &mtr); - - rnd = 677; - - for (j = 0; j < 250; j++) { - rnd = (rnd + 54841) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - - rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); - ut_a(rec); - } - ut_a(page_validate(page, index)); - mtr_print(&mtr); - - oldtm = ut_clock(); - - for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { - rnd = 677; - for (j = 0; j < 250; j++) { - rnd = (rnd + 54841) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - page_cur_search(page, tuple, PAGE_CUR_G, &cursor); - } - } - - tm = ut_clock(); - printf("Wall time for search of %lu recs %lu milliseconds\n", - i * j, tm - oldtm); - - oldtm = ut_clock(); - - for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { - rnd = 677; - for (j = 0; j < 250; j++) { - rnd = (rnd + 54841) % 1000; - dtuple_gen_test_tuple2(tuple, rnd, buf); - } - } - - tm = ut_clock(); - printf("Wall time for %lu empty loops %lu milliseconds\n", - i * j, tm - oldtm); - mtr_commit(&mtr); -} - -#endif - -/******************************************************************** -Main test function. */ - -void -main(void) -/*======*/ -{ - ulint tm, oldtm; - mtr_t mtr; - - sync_init(); - mem_init(); - os_aio_init(160, 5); - fil_init(25); - buf_pool_init(POOL_SIZE, POOL_SIZE); - fsp_init(); - log_init(); - - create_files(); - init_space(); - - mtr_start(&mtr); - - trx_sys_create(&mtr); - dict_create(&mtr); - - mtr_commit(&mtr); - - - oldtm = ut_clock(); - - ut_rnd_set_seed(19); - - test1(); - -/* mem_print_info(); */ - - tm = ut_clock(); - printf("Wall time for test %lu milliseconds\n", tm - oldtm); - printf("TESTS COMPLETED SUCCESSFULLY!\n"); -} |