diff options
Diffstat (limited to 'storage')
149 files changed, 5245 insertions, 21711 deletions
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 2df54567285..19a0ffe028a 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -785,7 +785,9 @@ int ha_archive::create(const char *name, TABLE *table_arg, { Field *field= key_part->field; - if (!(field->flags & AUTO_INCREMENT_FLAG)) + if (!(field->flags & AUTO_INCREMENT_FLAG) || + key_part->key_part_flag & HA_REVERSE_SORT) + { error= HA_WRONG_CREATE_OPTION; DBUG_PRINT("ha_archive", ("Index error in creating archive table")); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 6d180ac5441..5b6af042f68 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1809,6 +1809,12 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) pn= (char*)kp.key_part[k].field->field_name.str; name= PlugDup(g, pn); + if (kp.key_part[k].key_part_flag & HA_REVERSE_SORT) + { + strcpy(g->Message, "Descending indexes are not supported"); + xdp->Invalid= true; + } + // Allocate the key part description block kpp= new(g) KPARTDEF(name, k + 1); kpp->SetKlen(kp.key_part[k].length); @@ -6951,6 +6957,9 @@ int ha_connect::create(const char *name, TABLE *table_arg, strcpy(g->Message, "Compressed tables are not indexable"); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); rc= HA_ERR_UNSUPPORTED; + } else if (xdp->Invalid) { + my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); + rc= HA_ERR_UNSUPPORTED; } else if (GetIndexType(type) == 1) { PDBUSER dup= PlgGetUser(g); PCATLG cat= (dup) ? dup->Catalog : NULL; diff --git a/storage/connect/mysql-test/connect/r/index.result b/storage/connect/mysql-test/connect/r/index.result index bffaaecc785..c156e10749e 100644 --- a/storage/connect/mysql-test/connect/r/index.result +++ b/storage/connect/mysql-test/connect/r/index.result @@ -139,3 +139,12 @@ DELETE FROM t1; DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; +# +# MDEV-27591 Connect tables (FIX/DOS) don't work with DESC keys - wrong results +# +CREATE TABLE t1 ( +id INT, +f VARCHAR(32), +PRIMARY KEY (id DESC) +) ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='emp.txt'; +ERROR HY000: Descending indexes are not supported diff --git a/storage/connect/mysql-test/connect/t/index.test b/storage/connect/mysql-test/connect/t/index.test index 5e913582734..b631236832d 100644 --- a/storage/connect/mysql-test/connect/t/index.test +++ b/storage/connect/mysql-test/connect/t/index.test @@ -78,6 +78,16 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; +--echo # +--echo # MDEV-27591 Connect tables (FIX/DOS) don't work with DESC keys - wrong results +--echo # +--error ER_UNKNOWN_ERROR +CREATE TABLE t1 ( + id INT, + f VARCHAR(32), + PRIMARY KEY (id DESC) +) ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='emp.txt'; + # # Clean up # diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 50d63e53b26..6199504e04f 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1219,7 +1219,6 @@ bool ha_federatedx::create_where_from_key(String *to, KEY *key_info, const key_range *start_key, const key_range *end_key, - bool from_records_in_range, bool eq_range) { bool both_not_null= @@ -1240,7 +1239,6 @@ bool ha_federatedx::create_where_from_key(String *to, MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); for (uint i= 0; i <= 1; i++) { - bool needs_quotes; KEY_PART_INFO *key_part; if (ranges[i] == NULL) continue; @@ -1263,7 +1261,12 @@ bool ha_federatedx::create_where_from_key(String *to, Field *field= key_part->field; uint store_length= key_part->store_length; uint part_length= MY_MIN(store_length, length); - needs_quotes= field->str_needs_quotes(); + bool needs_quotes= field->str_needs_quotes(); + bool reverse= key_part->key_part_flag & HA_REVERSE_SORT; + static const LEX_CSTRING lt={STRING_WITH_LEN(" < ") }; + static const LEX_CSTRING gt={STRING_WITH_LEN(" > ") }; + static const LEX_CSTRING le={STRING_WITH_LEN(" <= ") }; + static const LEX_CSTRING ge={STRING_WITH_LEN(" >= ") }; DBUG_DUMP("key, start of loop", ptr, length); if (key_part->null_bit) @@ -1305,16 +1308,8 @@ bool ha_federatedx::create_where_from_key(String *to, if (emit_key_part_name(&tmp, key_part)) goto err; - if (from_records_in_range) - { - if (tmp.append(STRING_WITH_LEN(" >= "))) - goto err; - } - else - { - if (tmp.append(STRING_WITH_LEN(" = "))) - goto err; - } + if (tmp.append(STRING_WITH_LEN(" = "))) + goto err; if (emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr, part_length)) @@ -1345,12 +1340,12 @@ bool ha_federatedx::create_where_from_key(String *to, if (i > 0) /* end key */ { - if (tmp.append(STRING_WITH_LEN(" <= "))) + if (tmp.append(reverse ? ge : le)) goto err; } else /* start key */ { - if (tmp.append(STRING_WITH_LEN(" > "))) + if (tmp.append(reverse ? lt : gt)) goto err; } @@ -1365,7 +1360,7 @@ bool ha_federatedx::create_where_from_key(String *to, case HA_READ_KEY_OR_NEXT: DBUG_PRINT("info", ("federatedx HA_READ_KEY_OR_NEXT %d", i)); if (emit_key_part_name(&tmp, key_part) || - tmp.append(STRING_WITH_LEN(" >= ")) || + tmp.append(reverse ? le : ge) || emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr, part_length)) goto err; @@ -1375,7 +1370,7 @@ bool ha_federatedx::create_where_from_key(String *to, if (store_length >= length) { if (emit_key_part_name(&tmp, key_part) || - tmp.append(STRING_WITH_LEN(" < ")) || + tmp.append(reverse ? gt : lt) || emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr, part_length)) goto err; @@ -1385,7 +1380,7 @@ bool ha_federatedx::create_where_from_key(String *to, case HA_READ_KEY_OR_PREV: DBUG_PRINT("info", ("federatedx HA_READ_KEY_OR_PREV %d", i)); if (emit_key_part_name(&tmp, key_part) || - tmp.append(STRING_WITH_LEN(" <= ")) || + tmp.append(reverse ? ge : le) || emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr, part_length)) goto err; @@ -2640,10 +2635,7 @@ int ha_federatedx::index_read_idx_with_result_set(uchar *buf, uint index, range.key= key; range.length= key_len; range.flag= find_flag; - create_where_from_key(&index_string, - &table->key_info[index], - &range, - NULL, 0, 0); + create_where_from_key(&index_string, &table->key_info[index], &range, 0, 0); sql_query.append(index_string); if ((retval= txn->acquire(share, ha_thd(), TRUE, &io))) @@ -2722,9 +2714,8 @@ int ha_federatedx::read_range_first(const key_range *start_key, sql_query.length(0); sql_query.append(share->select_query); - create_where_from_key(&sql_query, - &table->key_info[active_index], - start_key, end_key, 0, eq_range_arg); + create_where_from_key(&sql_query, &table->key_info[active_index], + start_key, end_key, eq_range_arg); if ((retval= txn->acquire(share, ha_thd(), TRUE, &io))) DBUG_RETURN(retval); diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 2bbb116d646..3eb7a9c662c 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -291,8 +291,7 @@ private: FEDERATEDX_IO_RESULT *result); bool create_where_from_key(String *to, KEY *key_info, const key_range *start_key, - const key_range *end_key, - bool records_in_range, bool eq_range); + const key_range *end_key, bool eq_range); int stash_remote_error(); static federatedx_txn *get_txn(THD *thd, bool no_create= FALSE); diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index d06273ec9b7..7e938010860 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -281,7 +281,6 @@ SET(INNOBASE_SOURCES include/lock0types.h include/log0crypt.h include/log0log.h - include/log0log.inl include/log0recv.h include/log0types.h include/mach0data.h @@ -311,7 +310,6 @@ SET(INNOBASE_SOURCES include/que0types.h include/read0types.h include/rem0cmp.h - include/rem0cmp.inl include/rem0rec.h include/rem0rec.inl include/rem0types.h @@ -440,7 +438,9 @@ OPTION(WITH_PMEM "Support redo log in persistent memory" OFF) FIND_PACKAGE(PMEM) IF(PMEM_FOUND) INCLUDE_DIRECTORIES(${PMEM_INCLUDES}) - ADD_COMPILE_FLAGS(log/log0log.cc COMPILE_FLAGS "-DHAVE_PMEM") + ADD_COMPILE_FLAGS(log/log0log.cc log/log0recv.cc + buf/buf0flu.cc mtr/mtr0mtr.cc trx/trx0trx.cc srv/srv0start.cc + COMPILE_FLAGS "-DHAVE_PMEM") SET(PMEM_LIBRARY ${PMEM_LIBRARIES}) ELSE() IF(WITH_PMEM) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 53f4605ea8c..8f9984acb98 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2296,7 +2296,8 @@ btr_page_insert_fits( if (!(end_rec = split_rec)) { end_rec = page_rec_get_next(btr_cur_get_rec(cursor)); - } else if (cmp_dtuple_rec(tuple, split_rec, *offsets) < 0) { + } else if (cmp_dtuple_rec(tuple, split_rec, cursor->index, + *offsets) < 0) { rec = split_rec; end_rec = page_get_supremum_rec(page); goto got_rec; @@ -2587,7 +2588,7 @@ btr_page_tuple_smaller( ? cursor->index->n_core_fields : 0, n_uniq, heap); - return(cmp_dtuple_rec(tuple, first_rec, *offsets) < 0); + return cmp_dtuple_rec(tuple, first_rec, cursor->index, *offsets) < 0; } /** Insert the tuple into the right sibling page, if the cursor is at the end @@ -2977,7 +2978,8 @@ got_split_rec: ? cursor->index->n_core_fields : 0, n_uniq, heap); - insert_left = cmp_dtuple_rec(tuple, split_rec, *offsets) < 0; + insert_left = cmp_dtuple_rec(tuple, split_rec, cursor->index, + *offsets) < 0; if (!insert_left && new_page_zip && n_iterations > 0) { /* If a compressed page has already been split, @@ -4480,7 +4482,8 @@ btr_check_node_ptr( tuple, btr_cur_get_rec(&cursor), PAGE_CUR_WITHIN)); } else { - ut_a(!cmp_dtuple_rec(tuple, btr_cur_get_rec(&cursor), offsets)); + ut_a(!cmp_dtuple_rec(tuple, btr_cur_get_rec(&cursor), index, + offsets)); } func_exit: mem_heap_free(heap); @@ -4997,7 +5000,7 @@ broken_links: /* For spatial index, we cannot guarantee the key ordering across pages, so skip the record compare verification for now. Will enhanced in special R-Tree index validation scheme */ - if (!index->is_spatial() + if (index->is_btree() && cmp_rec_rec(rec, right_rec, offsets, offsets2, index) >= 0) { @@ -5043,8 +5046,7 @@ broken_links: in parent level and linked pages in the child level. 2) Search parent from root is very costly for R-tree. We will add special validation mechanism for R-tree later (WL #7520) */ - if (!index->is_spatial() - && block->page.id().page_no() != index->page) { + if (index->is_btree() && block->page.id().page_no() != index->page) { /* Check father node pointers */ rec_t* node_ptr = page_rec_get_next(page_get_infimum_rec(page)); @@ -5109,7 +5111,7 @@ broken_links: index, first_rec, 0, heap, btr_page_get_level(page)); - if (cmp_dtuple_rec(node_ptr_tuple, node_ptr, + if (cmp_dtuple_rec(node_ptr_tuple, node_ptr, index, offsets)) { btr_validate_report1(index, level, block); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index e374ffc0424..5d796cb9348 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1387,7 +1387,7 @@ dberr_t btr_cur_search_to_nth_level(dict_index_t *index, ulint level, # endif /* PAGE_CUR_LE_OR_EXTENDS */ && info->last_hash_succ && !(tuple->info_bits & REC_INFO_MIN_REC_FLAG) - && !index->is_spatial() && !index->table->is_temporary() + && index->is_btree() && !index->table->is_temporary() && btr_search_guess_on_hash(index, info, tuple, mode, latch_mode, cursor, mtr)) { @@ -1598,7 +1598,6 @@ retry_page_get: case BTR_INSERT_OP: case BTR_INSERT_IGNORE_UNIQUE_OP: ut_ad(buf_mode == BUF_GET_IF_IN_POOL); - ut_ad(!dict_index_is_spatial(index)); if (ibuf_insert(IBUF_OP_INSERT, tuple, index, page_id, zip_size, cursor->thr)) { @@ -1611,7 +1610,6 @@ retry_page_get: case BTR_DELMARK_OP: ut_ad(buf_mode == BUF_GET_IF_IN_POOL); - ut_ad(!dict_index_is_spatial(index)); if (ibuf_insert(IBUF_OP_DELETE_MARK, tuple, index, page_id, zip_size, @@ -1626,7 +1624,7 @@ retry_page_get: case BTR_DELETE_OP: ut_ad(buf_mode == BUF_GET_IF_IN_POOL_OR_WATCH); - ut_ad(!dict_index_is_spatial(index)); + ut_ad(index->is_btree()); auto& chain = buf_pool.page_hash.cell_get( page_id.fold()); diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index 0e6aaa0d6b2..e49ef672928 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -438,7 +438,7 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr) if (rel_pos == BTR_PCUR_ON && btr_pcur_is_on_user_rec(this)) { ulint n_matched_fields= 0; if (!cmp_dtuple_rec_with_match( - tuple, btr_pcur_get_rec(this), + tuple, btr_pcur_get_rec(this), index, rec_get_offsets(btr_pcur_get_rec(this), index, offsets, index->n_core_fields, ULINT_UNDEFINED, &heap), &n_matched_fields)) { diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 29345cf0104..09f2dac3ccf 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -808,7 +808,8 @@ btr_search_check_guess( offsets = rec_get_offsets(rec, cursor->index, offsets, cursor->index->n_core_fields, n_unique, &heap); - cmp = cmp_dtuple_rec_with_match(tuple, rec, offsets, &match); + cmp = cmp_dtuple_rec_with_match(tuple, rec, cursor->index, offsets, + &match); if (mode == PAGE_CUR_GE) { if (cmp > 0) { @@ -874,7 +875,7 @@ btr_search_check_guess( cursor->index->n_core_fields, n_unique, &heap); cmp = cmp_dtuple_rec_with_match( - tuple, prev_rec, offsets, &match); + tuple, prev_rec, cursor->index, offsets, &match); if (mode == PAGE_CUR_GE) { success = cmp > 0; } else { @@ -914,7 +915,7 @@ btr_search_check_guess( cursor->index->n_core_fields, n_unique, &heap); cmp = cmp_dtuple_rec_with_match( - tuple, next_rec, offsets, &match); + tuple, next_rec, cursor->index, offsets, &match); if (mode == PAGE_CUR_LE) { success = cmp < 0; cursor->up_match = match; diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 1d98ce058ed..7125263f934 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -36,10 +36,11 @@ Created 11/5/1995 Heikki Tuuri #include "mach0data.h" #include "buf0buf.h" #include "buf0checksum.h" -#include "ut0crc32.h" #include <string.h> -#ifndef UNIV_INNOCHECKSUM +#ifdef UNIV_INNOCHECKSUM +#include "my_sys.h" +#else #include "my_cpu.h" #include "mem0mem.h" #include "btr0btr.h" @@ -374,8 +375,8 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) src_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM, FIL_PAGE_FCRC32_CHECKSUM); - memcpy_aligned<OS_FILE_LOG_BLOCK_SIZE>(src_frame, tmp_frame, - srv_page_size); + memcpy_aligned<UNIV_PAGE_SIZE_MIN>(src_frame, tmp_frame, + srv_page_size); srv_stats.pages_decrypted.inc(); srv_stats.n_temp_blocks_decrypted.inc(); @@ -593,8 +594,8 @@ bool buf_page_is_corrupted(bool check_lsn, const byte *read_buf, } }); - if (crc32 != ut_crc32(read_buf, - size - FIL_PAGE_FCRC32_CHECKSUM)) { + if (crc32 != my_crc32c(0, read_buf, + size - FIL_PAGE_FCRC32_CHECKSUM)) { return true; } static_assert(FIL_PAGE_FCRC32_KEY_VERSION == 0, "alignment"); @@ -765,18 +766,10 @@ buf_madvise_do_dump() /* mirrors allocation in log_t::create() */ if (log_sys.buf) { - ret += madvise(log_sys.buf, - srv_log_buffer_size, - MADV_DODUMP); - ret += madvise(log_sys.flush_buf, - srv_log_buffer_size, + ret += madvise(log_sys.buf, log_sys.buf_size, MADV_DODUMP); + ret += madvise(log_sys.flush_buf, log_sys.buf_size, MADV_DODUMP); } - /* mirrors recv_sys_t::create() */ - if (recv_sys.buf) - { - ret+= madvise(recv_sys.buf, recv_sys.len, MADV_DODUMP); - } mysql_mutex_lock(&buf_pool.mutex); auto chunk = buf_pool.chunks; @@ -961,7 +954,7 @@ inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const { /* The page cleaner is disabled in read-only mode. No pages can be dirtied, so all of them must be clean. */ - ut_ad(lsn == 0 || lsn == recv_sys.recovered_lsn || + ut_ad(lsn == 0 || lsn == recv_sys.lsn || srv_force_recovery == SRV_FORCE_NO_LOG_REDO); break; } @@ -1059,7 +1052,11 @@ bool buf_pool_t::create() while (++chunk < chunks + n_chunks); ut_ad(is_initialised()); +#if defined(__aarch64__) mysql_mutex_init(buf_pool_mutex_key, &mutex, MY_MUTEX_INIT_FAST); +#else + mysql_mutex_init(buf_pool_mutex_key, &mutex, nullptr); +#endif UT_LIST_INIT(LRU, &buf_page_t::LRU); UT_LIST_INIT(withdraw, &buf_page_t::list); @@ -1201,7 +1198,7 @@ inline bool buf_pool_t::realloc(buf_block_t *block) hash_lock.lock(); if (block->page.can_relocate()) { - memcpy_aligned<OS_FILE_LOG_BLOCK_SIZE>( + memcpy_aligned<UNIV_PAGE_SIZE_MIN>( new_block->page.frame, block->page.frame, srv_page_size); mysql_mutex_lock(&buf_pool.flush_list_mutex); @@ -1322,8 +1319,8 @@ inline bool buf_pool_t::withdraw_blocks() buf_block_t* block; ulint loop_count = 0; - ib::info() << "start to withdraw the last " - << withdraw_target << " blocks"; + ib::info() << "Start to withdraw the last " + << withdraw_target << " blocks."; while (UT_LIST_GET_LEN(withdraw) < withdraw_target) { @@ -1406,15 +1403,15 @@ realloc_frame: mysql_mutex_unlock(&mutex); buf_resize_status( - "withdrawing blocks. (" ULINTPF "/" ULINTPF ")", + "Withdrawing blocks. (" ULINTPF "/" ULINTPF ").", UT_LIST_GET_LEN(withdraw), withdraw_target); - ib::info() << "withdrew " + ib::info() << "Withdrew " << count1 << " blocks from free list." - << " Tried to relocate " << count2 << " pages (" + << " Tried to relocate " << count2 << " blocks (" << UT_LIST_GET_LEN(withdraw) << "/" - << withdraw_target << ")"; + << withdraw_target << ")."; if (++loop_count >= 10) { /* give up for now. @@ -1437,8 +1434,8 @@ realloc_frame: } } - ib::info() << "withdrawn target: " << UT_LIST_GET_LEN(withdraw) - << " blocks"; + ib::info() << "Withdrawn target: " << UT_LIST_GET_LEN(withdraw) + << " blocks."; return(false); } @@ -1516,11 +1513,15 @@ inline void buf_pool_t::resize() ut_ad(srv_buf_pool_chunk_unit > 0); ulint new_instance_size = srv_buf_pool_size >> srv_page_size_shift; + std::ostringstream str_old_size, str_new_size, str_chunk_size; + str_old_size << ib::bytes_iec{srv_buf_pool_old_size}; + str_new_size << ib::bytes_iec{srv_buf_pool_size}; + str_chunk_size << ib::bytes_iec{srv_buf_pool_chunk_unit}; - buf_resize_status("Resizing buffer pool from " ULINTPF " to " - ULINTPF " (unit=" ULINTPF ").", - srv_buf_pool_old_size, srv_buf_pool_size, - srv_buf_pool_chunk_unit); + buf_resize_status("Resizing buffer pool from %s to %s (unit = %s).", + str_old_size.str().c_str(), + str_new_size.str().c_str(), + str_chunk_size.str().c_str()); #ifdef BTR_CUR_HASH_ADAPT /* disable AHI if needed */ @@ -1615,7 +1616,7 @@ withdraw_retry: goto withdraw_retry; } - buf_resize_status("Latching whole of buffer pool."); + buf_resize_status("Latching entire buffer pool."); #ifndef DBUG_OFF { @@ -1639,15 +1640,15 @@ withdraw_retry: /* Indicate critical path */ resizing.store(true, std::memory_order_relaxed); - mysql_mutex_lock(&mutex); - page_hash.write_lock_all(); + mysql_mutex_lock(&mutex); + page_hash.write_lock_all(); chunk_t::map_reg = UT_NEW_NOKEY(chunk_t::map()); /* add/delete chunks */ - buf_resize_status("buffer pool resizing with chunks " - ULINTPF " to " ULINTPF ".", + buf_resize_status("Resizing buffer pool from " + ULINTPF " chunks to " ULINTPF " chunks.", n_chunks, n_chunks_new); if (is_shrinking()) { @@ -1688,7 +1689,7 @@ withdraw_retry: withdraw_target = 0; ib::info() << n_chunks - n_chunks_new - << " chunks (" << sum_freed + << " Chunks (" << sum_freed << " blocks) were freed."; n_chunks = n_chunks_new; @@ -1805,18 +1806,18 @@ calc_buf_pool_size: if (!warning && new_size_too_diff) { srv_buf_pool_base_size = srv_buf_pool_size; - buf_resize_status("Resizing also other hash tables."); + buf_resize_status("Resizing other hash tables."); srv_lock_table_size = 5 * (srv_buf_pool_size >> srv_page_size_shift); lock_sys.resize(srv_lock_table_size); dict_sys.resize(); - ib::info() << "Resized hash tables at lock_sys," + ib::info() << "Resized hash tables: lock_sys," #ifdef BTR_CUR_HASH_ADAPT " adaptive hash index," #endif /* BTR_CUR_HASH_ADAPT */ - " dictionary."; + " and dictionary."; } /* normalize ibuf.max_size */ @@ -1824,9 +1825,8 @@ calc_buf_pool_size: if (srv_buf_pool_old_size != srv_buf_pool_size) { - ib::info() << "Completed to resize buffer pool from " - << srv_buf_pool_old_size - << " to " << srv_buf_pool_size << "."; + buf_resize_status("Completed resizing buffer pool from %zu to %zu bytes." + ,srv_buf_pool_old_size, srv_buf_pool_size); srv_buf_pool_old_size = srv_buf_pool_size; } @@ -1838,16 +1838,8 @@ calc_buf_pool_size: } #endif /* BTR_CUR_HASH_ADAPT */ - char now[32]; - - ut_sprintf_timestamp(now); - if (!warning) { - buf_resize_status("Completed resizing buffer pool at %s.", - now); - } else { - buf_resize_status("Resizing buffer pool failed," - " finished resizing at %s.", now); - } + if (warning) + buf_resize_status("Resizing buffer pool failed"); ut_d(validate()); diff --git a/storage/innobase/buf/buf0checksum.cc b/storage/innobase/buf/buf0checksum.cc index c9818fa600f..662343ae60d 100644 --- a/storage/innobase/buf/buf0checksum.cc +++ b/storage/innobase/buf/buf0checksum.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,7 +26,6 @@ Created Aug 11, 2011 Vasil Dimov #include "buf0checksum.h" #include "fil0fil.h" -#include "ut0crc32.h" #include "ut0rnd.h" #ifndef UNIV_INNOCHECKSUM @@ -46,12 +45,12 @@ uint32_t buf_calc_page_crc32(const byte* page) should be combined with the CRC-32 function, not with exclusive OR. We stick to the current algorithm in order to remain compatible with old data files. */ - return ut_crc32(page + FIL_PAGE_OFFSET, - FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION - - FIL_PAGE_OFFSET) - ^ ut_crc32(page + FIL_PAGE_DATA, - srv_page_size - - (FIL_PAGE_DATA + FIL_PAGE_END_LSN_OLD_CHKSUM)); + return my_crc32c(0, page + FIL_PAGE_OFFSET, + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + - FIL_PAGE_OFFSET) + ^ my_crc32c(0, page + FIL_PAGE_DATA, + srv_page_size + - (FIL_PAGE_DATA + FIL_PAGE_END_LSN_OLD_CHKSUM)); } #ifndef UNIV_INNOCHECKSUM diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 3c59955dbd8..00ded2a93aa 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -229,8 +229,6 @@ fail: /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); - - ib::info() << "Doublewrite buffer created"; goto start_again; } @@ -342,7 +340,7 @@ func_exit: /** Process and remove the double write buffer pages for all tablespaces. */ void buf_dblwr_t::recover() { - ut_ad(recv_sys.parse_start_lsn); + ut_ad(log_sys.last_checkpoint_lsn); if (!is_initialised()) return; @@ -360,13 +358,13 @@ void buf_dblwr_t::recover() continue; const lsn_t lsn= mach_read_from_8(page + FIL_PAGE_LSN); - if (recv_sys.parse_start_lsn > lsn) + if (log_sys.last_checkpoint_lsn > lsn) /* Pages written before the checkpoint are not useful for recovery. */ continue; const uint32_t space_id= page_get_space_id(page); const page_id_t page_id(space_id, page_no); - if (recv_sys.scanned_lsn < lsn) + if (recv_sys.lsn < lsn) { ib::info() << "Ignoring a doublewrite copy of page " << page_id << " with future log sequence number " << lsn; diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index 5027034e23a..afc227169f3 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -314,11 +314,13 @@ buf_dump( n_pages * sizeof(*dump))); if (dump == NULL) { + std::ostringstream str_bytes; mysql_mutex_unlock(&buf_pool.mutex); fclose(f); + str_bytes << ib::bytes_iec{n_pages * sizeof(*dump)}; buf_dump_status(STATUS_ERR, - "Cannot allocate " ULINTPF " bytes: %s", - (ulint) (n_pages * sizeof(*dump)), + "Cannot allocate %s: %s", + str_bytes.str().c_str(), strerror(errno)); /* leave tmp_filename to exist */ return; @@ -560,11 +562,14 @@ buf_load() } if (dump == NULL) { + std::ostringstream str_bytes; fclose(f); - buf_load_status(STATUS_ERR, - "Cannot allocate " ULINTPF " bytes: %s", - dump_n * sizeof(*dump), + str_bytes << ib::bytes_iec{dump_n * sizeof(*dump)}; + buf_dump_status(STATUS_ERR, + "Cannot allocate %s: %s", + str_bytes.str().c_str(), strerror(errno)); + /* leave tmp_filename to exist */ return; } diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index c51db802a24..31e523fa3ff 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -115,6 +115,7 @@ static void buf_flush_validate_skip() /** Wake up the page cleaner if needed */ void buf_pool_t::page_cleaner_wakeup() { + ut_d(buf_flush_validate_skip()); if (!page_cleaner_idle()) return; double dirty_pct= double(UT_LIST_GET_LEN(buf_pool.flush_list)) * 100.0 / @@ -155,7 +156,7 @@ void buf_pool_t::page_cleaner_wakeup() } } -inline void buf_pool_t::delete_from_flush_list_low(buf_page_t *bpage) +inline void buf_pool_t::delete_from_flush_list_low(buf_page_t *bpage) noexcept { ut_ad(!fsp_is_system_temporary(bpage->id().space())); mysql_mutex_assert_owner(&flush_list_mutex); @@ -163,40 +164,10 @@ inline void buf_pool_t::delete_from_flush_list_low(buf_page_t *bpage) UT_LIST_REMOVE(flush_list, bpage); } -/** Insert a modified block into the flush list. -@param block modified block -@param lsn start LSN of the mini-transaction that modified the block */ -void buf_pool_t::insert_into_flush_list(buf_block_t *block, lsn_t lsn) -{ - mysql_mutex_assert_not_owner(&mutex); - mysql_mutex_assert_owner(&log_sys.flush_order_mutex); - ut_ad(lsn > 2); - ut_ad(!fsp_is_system_temporary(block->page.id().space())); - - mysql_mutex_lock(&flush_list_mutex); - if (ut_d(const lsn_t old=) block->page.oldest_modification()) - { - ut_ad(old == 1); - delete_from_flush_list_low(&block->page); - } - else - stat.flush_list_bytes+= block->physical_size(); - ut_ad(stat.flush_list_bytes <= curr_pool_size); - - block->page.set_oldest_modification(lsn); - MEM_CHECK_DEFINED(block->page.zip.data - ? block->page.zip.data : block->page.frame, - block->physical_size()); - UT_LIST_ADD_FIRST(flush_list, &block->page); - ut_d(buf_flush_validate_skip()); - page_cleaner_wakeup(); - mysql_mutex_unlock(&flush_list_mutex); -} - /** Remove a block from flush_list. @param bpage buffer pool page @param clear whether to invoke buf_page_t::clear_oldest_modification() */ -void buf_pool_t::delete_from_flush_list(buf_page_t *bpage, bool clear) +void buf_pool_t::delete_from_flush_list(buf_page_t *bpage, bool clear) noexcept { delete_from_flush_list_low(bpage); stat.flush_list_bytes-= bpage->physical_size(); @@ -418,7 +389,7 @@ void buf_flush_assign_full_crc32_checksum(byte* page) ut_ad(!corrupted); ut_ad(size == uint(srv_page_size)); const ulint payload = srv_page_size - FIL_PAGE_FCRC32_CHECKSUM; - mach_write_to_4(page + payload, ut_crc32(page, payload)); + mach_write_to_4(page + payload, my_crc32c(0, page, payload)); } /** Initialize a page for writing to the tablespace. @@ -599,7 +570,7 @@ static byte* buf_tmp_page_encrypt(ulint offset, const byte* s, byte* d) return NULL; const ulint payload= srv_page_size - FIL_PAGE_FCRC32_CHECKSUM; - mach_write_to_4(d + payload, ut_crc32(d, payload)); + mach_write_to_4(d + payload, my_crc32c(0, d, payload)); srv_stats.pages_encrypted.inc(); srv_stats.n_temp_blocks_encrypted.inc(); @@ -724,7 +695,7 @@ not_compressed: if (full_crc32) { static_assert(FIL_PAGE_FCRC32_CHECKSUM == 4, "alignment"); - mach_write_to_4(tmp + len - 4, ut_crc32(tmp, len - 4)); + mach_write_to_4(tmp + len - 4, my_crc32c(0, tmp, len - 4)); ut_ad(!buf_page_is_corrupted(true, tmp, space->flags)); } @@ -736,7 +707,7 @@ not_compressed: } /** Free a page whose underlying file page has been freed. */ -inline void buf_pool_t::release_freed_page(buf_page_t *bpage) +inline void buf_pool_t::release_freed_page(buf_page_t *bpage) noexcept { mysql_mutex_assert_owner(&mutex); mysql_mutex_lock(&flush_list_mutex); @@ -890,8 +861,7 @@ inline bool buf_page_t::flush(bool lru, fil_space_t *space) (write_frame ? write_frame : frame))); ut_ad(lsn >= oldest_modification()); - if (lsn > log_sys.get_flushed_lsn()) - log_write_up_to(lsn, true); + log_write_up_to(lsn, true); } space->io(IORequest{type, this, slot}, physical_offset(), size, write_frame, this); @@ -1691,6 +1661,61 @@ ulint buf_flush_LRU(ulint max_n) return n_flushed; } +#ifdef HAVE_PMEM +# include <libpmem.h> +#endif + +/** Write checkpoint information to the log header and release mutex. +@param end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */ +inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept +{ + ut_ad(!srv_read_only_mode); + ut_ad(end_lsn >= next_checkpoint_lsn); + ut_ad(end_lsn <= get_lsn()); + ut_ad(end_lsn + SIZE_OF_FILE_CHECKPOINT <= get_lsn() || + srv_shutdown_state > SRV_SHUTDOWN_INITIATED); + + DBUG_PRINT("ib_log", + ("checkpoint at " LSN_PF " written", next_checkpoint_lsn)); + + auto n= next_checkpoint_no; + const size_t offset{(n & 1) ? CHECKPOINT_2 : CHECKPOINT_1}; + static_assert(CPU_LEVEL1_DCACHE_LINESIZE >= 64, "efficiency"); + static_assert(CPU_LEVEL1_DCACHE_LINESIZE <= 4096, "compatibility"); + byte* c= my_assume_aligned<CPU_LEVEL1_DCACHE_LINESIZE> + (is_pmem() ? buf + offset : checkpoint_buf); + memset_aligned<CPU_LEVEL1_DCACHE_LINESIZE>(c, 0, CPU_LEVEL1_DCACHE_LINESIZE); + mach_write_to_8(my_assume_aligned<8>(c), next_checkpoint_lsn); + mach_write_to_8(my_assume_aligned<8>(c + 8), end_lsn); + mach_write_to_4(my_assume_aligned<4>(c + 60), my_crc32c(0, c, 60)); +#ifdef HAVE_PMEM + if (is_pmem()) + pmem_persist(c, 64); + else +#endif + { + ut_ad(!checkpoint_pending); + checkpoint_pending= true; + latch.wr_unlock(); + /* FIXME: issue an asynchronous write */ + log.write(offset, {c, get_block_size()}); + if (srv_file_flush_method != SRV_O_DSYNC) + ut_a(log.flush()); + latch.wr_lock(SRW_LOCK_CALL); + ut_ad(checkpoint_pending); + checkpoint_pending= false; + } + + ut_ad(!checkpoint_pending); + next_checkpoint_no++; + last_checkpoint_lsn= next_checkpoint_lsn; + + DBUG_PRINT("ib_log", ("checkpoint ended at " LSN_PF ", flushed to " LSN_PF, + next_checkpoint_lsn, get_flushed_lsn())); + + latch.wr_unlock(); +} + /** Initiate a log checkpoint, discarding the start of the log. @param oldest_lsn the checkpoint LSN @param end_lsn log_sys.get_lsn() @@ -1698,34 +1723,26 @@ ulint buf_flush_LRU(ulint max_n) static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn) { ut_ad(!srv_read_only_mode); - mysql_mutex_assert_owner(&log_sys.mutex); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif ut_ad(oldest_lsn <= end_lsn); ut_ad(end_lsn == log_sys.get_lsn()); - ut_ad(oldest_lsn >= log_sys.last_checkpoint_lsn); - const lsn_t age= oldest_lsn - log_sys.last_checkpoint_lsn; - - if (age > SIZE_OF_FILE_CHECKPOINT + log_sys.framing_size()) - /* Some log has been written since the previous checkpoint. */; - else if (age > SIZE_OF_FILE_CHECKPOINT && - !((log_sys.log.calc_lsn_offset(oldest_lsn) ^ - log_sys.log.calc_lsn_offset(log_sys.last_checkpoint_lsn)) & - ~lsn_t{OS_FILE_LOG_BLOCK_SIZE - 1})) - /* Some log has been written to the same log block. */; - else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) - /* MariaDB startup expects the redo log file to be logically empty - (not even containing a FILE_CHECKPOINT record) after a clean shutdown. - Perform an extra checkpoint at shutdown. */; - else + if (oldest_lsn == log_sys.last_checkpoint_lsn || + (oldest_lsn == end_lsn && oldest_lsn == log_sys.last_checkpoint_lsn + + (log_sys.is_encrypted() + ? SIZE_OF_FILE_CHECKPOINT + 8 : SIZE_OF_FILE_CHECKPOINT))) { /* Do nothing, because nothing was logged (other than a FILE_CHECKPOINT record) since the previous checkpoint. */ - mysql_mutex_unlock(&log_sys.mutex); + do_nothing: + log_sys.latch.wr_unlock(); return true; } ut_ad(!recv_no_log_write); - + ut_ad(oldest_lsn > log_sys.last_checkpoint_lsn); /* Repeat the FILE_MODIFY records after the checkpoint, in case some log records between the checkpoint and log_sys.lsn need them. Finally, write a FILE_CHECKPOINT record. Redo log apply expects to @@ -1734,39 +1751,28 @@ static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn) It is important that we write out the redo log before any further dirty pages are flushed to the tablespace files. At this point, - because we hold log_sys.mutex, mtr_t::commit() in other threads will - be blocked, and no pages can be added to the flush lists. */ - lsn_t flush_lsn= oldest_lsn; - - if (fil_names_clear(flush_lsn, oldest_lsn != end_lsn || - srv_shutdown_state <= SRV_SHUTDOWN_INITIATED)) - { - flush_lsn= log_sys.get_lsn(); - ut_ad(flush_lsn >= end_lsn + SIZE_OF_FILE_CHECKPOINT); - mysql_mutex_unlock(&log_sys.mutex); - log_write_up_to(flush_lsn, true, true); - mysql_mutex_lock(&log_sys.mutex); - if (log_sys.last_checkpoint_lsn >= oldest_lsn) - { - mysql_mutex_unlock(&log_sys.mutex); - return true; - } - } - else - ut_ad(oldest_lsn >= log_sys.last_checkpoint_lsn); + because we hold exclusive log_sys.latch, + mtr_t::commit() in other threads will be blocked, + and no pages can be added to buf_pool.flush_list. */ + const lsn_t flush_lsn{fil_names_clear(oldest_lsn)}; + ut_ad(flush_lsn >= end_lsn + SIZE_OF_FILE_CHECKPOINT); + log_sys.latch.wr_unlock(); + log_write_up_to(flush_lsn, true); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + if (log_sys.last_checkpoint_lsn >= oldest_lsn) + goto do_nothing; ut_ad(log_sys.get_flushed_lsn() >= flush_lsn); if (log_sys.checkpoint_pending) { /* A checkpoint write is running */ - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.wr_unlock(); return false; } log_sys.next_checkpoint_lsn= oldest_lsn; - log_write_checkpoint_info(end_lsn); - mysql_mutex_assert_not_owner(&log_sys.mutex); + log_sys.write_checkpoint(end_lsn); return true; } @@ -1790,13 +1796,11 @@ static bool log_checkpoint() fil_flush_file_spaces(); } - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.wr_lock(SRW_LOCK_CALL); const lsn_t end_lsn= log_sys.get_lsn(); - mysql_mutex_lock(&log_sys.flush_order_mutex); mysql_mutex_lock(&buf_pool.flush_list_mutex); const lsn_t oldest_lsn= buf_pool.get_oldest_modification(end_lsn); mysql_mutex_unlock(&buf_pool.flush_list_mutex); - mysql_mutex_unlock(&log_sys.flush_order_mutex); return log_checkpoint_low(oldest_lsn, end_lsn); } @@ -1832,7 +1836,6 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) { ut_ad(sync_lsn); ut_ad(sync_lsn < LSN_MAX); - mysql_mutex_assert_not_owner(&log_sys.mutex); ut_ad(!srv_read_only_mode); if (recv_recovery_is_on()) @@ -1880,8 +1883,7 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) to happen until now. There could be an outstanding FILE_CHECKPOINT record from a previous fil_names_clear() call, which we must write out before we can advance the checkpoint. */ - if (sync_lsn > log_sys.get_flushed_lsn()) - log_write_up_to(sync_lsn, true); + log_write_up_to(sync_lsn, true); log_checkpoint(); } } @@ -1891,7 +1893,6 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) @param furious true=furious flushing, false=limit to innodb_io_capacity */ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) { - mysql_mutex_assert_not_owner(&log_sys.mutex); ut_ad(!srv_read_only_mode); if (recv_recovery_is_on()) @@ -1950,12 +1951,10 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) fil_flush_file_spaces(); } - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.wr_lock(SRW_LOCK_CALL); const lsn_t newest_lsn= log_sys.get_lsn(); - mysql_mutex_lock(&log_sys.flush_order_mutex); mysql_mutex_lock(&buf_pool.flush_list_mutex); lsn_t measure= buf_pool.get_oldest_modification(0); - mysql_mutex_unlock(&log_sys.flush_order_mutex); const lsn_t checkpoint_lsn= measure ? measure : newest_lsn; if (!recv_recovery_is_on() && @@ -1968,13 +1967,11 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) } else { - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.wr_unlock(); if (!measure) measure= LSN_MAX; } - mysql_mutex_assert_not_owner(&log_sys.mutex); - /* After attempting log checkpoint, check if we have reached our target. */ const lsn_t target= buf_flush_sync_lsn; @@ -2172,6 +2169,12 @@ static ulint page_cleaner_flush_pages_recommendation(ulint last_pages_in, return(n_pages); } +#if defined __aarch64__&&defined __GNUC__&&__GNUC__==4&&!defined __clang__ +/* Avoid GCC 4.8.5 internal compiler error "could not split insn". +We would only need this for buf_flush_page_cleaner(), +but GCC 4.8.5 does not support pop_options. */ +# pragma GCC optimize ("O0") +#endif /** page_cleaner thread tasked with flushing dirty pages from the buffer pools. As of now we'll have only one coordinator. */ static void buf_flush_page_cleaner() @@ -2474,7 +2477,11 @@ NOTE: The calling thread is not allowed to hold any buffer page latches! */ void buf_flush_sync() { if (recv_recovery_is_on()) + { + mysql_mutex_lock(&recv_sys.mutex); recv_sys.apply(true); + mysql_mutex_unlock(&recv_sys.mutex); + } thd_wait_begin(nullptr, THD_WAIT_DISKIO); tpool::tpool_wait_begin(); diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index c01b0e4ee66..33264bc88a1 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -460,9 +460,7 @@ not_found: << flush_failures << " failed attempts to" " flush a page!" " Consider increasing innodb_buffer_pool_size." - " Pending flushes (fsync) log: " - << log_sys.get_pending_flushes() - << "; buffer pool: " + " Pending flushes (fsync): " << fil_n_pending_tablespace_flushes << ". " << os_n_file_reads << " OS file reads, " << os_n_file_writes << " OS file writes, " diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index 0e485e58215..9a7eff2142f 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -79,40 +79,6 @@ void dtuple_t::trim(const dict_index_t& index) n_fields = i; } -/** Compare two data tuples. -@param[in] tuple1 first data tuple -@param[in] tuple2 second data tuple -@return positive, 0, negative if tuple1 is greater, equal, less, than tuple2, -respectively */ -int -dtuple_coll_cmp( - const dtuple_t* tuple1, - const dtuple_t* tuple2) -{ - ulint n_fields; - ulint i; - int cmp; - - ut_ad(tuple1 != NULL); - ut_ad(tuple2 != NULL); - ut_ad(tuple1->magic_n == DATA_TUPLE_MAGIC_N); - ut_ad(tuple2->magic_n == DATA_TUPLE_MAGIC_N); - ut_ad(dtuple_check_typed(tuple1)); - ut_ad(dtuple_check_typed(tuple2)); - - n_fields = dtuple_get_n_fields(tuple1); - - cmp = (int) n_fields - (int) dtuple_get_n_fields(tuple2); - - for (i = 0; cmp == 0 && i < n_fields; i++) { - const dfield_t* field1 = dtuple_get_nth_field(tuple1, i); - const dfield_t* field2 = dtuple_get_nth_field(tuple2, i); - cmp = cmp_dfield_dfield(field1, field2); - } - - return(cmp); -} - /*********************************************************************//** Sets number of fields used in a tuple. Normally this is set in dtuple_create, but if you want later to set it smaller, you can use this. */ @@ -466,8 +432,10 @@ dfield_print_raw( ulint print_len = ut_min(len, static_cast<ulint>(1000)); ut_print_buf(f, dfield_get_data(dfield), print_len); if (len != print_len) { - fprintf(f, "(total %lu bytes%s)", - (ulong) len, + std::ostringstream str_bytes; + str_bytes << ib::bytes_iec{len}; + fprintf(f, "(total %s%s)", + str_bytes.str().c_str(), dfield_is_ext(dfield) ? ", external" : ""); } } else { @@ -599,7 +567,7 @@ dtuple_convert_big_rec( size = rec_get_converted_size(index, entry, *n_ext); if (UNIV_UNLIKELY(size > 1000000000)) { - ib::warn() << "Tuple size is very big: " << size; + ib::warn() << "Tuple size is very big: " << ib::bytes_iec{size}; fputs("InnoDB: Tuple contents: ", stderr); dtuple_print(stderr, entry); putc('\n', stderr); diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 09cf3c31bd7..fab6ff4db8e 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -536,15 +536,15 @@ dict_create_sys_fields_tuple( dict_field_t* field; dfield_t* dfield; byte* ptr; - ibool index_contains_column_prefix_field = FALSE; - ulint j; + bool wide_pos = false; ut_ad(index); ut_ad(heap); - for (j = 0; j < index->n_fields; j++) { - if (dict_index_get_nth_field(index, j)->prefix_len > 0) { - index_contains_column_prefix_field = TRUE; + for (unsigned j = 0; j < index->n_fields; j++) { + const dict_field_t* f = dict_index_get_nth_field(index, j); + if (f->prefix_len || f->descending) { + wide_pos = true; break; } } @@ -569,12 +569,15 @@ dict_create_sys_fields_tuple( ptr = static_cast<byte*>(mem_heap_alloc(heap, 4)); - if (index_contains_column_prefix_field) { - /* If there are column prefix fields in the index, then - we store the number of the field to the 2 HIGH bytes - and the prefix length to the 2 low bytes, */ - - mach_write_to_4(ptr, (fld_no << 16) + field->prefix_len); + if (wide_pos) { + /* If there are column prefixes or columns with + descending order in the index, then we write the + field number to the 16 most significant bits, + the DESC flag to bit 15, and the prefix length + in the 15 least significant bits. */ + mach_write_to_4(ptr, (fld_no << 16) + | (!!field->descending) << 15 + | field->prefix_len); } else { /* Else we store the number of the field to the 2 LOW bytes. This is to keep the storage format compatible with diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 34362a6792f..51bb5dc4eba 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1273,7 +1273,7 @@ static bool dict_table_can_be_evicted(dict_table_t *table) dict_index_t *dict_index_t::clone() const { ut_ad(n_fields); - ut_ad(!(type & (DICT_IBUF | DICT_SPATIAL | DICT_FTS))); + ut_ad(is_btree()); ut_ad(online_status == ONLINE_INDEX_COMPLETE); ut_ad(is_committed()); ut_ad(!is_dummy); @@ -2289,15 +2289,14 @@ found: return(TRUE); } -/*******************************************************************//** -Adds a column to index. */ -void -dict_index_add_col( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - const dict_table_t* table, /*!< in: table */ - dict_col_t* col, /*!< in: column */ - ulint prefix_len) /*!< in: column prefix length */ +/** Add a column to an index. +@param index index +@param table table +@param col column +@param prefix_len column prefix length +@param descending whether to use descending order */ +void dict_index_add_col(dict_index_t *index, const dict_table_t *table, + dict_col_t *col, ulint prefix_len, bool descending) { dict_field_t* field; const char* col_name; @@ -2335,6 +2334,8 @@ dict_index_add_col( field->fixed_len = 0; } + field->descending = descending; + /* The comparison limit above must be constant. If it were changed, the disk format of some fixed-length columns would change, which would be a disaster. */ @@ -2366,7 +2367,7 @@ dict_index_copy( field = dict_index_get_nth_field(index2, i); dict_index_add_col(index1, index2->table, field->col, - field->prefix_len); + field->prefix_len, field->descending); } } @@ -2680,17 +2681,12 @@ dict_index_build_internal_non_clust( index entry uniquely */ for (i = 0; i < clust_index->n_uniq; i++) { - field = dict_index_get_nth_field(clust_index, i); - if (!indexed[field->col->ind]) { - dict_index_add_col(new_index, table, field->col, - field->prefix_len); - } else if (dict_index_is_spatial(index)) { - /*For spatial index, we still need to add the - field to index. */ + if (!indexed[field->col->ind] || index->is_spatial()) { dict_index_add_col(new_index, table, field->col, - field->prefix_len); + field->prefix_len, + field->descending); } } @@ -4665,7 +4661,7 @@ dict_foreign_qualify_index( return(false); } - if (index->type & (DICT_SPATIAL | DICT_FTS | DICT_CORRUPT)) { + if (!index->is_btree()) { return false; } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index fa77720399a..0e937ebe63b 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1533,6 +1533,7 @@ dict_load_field_low( ulint len; unsigned pos_and_prefix_len; unsigned prefix_len; + bool descending; bool first_field; ulint position; @@ -1585,10 +1586,12 @@ err_len: } if (first_field || pos_and_prefix_len > 0xFFFFUL) { - prefix_len = pos_and_prefix_len & 0xFFFFUL; + prefix_len = pos_and_prefix_len & 0x7FFFUL; + descending = (pos_and_prefix_len & 0x8000UL); position = (pos_and_prefix_len & 0xFFFF0000UL) >> 16; } else { prefix_len = 0; + descending = false; position = pos_and_prefix_len & 0xFFFFUL; } @@ -1638,11 +1641,12 @@ err_len: if (index) { dict_mem_index_add_field( index, mem_heap_strdupl(heap, (const char*) field, len), - prefix_len); + prefix_len, descending); } else { sys_field->name = mem_heap_strdupl( heap, (const char*) field, len); sys_field->prefix_len = prefix_len & ((1U << 12) - 1); + sys_field->descending = descending; *pos = position; } @@ -3114,12 +3118,12 @@ loop: following call does the comparison in the latin1_swedish_ci charset-collation, in a case-insensitive way. */ - if (0 != cmp_data_data(dfield_get_type(&dfield)->mtype, - dfield_get_type(&dfield)->prtype, - reinterpret_cast<const byte*>(table_name), - dfield_get_len(&dfield), - field, len)) { - + if (cmp_data(dfield_get_type(&dfield)->mtype, + dfield_get_type(&dfield)->prtype, + false, + reinterpret_cast<const byte*>(table_name), + dfield_get_len(&dfield), + field, len)) { goto load_next_index; } diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 0da0c5acf0f..6e3b0e1fabb 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -1046,32 +1046,6 @@ dict_mem_table_free_foreign_vcol_set( } /**********************************************************************//** -Adds a field definition to an index. NOTE: does not take a copy -of the column name if the field is a column. The memory occupied -by the column name may be released only after publishing the index. */ -void -dict_mem_index_add_field( -/*=====================*/ - dict_index_t* index, /*!< in: index */ - const char* name, /*!< in: column name */ - ulint prefix_len) /*!< in: 0 or the column prefix length - in a MySQL index like - INDEX (textcol(25)) */ -{ - dict_field_t* field; - - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - index->n_def++; - - field = dict_index_get_nth_field(index, unsigned(index->n_def) - 1); - - field->name = name; - field->prefix_len = prefix_len & ((1U << 12) - 1); -} - -/**********************************************************************//** Frees an index memory object. */ void dict_mem_index_free( diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 64e3ddb91e4..84fac55a304 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1125,7 +1125,7 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index, std::vector<index_field_stats_t> result; - ut_ad(!index->is_spatial()); + ut_ad(index->is_btree()); n_cols = dict_index_get_n_unique(index); @@ -1519,7 +1519,7 @@ empty_table: ut_ad(!dict_index_is_ibuf(index)); - if (index->type & (DICT_FTS | DICT_SPATIAL)) { + if (!index->is_btree()) { continue; } @@ -2552,8 +2552,7 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) ut_ad(!index->table->stats_mutex_is_owner()); ut_ad(index->table->get_ref_count()); - /* Disable update statistic for Rtree */ - if (dict_index_is_spatial(index)) { + if (!index->is_btree()) { DBUG_RETURN(result); } @@ -2906,9 +2905,7 @@ dict_stats_update_persistent( index != NULL; index = dict_table_get_next_index(index)) { - ut_ad(!dict_index_is_ibuf(index)); - - if (index->type & (DICT_FTS | DICT_SPATIAL)) { + if (!index->is_btree()) { continue; } diff --git a/storage/innobase/eval/eval0eval.cc b/storage/innobase/eval/eval0eval.cc index 73ab113cff5..bafb0b55d09 100644 --- a/storage/innobase/eval/eval0eval.cc +++ b/storage/innobase/eval/eval0eval.cc @@ -144,8 +144,8 @@ eval_cmp_like( switch (op) { case IB_LIKE_PREFIX: arg4 = que_node_get_next(arg3); - return(!cmp_dfield_dfield_like_prefix(que_node_get_val(arg1), - que_node_get_val(arg4))); + return(cmp_dfield_dfield_eq_prefix(que_node_get_val(arg1), + que_node_get_val(arg4))); case IB_LIKE_EXACT: return(!cmp_dfield_dfield(que_node_get_val(arg1), que_node_get_val(arg2))); diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 049778d831c..0a2026efa33 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -533,7 +533,7 @@ static byte* fil_encrypt_buf_for_full_crc32( ut_a(dstlen == srclen); const ulint payload = size - FIL_PAGE_FCRC32_CHECKSUM; - mach_write_to_4(dst_frame + payload, ut_crc32(dst_frame, payload)); + mach_write_to_4(dst_frame + payload, my_crc32c(0, dst_frame, payload)); /* Clean the rest of the buffer. FIXME: Punch holes when writing! */ memset(dst_frame + (payload + 4), 0, srv_page_size - (payload + 4)); diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index f78c08e268b..98024bd2769 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -883,18 +883,22 @@ bool fil_space_free(uint32_t id, bool x_latched) } if (!recv_recovery_is_on()) { - mysql_mutex_lock(&log_sys.mutex); - } - - mysql_mutex_assert_owner(&log_sys.mutex); + log_sys.latch.wr_lock(SRW_LOCK_CALL); - if (space->max_lsn != 0) { - ut_d(space->max_lsn = 0); - fil_system.named_spaces.remove(*space); - } + if (space->max_lsn) { + ut_d(space->max_lsn = 0); + fil_system.named_spaces.remove(*space); + } - if (!recv_recovery_is_on()) { - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.wr_unlock(); + } else { +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif + if (space->max_lsn) { + ut_d(space->max_lsn = 0); + fil_system.named_spaces.remove(*space); + } } fil_space_free_low(space); @@ -1389,46 +1393,6 @@ void fil_set_max_space_id_if_bigger(uint32_t max_id) mysql_mutex_unlock(&fil_system.mutex); } -/** Write the flushed LSN to the page header of the first page in the -system tablespace. -@param[in] lsn flushed LSN -@return DB_SUCCESS or error number */ -dberr_t -fil_write_flushed_lsn( - lsn_t lsn) -{ - byte* buf; - ut_ad(!srv_read_only_mode); - - if (!fil_system.sys_space->acquire()) { - return DB_ERROR; - } - - buf = static_cast<byte*>(aligned_malloc(srv_page_size, srv_page_size)); - - auto fio = fil_system.sys_space->io(IORequestRead, 0, srv_page_size, - buf); - - if (fio.err == DB_SUCCESS) { - mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - lsn); - - uint32_t fsp_flags = mach_read_from_4( - buf + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS); - - if (fil_space_t::full_crc32(fsp_flags)) { - buf_flush_assign_full_crc32_checksum(buf); - } - - fio = fil_system.sys_space->io(IORequestWrite, - 0, srv_page_size, buf); - fil_flush_file_spaces(); - } - - aligned_free(buf); - return fio.err; -} - /** Acquire a tablespace reference. @param id tablespace identifier @return tablespace @@ -1501,7 +1465,7 @@ inline void mtr_t::log_file_op(mfile_type_t type, uint32_t space_id, { ut_ad(strchr(new_path, '/')); m_log.push(reinterpret_cast<const byte*>(path), uint32_t(len + 1)); - m_log.push(reinterpret_cast<const byte*>(new_path), uint32_t(new_len)); + m_log.push(reinterpret_cast<const byte*>(new_path), uint32_t(new_len - 1)); } else m_log.push(reinterpret_cast<const byte*>(path), uint32_t(len)); @@ -1854,8 +1818,11 @@ fil_ibd_create( mtr.start(); mtr.log_file_op(FILE_CREATE, space_id, path); - mtr.commit(); - log_write_up_to(mtr.commit_lsn(), true); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + auto lsn= mtr.commit_files(); + log_sys.latch.wr_unlock(); + mtr.flag_wr_unlock(); + log_write_up_to(lsn, true); ulint type; static_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096, @@ -2654,8 +2621,8 @@ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len, void *buf, buf_page_t *bpage) { ut_ad(referenced()); - ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_ad((len % OS_FILE_LOG_BLOCK_SIZE) == 0); + ut_ad(offset % UNIV_ZIP_SIZE_MIN == 0); + ut_ad(len % 512 == 0); /* page_compressed */ ut_ad(fil_validate_skip()); ut_ad(type.is_read() || type.is_write()); ut_ad(type.type != IORequest::DBLWR_BATCH); @@ -2954,19 +2921,6 @@ fil_space_validate_for_mtr_commit( } #endif /* UNIV_DEBUG */ -/** Write a FILE_MODIFY record for a persistent tablespace. -@param[in] space tablespace -@param[in,out] mtr mini-transaction */ -static -void -fil_names_write( - const fil_space_t* space, - mtr_t* mtr) -{ - ut_ad(UT_LIST_GET_LEN(space->chain) == 1); - fil_name_write(space->id, UT_LIST_GET_FIRST(space->chain)->name, mtr); -} - /** Note that a non-predefined persistent tablespace has been modified by redo log. @param[in,out] space tablespace */ @@ -2974,7 +2928,9 @@ void fil_names_dirty( fil_space_t* space) { - mysql_mutex_assert_owner(&log_sys.mutex); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif ut_ad(recv_recovery_is_on()); ut_ad(log_sys.get_lsn() != 0); ut_ad(space->max_lsn == 0); @@ -2984,56 +2940,48 @@ fil_names_dirty( space->max_lsn = log_sys.get_lsn(); } -/** Write FILE_MODIFY records when a non-predefined persistent -tablespace was modified for the first time since the latest -fil_names_clear(). -@param[in,out] space tablespace */ -void fil_names_dirty_and_write(fil_space_t* space) +/** Write a FILE_MODIFY record when a non-predefined persistent +tablespace was modified for the first time since fil_names_clear(). */ +ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write() { - mysql_mutex_assert_owner(&log_sys.mutex); - ut_d(fil_space_validate_for_mtr_commit(space)); - ut_ad(space->max_lsn == log_sys.get_lsn()); - - fil_system.named_spaces.push_back(*space); - mtr_t mtr; - mtr.start(); - fil_names_write(space, &mtr); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif + ut_d(fil_space_validate_for_mtr_commit(m_user_space)); + ut_ad(!m_user_space->max_lsn); + m_user_space->max_lsn= log_sys.get_lsn(); - DBUG_EXECUTE_IF("fil_names_write_bogus", - { - char bogus_name[] = "./test/bogus file.ibd"; - fil_name_write( - SRV_SPACE_ID_UPPER_BOUND, - bogus_name, &mtr); - }); + fil_system.named_spaces.push_back(*m_user_space); + ut_ad(UT_LIST_GET_LEN(m_user_space->chain) == 1); - mtr.commit_files(); + mtr_t mtr; + mtr.start(); + fil_name_write(m_user_space->id, + UT_LIST_GET_FIRST(m_user_space->chain)->name, + &mtr); + mtr.commit_files(); } /** On a log checkpoint, reset fil_names_dirty_and_write() flags -and write out FILE_MODIFY and FILE_CHECKPOINT if needed. -@param[in] lsn checkpoint LSN -@param[in] do_write whether to always write FILE_CHECKPOINT -@return whether anything was written to the redo log -@retval false if no flags were set and nothing written -@retval true if anything was written to the redo log */ -bool -fil_names_clear( - lsn_t lsn, - bool do_write) +and write out FILE_MODIFY if needed, and write FILE_CHECKPOINT. +@param lsn checkpoint LSN +@return current LSN */ +lsn_t fil_names_clear(lsn_t lsn) { mtr_t mtr; - mysql_mutex_assert_owner(&log_sys.mutex); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif ut_ad(lsn); + ut_ad(log_sys.is_latest()); mtr.start(); for (auto it = fil_system.named_spaces.begin(); it != fil_system.named_spaces.end(); ) { - if (mtr.get_log_size() - + strlen(it->chain.start->name) - >= RECV_SCAN_SIZE - (3 + 5 + 1)) { + if (mtr.get_log_size() + strlen(it->chain.start->name) + >= recv_sys.MTR_SIZE_MAX - (3 + 5)) { /* Prevent log parse buffer overflow */ mtr.commit_files(); mtr.start(); @@ -3056,20 +3004,13 @@ fil_names_clear( was called. If we kept track of "min_lsn" (the first LSN where max_lsn turned nonzero), we could avoid the fil_names_write() call if min_lsn > lsn. */ - - fil_names_write(&*it, &mtr); - do_write = true; - + ut_ad(UT_LIST_GET_LEN((*it).chain) == 1); + fil_name_write((*it).id, UT_LIST_GET_FIRST((*it).chain)->name, + &mtr); it = next; } - if (do_write) { - mtr.commit_files(lsn); - } else { - ut_ad(!mtr.has_modifications()); - } - - return(do_write); + return mtr.commit_files(lsn); } /* Unit Tests */ diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index e85674401ee..c32f9d296c9 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -353,7 +353,7 @@ dberr_t Datafile::validate_to_dd(uint32_t space_id, uint32_t flags) /* Validate this single-table-tablespace with the data dictionary, but do not compare the DATA_DIR flag, in case the tablespace was remotely located. */ - err = validate_first_page(0); + err = validate_first_page(); if (err != DB_SUCCESS) { return(err); } @@ -396,7 +396,7 @@ Datafile::validate_for_recovery() ut_ad(is_open()); ut_ad(!srv_read_only_mode); - err = validate_first_page(0); + err = validate_first_page(); switch (err) { case DB_TABLESPACE_EXISTS: @@ -443,7 +443,7 @@ Datafile::validate_for_recovery() /* Free the previously read first page and then re-validate. */ free_first_page(); m_defer = false; - err = validate_first_page(0); + err = validate_first_page(); } return(err); @@ -453,11 +453,10 @@ Datafile::validate_for_recovery() tablespace is opened. This occurs before the fil_space_t is created so the Space ID found here must not already be open. m_is_valid is set true on success, else false. -@param[out] flush_lsn contents of FIL_PAGE_FILE_FLUSH_LSN @retval DB_SUCCESS on if the datafile is valid @retval DB_CORRUPTION if the datafile is not readable @retval DB_TABLESPACE_EXISTS if there is a duplicate space_id */ -dberr_t Datafile::validate_first_page(lsn_t *flush_lsn) +dberr_t Datafile::validate_first_page() { const char* error_txt = NULL; @@ -467,14 +466,6 @@ dberr_t Datafile::validate_first_page(lsn_t *flush_lsn) && read_first_page(srv_read_only_mode) != DB_SUCCESS) { error_txt = "Cannot read first page"; - } else { - ut_ad(m_first_page); - - if (flush_lsn != NULL) { - - *flush_lsn = mach_read_from_8( - m_first_page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - } } if (error_txt != NULL) { @@ -790,7 +781,7 @@ Datafile::restore_from_doublewrite() ib::info() << "Restoring page " << page_id << " of datafile '" << m_filepath << "' from the doublewrite buffer. Writing " - << physical_size << " bytes into file '" + << ib::bytes_iec{physical_size} << " into file '" << m_filepath << "'"; return(os_file_write( diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 74dbf207947..09583e157b7 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -449,8 +449,7 @@ void fsp_apply_init_file_page(buf_block_t *block) const page_id_t id(block->page.id()); mach_write_to_4(block->page.frame + FIL_PAGE_OFFSET, id.page_no()); - if (log_sys.is_physical()) - memset_aligned<8>(block->page.frame + FIL_PAGE_PREV, 0xff, 8); + memset_aligned<8>(block->page.frame + FIL_PAGE_PREV, 0xff, 8); mach_write_to_4(block->page.frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id.space()); if (page_zip_des_t* page_zip= buf_block_get_page_zip(block)) @@ -460,8 +459,7 @@ void fsp_apply_init_file_page(buf_block_t *block) static_assert(FIL_PAGE_OFFSET == 4, "compatibility"); memcpy_aligned<4>(page_zip->data + FIL_PAGE_OFFSET, block->page.frame + FIL_PAGE_OFFSET, 4); - if (log_sys.is_physical()) - memset_aligned<8>(page_zip->data + FIL_PAGE_PREV, 0xff, 8); + memset_aligned<8>(page_zip->data + FIL_PAGE_PREV, 0xff, 8); static_assert(FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID % 4 == 2, "not perfect alignment"); memcpy_aligned<2>(page_zip->data + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc index c9d09e31313..ef650436907 100644 --- a/storage/innobase/fsp/fsp0sysspace.cc +++ b/storage/innobase/fsp/fsp0sysspace.cc @@ -396,8 +396,8 @@ SysTablespace::set_size( /* We created the data file and now write it full of zeros */ ib::info() << "Setting file '" << file.filepath() << "' size to " - << (file.m_size >> (20U - srv_page_size_shift)) << " MB." - " Physically writing the file full; Please wait ..."; + << ib::bytes_iec{file.m_size << srv_page_size_shift} << + ". Physically writing the file full; Please wait ..."; bool success = os_file_set_size( file.m_filepath, file.m_handle, @@ -405,8 +405,8 @@ SysTablespace::set_size( if (success) { ib::info() << "File '" << file.filepath() << "' size is now " - << (file.m_size >> (20U - srv_page_size_shift)) - << " MB."; + << ib::bytes_iec{file.m_size << srv_page_size_shift} + << "."; } else { ib::error() << "Could not set the file size of '" << file.filepath() << "'. Probably out of disk space"; @@ -548,16 +548,11 @@ SysTablespace::open_file( } /** Check the tablespace header for this tablespace. -@param[out] flushed_lsn the value of FIL_PAGE_FILE_FLUSH_LSN @return DB_SUCCESS or error code */ -dberr_t -SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn) +inline dberr_t SysTablespace::read_lsn_and_check_flags() { dberr_t err; - /* Only relevant for the system tablespace. */ - ut_ad(space_id() == TRX_SYS_SPACE); - files_t::iterator it = m_files.begin(); ut_a(it->m_exists); @@ -589,7 +584,7 @@ SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn) first datafile. */ for (int retry = 0; retry < 2; ++retry) { - err = it->validate_first_page(flushed_lsn); + err = it->validate_first_page(); if (err != DB_SUCCESS && (retry == 1 @@ -616,6 +611,13 @@ SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn) return(err); } + if (srv_operation == SRV_OPERATION_NORMAL) { + /* Prepare for possible upgrade from 0-sized ib_logfile0. */ + ut_ad(!log_sys.next_checkpoint_lsn); + log_sys.next_checkpoint_lsn = mach_read_from_8( + it->m_first_page + 26/*FIL_PAGE_FILE_FLUSH_LSN*/); + } + it->close(); return(DB_SUCCESS); @@ -853,14 +855,12 @@ SysTablespace::check_file_spec( @param[in] is_temp whether this is a temporary tablespace @param[in] create_new_db whether we are creating a new database @param[out] sum_new_sizes sum of sizes of the new files added -@param[out] flush_lsn FIL_PAGE_FILE_FLUSH_LSN of first file @return DB_SUCCESS or error code */ dberr_t SysTablespace::open_or_create( bool is_temp, bool create_new_db, - ulint* sum_new_sizes, - lsn_t* flush_lsn) + ulint* sum_new_sizes) { dberr_t err = DB_SUCCESS; fil_space_t* space = NULL; @@ -909,10 +909,9 @@ SysTablespace::open_or_create( } - if (!create_new_db && flush_lsn) { - /* Validate the header page in the first datafile - and read LSNs fom the others. */ - err = read_lsn_and_check_flags(flush_lsn); + if (!create_new_db && space_id() == TRX_SYS_SPACE) { + /* Validate the header page in the first datafile. */ + err = read_lsn_and_check_flags(); if (err != DB_SUCCESS) { return(err); } diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index efa15251bbe..2707751a6f6 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -3939,7 +3939,7 @@ fts_sync_begin( ib::info() << "FTS SYNC for table " << sync->table->name << ", deleted count: " << ib_vector_size(cache->deleted_doc_ids) - << " size: " << cache->total_size << " bytes"; + << " size: " << ib::bytes_iec{cache->total_size}; } } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index acc179f28b5..eeff09c0c8d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -169,6 +169,8 @@ static const long AUTOINC_OLD_STYLE_LOCKING = 0; static const long AUTOINC_NEW_STYLE_LOCKING = 1; static const long AUTOINC_NO_LOCKING = 2; +static constexpr size_t buf_pool_chunk_min_size= 1U << 20; + static ulong innobase_open_files; static long innobase_autoinc_lock_mode; @@ -238,10 +240,10 @@ static void innodb_max_purge_lag_wait_update(THD *thd, st_mysql_sys_var *, if (thd_kill_level(thd)) break; /* Adjust for purge_coordinator_state::refresh() */ - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.rd_lock(SRW_LOCK_CALL); const lsn_t last= log_sys.last_checkpoint_lsn, max_age= log_sys.max_checkpoint_age; - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.rd_unlock(); const lsn_t lsn= log_sys.get_lsn(); if ((lsn - last) / 4 >= max_age / 5) buf_flush_ahead(last + max_age / 5, false); @@ -529,8 +531,6 @@ mysql_pfs_key_t fts_doc_id_mutex_key; mysql_pfs_key_t ibuf_bitmap_mutex_key; mysql_pfs_key_t ibuf_mutex_key; mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key; -mysql_pfs_key_t log_sys_mutex_key; -mysql_pfs_key_t log_flush_order_mutex_key; mysql_pfs_key_t recalc_pool_mutex_key; mysql_pfs_key_t purge_sys_pq_mutex_key; mysql_pfs_key_t recv_sys_mutex_key; @@ -562,11 +562,9 @@ static PSI_mutex_info all_innodb_mutexes[] = { PSI_KEY(fts_cache_init_mutex), PSI_KEY(fts_delete_mutex), PSI_KEY(fts_doc_id_mutex), - PSI_KEY(log_flush_order_mutex), PSI_KEY(ibuf_mutex), PSI_KEY(ibuf_pessimistic_insert_mutex), PSI_KEY(index_online_log), - PSI_KEY(log_sys_mutex), PSI_KEY(page_zip_stat_per_index_mutex), PSI_KEY(purge_sys_pq_mutex), PSI_KEY(recv_sys_mutex), @@ -592,8 +590,9 @@ mysql_pfs_key_t index_online_log_key; mysql_pfs_key_t fil_space_latch_key; mysql_pfs_key_t trx_i_s_cache_lock_key; mysql_pfs_key_t trx_purge_latch_key; -mysql_pfs_key_t lock_latch_key; mysql_pfs_key_t trx_rseg_latch_key; +mysql_pfs_key_t lock_latch_key; +mysql_pfs_key_t log_latch_key; /* all_innodb_rwlocks array contains rwlocks that are performance schema instrumented if "UNIV_PFS_RWLOCK" @@ -607,8 +606,9 @@ static PSI_rwlock_info all_innodb_rwlocks[] = { &fil_space_latch_key, "fil_space_latch", 0 }, { &trx_i_s_cache_lock_key, "trx_i_s_cache_lock", 0 }, { &trx_purge_latch_key, "trx_purge_latch", 0 }, - { &lock_latch_key, "lock_latch", 0 }, { &trx_rseg_latch_key, "trx_rseg_latch", 0 }, + { &lock_latch_key, "lock_latch", 0 }, + { &log_latch_key, "log_latch", 0 }, { &index_tree_rw_lock_key, "index_tree_rw_lock", PSI_RWLOCK_FLAG_SX } }; # endif /* UNIV_PFS_RWLOCK */ @@ -629,7 +629,6 @@ static PSI_thread_info all_innodb_threads[] = { performance schema instrumented if "UNIV_PFS_IO" is defined */ static PSI_file_info all_innodb_files[] = { PSI_KEY(innodb_data_file), - PSI_KEY(innodb_log_file), PSI_KEY(innodb_temp_file) }; # endif /* UNIV_PFS_IO */ @@ -953,12 +952,12 @@ static SHOW_VAR innodb_status_variables[]= { {"buffer_pool_reads", &export_vars.innodb_buffer_pool_reads, SHOW_SIZE_T}, {"buffer_pool_wait_free", &buf_pool.stat.LRU_waits, SHOW_SIZE_T}, - {"buffer_pool_write_requests", - &export_vars.innodb_buffer_pool_write_requests, SHOW_SIZE_T}, + {"buffer_pool_write_requests", &buf_pool.flush_list_requests, SHOW_SIZE_T}, {"checkpoint_age", &export_vars.innodb_checkpoint_age, SHOW_SIZE_T}, {"checkpoint_max_age", &export_vars.innodb_checkpoint_max_age, SHOW_SIZE_T}, - {"data_fsyncs", &export_vars.innodb_data_fsyncs, SHOW_SIZE_T}, - {"data_pending_fsyncs", &export_vars.innodb_data_pending_fsyncs,SHOW_SIZE_T}, + {"data_fsyncs", (size_t*) &os_n_fsyncs, SHOW_SIZE_T}, + {"data_pending_fsyncs", + (size_t*) &fil_n_pending_tablespace_flushes, SHOW_SIZE_T}, {"data_pending_reads", &export_vars.innodb_data_pending_reads, SHOW_SIZE_T}, {"data_pending_writes", &export_vars.innodb_data_pending_writes,SHOW_SIZE_T}, {"data_read", &export_vars.innodb_data_read, SHOW_SIZE_T}, @@ -983,9 +982,9 @@ static SHOW_VAR innodb_status_variables[]= { {"ibuf_merges", &ibuf.n_merges, SHOW_SIZE_T}, {"ibuf_segment_size", &ibuf.seg_size, SHOW_SIZE_T}, {"ibuf_size", &ibuf.size, SHOW_SIZE_T}, - {"log_waits", &export_vars.innodb_log_waits, SHOW_SIZE_T}, - {"log_write_requests", &export_vars.innodb_log_write_requests, SHOW_SIZE_T}, - {"log_writes", &export_vars.innodb_log_writes, SHOW_SIZE_T}, + {"log_waits", &log_sys.waits, SHOW_SIZE_T}, + {"log_write_requests", &log_sys.write_to_buf, SHOW_SIZE_T}, + {"log_writes", &log_sys.write_to_log, SHOW_SIZE_T}, {"lsn_current", &export_vars.innodb_lsn_current, SHOW_ULONGLONG}, {"lsn_flushed", &export_vars.innodb_lsn_flushed, SHOW_ULONGLONG}, {"lsn_last_checkpoint", &export_vars.innodb_lsn_last_checkpoint, @@ -997,11 +996,6 @@ static SHOW_VAR innodb_status_variables[]= { {"mem_adaptive_hash", &export_vars.innodb_mem_adaptive_hash, SHOW_SIZE_T}, #endif {"mem_dictionary", &export_vars.innodb_mem_dictionary, SHOW_SIZE_T}, - {"os_log_fsyncs", &export_vars.innodb_os_log_fsyncs, SHOW_SIZE_T}, - {"os_log_pending_fsyncs", &export_vars.innodb_os_log_pending_fsyncs, - SHOW_SIZE_T}, - {"os_log_pending_writes", &export_vars.innodb_os_log_pending_writes, - SHOW_SIZE_T}, {"os_log_written", &export_vars.innodb_os_log_written, SHOW_SIZE_T}, {"page_size", &srv_page_size, SHOW_ULONG}, {"pages_created", &buf_pool.stat.n_pages_created, SHOW_SIZE_T}, @@ -1627,54 +1621,14 @@ innobase_start_trx_and_assign_read_view( be committed */ /** Flush InnoDB redo logs to the file system. -@param[in] hton InnoDB handlerton -@param[in] binlog_group_flush true if we got invoked by binlog -group commit during flush stage, false in other cases. -@return false */ -static -bool -innobase_flush_logs( - handlerton* hton, - bool binlog_group_flush) -{ - DBUG_ENTER("innobase_flush_logs"); - DBUG_ASSERT(hton == innodb_hton_ptr); - - if (srv_read_only_mode) { - DBUG_RETURN(false); - } - - /* If !binlog_group_flush, we got invoked by FLUSH LOGS or similar. - Else, we got invoked by binlog group commit during flush stage. */ - - if (binlog_group_flush && srv_flush_log_at_trx_commit == 0) { - /* innodb_flush_log_at_trx_commit=0 - (write and sync once per second). - Do not flush the redo log during binlog group commit. */ - DBUG_RETURN(false); - } - - /* Flush the redo log buffer to the redo log file. - Sync it to disc if we are in FLUSH LOGS, or if - innodb_flush_log_at_trx_commit=1 - (write and sync at each commit). */ - log_buffer_flush_to_disk(!binlog_group_flush - || srv_flush_log_at_trx_commit == 1); - - DBUG_RETURN(false); -} - -/** Flush InnoDB redo logs to the file system. -@param[in] hton InnoDB handlerton -@param[in] binlog_group_flush true if we got invoked by binlog -group commit during flush stage, false in other cases. @return false */ -static -bool -innobase_flush_logs( - handlerton* hton) +static bool innobase_flush_logs(handlerton*) { - return innobase_flush_logs(hton, true); + if (!srv_read_only_mode && srv_flush_log_at_trx_commit) + /* Write any outstanding redo log. Durably if + innodb_flush_log_at_trx_commit=1. */ + log_buffer_flush_to_disk(srv_flush_log_at_trx_commit == 1); + return false; } /************************************************************************//** @@ -3730,11 +3684,6 @@ innodb_buffer_pool_size_update( void* var_ptr, const void* save); -/* If the default value of innodb_buffer_pool_size is increased to be more than -BUF_POOL_SIZE_THRESHOLD (srv/srv0start.cc), then srv_buf_pool_instances_default -can be removed and 8 used instead. The problem with the current setup is that -with 128MiB default buffer pool size and 8 instances by default we would emit -a warning when no options are specified. */ static MYSQL_SYSVAR_ULONGLONG(buffer_pool_size, innobase_buffer_pool_size, PLUGIN_VAR_RQCMDARG, "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", @@ -3789,17 +3738,26 @@ static ulonglong innodb_prepare_commit_versioned(THD* thd, ulonglong *trx_id) return 0; } -/** Initialize and normalize innodb_buffer_pool_size. */ +/** Initialize and normalize innodb_buffer_pool_{chunk_,}size. */ static void innodb_buffer_pool_size_init() { - if (srv_buf_pool_chunk_unit > srv_buf_pool_size) { - /* Size unit of buffer pool is larger than srv_buf_pool_size. - adjust srv_buf_pool_chunk_unit for srv_buf_pool_size. */ - srv_buf_pool_chunk_unit = ulong(srv_buf_pool_size); - } + if (srv_buf_pool_chunk_unit > srv_buf_pool_size) + { + /* Size unit of buffer pool is larger than srv_buf_pool_size. + adjust srv_buf_pool_chunk_unit for srv_buf_pool_size. */ + srv_buf_pool_chunk_unit = srv_buf_pool_size; + } + else if (srv_buf_pool_chunk_unit == 0) + { + srv_buf_pool_chunk_unit = srv_buf_pool_size / 64; + my_large_page_truncate(&srv_buf_pool_chunk_unit); + } - srv_buf_pool_size = buf_pool_size_align(srv_buf_pool_size); - innobase_buffer_pool_size = srv_buf_pool_size; + if (srv_buf_pool_chunk_unit < buf_pool_chunk_min_size) + srv_buf_pool_chunk_unit = buf_pool_chunk_min_size; + + srv_buf_pool_size = buf_pool_size_align(srv_buf_pool_size); + innobase_buffer_pool_size = srv_buf_pool_size; } @@ -4027,23 +3985,6 @@ static int innodb_init_params() << srv_page_size_shift); } - if (srv_log_write_ahead_size > srv_page_size) { - srv_log_write_ahead_size = srv_page_size; - } else { - ulong srv_log_write_ahead_size_tmp = OS_FILE_LOG_BLOCK_SIZE; - - while (srv_log_write_ahead_size_tmp - < srv_log_write_ahead_size) { - srv_log_write_ahead_size_tmp - = srv_log_write_ahead_size_tmp * 2; - } - if (srv_log_write_ahead_size_tmp - != srv_log_write_ahead_size) { - srv_log_write_ahead_size - = srv_log_write_ahead_size_tmp / 2; - } - } - srv_buf_pool_size = ulint(innobase_buffer_pool_size); if (innobase_open_files < 10) { @@ -4099,6 +4040,14 @@ static int innodb_init_params() } #endif +#if defined __linux__ || defined _WIN32 + if (srv_flush_log_at_trx_commit == 2) { + /* Do not disable the file system cache if + innodb_flush_log_at_trx_commit=2. */ + log_sys.log_buffered = true; + } +#endif + if (srv_read_only_mode) { ib::info() << "Started in read only mode"; srv_use_doublewrite_buf = FALSE; @@ -5519,6 +5468,11 @@ innobase_match_index_columns( col_type= DATA_FIXBINARY; } + if (innodb_idx_fld->descending + != !!(key_part->key_part_flag & HA_REVERSE_SORT)) { + DBUG_RETURN(FALSE); + } + if (col_type != mtype) { /* If the col_type we get from mysql type is a geometry data type, we should check if mtype is a legacy type @@ -10936,7 +10890,9 @@ create_index( } dict_mem_index_add_field(index, field->field_name.str, - 0); + 0, + key->key_part->key_part_flag + & HA_REVERSE_SORT); } DBUG_RETURN(convert_error_code_to_mysql( @@ -11030,7 +10986,9 @@ create_index( index->type |= DICT_VIRTUAL; } - dict_mem_index_add_field(index, field_name, prefix_len); + dict_mem_index_add_field(index, field_name, prefix_len, + key_part->key_part_flag + & HA_REVERSE_SORT); } ut_ad(key->flags & HA_FULLTEXT || !(index->type & DICT_FTS)); @@ -11598,6 +11556,8 @@ bool create_table_info_t::innobase_table_flags() /* Do a pre-check on FTS DOC ID index */ if (!(key->flags & HA_NOSAME) + || key->user_defined_key_parts != 1 + || (key->key_part[0].key_part_flag & HA_REVERSE_SORT) || strcmp(key->name.str, FTS_DOC_ID_INDEX_NAME) || strcmp(key->key_part[0].field->field_name.str, FTS_DOC_ID_COL_NAME)) { @@ -16839,7 +16799,8 @@ ha_innobase::cmp_ref( } if (result) { - + if (key_part->key_part_flag & HA_REVERSE_SORT) + result = -result; return(result); } @@ -17388,16 +17349,11 @@ static void innodb_buffer_pool_size_update(THD*,st_mysql_sys_var*,void*, const void* save) { - longlong in_val = *static_cast<const longlong*>(save); - snprintf(export_vars.innodb_buffer_pool_resize_status, sizeof(export_vars.innodb_buffer_pool_resize_status), - "Requested to resize buffer pool."); + "Buffer pool resize requested"); buf_resize_start(); - - ib::info() << export_vars.innodb_buffer_pool_resize_status - << " (new size: " << in_val << " bytes)"; } /** The latest assigned innodb_ft_aux_table name */ @@ -18296,31 +18252,22 @@ static my_bool innodb_buf_flush_list_now = TRUE; static uint innodb_merge_threshold_set_all_debug = DICT_INDEX_MERGE_THRESHOLD_DEFAULT; -/****************************************************************//** -Force innodb to checkpoint. */ +/** Force an InnoDB log checkpoint. */ static void -checkpoint_now_set(THD*, st_mysql_sys_var*, void*, const void* save) +checkpoint_now_set(THD*, st_mysql_sys_var*, void*, const void *save) { - if (*(my_bool*) save) { - mysql_mutex_unlock(&LOCK_global_system_variables); - - lsn_t lsn; - - while (log_sys.last_checkpoint_lsn.load( - std::memory_order_acquire) - + SIZE_OF_FILE_CHECKPOINT - < (lsn= log_sys.get_lsn(std::memory_order_acquire))) { - log_make_checkpoint(); - log_sys.log.flush(); - } - - if (dberr_t err = fil_write_flushed_lsn(lsn)) { - ib::warn() << "Checkpoint set failed " << err; - } + if (!*static_cast<const my_bool*>(save)) + return; + const auto size= log_sys.is_encrypted() + ? SIZE_OF_FILE_CHECKPOINT + 8 : SIZE_OF_FILE_CHECKPOINT; + mysql_mutex_unlock(&LOCK_global_system_variables); + lsn_t lsn; + while (log_sys.last_checkpoint_lsn.load(std::memory_order_acquire) + size < + (lsn= log_sys.get_lsn(std::memory_order_acquire))) + log_make_checkpoint(); - mysql_mutex_lock(&LOCK_global_system_variables); - } + mysql_mutex_lock(&LOCK_global_system_variables); } /****************************************************************//** @@ -18467,50 +18414,15 @@ buffer_pool_load_abort( } } -/****************************************************************//** -Update the system variable innodb_log_write_ahead_size using the "saved" -value. This function is registered as a callback with MySQL. */ -static -void -innodb_log_write_ahead_size_update( -/*===============================*/ - THD* thd, /*!< in: thread handle */ - st_mysql_sys_var*, void*, - const void* save) /*!< in: immediate result - from check function */ +#if defined __linux__ || defined _WIN32 +static void innodb_log_file_buffering_update(THD *thd, st_mysql_sys_var*, + void *, const void *save) { - ulong val = OS_FILE_LOG_BLOCK_SIZE; - ulong in_val = *static_cast<const ulong*>(save); - - while (val < in_val) { - val = val * 2; - } - - if (val > srv_page_size) { - val = srv_page_size; - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "innodb_log_write_ahead_size cannot" - " be set higher than innodb_page_size."); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "Setting innodb_log_write_ahead_size" - " to %lu", - srv_page_size); - } else if (val != in_val) { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "innodb_log_write_ahead_size should be" - " set 2^n value and larger than 512."); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "Setting innodb_log_write_ahead_size" - " to %lu", - val); - } - - srv_log_write_ahead_size = val; + mysql_mutex_unlock(&LOCK_global_system_variables); + log_sys.set_buffered(*static_cast<const my_bool*>(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } +#endif /** Update innodb_status_output or innodb_status_output_locks, which control InnoDB "status monitor" output to the error log. @@ -18744,7 +18656,7 @@ innobase_wsrep_set_checkpoint( if (wsrep_is_wsrep_xid(xid)) { trx_rseg_update_wsrep_checkpoint(xid); - innobase_flush_logs(hton, false); + log_buffer_flush_to_disk(srv_flush_log_at_trx_commit == 1); return 0; } else { return 1; @@ -18927,7 +18839,7 @@ static MYSQL_SYSVAR_ENUM(flush_method, srv_file_flush_method, static MYSQL_SYSVAR_STR(log_group_home_dir, srv_log_group_home_dir, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Path to InnoDB log files.", NULL, NULL, NULL); + "Path to ib_logfile0", NULL, NULL, NULL); static MYSQL_SYSVAR_DOUBLE(max_dirty_pages_pct, srv_max_buf_pool_modified_pct, PLUGIN_VAR_RQCMDARG, @@ -19062,13 +18974,13 @@ static MYSQL_SYSVAR_UINT(autoextend_increment, "Data file autoextend increment in megabytes", NULL, NULL, 64, 1, 1000, 0); -static MYSQL_SYSVAR_ULONG(buffer_pool_chunk_size, srv_buf_pool_chunk_unit, +static MYSQL_SYSVAR_SIZE_T(buffer_pool_chunk_size, srv_buf_pool_chunk_unit, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Size of a single memory chunk" - " for resizing buffer pool. Online buffer pool resizing happens" - " at this granularity. 0 means disable resizing buffer pool.", + " for resizing buffer pool. Online buffer pool resizing happens at this" + " granularity. 0 means autosize this variable based on buffer pool size.", NULL, NULL, - 128 * 1024 * 1024, 1024 * 1024, LONG_MAX, 1024 * 1024); + 0, 0, SIZE_T_MAX, 1024 * 1024); static MYSQL_SYSVAR_STR(buffer_pool_filename, srv_buf_dump_filename, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, @@ -19314,23 +19226,22 @@ static MYSQL_SYSVAR_ULONG(page_size, srv_page_size, NULL, NULL, UNIV_PAGE_SIZE_DEF, UNIV_PAGE_SIZE_MIN, UNIV_PAGE_SIZE_MAX, 0); -static MYSQL_SYSVAR_ULONG(log_buffer_size, srv_log_buffer_size, +static MYSQL_SYSVAR_SIZE_T(log_buffer_size, log_sys.buf_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "The size of the buffer which InnoDB uses to write log to the log files on disk.", - NULL, NULL, 16L << 20, 256L << 10, LONG_MAX, 1024); + "Redo log buffer size in bytes.", + NULL, NULL, 16U << 20, 2U << 20, SIZE_T_MAX, 4096); + +#if defined __linux__ || defined _WIN32 +static MYSQL_SYSVAR_BOOL(log_file_buffering, log_sys.log_buffered, + PLUGIN_VAR_OPCMDARG, + "Whether the file system cache for ib_logfile0 is enabled", + nullptr, innodb_log_file_buffering_update, FALSE); +#endif static MYSQL_SYSVAR_ULONGLONG(log_file_size, srv_log_file_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Size of each log file in a log group.", - NULL, NULL, 96 << 20, 1 << 20, std::numeric_limits<ulonglong>::max(), - UNIV_PAGE_SIZE_MAX); - -static MYSQL_SYSVAR_ULONG(log_write_ahead_size, srv_log_write_ahead_size, - PLUGIN_VAR_RQCMDARG, - "Redo log write ahead unit size to avoid read-on-write," - " it should match the OS cache block IO size", - NULL, innodb_log_write_ahead_size_update, - 8*1024L, OS_FILE_LOG_BLOCK_SIZE, UNIV_PAGE_SIZE_DEF, OS_FILE_LOG_BLOCK_SIZE); + "Redo log size in bytes.", + NULL, NULL, 96 << 20, 4 << 20, std::numeric_limits<ulonglong>::max(), 4096); static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct, PLUGIN_VAR_RQCMDARG, @@ -19769,8 +19680,10 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(deadlock_report), MYSQL_SYSVAR(page_size), MYSQL_SYSVAR(log_buffer_size), +#if defined __linux__ || defined _WIN32 + MYSQL_SYSVAR(log_file_buffering), +#endif MYSQL_SYSVAR(log_file_size), - MYSQL_SYSVAR(log_write_ahead_size), MYSQL_SYSVAR(log_group_home_dir), MYSQL_SYSVAR(max_dirty_pages_pct), MYSQL_SYSVAR(max_dirty_pages_pct_lwm), @@ -20897,7 +20810,7 @@ innodb_buffer_pool_size_validate( push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_WRONG_ARGUMENTS, "innodb_buffer_pool_size must be at least" - " innodb_buffer_pool_chunk_size=%lu", + " innodb_buffer_pool_chunk_size=%zu", srv_buf_pool_chunk_unit); /* nothing to do */ return(0); @@ -21242,12 +21155,12 @@ ulint buf_pool_size_align( ulint size) { - const ulong m = srv_buf_pool_chunk_unit; - size = ut_max((size_t) size, (size_t) MYSQL_SYSVAR_NAME(buffer_pool_size).min_val); + const size_t m = srv_buf_pool_chunk_unit; + size = ut_max(size, (size_t) MYSQL_SYSVAR_NAME(buffer_pool_size).min_val); if (size % m == 0) { return(size); } else { - return (ulint)((size / m + 1) * m); + return (size / m + 1) * m; } } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 1f46f66a1b7..d881a424946 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -3804,6 +3804,8 @@ innobase_create_index_field_def( index_field->col_no = key_part->fieldnr - num_v; } + index_field->descending= !!(key_part->key_part_flag & HA_REVERSE_SORT); + if (DATA_LARGE_MTYPE(col_type) || (key_part->length < field->pack_length() && field->type() != MYSQL_TYPE_VARCHAR) @@ -3905,6 +3907,7 @@ innobase_create_index_def( index->fields[0].col_no = key->key_part[0].fieldnr - num_v; index->fields[0].prefix_len = 0; index->fields[0].is_v_col = false; + index->fields[0].descending = false; /* Currently, the spatial index cannot be created on virtual columns. It is blocked in the SQL layer. */ @@ -3960,6 +3963,8 @@ innobase_fts_check_doc_id_index( if ((key.flags & HA_NOSAME) && key.user_defined_key_parts == 1 + && !(key.key_part[0].key_part_flag + & HA_REVERSE_SORT) && !strcmp(key.name.str, FTS_DOC_ID_INDEX_NAME) && !strcmp(key.key_part[0].field->field_name.str, FTS_DOC_ID_COL_NAME)) { @@ -3989,7 +3994,7 @@ innobase_fts_check_doc_id_index( } if (!dict_index_is_unique(index) - || dict_index_get_n_unique(index) > 1 + || dict_index_get_n_unique(index) != 1 || strcmp(index->name, FTS_DOC_ID_INDEX_NAME)) { return(FTS_INCORRECT_DOC_ID_INDEX); } @@ -4000,6 +4005,7 @@ innobase_fts_check_doc_id_index( /* The column would be of a BIGINT data type */ if (strcmp(field->name, FTS_DOC_ID_COL_NAME) == 0 + && !field->descending && field->col->mtype == DATA_INT && field->col->len == 8 && field->col->prtype & DATA_NOT_NULL @@ -4041,6 +4047,7 @@ innobase_fts_check_doc_id_index_in_def( named as "FTS_DOC_ID_INDEX" and on column "FTS_DOC_ID" */ if (!(key->flags & HA_NOSAME) || key->user_defined_key_parts != 1 + || (key->key_part[0].key_part_flag & HA_REVERSE_SORT) || strcmp(key->name.str, FTS_DOC_ID_INDEX_NAME) || strcmp(key->key_part[0].field->field_name.str, FTS_DOC_ID_COL_NAME)) { @@ -4238,6 +4245,7 @@ created_clustered: index->n_fields = 1; index->fields->col_no = fts_doc_id_col; index->fields->prefix_len = 0; + index->fields->descending = false; index->fields->is_v_col = false; index->ind_type = DICT_UNIQUE; ut_ad(!rebuild @@ -4847,7 +4855,8 @@ columns are removed from the PK; (3) Changing the order of existing PK columns; (4) Decreasing the prefix length just like removing existing PK columns follows rule(1), Increasing the prefix length just like adding existing -PK columns follows rule(2). +PK columns follows rule(2); +(5) Changing the ASC/DESC attribute of the existing PK columns. @param[in] col_map mapping of old column numbers to new ones @param[in] ha_alter_info Data used during in-place alter @param[in] old_clust_index index to be compared @@ -4940,10 +4949,16 @@ innobase_pk_order_preserved( continue; } + const dict_field_t &of = old_clust_index->fields[old_field]; + const dict_field_t &nf = new_clust_index->fields[new_field]; + + if (of.descending != nf.descending) { + return false; + } + /* Check prefix length change. */ const lint prefix_change = innobase_pk_col_prefix_compare( - new_clust_index->fields[new_field].prefix_len, - old_clust_index->fields[old_field].prefix_len); + nf.prefix_len, of.prefix_len); if (prefix_change < 0) { /* If a column's prefix length is decreased, it should @@ -9134,7 +9149,7 @@ innobase_rename_column_try( const char* to) { dberr_t error; - bool clust_has_prefixes = false; + bool clust_has_wide_format = false; DBUG_ENTER("innobase_rename_column_try"); @@ -9155,10 +9170,11 @@ innobase_rename_column_try( index != NULL; index = dict_table_get_next_index(index)) { - bool has_prefixes = false; + bool wide_format = false; for (size_t i = 0; i < dict_index_get_n_fields(index); i++) { - if (dict_index_get_nth_field(index, i)->prefix_len) { - has_prefixes = true; + dict_field_t* field= dict_index_get_nth_field(index, i); + if (field->prefix_len || field->descending) { + wide_format = true; break; } } @@ -9173,8 +9189,10 @@ innobase_rename_column_try( } pars_info_t* info = pars_info_create(); - ulint pos = has_prefixes ? i << 16 | f.prefix_len : i; - + ulint pos = wide_format + ? i << 16 | f.prefix_len + | !!f.descending << 15 + : i; pars_info_add_ull_literal(info, "indexid", index->id); pars_info_add_int4_literal(info, "nth", pos); pars_info_add_str_literal(info, "new", to); @@ -9194,15 +9212,16 @@ innobase_rename_column_try( goto err_exit; } - if (!has_prefixes || !clust_has_prefixes - || f.prefix_len) { + if (!wide_format || !clust_has_wide_format + || f.prefix_len || f.descending) { continue; } /* For secondary indexes, the - has_prefixes check can be 'polluted' - by PRIMARY KEY column prefix. Try also - the simpler encoding of SYS_FIELDS.POS. */ + wide_format check can be 'polluted' + by PRIMARY KEY column prefix or descending + field. Try also the simpler encoding + of SYS_FIELDS.POS. */ info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index->id); @@ -9224,7 +9243,7 @@ innobase_rename_column_try( } if (index == dict_table_get_first_index(ctx.old_table)) { - clust_has_prefixes = has_prefixes; + clust_has_wide_format = wide_format; } } diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 37b00a8ff21..792d8c84bcd 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -1632,6 +1632,7 @@ ibuf_entry_build( dfield_copy(field, entry_field); ifield = dict_index_get_nth_field(index, i); + ut_ad(!ifield->descending); /* Prefix index columns of fixed-length columns are of fixed length. However, in the function call below, dfield_get_type(entry_field) contains the fixed length @@ -2623,7 +2624,7 @@ static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash, ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER); const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER); const ulint len= rec_get_data_size_old(rec) - start; - const uint32_t fold= ut_crc32(rec + start, len); + const uint32_t fold= my_crc32c(0, rec + start, len); hash+= (fold / (CHAR_BIT * sizeof *hash)) % size; ulint bitmask= static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash))); @@ -3546,7 +3547,7 @@ ibuf_insert( ut_ad(dtuple_check_typed(entry)); ut_ad(page_id.space() != SRV_TMP_SPACE_ID); - + ut_ad(index->is_btree()); ut_a(!dict_index_is_clust(index)); ut_ad(!index->table->is_temporary()); diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 5b1c5c98e0b..24571483d05 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -787,7 +787,7 @@ public: { ut_ad(fsp_is_system_temporary(id().space())); ut_ad(in_file()); - ut_ad(!oldest_modification()); + ut_ad(!oldest_modification() || oldest_modification() == 2); oldest_modification_= 2; } @@ -1722,6 +1722,12 @@ public: FlushHp flush_hp; /** modified blocks (a subset of LRU) */ UT_LIST_BASE_NODE_T(buf_page_t) flush_list; + /** number of blocks ever added to flush_list; + sometimes protected by flush_list_mutex */ + size_t flush_list_requests; + + TPOOL_SUPPRESS_TSAN void add_flush_list_requests(size_t size) + { ut_ad(size); flush_list_requests+= size; } private: /** whether the page cleaner needs wakeup from indefinite sleep */ bool page_cleaner_is_idle; @@ -1732,7 +1738,7 @@ public: pthread_cond_t do_flush_list; /** @return whether the page cleaner must sleep due to being idle */ - bool page_cleaner_idle() const + bool page_cleaner_idle() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); return page_cleaner_is_idle; @@ -1857,24 +1863,31 @@ public: private: /** Remove a block from the flush list. */ - inline void delete_from_flush_list_low(buf_page_t *bpage); + inline void delete_from_flush_list_low(buf_page_t *bpage) noexcept; /** Remove a block from flush_list. @param bpage buffer pool page @param clear whether to invoke buf_page_t::clear_oldest_modification() */ - void delete_from_flush_list(buf_page_t *bpage, bool clear); + void delete_from_flush_list(buf_page_t *bpage, bool clear) noexcept; public: /** Remove a block from flush_list. @param bpage buffer pool page */ - void delete_from_flush_list(buf_page_t *bpage) + void delete_from_flush_list(buf_page_t *bpage) noexcept { delete_from_flush_list(bpage, true); } + /** Prepare to insert a modified blcok into flush_list. + @param lsn start LSN of the mini-transaction + @return insert position for insert_into_flush_list() */ + inline buf_page_t *prepare_insert_into_flush_list(lsn_t lsn) noexcept; + /** Insert a modified block into the flush list. + @param prev insert position (from prepare_insert_into_flush_list()) @param block modified block @param lsn start LSN of the mini-transaction that modified the block */ - void insert_into_flush_list(buf_block_t *block, lsn_t lsn); + inline void insert_into_flush_list(buf_page_t *prev, buf_block_t *block, + lsn_t lsn) noexcept; /** Free a page whose underlying file page has been freed. */ - inline void release_freed_page(buf_page_t *bpage); + inline void release_freed_page(buf_page_t *bpage) noexcept; private: /** Temporary memory for page_compressed and encrypted I/O */ diff --git a/storage/innobase/include/buf0buf.inl b/storage/innobase/include/buf0buf.inl index 3c4da98f83b..4516a24803c 100644 --- a/storage/innobase/include/buf0buf.inl +++ b/storage/innobase/include/buf0buf.inl @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2014, 2021, MariaDB Corporation. +Copyright (c) 2014, 2022, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -141,4 +141,3 @@ buf_block_get_modify_clock( ut_ad(block->page.lock.have_any()); return(block->modify_clock); } - diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 665fd1115e7..af38f61b13b 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2021, MariaDB Corporation. +Copyright (c) 2014, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -103,33 +103,6 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn); @param furious true=furious flushing, false=limit to innodb_io_capacity */ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious); -/********************************************************************//** -This function should be called at a mini-transaction commit, if a page was -modified in it. Puts the block to the list of modified blocks, if it not -already in it. */ -inline void buf_flush_note_modification(buf_block_t *b, lsn_t start, lsn_t end) -{ - ut_ad(!srv_read_only_mode); - ut_d(const auto s= b->page.state()); - ut_ad(s > buf_page_t::FREED); - ut_ad(s < buf_page_t::READ_FIX); - ut_ad(mach_read_from_8(b->page.frame + FIL_PAGE_LSN) <= end); - mach_write_to_8(b->page.frame + FIL_PAGE_LSN, end); - if (UNIV_LIKELY_NULL(b->page.zip.data)) - memcpy_aligned<8>(FIL_PAGE_LSN + b->page.zip.data, - FIL_PAGE_LSN + b->page.frame, 8); - - const lsn_t oldest_modification= b->page.oldest_modification(); - - if (oldest_modification > 1) - ut_ad(oldest_modification <= start); - else if (fsp_is_system_temporary(b->page.id().space())) - b->page.set_temp_modified(); - else - buf_pool.insert_into_flush_list(b, start); - srv_stats.buf_pool_write_requests.inc(); -} - /** Initialize page_cleaner. */ ATTRIBUTE_COLD void buf_flush_page_cleaner_init(); diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index 5eaad5bf552..a5356e0d1a3 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -316,16 +316,6 @@ dtuple_get_n_ext( /*=============*/ const dtuple_t* tuple) /*!< in: tuple */ MY_ATTRIBUTE((nonnull)); -/** Compare two data tuples. -@param[in] tuple1 first data tuple -@param[in] tuple2 second data tuple -@return positive, 0, negative if tuple1 is greater, equal, less, than tuple2, -respectively */ -int -dtuple_coll_cmp( - const dtuple_t* tuple1, - const dtuple_t* tuple2) - MY_ATTRIBUTE((warn_unused_result)); /** Fold a prefix given as the number of fields of a tuple. @param[in] tuple index record @param[in] n_fields number of complete fields to fold diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index f70e50f5d48..8daa07160a3 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1073,16 +1073,16 @@ dict_table_get_nth_col_pos( ulint n, /*!< in: column number */ ulint* prefix_col_pos) /*!< out: col num if prefix */ MY_ATTRIBUTE((nonnull(1), warn_unused_result)); -/*******************************************************************//** -Adds a column to index. */ -void -dict_index_add_col( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - const dict_table_t* table, /*!< in: table */ - dict_col_t* col, /*!< in: column */ - ulint prefix_len) /*!< in: column prefix length */ - MY_ATTRIBUTE((nonnull)); +/** Add a column to an index. +@param index index +@param table table +@param col column +@param prefix_len column prefix length +@param descending whether to use descending order */ +void dict_index_add_col(dict_index_t *index, const dict_table_t *table, + dict_col_t *col, ulint prefix_len, + bool descending= false) + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Copies types of fields contained in index to tuple. */ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 83987789bb5..da4c432e3f9 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -396,18 +396,7 @@ dict_mem_index_create( ulint type, /*!< in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */ ulint n_fields); /*!< in: number of fields */ -/**********************************************************************//** -Adds a field definition to an index. NOTE: does not take a copy -of the column name if the field is a column. The memory occupied -by the column name may be released only after publishing the index. */ -void -dict_mem_index_add_field( -/*=====================*/ - dict_index_t* index, /*!< in: index */ - const char* name, /*!< in: column name */ - ulint prefix_len); /*!< in: 0 or the column prefix length - in a MySQL index like - INDEX (textcol(25)) */ + /**********************************************************************//** Frees an index memory object. */ void @@ -886,9 +875,11 @@ struct dict_field_t{ unsigned fixed_len:10; /*!< 0 or the fixed length of the column if smaller than DICT_ANTELOPE_MAX_INDEX_COL_LEN */ + /** 1=DESC, 0=ASC */ + unsigned descending:1; /** Zero-initialize all fields */ - dict_field_t() : col(NULL), name(NULL), prefix_len(0), fixed_len(0) {} + dict_field_t() { memset((void*) this, 0, sizeof *this); } /** Check whether two index fields are equivalent. @param[in] old the other index field @@ -1475,6 +1466,21 @@ inline void dict_col_t::detach(const dict_index_t &index) reinterpret_cast<dict_v_col_t*>(this)->detach(index); } +/** Add a field definition to an index. +@param index index +@param name pointer to column name +@param prefix_len column prefix length, or 0 +@param descending whether to use descending order */ +inline void dict_mem_index_add_field(dict_index_t *index, const char *name, + ulint prefix_len, bool descending= false) +{ + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + dict_field_t &field= index->fields[index->n_def++]; + field.name= name; + field.prefix_len= prefix_len & ((1U << 12) - 1); + field.descending= descending; +} + /** The status of online index creation */ enum online_index_status { /** the index is complete and ready for access */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 3aeea21acf4..88de06a23d5 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -353,13 +353,10 @@ struct fil_space_t final /** fil_system.spaces chain node */ fil_space_t *hash; - lsn_t max_lsn; - /*!< LSN of the most recent - fil_names_write_if_was_clean(). - Reset to 0 by fil_names_clear(). - Protected by log_sys.mutex. - If and only if this is nonzero, the - tablespace will be in named_spaces. */ + /** LSN of the most recent fil_names_write_if_was_clean(). + Reset to 0 by fil_names_clear(). Protected by exclusive log_sys.latch. + If and only if max_lsn is nonzero, this is in fil_system.named_spaces. */ + lsn_t max_lsn; /** tablespace identifier */ uint32_t id; /** whether undo tablespace truncation is in progress */ @@ -427,9 +424,10 @@ private: /** Whether any corrupton of this tablespace has been reported */ mutable std::atomic_flag is_corrupted; +public: /** mutex to protect freed_ranges and last_freed_lsn */ std::mutex freed_range_mutex; - +private: /** Ranges of freed page numbers; protected by freed_range_mutex */ range_set freed_ranges; @@ -648,11 +646,7 @@ public: /** @return last_freed_lsn */ lsn_t get_last_freed_lsn() { return last_freed_lsn; } /** Update last_freed_lsn */ - void update_last_freed_lsn(lsn_t lsn) - { - std::lock_guard<std::mutex> freed_lock(freed_range_mutex); - last_freed_lsn= lsn; - } + void update_last_freed_lsn(lsn_t lsn) { last_freed_lsn= lsn; } /** Note that the file will need fsync(). @return whether this needs to be added to fil_system.unflushed_spaces */ @@ -673,11 +667,7 @@ public: /** Clear all freed ranges for undo tablespace when InnoDB encounters TRIM redo log record */ - void clear_freed_ranges() - { - std::lock_guard<std::mutex> freed_lock(freed_range_mutex); - freed_ranges.clear(); - } + void clear_freed_ranges() { freed_ranges.clear(); } #endif /* !UNIV_INNOCHECKSUM */ /** FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags; check fsp0types.h to more info about flags. */ @@ -950,7 +940,6 @@ public: /** Add the set of freed page ranges */ void add_free_range(const range_t range) { - std::lock_guard<std::mutex> freed_lock(freed_range_mutex); freed_ranges.add_range(range); } @@ -1053,7 +1042,7 @@ struct fil_node_t final { /** tablespace containing this file */ fil_space_t *space; - /** file name; protected by fil_system.mutex and log_sys.mutex */ + /** file name; protected by fil_system.mutex and exclusive log_sys.latch */ char *name; /** file handle */ pfs_os_file_t handle; @@ -1445,14 +1434,12 @@ public: /** nonzero if fil_node_open_file_low() should avoid moving the tablespace to the end of space_list, for FIFO policy of try_to_close() */ ulint freeze_space_list; + /** list of all tablespaces */ ilist<fil_space_t, space_list_tag_t> space_list; - /*!< list of all file spaces */ + /** list of all tablespaces for which a FILE_MODIFY record has been written + since the latest redo log checkpoint. + Protected only by exclusive log_sys.latch. */ ilist<fil_space_t, named_spaces_tag_t> named_spaces; - /*!< list of all file spaces - for which a FILE_MODIFY - record has been written since - the latest redo log checkpoint. - Protected only by log_sys.mutex. */ /** list of all ENCRYPTED=DEFAULT tablespaces that need to be converted to the current value of innodb_encrypt_tables */ @@ -1604,15 +1591,6 @@ Sets the max tablespace id counter if the given number is bigger than the previous value. */ void fil_set_max_space_id_if_bigger(uint32_t max_id); -/** Write the flushed LSN to the page header of the first page in the -system tablespace. -@param[in] lsn flushed LSN -@return DB_SUCCESS or error number */ -dberr_t -fil_write_flushed_lsn( - lsn_t lsn) -MY_ATTRIBUTE((warn_unused_result)); - MY_ATTRIBUTE((warn_unused_result)) /** Delete a tablespace and associated .ibd file. @param id tablespace identifier @@ -1781,50 +1759,14 @@ void fil_names_dirty( fil_space_t* space); -/** Write FILE_MODIFY records when a non-predefined persistent -tablespace was modified for the first time since the latest -fil_names_clear(). -@param[in,out] space tablespace */ -void fil_names_dirty_and_write(fil_space_t* space); - -/** Write FILE_MODIFY records if a persistent tablespace was modified -for the first time since the latest fil_names_clear(). -@param[in,out] space tablespace -@param[in,out] mtr mini-transaction -@return whether any FILE_MODIFY record was written */ -inline bool fil_names_write_if_was_clean(fil_space_t* space) -{ - mysql_mutex_assert_owner(&log_sys.mutex); - - if (space == NULL) { - return(false); - } - - const bool was_clean = space->max_lsn == 0; - ut_ad(space->max_lsn <= log_sys.get_lsn()); - space->max_lsn = log_sys.get_lsn(); - - if (was_clean) { - fil_names_dirty_and_write(space); - } - - return(was_clean); -} - bool fil_comp_algo_loaded(ulint comp_algo); /** On a log checkpoint, reset fil_names_dirty_and_write() flags -and write out FILE_MODIFY and FILE_CHECKPOINT if needed. -@param[in] lsn checkpoint LSN -@param[in] do_write whether to always write FILE_CHECKPOINT -@return whether anything was written to the redo log -@retval false if no flags were set and nothing written -@retval true if anything was written to the redo log */ -bool -fil_names_clear( - lsn_t lsn, - bool do_write); +and write out FILE_MODIFY if needed, and write FILE_CHECKPOINT. +@param lsn checkpoint LSN +@return current LSN */ +lsn_t fil_names_clear(lsn_t lsn); #ifdef UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH void test_make_filepath(); diff --git a/storage/innobase/include/fsp0file.h b/storage/innobase/include/fsp0file.h index 9dfb3cc7561..ce11b868bd1 100644 --- a/storage/innobase/include/fsp0file.h +++ b/storage/innobase/include/fsp0file.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, 2021, MariaDB Corporation. +Copyright (c) 2018, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -216,11 +216,10 @@ public: tablespace is opened. This occurs before the fil_space_t is created so the Space ID found here must not already be open. m_is_valid is set true on success, else false. - @param[out] flush_lsn contents of FIL_PAGE_FILE_FLUSH_LSN @retval DB_SUCCESS on if the datafile is valid @retval DB_CORRUPTION if the datafile is not readable @retval DB_TABLESPACE_EXISTS if there is a duplicate space_id */ - dberr_t validate_first_page(lsn_t* flush_lsn) + dberr_t validate_first_page() MY_ATTRIBUTE((warn_unused_result)); /** Get Datafile::m_filepath. diff --git a/storage/innobase/include/fsp0sysspace.h b/storage/innobase/include/fsp0sysspace.h index b6bdadd3501..514f3fdbf25 100644 --- a/storage/innobase/include/fsp0sysspace.h +++ b/storage/innobase/include/fsp0sysspace.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2021, MariaDB Corporation. +Copyright (c) 2016, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -151,20 +151,17 @@ public: @param[in] is_temp whether this is a temporary tablespace @param[in] create_new_db whether we are creating a new database @param[out] sum_new_sizes sum of sizes of the new files added - @param[out] flush_lsn FIL_PAGE_FILE_FLUSH_LSN of first file @return DB_SUCCESS or error code */ dberr_t open_or_create( bool is_temp, bool create_new_db, - ulint* sum_new_sizes, - lsn_t* flush_lsn) + ulint* sum_new_sizes) MY_ATTRIBUTE((warn_unused_result)); private: /** Check the tablespace header for this tablespace. - @param[out] flushed_lsn the value of FIL_PAGE_FILE_FLUSH_LSN @return DB_SUCCESS or error code */ - dberr_t read_lsn_and_check_flags(lsn_t* flushed_lsn); + inline dberr_t read_lsn_and_check_flags(); /** @return true if the last file size is valid. */ diff --git a/storage/innobase/include/ibuf0ibuf.inl b/storage/innobase/include/ibuf0ibuf.inl index 2c2620511c7..2d8265d2206 100644 --- a/storage/innobase/include/ibuf0ibuf.inl +++ b/storage/innobase/include/ibuf0ibuf.inl @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -130,12 +131,17 @@ ibuf_should_try( a secondary index when we decide */ { - return(innodb_change_buffering - && ibuf.max_size != 0 - && !dict_index_is_clust(index) - && !dict_index_is_spatial(index) - && index->table->quiesce == QUIESCE_NONE - && (ignore_sec_unique || !dict_index_is_unique(index))); + if (!innodb_change_buffering || !ibuf.max_size || index->is_clust() || + index->is_spatial()) + return false; + if (!ignore_sec_unique && index->is_unique()) + return false; + if (index->table->quiesce != QUIESCE_NONE) + return false; + for (unsigned i= 0; i < index->n_fields; i++) + if (index->fields[i].descending) + return false; + return true; } /******************************************************************//** diff --git a/storage/innobase/include/log0crypt.h b/storage/innobase/include/log0crypt.h index b9390927ece..22c0c9636bf 100644 --- a/storage/innobase/include/log0crypt.h +++ b/storage/innobase/include/log0crypt.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. -Copyright (C) 2014, 2021, MariaDB Corporation. +Copyright (C) 2014, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -24,27 +24,26 @@ Created 11/25/2013 Minli Zhu Modified Jan Lindström jan.lindstrom@mariadb.com MDEV-11782: Rewritten for MariaDB 10.2 by Marko Mäkelä, MariaDB Corporation. *******************************************************/ -#ifndef log0crypt_h -#define log0crypt_h +#pragma once #include "log0log.h" -/** innodb_encrypt_log: whether to encrypt the redo log */ -extern my_bool srv_encrypt_log; - /** Initialize the redo log encryption key and random parameters when creating a new redo log. -The random parameters will be persisted in the log checkpoint pages. -@see log_crypt_write_checkpoint_buf() -@see log_crypt_read_checkpoint_buf() +The random parameters will be persisted in the log header. +@see log_crypt_write_header() +@see log_crypt_read_header() @return whether the operation succeeded */ bool log_crypt_init(); -/*********************************************************************//** -Writes the crypto (version, msg and iv) info, which has been used for -log blocks with lsn <= this checkpoint's lsn, to a log header's -checkpoint buf. */ -void log_crypt_write_checkpoint_buf(byte *buf); +/** Add the encryption information to the log header buffer. +@param buf part of log header buffer */ +void log_crypt_write_header(byte *buf); + +/** Read the encryption information from a redo log checkpoint buffer. +@param buf part of checkpoint buffer +@return whether the operation was successful */ +bool log_crypt_read_header(const byte *buf); /** Read the MariaDB 10.1 checkpoint crypto (version, msg and iv) info. @param[in] buf checkpoint buffer @@ -60,25 +59,28 @@ ATTRIBUTE_COLD bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn); /** Read the checkpoint crypto (version, msg and iv) info. @param[in] buf checkpoint buffer @return whether the operation was successful */ -bool log_crypt_read_checkpoint_buf(const byte* buf); - -/** log_crypt() operation code */ -enum log_crypt_t { - /** encrypt a log block without rotating key */ - LOG_ENCRYPT, - /** decrypt a log block */ - LOG_DECRYPT, - /** attempt to rotate the key, and encrypt a log block */ - LOG_ENCRYPT_ROTATE_KEY -}; - -/** Encrypt or decrypt log blocks. -@param[in,out] buf log blocks to encrypt or decrypt +ATTRIBUTE_COLD bool log_crypt_read_checkpoint_buf(const byte* buf); + +/** Decrypt log blocks. +@param[in,out] buf log blocks to decrypt @param[in] lsn log sequence number of the start of the buffer @param[in] size size of the buffer, in bytes -@param[in] op whether to decrypt, encrypt, or rotate key and encrypt -@return whether the operation succeeded (encrypt always does) */ -bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op = LOG_ENCRYPT); +@return whether the operation succeeded */ +ATTRIBUTE_COLD bool log_decrypt(byte* buf, lsn_t lsn, ulint size); + +/** Decrypt part of a log record. +@param iv initialization vector +@param buf buffer for the decrypted data +@param data the encrypted data +@param len length of the data, in bytes +@return buf */ +byte *log_decrypt_buf(const byte *iv, byte *buf, const byte *data, uint len); + +/** Decrypt a log snippet. +@param iv initialization vector +@param buf buffer to be replaced with encrypted contents +@param end pointer past the end of buf */ +void log_decrypt_buf(const byte *iv, byte *buf, const byte *const end); /** Encrypt or decrypt a temporary file block. @param[in] src block to encrypt or decrypt @@ -111,7 +113,3 @@ log_tmp_block_decrypt( { return(log_tmp_block_encrypt(src, size, dst, offs, false)); } - -/** @return whether temporary files are encrypted */ -inline bool log_tmp_is_encrypted() { return srv_encrypt_log; } -#endif // log0crypt.h diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 629ddacdf1b..ef4465c41cd 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2009, Google Inc. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -31,14 +31,13 @@ Database log Created 12/9/1995 Heikki Tuuri *******************************************************/ -#ifndef log0log_h -#define log0log_h +#pragma once #include "log0types.h" #include "os0file.h" #include "span.h" #include "my_atomic_wrapper.h" -#include <vector> +#include "srw_lock.h" #include <string> using st_::span; @@ -51,77 +50,34 @@ static const char LOG_FILE_NAME[] = "ib_logfile0"; @return path with log file name*/ std::string get_log_file_path(const char *filename= LOG_FILE_NAME); -/** Returns paths for all existing log files */ -std::vector<std::string> get_existing_log_files_paths(); - /** Delete log file. @param[in] suffix suffix of the file name */ static inline void delete_log_file(const char* suffix) { auto path = get_log_file_path(LOG_FILE_NAME_PREFIX).append(suffix); - os_file_delete_if_exists(innodb_log_file_key, path.c_str(), nullptr); + os_file_delete_if_exists_func(path.c_str(), nullptr); } -/** Append a string to the log. -@param[in] str string -@param[in] len string length -@param[out] start_lsn start LSN of the log record -@return end lsn of the log record, zero if did not succeed */ -UNIV_INLINE -lsn_t -log_reserve_and_write_fast( - const void* str, - ulint len, - lsn_t* start_lsn); -/***********************************************************************//** -Checks if there is need for a log buffer flush or a new checkpoint, and does -this if yes. Any database operation should call this when it has modified -more than about 4 pages. NOTE that this function may only be called when the -OS thread owns no synchronization objects except dict_sys.latch. */ -UNIV_INLINE -void -log_free_check(void); -/*================*/ - -/** Extends the log buffer. -@param[in] len requested minimum size in bytes */ -void log_buffer_extend(ulong len); - -/** Calculate the recommended highest values for lsn - last_checkpoint_lsn -and lsn - buf_pool.get_oldest_modification(). -@param[in] file_size requested innodb_log_file_size -@retval true on success -@retval false if the smallest log is too small to -accommodate the number of OS threads in the database server */ -bool -log_set_capacity(ulonglong file_size) - MY_ATTRIBUTE((warn_unused_result)); +struct completion_callback; -/** -Ensure that the log has been written to the log file up to a given +/** Ensure that the log has been written to the log file up to a given log entry (such as that of a transaction commit). Start a new write, or wait and check if an already running write is covering the request. -@param[in] lsn log sequence number that should be -included in the redo log file write -@param[in] flush_to_disk whether the written log should also -be flushed to the file system -@param[in] rotate_key whether to rotate the encryption key -@param[in] cb completion callback. If not NULL, the callback will be called - whenever lsn is written or flushed. -*/ -struct completion_callback; -void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key = false, - const completion_callback* cb=nullptr); +@param lsn log sequence number that should be included in the file write +@param durable whether the write needs to be durable +@param callback log write completion callback */ +void log_write_up_to(lsn_t lsn, bool durable, + const completion_callback *callback= nullptr); /** Write to the log file up to the last log entry. -@param sync whether to wait for a durable write to complete */ -void log_buffer_flush_to_disk(bool sync= true); +@param durable whether to wait for a durable write to complete */ +void log_buffer_flush_to_disk(bool durable= true); -/** Prepare to invoke log_write_and_flush(), before acquiring log_sys.mutex. */ +/** Prepare to invoke log_write_and_flush(), before acquiring log_sys.latch. */ ATTRIBUTE_COLD void log_write_and_flush_prepare(); -/** Durably write the log up to log_sys.lsn() and release log_sys.mutex. */ +/** Durably write the log up to log_sys.get_lsn(). */ ATTRIBUTE_COLD void log_write_and_flush(); /** Make a checkpoint */ @@ -130,10 +86,6 @@ ATTRIBUTE_COLD void log_make_checkpoint(); /** Make a checkpoint at the latest lsn on shutdown. */ ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown(); -/** Write checkpoint info to the log header and release log_sys.mutex. -@param[in] end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */ -ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn); - /** Checks that there is enough free space in the log to start a new query step. Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this @@ -141,175 +93,12 @@ function may only be called if the calling thread owns no synchronization objects! */ ATTRIBUTE_COLD void log_check_margins(); -/************************************************************//** -Gets a log block flush bit. -@return TRUE if this block was the first to be written in a log flush */ -UNIV_INLINE -ibool -log_block_get_flush_bit( -/*====================*/ - const byte* log_block); /*!< in: log block */ -/************************************************************//** -Gets a log block number stored in the header. -@return log block number stored in the block header */ -UNIV_INLINE -ulint -log_block_get_hdr_no( -/*=================*/ - const byte* log_block); /*!< in: log block */ -/************************************************************//** -Gets a log block data length. -@return log block data length measured as a byte offset from the block start */ -UNIV_INLINE -ulint -log_block_get_data_len( -/*===================*/ - const byte* log_block); /*!< in: log block */ -/************************************************************//** -Sets the log block data length. */ -UNIV_INLINE -void -log_block_set_data_len( -/*===================*/ - byte* log_block, /*!< in/out: log block */ - ulint len); /*!< in: data length */ -/** Calculate the CRC-32C checksum of a log block. -@param[in] block log block -@return checksum */ -inline ulint log_block_calc_checksum_crc32(const byte* block); - -/************************************************************//** -Gets a log block checksum field value. -@return checksum */ -UNIV_INLINE -ulint -log_block_get_checksum( -/*===================*/ - const byte* log_block); /*!< in: log block */ -/************************************************************//** -Sets a log block checksum field value. */ -UNIV_INLINE -void -log_block_set_checksum( -/*===================*/ - byte* log_block, /*!< in/out: log block */ - ulint checksum); /*!< in: checksum */ -/************************************************************//** -Gets a log block first mtr log record group offset. -@return first mtr log record group byte offset from the block start, 0 -if none */ -UNIV_INLINE -ulint -log_block_get_first_rec_group( -/*==========================*/ - const byte* log_block); /*!< in: log block */ -/************************************************************//** -Sets the log block first mtr log record group offset. */ -UNIV_INLINE -void -log_block_set_first_rec_group( -/*==========================*/ - byte* log_block, /*!< in/out: log block */ - ulint offset); /*!< in: offset, 0 if none */ -/************************************************************//** -Gets a log block checkpoint number field (4 lowest bytes). -@return checkpoint no (4 lowest bytes) */ -UNIV_INLINE -ulint -log_block_get_checkpoint_no( -/*========================*/ - const byte* log_block); /*!< in: log block */ -/************************************************************//** -Initializes a log block in the log buffer. */ -UNIV_INLINE -void -log_block_init( -/*===========*/ - byte* log_block, /*!< in: pointer to the log buffer */ - lsn_t lsn); /*!< in: lsn within the log block */ -/************************************************************//** -Converts a lsn to a log block number. -@return log block number, it is > 0 and <= 1G */ -UNIV_INLINE -ulint -log_block_convert_lsn_to_no( -/*========================*/ - lsn_t lsn); /*!< in: lsn of a byte within the block */ /******************************************************//** Prints info of the log. */ void log_print( /*======*/ FILE* file); /*!< in: file where to print */ -/**********************************************************************//** -Refreshes the statistics used to print per-second averages. */ -void -log_refresh_stats(void); -/*===================*/ - -/* The counting of lsn's starts from this value: this must be non-zero */ -#define LOG_START_LSN ((lsn_t) (16 * OS_FILE_LOG_BLOCK_SIZE)) - -/* Offsets of a log block header */ -#define LOG_BLOCK_HDR_NO 0 /* block number which must be > 0 and - is allowed to wrap around at 2G; the - highest bit is set to 1 if this is the - first log block in a log flush write - segment */ -#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000UL - /* mask used to get the highest bit in - the preceding field */ -#define LOG_BLOCK_HDR_DATA_LEN 4 /* number of bytes of log written to - this block */ -#define LOG_BLOCK_FIRST_REC_GROUP 6 /* offset of the first start of an - mtr log record group in this log block, - 0 if none; if the value is the same - as LOG_BLOCK_HDR_DATA_LEN, it means - that the first rec group has not yet - been catenated to this log block, but - if it will, it will start at this - offset; an archive recovery can - start parsing the log records starting - from this offset in this log block, - if value not 0 */ -#define LOG_BLOCK_CHECKPOINT_NO 8 /* 4 lower bytes of the value of - log_sys.next_checkpoint_no when the - log block was last written to: if the - block has not yet been written full, - this value is only updated before a - log buffer flush */ -#define LOG_BLOCK_HDR_SIZE 12 /* size of the log block header in - bytes */ - -#define LOG_BLOCK_KEY 4 /* encryption key version - before LOG_BLOCK_CHECKSUM; - after log_t::FORMAT_ENC_10_4 only */ -#define LOG_BLOCK_CHECKSUM 4 /* 4 byte checksum of the log block - contents; in InnoDB versions - < 3.23.52 this did not contain the - checksum but the same value as - LOG_BLOCK_HDR_NO */ - -/** Offsets inside the checkpoint pages (redo log format version 1) @{ */ -/** Checkpoint number */ -#define LOG_CHECKPOINT_NO 0 -/** Log sequence number up to which all changes have been flushed */ -#define LOG_CHECKPOINT_LSN 8 -/** Byte offset of the log record corresponding to LOG_CHECKPOINT_LSN */ -#define LOG_CHECKPOINT_OFFSET 16 -/** srv_log_buffer_size at the time of the checkpoint (not used) */ -#define LOG_CHECKPOINT_LOG_BUF_SIZE 24 -/** MariaDB 10.2.5 encrypted redo log encryption key version (32 bits)*/ -#define LOG_CHECKPOINT_CRYPT_KEY 32 -/** MariaDB 10.2.5 encrypted redo log random nonce (32 bits) */ -#define LOG_CHECKPOINT_CRYPT_NONCE 36 -/** MariaDB 10.2.5 encrypted redo log random message (MY_AES_BLOCK_SIZE) */ -#define LOG_CHECKPOINT_CRYPT_MESSAGE 40 -/** start LSN of the MLOG_CHECKPOINT mini-transaction corresponding -to this checkpoint, or 0 if the information has not been written */ -#define LOG_CHECKPOINT_END_LSN OS_FILE_LOG_BLOCK_SIZE - 16 - -/* @} */ /** Offsets of a log file header */ /* @{ */ @@ -317,12 +106,6 @@ to this checkpoint, or 0 if the information has not been written */ This used to be called LOG_GROUP_ID and always written as 0, because InnoDB never supported more than one copy of the redo log. */ #define LOG_HEADER_FORMAT 0 -/** Redo log subformat (originally 0). In format version 0, the -LOG_FILE_START_LSN started here, 4 bytes earlier than LOG_HEADER_START_LSN, -which the LOG_FILE_START_LSN was renamed to. -Subformat 1 is for the fully redo-logged TRUNCATE -(no MLOG_TRUNCATE records or extra log checkpoints or log file) */ -#define LOG_HEADER_SUBFORMAT 4 /** LSN of the start of data in this log file (with format version 1; in format version 0, it was called LOG_FILE_START_LSN and at offset 4). */ #define LOG_HEADER_START_LSN 8 @@ -331,123 +114,69 @@ and the creation time if the log file was created by mysqlbackup --restore, or the MySQL version that created the redo log file. */ #define LOG_HEADER_CREATOR 16 /** End of the log file creator field. */ -#define LOG_HEADER_CREATOR_END (LOG_HEADER_CREATOR + 32) -/** Contents of the LOG_HEADER_CREATOR field */ -#define LOG_HEADER_CREATOR_CURRENT \ - "MariaDB " \ - IB_TO_STR(MYSQL_VERSION_MAJOR) "." \ - IB_TO_STR(MYSQL_VERSION_MINOR) "." \ - IB_TO_STR(MYSQL_VERSION_PATCH) - +#define LOG_HEADER_CREATOR_END 48 /* @} */ -#define LOG_CHECKPOINT_1 OS_FILE_LOG_BLOCK_SIZE - /* first checkpoint field in the log - header; we write alternately to the - checkpoint fields when we make new - checkpoints; this field is only defined - in the first log file of a log */ -#define LOG_CHECKPOINT_2 (3 * OS_FILE_LOG_BLOCK_SIZE) - /* second checkpoint field in the log - header */ -#define LOG_FILE_HDR_SIZE (4 * OS_FILE_LOG_BLOCK_SIZE) - -/** Abstraction for reading, writing and flushing file cache to disk */ -class file_io -{ -public: - file_io(bool durable_writes= false) : m_durable_writes(durable_writes) {} - virtual ~file_io() noexcept {}; - virtual dberr_t open(const char *path, bool read_only) noexcept= 0; - virtual dberr_t rename(const char *old_path, - const char *new_path) noexcept= 0; - virtual dberr_t close() noexcept= 0; - virtual dberr_t read(os_offset_t offset, span<byte> buf) noexcept= 0; - virtual dberr_t write(const char *path, os_offset_t offset, - span<const byte> buf) noexcept= 0; - virtual dberr_t flush() noexcept= 0; - - /** Durable writes doesn't require calling flush() */ - bool writes_are_durable() const noexcept { return m_durable_writes; } - -protected: - bool m_durable_writes; -}; +struct log_t; -class file_os_io final: public file_io -{ -public: - file_os_io()= default; - file_os_io(const file_os_io &)= delete; - file_os_io &operator=(const file_os_io &)= delete; - file_os_io(file_os_io &&rhs); - file_os_io &operator=(file_os_io &&rhs); - ~file_os_io() noexcept; - - dberr_t open(const char *path, bool read_only) noexcept final; - bool is_opened() const noexcept { return m_fd != OS_FILE_CLOSED; } - dberr_t rename(const char *old_path, const char *new_path) noexcept final; - dberr_t close() noexcept final; - dberr_t read(os_offset_t offset, span<byte> buf) noexcept final; - dberr_t write(const char *path, os_offset_t offset, - span<const byte> buf) noexcept final; - dberr_t flush() noexcept final; - -private: - pfs_os_file_t m_fd{OS_FILE_CLOSED}; -}; - -/** File abstraction + path */ +/** File abstraction */ class log_file_t { + friend log_t; + os_file_t m_file{OS_FILE_CLOSED}; public: - log_file_t(std::string path= "") noexcept : m_path{std::move(path)} {} - - dberr_t open(bool read_only) noexcept; - bool is_opened() const noexcept; + log_file_t()= default; + log_file_t(os_file_t file) noexcept : m_file(file) {} - const std::string &get_path() const noexcept { return m_path; } + /** Open a file + @return file size in bytes + @retval 0 if not readable */ + os_offset_t open(bool read_only) noexcept; + bool is_opened() const noexcept { return m_file != OS_FILE_CLOSED; } - dberr_t rename(std::string new_path) noexcept; dberr_t close() noexcept; dberr_t read(os_offset_t offset, span<byte> buf) noexcept; - bool writes_are_durable() const noexcept; - dberr_t write(os_offset_t offset, span<const byte> buf) noexcept; - dberr_t flush() noexcept; - void free() - { - m_path.clear(); - m_path.shrink_to_fit(); - } - -private: - std::unique_ptr<file_io> m_file; - std::string m_path; + void write(os_offset_t offset, span<const byte> buf) noexcept; + bool flush() const noexcept { return os_file_flush(m_file); } +#ifdef HAVE_PMEM + byte *mmap(bool read_only, const struct stat &st) noexcept; +#endif }; /** Redo log buffer */ -struct log_t{ +struct log_t +{ /** The original (not version-tagged) InnoDB redo log format */ - static constexpr uint32_t FORMAT_3_23 = 0; + static constexpr uint32_t FORMAT_3_23= 0; /** The MySQL 5.7.9/MariaDB 10.2.2 log format */ - static constexpr uint32_t FORMAT_10_2 = 1; - /** The MariaDB 10.3.2 log format. - To prevent crash-downgrade to earlier 10.2 due to the inability to - roll back a retroactively introduced TRX_UNDO_RENAME_TABLE undo log record, - MariaDB 10.2.18 and later will use the 10.3 format, but LOG_HEADER_SUBFORMAT - 1 instead of 0. MariaDB 10.3 will use subformat 0 (5.7-style TRUNCATE) or 2 - (MDEV-13564 backup-friendly TRUNCATE). */ - static constexpr uint32_t FORMAT_10_3 = 103; + static constexpr uint32_t FORMAT_10_2= 1; + /** The MariaDB 10.3.2 log format. */ + static constexpr uint32_t FORMAT_10_3= 103; /** The MariaDB 10.4.0 log format. */ - static constexpr uint32_t FORMAT_10_4 = 104; + static constexpr uint32_t FORMAT_10_4= 104; /** Encrypted MariaDB redo log */ - static constexpr uint32_t FORMAT_ENCRYPTED = 1U << 31; + static constexpr uint32_t FORMAT_ENCRYPTED= 1U << 31; /** The MariaDB 10.4.0 log format (only with innodb_encrypt_log=ON) */ - static constexpr uint32_t FORMAT_ENC_10_4 = FORMAT_10_4 | FORMAT_ENCRYPTED; - /** The MariaDB 10.5 physical redo log format */ - static constexpr uint32_t FORMAT_10_5 = 0x50485953; - /** The MariaDB 10.5 physical format (only with innodb_encrypt_log=ON) */ - static constexpr uint32_t FORMAT_ENC_10_5 = FORMAT_10_5 | FORMAT_ENCRYPTED; + static constexpr uint32_t FORMAT_ENC_10_4= FORMAT_10_4 | FORMAT_ENCRYPTED; + /** The MariaDB 10.5.1 physical redo log format */ + static constexpr uint32_t FORMAT_10_5= 0x50485953; + /** The MariaDB 10.5.1 physical format (only with innodb_encrypt_log=ON) */ + static constexpr uint32_t FORMAT_ENC_10_5= FORMAT_10_5 | FORMAT_ENCRYPTED; + /** The MariaDB 10.8.0 variable-block-size redo log format */ + static constexpr uint32_t FORMAT_10_8= 0x50687973; + /** The MariaDB 10.8.0 format with innodb_encrypt_log=ON */ + static constexpr uint32_t FORMAT_ENC_10_8= FORMAT_10_8 | FORMAT_ENCRYPTED; + + /** Location of the first checkpoint block */ + static constexpr size_t CHECKPOINT_1= 4096; + /** Location of the second checkpoint block */ + static constexpr size_t CHECKPOINT_2= 8192; + /** Start of record payload */ + static constexpr lsn_t START_OFFSET= 12288; + + /** smallest possible log sequence number in the current format + (used to be 2048 before FORMAT_10_8). */ + static constexpr lsn_t FIRST_LSN= START_OFFSET; private: /** The log sequence number of the last change of durable InnoDB files */ @@ -459,127 +188,77 @@ private: preflush buffer pool pages, or initiate a log checkpoint. This must hold if lsn - last_checkpoint_lsn > max_checkpoint_age. */ std::atomic<bool> check_flush_or_checkpoint_; + + +#if defined(__aarch64__) +/* On ARM, we do more spinning */ +typedef srw_spin_lock log_rwlock_t; +#define LSN_LOCK_ATTR MY_MUTEX_INIT_FAST +#else +typedef srw_lock log_rwlock_t; +#define LSN_LOCK_ATTR nullptr +#endif + public: - /** mutex protecting the log */ - alignas(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t mutex; - /** first free offset within the log buffer in use */ - size_t buf_free; - /** recommended maximum size of buf, after which the buffer is flushed */ - size_t max_buf_free; - /** mutex to serialize access to the flush list when we are putting - dirty blocks in the list. The idea behind this mutex is to be able - to release log_sys.mutex during mtr_commit and still ensure that - insertions in the flush_list happen in the LSN order. */ - alignas(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t flush_order_mutex; - /** log_buffer, append data here */ + /** rw-lock protecting buf */ + alignas(CPU_LEVEL1_DCACHE_LINESIZE) log_rwlock_t latch; +private: + /** Last written LSN */ + lsn_t write_lsn; +public: + /** log record buffer, written to by mtr_t::commit() */ byte *buf; - /** log_buffer, writing data to file from this buffer. - Before flushing write_buf is swapped with flush_buf */ + /** buffer for writing data to ib_logfile0, or nullptr if is_pmem() + In write_buf(), buf and flush_buf are swapped */ byte *flush_buf; - /** Log file stuff. Protected by mutex. */ - struct file { - /** format of the redo log: e.g., FORMAT_10_5 */ - uint32_t format; - /** redo log subformat: 0 with separately logged TRUNCATE, - 2 with fully redo-logged TRUNCATE (1 in MariaDB 10.2) */ - uint32_t subformat; - /** individual log file size in bytes, including the header */ - lsn_t file_size; - private: - /** lsn used to fix coordinates within the log group */ - lsn_t lsn; - /** the byte offset of the above lsn */ - lsn_t lsn_offset; - /** log file */ - log_file_t fd; - - public: - /** used only in recovery: recovery scan succeeded up to this - lsn in this log group */ - lsn_t scanned_lsn; - - /** opens log file which must be closed prior this call */ - void open_file(std::string path); - /** writes header */ - void write_header_durable(lsn_t lsn); - /** opens log file which must be closed prior this call */ - dberr_t rename(std::string path) { return fd.rename(path); } - /** reads buffer from log file - @param[in] offset offset in log file - @param[in] buf buffer where to read */ - void read(os_offset_t offset, span<byte> buf); - /** Tells whether writes require calling flush() */ - bool writes_are_durable() const noexcept; - /** writes buffer to log file - @param[in] offset offset in log file - @param[in] buf buffer from which to write */ - void write(os_offset_t offset, span<byte> buf); - /** flushes OS page cache (excluding metadata!) for log file */ - void flush(); - /** closes log file */ - void close_file(); - - /** @return whether the redo log is encrypted */ - bool is_encrypted() const { return format & FORMAT_ENCRYPTED; } - /** @return whether the redo log is in the physical format */ - bool is_physical() const - { return (format & ~FORMAT_ENCRYPTED) == FORMAT_10_5; } - /** @return capacity in bytes */ - lsn_t capacity() const{ return file_size - LOG_FILE_HDR_SIZE; } - /** Calculate the offset of a log sequence number. - @param[in] lsn log sequence number - @return offset within the log */ - inline lsn_t calc_lsn_offset(lsn_t lsn) const; - inline lsn_t calc_lsn_offset_old(lsn_t lsn) const; - - /** Set the field values to correspond to a given lsn. */ - void set_fields(lsn_t lsn) - { - lsn_t c_lsn_offset = calc_lsn_offset(lsn); - set_lsn(lsn); - set_lsn_offset(c_lsn_offset); - } - - /** Read a log segment to log_sys.buf. - @param[in,out] start_lsn in: read area start, - out: the last read valid lsn - @param[in] end_lsn read area end - @return whether no invalid blocks (e.g checksum mismatch) were found */ - bool read_log_seg(lsn_t* start_lsn, lsn_t end_lsn); - - /** Initialize the redo log buffer. */ - void create(); - - /** Close the redo log buffer. */ - void close() { close_file(); } - void set_lsn(lsn_t a_lsn); - lsn_t get_lsn() const { return lsn; } - void set_lsn_offset(lsn_t a_lsn); - lsn_t get_lsn_offset() const { return lsn_offset; } - } log; - - /** The fields involved in the log buffer flush @{ */ - - size_t buf_next_to_write;/*!< first offset in the log buffer - where the byte content may not exist - written to file, e.g., the start - offset of a log record catenated - later; this is advanced when a flush - operation is completed to all the log - groups */ - lsn_t write_lsn; /*!< last written lsn */ - lsn_t current_flush_lsn;/*!< end lsn for the current running - write + flush operation */ - std::atomic<size_t> pending_flushes; /*!< system calls in progress */ - std::atomic<size_t> flushes; /*!< system calls counter */ - - ulint n_log_ios; /*!< number of log i/os initiated thus - far */ - ulint n_log_ios_old; /*!< number of log i/o's at the - previous printout */ - time_t last_printout_time;/*!< when log_print was last time - called */ - /* @} */ + /** number of std::swap(buf, flush_buf) and writes from buf to log; + protected by latch.wr_lock() */ + ulint write_to_log; + /** innodb_log_buffer_size (size of buf and flush_buf, in bytes) */ + size_t buf_size; + +private: + /** spin lock protecting lsn, buf_free in append_prepare() */ + alignas(CPU_LEVEL1_DCACHE_LINESIZE) pthread_mutex_t lsn_lock; + void init_lsn_lock() { pthread_mutex_init(&lsn_lock, LSN_LOCK_ATTR); } + void lock_lsn() { pthread_mutex_lock(&lsn_lock); } + void unlock_lsn() { pthread_mutex_unlock(&lsn_lock); } + void destroy_lsn_lock() { pthread_mutex_destroy(&lsn_lock); } + +public: + /** first free offset within buf use; protected by lsn_lock */ + Atomic_relaxed<size_t> buf_free; + /** number of write requests (to buf); protected by exclusive lsn_lock */ + ulint write_to_buf; + /** number of waits in append_prepare(); protected by lsn_lock */ + ulint waits; + /** recommended maximum size of buf, after which the buffer is flushed */ + size_t max_buf_free; + + /** log file size in bytes, including the header */ + lsn_t file_size; +private: + /** the log sequence number at the start of the log file */ + lsn_t first_lsn; +#if defined __linux__ || defined _WIN32 + /** The physical block size of the storage */ + uint32_t block_size; +#endif +public: + /** format of the redo log: e.g., FORMAT_10_8 */ + uint32_t format; + /** Log file */ + log_file_t log; +#if defined __linux__ || defined _WIN32 + /** whether file system caching is enabled for the log */ + my_bool log_buffered; +# ifdef _WIN32 + static constexpr bool log_maybe_unbuffered= true; +# else + /** whether file system caching may be disabled */ + bool log_maybe_unbuffered; +# endif +#endif /** Fields involved in checkpoints @{ */ lsn_t log_capacity; /*!< capacity of the log; if @@ -597,12 +276,12 @@ public: /*!< this is the maximum allowed value for lsn - last_checkpoint_lsn when a new query step is started */ - ib_uint64_t next_checkpoint_no; - /*!< next checkpoint number */ - /** latest completed checkpoint (protected by log_sys.mutex) */ + /** latest completed checkpoint (protected by latch.wr_lock()) */ Atomic_relaxed<lsn_t> last_checkpoint_lsn; - /** next checkpoint LSN (protected by log_sys.mutex) */ + /** next checkpoint LSN (protected by log_sys.latch) */ lsn_t next_checkpoint_lsn; + /** next checkpoint number (protected by latch.wr_lock()) */ + ulint next_checkpoint_no; /** whether a checkpoint is pending */ Atomic_relaxed<bool> checkpoint_pending; @@ -610,32 +289,68 @@ public: byte *checkpoint_buf; /* @} */ -private: - bool m_initialised; -public: - /** - Constructor. + bool is_initialised() const noexcept { return max_buf_free != 0; } - Some members may require late initialisation, thus we just mark object as - uninitialised. Real initialisation happens in create(). - */ - log_t(): m_initialised(false) {} +#ifdef HAVE_PMEM + bool is_pmem() const noexcept { return !flush_buf; } +#else + static constexpr bool is_pmem() { return false; } +#endif - /** @return whether the redo log is encrypted */ - bool is_encrypted() const { return(log.is_encrypted()); } - /** @return whether the redo log is in the physical format */ - bool is_physical() const { return log.is_physical(); } + bool is_opened() const noexcept { return log.is_opened(); } + + static constexpr bool resize_in_progress() { return false; } + + /** Rename a log file after resizing. + @return whether an error occurred */ + static bool rename_resized() noexcept; + +#if defined __linux__ || defined _WIN32 + /** Try to enable or disable file system caching (update log_buffered) */ + void set_buffered(bool buffered); +#endif + + void attach(log_file_t file, os_offset_t size); + + void close_file(); - bool is_initialised() const { return m_initialised; } + /** Calculate the checkpoint safety margins. */ + static void set_capacity(); lsn_t get_lsn(std::memory_order order= std::memory_order_relaxed) const { return lsn.load(order); } void set_lsn(lsn_t lsn) { this->lsn.store(lsn, std::memory_order_release); } - lsn_t get_flushed_lsn() const - { return flushed_to_disk_lsn.load(std::memory_order_acquire); } - void set_flushed_lsn(lsn_t lsn) - { flushed_to_disk_lsn.store(lsn, std::memory_order_release); } + lsn_t get_flushed_lsn(std::memory_order order= std::memory_order_acquire) + const noexcept + { return flushed_to_disk_lsn.load(order); } + + /** Initialize the LSN on initial log file creation. */ + lsn_t init_lsn() noexcept + { + latch.wr_lock(SRW_LOCK_CALL); + const lsn_t lsn{get_lsn()}; + flushed_to_disk_lsn.store(lsn, std::memory_order_relaxed); + write_lsn= lsn; + latch.wr_unlock(); + return lsn; + } + + void set_recovered_lsn(lsn_t lsn) noexcept + { +#ifndef SUX_LOCK_GENERIC + ut_ad(latch.is_write_locked()); +#endif /* SUX_LOCK_GENERIC */ + write_lsn= lsn; + this->lsn.store(lsn, std::memory_order_relaxed); + flushed_to_disk_lsn.store(lsn, std::memory_order_relaxed); + } + +#ifdef HAVE_PMEM + /** Persist the log. + @param lsn desired new value of flushed_to_disk_lsn */ + inline void persist(lsn_t lsn) noexcept; +#endif bool check_flush_or_checkpoint() const { @@ -645,96 +360,105 @@ public: void set_check_flush_or_checkpoint(bool flag= true) { check_flush_or_checkpoint_.store(flag, std::memory_order_relaxed); } - bool has_encryption_key_rotation() const { - return log.format == FORMAT_ENC_10_4 || log.format == FORMAT_ENC_10_5; - } + /** Make previous write_buf() durable and update flushed_to_disk_lsn. */ + inline bool flush(lsn_t lsn) noexcept; - /** @return the log block header + trailer size */ - unsigned framing_size() const - { - return has_encryption_key_rotation() - ? LOG_BLOCK_HDR_SIZE + LOG_BLOCK_KEY + LOG_BLOCK_CHECKSUM - : LOG_BLOCK_HDR_SIZE + LOG_BLOCK_CHECKSUM; - } - /** @return the log block payload size */ - unsigned payload_size() const - { - return has_encryption_key_rotation() - ? OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE - LOG_BLOCK_CHECKSUM - - LOG_BLOCK_KEY - : OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE - LOG_BLOCK_CHECKSUM; - } - /** @return the log block trailer offset */ - unsigned trailer_offset() const + /** Initialise the redo log subsystem. */ + void create(); + + /** Shut down the redo log subsystem. */ + void close(); + +#if defined __linux__ || defined _WIN32 + /** @return the physical block size of the storage */ + size_t get_block_size() const noexcept + { ut_ad(block_size); return block_size; } + /** Set the log block size for file I/O. */ + void set_block_size(uint32_t size) noexcept { block_size= size; } +#else + /** @return the physical block size of the storage */ + static size_t get_block_size() { return 512; } +#endif + +private: + /** Wait in append_prepare() for buffer to become available + @param ex whether log_sys.latch is exclusively locked */ + ATTRIBUTE_COLD static void append_prepare_wait(bool ex) noexcept; +public: + /** Reserve space in the log buffer for appending data. + @tparam pmem log_sys.is_pmem() + @param size total length of the data to append(), in bytes + @param ex whether log_sys.latch is exclusively locked + @return the start LSN and the buffer position for append() */ + template<bool pmem> + inline std::pair<lsn_t,byte*> append_prepare(size_t size, bool ex) noexcept; + + /** Append a string of bytes to the redo log. + @param d destination + @param s string of bytes + @param size length of str, in bytes */ + void append(byte *&d, const void *s, size_t size) noexcept { - return has_encryption_key_rotation() - ? OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_CHECKSUM - LOG_BLOCK_KEY - : OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_CHECKSUM; +#ifndef SUX_LOCK_GENERIC + ut_ad(latch.is_locked()); +#endif + ut_ad(d + size <= buf + (is_pmem() ? file_size : buf_size)); + memcpy(d, s, size); + d+= size; } - size_t get_pending_flushes() const + /** Set the log file format. */ + void set_latest_format(bool encrypted) noexcept + { format= encrypted ? FORMAT_ENC_10_8 : FORMAT_10_8; } + /** @return whether the redo log is encrypted */ + bool is_encrypted() const noexcept { return format & FORMAT_ENCRYPTED; } + /** @return whether the redo log is in the latest format */ + bool is_latest() const noexcept + { return (~FORMAT_ENCRYPTED & format) == FORMAT_10_8; } + + /** @return capacity in bytes */ + lsn_t capacity() const noexcept { return file_size - START_OFFSET; } + + /** Set the LSN of the log file at file creation. */ + void set_first_lsn(lsn_t lsn) noexcept { write_lsn= first_lsn= lsn; } + /** @return the first LSN of the log file */ + lsn_t get_first_lsn() const noexcept { return first_lsn; } + + /** Determine the sequence bit at a log sequence number */ + byte get_sequence_bit(lsn_t lsn) const noexcept { - return pending_flushes.load(std::memory_order_relaxed); + ut_ad(lsn >= first_lsn); + return !(((lsn - first_lsn) / capacity()) & 1); } - size_t get_flushes() const + /** Calculate the offset of a log sequence number. + @param lsn log sequence number + @return byte offset within ib_logfile0 */ + lsn_t calc_lsn_offset(lsn_t lsn) const noexcept { - return flushes.load(std::memory_order_relaxed); + ut_ad(lsn >= first_lsn); + return START_OFFSET + (lsn - first_lsn) % capacity(); } - /** Initialise the redo log subsystem. */ - void create(); + /** Write checkpoint information and invoke latch.wr_unlock(). + @param end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */ + inline void write_checkpoint(lsn_t end_lsn) noexcept; - /** Shut down the redo log subsystem. */ - void close(); + /** Write buf to ib_logfile0. + @tparam release_latch whether to invoke latch.wr_unlock() + @return new write target + @retval 0 if everything was written */ + template<bool release_latch> inline lsn_t write_buf() noexcept; + + /** Create the log. */ + void create(lsn_t lsn) noexcept; }; /** Redo log system */ extern log_t log_sys; -#ifdef UNIV_DEBUG -extern bool log_write_lock_own(); -#endif - -/** Calculate the offset of a log sequence number. -@param[in] lsn log sequence number -@return offset within the log */ -inline lsn_t log_t::file::calc_lsn_offset(lsn_t lsn) const -{ - ut_ad(this == &log_sys.log); - /* The lsn parameters are updated while holding both the mutexes - and it is ok to have either of them while reading */ -#ifdef SAFE_MUTEX - ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own()); -#endif /* SAFE_MUTEX */ - const lsn_t size = capacity(); - lsn_t l= lsn - this->lsn; - if (longlong(l) < 0) { - l = lsn_t(-longlong(l)) % size; - l = size - l; - } - - l+= lsn_offset - LOG_FILE_HDR_SIZE * (1 + lsn_offset / file_size); - l %= size; - return l + LOG_FILE_HDR_SIZE * (1 + l / (file_size - LOG_FILE_HDR_SIZE)); -} -inline void log_t::file::set_lsn(lsn_t a_lsn) +inline void log_free_check() { -#ifdef SAFE_MUTEX - ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own()); -#endif /* SAFE_MUTEX */ - lsn= a_lsn; + if (log_sys.check_flush_or_checkpoint()) + log_check_margins(); } - -inline void log_t::file::set_lsn_offset(lsn_t a_lsn) -{ -#ifdef SAFE_MUTEX - ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own()); -#endif /* SAFE_MUTEX */ - ut_ad((lsn % OS_FILE_LOG_BLOCK_SIZE) == (a_lsn % OS_FILE_LOG_BLOCK_SIZE)); - lsn_offset= a_lsn; -} - -#include "log0log.inl" - -#endif diff --git a/storage/innobase/include/log0log.inl b/storage/innobase/include/log0log.inl deleted file mode 100644 index 73434737925..00000000000 --- a/storage/innobase/include/log0log.inl +++ /dev/null @@ -1,311 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/**************************************************//** -@file include/log0log.ic -Database log - -Created 12/9/1995 Heikki Tuuri -*******************************************************/ - -#include "mach0data.h" -#include "assume_aligned.h" -#include "ut0crc32.h" - -extern ulong srv_log_buffer_size; - -/************************************************************//** -Gets a log block flush bit. -@return TRUE if this block was the first to be written in a log flush */ -UNIV_INLINE -ibool -log_block_get_flush_bit( -/*====================*/ - const byte* log_block) /*!< in: log block */ -{ - static_assert(LOG_BLOCK_HDR_NO == 0, "compatibility"); - static_assert(LOG_BLOCK_FLUSH_BIT_MASK == 0x80000000, "compatibility"); - - return *log_block & 0x80; -} - -/************************************************************//** -Sets the log block flush bit. */ -UNIV_INLINE -void -log_block_set_flush_bit( -/*====================*/ - byte* log_block, /*!< in/out: log block */ - ibool val) /*!< in: value to set */ -{ - static_assert(LOG_BLOCK_HDR_NO == 0, "compatibility"); - static_assert(LOG_BLOCK_FLUSH_BIT_MASK == 0x80000000, "compatibility"); - - if (val) - *log_block|= 0x80; - else - *log_block&= 0x7f; -} - -/************************************************************//** -Gets a log block number stored in the header. -@return log block number stored in the block header */ -UNIV_INLINE -ulint -log_block_get_hdr_no( -/*=================*/ - const byte* log_block) /*!< in: log block */ -{ - static_assert(LOG_BLOCK_HDR_NO == 0, "compatibility"); - return mach_read_from_4(my_assume_aligned<4>(log_block)) & - ~LOG_BLOCK_FLUSH_BIT_MASK; -} - -/************************************************************//** -Sets the log block number stored in the header; NOTE that this must be set -before the flush bit! */ -UNIV_INLINE -void -log_block_set_hdr_no( -/*=================*/ - byte* log_block, /*!< in/out: log block */ - ulint n) /*!< in: log block number: must be > 0 and - < LOG_BLOCK_FLUSH_BIT_MASK */ -{ - static_assert(LOG_BLOCK_HDR_NO == 0, "compatibility"); - ut_ad(n > 0); - ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK); - - mach_write_to_4(my_assume_aligned<4>(log_block), n); -} - -/************************************************************//** -Gets a log block data length. -@return log block data length measured as a byte offset from the block start */ -UNIV_INLINE -ulint -log_block_get_data_len( -/*===================*/ - const byte* log_block) /*!< in: log block */ -{ - return mach_read_from_2(my_assume_aligned<2> - (log_block + LOG_BLOCK_HDR_DATA_LEN)); -} - -/************************************************************//** -Sets the log block data length. */ -UNIV_INLINE -void -log_block_set_data_len( -/*===================*/ - byte* log_block, /*!< in/out: log block */ - ulint len) /*!< in: data length */ -{ - mach_write_to_2(my_assume_aligned<2>(log_block + LOG_BLOCK_HDR_DATA_LEN), - len); -} - -/************************************************************//** -Gets a log block first mtr log record group offset. -@return first mtr log record group byte offset from the block start, 0 -if none */ -UNIV_INLINE -ulint -log_block_get_first_rec_group( -/*==========================*/ - const byte* log_block) /*!< in: log block */ -{ - return mach_read_from_2(my_assume_aligned<2> - (log_block + LOG_BLOCK_FIRST_REC_GROUP)); -} - -/************************************************************//** -Sets the log block first mtr log record group offset. */ -UNIV_INLINE -void -log_block_set_first_rec_group( -/*==========================*/ - byte* log_block, /*!< in/out: log block */ - ulint offset) /*!< in: offset, 0 if none */ -{ - mach_write_to_2(my_assume_aligned<2> - (log_block + LOG_BLOCK_FIRST_REC_GROUP), offset); -} - -/************************************************************//** -Gets a log block checkpoint number field (4 lowest bytes). -@return checkpoint no (4 lowest bytes) */ -UNIV_INLINE -ulint -log_block_get_checkpoint_no( -/*========================*/ - const byte* log_block) /*!< in: log block */ -{ - return mach_read_from_4(my_assume_aligned<4> - (log_block + LOG_BLOCK_CHECKPOINT_NO)); -} - -/************************************************************//** -Sets a log block checkpoint number field (4 lowest bytes). */ -UNIV_INLINE -void -log_block_set_checkpoint_no( -/*========================*/ - byte* log_block, /*!< in/out: log block */ - ib_uint64_t no) /*!< in: checkpoint no */ -{ - mach_write_to_4(my_assume_aligned<4>(log_block + LOG_BLOCK_CHECKPOINT_NO), - static_cast<uint32_t>(no)); -} - -/************************************************************//** -Converts a lsn to a log block number. -@return log block number, it is > 0 and <= 1G */ -UNIV_INLINE -ulint -log_block_convert_lsn_to_no( -/*========================*/ - lsn_t lsn) /*!< in: lsn of a byte within the block */ -{ - return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & - (DBUG_IF("innodb_small_log_block_no_limit") - ? 0xFUL : 0x3FFFFFFFUL)) + 1); -} - -/** Calculate the CRC-32C checksum of a log block. -@param[in] block log block -@return checksum */ -inline ulint log_block_calc_checksum_crc32(const byte* block) -{ - return ut_crc32(block, OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_CHECKSUM); -} - -/************************************************************//** -Gets a log block checksum field value. -@return checksum */ -UNIV_INLINE -ulint -log_block_get_checksum( -/*===================*/ - const byte* log_block) /*!< in: log block */ -{ - return mach_read_from_4(my_assume_aligned<4> - (OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_CHECKSUM + - log_block)); -} - -/************************************************************//** -Sets a log block checksum field value. */ -UNIV_INLINE -void -log_block_set_checksum( -/*===================*/ - byte* log_block, /*!< in/out: log block */ - ulint checksum) /*!< in: checksum */ -{ - mach_write_to_4(my_assume_aligned<4> - (OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_CHECKSUM + - log_block), checksum); -} - -/************************************************************//** -Initializes a log block in the log buffer. */ -UNIV_INLINE -void -log_block_init( -/*===========*/ - byte* log_block, /*!< in: pointer to the log buffer */ - lsn_t lsn) /*!< in: lsn within the log block */ -{ - ulint no; - - no = log_block_convert_lsn_to_no(lsn); - - log_block_set_hdr_no(log_block, no); - - log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE); - log_block_set_first_rec_group(log_block, 0); -} - -/** Append a string to the log. -@param[in] str string -@param[in] len string length -@param[out] start_lsn start LSN of the log record -@return end lsn of the log record, zero if did not succeed */ -UNIV_INLINE -lsn_t -log_reserve_and_write_fast( - const void* str, - ulint len, - lsn_t* start_lsn) -{ - mysql_mutex_assert_owner(&log_sys.mutex); - ut_ad(len > 0); - - const ulint data_len = len - + log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE; - - if (data_len >= log_sys.trailer_offset()) { - - /* The string does not fit within the current log block - or the log block would become full */ - - return(0); - } - - lsn_t lsn = log_sys.get_lsn(); - *start_lsn = lsn; - - memcpy(log_sys.buf + log_sys.buf_free, str, len); - - log_block_set_data_len( - reinterpret_cast<byte*>(ut_align_down( - log_sys.buf + log_sys.buf_free, - OS_FILE_LOG_BLOCK_SIZE)), - data_len); - - log_sys.buf_free += len; - - ut_ad(log_sys.buf_free <= size_t{srv_log_buffer_size}); - - lsn += len; - log_sys.set_lsn(lsn); - - return lsn; -} - -/***********************************************************************//** -Checks if there is need for a log buffer flush or a new checkpoint, and does -this if yes. Any database operation should call this when it has modified -more than about 4 pages. NOTE that this function may only be called when the -OS thread owns no synchronization objects except dict_sys.latch. */ -UNIV_INLINE -void -log_free_check(void) -/*================*/ -{ - /* During row_log_table_apply(), this function will be called while we - are holding some latches. This is OK, as long as we are not holding - any latches on buffer blocks. */ - - if (log_sys.check_flush_or_checkpoint()) { - - log_check_margins(); - } -} diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 6c47c135526..c661c52905b 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -37,13 +37,6 @@ Created 9/20/1997 Heikki Tuuri /** @return whether recovery is currently running. */ #define recv_recovery_is_on() UNIV_UNLIKELY(recv_sys.recovery_on) -/** Find the latest checkpoint in the log header. -@param[out] max_field LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 -@return error code or DB_SUCCESS */ -dberr_t -recv_find_max_checkpoint(ulint* max_field) - MY_ATTRIBUTE((nonnull, warn_unused_result)); - ATTRIBUTE_COLD MY_ATTRIBUTE((nonnull, warn_unused_result)) /** Apply any buffered redo log to a page that was just read from a data file. @param[in,out] space tablespace @@ -52,12 +45,9 @@ ATTRIBUTE_COLD MY_ATTRIBUTE((nonnull, warn_unused_result)) bool recv_recover_page(fil_space_t* space, buf_page_t* bpage); /** Start recovering from a redo log checkpoint. -@param[in] flush_lsn FIL_PAGE_FILE_FLUSH_LSN of first system tablespace page @return error code or DB_SUCCESS */ -dberr_t -recv_recovery_from_checkpoint_start( - lsn_t flush_lsn); +dberr_t recv_recovery_from_checkpoint_start(); /** Whether to store redo log records in recv_sys.pages */ enum store_t { @@ -70,17 +60,6 @@ enum store_t { }; -/** Adds data from a new log block to the parsing buffer of recv_sys if -recv_sys.parse_start_lsn is non-zero. -@param[in] log_block log block to add -@param[in] scanned_lsn lsn of how far we were able to find - data in this log block -@return true if more data added */ -bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn); - -/** Moves the parsing buffer data left to the buffer start */ -void recv_sys_justify_left_parsing_buf(); - /** Report an operation to create, delete, or rename a file during backup. @param[in] space_id tablespace identifier @param[in] type file operation redo log type @@ -228,35 +207,24 @@ private: during log scan or apply */ bool found_corrupt_fs; public: + /** @return maximum guaranteed size of a mini-transaction on recovery */ + static constexpr size_t MTR_SIZE_MAX{1U << 20}; + /** whether we are applying redo log records during crash recovery */ bool recovery_on; /** whether recv_recover_page(), invoked from buf_page_t::read_complete(), should apply log records*/ bool apply_log_recs; - byte* buf; /*!< buffer for parsing log records */ - ulint len; /*!< amount of data in buf */ - lsn_t parse_start_lsn; - /*!< this is the lsn from which we were able to - start parsing log records and adding them to - pages; zero if a suitable - start point not found yet */ - lsn_t scanned_lsn; - /*!< the log data has been scanned up to this - lsn */ - ulint scanned_checkpoint_no; - /*!< the log data has been scanned up to this - checkpoint number (lowest 4 bytes) */ - ulint recovered_offset; - /*!< start offset of non-parsed log records in - buf */ - lsn_t recovered_lsn; - /*!< the log records have been parsed up to - this lsn */ - lsn_t mlog_checkpoint_lsn; - /*!< the LSN of a FILE_CHECKPOINT - record, or 0 if none was parsed */ - /** the time when progress was last reported */ - time_t progress_time; + /** number of bytes in log_sys.buf */ + size_t len; + /** start offset of non-parsed log records in log_sys.buf */ + size_t offset; + /** log sequence number of the first non-parsed record */ + lsn_t lsn; + /** log sequence number at the end of the FILE_CHECKPOINT record, or 0 */ + lsn_t file_checkpoint; + /** the time when progress was last reported */ + time_t progress_time; using map = std::map<const page_id_t, page_recv_t, std::less<const page_id_t>, @@ -284,10 +252,10 @@ public: /** The contents of the doublewrite buffer */ recv_dblwr_t dblwr; - /** Last added LSN to pages. */ + /** Last added LSN to pages, before switching to STORE_NO */ lsn_t last_stored_lsn= 0; - void read(os_offset_t offset, span<byte> buf); + inline void read(os_offset_t offset, span<byte> buf); inline size_t files_size(); void close_files() { files.clear(); files.shrink_to_fit(); } @@ -313,17 +281,13 @@ private: from before MariaDB Server 10.5.1) */ std::vector<log_file_t> files; - void open_log_files_if_needed(); - /** Base node of the redo block list. List elements are linked via buf_block_t::unzip_LRU. */ UT_LIST_BASE_NODE_T(buf_block_t) blocks; public: /** Check whether the number of read redo log blocks exceeds the maximum. - Store last_stored_lsn if the recovery is not in the last phase. - @param[in,out] store whether to store page operations @return whether the memory is exhausted */ - inline bool is_memory_exhausted(store_t *store); + inline bool is_memory_exhausted(); /** Apply buffered log to persistent data pages. @param last_batch whether it is possible to write more redo log */ void apply(bool last_batch); @@ -343,22 +307,42 @@ public: bool is_initialised() const { return last_stored_lsn != 0; } + /** Find the latest checkpoint. + @return error code or DB_SUCCESS */ + dberr_t find_checkpoint(); + /** Register a redo log snippet for a page. @param it page iterator @param start_lsn start LSN of the mini-transaction @param lsn @see mtr_t::commit_lsn() - @param l redo log snippet @see log_t::FORMAT_10_5 + @param l redo log snippet @param len length of l, in bytes */ inline void add(map::iterator it, lsn_t start_lsn, lsn_t lsn, const byte *l, size_t len); - /** Parse and register one mini-transaction in log_t::FORMAT_10_5. - @param checkpoint_lsn the log sequence number of the latest checkpoint - @param store whether to store the records - @param apply whether to apply file-level log records - @return whether FILE_CHECKPOINT record was seen the first time, - or corruption was noticed */ - bool parse(lsn_t checkpoint_lsn, store_t *store, bool apply); + enum parse_mtr_result { OK, PREMATURE_EOF, GOT_EOF }; + +private: + /** Parse and register one log_t::FORMAT_10_8 mini-transaction. + @param store whether to store the records + @param l log data source */ + template<typename source> + inline parse_mtr_result parse(store_t store, source& l) noexcept; +public: + /** Parse and register one log_t::FORMAT_10_8 mini-transaction, + handling log_sys.is_pmem() buffer wrap-around. + @param store whether to store the records */ + static parse_mtr_result parse_mtr(store_t store) noexcept; + + /** Parse and register one log_t::FORMAT_10_8 mini-transaction, + handling log_sys.is_pmem() buffer wrap-around. + @param store whether to store the records */ + static parse_mtr_result parse_pmem(store_t store) noexcept +#ifdef HAVE_PMEM + ; +#else + { return parse_mtr(store); } +#endif /** Clear a fully processed set of stored redo log records. */ inline void clear(); @@ -441,20 +425,12 @@ extern bool recv_no_ibuf_operations; /** TRUE when recv_init_crash_recovery() has been called. */ extern bool recv_needed_recovery; #ifdef UNIV_DEBUG -/** TRUE if writing to the redo log (mtr_commit) is forbidden. -Protected by log_sys.mutex. */ -extern bool recv_no_log_write; +/** whether writing to the redo log is forbidden; +protected by exclusive log_sys.latch. */ +extern bool recv_no_log_write; #endif /* UNIV_DEBUG */ /** TRUE if buf_page_is_corrupted() should check if the log sequence number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by recv_recovery_from_checkpoint_start(). */ extern bool recv_lsn_checks_on; - -/** Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many -times! */ -#define RECV_PARSING_BUF_SIZE (2U << 20) - -/** Size of block reads when the log groups are scanned forward to do a -roll-forward */ -#define RECV_SCAN_SIZE (4U << srv_page_size_shift) diff --git a/storage/innobase/include/mtr0log.h b/storage/innobase/include/mtr0log.h index 093b706c1de..ca194f905b5 100644 --- a/storage/innobase/include/mtr0log.h +++ b/storage/innobase/include/mtr0log.h @@ -53,7 +53,8 @@ inline uint8_t mlog_decode_varint_length(byte first) @param log redo log record buffer @return the decoded integer @retval MLOG_DECODE_ERROR on error */ -inline uint32_t mlog_decode_varint(const byte* log) +template<typename byte_pointer> +inline uint32_t mlog_decode_varint(const byte_pointer log) { uint32_t i= *log; if (i < MIN_2BYTE) diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 7f9bf27c6fb..21d0cfbb5a1 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -111,10 +111,11 @@ struct mtr_t { /** Commit a mini-transaction that did not modify any pages, but generated some redo log on a higher level, such as FILE_MODIFY records and an optional FILE_CHECKPOINT marker. - The caller must hold log_sys.mutex. + The caller must hold exclusive log_sys.latch. This is to be used at log_checkpoint(). - @param checkpoint_lsn the log sequence number of a checkpoint, or 0 */ - void commit_files(lsn_t checkpoint_lsn= 0); + @param checkpoint_lsn the log sequence number of a checkpoint, or 0 + @return current LSN */ + lsn_t commit_files(lsn_t checkpoint_lsn= 0); /** @return mini-transaction savepoint (current size of m_memo) */ ulint get_savepoint() const { ut_ad(is_active()); return m_memo.size(); } @@ -329,12 +330,9 @@ public: /** @return true if we are inside the change buffer code */ bool is_inside_ibuf() const { return m_inside_ibuf; } - /** Note that pages has been trimed */ + /** Note that some pages have been freed */ void set_trim_pages() { m_trim_pages= true; } - /** @return true if pages has been trimed */ - bool is_trim_pages() { return m_trim_pages; } - /** Latch a buffer pool block. @param block block to be latched @param rw_latch RW_S_LATCH, RW_SX_LATCH, RW_X_LATCH, RW_NO_LATCH */ @@ -611,6 +609,9 @@ public: @return number of buffer count added by this mtr */ uint32_t get_fix_count(const buf_block_t *block) const; + /** Note that log_sys.latch is no longer being held exclusively. */ + void flag_wr_unlock() noexcept { ut_ad(m_latch_ex); m_latch_ex= false; } + /** type of page flushing is needed during commit() */ enum page_flush_ahead { @@ -623,6 +624,11 @@ public: }; private: + /** Handle any pages that were freed during the mini-transaction. */ + void process_freed_pages(); + /** Release modified pages when no log was written. */ + void release_unlogged(); + /** Log a write of a byte string to a page. @param block buffer page @param offset byte offset within page @@ -648,6 +654,13 @@ private: @param type extended record subtype; @see mrec_ext_t */ inline void log_write_extended(const buf_block_t &block, byte type); + /** Write a FILE_MODIFY record when a non-predefined persistent + tablespace was modified for the first time since fil_names_clear(). */ + ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void name_write(); + + /** Encrypt the log */ + ATTRIBUTE_NOINLINE void encrypt(); + /** Append the redo log records to the redo log buffer. @return {start_lsn,flush_ahead} */ std::pair<lsn_t,page_flush_ahead> do_write(); @@ -655,7 +668,7 @@ private: /** Append the redo log records to the redo log buffer. @param len number of bytes to write @return {start_lsn,flush_ahead} */ - inline std::pair<lsn_t,page_flush_ahead> finish_write(ulint len); + std::pair<lsn_t,page_flush_ahead> finish_write(size_t len); /** Release the resources */ inline void release_resources(); @@ -679,7 +692,7 @@ private: /** whether freeing_tree() has been called */ bool m_freeing_tree= false; #endif - +private: /** The page of the most recent m_log record written, or NULL */ const buf_page_t* m_last; /** The current byte offset in m_last, or 0 */ @@ -694,6 +707,9 @@ private: /** whether at least one previously clean buffer pool page was written to */ uint16_t m_made_dirty:1; + /** whether log_sys.latch is locked exclusively */ + uint16_t m_latch_ex:1; + /** whether change buffer is latched; only needed in non-debug builds to suppress some read-ahead operations, @see ibuf_inside() */ uint16_t m_inside_ibuf:1; @@ -701,6 +717,9 @@ private: /** whether the pages has been trimmed */ uint16_t m_trim_pages:1; + /** CRC-32C of m_log */ + uint32_t m_crc; + #ifdef UNIV_DEBUG /** Persistent user tablespace associated with the mini-transaction, or 0 (TRX_SYS_SPACE) if none yet */ diff --git a/storage/innobase/include/mtr0mtr.inl b/storage/innobase/include/mtr0mtr.inl index 75be7adc6a5..1368cca0efd 100644 --- a/storage/innobase/include/mtr0mtr.inl +++ b/storage/innobase/include/mtr0mtr.inl @@ -107,9 +107,8 @@ mtr_t::sx_latch_at_savepoint( mtr_memo_slot_t* slot = m_memo.at<mtr_memo_slot_t*>(savepoint); ut_ad(slot->object == block); - - /* == RW_NO_LATCH */ - ut_a(slot->type == MTR_MEMO_BUF_FIX); + ut_ad(slot->type == MTR_MEMO_BUF_FIX); /* == RW_NO_LATCH */ + slot->type = MTR_MEMO_PAGE_SX_FIX; block->page.lock.u_lock(); ut_ad(!block->page.is_io_fixed()); @@ -117,8 +116,6 @@ mtr_t::sx_latch_at_savepoint( if (!m_made_dirty) { m_made_dirty = is_block_dirtied(block); } - - slot->type = MTR_MEMO_PAGE_SX_FIX; } /** @@ -141,9 +138,8 @@ mtr_t::x_latch_at_savepoint( mtr_memo_slot_t* slot = m_memo.at<mtr_memo_slot_t*>(savepoint); ut_ad(slot->object == block); - - /* == RW_NO_LATCH */ - ut_a(slot->type == MTR_MEMO_BUF_FIX); + ut_ad(slot->type == MTR_MEMO_BUF_FIX); /* == RW_NO_LATCH */ + slot->type = MTR_MEMO_PAGE_X_FIX; block->page.lock.x_lock(); ut_ad(!block->page.is_io_fixed()); @@ -151,8 +147,6 @@ mtr_t::x_latch_at_savepoint( if (!m_made_dirty) { m_made_dirty = is_block_dirtied(block); } - - slot->type = MTR_MEMO_PAGE_X_FIX; } /** diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h index 7acc255da36..1de31126a88 100644 --- a/storage/innobase/include/mtr0types.h +++ b/storage/innobase/include/mtr0types.h @@ -52,17 +52,17 @@ enum mtr_log_t { /* A mini-transaction is a stream of records that is always terminated by -a NUL byte. The first byte of a mini-transaction record is never NUL, -but NUL bytes can occur within mini-transaction records. The first -bytes of each record will explicitly encode the length of the record. -NUL bytes also acts as padding in log blocks, that is, there can be -multiple sucessive NUL bytes between mini-transactions in a redo log -block. +a byte 0x00 or 0x01. The first byte of a mini-transaction record is +never one of these bytes, but these bytes can occur within mini-transaction +records. The first byte of the record would contain a record type, flags, and a part of length. The optional second byte of the record will contain more length. (Not needed for short records.) +For example, because the length of an INIT_PAGE record is 3 to 11 bytes, +the first byte will be 0x02 to 0x0a, indicating the number of subsequent bytes. + Bit 7 of the first byte of a redo log record is the same_page flag. If same_page=1, the record is referring to the same page as the previous record. Records that do not refer to data pages but to file @@ -187,8 +187,11 @@ A subsequent WRITE to the same page could be logged 0xb5 0x7f 0x23 0x34 0x56 0x78, meaning "same page, type code 3 (WRITE), 5 bytes to follow", "byte offset 0x7f"+0x60+2, bytes 0x23,0x34,0x56,0x78. -The end of the mini-transaction would be indicated by a NUL byte. -*/ +The end of the mini-transaction would be indicated by the end byte +0x00 or 0x01; @see log_sys.get_sequence_bit(). +If log_sys.is_encrypted(), that is followed by 8 bytes of nonce +(part of initialization vector). That will be followed by 4 bytes +of CRC-32C of the entire mini-tranasction, excluding the end byte. */ /** Redo log record types. These bit patterns (3 bits) will be written to the redo log file, so the existing codes or their interpretation on @@ -305,14 +308,16 @@ enum mfile_type_t FILE_RENAME = 0xa0, /** Modify a file. Followed by tablespace ID and the file name. */ FILE_MODIFY = 0xb0, - /** End-of-checkpoint marker. Followed by 2 dummy bytes of page identifier, - 8 bytes of LSN, and padded with a NUL; @see SIZE_OF_FILE_CHECKPOINT. */ + /** End-of-checkpoint marker, at the end of a mini-transaction. + Followed by 2 NUL bytes of page identifier and 8 bytes of LSN; + @see SIZE_OF_FILE_CHECKPOINT. + When all bytes are NUL, this is a dummy padding record. */ FILE_CHECKPOINT = 0xf0 }; /** Size of a FILE_CHECKPOINT record, including the trailing byte to -terminate the mini-transaction. */ -constexpr byte SIZE_OF_FILE_CHECKPOINT= 3/*type,page_id*/ + 8/*LSN*/ + 1; +terminate the mini-transaction and the CRC-32C. */ +constexpr byte SIZE_OF_FILE_CHECKPOINT= 3/*type,page_id*/ + 8/*LSN*/ + 1 + 4; #ifndef UNIV_INNOCHECKSUM /** Types for the mlock objects to store in the mtr_t::m_memo */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 40ffc4297ec..036ad502eb4 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -107,15 +107,6 @@ struct pfs_os_file_t #endif }; -/** The next value should be smaller or equal to the smallest sector size used -on any disk. A log block is required to be a portion of disk which is written -so that if the start and the end of a block get written to disk, then the -whole block gets written. This should be true even in most cases of a crash: -if this fails for a log block, then it is equivalent to a media failure in the -log. */ - -#define OS_FILE_LOG_BLOCK_SIZE 512U - /** Options for os_file_create_func @{ */ enum os_file_create_t { OS_FILE_OPEN = 51, /*!< to open an existing file (if @@ -464,7 +455,6 @@ bool os_file_close_func(os_file_t file); /* Keys to register InnoDB I/O with performance schema */ extern mysql_pfs_key_t innodb_data_file_key; -extern mysql_pfs_key_t innodb_log_file_key; extern mysql_pfs_key_t innodb_temp_file_key; /* Following four macros are instumentations to register diff --git a/storage/innobase/include/page0cur.inl b/storage/innobase/include/page0cur.inl index 8f69dc22878..d6bf2fdfe09 100644 --- a/storage/innobase/include/page0cur.inl +++ b/storage/innobase/include/page0cur.inl @@ -200,6 +200,7 @@ page_cur_tuple_insert( index, rec, *offsets, mtr); } - ut_ad(!rec || !cmp_dtuple_rec(tuple, rec, *offsets)); + ut_ad(!rec || !cmp_dtuple_rec(tuple, rec, index, *offsets)); return(rec); } + diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index 0ad42474f84..2978656b508 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -1092,7 +1092,7 @@ page_find_rec_with_heap_no( @param[in] page index tree leaf page @return the last record, not delete-marked @retval infimum record if all records are delete-marked */ -const rec_t *page_find_rec_max_not_deleted(const page_t *page); +const rec_t *page_find_rec_last_not_deleted(const page_t *page); #endif /* !UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/include/rem0cmp.h b/storage/innobase/include/rem0cmp.h index 6f2201971d1..3a30f5a92f3 100644 --- a/storage/innobase/include/rem0cmp.h +++ b/storage/innobase/include/rem0cmp.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -24,8 +24,7 @@ Comparison services for records Created 7/1/1994 Heikki Tuuri ************************************************************************/ -#ifndef rem0cmp_h -#define rem0cmp_h +#pragma once #include "data0data.h" #include "data0type.h" @@ -43,39 +42,40 @@ cmp_cols_are_equal( ibool check_charsets); /*!< in: whether to check charsets */ /** Compare two data fields. -@param[in] mtype main type -@param[in] prtype precise type -@param[in] data1 data field -@param[in] len1 length of data1 in bytes, or UNIV_SQL_NULL -@param[in] data2 data field -@param[in] len2 length of data2 in bytes, or UNIV_SQL_NULL +@param mtype main type +@param prtype precise type +@param descending whether to use descending order +@param data1 data field +@param len1 length of data1 in bytes, or UNIV_SQL_NULL +@param data2 data field +@param len2 length of data2 in bytes, or UNIV_SQL_NULL @return the comparison result of data1 and data2 @retval 0 if data1 is equal to data2 @retval negative if data1 is less than data2 @retval positive if data1 is greater than data2 */ -int -cmp_data_data( - ulint mtype, - ulint prtype, - const byte* data1, - ulint len1, - const byte* data2, - ulint len2) - MY_ATTRIBUTE((warn_unused_result)); +int cmp_data(ulint mtype, ulint prtype, bool descending, + const byte *data1, size_t len1, const byte *data2, size_t len2) + MY_ATTRIBUTE((warn_unused_result)); /** Compare two data fields. -@param[in] dfield1 data field; must have type field set -@param[in] dfield2 data field +@param dfield1 data field; must have type field set +@param dfield2 data field +@param descending whether to use descending order @return the comparison result of dfield1 and dfield2 @retval 0 if dfield1 is equal to dfield2 @retval negative if dfield1 is less than dfield2 @retval positive if dfield1 is greater than dfield2 */ -UNIV_INLINE -int -cmp_dfield_dfield( -/*==============*/ - const dfield_t* dfield1,/*!< in: data field; must have type field set */ - const dfield_t* dfield2);/*!< in: data field */ +inline int cmp_dfield_dfield(const dfield_t *dfield1, const dfield_t *dfield2, + bool descending= false) +{ + ut_ad(dfield_check_typed(dfield1)); + const dtype_t *type= dfield_get_type(dfield1); + return cmp_data(type->mtype, type->prtype, descending, + static_cast<const byte*>(dfield_get_data(dfield1)), + dfield_get_len(dfield1), + static_cast<const byte*>(dfield_get_data(dfield2)), + dfield_get_len(dfield2)); +} #ifdef UNIV_DEBUG /** Compare a GIS data tuple to a physical record. @@ -103,15 +103,15 @@ inline int cmp_geometry_field(const void *a, const void *b) double x2= mach_double_read(mbr2); if (x1 > x2) return 1; - if (x2 > x1) + if (x1 < x2) return -1; - double y1= mach_double_read(mbr1 + sizeof(double) * SPDIMS); - double y2= mach_double_read(mbr2 + sizeof(double) * SPDIMS); + x1= mach_double_read(mbr1 + sizeof(double) * SPDIMS); + x2= mach_double_read(mbr2 + sizeof(double) * SPDIMS); - if (y1 > y2) + if (x1 > x2) return 1; - if (y2 > y1) + if (x1 < x2) return -1; /* left lower corner (xmin, ymin) overlaps, now right upper corner */ @@ -120,41 +120,39 @@ inline int cmp_geometry_field(const void *a, const void *b) if (x1 > x2) return 1; - if (x2 > x1) + if (x1 < x2) return -1; - y1= mach_double_read(mbr1 + sizeof(double) * 2 + sizeof(double)); - y2= mach_double_read(mbr2 + sizeof(double) * 2 + sizeof(double)); + x1= mach_double_read(mbr1 + sizeof(double) * 2 + sizeof(double)); + x2= mach_double_read(mbr2 + sizeof(double) * 2 + sizeof(double)); - if (y1 > y2) + if (x1 > x2) return 1; - if (y2 > y1) + if (x1 < x2) return -1; return 0; } /** Compare a data tuple to a physical record. -@param[in] dtuple data tuple -@param[in] rec B-tree record -@param[in] offsets rec_get_offsets(rec) -@param[in] n_cmp number of fields to compare -@param[in,out] matched_fields number of completely matched fields +@param dtuple data tuple +@param rec B-tree index record +@param index B-tree index +@param offsets rec_get_offsets(rec,index) +@param n_cmp number of fields to compare +@param matched_fields number of completely matched fields @return the comparison result of dtuple and rec @retval 0 if dtuple is equal to rec @retval negative if dtuple is less than rec @retval positive if dtuple is greater than rec */ -int -cmp_dtuple_rec_with_match_low( - const dtuple_t* dtuple, - const rec_t* rec, - const rec_offs* offsets, - ulint n_cmp, - ulint* matched_fields) - MY_ATTRIBUTE((nonnull)); -#define cmp_dtuple_rec_with_match(tuple,rec,offsets,fields) \ +int cmp_dtuple_rec_with_match_low(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, + const rec_offs *offsets, + ulint n_cmp, ulint *matched_fields) + MY_ATTRIBUTE((nonnull)); +#define cmp_dtuple_rec_with_match(tuple,rec,index,offsets,fields) \ cmp_dtuple_rec_with_match_low( \ - tuple,rec,offsets,dtuple_get_n_fields_cmp(tuple),fields) + tuple,rec,index,offsets,dtuple_get_n_fields_cmp(tuple),fields) /** Compare a data tuple to a physical record. @param[in] dtuple data tuple @param[in] rec B-tree or R-tree index record @@ -178,28 +176,32 @@ cmp_dtuple_rec_with_match_bytes( MY_ATTRIBUTE((warn_unused_result)); /** Compare a data tuple to a physical record. @see cmp_dtuple_rec_with_match -@param[in] dtuple data tuple -@param[in] rec B-tree record -@param[in] offsets rec_get_offsets(rec) +@param dtuple data tuple +@param rec index record +@param index index +@param offsets rec_get_offsets(rec, index) @return the comparison result of dtuple and rec @retval 0 if dtuple is equal to rec @retval negative if dtuple is less than rec @retval positive if dtuple is greater than rec */ -int -cmp_dtuple_rec( - const dtuple_t* dtuple, - const rec_t* rec, - const rec_offs* offsets); -/**************************************************************//** -Checks if a dtuple is a prefix of a record. The last field in dtuple -is allowed to be a prefix of the corresponding field in the record. -@return TRUE if prefix */ -ibool -cmp_dtuple_is_prefix_of_rec( -/*========================*/ - const dtuple_t* dtuple, /*!< in: data tuple */ - const rec_t* rec, /*!< in: physical record */ - const rec_offs* offsets);/*!< in: array returned by rec_get_offsets() */ +inline int cmp_dtuple_rec(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, const rec_offs *offsets) +{ + ulint matched= 0; + return cmp_dtuple_rec_with_match(dtuple, rec, index, offsets, &matched); +} + +/** Check if a dtuple is a prefix of a record. +@param dtuple data tuple +@param rec index record +@param index index +@param offsets rec_get_offsets(rec) +@return whether dtuple is a prefix of rec */ +bool cmp_dtuple_is_prefix_of_rec(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, + const rec_offs *offsets) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + /** Compare two physical records that contain the same number of columns, none of which are stored externally. @retval positive if rec1 (including non-ordering columns) is greater than rec2 @@ -246,18 +248,39 @@ cmp_rec_rec( MY_ATTRIBUTE((nonnull(1,2,3,4,5))); /** Compare two data fields. -@param[in] dfield1 data field -@param[in] dfield2 data field +@param dfield1 data field +@param dfield2 data field @return the comparison result of dfield1 and dfield2 -@retval 0 if dfield1 is equal to dfield2, or a prefix of dfield1 -@retval negative if dfield1 is less than dfield2 -@retval positive if dfield1 is greater than dfield2 */ -UNIV_INLINE -int -cmp_dfield_dfield_like_prefix( - const dfield_t* dfield1, - const dfield_t* dfield2); +@retval true if dfield1 is equal to dfield2, or a prefix of dfield1 +@retval false otherwise */ +inline bool cmp_dfield_dfield_eq_prefix(const dfield_t *dfield1, + const dfield_t *dfield2) +{ + ut_ad(dfield_check_typed(dfield1)); + ut_ad(dfield_check_typed(dfield2)); + const dtype_t *type= dfield_get_type(dfield1); -#include "rem0cmp.inl" +#ifdef UNIV_DEBUG + switch (type->prtype & DATA_MYSQL_TYPE_MASK) { + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_VARCHAR: + break; + default: + ut_error; + } +#endif /* UNIV_DEBUG */ -#endif + uint cs_num= dtype_get_charset_coll(type->prtype); + CHARSET_INFO *cs= get_charset(cs_num, MYF(MY_WME)); + ut_a(cs); + return !cs->strnncoll(static_cast<const uchar*>(dfield_get_data(dfield1)), + dfield_get_len(dfield1), + static_cast<const uchar*>(dfield_get_data(dfield2)), + dfield_get_len(dfield2), 1); +} diff --git a/storage/innobase/include/rem0cmp.inl b/storage/innobase/include/rem0cmp.inl deleted file mode 100644 index 6e21382d187..00000000000 --- a/storage/innobase/include/rem0cmp.inl +++ /dev/null @@ -1,107 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2020, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/*******************************************************************//** -@file include/rem0cmp.ic -Comparison services for records - -Created 7/1/1994 Heikki Tuuri -************************************************************************/ - -#include <mysql_com.h> -#include <my_sys.h> - -/** Compare two data fields. -@param[in] dfield1 data field; must have type field set -@param[in] dfield2 data field -@return the comparison result of dfield1 and dfield2 -@retval 0 if dfield1 is equal to dfield2 -@retval negative if dfield1 is less than dfield2 -@retval positive if dfield1 is greater than dfield2 */ -UNIV_INLINE -int -cmp_dfield_dfield( - const dfield_t* dfield1, - const dfield_t* dfield2) -{ - const dtype_t* type; - - ut_ad(dfield_check_typed(dfield1)); - - type = dfield_get_type(dfield1); - - return(cmp_data_data(type->mtype, type->prtype, - (const byte*) dfield_get_data(dfield1), - dfield_get_len(dfield1), - (const byte*) dfield_get_data(dfield2), - dfield_get_len(dfield2))); -} - -/** Compare two data fields. -@param[in] dfield1 data field -@param[in] dfield2 data field -@return the comparison result of dfield1 and dfield2 -@retval 0 if dfield1 is equal to dfield2, or a prefix of dfield1 -@retval negative if dfield1 is less than dfield2 -@retval positive if dfield1 is greater than dfield2 */ -UNIV_INLINE -int -cmp_dfield_dfield_like_prefix( - const dfield_t* dfield1, - const dfield_t* dfield2) -{ - const dtype_t* type; - - ut_ad(dfield_check_typed(dfield1)); - ut_ad(dfield_check_typed(dfield2)); - - type = dfield_get_type(dfield1); - -#ifdef UNIV_DEBUG - switch (type->prtype & DATA_MYSQL_TYPE_MASK) { - case MYSQL_TYPE_BIT: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_VARCHAR: - break; - default: - ut_error; - } -#endif /* UNIV_DEBUG */ - - uint cs_num = (uint) dtype_get_charset_coll(type->prtype); - - if (CHARSET_INFO* cs = get_charset(cs_num, MYF(MY_WME))) { - return(cs->strnncoll( - static_cast<const uchar*>( - dfield_get_data(dfield1)), - dfield_get_len(dfield1), - static_cast<const uchar*>( - dfield_get_data(dfield2)), - dfield_get_len(dfield2), - 1)); - } - - ib::fatal() << "Unable to find charset-collation " << cs_num; - return(0); -} diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index 9d1d55545ac..93ea650d0cf 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -109,6 +109,7 @@ struct index_field_t { ulint prefix_len; /*!< column prefix length, or 0 if indexing the whole column */ bool is_v_col; /*!< whether this is a virtual column */ + bool descending; /*!< whether to use DESC order */ }; /** Definition of an index being created */ diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 971f6363bdb..1ca2d7a429f 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -269,9 +269,6 @@ enum monitor_id_t { MONITOR_OS_PENDING_READS, MONITOR_OS_PENDING_WRITES, MONITOR_OVLD_OS_LOG_WRITTEN, - MONITOR_OVLD_OS_LOG_FSYNC, - MONITOR_OVLD_OS_LOG_PENDING_FSYNC, - MONITOR_OVLD_OS_LOG_PENDING_WRITES, /* Transaction related counters */ MONITOR_MODULE_TRX, @@ -298,20 +295,16 @@ enum monitor_id_t { /* Recovery related counters */ MONITOR_MODULE_RECOVERY, - MONITOR_NUM_CHECKPOINT, + MONITOR_OVLD_CHECKPOINTS, MONITOR_OVLD_LSN_FLUSHDISK, MONITOR_OVLD_LSN_CHECKPOINT, MONITOR_OVLD_LSN_CURRENT, MONITOR_LSN_CHECKPOINT_AGE, MONITOR_OVLD_BUF_OLDEST_LSN, MONITOR_OVLD_MAX_AGE_ASYNC, - MONITOR_PENDING_LOG_FLUSH, - MONITOR_PENDING_CHECKPOINT_WRITE, - MONITOR_LOG_IO, MONITOR_OVLD_LOG_WAITS, MONITOR_OVLD_LOG_WRITE_REQUEST, MONITOR_OVLD_LOG_WRITES, - MONITOR_OVLD_LOG_PADDED, /* Page Manager related counters */ MONITOR_MODULE_PAGE, diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 4cd77b08a60..41f61567b53 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -86,28 +86,6 @@ struct srv_stats_t /** Count the amount of data written in total (in bytes) */ ulint_ctr_1_t data_written; - /** Number of the log write requests done */ - ulint_ctr_1_t log_write_requests; - - /** Number of physical writes to the log performed */ - ulint_ctr_1_t log_writes; - - /** Amount of data padded for log write ahead */ - ulint_ctr_1_t log_padded; - - /** Amount of data written to the log files in bytes */ - lsn_ctr_1_t os_log_written; - - /** Number of writes being done to the log files */ - ulint_ctr_1_t os_log_pending_writes; - - /** We increase this counter, when we don't have enough - space in the log buffer and have to flush it */ - ulint_ctr_1_t log_waits; - - /** Store the number of write requests issued */ - ulint_ctr_1_t buf_pool_write_requests; - /** Number of buffer pool reads that led to the reading of a disk page */ ulint_ctr_1_t buf_pool_reads; @@ -286,18 +264,15 @@ extern char* srv_log_group_home_dir; /** The InnoDB redo log file size, or 0 when changing the redo log format at startup (while disallowing writes to the redo log). */ extern ulonglong srv_log_file_size; -extern ulong srv_log_buffer_size; extern ulong srv_flush_log_at_trx_commit; extern uint srv_flush_log_at_timeout; -extern ulong srv_log_write_ahead_size; extern my_bool srv_adaptive_flushing; extern my_bool srv_flush_sync; /** Requested size in bytes */ extern ulint srv_buf_pool_size; -/** Requested buffer pool chunk size. Each buffer pool instance consists -of one or more chunks. */ -extern ulong srv_buf_pool_chunk_unit; +/** Requested buffer pool chunk size */ +extern size_t srv_buf_pool_chunk_unit; /** Scan depth for LRU flush batch i.e.: number of blocks scanned*/ extern ulong srv_LRU_scan_depth; /** Whether or not to flush neighbors of a block */ @@ -459,9 +434,13 @@ extern my_bool srv_print_all_deadlocks; extern my_bool srv_cmp_per_index_enabled; +/** innodb_encrypt_log */ +extern my_bool srv_encrypt_log; + /* is encryption enabled */ extern ulong srv_encrypt_tables; + /** Status variables to be passed to MySQL */ extern struct export_var_t export_vars; @@ -688,7 +667,6 @@ struct export_var_t{ ulint innodb_buffer_pool_pages_old; ulint innodb_buffer_pool_read_requests; /*!< buf_pool.stat.n_page_gets */ ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */ - ulint innodb_buffer_pool_write_requests;/*!< srv_stats.buf_pool_write_requests */ ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/ @@ -696,8 +674,6 @@ struct export_var_t{ ulint innodb_checkpoint_max_age; ulint innodb_data_pending_reads; /*!< Pending reads */ ulint innodb_data_pending_writes; /*!< Pending writes */ - ulint innodb_data_pending_fsyncs; /*!< Pending fsyncs */ - ulint innodb_data_fsyncs; /*!< Number of fsyncs so far */ ulint innodb_data_read; /*!< Data bytes read */ ulint innodb_data_writes; /*!< I/O write requests */ ulint innodb_data_written; /*!< Data bytes written */ @@ -706,9 +682,6 @@ struct export_var_t{ ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */ ulint innodb_deadlocks; ulint innodb_history_list_length; - ulint innodb_log_waits; /*!< srv_log_waits */ - ulint innodb_log_write_requests; /*!< srv_log_write_requests */ - ulint innodb_log_writes; /*!< srv_log_writes */ lsn_t innodb_lsn_current; lsn_t innodb_lsn_flushed; lsn_t innodb_lsn_last_checkpoint; @@ -717,10 +690,8 @@ struct export_var_t{ ulint innodb_mem_adaptive_hash; #endif ulint innodb_mem_dictionary; - lsn_t innodb_os_log_written; /*!< srv_os_log_written */ - ulint innodb_os_log_fsyncs; /*!< n_log_flushes */ - ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */ - ulint innodb_os_log_pending_fsyncs; /*!< n_pending_log_flushes */ + /** log_sys.get_lsn() - recv_sys.lsn */ + lsn_t innodb_os_log_written; ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */ ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */ int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 1c35238e348..5ab4ca0f0a3 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -506,8 +506,6 @@ extern mysql_pfs_key_t fts_doc_id_mutex_key; extern mysql_pfs_key_t ibuf_bitmap_mutex_key; extern mysql_pfs_key_t ibuf_mutex_key; extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key; -extern mysql_pfs_key_t log_sys_mutex_key; -extern mysql_pfs_key_t log_flush_order_mutex_key; extern mysql_pfs_key_t recalc_pool_mutex_key; extern mysql_pfs_key_t purge_sys_pq_mutex_key; extern mysql_pfs_key_t recv_sys_mutex_key; @@ -534,6 +532,7 @@ extern mysql_pfs_key_t index_tree_rw_lock_key; extern mysql_pfs_key_t index_online_log_key; extern mysql_pfs_key_t trx_sys_rw_lock_key; extern mysql_pfs_key_t lock_latch_key; +extern mysql_pfs_key_t log_latch_key; extern mysql_pfs_key_t trx_rseg_latch_key; # endif /* UNIV_PFS_RWLOCK */ #endif /* HAVE_PSI_INTERFACE */ diff --git a/storage/innobase/include/ut0crc32.h b/storage/innobase/include/ut0crc32.h deleted file mode 100644 index 0cbccb976e2..00000000000 --- a/storage/innobase/include/ut0crc32.h +++ /dev/null @@ -1,37 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/**************************************************//** -@file include/ut0crc32.h -CRC32 implementation - -Created Aug 10, 2011 Vasil Dimov -*******************************************************/ - -#ifndef ut0crc32_h -#define ut0crc32_h - -#include "univ.i" -#include <my_sys.h> -static inline uint32_t ut_crc32(const byte *s, size_t size) -{ - return my_crc32c(0, s, size); -} - -#endif /* ut0crc32_h */ diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 89ff0ca709f..95541ea574e 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -305,6 +305,16 @@ operator<<( return(lhs); } +/** This is a wrapper class, used to print any number in IEC style */ +struct bytes_iec { + explicit bytes_iec(unsigned long long t): m_val(t) {} + double get_double() const { return static_cast<double>(m_val); } + const unsigned long long m_val; +}; + +/** Like hex operator above, except for bytes_iec */ +std::ostream &operator<<(std::ostream &lhs, const bytes_iec &rhs); + /** The class logger is the base class of all the error log related classes. It contains a std::ostringstream object. The main purpose of this class is to forward operator<< to the underlying std::ostringstream object. Do not diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc index d035808c6b9..8a7714101ba 100644 --- a/storage/innobase/log/log0crypt.cc +++ b/storage/innobase/log/log0crypt.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. -Copyright (C) 2014, 2021, MariaDB Corporation. +Copyright (C) 2014, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -31,16 +31,14 @@ MDEV-11782: Rewritten for MariaDB 10.2 by Marko Mäkelä, MariaDB Corporation. #include "log0crypt.h" #include "log0recv.h" // for recv_sys - -/** innodb_encrypt_log: whether to encrypt the redo log */ -my_bool srv_encrypt_log; +#include "mach0data.h" /** Redo log encryption key ID */ #define LOG_DEFAULT_ENCRYPTION_KEY 1 struct crypt_info_t { - ulint checkpoint_no; /*!< checkpoint no; 32 bits */ - uint key_version; /*!< mysqld key version */ + uint32_t checkpoint_no; /*!< checkpoint no; 32 bits */ + uint32_t key_version; /*!< key version */ /** random string for encrypting the key */ alignas(8) byte crypt_msg[MY_AES_BLOCK_SIZE]; /** the secret key */ @@ -60,6 +58,40 @@ static crypt_info_t infos[5 * 2]; /** First unused slot in infos[] */ static size_t infos_used; +/* Offsets of a log block header */ +#define LOG_BLOCK_HDR_NO 0 /* block number which must be > 0 and + is allowed to wrap around at 2G; the + highest bit is set to 1 if this is the + first log block in a log flush write + segment */ +#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000UL + /* mask used to get the highest bit in + the preceding field */ +#define LOG_BLOCK_HDR_DATA_LEN 4 /* number of bytes of log written to + this block */ +#define LOG_BLOCK_FIRST_REC_GROUP 6 /* offset of the first start of an + mtr log record group in this log block, + 0 if none; if the value is the same + as LOG_BLOCK_HDR_DATA_LEN, it means + that the first rec group has not yet + been catenated to this log block, but + if it will, it will start at this + offset; an archive recovery can + start parsing the log records starting + from this offset in this log block, + if value not 0 */ +#define LOG_BLOCK_HDR_SIZE 12 /* size of the log block header in + bytes */ + +#define LOG_BLOCK_KEY 4 /* encryption key version + before LOG_BLOCK_CHECKSUM; + after log_t::FORMAT_ENC_10_4 only */ +#define LOG_BLOCK_CHECKSUM 4 /* 4 byte checksum of the log block + contents; in InnoDB versions + < 3.23.52 this did not contain the + checksum but the same value as + LOG_BLOCK_HDR_NO */ + /*********************************************************************//** Get a log block's start lsn. @return a log block's start lsn */ @@ -123,26 +155,36 @@ static bool init_crypt_key(crypt_info_t* info, bool upgrade = false) return true; } -/** Encrypt or decrypt log blocks. -@param[in,out] buf log blocks to encrypt or decrypt +static ulint log_block_get_hdr_no(const byte *log_block) +{ + static_assert(LOG_BLOCK_HDR_NO == 0, "compatibility"); + return mach_read_from_4(my_assume_aligned<4>(log_block)) & + ~LOG_BLOCK_FLUSH_BIT_MASK; +} + +/** Decrypt log blocks. +@param[in,out] buf log blocks to decrypt @param[in] lsn log sequence number of the start of the buffer @param[in] size size of the buffer, in bytes -@param[in] op whether to decrypt, encrypt, or rotate key and encrypt -@return whether the operation succeeded (encrypt always does) */ -bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op) +@return whether the operation succeeded */ +ATTRIBUTE_COLD bool log_decrypt(byte* buf, lsn_t lsn, ulint size) { - ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_ad(ulint(buf) % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_ad(!(size & 511)); + ut_ad(!(ulint(buf) & 511)); ut_a(info.key_version); alignas(8) byte aes_ctr_iv[MY_AES_BLOCK_SIZE]; #define LOG_CRYPT_HDR_SIZE 4 - lsn &= ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1); + lsn &= ~lsn_t{511}; + + const bool has_encryption_key_rotation + = log_sys.format == log_t::FORMAT_ENC_10_4 + || log_sys.format == log_t::FORMAT_ENC_10_5; for (const byte* const end = buf + size; buf != end; - buf += OS_FILE_LOG_BLOCK_SIZE, lsn += OS_FILE_LOG_BLOCK_SIZE) { - alignas(4) byte dst[OS_FILE_LOG_BLOCK_SIZE - LOG_CRYPT_HDR_SIZE + buf += 512, lsn += 512) { + alignas(4) byte dst[512 - LOG_CRYPT_HDR_SIZE - LOG_BLOCK_CHECKSUM]; /* The log block number is not encrypted. */ @@ -156,45 +198,28 @@ bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op) ut_ad(log_block_get_start_lsn(lsn, log_block_get_hdr_no(buf)) == lsn); - byte* key_ver = &buf[OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_KEY - - LOG_BLOCK_CHECKSUM]; - const size_t dst_size - = log_sys.has_encryption_key_rotation() + byte* key_ver = &buf[512 - LOG_BLOCK_KEY - LOG_BLOCK_CHECKSUM]; + + const size_t dst_size = has_encryption_key_rotation ? sizeof dst - LOG_BLOCK_KEY : sizeof dst; - if (log_sys.has_encryption_key_rotation()) { - const uint key_version = info.key_version; - switch (op) { - case LOG_ENCRYPT_ROTATE_KEY: - info.key_version - = encryption_key_get_latest_version( - LOG_DEFAULT_ENCRYPTION_KEY); - if (key_version != info.key_version - && !init_crypt_key(&info)) { - info.key_version = key_version; - } - /* fall through */ - case LOG_ENCRYPT: - mach_write_to_4(key_ver, info.key_version); - break; - case LOG_DECRYPT: - info.key_version = mach_read_from_4(key_ver); - if (key_version != info.key_version - && !init_crypt_key(&info)) { - return false; - } - } + if (has_encryption_key_rotation) { + const auto key_version = info.key_version; + info.key_version = mach_read_from_4(key_ver); + if (key_version == info.key_version) { + } else if (!init_crypt_key(&info)) { + return false; #ifndef DBUG_OFF - if (key_version != info.key_version) { + } else { DBUG_PRINT("ib_log", ("key_version: %x -> %x", key_version, info.key_version)); - } #endif /* !DBUG_OFF */ + } } ut_ad(LOG_CRYPT_HDR_SIZE + dst_size - == log_sys.trailer_offset()); + == 512 - LOG_BLOCK_CHECKSUM - LOG_BLOCK_KEY); uint dst_len; int rc = encryption_crypt( @@ -203,9 +228,7 @@ bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op) const_cast<byte*>(info.crypt_key), MY_AES_BLOCK_SIZE, aes_ctr_iv, sizeof aes_ctr_iv, - op == LOG_DECRYPT - ? ENCRYPTION_FLAG_DECRYPT | ENCRYPTION_FLAG_NOPAD - : ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD, + ENCRYPTION_FLAG_DECRYPT | ENCRYPTION_FLAG_NOPAD, LOG_DEFAULT_ENCRYPTION_KEY, info.key_version); ut_a(rc == MY_AES_OK); @@ -219,8 +242,8 @@ bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op) /** Initialize the redo log encryption key and random parameters when creating a new redo log. The random parameters will be persisted in the log checkpoint pages. -@see log_crypt_write_checkpoint_buf() -@see log_crypt_read_checkpoint_buf() +@see log_crypt_write_header() +@see log_crypt_read_header() @return whether the operation succeeded */ bool log_crypt_init() { @@ -287,8 +310,7 @@ next_slot: @return whether the decryption was successful */ ATTRIBUTE_COLD bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn) { - const uint32_t checkpoint_no - = uint32_t(log_block_get_checkpoint_no(buf)); + const uint32_t checkpoint_no = mach_read_from_4(buf + 8); const crypt_info_t* info = infos; for (const crypt_info_t* const end = info + infos_used; info < end; info++) { @@ -309,16 +331,16 @@ ATTRIBUTE_COLD bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn) return false; } found: - byte dst[OS_FILE_LOG_BLOCK_SIZE]; + byte dst[512]; uint dst_len; byte aes_ctr_iv[MY_AES_BLOCK_SIZE]; - const uint src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE; + const uint src_len = 512 - LOG_BLOCK_HDR_SIZE; ulint log_block_no = log_block_get_hdr_no(buf); /* The log block header is not encrypted. */ - memcpy(dst, buf, LOG_BLOCK_HDR_SIZE); + memcpy(dst, buf, 512); memcpy(aes_ctr_iv, info->crypt_nonce, 3); mach_write_to_8(aes_ctr_iv + 3, @@ -345,30 +367,47 @@ found: return true; } -/** Add the encryption information to a redo log checkpoint buffer. -@param[in,out] buf checkpoint buffer */ -void log_crypt_write_checkpoint_buf(byte *buf) +/** MariaDB 10.2.5 encrypted redo log encryption key version (32 bits)*/ +constexpr size_t LOG_CHECKPOINT_CRYPT_KEY= 32; +/** MariaDB 10.2.5 encrypted redo log random nonce (32 bits) */ +constexpr size_t LOG_CHECKPOINT_CRYPT_NONCE= 36; +/** MariaDB 10.2.5 encrypted redo log random message (MY_AES_BLOCK_SIZE) */ +constexpr size_t LOG_CHECKPOINT_CRYPT_MESSAGE= 40; + +/** Add the encryption information to the log header buffer. +@param buf part of log header buffer */ +void log_crypt_write_header(byte *buf) { - ut_ad(info.key_version); - compile_time_assert(16 == sizeof info.crypt_msg); - compile_time_assert(16 == MY_AES_BLOCK_SIZE); - compile_time_assert(LOG_CHECKPOINT_CRYPT_MESSAGE - - LOG_CHECKPOINT_CRYPT_NONCE - == sizeof info.crypt_nonce); + ut_ad(info.key_version); + mach_write_to_4(my_assume_aligned<4>(buf), LOG_DEFAULT_ENCRYPTION_KEY); + mach_write_to_4(my_assume_aligned<4>(buf + 4), info.key_version); + memcpy_aligned<8>(buf + 8, info.crypt_msg, MY_AES_BLOCK_SIZE); + static_assert(MY_AES_BLOCK_SIZE == 16, "compatibility"); + memcpy_aligned<4>(buf + 24, info.crypt_nonce, sizeof info.crypt_nonce); +} - memcpy(buf + LOG_CHECKPOINT_CRYPT_MESSAGE, info.crypt_msg, - MY_AES_BLOCK_SIZE); - memcpy(buf + LOG_CHECKPOINT_CRYPT_NONCE, info.crypt_nonce, - sizeof info.crypt_nonce); - mach_write_to_4(buf + LOG_CHECKPOINT_CRYPT_KEY, info.key_version); +/** Read the encryption information from a log header buffer. +@param buf part of log header buffer +@return whether the operation was successful */ +bool log_crypt_read_header(const byte *buf) +{ + MEM_UNDEFINED(&info.checkpoint_no, sizeof info.checkpoint_no); + MEM_NOACCESS(&info.checkpoint_no, sizeof info.checkpoint_no); + if (mach_read_from_4(my_assume_aligned<4>(buf)) != + LOG_DEFAULT_ENCRYPTION_KEY) + return false; + info.key_version= mach_read_from_4(my_assume_aligned<4>(buf + 4)); + memcpy_aligned<8>(info.crypt_msg, buf + 8, MY_AES_BLOCK_SIZE); + memcpy_aligned<4>(info.crypt_nonce, buf + 24, sizeof info.crypt_nonce); + return init_crypt_key(&info); } /** Read the checkpoint crypto (version, msg and iv) info. @param[in] buf checkpoint buffer @return whether the operation was successful */ -bool log_crypt_read_checkpoint_buf(const byte* buf) +ATTRIBUTE_COLD bool log_crypt_read_checkpoint_buf(const byte* buf) { - info.checkpoint_no = mach_read_from_4(buf + (LOG_CHECKPOINT_NO + 4)); + info.checkpoint_no = mach_read_from_4(buf + 4); info.key_version = mach_read_from_4(buf + LOG_CHECKPOINT_CRYPT_KEY); #if MY_AES_BLOCK_SIZE != 16 @@ -423,3 +462,180 @@ bool log_tmp_block_encrypt( return rc == MY_AES_OK; } + +/** Decrypt part of a log record. +@param iv initialization vector +@param buf buffer for the decrypted data +@param data the encrypted data +@param len length of the data, in bytes +@return buf */ +byte *log_decrypt_buf(const byte *iv, byte *buf, const byte *data, uint len) +{ + ut_a(MY_AES_OK == encryption_crypt(data, len, buf, &len, + info.crypt_key, MY_AES_BLOCK_SIZE, + iv, MY_AES_BLOCK_SIZE, + ENCRYPTION_FLAG_DECRYPT | + ENCRYPTION_FLAG_NOPAD, + LOG_DEFAULT_ENCRYPTION_KEY, + info.key_version)); + return buf; +} + +#include "mtr0log.h" + +/** Encrypt a log snippet +@param iv initialization vector +@param tmp temporary buffer +@param buf buffer to be replaced with encrypted contents +@param end pointer past the end of buf +@return encrypted data bytes that follow */ +static size_t log_encrypt_buf(byte iv[MY_AES_BLOCK_SIZE], + byte *&tmp, byte *buf, const byte *const end) +{ + for (byte *l= buf; l != end; ) + { + const byte b= *l++; + size_t rlen= b & 0xf; + if (!rlen) + { + const size_t lenlen= mlog_decode_varint_length(*l); + const uint32_t addlen= mlog_decode_varint(l); + ut_ad(addlen != MLOG_DECODE_ERROR); + rlen= addlen + 15 - lenlen; + l+= lenlen; + } + + if (b < 0x80) + { + /* Add the page identifier to the initialization vector. */ + size_t idlen= mlog_decode_varint_length(*l); + ut_ad(idlen <= 5); + ut_ad(idlen < rlen); + mach_write_to_4(my_assume_aligned<4>(iv + 8), mlog_decode_varint(l)); + l+= idlen; + rlen-= idlen; + idlen= mlog_decode_varint_length(*l); + ut_ad(idlen <= 5); + ut_ad(idlen <= rlen); + mach_write_to_4(my_assume_aligned<4>(iv + 12), mlog_decode_varint(l)); + l+= idlen; + rlen-= idlen; + } + + uint len; + + if (l + rlen > end) + { + if (size_t len= end - l) + { + /* Only WRITE or EXTENDED records may comprise multiple segments. */ + static_assert((EXTENDED | 0x10) == WRITE, "compatibility"); + ut_ad((b & 0x60) == EXTENDED); + ut_ad(l < end); + memcpy(tmp, l, len); + tmp+= len; + rlen-= len; + } + return rlen; + } + + if (!rlen) + continue; /* FREE_PAGE and INIT_PAGE have no payload. */ + + len= static_cast<uint>(rlen); + ut_a(MY_AES_OK == encryption_crypt(l, len, tmp, &len, + info.crypt_key, MY_AES_BLOCK_SIZE, + iv, MY_AES_BLOCK_SIZE, + ENCRYPTION_FLAG_ENCRYPT | + ENCRYPTION_FLAG_NOPAD, + LOG_DEFAULT_ENCRYPTION_KEY, + info.key_version)); + ut_ad(len == rlen); + memcpy(l, tmp, rlen); + l+= rlen; + } + + return 0; +} + +/** Encrypt the log */ +ATTRIBUTE_NOINLINE void mtr_t::encrypt() +{ + ut_ad(log_sys.format == log_t::FORMAT_ENC_10_8); + ut_ad(m_log.size()); + + alignas(8) byte iv[MY_AES_BLOCK_SIZE]; + + m_commit_lsn= log_sys.get_lsn(); + ut_ad(m_commit_lsn); + byte *tmp= static_cast<byte*>(alloca(srv_page_size)), *t= tmp; + byte *dst= static_cast<byte*>(alloca(srv_page_size)); + mach_write_to_8(iv, m_commit_lsn); + mtr_buf_t::block_t *start= nullptr; + size_t size= 0, start_size= 0; + m_crc= 0; + + m_log.for_each_block([&](mtr_buf_t::block_t *b) + { + ut_ad(t - tmp + size <= srv_page_size); + byte *buf= b->begin(); + if (!start) + { + parse: + ut_ad(t == tmp); + size= log_encrypt_buf(iv, t, buf, b->end()); + if (!size) + { + ut_ad(t == tmp); + start_size= 0; + } + else + { + start= b; + start_size= t - tmp; + } + m_crc= my_crc32c(m_crc, buf, b->end() - buf - start_size); + } + else if (size > b->used()) + { + ::memcpy(t, buf, b->used()); + t+= b->used(); + size-= b->used(); + } + else + { + ::memcpy(t, buf, size); + t+= size; + buf+= size; + uint len= static_cast<uint>(t - tmp); + ut_a(MY_AES_OK == encryption_crypt(tmp, len, dst, &len, + info.crypt_key, MY_AES_BLOCK_SIZE, + iv, MY_AES_BLOCK_SIZE, + ENCRYPTION_FLAG_ENCRYPT | + ENCRYPTION_FLAG_NOPAD, + LOG_DEFAULT_ENCRYPTION_KEY, + info.key_version)); + ut_ad(tmp + len == t); + m_crc= my_crc32c(m_crc, dst, len); + /* Copy the encrypted data back to the log snippets. */ + ::memcpy(start->end() - start_size, dst, start_size); + t= dst + start_size; + for (ilist<mtr_buf_t::block_t>::iterator i(start); &*++i != b;) + { + const size_t l{i->used()}; + ::memcpy(i->begin(), t, l); + t+= l; + } + ::memcpy(b->begin(), t, size); + ut_ad(t + size == dst + len); + t= tmp; + start= nullptr; + goto parse; + } + return true; + }); + + ut_ad(t == tmp); + ut_ad(!start); + ut_ad(!size); +} diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index e127507e544..60d661f95f1 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -52,6 +52,7 @@ Created 12/9/1995 Heikki Tuuri #include "srv0mon.h" #include "buf0dump.h" #include "log0sync.h" +#include "log.h" /* General philosophy of InnoDB redo-logs: @@ -60,110 +61,38 @@ Every change to a contents of a data page must be done through mtr_t, and mtr_t::commit() will write log records to the InnoDB redo log. */ +alignas(CPU_LEVEL1_DCACHE_LINESIZE) +static group_commit_lock flush_lock; +alignas(CPU_LEVEL1_DCACHE_LINESIZE) +static group_commit_lock write_lock; + /** Redo log system */ log_t log_sys; -/* A margin for free space in the log buffer before a log entry is catenated */ -#define LOG_BUF_WRITE_MARGIN (4 * OS_FILE_LOG_BLOCK_SIZE) - /* Margins for free space in the log buffer after a log entry is catenated */ #define LOG_BUF_FLUSH_RATIO 2 -#define LOG_BUF_FLUSH_MARGIN (LOG_BUF_WRITE_MARGIN \ +#define LOG_BUF_FLUSH_MARGIN ((4 * 4096) /* cf. log_t::append_prepare() */ \ + (4U << srv_page_size_shift)) -/** Extends the log buffer. -@param[in] len requested minimum size in bytes */ -void log_buffer_extend(ulong len) -{ - const size_t new_buf_size = ut_calc_align(len, srv_page_size); - byte* new_buf = static_cast<byte*> - (ut_malloc_dontdump(new_buf_size, PSI_INSTRUMENT_ME)); - byte* new_flush_buf = static_cast<byte*> - (ut_malloc_dontdump(new_buf_size, PSI_INSTRUMENT_ME)); - - mysql_mutex_lock(&log_sys.mutex); - - if (len <= srv_log_buffer_size) { - /* Already extended enough by the others */ - mysql_mutex_unlock(&log_sys.mutex); - ut_free_dodump(new_buf, new_buf_size); - ut_free_dodump(new_flush_buf, new_buf_size); - return; - } - - ib::warn() << "The redo log transaction size " << len << - " exceeds innodb_log_buffer_size=" - << srv_log_buffer_size << " / 2). Trying to extend it."; - - byte* old_buf = log_sys.buf; - byte* old_flush_buf = log_sys.flush_buf; - const ulong old_buf_size = srv_log_buffer_size; - srv_log_buffer_size = static_cast<ulong>(new_buf_size); - log_sys.buf = new_buf; - log_sys.flush_buf = new_flush_buf; - memcpy_aligned<OS_FILE_LOG_BLOCK_SIZE>(new_buf, old_buf, - log_sys.buf_free); - - log_sys.max_buf_free = new_buf_size / LOG_BUF_FLUSH_RATIO - - LOG_BUF_FLUSH_MARGIN; - - mysql_mutex_unlock(&log_sys.mutex); - - ut_free_dodump(old_buf, old_buf_size); - ut_free_dodump(old_flush_buf, old_buf_size); - - ib::info() << "innodb_log_buffer_size was extended to " - << new_buf_size << "."; -} - -/** Calculate the recommended highest values for lsn - last_checkpoint_lsn -and lsn - buf_pool.get_oldest_modification(). -@param[in] file_size requested innodb_log_file_size -@retval true on success -@retval false if the smallest log group is too small to -accommodate the number of OS threads in the database server */ -bool -log_set_capacity(ulonglong file_size) +void log_t::set_capacity() { +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif /* Margin for the free space in the smallest log, before a new query step which modifies the database, is started */ - const size_t LOG_CHECKPOINT_FREE_PER_THREAD = 4U - << srv_page_size_shift; - const size_t LOG_CHECKPOINT_EXTRA_FREE = 8U << srv_page_size_shift; - - lsn_t margin; - ulint free; - lsn_t smallest_capacity = file_size - LOG_FILE_HDR_SIZE; + lsn_t smallest_capacity = srv_log_file_size - log_t::START_OFFSET; /* Add extra safety */ smallest_capacity -= smallest_capacity / 10; - /* For each OS thread we must reserve so much free space in the - smallest log group that it can accommodate the log entries produced - by single query steps: running out of free log space is a serious - system error which requires rebooting the database. */ - - free = LOG_CHECKPOINT_FREE_PER_THREAD * 10 - + LOG_CHECKPOINT_EXTRA_FREE; - if (free >= smallest_capacity / 2) { - ib::error() << "innodb_log_file_size is too small. " - << INNODB_PARAMETERS_MSG; - return false; - } - - margin = smallest_capacity - free; - margin = margin - margin / 10; /* Add still some extra safety */ - - mysql_mutex_lock(&log_sys.mutex); + lsn_t margin = smallest_capacity - (48 << srv_page_size_shift); + margin -= margin / 10; /* Add still some extra safety */ log_sys.log_capacity = smallest_capacity; log_sys.max_modified_age_async = margin - margin / 8; log_sys.max_checkpoint_age = margin; - - mysql_mutex_unlock(&log_sys.mutex); - - return(true); } /** Initialize the redo log subsystem. */ @@ -171,716 +100,661 @@ void log_t::create() { ut_ad(this == &log_sys); ut_ad(!is_initialised()); - m_initialised= true; -#if defined(__aarch64__) - mysql_mutex_init(log_sys_mutex_key, &mutex, MY_MUTEX_INIT_FAST); - mysql_mutex_init( - log_flush_order_mutex_key, &flush_order_mutex, MY_MUTEX_INIT_FAST); -#else - mysql_mutex_init(log_sys_mutex_key, &mutex, nullptr); - mysql_mutex_init(log_flush_order_mutex_key, &flush_order_mutex, nullptr); -#endif - - /* Start the lsn from one log block from zero: this way every - log record has a non-zero start lsn, a fact which we will use */ - - set_lsn(LOG_START_LSN + LOG_BLOCK_HDR_SIZE); - set_flushed_lsn(LOG_START_LSN + LOG_BLOCK_HDR_SIZE); + latch.SRW_LOCK_INIT(log_latch_key); + init_lsn_lock(); - ut_ad(srv_log_buffer_size >= 16 * OS_FILE_LOG_BLOCK_SIZE); - ut_ad(srv_log_buffer_size >= 4U << srv_page_size_shift); + /* LSN 0 and 1 are reserved; @see buf_page_t::oldest_modification_ */ + lsn.store(FIRST_LSN, std::memory_order_relaxed); + flushed_to_disk_lsn.store(FIRST_LSN, std::memory_order_relaxed); + write_lsn= FIRST_LSN; - buf= static_cast<byte*>(ut_malloc_dontdump(srv_log_buffer_size, - PSI_INSTRUMENT_ME)); - TRASH_ALLOC(buf, srv_log_buffer_size); - flush_buf= static_cast<byte*>(ut_malloc_dontdump(srv_log_buffer_size, +#ifndef HAVE_PMEM + buf= static_cast<byte*>(ut_malloc_dontdump(buf_size, PSI_INSTRUMENT_ME)); + TRASH_ALLOC(buf, buf_size); + flush_buf= static_cast<byte*>(ut_malloc_dontdump(buf_size, PSI_INSTRUMENT_ME)); - TRASH_ALLOC(flush_buf, srv_log_buffer_size); + TRASH_ALLOC(flush_buf, buf_size); + checkpoint_buf= static_cast<byte*>(aligned_malloc(4096, 4096)); + memset_aligned<4096>(checkpoint_buf, 0, 4096); +#else + ut_ad(!checkpoint_buf); + ut_ad(!buf); + ut_ad(!flush_buf); +#endif - max_buf_free= srv_log_buffer_size / LOG_BUF_FLUSH_RATIO - - LOG_BUF_FLUSH_MARGIN; + max_buf_free= buf_size / LOG_BUF_FLUSH_RATIO - LOG_BUF_FLUSH_MARGIN; set_check_flush_or_checkpoint(); - n_log_ios_old= n_log_ios; - last_printout_time= time(NULL); - - buf_next_to_write= 0; - last_checkpoint_lsn= write_lsn= LOG_START_LSN; - n_log_ios= 0; - n_log_ios_old= 0; + last_checkpoint_lsn= FIRST_LSN; log_capacity= 0; max_modified_age_async= 0; max_checkpoint_age= 0; - next_checkpoint_no= 0; next_checkpoint_lsn= 0; checkpoint_pending= false; - log_block_init(buf, LOG_START_LSN); - log_block_set_first_rec_group(buf, LOG_BLOCK_HDR_SIZE); - - buf_free= LOG_BLOCK_HDR_SIZE; - checkpoint_buf= static_cast<byte*> - (aligned_malloc(OS_FILE_LOG_BLOCK_SIZE, OS_FILE_LOG_BLOCK_SIZE)); -} - -file_os_io::file_os_io(file_os_io &&rhs) : m_fd(rhs.m_fd) -{ - rhs.m_fd= OS_FILE_CLOSED; -} - -file_os_io &file_os_io::operator=(file_os_io &&rhs) -{ - std::swap(m_fd, rhs.m_fd); - return *this; -} - -file_os_io::~file_os_io() noexcept -{ - if (is_opened()) - close(); -} - -dberr_t file_os_io::open(const char *path, bool read_only) noexcept -{ - ut_ad(!is_opened()); - - bool success; - auto tmp_fd= os_file_create( - innodb_log_file_key, path, OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, - OS_FILE_NORMAL, OS_LOG_FILE, read_only, &success); - if (!success) - return DB_ERROR; + buf_free= 0; - m_durable_writes= srv_file_flush_method == SRV_O_DSYNC; - m_fd= tmp_fd; - return success ? DB_SUCCESS : DB_ERROR; + ut_ad(is_initialised()); } -dberr_t file_os_io::rename(const char *old_path, const char *new_path) noexcept +dberr_t log_file_t::close() noexcept { - return os_file_rename(innodb_log_file_key, old_path, new_path) ? DB_SUCCESS - : DB_ERROR; -} + ut_a(is_opened()); -dberr_t file_os_io::close() noexcept -{ - if (!os_file_close(m_fd)) + if (!os_file_close_func(m_file)) return DB_ERROR; - m_fd= OS_FILE_CLOSED; + m_file= OS_FILE_CLOSED; return DB_SUCCESS; } -dberr_t file_os_io::read(os_offset_t offset, span<byte> buf) noexcept -{ - return os_file_read(IORequestRead, m_fd, buf.data(), offset, buf.size()); -} - -dberr_t file_os_io::write(const char *path, os_offset_t offset, - span<const byte> buf) noexcept +dberr_t log_file_t::read(os_offset_t offset, span<byte> buf) noexcept { - return os_file_write(IORequestWrite, path, m_fd, buf.data(), offset, - buf.size()); + ut_ad(is_opened()); + return os_file_read(IORequestRead, m_file, buf.data(), offset, buf.size()); } -dberr_t file_os_io::flush() noexcept +void log_file_t::write(os_offset_t offset, span<const byte> buf) noexcept { - return os_file_flush(m_fd) ? DB_SUCCESS : DB_ERROR; + ut_ad(is_opened()); + if (dberr_t err= os_file_write(IORequestWrite, "ib_logfile0", m_file, + buf.data(), offset, buf.size())) + ib::fatal() << "write(\"ib_logfile0\") returned " << err; } #ifdef HAVE_PMEM +# include <libpmem.h> +#endif -#include <libpmem.h> - -/** Memory mapped file */ -class mapped_file_t -{ -public: - mapped_file_t()= default; - mapped_file_t(const mapped_file_t &)= delete; - mapped_file_t &operator=(const mapped_file_t &)= delete; - mapped_file_t(mapped_file_t &&)= delete; - mapped_file_t &operator=(mapped_file_t &&)= delete; - ~mapped_file_t() noexcept; - - dberr_t map(const char *path, bool read_only= false, - bool nvme= false) noexcept; - dberr_t unmap() noexcept; - byte *data() noexcept { return m_area.data(); } - -private: - span<byte> m_area; -}; - -mapped_file_t::~mapped_file_t() noexcept -{ - if (!m_area.empty()) - unmap(); -} - -dberr_t mapped_file_t::map(const char *path, bool read_only, - bool nvme) noexcept +void log_t::attach(log_file_t file, os_offset_t size) { - auto fd= mysql_file_open(innodb_log_file_key, path, - read_only ? O_RDONLY : O_RDWR, MYF(MY_WME)); - if (fd == -1) - return DB_ERROR; - - const auto file_size= size_t{os_file_get_size(path).m_total_size}; + log= file; + ut_ad(!size || size >= START_OFFSET + SIZE_OF_FILE_CHECKPOINT); + file_size= size; - const int nvme_flag= nvme ? MAP_SYNC : 0; - void *ptr= - my_mmap(0, file_size, read_only ? PROT_READ : PROT_READ | PROT_WRITE, - MAP_SHARED_VALIDATE | nvme_flag, fd, 0); - mysql_file_close(fd, MYF(MY_WME)); +#ifdef HAVE_PMEM + ut_ad(!buf); + ut_ad(!flush_buf); + if (size && !(size_t(size) & 4095) && srv_operation != SRV_OPERATION_BACKUP) + { + void *ptr= + my_mmap(0, size_t(size), + srv_read_only_mode ? PROT_READ : PROT_READ | PROT_WRITE, + MAP_SHARED_VALIDATE | MAP_SYNC, log.m_file, 0); +#ifdef __linux__ + if (ptr == MAP_FAILED) + { + struct stat st; + if (!fstat(log.m_file, &st)) + { + MSAN_STAT_WORKAROUND(&st); + const auto st_dev= st.st_dev; + if (!stat("/dev/shm", &st)) + { + MSAN_STAT_WORKAROUND(&st); + if (st.st_dev == st_dev) + ptr= my_mmap(0, size_t(size), srv_read_only_mode + ? PROT_READ : PROT_READ | PROT_WRITE, + MAP_SHARED, log.m_file, 0); + } + } + } +#endif /* __linux__ */ + if (ptr != MAP_FAILED) + { + log.close(); + mprotect(ptr, size_t(size), PROT_READ); + buf= static_cast<byte*>(ptr); +#if defined __linux__ || defined _WIN32 + set_block_size(CPU_LEVEL1_DCACHE_LINESIZE); +#endif + log_maybe_unbuffered= true; + log_buffered= false; + return; + } + } + buf= static_cast<byte*>(ut_malloc_dontdump(buf_size, PSI_INSTRUMENT_ME)); + TRASH_ALLOC(buf, buf_size); + flush_buf= static_cast<byte*>(ut_malloc_dontdump(buf_size, + PSI_INSTRUMENT_ME)); + TRASH_ALLOC(flush_buf, buf_size); +#endif - if (ptr == MAP_FAILED) - return DB_ERROR; +#if defined __linux__ || defined _WIN32 + sql_print_information("InnoDB: %s (block size=%u bytes)", + log_buffered + ? "Buffered log writes" + : "File system buffers for log disabled", + block_size); +#endif - m_area= {static_cast<byte *>(ptr), file_size}; - return DB_SUCCESS; +#ifdef HAVE_PMEM + checkpoint_buf= static_cast<byte*>(aligned_malloc(block_size, block_size)); + memset_aligned<64>(checkpoint_buf, 0, block_size); +#endif } -dberr_t mapped_file_t::unmap() noexcept +void log_t::create(lsn_t lsn) noexcept { - ut_ad(!m_area.empty()); - - if (my_munmap(m_area.data(), m_area.size())) - return DB_ERROR; - - m_area= {}; - return DB_SUCCESS; -} +#ifndef SUX_LOCK_GENERIC + ut_ad(latch.is_write_locked()); +#endif + ut_ad(!recv_no_log_write); + ut_ad(is_latest()); + ut_ad(this == &log_sys); -static bool is_pmem(const char *path) noexcept -{ - mapped_file_t mf; - return mf.map(path, true, true) == DB_SUCCESS ? true : false; -} + this->lsn.store(lsn, std::memory_order_relaxed); + this->flushed_to_disk_lsn.store(lsn, std::memory_order_relaxed); + first_lsn= lsn; + write_lsn= lsn; -class file_pmem_io final : public file_io -{ -public: - file_pmem_io() noexcept : file_io(true) {} + last_checkpoint_lsn= 0; - dberr_t open(const char *path, bool read_only) noexcept final - { - return m_file.map(path, read_only, true); - } - dberr_t rename(const char *old_path, const char *new_path) noexcept final - { - return os_file_rename(innodb_log_file_key, old_path, new_path) ? DB_SUCCESS - : DB_ERROR; - } - dberr_t close() noexcept final { return m_file.unmap(); } - dberr_t read(os_offset_t offset, span<byte> buf) noexcept final - { - memcpy(buf.data(), m_file.data() + offset, buf.size()); - return DB_SUCCESS; - } - dberr_t write(const char *, os_offset_t offset, - span<const byte> buf) noexcept final +#ifdef HAVE_PMEM + if (is_pmem()) { - pmem_memcpy_persist(m_file.data() + offset, buf.data(), buf.size()); - return DB_SUCCESS; + mprotect(buf, size_t(file_size), PROT_READ | PROT_WRITE); + memset_aligned<4096>(buf, 0, 4096); + buf_free= START_OFFSET; } - dberr_t flush() noexcept final + else +#endif { - ut_ad(0); - return DB_SUCCESS; + buf_free= 0; + memset_aligned<4096>(flush_buf, 0, buf_size); + memset_aligned<4096>(buf, 0, buf_size); } -private: - mapped_file_t m_file; -}; -#endif + mach_write_to_4(buf + LOG_HEADER_FORMAT, FORMAT_10_8); + mach_write_to_8(buf + LOG_HEADER_START_LSN, lsn); + static constexpr const char LOG_HEADER_CREATOR_CURRENT[]= + "MariaDB " + IB_TO_STR(MYSQL_VERSION_MAJOR) "." + IB_TO_STR(MYSQL_VERSION_MINOR) "." + IB_TO_STR(MYSQL_VERSION_PATCH); -dberr_t log_file_t::open(bool read_only) noexcept -{ - ut_a(!is_opened()); + strcpy(reinterpret_cast<char*>(buf) + LOG_HEADER_CREATOR, + LOG_HEADER_CREATOR_CURRENT); + static_assert(LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR >= + sizeof LOG_HEADER_CREATOR_CURRENT, "compatibility"); + if (is_encrypted()) + log_crypt_write_header(buf + LOG_HEADER_CREATOR_END); + mach_write_to_4(my_assume_aligned<4>(508 + buf), my_crc32c(0, buf, 508)); + + DBUG_PRINT("ib_log", ("write header " LSN_PF, lsn)); #ifdef HAVE_PMEM - auto ptr= is_pmem(m_path.c_str()) - ? std::unique_ptr<file_io>(new file_pmem_io) - : std::unique_ptr<file_io>(new file_os_io); -#else - auto ptr= std::unique_ptr<file_io>(new file_os_io); + if (is_pmem()) + pmem_persist(buf, 512); + else #endif - - if (dberr_t err= ptr->open(m_path.c_str(), read_only)) - return err; - - m_file= std::move(ptr); - return DB_SUCCESS; -} - -bool log_file_t::is_opened() const noexcept -{ - return static_cast<bool>(m_file); -} - -dberr_t log_file_t::rename(std::string new_path) noexcept -{ - if (dberr_t err= m_file->rename(m_path.c_str(), new_path.c_str())) - return err; - - m_path = std::move(new_path); - return DB_SUCCESS; + { + log.write(0, {buf, 4096}); + memset_aligned<512>(buf, 0, 512); + } } -dberr_t log_file_t::close() noexcept +void log_t::close_file() { - ut_a(is_opened()); - - if (dberr_t err= m_file->close()) - return err; - - m_file.reset(); - return DB_SUCCESS; -} +#ifdef HAVE_PMEM + if (is_pmem()) + { + ut_ad(!is_opened()); + ut_ad(!checkpoint_buf); + if (buf) + { + my_munmap(buf, file_size); + buf= nullptr; + } + return; + } -dberr_t log_file_t::read(os_offset_t offset, span<byte> buf) noexcept -{ - ut_ad(is_opened()); - return m_file->read(offset, buf); + ut_free_dodump(buf, buf_size); + buf= nullptr; + ut_free_dodump(flush_buf, buf_size); + flush_buf= nullptr; + aligned_free(checkpoint_buf); + checkpoint_buf= nullptr; +#endif + if (is_opened()) + if (const dberr_t err= log.close()) + ib::fatal() << "closing ib_logfile0 failed: " << err; } -bool log_file_t::writes_are_durable() const noexcept +#if defined __linux__ || defined _WIN32 +/** Acquire all latches that protect the log. */ +static void log_resize_acquire() { - return m_file->writes_are_durable(); -} + if (!log_sys.is_pmem()) + { + while (flush_lock.acquire(log_sys.get_lsn() + 1, nullptr) != + group_commit_lock::ACQUIRED); + while (write_lock.acquire(log_sys.get_lsn() + 1, nullptr) != + group_commit_lock::ACQUIRED); + } -dberr_t log_file_t::write(os_offset_t offset, span<const byte> buf) noexcept -{ - ut_ad(is_opened()); - return m_file->write(m_path.c_str(), offset, buf); + log_sys.latch.wr_lock(SRW_LOCK_CALL); } -dberr_t log_file_t::flush() noexcept +/** Release the latches that protect the log. */ +void log_resize_release() { - ut_ad(is_opened()); - return m_file->flush(); -} + log_sys.latch.wr_unlock(); -void log_t::file::open_file(std::string path) -{ - fd= log_file_t(std::move(path)); - if (const dberr_t err= fd.open(srv_read_only_mode)) - ib::fatal() << "open(" << fd.get_path() << ") returned " << err; + if (!log_sys.is_pmem()) + { + lsn_t lsn1= write_lock.release(write_lock.value()); + lsn_t lsn2= flush_lock.release(flush_lock.value()); + if (lsn1 || lsn2) + log_write_up_to(std::max(lsn1, lsn2), true, nullptr); + } } -/** Update the log block checksum. */ -static void log_block_store_checksum(byte* block) +/** Try to enable or disable file system caching (update log_buffered) */ +void log_t::set_buffered(bool buffered) { - log_block_set_checksum(block, log_block_calc_checksum_crc32(block)); + if (!log_maybe_unbuffered || is_pmem() || high_level_read_only) + return; + log_resize_acquire(); + if (!resize_in_progress() && is_opened() && bool(log_buffered) != buffered) + { + os_file_close_func(log.m_file); + log.m_file= OS_FILE_CLOSED; + std::string path{get_log_file_path()}; + log_buffered= buffered; + bool success; + log.m_file= os_file_create_func(path.c_str(), + OS_FILE_OPEN, OS_FILE_NORMAL, OS_LOG_FILE, + false, &success); + ut_a(log.m_file != OS_FILE_CLOSED); + sql_print_information("InnoDB: %s (block size=%u bytes)", + log_buffered + ? "Buffered log writes" + : "File system buffers for log disabled", + block_size); + } + log_resize_release(); } +#endif -void log_t::file::write_header_durable(lsn_t lsn) +/** Write an aligned buffer to ib_logfile0. +@param buf buffer to be written +@param len length of data to be written +@param offset log file offset */ +static void log_write_buf(const byte *buf, size_t len, lsn_t offset) { - ut_ad(lsn % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_ad(write_lock.is_owner()); ut_ad(!recv_no_log_write); - ut_ad(log_sys.log.format == log_t::FORMAT_10_5 || - log_sys.log.format == log_t::FORMAT_ENC_10_5); + ut_d(const size_t block_size_1= log_sys.get_block_size() - 1); + ut_ad(!(offset & block_size_1)); + ut_ad(!(len & block_size_1)); + ut_ad(!(size_t(buf) & block_size_1)); + ut_ad(len); - byte *buf= log_sys.checkpoint_buf; - memset_aligned<OS_FILE_LOG_BLOCK_SIZE>(buf, 0, OS_FILE_LOG_BLOCK_SIZE); - - mach_write_to_4(buf + LOG_HEADER_FORMAT, log_sys.log.format); - mach_write_to_4(buf + LOG_HEADER_SUBFORMAT, log_sys.log.subformat); - mach_write_to_8(buf + LOG_HEADER_START_LSN, lsn); - strcpy(reinterpret_cast<char*>(buf) + LOG_HEADER_CREATOR, - LOG_HEADER_CREATOR_CURRENT); - ut_ad(LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR >= - sizeof LOG_HEADER_CREATOR_CURRENT); - log_block_store_checksum(buf); - - DBUG_PRINT("ib_log", ("write " LSN_PF, lsn)); - - log_sys.log.write(0, {buf, OS_FILE_LOG_BLOCK_SIZE}); - if (!log_sys.log.writes_are_durable()) - log_sys.log.flush(); -} + if (UNIV_LIKELY(offset + len <= log_sys.file_size)) + { +write: + log_sys.log.write(offset, {buf, len}); + return; + } -void log_t::file::read(os_offset_t offset, span<byte> buf) -{ - if (const dberr_t err= fd.read(offset, buf)) - ib::fatal() << "read(" << fd.get_path() << ") returned "<< err; + const size_t write_len= size_t(log_sys.file_size - offset); + log_sys.log.write(offset, {buf, write_len}); + len-= write_len; + buf+= write_len; + ut_ad(log_sys.START_OFFSET + len < offset); + offset= log_sys.START_OFFSET; + goto write; } -bool log_t::file::writes_are_durable() const noexcept -{ - return fd.writes_are_durable(); -} +/** Invoke commit_checkpoint_notify_ha() to notify that outstanding +log writes have been completed. */ +void log_flush_notify(lsn_t flush_lsn); -void log_t::file::write(os_offset_t offset, span<byte> buf) -{ - srv_stats.os_log_pending_writes.inc(); - if (const dberr_t err= fd.write(offset, buf)) - ib::fatal() << "write(" << fd.get_path() << ") returned " << err; - srv_stats.os_log_pending_writes.dec(); - srv_stats.os_log_written.add(buf.size()); - srv_stats.log_writes.inc(); - log_sys.n_log_ios++; -} +#if 0 // Currently we overwrite the last log block until it is complete. +/** CRC-32C of pad messages using between 1 and 15 bytes of NUL bytes +in the payload */ +static const unsigned char pad_crc[15][4]= { + {0xA6,0x59,0xC1,0xDB}, {0xF2,0xAF,0x80,0x73}, {0xED,0x02,0xF1,0x90}, + {0x68,0x4E,0xA3,0xF3}, {0x5D,0x1B,0xEA,0x6A}, {0xE0,0x01,0x86,0xB9}, + {0xD1,0x06,0x86,0xF5}, {0xEB,0x20,0x12,0x33}, {0xBA,0x73,0xB2,0xA3}, + {0x5F,0xA2,0x08,0x03}, {0x70,0x03,0xD6,0x9D}, {0xED,0xB3,0x49,0x78}, + {0xFD,0xD6,0xB9,0x9C}, {0x25,0xF8,0xB1,0x2C}, {0xCD,0xAA,0xE7,0x10} +}; -void log_t::file::flush() +/** Pad the log with some dummy bytes +@param lsn desired log sequence number +@param pad number of bytes to append to the log +@param begin buffer to write 'pad' bytes to +@param extra buffer for additional pad bytes (up to 15 bytes) +@return additional bytes used in extra[] */ +ATTRIBUTE_NOINLINE +static size_t log_pad(lsn_t lsn, size_t pad, byte *begin, byte *extra) { - log_sys.pending_flushes.fetch_add(1, std::memory_order_acquire); - if (const dberr_t err= fd.flush()) - ib::fatal() << "flush(" << fd.get_path() << ") returned " << err; - log_sys.pending_flushes.fetch_sub(1, std::memory_order_release); - log_sys.flushes.fetch_add(1, std::memory_order_release); -} + ut_ad(!(size_t(begin + pad) & (log_sys.get_block_size() - 1))); + byte *b= begin; + const byte seq{log_sys.get_sequence_bit(lsn)}; + /* The caller should never request padding such that the + file would wrap around to the beginning. That is, the sequence + bit must be the same for all records. */ + ut_ad(seq == log_sys.get_sequence_bit(lsn + pad)); + + if (log_sys.is_encrypted()) + { + /* The lengths of our pad messages vary between 15 and 29 bytes + (FILE_CHECKPOINT byte, 1 to 15 NUL bytes, sequence byte, + 4 bytes checksum, 8 NUL bytes nonce). */ + if (pad < 15) + { + extra[0]= FILE_CHECKPOINT | 1; + extra[1]= 0; + extra[2]= seq; + memcpy(extra + 3, pad_crc[0], 4); + memset(extra + 7, 0, 8); + memcpy(b, extra, pad); + memmove(extra, extra + pad, 15 - pad); + return 15 - pad; + } -void log_t::file::close_file() -{ - if (fd.is_opened()) + /* Pad first with 29-byte messages until the remaining size is + less than 29+15 bytes, and then write 1 or 2 shorter messages. */ + const byte *const end= begin + pad; + for (; b + (29 + 15) < end; b+= 29) + { + b[0]= FILE_CHECKPOINT | 15; + memset(b + 1, 0, 15); + b[16]= seq; + memcpy(b + 17, pad_crc[14], 4); + memset(b + 21, 0, 8); + } + if (b + 29 < end) + { + b[0]= FILE_CHECKPOINT | 1; + b[1]= 0; + b[2]= seq; + memcpy(b + 3, pad_crc[0], 4); + memset(b + 7, 0, 8); + b+= 15; + } + const size_t last_pad(end - b); + ut_ad(last_pad >= 15); + ut_ad(last_pad <= 29); + b[0]= FILE_CHECKPOINT | byte(last_pad - 14); + memset(b + 1, 0, last_pad - 14); + b[last_pad - 13]= seq; + memcpy(b + last_pad - 12, pad_crc[last_pad - 15], 4); + memset(b + last_pad - 8, 0, 8); + } + else { - if (const dberr_t err= fd.close()) - ib::fatal() << "close(" << fd.get_path() << ") returned " << err; + /* The lengths of our pad messages vary between 7 and 21 bytes + (FILE_CHECKPOINT byte, 1 to 15 NUL bytes, sequence byte, + 4 bytes checksum). */ + if (pad < 7) + { + extra[0]= FILE_CHECKPOINT | 1; + extra[1]= 0; + extra[2]= seq; + memcpy(extra + 3, pad_crc[0], 4); + memcpy(b, extra, pad); + memmove(extra, extra + pad, 7 - pad); + return 7 - pad; + } + + /* Pad first with 21-byte messages until the remaining size is + less than 21+7 bytes, and then write 1 or 2 shorter messages. */ + const byte *const end= begin + pad; + for (; b + (21 + 7) < end; b+= 21) + { + b[0]= FILE_CHECKPOINT | 15; + memset(b + 1, 0, 15); + b[16]= seq; + memcpy(b + 17, pad_crc[14], 4); + } + if (b + 21 < end) + { + b[0]= FILE_CHECKPOINT | 1; + b[1]= 0; + b[2]= seq; + memcpy(b + 3, pad_crc[0], 4); + b+= 7; + } + const size_t last_pad(end - b); + ut_ad(last_pad >= 7); + ut_ad(last_pad <= 21); + b[0]= FILE_CHECKPOINT | byte(last_pad - 6); + memset(b + 1, 0, last_pad - 6); + b[last_pad - 5]= seq; + memcpy(b + last_pad - 4, pad_crc[last_pad - 7], 4); } - fd.free(); // Free path -} -/** Initialize the redo log. */ -void log_t::file::create() -{ - ut_ad(this == &log_sys.log); - ut_ad(log_sys.is_initialised()); - - format= srv_encrypt_log ? log_t::FORMAT_ENC_10_5 : log_t::FORMAT_10_5; - subformat= 2; - file_size= srv_log_file_size; - lsn= LOG_START_LSN; - lsn_offset= LOG_FILE_HDR_SIZE; + return 0; } - -/******************************************************//** -Writes a buffer to a log file. */ -static -void -log_write_buf( - byte* buf, /*!< in: buffer */ - ulint len, /*!< in: buffer len; must be divisible - by OS_FILE_LOG_BLOCK_SIZE */ -#ifdef UNIV_DEBUG - ulint pad_len, /*!< in: pad len in the buffer len */ -#endif /* UNIV_DEBUG */ - lsn_t start_lsn, /*!< in: start lsn of the buffer; must - be divisible by - OS_FILE_LOG_BLOCK_SIZE */ - ulint new_data_offset)/*!< in: start offset of new data in - buf: this parameter is used to decide - if we have to write a new log file - header */ -{ - ulint write_len; - lsn_t next_offset; - ulint i; - - ut_ad(log_write_lock_own()); - ut_ad(!recv_no_log_write); - ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_a(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0); - -loop: - if (len == 0) { - - return; - } - - next_offset = log_sys.log.calc_lsn_offset(start_lsn); - - if ((next_offset % log_sys.log.file_size) + len - > log_sys.log.file_size) { - /* if the above condition holds, then the below expression - is < len which is ulint, so the typecast is ok */ - write_len = ulint(log_sys.log.file_size - - (next_offset % log_sys.log.file_size)); - } else { - write_len = len; - } - - DBUG_PRINT("ib_log", - ("write " LSN_PF " to " LSN_PF - ": len " ULINTPF - " blocks " ULINTPF ".." ULINTPF, - start_lsn, next_offset, - write_len, - log_block_get_hdr_no(buf), - log_block_get_hdr_no( - buf + write_len - - OS_FILE_LOG_BLOCK_SIZE))); - - ut_ad(pad_len >= len - || log_block_get_hdr_no(buf) - == log_block_convert_lsn_to_no(start_lsn)); - - /* Calculate the checksums for each log block and write them to - the trailer fields of the log blocks */ - - for (i = 0; i < write_len / OS_FILE_LOG_BLOCK_SIZE; i++) { -#ifdef UNIV_DEBUG - ulint hdr_no_2 = log_block_get_hdr_no(buf) + i; - DBUG_EXECUTE_IF("innodb_small_log_block_no_limit", - hdr_no_2 = ((hdr_no_2 - 1) & 0xFUL) + 1;); #endif - ut_ad(pad_len >= len - || i * OS_FILE_LOG_BLOCK_SIZE >= len - pad_len - || log_block_get_hdr_no(buf + i * OS_FILE_LOG_BLOCK_SIZE) == hdr_no_2); - log_block_store_checksum(buf + i * OS_FILE_LOG_BLOCK_SIZE); - } - - log_sys.log.write(next_offset, {buf, write_len}); - - if (write_len < len) { - start_lsn += write_len; - len -= write_len; - buf += write_len; - goto loop; - } -} - -/** Flush the recently written changes to the log file.*/ -static void log_write_flush_to_disk_low(lsn_t lsn) -{ - if (!log_sys.log.writes_are_durable()) - log_sys.log.flush(); - ut_a(lsn >= log_sys.get_flushed_lsn()); - log_sys.set_flushed_lsn(lsn); -} -/** Swap log buffers, and copy the content of last block -from old buf to the head of the new buf. Thus, buf_free and -buf_next_to_write would be changed accordingly */ -static inline -void -log_buffer_switch() +#ifdef HAVE_PMEM +/** Persist the log. +@param lsn desired new value of flushed_to_disk_lsn */ +inline void log_t::persist(lsn_t lsn) noexcept { - mysql_mutex_assert_owner(&log_sys.mutex); - ut_ad(log_write_lock_own()); - - size_t area_end = ut_calc_align<size_t>( - log_sys.buf_free, OS_FILE_LOG_BLOCK_SIZE); + ut_ad(is_pmem()); + ut_ad(!write_lock.is_owner()); + ut_ad(!flush_lock.is_owner()); - /* Copy the last block to new buf */ - memcpy_aligned<OS_FILE_LOG_BLOCK_SIZE>( - log_sys.flush_buf, - log_sys.buf + area_end - OS_FILE_LOG_BLOCK_SIZE, - OS_FILE_LOG_BLOCK_SIZE); + lsn_t old= flushed_to_disk_lsn.load(std::memory_order_relaxed); - std::swap(log_sys.buf, log_sys.flush_buf); + if (old >= lsn) + return; - log_sys.buf_free %= OS_FILE_LOG_BLOCK_SIZE; - log_sys.buf_next_to_write = log_sys.buf_free; -} + const size_t start(calc_lsn_offset(old)); + const size_t end(calc_lsn_offset(lsn)); + if (UNIV_UNLIKELY(end < start)) + { + pmem_persist(log_sys.buf + start, log_sys.file_size - start); + pmem_persist(log_sys.buf + log_sys.START_OFFSET, + end - log_sys.START_OFFSET); + } + else + pmem_persist(log_sys.buf + start, end - start); -/** Invoke commit_checkpoint_notify_ha() to notify that outstanding -log writes have been completed. */ -void log_flush_notify(lsn_t flush_lsn); + old= flushed_to_disk_lsn.load(std::memory_order_relaxed); -/** -Writes log buffer to disk -which is the "write" part of log_write_up_to(). + if (old >= lsn) + return; -This function does not flush anything. + while (!flushed_to_disk_lsn.compare_exchange_weak + (old, lsn, std::memory_order_release, std::memory_order_relaxed)) + if (old >= lsn) + break; -Note : the caller must have log_sys.mutex locked, and this -mutex is released in the function. + log_flush_notify(lsn); + DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE();); +} +#endif +/** Write buf to ib_logfile0. +@tparam release_latch whether to invoke latch.wr_unlock() +@return lsn of a callback pending on write_lock +@retval 0 if everything was written */ -static void log_write(bool rotate_key) +template<bool release_latch> inline lsn_t log_t::write_buf() noexcept { - mysql_mutex_assert_owner(&log_sys.mutex); - lsn_t write_lsn; - if (log_sys.buf_free == log_sys.buf_next_to_write) { - /* Nothing to write */ - mysql_mutex_unlock(&log_sys.mutex); - return; - } - - ut_ad(!recv_no_log_write); - - ulint start_offset; - ulint end_offset; - ulint area_start; - ulint area_end; - ulong write_ahead_size = srv_log_write_ahead_size; - ulint pad_size; - - DBUG_PRINT("ib_log", ("write " LSN_PF " to " LSN_PF, - log_sys.write_lsn, - log_sys.get_lsn())); - - - start_offset = log_sys.buf_next_to_write; - end_offset = log_sys.buf_free; - - area_start = ut_2pow_round(start_offset, - ulint(OS_FILE_LOG_BLOCK_SIZE)); - area_end = ut_calc_align(end_offset, ulint(OS_FILE_LOG_BLOCK_SIZE)); - - ut_ad(area_end - area_start > 0); - - log_block_set_flush_bit(log_sys.buf + area_start, TRUE); - log_block_set_checkpoint_no( - log_sys.buf + area_end - OS_FILE_LOG_BLOCK_SIZE, - log_sys.next_checkpoint_no); - - write_lsn = log_sys.get_lsn(); - byte *write_buf = log_sys.buf; - - log_buffer_switch(); - - log_sys.log.set_fields(log_sys.write_lsn); +#ifndef SUX_LOCK_GENERIC + ut_ad(latch.is_write_locked()); +#endif + ut_ad(!srv_read_only_mode); + ut_ad(!is_pmem()); - mysql_mutex_unlock(&log_sys.mutex); - /* Erase the end of the last log block. */ - memset(write_buf + end_offset, 0, - ~end_offset & (OS_FILE_LOG_BLOCK_SIZE - 1)); + const lsn_t lsn{get_lsn(std::memory_order_relaxed)}; - /* Calculate pad_size if needed. */ - pad_size = 0; - if (write_ahead_size > OS_FILE_LOG_BLOCK_SIZE) { - ulint end_offset_in_unit; - lsn_t end_offset = log_sys.log.calc_lsn_offset( - ut_uint64_align_up(write_lsn, OS_FILE_LOG_BLOCK_SIZE)); - end_offset_in_unit = (ulint) (end_offset % write_ahead_size); + if (write_lsn >= lsn) + { + if (release_latch) + latch.wr_unlock(); + ut_ad(write_lsn == lsn); + } + else + { + ut_ad(!recv_no_log_write); + write_lock.set_pending(lsn); + ut_ad(write_lsn >= get_flushed_lsn()); + const size_t block_size_1{get_block_size() - 1}; + const lsn_t offset{calc_lsn_offset(write_lsn) & ~lsn_t{block_size_1}}; + + DBUG_PRINT("ib_log", ("write " LSN_PF " to " LSN_PF " at " LSN_PF, + write_lsn, lsn, offset)); + const byte *write_buf{buf}; + size_t length{buf_free}; + ut_ad(length >= (calc_lsn_offset(write_lsn) & block_size_1)); + const size_t new_buf_free{length & block_size_1}; + buf_free= new_buf_free; + ut_ad(new_buf_free == ((lsn - first_lsn) & block_size_1)); + + if (new_buf_free) + { +#if 0 /* TODO: Pad the last log block with dummy records. */ + buf_free= log_pad(lsn, get_block_size() - new_buf_free, + buf + new_buf_free, flush_buf); + ... /* TODO: Update the LSN and adjust other code. */ +#else + /* The rest of the block will be written as garbage. + (We want to avoid memset() while holding mutex.) + This block will be overwritten later, once records beyond + the current LSN are generated. */ + MEM_MAKE_DEFINED(buf + length, get_block_size() - new_buf_free); + buf[length]= 0; /* allow recovery to catch EOF faster */ + length&= ~block_size_1; + memcpy_aligned<16>(flush_buf, buf + length, (new_buf_free + 15) & ~15); + length+= get_block_size(); +#endif + } - if (end_offset_in_unit > 0 - && (area_end - area_start) > end_offset_in_unit) { - /* The first block in the unit was initialized - after the last writing. - Needs to be written padded data once. */ - pad_size = std::min<ulint>( - ulint(write_ahead_size) - end_offset_in_unit, - srv_log_buffer_size - area_end); - ::memset(write_buf + area_end, 0, pad_size); - } - } + std::swap(buf, flush_buf); + write_to_log++; + if (release_latch) + latch.wr_unlock(); - if (UNIV_UNLIKELY(srv_shutdown_state > SRV_SHUTDOWN_INITIATED)) { - service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, - "InnoDB log write: " - LSN_PF, log_sys.write_lsn); - } + if (UNIV_UNLIKELY(srv_shutdown_state > SRV_SHUTDOWN_INITIATED)) + { + service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, + "InnoDB log write: " LSN_PF, write_lsn); + } - if (log_sys.is_encrypted()) { - log_crypt(write_buf + area_start, log_sys.write_lsn, - area_end - area_start, - rotate_key ? LOG_ENCRYPT_ROTATE_KEY : LOG_ENCRYPT); - } + /* Do the write to the log file */ + log_write_buf(write_buf, length, offset); + write_lsn= lsn; + } - /* Do the write to the log file */ - log_write_buf( - write_buf + area_start, area_end - area_start + pad_size, -#ifdef UNIV_DEBUG - pad_size, -#endif /* UNIV_DEBUG */ - ut_uint64_align_down(log_sys.write_lsn, - OS_FILE_LOG_BLOCK_SIZE), - start_offset - area_start); - srv_stats.log_padded.add(pad_size); - log_sys.write_lsn = write_lsn; - return; + return write_lock.release(lsn); } -static group_commit_lock write_lock; -static group_commit_lock flush_lock; +inline bool log_t::flush(lsn_t lsn) noexcept +{ + ut_ad(lsn >= get_flushed_lsn()); + flush_lock.set_pending(lsn); + const bool success{srv_file_flush_method == SRV_O_DSYNC || log.flush()}; + if (UNIV_LIKELY(success)) + { + flushed_to_disk_lsn.store(lsn, std::memory_order_release); + log_flush_notify(lsn); + } + return success; +} -#ifdef UNIV_DEBUG -bool log_write_lock_own() +/** Ensure that previous log writes are durable. +@param lsn previously written LSN +@return new durable lsn target +@retval 0 if there are no pending callbacks on flush_lock + or there is another group commit lead. +*/ +static lsn_t log_flush(lsn_t lsn) { - return write_lock.is_owner(); + ut_ad(!log_sys.is_pmem()); + ut_a(log_sys.flush(lsn)); + DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE();); + return flush_lock.release(lsn); } -#endif +static const completion_callback dummy_callback{[](void *) {},nullptr}; /** Ensure that the log has been written to the log file up to a given log entry (such as that of a transaction commit). Start a new write, or wait and check if an already running write is covering the request. -@param[in] lsn log sequence number that should be -included in the redo log file write -@param[in] flush_to_disk whether the written log should also -be flushed to the file system -@param[in] rotate_key whether to rotate the encryption key */ -void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key, +@param lsn log sequence number that should be included in the file write +@param durable whether the write needs to be durable +@param callback log write completion callback */ +void log_write_up_to(lsn_t lsn, bool durable, const completion_callback *callback) { ut_ad(!srv_read_only_mode); - ut_ad(!rotate_key || flush_to_disk); ut_ad(lsn != LSN_MAX); - if (recv_no_ibuf_operations) + if (UNIV_UNLIKELY(recv_no_ibuf_operations)) { - /* Recovery is running and no operations on the log files are - allowed yet (the variable name .._no_ibuf_.. is misleading) */ + /* A non-final batch of recovery is active no writes to the log + are allowed yet. */ ut_a(!callback); return; } -repeat: - lsn_t ret_lsn1= 0, ret_lsn2= 0; + ut_ad(lsn <= log_sys.get_lsn()); - if (flush_to_disk) +#ifdef HAVE_PMEM + if (log_sys.is_pmem()) + { + ut_ad(!callback); + if (durable) + log_sys.persist(lsn); + return; + } +#endif + +repeat: + if (durable) { if (flush_lock.acquire(lsn, callback) != group_commit_lock::ACQUIRED) return; flush_lock.set_pending(log_sys.get_lsn()); } + + + lsn_t pending_write_lsn= 0, pending_flush_lsn= 0; - if (write_lock.acquire(lsn, flush_to_disk ? nullptr : callback) == + if (write_lock.acquire(lsn, durable ? nullptr : callback) == group_commit_lock::ACQUIRED) { - mysql_mutex_lock(&log_sys.mutex); - lsn_t write_lsn= log_sys.get_lsn(); - write_lock.set_pending(write_lsn); - if (flush_to_disk) - flush_lock.set_pending(write_lsn); - log_write(rotate_key); - - ut_a(log_sys.write_lsn == write_lsn); - ret_lsn1= write_lock.release(write_lsn); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + pending_write_lsn= log_sys.write_buf<true>(); } - if (flush_to_disk) + if (durable) { - /* Flush the highest written lsn.*/ - auto flush_lsn = write_lock.value(); - flush_lock.set_pending(flush_lsn); - log_write_flush_to_disk_low(flush_lsn); - ret_lsn2= flush_lock.release(flush_lsn); - - log_flush_notify(flush_lsn); - DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE();); + pending_flush_lsn= log_flush(write_lock.value()); } - if (ret_lsn1 || ret_lsn2) + if (pending_write_lsn || pending_flush_lsn) { - /* - There is no new group commit lead, some async waiters could stall. - Rerun log_write_up_to(), to prevent that. - */ - lsn= std::max(ret_lsn1, ret_lsn2); - static const completion_callback dummy{[](void *) {},nullptr}; - callback= &dummy; + /* There is no new group commit lead; some async waiters could stall. */ + callback= &dummy_callback; + lsn= std::max(pending_write_lsn, pending_flush_lsn); goto repeat; } } /** Write to the log file up to the last log entry. -@param sync whether to wait for a durable write to complete */ -void log_buffer_flush_to_disk(bool sync) +@param durable whether to wait for a durable write to complete */ +void log_buffer_flush_to_disk(bool durable) { ut_ad(!srv_read_only_mode); - log_write_up_to(log_sys.get_lsn(std::memory_order_acquire), sync); + log_write_up_to(log_sys.get_lsn(std::memory_order_acquire), durable); } -/** Prepare to invoke log_write_and_flush(), before acquiring log_sys.mutex. */ +/** Prepare to invoke log_write_and_flush(), before acquiring log_sys.latch. */ ATTRIBUTE_COLD void log_write_and_flush_prepare() { - mysql_mutex_assert_not_owner(&log_sys.mutex); + if (log_sys.is_pmem()) + return; while (flush_lock.acquire(log_sys.get_lsn() + 1, nullptr) != group_commit_lock::ACQUIRED); @@ -888,20 +762,19 @@ ATTRIBUTE_COLD void log_write_and_flush_prepare() group_commit_lock::ACQUIRED); } -/** Durably write the log and release log_sys.mutex */ +/** Durably write the log up to log_sys.get_lsn(). */ ATTRIBUTE_COLD void log_write_and_flush() { ut_ad(!srv_read_only_mode); - auto lsn= log_sys.get_lsn(); - write_lock.set_pending(lsn); - log_write(false); - ut_a(log_sys.write_lsn == lsn); - write_lock.release(lsn); - - lsn= write_lock.value(); - flush_lock.set_pending(lsn); - log_write_flush_to_disk_low(lsn); - flush_lock.release(lsn); + if (!log_sys.is_pmem()) + { + log_sys.write_buf<false>(); + log_flush(write_lock.value()); + } +#ifdef HAVE_PMEM + else + log_sys.persist(log_sys.get_lsn()); +#endif } /******************************************************************** @@ -910,90 +783,8 @@ Tries to establish a big enough margin of free space in the log buffer, such that a new log entry can be catenated without an immediate need for a flush. */ ATTRIBUTE_COLD static void log_flush_margin() { - lsn_t lsn = 0; - - mysql_mutex_lock(&log_sys.mutex); - - if (log_sys.buf_free > log_sys.max_buf_free) { - /* We can write during flush */ - lsn = log_sys.get_lsn(); - } - - mysql_mutex_unlock(&log_sys.mutex); - - if (lsn) { - log_write_up_to(lsn, false); - } -} - -/** Write checkpoint info to the log header and release log_sys.mutex. -@param[in] end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */ -ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn) -{ - ut_ad(!srv_read_only_mode); - ut_ad(end_lsn == 0 || end_lsn >= log_sys.next_checkpoint_lsn); - ut_ad(end_lsn <= log_sys.get_lsn()); - ut_ad(end_lsn + SIZE_OF_FILE_CHECKPOINT <= log_sys.get_lsn() - || srv_shutdown_state > SRV_SHUTDOWN_INITIATED); - - DBUG_PRINT("ib_log", ("checkpoint " UINT64PF " at " LSN_PF - " written", - log_sys.next_checkpoint_no, - log_sys.next_checkpoint_lsn)); - - byte* buf = log_sys.checkpoint_buf; - memset_aligned<OS_FILE_LOG_BLOCK_SIZE>(buf, 0, OS_FILE_LOG_BLOCK_SIZE); - - mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys.next_checkpoint_no); - mach_write_to_8(buf + LOG_CHECKPOINT_LSN, log_sys.next_checkpoint_lsn); - - if (log_sys.is_encrypted()) { - log_crypt_write_checkpoint_buf(buf); - } - - lsn_t lsn_offset - = log_sys.log.calc_lsn_offset(log_sys.next_checkpoint_lsn); - mach_write_to_8(buf + LOG_CHECKPOINT_OFFSET, lsn_offset); - mach_write_to_8(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, - srv_log_buffer_size); - mach_write_to_8(buf + LOG_CHECKPOINT_END_LSN, end_lsn); - - log_block_store_checksum(buf); - - ut_ad(LOG_CHECKPOINT_1 < srv_page_size); - ut_ad(LOG_CHECKPOINT_2 < srv_page_size); - - ut_ad(!log_sys.checkpoint_pending); - log_sys.checkpoint_pending = true; - - mysql_mutex_unlock(&log_sys.mutex); - - /* Note: We alternate the physical place of the checkpoint info. - See the (next_checkpoint_no & 1) below. */ - - log_sys.log.write((log_sys.next_checkpoint_no & 1) ? LOG_CHECKPOINT_2 - : LOG_CHECKPOINT_1, - {buf, OS_FILE_LOG_BLOCK_SIZE}); - - log_sys.log.flush(); - - mysql_mutex_lock(&log_sys.mutex); - - ut_ad(log_sys.checkpoint_pending); - log_sys.checkpoint_pending = false; - - log_sys.next_checkpoint_no++; - - log_sys.last_checkpoint_lsn = log_sys.next_checkpoint_lsn; - - DBUG_PRINT("ib_log", ("checkpoint ended at " LSN_PF - ", flushed to " LSN_PF, - lsn_t{log_sys.last_checkpoint_lsn}, - log_sys.get_flushed_lsn())); - - MONITOR_INC(MONITOR_NUM_CHECKPOINT); - - mysql_mutex_unlock(&log_sys.mutex); + if (log_sys.buf_free > log_sys.max_buf_free) + log_buffer_flush_to_disk(false); } /****************************************************************//** @@ -1005,26 +796,27 @@ ATTRIBUTE_COLD static void log_checkpoint_margin() { while (log_sys.check_flush_or_checkpoint()) { - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.rd_lock(SRW_LOCK_CALL); ut_ad(!recv_no_log_write); if (!log_sys.check_flush_or_checkpoint()) { func_exit: - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.rd_unlock(); return; } const lsn_t lsn= log_sys.get_lsn(); const lsn_t checkpoint= log_sys.last_checkpoint_lsn; const lsn_t sync_lsn= checkpoint + log_sys.max_checkpoint_age; + if (lsn <= sync_lsn) { log_sys.set_check_flush_or_checkpoint(false); goto func_exit; } - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.rd_unlock(); /* We must wait to prevent the tail of the log overwriting the head. */ buf_flush_wait_flushed(std::min(sync_lsn, checkpoint + (1U << 20))); @@ -1173,24 +965,6 @@ wait_suspend_loop: buf_flush_buffer_pool(); } - if (log_sys.is_initialised()) { - mysql_mutex_lock(&log_sys.mutex); - const size_t n_write{log_sys.checkpoint_pending}; - const size_t n_flush{log_sys.get_pending_flushes()}; - mysql_mutex_unlock(&log_sys.mutex); - - if (n_write || n_flush) { - if (srv_print_verbose_log && count > 600) { - ib::info() << "Pending checkpoint_writes: " - << n_write - << ". Pending log flush writes: " - << n_flush; - count = 0; - } - goto loop; - } - } - if (srv_fast_shutdown == 2 || !srv_was_started) { if (!srv_read_only_mode && srv_was_started) { ib::info() << "Executing innodb_fast_shutdown=2." @@ -1215,24 +989,25 @@ wait_suspend_loop: "ensuring dirty buffer pool are written to log"); log_make_checkpoint(); - mysql_mutex_lock(&log_sys.mutex); + const auto sizeof_cp = log_sys.is_encrypted() + ? SIZE_OF_FILE_CHECKPOINT + 8 + : SIZE_OF_FILE_CHECKPOINT; + + log_sys.latch.rd_lock(SRW_LOCK_CALL); lsn = log_sys.get_lsn(); const bool lsn_changed = lsn != log_sys.last_checkpoint_lsn - && lsn != log_sys.last_checkpoint_lsn - + SIZE_OF_FILE_CHECKPOINT; + && lsn != log_sys.last_checkpoint_lsn + sizeof_cp; ut_ad(lsn >= log_sys.last_checkpoint_lsn); - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.rd_unlock(); if (lsn_changed) { goto loop; } - - log_sys.log.flush(); } else { - lsn = recv_sys.recovered_lsn; + lsn = recv_sys.lsn; } srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; @@ -1247,23 +1022,14 @@ wait_suspend_loop: ut_a(lsn == log_sys.get_lsn() || srv_force_recovery == SRV_FORCE_NO_LOG_REDO); - if (UNIV_UNLIKELY(lsn < recv_sys.recovered_lsn)) { - ib::error() << "Shutdown LSN=" << lsn - << " is less than start LSN=" - << recv_sys.recovered_lsn; + if (UNIV_UNLIKELY(lsn < recv_sys.lsn)) { + sql_print_error("InnoDB: Shutdown LSN=" LSN_PF + " is less than start LSN=" LSN_PF, + lsn, recv_sys.lsn); } srv_shutdown_lsn = lsn; - if (!srv_read_only_mode) { - dberr_t err = fil_write_flushed_lsn(lsn); - - if (err != DB_SUCCESS) { - ib::error() << "Writing flushed lsn " << lsn - << " failed; error=" << err; - } - } - /* Make some checks that the server really is quiet */ ut_ad(!srv_any_background_activity()); @@ -1278,10 +1044,7 @@ log_print( /*======*/ FILE* file) /*!< in: file where to print */ { - double time_elapsed; - time_t current_time; - - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.rd_lock(SRW_LOCK_CALL); const lsn_t lsn= log_sys.get_lsn(); mysql_mutex_lock(&buf_pool.flush_list_mutex); @@ -1298,40 +1061,7 @@ log_print( pages_flushed, lsn_t{log_sys.last_checkpoint_lsn}); - current_time = time(NULL); - - time_elapsed = difftime(current_time, - log_sys.last_printout_time); - - if (time_elapsed <= 0) { - time_elapsed = 1; - } - - fprintf(file, - ULINTPF " pending log flushes, " - ULINTPF " pending chkp writes\n" - ULINTPF " log i/o's done, %.2f log i/o's/second\n", - log_sys.pending_flushes.load(), - ulint{log_sys.checkpoint_pending}, - log_sys.n_log_ios, - static_cast<double>( - log_sys.n_log_ios - log_sys.n_log_ios_old) - / time_elapsed); - - log_sys.n_log_ios_old = log_sys.n_log_ios; - log_sys.last_printout_time = current_time; - - mysql_mutex_unlock(&log_sys.mutex); -} - -/**********************************************************************//** -Refreshes the statistics used to print per-second averages. */ -void -log_refresh_stats(void) -/*===================*/ -{ - log_sys.n_log_ios_old = log_sys.n_log_ios; - log_sys.last_printout_time = time(NULL); + log_sys.latch.rd_unlock(); } /** Shut down the redo log subsystem. */ @@ -1339,21 +1069,27 @@ void log_t::close() { ut_ad(this == &log_sys); if (!is_initialised()) return; - m_initialised= false; - log.close(); + close_file(); - ut_free_dodump(buf, srv_log_buffer_size); +#ifndef HAVE_PMEM + ut_free_dodump(buf, buf_size); buf= nullptr; - ut_free_dodump(flush_buf, srv_log_buffer_size); + ut_free_dodump(flush_buf, buf_size); flush_buf= nullptr; + aligned_free(checkpoint_buf); + checkpoint_buf= nullptr; +#else + ut_ad(!checkpoint_buf); + ut_ad(!buf); + ut_ad(!flush_buf); +#endif - mysql_mutex_destroy(&mutex); - mysql_mutex_destroy(&flush_order_mutex); + latch.destroy(); + destroy_lsn_lock(); recv_sys.close(); - aligned_free(checkpoint_buf); - checkpoint_buf= nullptr; + max_buf_free= 0; } std::string get_log_file_path(const char *filename) @@ -1377,23 +1113,3 @@ std::string get_log_file_path(const char *filename) return path; } - -std::vector<std::string> get_existing_log_files_paths() { - std::vector<std::string> result; - - for (int i= 0; i < 101; i++) { - auto path= get_log_file_path(LOG_FILE_NAME_PREFIX) - .append(std::to_string(i)); - os_file_stat_t stat; - dberr_t err= os_file_get_status(path.c_str(), &stat, false, true); - if (err) - break; - - if (stat.type != OS_FILE_TYPE_FILE) - break; - - result.push_back(std::move(path)); - } - - return result; -} diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 183500e19c3..a53bf30edf0 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -62,7 +62,7 @@ recv_sys_t recv_sys; bool recv_needed_recovery; #ifdef UNIV_DEBUG /** TRUE if writing to the redo log (mtr_commit) is forbidden. -Protected by log_sys.mutex. */ +Protected by log_sys.latch. */ bool recv_no_log_write = false; #endif /* UNIV_DEBUG */ @@ -279,19 +279,19 @@ public: memset_aligned<8>(FIL_PAGE_PREV + frame, 0xff, 8); mach_write_to_4(frame + FIL_PAGE_SPACE_ID, block.page.id().space()); last_offset= FIL_PAGE_TYPE; - next_after_applying: + next_after_applying: if (applied == APPLIED_NO) applied= APPLIED_YES; } else { - record_corrupted: + record_corrupted: if (!srv_force_recovery) { recv_sys.set_corrupt_log(); return applied; } - next_not_same_page: + next_not_same_page: last_offset= 1; /* the next record must not be same_page */ } l+= rlen; @@ -1185,31 +1185,17 @@ inline void recv_sys_t::trim(const page_id_t page_id, lsn_t lsn) DBUG_VOID_RETURN; } -void recv_sys_t::open_log_files_if_needed() +inline void recv_sys_t::read(os_offset_t total_offset, span<byte> buf) { - if (!recv_sys.files.empty()) - return; - - for (auto &&path : get_existing_log_files_paths()) - { - recv_sys.files.emplace_back(std::move(path)); - ut_a(recv_sys.files.back().open(true) == DB_SUCCESS); - } -} - -void recv_sys_t::read(os_offset_t total_offset, span<byte> buf) -{ - open_log_files_if_needed(); - - size_t file_idx= static_cast<size_t>(total_offset / log_sys.log.file_size); - os_offset_t offset= total_offset % log_sys.log.file_size; + size_t file_idx= static_cast<size_t>(total_offset / log_sys.file_size); + os_offset_t offset= total_offset % log_sys.file_size; dberr_t err= recv_sys.files[file_idx].read(offset, buf); ut_a(err == DB_SUCCESS); } inline size_t recv_sys_t::files_size() { - open_log_files_if_needed(); + ut_ad(!files.empty()); return files.size(); } @@ -1295,12 +1281,14 @@ same_space: sql_print_error("InnoDB: Tablespace " UINT32PF " has been found" " in two places:" - " '%.*s' and '%s'." + " '%.*s' and '%.*s'." " You must delete" " one of them.", space_id, int(f.name.size()), - f.name.data(), name); + f.name.data(), + int(fname.name.size()), + fname.name.data()); recv_sys.set_corrupt_fs(); } break; @@ -1325,15 +1313,16 @@ same_space: sql_print_information( "InnoDB: At LSN: " LSN_PF - ": unable to open file %s" + ": unable to open file %.*s" " for tablespace " UINT32PF, - recv_sys.recovered_lsn, - name, space_id); + recv_sys.lsn, + int(fname.name.size()), + fname.name.data(), space_id); } break; case FIL_LOAD_DEFER: - /* Skip the deferred spaces + /** Skip the deferred spaces when lsn is already processed */ if (store != store_t::STORE_IF_EXISTS) { deferred_spaces.add( @@ -1394,12 +1383,6 @@ void recv_sys_t::close() deferred_spaces.clear(); ut_d(mysql_mutex_unlock(&mutex)); - if (buf) - { - ut_free_dodump(buf, RECV_PARSING_BUF_SIZE); - buf= nullptr; - } - last_stored_lsn= 0; mysql_mutex_destroy(&mutex); pthread_cond_destroy(&cond); @@ -1422,17 +1405,12 @@ void recv_sys_t::create() apply_log_recs = false; apply_batch_on = false; - buf = static_cast<byte*>(ut_malloc_dontdump(RECV_PARSING_BUF_SIZE, - PSI_INSTRUMENT_ME)); len = 0; - parse_start_lsn = 0; - scanned_lsn = 0; - scanned_checkpoint_no = 0; - recovered_offset = 0; - recovered_lsn = 0; + offset = 0; + lsn = 0; found_corrupt_log = false; found_corrupt_fs = false; - mlog_checkpoint_lsn = 0; + file_checkpoint = 0; progress_time = time(NULL); recv_max_page_lsn = 0; @@ -1473,9 +1451,6 @@ void recv_sys_t::debug_free() recovery_on= false; pages.clear(); - ut_free_dodump(buf, RECV_PARSING_BUF_SIZE); - - buf= nullptr; mysql_mutex_unlock(&mutex); } @@ -1559,176 +1534,11 @@ inline void recv_sys_t::free(const void *data) } -/** Read a log segment to log_sys.buf. -@param[in,out] start_lsn in: read area start, -out: the last read valid lsn -@param[in] end_lsn read area end -@return whether no invalid blocks (e.g checksum mismatch) were found */ -bool log_t::file::read_log_seg(lsn_t* start_lsn, lsn_t end_lsn) +/** @return whether a log_t::FORMAT_10_5 log block checksum matches */ +static bool recv_check_log_block(const byte *buf) { - ulint len; - bool success = true; - mysql_mutex_assert_owner(&log_sys.mutex); - ut_ad(!(*start_lsn % OS_FILE_LOG_BLOCK_SIZE)); - ut_ad(!(end_lsn % OS_FILE_LOG_BLOCK_SIZE)); - byte* buf = log_sys.buf; -loop: - lsn_t source_offset = calc_lsn_offset_old(*start_lsn); - - ut_a(end_lsn - *start_lsn <= ULINT_MAX); - len = (ulint) (end_lsn - *start_lsn); - - ut_ad(len != 0); - - const bool at_eof = (source_offset % file_size) + len > file_size; - if (at_eof) { - /* If the above condition is true then len (which is ulint) - is > the expression below, so the typecast is ok */ - len = ulint(file_size - (source_offset % file_size)); - } - - log_sys.n_log_ios++; - - ut_a((source_offset >> srv_page_size_shift) <= ULINT_MAX); - - recv_sys.read(source_offset, {buf, len}); - - for (ulint l = 0; l < len; l += OS_FILE_LOG_BLOCK_SIZE, - buf += OS_FILE_LOG_BLOCK_SIZE, - (*start_lsn) += OS_FILE_LOG_BLOCK_SIZE) { - const ulint block_number = log_block_get_hdr_no(buf); - - if (block_number != log_block_convert_lsn_to_no(*start_lsn)) { - /* Garbage or an incompletely written log block. - We will not report any error, because this can - happen when InnoDB was killed while it was - writing redo log. We simply treat this as an - abrupt end of the redo log. */ -fail: - end_lsn = *start_lsn; - success = false; - break; - } - - ulint crc = log_block_calc_checksum_crc32(buf); - ulint cksum = log_block_get_checksum(buf); - - DBUG_EXECUTE_IF("log_intermittent_checksum_mismatch", { - static int block_counter; - if (block_counter++ == 0) { - cksum = crc + 1; - } - }); - - DBUG_EXECUTE_IF("log_checksum_mismatch", { cksum = crc + 1; }); - - if (UNIV_UNLIKELY(crc != cksum)) { - ib::error_or_warn(srv_operation!=SRV_OPERATION_BACKUP) - << "Invalid log block checksum. block: " - << block_number - << " checkpoint no: " - << log_block_get_checkpoint_no(buf) - << " expected: " << crc - << " found: " << cksum; - goto fail; - } - - if (is_encrypted() - && !log_crypt(buf, *start_lsn, - OS_FILE_LOG_BLOCK_SIZE, - LOG_DECRYPT)) { - goto fail; - } - - ulint dl = log_block_get_data_len(buf); - if (dl < LOG_BLOCK_HDR_SIZE - || (dl != OS_FILE_LOG_BLOCK_SIZE - && dl > log_sys.trailer_offset())) { - recv_sys.set_corrupt_log(); - goto fail; - } - } - - if (recv_sys.report(time(NULL))) { - sql_print_information("InnoDB: Read redo log up to LSN=" - LSN_PF, *start_lsn); - service_manager_extend_timeout( - INNODB_EXTEND_TIMEOUT_INTERVAL, - "Read redo log up to LSN=" LSN_PF, *start_lsn); - } - - if (*start_lsn != end_lsn) { - goto loop; - } - - return(success); -} - - - -/********************************************************//** -Copies a log segment from the most up-to-date log group to the other log -groups, so that they all contain the latest log data. Also writes the info -about the latest checkpoint to the groups, and inits the fields in the group -memory structs to up-to-date values. */ -static -void -recv_synchronize_groups() -{ - const lsn_t recovered_lsn = recv_sys.recovered_lsn; - - /* Read the last recovered log block to the recovery system buffer: - the block is always incomplete */ - - lsn_t start_lsn = ut_uint64_align_down(recovered_lsn, - OS_FILE_LOG_BLOCK_SIZE); - log_sys.log.read_log_seg(&start_lsn, - start_lsn + OS_FILE_LOG_BLOCK_SIZE); - log_sys.log.set_fields(recovered_lsn); - - /* Copy the checkpoint info to the log; remember that we have - incremented checkpoint_no by one, and the info will not be written - over the max checkpoint info, thus making the preservation of max - checkpoint info on disk certain */ - - if (!srv_read_only_mode) { - log_write_checkpoint_info(0); - mysql_mutex_lock(&log_sys.mutex); - } -} - -/** Check the consistency of a log header block. -@param[in] log header block -@return true if ok */ -static -bool -recv_check_log_header_checksum( - const byte* buf) -{ - return(log_block_get_checksum(buf) - == log_block_calc_checksum_crc32(buf)); -} - -static bool redo_file_sizes_are_correct() -{ - auto paths= get_existing_log_files_paths(); - auto get_size= [](const std::string &path) { - return os_file_get_size(path.c_str()).m_total_size; - }; - os_offset_t size= get_size(paths[0]); - - auto it= - std::find_if(paths.begin(), paths.end(), [&](const std::string &path) { - return get_size(path) != size; - }); - - if (it == paths.end()) - return true; - - sql_print_error("InnoDB: Log file %.*s is of different size " UINT64PF - " bytes than other log files " UINT64PF " bytes!", - int(it->size()), it->data(), get_size(*it), size); - return false; + return mach_read_from_4(my_assume_aligned<4>(508 + buf)) == + my_crc32c(0, buf, 508); } /** Calculate the checksum for a log block using the pre-10.2.2 algorithm. */ @@ -1757,12 +1567,8 @@ inline uint32_t log_block_calc_checksum_format_0(const byte *b) ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() { uint64_t max_no= 0; - byte *buf= log_sys.buf; - - ut_ad(log_sys.log.format == 0); - if (!redo_file_sizes_are_correct()) - return DB_CORRUPTION; + ut_ad(log_sys.format == 0); /** Offset of the first checkpoint checksum */ constexpr uint CHECKSUM_1= 288; @@ -1775,22 +1581,21 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() /** Least significant bits of the checkpoint offset */ constexpr uint OFFS_LO= 16; - lsn_t lsn= 0; - - for (ulint field= LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2; - field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) + lsn_t source_offset= 0; + const lsn_t log_size{(log_sys.file_size - 2048) * recv_sys.files_size()}; + for (size_t field= 512; field < 2048; field+= 1024) { - log_sys.log.read(field, {buf, OS_FILE_LOG_BLOCK_SIZE}); + const byte *buf= log_sys.buf + field; if (static_cast<uint32_t>(ut_fold_binary(buf, CHECKSUM_1)) != mach_read_from_4(buf + CHECKSUM_1) || static_cast<uint32_t>(ut_fold_binary(buf + CHECKPOINT_LSN, CHECKSUM_2 - CHECKPOINT_LSN)) != mach_read_from_4(buf + CHECKSUM_2)) - { - DBUG_LOG("ib_log", "invalid pre-10.2.2 checkpoint " << field); - continue; - } + { + DBUG_PRINT("ib_log", ("invalid pre-10.2.2 checkpoint %zu", field)); + continue; + } if (!log_crypt_101_read_checkpoint(buf)) { @@ -1804,292 +1609,361 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2() checkpoint_no, mach_read_from_8(buf + CHECKPOINT_LSN))); - if (checkpoint_no >= max_no) + if (checkpoint_no < max_no) + continue; + + const lsn_t o= lsn_t{mach_read_from_4(buf + OFFS_HI)} << 32 | + mach_read_from_4(buf + OFFS_LO); + if (o >= 0x80c && (o & ~511) + 512 < log_size) { max_no= checkpoint_no; - lsn= mach_read_from_8(buf + CHECKPOINT_LSN); - log_sys.log.set_lsn(lsn); - log_sys.log.set_lsn_offset(lsn_t{mach_read_from_4(buf + OFFS_HI)} << 32 | - mach_read_from_4(buf + OFFS_LO)); + log_sys.next_checkpoint_lsn= mach_read_from_8(buf + CHECKPOINT_LSN); + source_offset= o; } } - if (!lsn) + const char *uag= srv_operation == SRV_OPERATION_NORMAL + ? "InnoDB: Upgrade after a crash is not supported." + : "mariadb-backup --prepare is not possible."; + + if (!log_sys.next_checkpoint_lsn) { - sql_print_error("InnoDB: Upgrade after a crash is not supported." + sql_print_error("%s" " This redo log was created before MariaDB 10.2.2," " and we did not find a valid checkpoint." " Please follow the instructions at" - " https://mariadb.com/kb/en/library/upgrading/"); + " https://mariadb.com/kb/en/library/upgrading/", uag); return DB_ERROR; } - log_sys.set_lsn(lsn); - log_sys.set_flushed_lsn(lsn); - const lsn_t source_offset= log_sys.log.calc_lsn_offset_old(lsn); - - static constexpr char NO_UPGRADE_RECOVERY_MSG[]= - "InnoDB: Upgrade after a crash is not supported." + static const char pre_10_2[]= " This redo log was created before MariaDB 10.2.2"; - recv_sys.read(source_offset & ~511, {buf, 512}); + byte *buf= const_cast<byte*>(field_ref_zero); + + if (source_offset < (log_sys.is_pmem() ? log_sys.file_size : 4096)) + memcpy_aligned<512>(buf, &log_sys.buf[source_offset & ~511], 512); + else + recv_sys.read(source_offset & ~511, {buf, 512}); - if (log_block_calc_checksum_format_0(buf) != log_block_get_checksum(buf) && - !log_crypt_101_read_block(buf, lsn)) + if (log_block_calc_checksum_format_0(buf) != + mach_read_from_4(my_assume_aligned<4>(buf + 508)) && + !log_crypt_101_read_block(buf, log_sys.next_checkpoint_lsn)) { - sql_print_error("%s, and it appears corrupted.", NO_UPGRADE_RECOVERY_MSG); + sql_print_error("%s%s, and it appears corrupted.", uag, pre_10_2); return DB_CORRUPTION; } if (mach_read_from_2(buf + 4) == (source_offset & 511)) - { - /* Mark the redo log for upgrading. */ - srv_log_file_size= 0; - recv_sys.parse_start_lsn= recv_sys.recovered_lsn= recv_sys.scanned_lsn= - recv_sys.mlog_checkpoint_lsn = lsn; - log_sys.last_checkpoint_lsn= log_sys.next_checkpoint_lsn= - log_sys.write_lsn= log_sys.current_flush_lsn= lsn; - log_sys.next_checkpoint_no= 0; return DB_SUCCESS; - } if (buf[20 + 32 * 9] == 2) sql_print_error("InnoDB: Cannot decrypt log for upgrading." " The encrypted log was created before MariaDB 10.2.2."); else - sql_print_error("%s. You must start up and shut down" + sql_print_error("%s%s. You must start up and shut down" " MariaDB 10.1 or MySQL 5.6 or earlier" " on the data directory.", - NO_UPGRADE_RECOVERY_MSG); + uag, pre_10_2); return DB_ERROR; } -/** Calculate the offset of a log sequence number -in an old redo log file (during upgrade check). -@param[in] lsn log sequence number -@return byte offset within the log */ -inline lsn_t log_t::file::calc_lsn_offset_old(lsn_t lsn) const +/** Determine if a redo log from MariaDB 10.2.2, 10.3, 10.4, or 10.5 is clean. +@param lsn_offset checkpoint LSN offset +@return error code +@retval DB_SUCCESS if the redo log is clean +@retval DB_CORRUPTION if the redo log is corrupted +@retval DB_ERROR if the redo log is not empty */ +static dberr_t recv_log_recover_10_5(lsn_t lsn_offset) { - const lsn_t size= capacity() * recv_sys.files_size(); - lsn_t l= lsn - this->lsn; - if (longlong(l) < 0) + byte *buf= const_cast<byte*>(field_ref_zero); + + if (lsn_offset < (log_sys.is_pmem() ? log_sys.file_size : 4096)) + memcpy_aligned<512>(buf, &log_sys.buf[lsn_offset & ~511], 512); + else + recv_sys.read(lsn_offset & ~511, {buf, 512}); + + if (!recv_check_log_block(buf)) { - l= lsn_t(-longlong(l)) % size; - l= size - l; + sql_print_error("InnoDB: Invalid log header checksum"); + return DB_CORRUPTION; } - l+= lsn_offset - LOG_FILE_HDR_SIZE * (1 + lsn_offset / file_size); - l%= size; - return l + LOG_FILE_HDR_SIZE * (1 + l / (file_size - LOG_FILE_HDR_SIZE)); + if (log_sys.is_encrypted() && + !log_decrypt(buf, log_sys.next_checkpoint_lsn & ~511, 512)) + return DB_ERROR; + + /* On a clean shutdown, the redo log will be logically empty + after the checkpoint lsn. */ + + if (mach_read_from_2(my_assume_aligned<2>(buf + 4)) != (lsn_offset & 511)) + return DB_ERROR; + + return DB_SUCCESS; } -/** Determine if a redo log from MariaDB 10.2.2+, 10.3, or 10.4 is clean. -@return error code -@retval DB_SUCCESS if the redo log is clean -@retval DB_CORRUPTION if the redo log is corrupted -@retval DB_ERROR if the redo log is not empty */ -static dberr_t recv_log_recover_10_4() +dberr_t recv_sys_t::find_checkpoint() { - const lsn_t lsn = log_sys.log.get_lsn(); - const lsn_t source_offset = log_sys.log.calc_lsn_offset_old(lsn); - byte* buf = log_sys.buf; + bool wrong_size= false; + byte *buf; - if (!redo_file_sizes_are_correct()) { - return DB_CORRUPTION; - } + if (files.empty()) + { + file_checkpoint= 0; + std::string path{get_log_file_path()}; + bool success; + os_file_t file{os_file_create_func(path.c_str(), + OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, + OS_FILE_NORMAL, OS_LOG_FILE, + srv_read_only_mode, &success)}; + if (file == OS_FILE_CLOSED) + return DB_ERROR; + const os_offset_t size{os_file_get_size(file)}; + if (!size) + { + if (srv_operation != SRV_OPERATION_NORMAL) + goto too_small; + } + else if (size < log_t::START_OFFSET + SIZE_OF_FILE_CHECKPOINT) + { + too_small: + os_file_close(file); + sql_print_error("InnoDB: File %.*s is too small", + int(path.size()), path.data()); + return DB_ERROR; + } - recv_sys.read(source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1), - {buf, OS_FILE_LOG_BLOCK_SIZE}); + log_sys.attach(file, size); + recv_sys.files.emplace_back(file); + for (int i= 1; i < 101; i++) + { + path= get_log_file_path(LOG_FILE_NAME_PREFIX).append(std::to_string(i)); + file= os_file_create_func(path.c_str(), + OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT | + OS_FILE_ON_ERROR_SILENT, + OS_FILE_NORMAL, OS_LOG_FILE, true, &success); + if (file == OS_FILE_CLOSED) + break; + const os_offset_t sz{os_file_get_size(file)}; + if (size != sz) + { + sql_print_error("InnoDB: Log file %.*s is of different size " UINT64PF + " bytes than other log files " UINT64PF " bytes!", + int(path.size()), path.data(), sz, size); + wrong_size= true; + } + recv_sys.files.emplace_back(file); + } - ulint crc = log_block_calc_checksum_crc32(buf); - ulint cksum = log_block_get_checksum(buf); + if (!size) + { + if (wrong_size) + return DB_CORRUPTION; + if (log_sys.next_checkpoint_lsn < 8204) + { + /* Before MDEV-14425, InnoDB had a minimum LSN of 8192+12=8204. + Likewise, mariadb-backup --prepare would create an empty + ib_logfile0 after applying the log. We will allow an upgrade + from such an empty log. + + If a user replaces the redo log with an empty file and the + FIL_PAGE_FILE_FLUSH_LSN field was zero in the system + tablespace (see SysTablespace::read_lsn_and_check_flags()) we + must refuse to start up. */ + sql_print_error("InnoDB: ib_logfile0 is empty, and LSN is unknown."); + return DB_CORRUPTION; + } + lsn= log_sys.next_checkpoint_lsn; + log_sys.format= log_t::FORMAT_3_23; + goto upgrade; + } + } + else + ut_ad(srv_operation == SRV_OPERATION_BACKUP); + log_sys.next_checkpoint_lsn= 0; + lsn= 0; + buf= my_assume_aligned<4096>(log_sys.buf); + if (!log_sys.is_pmem()) + if (dberr_t err= log_sys.log.read(0, {buf, 4096})) + return err; + /* Check the header page checksum. There was no + checksum in the first redo log format (version 0). */ + log_sys.format= mach_read_from_4(buf + LOG_HEADER_FORMAT); + if (log_sys.format == log_t::FORMAT_3_23) + { + if (wrong_size) + return DB_CORRUPTION; + if (dberr_t err= recv_log_recover_pre_10_2()) + return err; + upgrade: + memset_aligned<512>(const_cast<byte*>(field_ref_zero), 0, 512); + /* Mark the redo log for upgrading. */ + log_sys.last_checkpoint_lsn= log_sys.next_checkpoint_lsn; + log_sys.set_recovered_lsn(log_sys.next_checkpoint_lsn); + lsn= file_checkpoint= log_sys.next_checkpoint_lsn; + log_sys.next_checkpoint_no= 0; + return DB_SUCCESS; + } - if (UNIV_UNLIKELY(crc != cksum)) { - sql_print_error("InnoDB: Invalid log block checksum." - " block: " ULINTPF " checkpoint no: " ULINTPF - " expected: " ULINTPF " found: " ULINTPF, - log_block_get_hdr_no(buf), - log_block_get_checkpoint_no(buf), crc, cksum); - return DB_CORRUPTION; - } + if (!recv_check_log_block(buf)) + { + sql_print_error("InnoDB: Invalid log header checksum"); + return DB_CORRUPTION; + } - if (log_sys.log.is_encrypted() - && !log_crypt(buf, lsn & ~511, 512, LOG_DECRYPT)) { - return DB_ERROR; - } + const lsn_t first_lsn{mach_read_from_8(buf + LOG_HEADER_START_LSN)}; + log_sys.set_first_lsn(first_lsn); + char creator[LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR + 1]; + memcpy(creator, buf + LOG_HEADER_CREATOR, sizeof creator); + /* Ensure that the string is NUL-terminated. */ + creator[LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR]= 0; - /* On a clean shutdown, the redo log will be logically empty - after the checkpoint lsn. */ + lsn_t lsn_offset= 0; - if (log_block_get_data_len(buf) - != (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) { - return DB_ERROR; - } + switch (log_sys.format) { + default: + sql_print_error("InnoDB: Unsupported redo log format." + " The redo log was created with %s.", creator); + return DB_ERROR; + case log_t::FORMAT_10_8: + if (files.size() != 1) + { + sql_print_error("InnoDB: Expecting only ib_logfile0"); + return DB_CORRUPTION; + } - /* Mark the redo log for upgrading. */ - srv_log_file_size = 0; - recv_sys.parse_start_lsn = recv_sys.recovered_lsn - = recv_sys.scanned_lsn - = recv_sys.mlog_checkpoint_lsn = lsn; - log_sys.set_lsn(lsn); - log_sys.set_flushed_lsn(lsn); - log_sys.last_checkpoint_lsn = log_sys.next_checkpoint_lsn - = log_sys.write_lsn = log_sys.current_flush_lsn = lsn; - log_sys.next_checkpoint_no = 0; - return DB_SUCCESS; -} + if (*reinterpret_cast<const uint32_t*>(buf + LOG_HEADER_FORMAT + 4) || + first_lsn < log_t::FIRST_LSN) + { + sql_print_error("InnoDB: Invalid ib_logfile0 header block;" + " the log was created with %s.", creator); + return DB_CORRUPTION; + } -/** Find the latest checkpoint in the log header. -@param[out] max_field LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 -@return error code or DB_SUCCESS */ -dberr_t -recv_find_max_checkpoint(ulint* max_field) -{ - ib_uint64_t max_no; - ib_uint64_t checkpoint_no; - ulint field; - byte* buf; - - max_no = 0; - *max_field = 0; - - buf = log_sys.checkpoint_buf; - - log_sys.log.read(0, {buf, OS_FILE_LOG_BLOCK_SIZE}); - /* Check the header page checksum. There was no - checksum in the first redo log format (version 0). */ - log_sys.log.format = mach_read_from_4(buf + LOG_HEADER_FORMAT); - log_sys.log.subformat = log_sys.log.format != log_t::FORMAT_3_23 - ? mach_read_from_4(buf + LOG_HEADER_SUBFORMAT) - : 0; - if (log_sys.log.format != log_t::FORMAT_3_23 - && !recv_check_log_header_checksum(buf)) { - sql_print_error("InnoDB: Invalid redo log header checksum."); - return DB_CORRUPTION; - } + if (!mach_read_from_4(buf + LOG_HEADER_CREATOR_END)); + else if (!log_crypt_read_header(buf + LOG_HEADER_CREATOR_END)) + { + sql_print_error("InnoDB: Reading log encryption info failed;" + " the log was created with %s.", creator); + return DB_ERROR; + } + else + log_sys.format= log_t::FORMAT_ENC_10_8; - char creator[LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR + 1]; - - memcpy(creator, buf + LOG_HEADER_CREATOR, sizeof creator); - /* Ensure that the string is NUL-terminated. */ - creator[LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR] = 0; - - switch (log_sys.log.format) { - case log_t::FORMAT_3_23: - return recv_log_recover_pre_10_2(); - case log_t::FORMAT_10_2: - case log_t::FORMAT_10_2 | log_t::FORMAT_ENCRYPTED: - case log_t::FORMAT_10_3: - case log_t::FORMAT_10_3 | log_t::FORMAT_ENCRYPTED: - case log_t::FORMAT_10_4: - case log_t::FORMAT_10_4 | log_t::FORMAT_ENCRYPTED: - case log_t::FORMAT_10_5: - case log_t::FORMAT_10_5 | log_t::FORMAT_ENCRYPTED: - break; - default: - sql_print_error("InnoDB: Unsupported redo log format." - " The redo log was created with %s.", creator); - return DB_ERROR; - } + for (size_t field= log_t::CHECKPOINT_1; field <= log_t::CHECKPOINT_2; + field+= log_t::CHECKPOINT_2 - log_t::CHECKPOINT_1) + { + if (log_sys.is_pmem()) + buf= log_sys.buf + field; + else + if (dberr_t err= log_sys.log.read(field, + {buf, log_sys.get_block_size()})) + return err; + const lsn_t checkpoint_lsn{mach_read_from_8(buf)}; + const lsn_t end_lsn{mach_read_from_8(buf + 8)}; + if (checkpoint_lsn < first_lsn || end_lsn < checkpoint_lsn || + memcmp(buf + 16, field_ref_zero, 60 - 16) || + my_crc32c(0, buf, 60) != mach_read_from_4(buf + 60)) + { + DBUG_PRINT("ib_log", ("invalid checkpoint at %zu", field)); + continue; + } - for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2; - field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) { - log_sys.log.read(field, {buf, OS_FILE_LOG_BLOCK_SIZE}); + if (checkpoint_lsn >= log_sys.next_checkpoint_lsn) + { + log_sys.next_checkpoint_lsn= checkpoint_lsn; + log_sys.next_checkpoint_no= field == log_t::CHECKPOINT_1; + lsn= end_lsn; + } + } + if (!log_sys.next_checkpoint_lsn) + goto got_no_checkpoint; + if (!memcmp(creator, "Backup ", 7)) + srv_start_after_restore= true; + return DB_SUCCESS; + case log_t::FORMAT_10_5: + case log_t::FORMAT_10_5 | log_t::FORMAT_ENCRYPTED: + if (files.size() != 1) + { + sql_print_error("InnoDB: Expecting only ib_logfile0"); + return DB_CORRUPTION; + } + /* fall through */ + case log_t::FORMAT_10_2: + case log_t::FORMAT_10_2 | log_t::FORMAT_ENCRYPTED: + case log_t::FORMAT_10_3: + case log_t::FORMAT_10_3 | log_t::FORMAT_ENCRYPTED: + case log_t::FORMAT_10_4: + case log_t::FORMAT_10_4 | log_t::FORMAT_ENCRYPTED: + uint64_t max_no= 0; + const lsn_t log_size{(log_sys.file_size - 2048) * files.size()}; + for (size_t field= 512; field < 2048; field += 1024) + { + const byte *b = buf + field; - const ulint crc32 = log_block_calc_checksum_crc32(buf); - const ulint cksum = log_block_get_checksum(buf); + if (!recv_check_log_block(b)) + { + DBUG_PRINT("ib_log", ("invalid checkpoint checksum at %zu", field)); + continue; + } - if (crc32 != cksum) { - DBUG_PRINT("ib_log", - ("invalid checkpoint," - " at " ULINTPF - ", checksum " ULINTPFx - " expected " ULINTPFx, - field, cksum, crc32)); - continue; - } + if (log_sys.is_encrypted() && !log_crypt_read_checkpoint_buf(b)) + { + sql_print_error("InnoDB: Reading checkpoint encryption info failed."); + continue; + } - if (log_sys.is_encrypted() - && !log_crypt_read_checkpoint_buf(buf)) { - sql_print_error("InnoDB: Reading checkpoint" - " encryption info failed."); - continue; - } + const uint64_t checkpoint_no= mach_read_from_8(b); + const lsn_t checkpoint_lsn= mach_read_from_8(b + 8); + DBUG_PRINT("ib_log", ("checkpoint " UINT64PF " at " LSN_PF " found", + checkpoint_no, checkpoint_lsn)); + const lsn_t o{mach_read_from_8(b + 16)}; + if (checkpoint_no >= max_no && o >= 0x80c && (o & ~511) + 512 < log_size) + { + max_no= checkpoint_no; + log_sys.next_checkpoint_lsn= checkpoint_lsn; + log_sys.next_checkpoint_no= field == 512; + lsn_offset= mach_read_from_8(b + 16); + } + } + } - checkpoint_no = mach_read_from_8( - buf + LOG_CHECKPOINT_NO); - - DBUG_PRINT("ib_log", - ("checkpoint " UINT64PF " at " LSN_PF " found", - checkpoint_no, mach_read_from_8( - buf + LOG_CHECKPOINT_LSN))); - - if (checkpoint_no >= max_no) { - *max_field = field; - max_no = checkpoint_no; - log_sys.log.set_lsn(mach_read_from_8( - buf + LOG_CHECKPOINT_LSN)); - log_sys.log.set_lsn_offset(mach_read_from_8( - buf + LOG_CHECKPOINT_OFFSET)); - log_sys.next_checkpoint_no = checkpoint_no; - } - } + if (!log_sys.next_checkpoint_lsn) + { + got_no_checkpoint: + sql_print_error("InnoDB: No valid checkpoint was found;" + " the log was created with %s.", creator); + return DB_ERROR; + } - if (*max_field == 0) { - /* Before 10.2.2, we could get here during database - initialization if we created an ib_logfile0 file that - was filled with zeroes, and were killed. After - 10.2.2, we would reject such a file already earlier, - when checking the file header. */ - sql_print_error("InnoDB: No valid checkpoint found" - " (corrupted redo log)." - " You can try --innodb-force-recovery=6" - " as a last resort."); - return DB_ERROR; - } + if (wrong_size) + return DB_CORRUPTION; - switch (log_sys.log.format) { - case log_t::FORMAT_10_5: - case log_t::FORMAT_10_5 | log_t::FORMAT_ENCRYPTED: - break; - default: - if (dberr_t err = recv_log_recover_10_4()) { - sql_print_error("InnoDB: Upgrade after a crash " - "is not supported." - " The redo log was created with %s%s.", - creator, - err == DB_ERROR - ? ". You must start up and shut down" - " MariaDB 10.4 or earlier" - " on the data directory" - : ", and it appears corrupted"); - return err; - } - } + if (dberr_t err= recv_log_recover_10_5(lsn_offset)) + { + const char *msg1, *msg2, *msg3; + msg1= srv_operation == SRV_OPERATION_NORMAL + ? "InnoDB: Upgrade after a crash is not supported." + : "mariadb-backup --prepare is not possible."; - return(DB_SUCCESS); -} + if (err == DB_ERROR) + { + msg2= srv_operation == SRV_OPERATION_NORMAL + ? ". You must start up and shut down MariaDB " + : ". You must use mariadb-backup "; + msg3= (log_sys.format & ~log_t::FORMAT_ENCRYPTED) == log_t::FORMAT_10_5 + ? "10.7 or earlier." : "10.4 or earlier."; + } + else + msg2= ", and it appears corrupted.", msg3= ""; -/*******************************************************//** -Calculates the new value for lsn when more data is added to the log. */ -static -lsn_t -recv_calc_lsn_on_data_add( -/*======================*/ - lsn_t lsn, /*!< in: old lsn */ - ib_uint64_t len) /*!< in: this many bytes of data is - added, log block headers not included */ -{ - unsigned frag_len = static_cast<unsigned>(lsn % OS_FILE_LOG_BLOCK_SIZE) - - LOG_BLOCK_HDR_SIZE; - unsigned payload_size = log_sys.payload_size(); - ut_ad(frag_len < payload_size); - lsn_t lsn_len = len; - lsn_len += (lsn_len + frag_len) / payload_size - * (OS_FILE_LOG_BLOCK_SIZE - payload_size); - - return(lsn + lsn_len); + sql_print_error("%s The redo log was created with %s%s%s", + msg1, creator, msg2, msg3); + return err; + } + + goto upgrade; } /** Trim old log records for a page. @@ -2136,7 +2010,7 @@ inline void page_recv_t::will_not_read() @param it page iterator @param start_lsn start LSN of the mini-transaction @param lsn @see mtr_t::commit_lsn() -@param recs redo log snippet @see log_t::FORMAT_10_5 +@param l redo log snippet @param len length of l, in bytes */ inline void recv_sys_t::add(map::iterator it, lsn_t start_lsn, lsn_t lsn, const byte *l, size_t len) @@ -2185,7 +2059,7 @@ append: goto append; } recs.log.append(new (alloc(log_phys_t::alloc_size(len))) - log_phys_t(start_lsn, lsn, l, len)); + log_phys_t{start_lsn, lsn, l, len}); } /** Store/remove the freed pages in fil_name_t of recv_spaces. @@ -2195,8 +2069,6 @@ static void store_freed_or_init_rec(page_id_t page_id, bool freed) { uint32_t space_id= page_id.space(); uint32_t page_no= page_id.page_no(); - if (!freed && page_no == 0 && first_page_init) - first_page_init(space_id); if (is_predefined_tablespace(space_id)) { if (!srv_immediate_scrub_data_uncompressed) @@ -2221,83 +2093,332 @@ static void store_freed_or_init_rec(page_id_t page_id, bool freed) } } -/** Parse and register one mini-transaction in log_t::FORMAT_10_5. -@param checkpoint_lsn the log sequence number of the latest checkpoint -@param store whether to store the records -@param apply whether to apply file-level log records -@return whether FILE_CHECKPOINT record was seen the first time, -or corruption was noticed */ -bool recv_sys_t::parse(lsn_t checkpoint_lsn, store_t *store, bool apply) +/** Wrapper for log_sys.buf[] between recv_sys.offset and recv_sys.len */ +struct recv_buf +{ + bool is_pmem() const noexcept { return log_sys.is_pmem(); } + + const byte *ptr; + + constexpr recv_buf(const byte *ptr) : ptr(ptr) {} + constexpr bool operator==(const recv_buf other) const + { return ptr == other.ptr; } + + static const byte *end() { return &log_sys.buf[recv_sys.len]; } + + const char *get_filename(byte*, size_t) const noexcept + { return reinterpret_cast<const char*>(ptr); } + + bool is_eof(size_t len= 0) const noexcept { return ptr + len >= end(); } + + byte operator*() const noexcept + { + ut_ad(ptr >= log_sys.buf); + ut_ad(ptr < end()); + return *ptr; + } + byte operator[](size_t size) const noexcept { return *(*this + size); } + recv_buf operator+(size_t len) const noexcept + { recv_buf r{*this}; return r+= len; } + recv_buf &operator++() noexcept { return *this+= 1; } + recv_buf &operator+=(size_t len) noexcept { ptr+= len; return *this; } + + size_t operator-(const recv_buf start) const noexcept + { + ut_ad(ptr >= start.ptr); + return size_t(ptr - start.ptr); + } + + uint32_t crc32c(const recv_buf start) const noexcept + { + return my_crc32c(0, start.ptr, ptr - start.ptr); + } + + void *memcpy(void *buf, size_t size) const noexcept + { + ut_ad(size); + ut_ad(!is_eof(size - 1)); + return ::memcpy(buf, ptr, size); + } + + bool is_zero(size_t size) const noexcept + { + ut_ad(!is_eof(size)); + return !memcmp(ptr, field_ref_zero, size); + } + + uint64_t read8() const noexcept + { ut_ad(!is_eof(7)); return mach_read_from_8(ptr); } + uint32_t read4() const noexcept + { ut_ad(!is_eof(3)); return mach_read_from_4(ptr); } + + /** Update the pointer if the new pointer is within the buffer. */ + bool set_if_contains(const byte *pos) noexcept + { + if (pos > end() || pos < ptr) + return false; + ptr= pos; + return true; + } + + /** Get the contiguous, unencrypted buffer. + @param buf return value of copy_if_needed() + @param start start of the mini-transaction + @param decrypt_buf possibly, a copy of the mini-transaction + @return contiguous, non-encrypted buffer */ + const byte *get_buf(const byte *buf, const recv_buf start, + const byte *decrypt_buf) const noexcept + { return ptr == buf ? start.ptr : decrypt_buf; } + + /** Copy and decrypt a log record if needed. + @param iv initialization vector + @param tmp buffer for the decrypted log record + @param start un-encrypted start of the log record + @param len length of the possibly encrypted part, in bytes */ + const byte *copy_if_needed(const byte *iv, byte *tmp, recv_buf start, + size_t len) + { + ut_ad(*this - start + len <= srv_page_size); + if (!len || !log_sys.is_encrypted()) + return ptr; + const size_t s(*this - start); + start.memcpy(tmp, s); + return log_decrypt_buf(iv, tmp + s, ptr, static_cast<uint>(len)); + } +}; + +#ifdef HAVE_PMEM +/** Ring buffer wrapper for log_sys.buf[]; recv_sys.len == log_sys.file_size */ +struct recv_ring : public recv_buf +{ + static constexpr bool is_pmem() { return true; } + + constexpr recv_ring(const byte *ptr) : recv_buf(ptr) {} + + constexpr static bool is_eof() { return false; } + constexpr static bool is_eof(size_t) { return false; } + + byte operator*() const noexcept + { + ut_ad(ptr >= &log_sys.buf[log_sys.START_OFFSET]); + ut_ad(ptr < end()); + return *ptr; + } + byte operator[](size_t size) const noexcept { return *(*this + size); } + recv_ring operator+(size_t len) const noexcept + { recv_ring r{*this}; return r+= len; } + recv_ring &operator++() noexcept { return *this+= 1; } + recv_ring &operator+=(size_t len) noexcept + { + ut_ad(ptr < end()); + ut_ad(ptr >= &log_sys.buf[log_sys.START_OFFSET]); + ut_ad(len < recv_sys.MTR_SIZE_MAX * 2); + ptr+= len; + if (ptr >= end()) + { + ptr-= recv_sys.len - log_sys.START_OFFSET; + ut_ad(ptr >= &log_sys.buf[log_sys.START_OFFSET]); + ut_ad(ptr < end()); + } + return *this; + } + size_t operator-(const recv_ring start) const noexcept + { + auto s= ptr - start.ptr; + return s >= 0 + ? size_t(s) + : size_t(s + recv_sys.len - log_sys.START_OFFSET); + } + + uint32_t crc32c(const recv_ring start) const noexcept + { + return ptr >= start.ptr + ? my_crc32c(0, start.ptr, ptr - start.ptr) + : my_crc32c(my_crc32c(0, start.ptr, end() - start.ptr), + &log_sys.buf[log_sys.START_OFFSET], + ptr - &log_sys.buf[log_sys.START_OFFSET]); + } + + void *memcpy(void *buf, size_t size) const noexcept + { + ut_ad(size); + ut_ad(size < srv_page_size); + + auto s= ptr + size - end(); + if (s <= 0) + return ::memcpy(buf, ptr, size); + ::memcpy(buf, ptr, size - s); + ::memcpy(static_cast<byte*>(buf) + size - s, + &log_sys.buf[log_sys.START_OFFSET], s); + return buf; + } + + bool is_zero(size_t size) const noexcept + { + auto s= ptr + size - end(); + if (s <= 0) + return !memcmp(ptr, field_ref_zero, size); + return !memcmp(ptr, field_ref_zero, size - s) && + !memcmp(&log_sys.buf[log_sys.START_OFFSET], field_ref_zero, s); + } + + uint64_t read8() const noexcept + { + if (UNIV_LIKELY(ptr + 8 <= end())) + return mach_read_from_8(ptr); + byte b[8]; + return mach_read_from_8(static_cast<const byte*>(memcpy(b, 8))); + } + uint32_t read4() const noexcept + { + if (UNIV_LIKELY(ptr + 4 <= end())) + return mach_read_from_4(ptr); + byte b[4]; + return mach_read_from_4(static_cast<const byte*>(memcpy(b, 4))); + } + + /** Get the contiguous, unencrypted buffer. + @param buf return value of copy_if_needed() + @param start start of the mini-transaction + @param decrypt_buf possibly, a copy of the mini-transaction + @return contiguous, non-encrypted buffer */ + const byte *get_buf(const byte *buf, const recv_ring start, + const byte *decrypt_buf) const noexcept + { return ptr == buf && start.ptr < ptr ? start.ptr : decrypt_buf; } + + const char *get_filename(byte* buf, size_t rlen) const noexcept + { + return UNIV_LIKELY(ptr + rlen <= end()) + ? reinterpret_cast<const char*>(ptr) + : static_cast<const char*>(memcpy(buf, rlen)); + } + + /** Copy and decrypt a log record if needed. + @param iv initialization vector + @param tmp buffer for the decrypted log record + @param start un-encrypted start of the log record + @param len length of the possibly encrypted part, in bytes */ + const byte *copy_if_needed(const byte *iv, byte *tmp, recv_ring start, + size_t len) + { + if (!len) + return ptr; + const size_t s(*this - start); + ut_ad(s + len <= srv_page_size); + if (!log_sys.is_encrypted()) + { + if (start.ptr + s == ptr && ptr + len <= end()) + return ptr; + start.memcpy(tmp, s + len); + return tmp + s; + } + + start.memcpy(tmp, s); + + const byte *b= ptr; + if (ptr + len > end()) + b= static_cast<byte*>(memcpy(alloca(len), len)); + return log_decrypt_buf(iv, tmp + s, b, static_cast<uint>(len)); + } +}; +#endif + +/** Parse and register one log_t::FORMAT_10_8 mini-transaction. +@param store whether to store the records +@param l log data source */ +template<typename source> +inline recv_sys_t::parse_mtr_result recv_sys_t::parse(store_t store, source &l) + noexcept { - mysql_mutex_assert_owner(&log_sys.mutex); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked() || + srv_operation == SRV_OPERATION_BACKUP || + srv_operation == SRV_OPERATION_BACKUP_NO_DEFER); +#endif mysql_mutex_assert_owner(&mutex); - ut_ad(parse_start_lsn); - ut_ad(log_sys.is_physical()); + ut_ad(log_sys.next_checkpoint_lsn); + ut_ad(log_sys.is_latest()); - bool last_phase= (*store == STORE_IF_EXISTS); - const byte *const end= buf + len; -loop: - const byte *const log= buf + recovered_offset; - const lsn_t start_lsn= recovered_lsn; - map::iterator cached_pages_it = pages.end(); + alignas(8) byte iv[MY_AES_BLOCK_SIZE]; + byte *decrypt_buf= static_cast<byte*>(alloca(srv_page_size)); + + const lsn_t start_lsn{lsn}; + map::iterator cached_pages_it{pages.end()}; /* Check that the entire mini-transaction is included within the buffer */ - const byte *l; + if (l.is_eof(0)) + return PREMATURE_EOF; + + if (*l <= 1) + return GOT_EOF; /* We should never write an empty mini-transaction. */ + + const source begin{l}; uint32_t rlen; - for (l= log; l < end; l+= rlen) + for (uint32_t total_len= 0; !l.is_eof(); l+= rlen, total_len+= rlen) { - if (!*l) + if (total_len >= MTR_SIZE_MAX) + return GOT_EOF; + if (*l <= 1) goto eom_found; - if (UNIV_LIKELY((*l & 0x70) != RESERVED)); - else if (srv_force_recovery) - sql_print_warning("InnoDB: Ignoring unknown log record at LSN " LSN_PF, - recovered_lsn); - else - { -malformed: - sql_print_error("InnoDB: Malformed log record;" - " set innodb_force_recovery=1 to ignore."); -corrupted: - const size_t trailing_bytes= std::min<size_t>(100, size_t(end - l)); - sql_print_information("InnoDB: Dump from the start of the" - " mini-transaction (LSN=" LSN_PF ") to %zu" - " bytes after the record:", - start_lsn, trailing_bytes); - ut_print_buf(stderr, log, l - log + trailing_bytes); - putc('\n', stderr); - found_corrupt_log= true; - return true; - } - rlen= *l++ & 0xf; - if (l + (rlen ? rlen : 16) >= end) - break; + rlen= *l & 0xf; + ++l; if (!rlen) { + if (l.is_eof(0)) + break; rlen= mlog_decode_varint_length(*l); - if (l + rlen >= end) + if (l.is_eof(rlen)) break; const uint32_t addlen= mlog_decode_varint(l); - if (UNIV_UNLIKELY(addlen == MLOG_DECODE_ERROR)) - { - sql_print_error("InnoDB: Corrupted record length"); - goto corrupted; - } + if (UNIV_UNLIKELY(addlen >= MTR_SIZE_MAX)) + return GOT_EOF; rlen= addlen + 15; } } /* Not the entire mini-transaction was present. */ - return false; + return PREMATURE_EOF; -eom_found: - ut_ad(!*l); - ut_d(const byte *const el= l + 1); + eom_found: + if (*l != log_sys.get_sequence_bit((l - begin) + lsn)) + return GOT_EOF; - const lsn_t end_lsn= recv_calc_lsn_on_data_add(start_lsn, l + 1 - log); - if (UNIV_UNLIKELY(end_lsn > scanned_lsn)) - /* The log record filled a log block, and we require that also the - next log block should have been scanned in */ - return false; + if (l.is_eof(4)) + return PREMATURE_EOF; + + uint32_t crc{l.crc32c(begin)}; + + if (log_sys.is_encrypted()) + { + if (l.is_eof(8 + 4)) + return PREMATURE_EOF; + (l + 1).memcpy(iv, 8); + l+= 8; + crc= my_crc32c(crc, iv, 8); + } + + DBUG_EXECUTE_IF("log_intermittent_checksum_mismatch", + { + static int c; + if (!c++) + { + sql_print_information("Invalid log block checksum"); + return GOT_EOF; + } + }); + + if (crc != (l + 1).read4()) + return GOT_EOF; + + l+= 5; + ut_d(const source el{l}); + lsn+= l - begin; + offset= l.ptr - log_sys.buf; + if (!l.is_pmem()); + else if (offset == log_sys.file_size) + offset= log_sys.START_OFFSET; + else + ut_ad(offset < log_sys.file_size); ut_d(std::set<page_id_t> freed); #if 0 && defined UNIV_DEBUG /* MDEV-21727 FIXME: enable this */ @@ -2312,58 +2433,83 @@ eom_found: uint32_t space_id= 0, page_no= 0, last_offset= 0; bool got_page_op= false; - for (l= log; l < end; l+= rlen) + + for (l= begin;; l+= rlen) { - const byte *const recs= l; - const byte b= *l++; + const source recs{l}; + ++l; + const byte b= *recs; - if (!b) + if (b <= 1) break; - ut_ad(UNIV_LIKELY(b & 0x70) != RESERVED || srv_force_recovery); + + if (UNIV_LIKELY((b & 0x70) != RESERVED)); + else if (srv_force_recovery) + sql_print_warning("InnoDB: Ignoring unknown log record at LSN " LSN_PF, + lsn); + else + { + sql_print_error("InnoDB: Unknown log record at LSN " LSN_PF, lsn); + corrupted: + found_corrupt_log= true; + pthread_cond_broadcast(&cond); + return GOT_EOF; + } + rlen= b & 0xf; - ut_ad(l + rlen < end); - ut_ad(rlen || l + 16 < end); if (!rlen) { const uint32_t lenlen= mlog_decode_varint_length(*l); - ut_ad(l + lenlen < end); const uint32_t addlen= mlog_decode_varint(l); ut_ad(addlen != MLOG_DECODE_ERROR); rlen= addlen + 15 - lenlen; l+= lenlen; } - ut_ad(l + rlen < end); + ut_ad(!l.is_eof(rlen)); + uint32_t idlen; if ((b & 0x80) && got_page_op) { /* This record is for the same page as the previous one. */ if (UNIV_UNLIKELY((b & 0x70) <= INIT_PAGE)) { -record_corrupted: + record_corrupted: /* FREE_PAGE,INIT_PAGE cannot be with same_page flag */ if (!srv_force_recovery) - goto malformed; + { + malformed: + sql_print_error("InnoDB: Malformed log record at LSN " LSN_PF + "; set innodb_force_recovery=1 to ignore.", lsn); + goto corrupted; + } sql_print_warning("InnoDB: Ignoring malformed log record at LSN " - LSN_PF, recovered_lsn); + LSN_PF, lsn); last_offset= 1; /* the next record must not be same_page */ continue; } + if (srv_operation == SRV_OPERATION_BACKUP) + continue; + DBUG_PRINT("ib_log", + ("scan " LSN_PF ": rec %x len %zu page %u:%u", + lsn, b, l - recs + rlen, space_id, page_no)); goto same_page; } last_offset= 0; idlen= mlog_decode_varint_length(*l); if (UNIV_UNLIKELY(idlen > 5 || idlen >= rlen)) { -page_id_corrupted: + if (!*l && b == FILE_CHECKPOINT + 1) + continue; + page_id_corrupted: if (!srv_force_recovery) { sql_print_error("InnoDB: Corrupted page identifier at " LSN_PF "; set innodb_force_recovery=1 to ignore the record.", - recovered_lsn); + lsn); goto corrupted; } sql_print_warning("InnoDB: Ignoring corrupted page identifier at LSN " - LSN_PF, recovered_lsn); + LSN_PF, lsn); continue; } space_id= mlog_decode_varint(l); @@ -2379,12 +2525,21 @@ page_id_corrupted: goto page_id_corrupted; l+= idlen; rlen-= idlen; - got_page_op = !(b & 0x80); - if (got_page_op && apply && !is_predefined_tablespace(space_id)) + mach_write_to_4(iv + 8, space_id); + mach_write_to_4(iv + 12, page_no); + got_page_op= !(b & 0x80); + if (!got_page_op); + else if (srv_operation == SRV_OPERATION_BACKUP) + { + if (page_no == 0 && first_page_init && (b & 0x10)) + first_page_init(space_id); + continue; + } + else if (file_checkpoint && !is_predefined_tablespace(space_id)) { recv_spaces_t::iterator i= recv_spaces.lower_bound(space_id); if (i != recv_spaces.end() && i->first == space_id); - else if (recovered_lsn < mlog_checkpoint_lsn) + else if (lsn < file_checkpoint) /* We have not seen all records between the checkpoint and FILE_CHECKPOINT. There should be a FILE_DELETE for this tablespace later. */ @@ -2395,23 +2550,25 @@ page_id_corrupted: if (!srv_force_recovery) { ib::error() << "Missing FILE_DELETE or FILE_MODIFY for " << id - << " at " << recovered_lsn + << " at " << lsn << "; set innodb_force_recovery=1 to ignore the record."; goto corrupted; } - ib::warn() << "Ignoring record for " << id << " at " << recovered_lsn; + ib::warn() << "Ignoring record for " << id << " at " << lsn; continue; } } -same_page: DBUG_PRINT("ib_log", ("scan " LSN_PF ": rec %x len %zu page %u:%u", - recovered_lsn, b, static_cast<size_t>(l + rlen - recs), - space_id, page_no)); - + lsn, b, l - recs + rlen, space_id, page_no)); if (got_page_op) { - const page_id_t id(space_id, page_no); + same_page: + const byte *cl= l.ptr; + if (!rlen); + else if (UNIV_UNLIKELY(l - recs + rlen > srv_page_size)) + goto record_corrupted; + const page_id_t id{space_id, page_no}; ut_d(if ((b & 0x70) == INIT_PAGE || (b & 0x70) == OPTION) freed.erase(id)); ut_ad(freed.find(id) == freed.end()); @@ -2430,7 +2587,8 @@ same_page: case EXTENDED: if (UNIV_UNLIKELY(!rlen)) goto record_corrupted; - if (rlen == 1 && *l == TRIM_PAGES) + cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); + if (rlen == 1 && *cl == TRIM_PAGES) { #if 0 /* For now, we can only truncate an undo log tablespace */ if (UNIV_UNLIKELY(!space_id || !page_no)) @@ -2442,7 +2600,7 @@ same_page: static_assert(UT_ARR_SIZE(truncated_undo_spaces) == TRX_SYS_MAX_UNDO_SPACES, "compatibility"); truncated_undo_spaces[space_id - srv_undo_space_id_start]= - { recovered_lsn, page_no }; + { lsn, page_no }; #endif last_offset= 1; /* the next record must not be same_page */ continue; @@ -2451,7 +2609,10 @@ same_page: break; case OPTION: if (rlen == 5 && *l == OPT_PAGE_CHECKSUM) + { + cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); break; + } /* fall through */ case RESERVED: continue; @@ -2460,10 +2621,12 @@ same_page: case MEMSET: if (UNIV_UNLIKELY(rlen == 0 || last_offset == 1)) goto record_corrupted; - const uint32_t olen= mlog_decode_varint_length(*l); + ut_d(const source payload{l}); + cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); + const uint32_t olen= mlog_decode_varint_length(*cl); if (UNIV_UNLIKELY(olen >= rlen) || UNIV_UNLIKELY(olen > 3)) goto record_corrupted; - const uint32_t offset= mlog_decode_varint(l); + const uint32_t offset= mlog_decode_varint(cl); ut_ad(offset != MLOG_DECODE_ERROR); static_assert(FIL_PAGE_OFFSET == 4, "compatibility"); if (UNIV_UNLIKELY(offset >= srv_page_size)) @@ -2471,13 +2634,13 @@ same_page: last_offset+= offset; if (UNIV_UNLIKELY(last_offset < 8 || last_offset >= srv_page_size)) goto record_corrupted; - l+= olen; + cl+= olen; rlen-= olen; if ((b & 0x70) == WRITE) { if (UNIV_UNLIKELY(rlen + last_offset > srv_page_size)) goto record_corrupted; - if (UNIV_UNLIKELY(!page_no) && apply) + if (UNIV_UNLIKELY(!page_no) && file_checkpoint) { const bool has_size= last_offset <= FSP_HEADER_OFFSET + FSP_SIZE && last_offset + rlen >= FSP_HEADER_OFFSET + FSP_SIZE + 4; @@ -2488,15 +2651,15 @@ same_page: { recv_spaces_t::iterator it= recv_spaces.find(space_id); const uint32_t size= has_size - ? mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE + l - + ? mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE + cl - last_offset) : 0; const uint32_t flags= has_flags - ? mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + l - + ? mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + cl - last_offset) : file_name_t::initial_flags; if (it == recv_spaces.end()) - ut_ad(!mlog_checkpoint_lsn || space_id == TRX_SYS_SPACE || + ut_ad(!file_checkpoint || space_id == TRX_SYS_SPACE || srv_is_undo_tablespace(space_id)); else if (!it->second.space) { @@ -2508,30 +2671,33 @@ same_page: fil_space_set_recv_size_and_flags(space_id, size, flags); } } + parsed_ok: last_offset+= rlen; + ut_ad(l == payload); + if (!l.set_if_contains(cl)) + (l= recs)+= cl - decrypt_buf; break; } - uint32_t llen= mlog_decode_varint_length(*l); + uint32_t llen= mlog_decode_varint_length(*cl); if (UNIV_UNLIKELY(llen > rlen || llen > 3)) goto record_corrupted; - const uint32_t len= mlog_decode_varint(l); + const uint32_t len= mlog_decode_varint(cl); ut_ad(len != MLOG_DECODE_ERROR); if (UNIV_UNLIKELY(last_offset + len > srv_page_size)) goto record_corrupted; - l+= llen; + cl+= llen; rlen-= llen; llen= len; if ((b & 0x70) == MEMSET) { if (UNIV_UNLIKELY(rlen > llen)) goto record_corrupted; - last_offset+= llen; - break; + goto parsed_ok; } - const uint32_t slen= mlog_decode_varint_length(*l); + const uint32_t slen= mlog_decode_varint_length(*cl); if (UNIV_UNLIKELY(slen != rlen || slen > 3)) goto record_corrupted; - uint32_t s= mlog_decode_varint(l); + uint32_t s= mlog_decode_varint(cl); ut_ad(slen != MLOG_DECODE_ERROR); if (s & 1) s= last_offset - (s >> 1) - 1; @@ -2539,8 +2705,7 @@ same_page: s= last_offset + (s >> 1) + 1; if (UNIV_UNLIKELY(s < 8 || s + llen > srv_page_size)) goto record_corrupted; - last_offset+= llen; - break; + goto parsed_ok; } #if 0 && defined UNIV_DEBUG switch (b & 0x70) { @@ -2555,7 +2720,7 @@ same_page: } #endif const bool is_init= (b & 0x70) <= INIT_PAGE; - switch (*store) { + switch (store) { case STORE_IF_EXISTS: if (fil_space_t *space= fil_space_t::get(space_id)) { @@ -2570,10 +2735,11 @@ same_page: case STORE_YES: if (!mlog_init.will_avoid_read(id, start_lsn)) { - if (cached_pages_it == pages.end() || cached_pages_it->first != id) - cached_pages_it= pages.emplace(id, page_recv_t()).first; - add(cached_pages_it, start_lsn, end_lsn, recs, - static_cast<size_t>(l + rlen - recs)); + if (cached_pages_it == pages.end() || + cached_pages_it->first != id) + cached_pages_it= pages.emplace(id, page_recv_t{}).first; + add(cached_pages_it, start_lsn, lsn, + l.get_buf(cl, recs, decrypt_buf), l - recs + rlen); } continue; case STORE_NO: @@ -2591,41 +2757,42 @@ same_page: { switch (b & 0xf0) { case FILE_CHECKPOINT: - if (space_id == 0 && page_no == 0 && rlen == 8) + if (space_id || page_no || l[rlen] > 1); + else if (rlen != 8) + { + if (rlen < UNIV_PAGE_SIZE_MAX && !l.is_zero(rlen)) + continue; + } + else if (const lsn_t c= l.read8()) { - const lsn_t lsn= mach_read_from_8(l); - if (UNIV_UNLIKELY(srv_print_verbose_log == 2)) fprintf(stderr, "FILE_CHECKPOINT(" LSN_PF ") %s at " LSN_PF "\n", - lsn, lsn != checkpoint_lsn - ? "ignored" - : mlog_checkpoint_lsn ? "reread" : "read", - recovered_lsn); - - DBUG_PRINT("ib_log", ("FILE_CHECKPOINT(" LSN_PF ") %s at " LSN_PF, - lsn, lsn != checkpoint_lsn - ? "ignored" - : mlog_checkpoint_lsn ? "reread" : "read", - recovered_lsn)); - - if (lsn == checkpoint_lsn) + c, c != log_sys.next_checkpoint_lsn + ? "ignored" : file_checkpoint ? "reread" : "read", lsn); + + DBUG_PRINT("ib_log", + ("FILE_CHECKPOINT(" LSN_PF ") %s at " LSN_PF, + c, c != log_sys.next_checkpoint_lsn + ? "ignored" : file_checkpoint ? "reread" : "read", lsn)); + + if (c == log_sys.next_checkpoint_lsn) { /* There can be multiple FILE_CHECKPOINT for the same LSN. */ - if (mlog_checkpoint_lsn) + if (file_checkpoint) continue; - mlog_checkpoint_lsn= recovered_lsn; - l+= 8; - recovered_offset= l - buf; - return true; + file_checkpoint= lsn; + return GOT_EOF; } continue; } + else + continue; /* fall through */ default: if (!srv_force_recovery) goto malformed; sql_print_warning("InnoDB: Ignoring malformed log record at LSN " - LSN_PF, recovered_lsn); + LSN_PF, lsn); continue; case FILE_DELETE: case FILE_MODIFY: @@ -2641,7 +2808,7 @@ same_page: } sql_print_warning("InnoDB: Ignoring corrupted file-level record" - " at LSN " LSN_PF, recovered_lsn); + " at LSN " LSN_PF, lsn); continue; } /* fall through */ @@ -2650,7 +2817,8 @@ same_page: goto file_rec_error; /* There is no terminating NUL character. Names must end in .ibd. For FILE_RENAME, there is a NUL between the two file names. */ - const char * const fn= reinterpret_cast<const char*>(l); + + const char * const fn= l.get_filename(decrypt_buf, rlen); const char *fn2= static_cast<const char*>(memchr(fn, 0, rlen)); if (UNIV_UNLIKELY((fn2 == nullptr) == ((b & 0xf0) == FILE_RENAME))) @@ -2673,21 +2841,25 @@ same_page: if (fnend - fn < 4 || memcmp(fnend - 4, DOT_IBD, 4)) goto file_rec_error; + if (UNIV_UNLIKELY(!recv_needed_recovery && srv_read_only_mode)) + continue; + fil_name_process(fn, fnend - fn, space_id, (b & 0xf0) == FILE_DELETE ? FILE_DELETE : FILE_MODIFY, - start_lsn, *store); + start_lsn, store); if ((b & 0xf0) < FILE_CHECKPOINT && log_file_op) log_file_op(space_id, b & 0xf0, - l, static_cast<ulint>(fnend - fn), + reinterpret_cast<const byte*>(fn), + static_cast<ulint>(fnend - fn), reinterpret_cast<const byte*>(fn2), fn2 ? static_cast<ulint>(fn2end - fn2) : 0); if (fn2) { fil_name_process(fn2, fn2end - fn2, space_id, - FILE_RENAME, start_lsn, *store); - if (apply) + FILE_RENAME, start_lsn, store); + if (file_checkpoint) { const size_t len= fn2end - fn2; auto r= renamed_spaces.emplace(space_id, std::string{fn2, len}); @@ -2697,21 +2869,43 @@ same_page: } if (is_corrupt_fs()) - return true; + return GOT_EOF; } } + else if (b == FILE_CHECKPOINT + 2 && !space_id && !page_no); else goto malformed; } + l+= log_sys.is_encrypted() ? 4U + 8U : 4U; ut_ad(l == el); - recovered_offset= l - buf; - recovered_lsn= end_lsn; - if (is_memory_exhausted(store) && last_phase) - return false; - goto loop; + return OK; } +ATTRIBUTE_NOINLINE +recv_sys_t::parse_mtr_result recv_sys_t::parse_mtr(store_t store) noexcept +{ + recv_buf s{&log_sys.buf[recv_sys.offset]}; + return recv_sys.parse(store, s); +} + +#ifdef HAVE_PMEM +recv_sys_t::parse_mtr_result recv_sys_t::parse_pmem(store_t store) noexcept +{ + recv_sys_t::parse_mtr_result r{parse_mtr(store)}; + if (r != PREMATURE_EOF || !log_sys.is_pmem()) + return r; + ut_ad(recv_sys.len == log_sys.file_size); + ut_ad(recv_sys.offset >= log_sys.START_OFFSET); + ut_ad(recv_sys.offset <= recv_sys.len); + recv_ring s + {recv_sys.offset == recv_sys.len + ? &log_sys.buf[log_sys.START_OFFSET] + : &log_sys.buf[recv_sys.offset]}; + return recv_sys.parse(store, s); +} +#endif + /** Apply the hashed log records to the page, if the page lsn is less than the lsn of a log record. @param[in,out] block buffer pool page @@ -2734,7 +2928,7 @@ static buf_block_t *recv_recover_page(buf_block_t *block, mtr_t &mtr, ut_ad(block->page.id() == p->first); ut_ad(!p->second.is_being_processed()); ut_ad(!space || space->id == block->page.id().space()); - ut_ad(log_sys.is_physical()); + ut_ad(log_sys.is_latest()); if (UNIV_UNLIKELY(srv_print_verbose_log == 2)) { ib::info() << "Applying log to page " << block->page.id(); @@ -2765,7 +2959,7 @@ static buf_block_t *recv_recover_page(buf_block_t *block, mtr_t &mtr, const log_phys_t* l = static_cast<const log_phys_t*>(recv); ut_ad(l->lsn); ut_ad(end_lsn <= l->lsn); - ut_ad(l->lsn <= log_sys.log.scanned_lsn); + ut_ad(l->lsn <= recv_sys.lsn); ut_ad(l->start_lsn); ut_ad(recv_start_lsn <= l->start_lsn); @@ -2909,19 +3103,23 @@ set_start_lsn: if (start_lsn) { ut_ad(end_lsn >= start_lsn); + ut_ad(!block->page.oldest_modification()); mach_write_to_8(FIL_PAGE_LSN + frame, end_lsn); - if (UNIV_LIKELY(frame == block->page.frame)) { + if (UNIV_LIKELY(!block->page.zip.data)) { mach_write_to_8(srv_page_size - FIL_PAGE_END_LSN_OLD_CHKSUM + frame, end_lsn); } else { buf_zip_decompress(block, false); } - - buf_block_modify_clock_inc(block); - mysql_mutex_lock(&log_sys.flush_order_mutex); - buf_flush_note_modification(block, start_lsn, end_lsn); - mysql_mutex_unlock(&log_sys.flush_order_mutex); + /* The following is adapted from + buf_pool_t::insert_into_flush_list() */ + mysql_mutex_lock(&buf_pool.flush_list_mutex); + buf_pool.stat.flush_list_bytes+= block->physical_size(); + block->page.set_oldest_modification(start_lsn); + UT_LIST_ADD_FIRST(buf_pool.flush_list, &block->page); + buf_pool.page_cleaner_wakeup(); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); } else if (free_page && init) { /* There have been no operations that modify the page. Any buffered changes must not be merged. A subsequent @@ -3107,7 +3305,7 @@ inline buf_block_t *recv_sys_t::recover_low(const page_id_t page_id, ut_ad(recs.state == page_recv_t::RECV_WILL_NOT_READ); buf_block_t* block= nullptr; mlog_init_t::init &i= mlog_init.last(page_id); - const lsn_t end_lsn = recs.log.last()->lsn; + const lsn_t end_lsn= recs.log.last()->lsn; if (end_lsn < i.lsn) DBUG_LOG("ib_log", "skip log for page " << page_id << " LSN " << end_lsn << " < " << i.lsn); @@ -3241,30 +3439,26 @@ void recv_sys_t::apply(bool last_batch) srv_operation == SRV_OPERATION_RESTORE || srv_operation == SRV_OPERATION_RESTORE_EXPORT); -#ifdef SAFE_MUTEX - DBUG_ASSERT(!last_batch == mysql_mutex_is_owner(&log_sys.mutex)); -#endif /* SAFE_MUTEX */ - mysql_mutex_lock(&mutex); + mysql_mutex_assert_owner(&mutex); timespec abstime; while (apply_batch_on) { if (is_corrupt_log()) - { - mysql_mutex_unlock(&mutex); return; - } if (last_batch) - { - mysql_mutex_assert_not_owner(&log_sys.mutex); my_cond_wait(&cond, &mutex.m_mutex); - } else { - mysql_mutex_unlock(&mutex); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif + log_sys.latch.wr_unlock(); set_timespec_nsec(abstime, 500000000ULL); /* 0.5s */ - my_cond_timedwait(&cond, &log_sys.mutex.m_mutex, &abstime); + my_cond_timedwait(&cond, &mutex.m_mutex, &abstime); + mysql_mutex_unlock(&mutex); + log_sys.latch.wr_lock(SRW_LOCK_CALL); mysql_mutex_lock(&mutex); } } @@ -3278,11 +3472,11 @@ void recv_sys_t::apply(bool last_batch) if (!pages.empty()) { const char *msg= last_batch - ? "Starting final batch to recover " - : "Starting a batch to recover "; + ? "Starting final batch to recover" + : "Starting a batch to recover"; const size_t n= pages.size(); sql_print_information("InnoDB: %s %zu pages from redo log.", msg, n); - sd_notifyf(0, "STATUS=%s" ULINTPF " pages from redo log", msg, n); + sd_notifyf(0, "STATUS=%s %zu pages from redo log", msg, n); apply_log_recs= true; apply_batch_on= true; @@ -3371,7 +3565,6 @@ next_free_block: { if (last_batch) { - mysql_mutex_assert_not_owner(&log_sys.mutex); if (!empty) my_cond_wait(&cond, &mutex.m_mutex); else @@ -3385,9 +3578,14 @@ next_free_block: } else { - mysql_mutex_unlock(&mutex); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif + log_sys.latch.wr_unlock(); set_timespec_nsec(abstime, 500000000ULL); /* 0.5s */ - my_cond_timedwait(&cond, &log_sys.mutex.m_mutex, &abstime); + my_cond_timedwait(&cond, &mutex.m_mutex, &abstime); + mysql_mutex_unlock(&mutex); + log_sys.latch.wr_lock(SRW_LOCK_CALL); mysql_mutex_lock(&mutex); } continue; @@ -3395,7 +3593,6 @@ next_free_block: if (is_corrupt_fs() && !srv_force_recovery) sql_print_information("InnoDB: Set innodb_force_recovery=1" " to ignore corrupted pages."); - mysql_mutex_unlock(&mutex); return; } } @@ -3406,405 +3603,236 @@ next_free_block: else { mlog_init.reset(); - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.wr_unlock(); } - mysql_mutex_assert_not_owner(&log_sys.mutex); mysql_mutex_unlock(&mutex); if (last_batch && srv_operation != SRV_OPERATION_RESTORE && srv_operation != SRV_OPERATION_RESTORE_EXPORT) + /* Instead of flushing, last_batch sorts the buf_pool.flush_list + in ascending order of buf_page_t::oldest_modification. */ log_sort_flush_list(); else - { - /* Instead of flushing, last_batch could sort the buf_pool.flush_list - in ascending order of buf_page_t::oldest_modification. */ - buf_flush_sync_batch(recovered_lsn); - } + buf_flush_sync_batch(lsn); if (!last_batch) { buf_pool_invalidate(); - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.wr_lock(SRW_LOCK_CALL); } +#ifdef HAVE_PMEM + else if (log_sys.is_pmem()) + mprotect(log_sys.buf, len, PROT_READ | PROT_WRITE); +#endif mysql_mutex_lock(&mutex); ut_d(after_apply= true); clear(); - mysql_mutex_unlock(&mutex); } /** Check whether the number of read redo log blocks exceeds the maximum. -Store last_stored_lsn if the recovery is not in the last phase. -@param[in,out] store whether to store page operations @return whether the memory is exhausted */ -inline bool recv_sys_t::is_memory_exhausted(store_t *store) +inline bool recv_sys_t::is_memory_exhausted() { - if (*store == STORE_NO || - UT_LIST_GET_LEN(blocks) * 3 < buf_pool.get_n_pages()) + if (UT_LIST_GET_LEN(blocks) * 3 < buf_pool.get_n_pages()) return false; - if (*store == STORE_YES) - last_stored_lsn= recovered_lsn; - *store= STORE_NO; DBUG_PRINT("ib_log",("Ran out of memory and last stored lsn " LSN_PF - " last stored offset " ULINTPF "\n", - recovered_lsn, recovered_offset)); + " last stored offset %zu\n", lsn, offset)); return true; } -/** Adds data from a new log block to the parsing buffer of recv_sys if -recv_sys.parse_start_lsn is non-zero. -@param[in] log_block log block to add -@param[in] scanned_lsn lsn of how far we were able to find - data in this log block -@return true if more data added */ -bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn) -{ - ulint more_len; - ulint data_len; - ulint start_offset; - ulint end_offset; - - ut_ad(scanned_lsn >= recv_sys.scanned_lsn); - - if (!recv_sys.parse_start_lsn) { - /* Cannot start parsing yet because no start point for - it found */ - return(false); - } - - data_len = log_block_get_data_len(log_block); - - if (recv_sys.parse_start_lsn >= scanned_lsn) { - - return(false); - - } else if (recv_sys.scanned_lsn >= scanned_lsn) { - - return(false); - - } else if (recv_sys.parse_start_lsn > recv_sys.scanned_lsn) { - more_len = (ulint) (scanned_lsn - recv_sys.parse_start_lsn); - } else { - more_len = (ulint) (scanned_lsn - recv_sys.scanned_lsn); - } - - if (more_len == 0) { - return(false); - } - - ut_ad(data_len >= more_len); - - start_offset = data_len - more_len; - - if (start_offset < LOG_BLOCK_HDR_SIZE) { - start_offset = LOG_BLOCK_HDR_SIZE; - } - - end_offset = std::min<ulint>(data_len, log_sys.trailer_offset()); - - ut_ad(start_offset <= end_offset); - - if (start_offset < end_offset) { - memcpy(recv_sys.buf + recv_sys.len, - log_block + start_offset, end_offset - start_offset); - - recv_sys.len += end_offset - start_offset; - - ut_a(recv_sys.len <= RECV_PARSING_BUF_SIZE); - } - - return(true); -} - -/** Moves the parsing buffer data left to the buffer start. */ -void recv_sys_justify_left_parsing_buf() -{ - memmove(recv_sys.buf, recv_sys.buf + recv_sys.recovered_offset, - recv_sys.len - recv_sys.recovered_offset); - - recv_sys.len -= recv_sys.recovered_offset; - - recv_sys.recovered_offset = 0; -} - -/** Scan redo log from a buffer and stores new log data to the parsing buffer. -Parse and hash the log records if new data found. -Apply log records automatically when the hash table becomes full. -@param[in,out] store whether the records should be - stored into recv_sys.pages; this is - reset if just debug checking is - needed, or when the num_max_blocks in - recv_sys runs out -@param[in] log_block log segment -@param[in] checkpoint_lsn latest checkpoint LSN -@param[in] start_lsn buffer start LSN -@param[in] end_lsn buffer end LSN -@param[in,out] contiguous_lsn it is known that all groups contain - contiguous log data upto this lsn -@param[out] group_scanned_lsn scanning succeeded upto this lsn -@return true if not able to scan any more in this log group */ -static bool recv_scan_log_recs( - store_t* store, - const byte* log_block, - lsn_t checkpoint_lsn, - lsn_t start_lsn, - lsn_t end_lsn, - lsn_t* contiguous_lsn, - lsn_t* group_scanned_lsn) +/** Scan log_t::FORMAT_10_8 log store records to the parsing buffer. +@param last_phase whether changes can be applied to the tablespaces +@return whether rescan is needed (not everything was stored) */ +static bool recv_scan_log(bool last_phase) { - lsn_t scanned_lsn = start_lsn; - bool finished = false; - ulint data_len; - bool more_data = false; - bool apply = recv_sys.mlog_checkpoint_lsn != 0; - ulint recv_parsing_buf_size = RECV_PARSING_BUF_SIZE; - const bool last_phase = (*store == STORE_IF_EXISTS); - ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_ad(end_lsn % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_ad(end_lsn >= start_lsn + OS_FILE_LOG_BLOCK_SIZE); - ut_ad(log_sys.is_physical()); - - const byte* const log_end = log_block - + ulint(end_lsn - start_lsn); - constexpr ulint sizeof_checkpoint= SIZE_OF_FILE_CHECKPOINT; - - do { - ut_ad(!finished); - - if (log_block_get_flush_bit(log_block)) { - /* This block was a start of a log flush operation: - we know that the previous flush operation must have - been completed for all log groups before this block - can have been flushed to any of the groups. Therefore, - we know that log data is contiguous up to scanned_lsn - in all non-corrupt log groups. */ - - if (scanned_lsn > *contiguous_lsn) { - *contiguous_lsn = scanned_lsn; - } - } - - data_len = log_block_get_data_len(log_block); - - if (scanned_lsn + data_len > recv_sys.scanned_lsn - && log_block_get_checkpoint_no(log_block) - < recv_sys.scanned_checkpoint_no - && (recv_sys.scanned_checkpoint_no - - log_block_get_checkpoint_no(log_block) - > 0x80000000UL)) { - - /* Garbage from a log buffer flush which was made - before the most recent database recovery */ - finished = true; - break; - } - - if (!recv_sys.parse_start_lsn - && (log_block_get_first_rec_group(log_block) > 0)) { - - /* We found a point from which to start the parsing - of log records */ - - recv_sys.parse_start_lsn = scanned_lsn - + log_block_get_first_rec_group(log_block); - recv_sys.scanned_lsn = recv_sys.parse_start_lsn; - recv_sys.recovered_lsn = recv_sys.parse_start_lsn; - } - - scanned_lsn += data_len; - - if (data_len == LOG_BLOCK_HDR_SIZE + sizeof_checkpoint - && scanned_lsn == checkpoint_lsn + sizeof_checkpoint - && log_block[LOG_BLOCK_HDR_SIZE] - == (FILE_CHECKPOINT | (SIZE_OF_FILE_CHECKPOINT - 2)) - && checkpoint_lsn == mach_read_from_8( - (LOG_BLOCK_HDR_SIZE + 1 + 2) - + log_block)) { - /* The redo log is logically empty. */ - ut_ad(recv_sys.mlog_checkpoint_lsn == 0 - || recv_sys.mlog_checkpoint_lsn - == checkpoint_lsn); - recv_sys.mlog_checkpoint_lsn = checkpoint_lsn; - DBUG_PRINT("ib_log", ("found empty log; LSN=" LSN_PF, - scanned_lsn)); - finished = true; - break; - } - - if (scanned_lsn > recv_sys.scanned_lsn) { - ut_ad(!srv_log_file_created); - if (!recv_needed_recovery) { - recv_needed_recovery = true; + DBUG_ENTER("recv_scan_log"); + DBUG_ASSERT(!last_phase || recv_sys.file_checkpoint); + + ut_ad(log_sys.is_latest()); + const size_t block_size_1{log_sys.get_block_size() - 1}; + + mysql_mutex_lock(&recv_sys.mutex); + recv_sys.clear(); + ut_d(recv_sys.after_apply= last_phase); + ut_ad(!last_phase || recv_sys.file_checkpoint); + + store_t store= last_phase + ? STORE_IF_EXISTS : recv_sys.file_checkpoint ? STORE_YES : STORE_NO; + size_t buf_size= log_sys.buf_size; +#ifdef HAVE_PMEM + if (log_sys.is_pmem()) + { + recv_sys.offset= size_t(log_sys.calc_lsn_offset(recv_sys.lsn)); + buf_size= size_t(log_sys.file_size); + recv_sys.len= size_t(log_sys.file_size); + } + else +#endif + { + recv_sys.offset= size_t(recv_sys.lsn - log_sys.get_first_lsn()) & + block_size_1; + recv_sys.len= 0; + } - if (srv_read_only_mode) { - sql_print_warning( - "InnoDB: innodb_read_only" - " prevents crash recovery"); - return(true); - } + for (ut_d(lsn_t source_offset= 0);;) + { +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif +#ifdef UNIV_DEBUG + const bool wrap{source_offset + recv_sys.len == log_sys.file_size}; +#endif + if (size_t size= buf_size - recv_sys.len) + { +#ifndef UNIV_DEBUG + lsn_t +#endif + source_offset= + log_sys.calc_lsn_offset(recv_sys.lsn + recv_sys.len - recv_sys.offset); + ut_ad(!wrap || source_offset == log_t::START_OFFSET); + source_offset&= ~block_size_1; - sql_print_information("InnoDB: Starting" - " crash recovery from" - " checkpoint LSN=" LSN_PF - "," LSN_PF, - checkpoint_lsn, - recv_sys.scanned_lsn); - } + if (source_offset + size > log_sys.file_size) + size= static_cast<size_t>(log_sys.file_size - source_offset); - /* We were able to find more log data: add it to the - parsing buffer if parse_start_lsn is already - non-zero */ - - DBUG_EXECUTE_IF( - "reduce_recv_parsing_buf", - recv_parsing_buf_size = RECV_SCAN_SIZE * 2; - ); - - if (recv_sys.len + 4 * OS_FILE_LOG_BLOCK_SIZE - >= recv_parsing_buf_size) { - sql_print_error("InnoDB: Log parsing buffer" - " overflow." - " Recovery may have failed!"); - - recv_sys.set_corrupt_log(); - - if (!srv_force_recovery) { - sql_print_information( - "InnoDB: Set" - " innodb_force_recovery" - " to ignore this error."); - return(true); - } - } else if (!recv_sys.is_corrupt_log()) { - more_data = recv_sys_add_to_parsing_buf( - log_block, scanned_lsn); - } + if (dberr_t err= log_sys.log.read(source_offset, + {log_sys.buf + recv_sys.len, size})) + { + mysql_mutex_unlock(&recv_sys.mutex); + ib::error() << "Failed to read log at " << source_offset + << ": " << err; + recv_sys.set_corrupt_log(); + mysql_mutex_lock(&recv_sys.mutex); + } + else + recv_sys.len+= size; + } - recv_sys.scanned_lsn = scanned_lsn; - recv_sys.scanned_checkpoint_no - = log_block_get_checkpoint_no(log_block); - } + if (recv_sys.report(time(nullptr))) + { + sql_print_information("InnoDB: Read redo log up to LSN=" LSN_PF, + recv_sys.lsn); + service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, + "Read redo log up to LSN=" LSN_PF, + recv_sys.lsn); + } - /* During last phase of scanning, there can be redo logs - left in recv_sys.buf to parse & store it in recv_sys.heap */ - if (last_phase - && recv_sys.recovered_lsn < recv_sys.scanned_lsn) { - more_data = true; - } + recv_sys_t::parse_mtr_result r; - if (data_len < OS_FILE_LOG_BLOCK_SIZE) { - /* Log data for this group ends here */ - finished = true; - break; - } else { - log_block += OS_FILE_LOG_BLOCK_SIZE; - } - } while (log_block < log_end); + if (UNIV_UNLIKELY(!recv_needed_recovery)) + { + ut_ad(store == (recv_sys.file_checkpoint ? STORE_YES : STORE_NO)); + ut_ad(recv_sys.lsn >= log_sys.next_checkpoint_lsn); - *group_scanned_lsn = scanned_lsn; + for (;;) + { + const byte& b{log_sys.buf[recv_sys.offset]}; + r= recv_sys.parse_pmem(store); + if (r == recv_sys_t::OK) + { + if (store == STORE_NO && + (b == FILE_CHECKPOINT + 2 + 8 || (b & 0xf0) == FILE_MODIFY)) + continue; + } + else if (r == recv_sys_t::PREMATURE_EOF) + goto read_more; + else if (store != STORE_NO) + break; - mysql_mutex_lock(&recv_sys.mutex); + if (store == STORE_NO) + { + const lsn_t end{recv_sys.file_checkpoint}; + mysql_mutex_unlock(&recv_sys.mutex); - if (more_data && !recv_sys.is_corrupt_log()) { - /* Try to parse more log records */ - if (recv_sys.parse(checkpoint_lsn, store, apply)) { - ut_ad(recv_sys.is_corrupt_log() - || recv_sys.is_corrupt_fs() - || recv_sys.mlog_checkpoint_lsn - == recv_sys.recovered_lsn); - finished = true; - goto func_exit; - } + if (!end) + { + recv_sys.set_corrupt_log(); + sql_print_error("InnoDB: Missing FILE_CHECKPOINT(" LSN_PF + ") at " LSN_PF, log_sys.next_checkpoint_lsn, + recv_sys.lsn); + } + else + ut_ad(end == recv_sys.lsn); + DBUG_RETURN(true); + } - recv_sys.is_memory_exhausted(store); + recv_needed_recovery= true; + if (srv_read_only_mode) + { + mysql_mutex_unlock(&recv_sys.mutex); + DBUG_RETURN(false); + } + sql_print_information("InnoDB: Starting crash recovery from" + " checkpoint LSN=" LSN_PF, + log_sys.next_checkpoint_lsn); + break; + } + } - if (recv_sys.recovered_offset > recv_parsing_buf_size / 4 - || (recv_sys.recovered_offset - && recv_sys.len - >= recv_parsing_buf_size - RECV_SCAN_SIZE)) { - /* Move parsing buffer data to the buffer start */ - recv_sys_justify_left_parsing_buf(); - } + while ((r= recv_sys.parse_pmem(store)) == recv_sys_t::OK) + { + if (store != STORE_NO && recv_sys.is_memory_exhausted()) + { + ut_ad(last_phase == (store == STORE_IF_EXISTS)); + if (store == STORE_YES) + { + store= STORE_NO; + recv_sys.last_stored_lsn= recv_sys.lsn; + } + else + { + ut_ad(store == STORE_IF_EXISTS); + recv_sys.apply(false); + } + } + } - /* Need to re-parse the redo log which're stored - in recv_sys.buf */ - if (last_phase && *store == STORE_NO) { - finished = false; - } - } + if (r != recv_sys_t::PREMATURE_EOF) + { + ut_ad(r == recv_sys_t::GOT_EOF); + break; + } -func_exit: - recv_sys.maybe_finish_batch(); - mysql_mutex_unlock(&recv_sys.mutex); - return(finished); -} + read_more: +#ifdef HAVE_PMEM + if (log_sys.is_pmem()) + break; +#endif + if (recv_sys.is_corrupt_log()) + break; -/** Scans log from a buffer and stores new log data to the parsing buffer. -Parses and hashes the log records if new data found. -@param[in] checkpoint_lsn latest checkpoint log sequence number -@param[in,out] contiguous_lsn log sequence number -until which all redo log has been scanned -@param[in] last_phase whether changes -can be applied to the tablespaces -@return whether rescan is needed (not everything was stored) */ -static -bool -recv_group_scan_log_recs( - lsn_t checkpoint_lsn, - lsn_t* contiguous_lsn, - bool last_phase) -{ - DBUG_ENTER("recv_group_scan_log_recs"); - DBUG_ASSERT(!last_phase || recv_sys.mlog_checkpoint_lsn > 0); + if (recv_sys.offset < log_sys.get_block_size()) + break; - mysql_mutex_lock(&recv_sys.mutex); - recv_sys.len = 0; - recv_sys.recovered_offset = 0; - recv_sys.clear(); - recv_sys.parse_start_lsn = *contiguous_lsn; - recv_sys.scanned_lsn = *contiguous_lsn; - recv_sys.recovered_lsn = *contiguous_lsn; - recv_sys.scanned_checkpoint_no = 0; - ut_ad(recv_max_page_lsn == 0); - mysql_mutex_unlock(&recv_sys.mutex); + if (recv_sys.offset > buf_size / 4 || + (recv_sys.offset > block_size_1 && + recv_sys.len >= buf_size - recv_sys.MTR_SIZE_MAX)) + { + const size_t ofs{recv_sys.offset & ~block_size_1}; + memmove_aligned<64>(log_sys.buf, log_sys.buf + ofs, recv_sys.len - ofs); + recv_sys.len-= ofs; + recv_sys.offset&= block_size_1; + } + } - lsn_t start_lsn; - lsn_t end_lsn; - store_t store = recv_sys.mlog_checkpoint_lsn == 0 - ? STORE_NO : (last_phase ? STORE_IF_EXISTS : STORE_YES); - - log_sys.log.scanned_lsn = end_lsn = *contiguous_lsn = - ut_uint64_align_down(*contiguous_lsn, OS_FILE_LOG_BLOCK_SIZE); - ut_d(recv_sys.after_apply = last_phase); - - do { - if (last_phase && store == STORE_NO) { - store = STORE_IF_EXISTS; - recv_sys.apply(false); - /* Rescan the redo logs from last stored lsn */ - end_lsn = recv_sys.recovered_lsn; - } + const bool corrupt= recv_sys.is_corrupt_log() || recv_sys.is_corrupt_fs(); + recv_sys.maybe_finish_batch(); + if (last_phase) + log_sys.set_recovered_lsn(recv_sys.lsn); + mysql_mutex_unlock(&recv_sys.mutex); - start_lsn = ut_uint64_align_down(end_lsn, - OS_FILE_LOG_BLOCK_SIZE); - end_lsn = start_lsn; - log_sys.log.read_log_seg(&end_lsn, start_lsn + RECV_SCAN_SIZE); - } while (end_lsn != start_lsn - && !recv_scan_log_recs(&store, log_sys.buf, checkpoint_lsn, - start_lsn, end_lsn, contiguous_lsn, - &log_sys.log.scanned_lsn)); - - if (recv_sys.is_corrupt_log() || recv_sys.is_corrupt_fs()) { - DBUG_RETURN(false); - } + if (corrupt) + DBUG_RETURN(false); - DBUG_PRINT("ib_log", ("%s " LSN_PF " completed", - last_phase ? "rescan" : "scan", - log_sys.log.scanned_lsn)); + DBUG_PRINT("ib_log", + ("%s " LSN_PF " completed", last_phase ? "rescan" : "scan", + recv_sys.lsn)); + ut_ad(!last_phase || recv_sys.lsn >= recv_sys.file_checkpoint); - DBUG_RETURN(store == STORE_NO); + DBUG_RETURN(store == STORE_NO); } /** Report a missing tablespace for which page-redo log exists. @@ -4020,7 +4048,9 @@ recv_init_crash_recovery_spaces(bool rescan, bool& missing_tablespace) static dberr_t recv_rename_files() { mysql_mutex_assert_owner(&recv_sys.mutex); - mysql_mutex_assert_owner(&log_sys.mutex); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif dberr_t err= DB_SUCCESS; @@ -4093,19 +4123,11 @@ done: } /** Start recovering from a redo log checkpoint. -@param[in] flush_lsn FIL_PAGE_FILE_FLUSH_LSN of first system tablespace page @return error code or DB_SUCCESS */ -dberr_t -recv_recovery_from_checkpoint_start(lsn_t flush_lsn) +dberr_t recv_recovery_from_checkpoint_start() { - ulint max_cp_field; - lsn_t checkpoint_lsn; bool rescan = false; - ib_uint64_t checkpoint_no; - lsn_t contiguous_lsn; - byte* buf; - dberr_t err = DB_SUCCESS; ut_ad(srv_operation == SRV_OPERATION_NORMAL || srv_operation == SRV_OPERATION_RESTORE @@ -4123,148 +4145,65 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) recv_sys.recovery_on = true; - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.wr_lock(SRW_LOCK_CALL); - err = recv_find_max_checkpoint(&max_cp_field); - - if (err != DB_SUCCESS) { - recv_sys.recovered_lsn = log_sys.get_lsn(); - mysql_mutex_unlock(&log_sys.mutex); - return(err); + dberr_t err = recv_sys.find_checkpoint(); + if (err != DB_SUCCESS) { +early_exit: + log_sys.latch.wr_unlock(); + return err; } - buf = log_sys.checkpoint_buf; - log_sys.log.read(max_cp_field, {buf, OS_FILE_LOG_BLOCK_SIZE}); - - checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); - checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); + log_sys.set_capacity(); /* Start reading the log from the checkpoint lsn. The variable contiguous_lsn contains an lsn up to which the log is known to be contiguously written. */ - recv_sys.mlog_checkpoint_lsn = 0; - - ut_ad(RECV_SCAN_SIZE <= srv_log_buffer_size); - - const lsn_t end_lsn = mach_read_from_8( - buf + LOG_CHECKPOINT_END_LSN); - - ut_ad(recv_sys.pages.empty()); - contiguous_lsn = checkpoint_lsn; - switch (log_sys.log.format) { - case 0: - mysql_mutex_unlock(&log_sys.mutex); - return DB_SUCCESS; - default: - if (end_lsn == 0) { - break; - } - if (end_lsn >= checkpoint_lsn) { - contiguous_lsn = end_lsn; - break; - } - recv_sys.set_corrupt_log(); - mysql_mutex_unlock(&log_sys.mutex); - return(DB_ERROR); - } - - size_t sizeof_checkpoint; - - if (!log_sys.is_physical()) { - sizeof_checkpoint = 9/* size of MLOG_CHECKPOINT */; - goto completed; - } - /* Look for FILE_CHECKPOINT. */ - recv_group_scan_log_recs(checkpoint_lsn, &contiguous_lsn, false); - /* The first scan should not have stored or applied any records. */ ut_ad(recv_sys.pages.empty()); - ut_ad(!recv_sys.is_corrupt_fs()); - - if (srv_read_only_mode && recv_needed_recovery) { - mysql_mutex_unlock(&log_sys.mutex); - return(DB_READ_ONLY); - } - if (recv_sys.is_corrupt_log() && !srv_force_recovery) { - mysql_mutex_unlock(&log_sys.mutex); - sql_print_warning("InnoDB: Log scan aborted at LSN " LSN_PF, - contiguous_lsn); - return(DB_ERROR); + if (log_sys.format == log_t::FORMAT_3_23) { + goto early_exit; } - if (recv_sys.mlog_checkpoint_lsn == 0) { - lsn_t scan_lsn = log_sys.log.scanned_lsn; - if (!srv_read_only_mode && scan_lsn != checkpoint_lsn) { - mysql_mutex_unlock(&log_sys.mutex); - sql_print_error("InnoDB: Missing FILE_CHECKPOINT" - " at " LSN_PF - " between the checkpoint " LSN_PF - " and the end " LSN_PF ".", - end_lsn, checkpoint_lsn, scan_lsn); - return(DB_ERROR); + if (log_sys.is_latest()) { + const bool rewind = recv_sys.lsn + != log_sys.next_checkpoint_lsn; + log_sys.last_checkpoint_lsn = log_sys.next_checkpoint_lsn; + + recv_scan_log(false); + if (recv_needed_recovery) { +read_only_recovery: + sql_print_warning("InnoDB: innodb_read_only" + " prevents crash recovery"); + err = DB_READ_ONLY; + goto early_exit; } - - log_sys.log.scanned_lsn = checkpoint_lsn; - } else { - contiguous_lsn = checkpoint_lsn; - rescan = recv_group_scan_log_recs( - checkpoint_lsn, &contiguous_lsn, false); - - if ((recv_sys.is_corrupt_log() && !srv_force_recovery) - || recv_sys.is_corrupt_fs()) { - mysql_mutex_unlock(&log_sys.mutex); - return(DB_ERROR); + if (recv_sys.is_corrupt_log()) { + sql_print_error("InnoDB: Log scan aborted at LSN " + LSN_PF, recv_sys.lsn); + goto err_exit; } - } - - /* NOTE: we always do a 'recovery' at startup, but only if - there is something wrong we will print a message to the - user about recovery: */ - sizeof_checkpoint= SIZE_OF_FILE_CHECKPOINT; - -completed: - if (flush_lsn == checkpoint_lsn + sizeof_checkpoint - && recv_sys.mlog_checkpoint_lsn == checkpoint_lsn) { - /* The redo log is logically empty. */ - } else if (checkpoint_lsn != flush_lsn) { - ut_ad(!srv_log_file_created); - - if (checkpoint_lsn + sizeof_checkpoint < flush_lsn) { - sql_print_warning("InnoDB: Are you sure you are using" - " the right ib_logfile0" - " to start up the database?" - " The checkpoint is " LSN_PF - ", less than the" - " log sequence number " LSN_PF - " in the system tablespace.", - checkpoint_lsn, flush_lsn); + ut_ad(recv_sys.file_checkpoint); + if (rewind) { + recv_sys.lsn = log_sys.next_checkpoint_lsn; + recv_sys.offset = 0; + recv_sys.len = 0; } + ut_ad(!recv_max_page_lsn); + rescan = recv_scan_log(false); - if (!recv_needed_recovery) { - sql_print_information( - "InnoDB: The log sequence number " LSN_PF - " in the system tablespace does not match" - " the log checkpoint " LSN_PF - " in ib_logfile0!", flush_lsn, checkpoint_lsn); - - if (srv_read_only_mode) { - sql_print_error("InnoDB: innodb_read_only" - " prevents crash recovery"); - mysql_mutex_unlock(&log_sys.mutex); - return(DB_READ_ONLY); - } + if (srv_read_only_mode && recv_needed_recovery) { + goto read_only_recovery; + } - recv_needed_recovery = true; + if ((recv_sys.is_corrupt_log() && !srv_force_recovery) + || recv_sys.is_corrupt_fs()) { + goto err_exit; } } - log_sys.set_lsn(recv_sys.recovered_lsn); - if (UNIV_LIKELY(log_sys.get_flushed_lsn() < recv_sys.recovered_lsn)) { - /* This may already have been set by create_log_file() - if no logs existed when the server started up. */ - log_sys.set_flushed_lsn(recv_sys.recovered_lsn); - } + log_sys.set_recovered_lsn(recv_sys.lsn); if (recv_needed_recovery) { bool missing_tablespace = false; @@ -4273,8 +4212,7 @@ completed: rescan, missing_tablespace); if (err != DB_SUCCESS) { - mysql_mutex_unlock(&log_sys.mutex); - return(err); + goto early_exit; } /* If there is any missing tablespace and rescan is needed @@ -4284,34 +4222,30 @@ completed: ut_ad(rescan || !missing_tablespace); while (missing_tablespace) { + recv_sys.lsn = recv_sys.last_stored_lsn; DBUG_PRINT("ib_log", ("Rescan of redo log to validate " "the missing tablespace. Scan " "from last stored LSN " LSN_PF, - recv_sys.last_stored_lsn)); - - lsn_t recent_stored_lsn = recv_sys.last_stored_lsn; - rescan = recv_group_scan_log_recs( - checkpoint_lsn, &recent_stored_lsn, false); - + recv_sys.lsn)); + rescan = recv_scan_log(false); ut_ad(!recv_sys.is_corrupt_fs()); missing_tablespace = false; - err = recv_sys.is_corrupt_log() - ? DB_ERROR - : recv_validate_tablespace( - rescan, missing_tablespace); + if (recv_sys.is_corrupt_log()) { + goto err_exit; + } + + err = recv_validate_tablespace( + rescan, missing_tablespace); if (err != DB_SUCCESS) { - mysql_mutex_unlock(&log_sys.mutex); - return err; + goto early_exit; } rescan = true; } - recv_sys.parse_start_lsn = checkpoint_lsn; - if (srv_operation == SRV_OPERATION_NORMAL) { deferred_spaces.deferred_dblwr(); buf_dblwr.recover(); @@ -4320,69 +4254,65 @@ completed: ut_ad(srv_force_recovery <= SRV_FORCE_NO_UNDO_LOG_SCAN); if (rescan) { - contiguous_lsn = checkpoint_lsn; - - recv_group_scan_log_recs( - checkpoint_lsn, &contiguous_lsn, true); - + recv_sys.lsn = log_sys.next_checkpoint_lsn; + rescan = recv_scan_log(true); if ((recv_sys.is_corrupt_log() && !srv_force_recovery) || recv_sys.is_corrupt_fs()) { - mysql_mutex_unlock(&log_sys.mutex); - return(DB_ERROR); + goto err_exit; } } } else { - ut_ad(!rescan || recv_sys.pages.empty()); + ut_ad(recv_sys.pages.empty()); } - if (log_sys.is_physical() - && (log_sys.log.scanned_lsn < checkpoint_lsn - || log_sys.log.scanned_lsn < recv_max_page_lsn)) { + if (log_sys.is_latest() + && (recv_sys.lsn < log_sys.next_checkpoint_lsn + || recv_sys.lsn < recv_max_page_lsn)) { sql_print_error("InnoDB: We scanned the log up to " LSN_PF "." " A checkpoint was at " LSN_PF " and the maximum LSN on a database page was " LSN_PF ". It is possible that the" " database is now corrupt!", - log_sys.log.scanned_lsn, checkpoint_lsn, + recv_sys.lsn, + log_sys.next_checkpoint_lsn, recv_max_page_lsn); } - if (recv_sys.recovered_lsn < checkpoint_lsn) { - mysql_mutex_unlock(&log_sys.mutex); - sql_print_error("InnoDB: Recovered only to lsn: " LSN_PF - " checkpoint_lsn: " LSN_PF, - recv_sys.recovered_lsn, checkpoint_lsn); - return(DB_ERROR); + if (recv_sys.lsn < log_sys.next_checkpoint_lsn) { +err_exit: + err = DB_ERROR; + goto early_exit; } - log_sys.next_checkpoint_lsn = checkpoint_lsn; - log_sys.next_checkpoint_no = checkpoint_no + 1; - - recv_synchronize_groups(); - - ut_ad(recv_needed_recovery - || checkpoint_lsn == recv_sys.recovered_lsn); - - log_sys.write_lsn = log_sys.get_lsn(); - log_sys.buf_free = log_sys.write_lsn % OS_FILE_LOG_BLOCK_SIZE; - log_sys.buf_next_to_write = log_sys.buf_free; - - log_sys.last_checkpoint_lsn = checkpoint_lsn; - - if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL - && (~log_t::FORMAT_ENCRYPTED & log_sys.log.format) - == log_t::FORMAT_10_5) { - /* Write a FILE_CHECKPOINT marker as the first thing, - before generating any other redo log. This ensures - that subsequent crash recovery will be possible even - if the server were killed soon after this. */ - fil_names_clear(log_sys.last_checkpoint_lsn, true); + if (!srv_read_only_mode && log_sys.is_latest()) { + ut_ad(log_sys.get_flushed_lsn() == log_sys.get_lsn()); + ut_ad(recv_sys.lsn == log_sys.get_lsn()); + if (!log_sys.is_pmem()) { + const size_t bs_1{log_sys.get_block_size() - 1}; + const size_t ro{recv_sys.offset}; + recv_sys.offset &= bs_1; + memmove_aligned<64>(log_sys.buf, + log_sys.buf + (ro & ~bs_1), + log_sys.get_block_size()); +#ifdef HAVE_PMEM + } else { + mprotect(log_sys.buf, size_t(log_sys.file_size), + PROT_READ | PROT_WRITE); +#endif + } + log_sys.buf_free = recv_sys.offset; + if (recv_needed_recovery + && srv_operation == SRV_OPERATION_NORMAL) { + /* Write a FILE_CHECKPOINT marker as the first thing, + before generating any other redo log. This ensures + that subsequent crash recovery will be possible even + if the server were killed soon after this. */ + fil_names_clear(log_sys.next_checkpoint_lsn); + } } - log_sys.next_checkpoint_no = ++checkpoint_no; - mysql_mutex_lock(&recv_sys.mutex); recv_sys.apply_log_recs = true; recv_no_ibuf_operations = false; @@ -4403,7 +4333,7 @@ completed: err = DB_CORRUPTION; } - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.wr_unlock(); return err; } diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 04e2db8aab4..52152d9a678 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -24,18 +24,15 @@ Mini-transaction buffer Created 11/26/1995 Heikki Tuuri *******************************************************/ -#include "mtr0mtr.h" - +#include "mtr0log.h" #include "buf0buf.h" #include "buf0flu.h" -#include "fsp0sysspace.h" #include "page0types.h" -#include "mtr0log.h" -#include "log0recv.h" -#include "my_cpu.h" +#include "log0crypt.h" #ifdef BTR_CUR_HASH_ADAPT # include "btr0sea.h" #endif +#include "log.h" /** Iterate over a memo block in reverse. */ template <typename Functor> @@ -228,18 +225,19 @@ static void memo_slot_release(mtr_memo_slot_t *slot) default: buf_page_t *bpage= static_cast<buf_page_t*>(object); bpage->unfix(); - switch (auto latch= slot->type & ~MTR_MEMO_MODIFY) { + switch (type) { case MTR_MEMO_PAGE_S_FIX: bpage->lock.s_unlock(); - return; - case MTR_MEMO_PAGE_SX_FIX: - case MTR_MEMO_PAGE_X_FIX: - bpage->lock.u_or_x_unlock(latch == MTR_MEMO_PAGE_SX_FIX); - /* fall through */ + break; case MTR_MEMO_BUF_FIX: - return; + break; + default: + ut_ad(type == MTR_MEMO_PAGE_SX_FIX || + type == MTR_MEMO_PAGE_X_FIX || + type == MTR_MEMO_PAGE_SX_MODIFY || + type == MTR_MEMO_PAGE_X_MODIFY); + bpage->lock.u_or_x_unlock(type & MTR_MEMO_PAGE_SX_FIX); } - ut_ad("invalid type" == 0); } } @@ -355,28 +353,266 @@ struct DebugCheck { }; #endif -/** Release page latches held by the mini-transaction. */ -struct ReleaseBlocks +/** Prepare to insert a modified blcok into flush_list. +@param lsn start LSN of the mini-transaction +@return insert position for insert_into_flush_list() */ +inline buf_page_t *buf_pool_t::prepare_insert_into_flush_list(lsn_t lsn) + noexcept +{ +#ifndef SUX_LOCK_GENERIC + ut_ad(recv_recovery_is_on() || log_sys.latch.is_locked()); +#endif + ut_ad(lsn >= log_sys.last_checkpoint_lsn); + mysql_mutex_assert_owner(&flush_list_mutex); + static_assert(log_t::FIRST_LSN >= 2, "compatibility"); + +rescan: + buf_page_t *prev= UT_LIST_GET_FIRST(flush_list); + if (prev) + { + lsn_t om= prev->oldest_modification(); + if (om == 1) + { + delete_from_flush_list(prev); + goto rescan; + } + ut_ad(om > 2); + if (om <= lsn) + return nullptr; + while (buf_page_t *next= UT_LIST_GET_NEXT(list, prev)) + { + om= next->oldest_modification(); + if (om == 1) + { + delete_from_flush_list(next); + continue; + } + ut_ad(om > 2); + if (om <= lsn) + break; + prev= next; + } + flush_hp.adjust(prev); + } + return prev; +} + +/** Insert a modified block into the flush list. +@param prev insert position (from prepare_insert_into_flush_list()) +@param block modified block +@param lsn start LSN of the mini-transaction that modified the block */ +inline void buf_pool_t::insert_into_flush_list(buf_page_t *prev, + buf_block_t *block, lsn_t lsn) + noexcept { + ut_ad(!fsp_is_system_temporary(block->page.id().space())); + mysql_mutex_assert_owner(&flush_list_mutex); + + MEM_CHECK_DEFINED(block->page.zip.data + ? block->page.zip.data : block->page.frame, + block->physical_size()); + + if (const lsn_t old= block->page.oldest_modification()) + { + if (old > 1) + return; + flush_hp.adjust(&block->page); + UT_LIST_REMOVE(flush_list, &block->page); + } + else + stat.flush_list_bytes+= block->physical_size(); + + ut_ad(stat.flush_list_bytes <= curr_pool_size); + + if (prev) + UT_LIST_INSERT_AFTER(flush_list, prev, &block->page); + else + UT_LIST_ADD_FIRST(flush_list, &block->page); + + block->page.set_oldest_modification(lsn); +} + +/** Update modified pages of the mini-transaction. */ +struct ReleaseModified +{ + buf_page_t *const prev; const lsn_t start, end; - ReleaseBlocks(lsn_t start, lsn_t end) : start(start), end(end) {} + mutable size_t modified= 0; + + ReleaseModified(buf_page_t *prev, lsn_t start, lsn_t end) : + prev(prev), start(start), end(end) + { + ut_ad(start > 2); + ut_ad(end >= start); + } /** @return true always */ bool operator()(mtr_memo_slot_t *slot) const { - if (!slot->object) + if (!slot->object || !(slot->type & MTR_MEMO_MODIFY)) return true; - switch (slot->type) { - case MTR_MEMO_PAGE_X_MODIFY: - case MTR_MEMO_PAGE_SX_MODIFY: + ut_ad(slot->type == MTR_MEMO_PAGE_X_MODIFY || + slot->type == MTR_MEMO_PAGE_SX_MODIFY); + + modified++; + buf_block_t *b= static_cast<buf_block_t*>(slot->object); + ut_ad(b->page.id() < end_page_id); + ut_d(const auto s= b->page.state()); + ut_ad(s > buf_page_t::FREED); + ut_ad(s < buf_page_t::READ_FIX); + ut_ad(mach_read_from_8(b->page.frame + FIL_PAGE_LSN) <= end); + mach_write_to_8(b->page.frame + FIL_PAGE_LSN, end); + if (UNIV_LIKELY_NULL(b->page.zip.data)) + memcpy_aligned<8>(FIL_PAGE_LSN + b->page.zip.data, + FIL_PAGE_LSN + b->page.frame, 8); + buf_pool.insert_into_flush_list(prev, b, start); + return true; + } +}; + +/** Release latches to already dirtied pages. +This is a bit more than ReleaseAll, +kind of a combination of ReleaseLatches and a subset of ReleaseModified. */ +struct ReleaseSimple +{ + const lsn_t end; + mutable size_t modified; + ReleaseSimple(lsn_t end) : end(end), modified(0) { ut_ad(end); } + + /** @return true always */ + bool operator()(mtr_memo_slot_t *slot) const + { + void *object= slot->object; + if (!object) + return true; + slot->object= nullptr; + switch (const auto type= slot->type) { + case MTR_MEMO_S_LOCK: + static_cast<index_lock*>(object)->s_unlock(); + break; + case MTR_MEMO_SPACE_X_LOCK: + static_cast<fil_space_t*>(object)->set_committed_size(); + static_cast<fil_space_t*>(object)->x_unlock(); + break; + case MTR_MEMO_SPACE_S_LOCK: + static_cast<fil_space_t*>(object)->s_unlock(); + break; + case MTR_MEMO_X_LOCK: + case MTR_MEMO_SX_LOCK: + static_cast<index_lock*>(object)-> + u_or_x_unlock(type == MTR_MEMO_SX_LOCK); break; default: - ut_ad(!(slot->type & MTR_MEMO_MODIFY)); - return true; + buf_page_t *bpage= static_cast<buf_page_t*>(object); + if (type & MTR_MEMO_MODIFY) + { + ut_ad(slot->type == MTR_MEMO_PAGE_X_MODIFY || + slot->type == MTR_MEMO_PAGE_SX_MODIFY); + ut_ad(bpage->oldest_modification() > 1); + ut_ad(bpage->oldest_modification() < end); + ut_ad(bpage->id() < end_page_id); + ut_d(const auto s= bpage->state()); + ut_ad(s > buf_page_t::FREED); + ut_ad(s < buf_page_t::READ_FIX); + ut_ad(mach_read_from_8(bpage->frame + FIL_PAGE_LSN) <= end); + mach_write_to_8(bpage->frame + FIL_PAGE_LSN, end); + if (UNIV_LIKELY_NULL(bpage->zip.data)) + memcpy_aligned<8>(FIL_PAGE_LSN + bpage->zip.data, + FIL_PAGE_LSN + bpage->frame, 8); + modified++; + } + bpage->unfix(); + switch (auto latch= type & ~MTR_MEMO_MODIFY) { + case MTR_MEMO_PAGE_S_FIX: + bpage->lock.s_unlock(); + return true; + case MTR_MEMO_PAGE_SX_FIX: + case MTR_MEMO_PAGE_X_FIX: + bpage->lock.u_or_x_unlock(latch == MTR_MEMO_PAGE_SX_FIX); + /* fall through */ + case MTR_MEMO_BUF_FIX: + return true; + } + ut_ad("invalid type" == 0); } + return true; + } +}; - buf_block_t *block= static_cast<buf_block_t*>(slot->object); - buf_flush_note_modification(block, start, end); +ATTRIBUTE_COLD __attribute__((noinline)) +/** Insert a modified block into buf_pool.flush_list on IMPORT TABLESPACE. */ +static void insert_imported(buf_block_t *block) +{ + ut_d(const auto s= block->page.state()); + ut_ad(s > buf_page_t::FREED); + ut_ad(s < buf_page_t::READ_FIX); + if (block->page.oldest_modification() <= 1) + { + log_sys.latch.rd_lock(SRW_LOCK_CALL); + const lsn_t lsn= log_sys.last_checkpoint_lsn; + mysql_mutex_lock(&buf_pool.flush_list_mutex); + buf_pool.insert_into_flush_list + (buf_pool.prepare_insert_into_flush_list(lsn), block, lsn); + log_sys.latch.rd_unlock(); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + } +} + +/** Release latches to already pages when no log was written. +This is like ReleaseSimple, but it cover pages of the temporary tablespace +as well as pages modified during IMPORT TABLESPACE. */ +struct ReleaseUnlogged +{ + /** @return true always */ + bool operator()(mtr_memo_slot_t *slot) const + { + void *object= slot->object; + if (!object) + return true; + slot->object= nullptr; + switch (const auto type= slot->type) { + case MTR_MEMO_S_LOCK: + static_cast<index_lock*>(object)->s_unlock(); + break; + case MTR_MEMO_SPACE_X_LOCK: + static_cast<fil_space_t*>(object)->set_committed_size(); + static_cast<fil_space_t*>(object)->x_unlock(); + break; + case MTR_MEMO_SPACE_S_LOCK: + static_cast<fil_space_t*>(object)->s_unlock(); + break; + case MTR_MEMO_X_LOCK: + case MTR_MEMO_SX_LOCK: + static_cast<index_lock*>(object)-> + u_or_x_unlock(type == MTR_MEMO_SX_LOCK); + break; + default: + buf_block_t *block= static_cast<buf_block_t*>(object); + block->page.unfix(); + + if (type & MTR_MEMO_MODIFY) + { + ut_ad(type == MTR_MEMO_PAGE_X_MODIFY || + type == MTR_MEMO_PAGE_SX_MODIFY); + if (UNIV_LIKELY(block->page.id() >= end_page_id)) + block->page.set_temp_modified(); + else + insert_imported(block); + } + + switch (type) { + case MTR_MEMO_PAGE_S_FIX: + block->page.lock.s_unlock(); + break; + case MTR_MEMO_BUF_FIX: + break; + default: + ut_ad(type == MTR_MEMO_PAGE_SX_FIX || type == MTR_MEMO_PAGE_X_FIX || + type == MTR_MEMO_PAGE_SX_MODIFY || + type == MTR_MEMO_PAGE_X_MODIFY); + block->page.lock.u_or_x_unlock(type & MTR_MEMO_PAGE_SX_FIX); + } + } return true; } }; @@ -401,6 +637,7 @@ void mtr_t::start() new(&m_log) mtr_buf_t(); m_made_dirty= false; + m_latch_ex= false; m_inside_ibuf= false; m_modifications= false; m_log_mode= MTR_LOG_ALL; @@ -420,6 +657,44 @@ inline void mtr_t::release_resources() ut_d(m_commit= true); } +/** Handle any pages that were freed during the mini-transaction. */ +void mtr_t::process_freed_pages() +{ + if (m_freed_pages) + { + ut_ad(!m_freed_pages->empty()); + ut_ad(m_freed_space); + ut_ad(m_freed_space->is_owner()); + ut_ad(is_named_space(m_freed_space)); + + /* Update the last freed lsn */ + m_freed_space->freed_range_mutex.lock(); + m_freed_space->update_last_freed_lsn(m_commit_lsn); + if (!m_trim_pages) + for (const auto &range : *m_freed_pages) + m_freed_space->add_free_range(range); + else + m_freed_space->clear_freed_ranges(); + m_freed_space->freed_range_mutex.unlock(); + + delete m_freed_pages; + m_freed_pages= nullptr; + m_freed_space= nullptr; + /* mtr_t::start() will reset m_trim_pages */ + } + else + ut_ad(!m_freed_space); +} + +/** Release modified pages when no log was written. */ +void mtr_t::release_unlogged() +{ + ut_ad(m_log_mode == MTR_LOG_NO_REDO); + ut_ad(m_log.size() == 0); + process_freed_pages(); + m_memo.for_each_block_in_reverse(CIterate<ReleaseUnlogged>()); +} + /** Commit a mini-transaction. */ void mtr_t::commit() { @@ -429,73 +704,66 @@ void mtr_t::commit() /* This is a dirty read, for debugging. */ ut_ad(!m_modifications || !recv_no_log_write); ut_ad(!m_modifications || m_log_mode != MTR_LOG_NONE); + ut_ad(!m_latch_ex); if (m_modifications && (m_log_mode == MTR_LOG_NO_REDO || !m_log.empty())) { - ut_ad(!srv_read_only_mode || m_log_mode == MTR_LOG_NO_REDO); + if (UNIV_UNLIKELY(!is_logged())) + { + release_unlogged(); + goto func_exit; + } - std::pair<lsn_t,page_flush_ahead> lsns; + ut_ad(!srv_read_only_mode); + std::pair<lsn_t,page_flush_ahead> lsns{do_write()}; + process_freed_pages(); - if (UNIV_LIKELY(is_logged())) + if (m_made_dirty) { - lsns= do_write(); + mysql_mutex_lock(&buf_pool.flush_list_mutex); + { + CIterate<ReleaseModified> rm + {ReleaseModified{buf_pool.prepare_insert_into_flush_list(lsns.first), + lsns.first, m_commit_lsn}}; + m_memo.for_each_block_in_reverse(rm); + ut_ad(rm.functor.modified); + buf_pool.flush_list_requests+= rm.functor.modified; + } + + buf_pool.page_cleaner_wakeup(); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); - if (m_made_dirty) - mysql_mutex_lock(&log_sys.flush_order_mutex); + if (m_latch_ex) + { + log_sys.latch.wr_unlock(); + m_latch_ex= false; + } + else + log_sys.latch.rd_unlock(); - /* It is now safe to release log_sys.mutex because the - buf_pool.flush_order_mutex will ensure that we are the first one - to insert into buf_pool.flush_list. */ - mysql_mutex_unlock(&log_sys.mutex); + m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>()); } else { - ut_ad(m_log_mode == MTR_LOG_NO_REDO); - ut_ad(m_log.size() == 0); - m_commit_lsn= log_sys.get_lsn(); - lsns= { m_commit_lsn, PAGE_FLUSH_NO }; - if (UNIV_UNLIKELY(m_made_dirty)) /* This should be IMPORT TABLESPACE */ - mysql_mutex_lock(&log_sys.flush_order_mutex); - } - - if (m_freed_pages) - { - ut_ad(!m_freed_pages->empty()); - ut_ad(m_freed_space); - ut_ad(m_freed_space->is_owner()); - ut_ad(is_named_space(m_freed_space)); - /* Update the last freed lsn */ - m_freed_space->update_last_freed_lsn(m_commit_lsn); - - if (!is_trim_pages()) - for (const auto &range : *m_freed_pages) - m_freed_space->add_free_range(range); + if (m_latch_ex) + { + log_sys.latch.wr_unlock(); + m_latch_ex= false; + } else - m_freed_space->clear_freed_ranges(); - delete m_freed_pages; - m_freed_pages= nullptr; - m_freed_space= nullptr; - /* mtr_t::start() will reset m_trim_pages */ + log_sys.latch.rd_unlock(); + Iterate<ReleaseSimple> rs{ReleaseSimple{m_commit_lsn}}; + m_memo.for_each_block_in_reverse(rs); + buf_pool.add_flush_list_requests(rs.functor.modified); } - else - ut_ad(!m_freed_space); - - m_memo.for_each_block_in_reverse - (CIterate<const ReleaseBlocks>(ReleaseBlocks(lsns.first, m_commit_lsn))); - if (m_made_dirty) - mysql_mutex_unlock(&log_sys.flush_order_mutex); - - m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>()); if (UNIV_UNLIKELY(lsns.second != PAGE_FLUSH_NO)) buf_flush_ahead(m_commit_lsn, lsns.second == PAGE_FLUSH_SYNC); - - if (m_made_dirty) - srv_stats.log_write_requests.inc(); } else m_memo.for_each_block_in_reverse(CIterate<ReleaseAll>()); +func_exit: release_resources(); } @@ -575,43 +843,38 @@ void mtr_t::commit_shrink(fil_space_t &space) ut_ad(UT_LIST_GET_LEN(space.chain) == 1); log_write_and_flush_prepare(); + m_latch_ex= true; + log_sys.latch.wr_lock(SRW_LOCK_CALL); const lsn_t start_lsn= do_write().first; ut_d(m_log.erase()); - mysql_mutex_lock(&log_sys.flush_order_mutex); /* Durably write the reduced FSP_SIZE before truncating the data file. */ log_write_and_flush(); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif os_file_truncate(space.chain.start->name, space.chain.start->handle, os_offset_t{space.size} << srv_page_size_shift, true); - if (m_freed_pages) - { - ut_ad(!m_freed_pages->empty()); - ut_ad(m_freed_space == &space); - ut_ad(memo_contains(*m_freed_space)); - ut_ad(is_named_space(m_freed_space)); - m_freed_space->update_last_freed_lsn(m_commit_lsn); - - if (!is_trim_pages()) - for (const auto &range : *m_freed_pages) - m_freed_space->add_free_range(range); - else - m_freed_space->clear_freed_ranges(); - delete m_freed_pages; - m_freed_pages= nullptr; - m_freed_space= nullptr; - /* mtr_t::start() will reset m_trim_pages */ - } - else - ut_ad(!m_freed_space); + ut_ad(!m_freed_pages || m_freed_space == &space); + process_freed_pages(); m_memo.for_each_block_in_reverse(CIterate<Shrink>{space}); - - m_memo.for_each_block_in_reverse(CIterate<const ReleaseBlocks> - (ReleaseBlocks(start_lsn, m_commit_lsn))); - mysql_mutex_unlock(&log_sys.flush_order_mutex); + mysql_mutex_lock(&buf_pool.flush_list_mutex); + { + CIterate<ReleaseModified> rm + {ReleaseModified{buf_pool.prepare_insert_into_flush_list(start_lsn), + start_lsn, m_commit_lsn}}; + m_memo.for_each_block_in_reverse(rm); + ut_ad(rm.functor.modified); + buf_pool.flush_list_requests+= rm.functor.modified; + } + buf_pool.page_cleaner_wakeup(); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + log_sys.latch.wr_unlock(); + m_latch_ex= false; mysql_mutex_lock(&fil_system.mutex); ut_ad(space.is_being_truncated); @@ -621,7 +884,6 @@ void mtr_t::commit_shrink(fil_space_t &space) mysql_mutex_unlock(&fil_system.mutex); m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>()); - srv_stats.log_write_requests.inc(); release_resources(); } @@ -640,12 +902,30 @@ bool mtr_t::commit_file(fil_space_t &space, const char *name) ut_ad(!recv_recovery_is_on()); ut_ad(m_log_mode == MTR_LOG_ALL); ut_ad(UT_LIST_GET_LEN(space.chain) == 1); + ut_ad(!m_latch_ex); + + m_latch_ex= true; log_write_and_flush_prepare(); - do_write(); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + + size_t size= m_log.size() + 5; + + if (log_sys.is_encrypted()) + { + /* We will not encrypt any FILE_ records, but we will reserve + a nonce at the end. */ + size+= 8; + m_commit_lsn= log_sys.get_lsn(); + } + else + m_commit_lsn= 0; - mysql_mutex_assert_owner(&log_sys.mutex); + m_crc= 0; + m_log.for_each_block([this](const mtr_buf_t::block_t *b) + { m_crc= my_crc32c(m_crc, b->begin(), b->used()); return true; }); + finish_write(size); if (!name && space.max_lsn) { @@ -659,6 +939,9 @@ bool mtr_t::commit_file(fil_space_t &space, const char *name) /* Durably write the log for the file system operation. */ log_write_and_flush(); + log_sys.latch.wr_unlock(); + m_latch_ex= false; + char *old_name= space.chain.start->name; bool success; @@ -708,48 +991,66 @@ bool mtr_t::commit_file(fil_space_t &space, const char *name) ut_d(m_log.erase()); release_resources(); - srv_stats.log_write_requests.inc(); return success; } /** Commit a mini-transaction that did not modify any pages, but generated some redo log on a higher level, such as FILE_MODIFY records and an optional FILE_CHECKPOINT marker. -The caller must hold log_sys.mutex. +The caller must hold exclusive log_sys.latch. This is to be used at log_checkpoint(). -@param[in] checkpoint_lsn log checkpoint LSN, or 0 */ -void mtr_t::commit_files(lsn_t checkpoint_lsn) +@param checkpoint_lsn the log sequence number of a checkpoint, or 0 +@return current LSN */ +lsn_t mtr_t::commit_files(lsn_t checkpoint_lsn) { - mysql_mutex_assert_owner(&log_sys.mutex); - ut_ad(is_active()); - ut_ad(!is_inside_ibuf()); - ut_ad(m_log_mode == MTR_LOG_ALL); - ut_ad(!m_made_dirty); - ut_ad(m_memo.size() == 0); - ut_ad(!srv_read_only_mode); - ut_ad(!m_freed_space); - ut_ad(!m_freed_pages); - - if (checkpoint_lsn) { - byte* ptr = m_log.push<byte*>(SIZE_OF_FILE_CHECKPOINT); - compile_time_assert(SIZE_OF_FILE_CHECKPOINT == 3 + 8 + 1); - *ptr = FILE_CHECKPOINT | (SIZE_OF_FILE_CHECKPOINT - 2); - ::memset(ptr + 1, 0, 2); - mach_write_to_8(ptr + 3, checkpoint_lsn); - ptr[3 + 8] = 0; - } else { - *m_log.push<byte*>(1) = 0; - } +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_write_locked()); +#endif + ut_ad(is_active()); + ut_ad(!is_inside_ibuf()); + ut_ad(m_log_mode == MTR_LOG_ALL); + ut_ad(!m_made_dirty); + ut_ad(m_memo.size() == 0); + ut_ad(!srv_read_only_mode); + ut_ad(!m_freed_space); + ut_ad(!m_freed_pages); + ut_ad(!m_user_space); + ut_ad(!m_latch_ex); - finish_write(m_log.size()); - srv_stats.log_write_requests.inc(); - release_resources(); + m_latch_ex= true; - if (checkpoint_lsn) { - DBUG_PRINT("ib_log", - ("FILE_CHECKPOINT(" LSN_PF ") written at " LSN_PF, - checkpoint_lsn, log_sys.get_lsn())); - } + if (checkpoint_lsn) + { + byte *ptr= m_log.push<byte*>(3 + 8); + *ptr= FILE_CHECKPOINT | (2 + 8); + ::memset(ptr + 1, 0, 2); + mach_write_to_8(ptr + 3, checkpoint_lsn); + } + + size_t size= m_log.size() + 5; + + if (log_sys.is_encrypted()) + { + /* We will not encrypt any FILE_ records, but we will reserve + a nonce at the end. */ + size+= 8; + m_commit_lsn= log_sys.get_lsn(); + } + else + m_commit_lsn= 0; + + m_crc= 0; + m_log.for_each_block([this](const mtr_buf_t::block_t *b) + { m_crc= my_crc32c(m_crc, b->begin(), b->used()); return true; }); + finish_write(size); + release_resources(); + + if (checkpoint_lsn) + DBUG_PRINT("ib_log", + ("FILE_CHECKPOINT(" LSN_PF ") written at " LSN_PF, + checkpoint_lsn, m_commit_lsn)); + + return m_commit_lsn; } #ifdef UNIV_DEBUG @@ -860,183 +1161,111 @@ mtr_t::release_page(const void* ptr, mtr_memo_type_t type) ut_ad(0); } -static bool log_margin_warned; -static time_t log_margin_warn_time; static bool log_close_warned; static time_t log_close_warn_time; -/** Check margin not to overwrite transaction log from the last checkpoint. -If would estimate the log write to exceed the log_capacity, -waits for the checkpoint is done enough. -@param len length of the data to be written */ -static void log_margin_checkpoint_age(ulint len) +/** Display a warning that the log tail is overwriting the head, +making the server crash-unsafe. */ +ATTRIBUTE_COLD static void log_overwrite_warning(lsn_t age, lsn_t capacity) { - const ulint framing_size= log_sys.framing_size(); - /* actual length stored per block */ - const ulint len_per_blk= OS_FILE_LOG_BLOCK_SIZE - framing_size; - - /* actual data length in last block already written */ - ulint extra_len= log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE; - - ut_ad(extra_len >= LOG_BLOCK_HDR_SIZE); - extra_len-= LOG_BLOCK_HDR_SIZE; - - /* total extra length for block header and trailer */ - extra_len= ((len + extra_len) / len_per_blk) * framing_size; - - const ulint margin= len + extra_len; - - mysql_mutex_assert_owner(&log_sys.mutex); - - const lsn_t lsn= log_sys.get_lsn(); - - if (UNIV_UNLIKELY(margin > log_sys.log_capacity)) + time_t t= time(nullptr); + if (!log_close_warned || difftime(t, log_close_warn_time) > 15) { - time_t t= time(nullptr); + log_close_warned= true; + log_close_warn_time= t; - /* return with warning output to avoid deadlock */ - if (!log_margin_warned || difftime(t, log_margin_warn_time) > 15) - { - log_margin_warned= true; - log_margin_warn_time= t; - - ib::error() << "innodb_log_file_size is too small " - "for mini-transaction size " << len; - } + sql_print_error("InnoDB: The age of the last checkpoint is " LSN_PF + ", which exceeds the log capacity " LSN_PF ".", + age, capacity); } - else if (UNIV_LIKELY(lsn + margin <= log_sys.last_checkpoint_lsn + - log_sys.log_capacity)) - return; - - log_sys.set_check_flush_or_checkpoint(); } - -/** Open the log for log_write_low(). The log must be closed with log_close(). -@param len length of the data to be written -@return start lsn of the log record */ -static lsn_t log_reserve_and_open(size_t len) +/** Wait in append_prepare() for buffer to become available +@param ex whether log_sys.latch is exclusively locked */ +ATTRIBUTE_COLD void log_t::append_prepare_wait(bool ex) noexcept { - for (ut_d(ulint count= 0);;) - { - mysql_mutex_assert_owner(&log_sys.mutex); - - /* Calculate an upper limit for the space the string may take in - the log buffer */ - - size_t len_upper_limit= (4 * OS_FILE_LOG_BLOCK_SIZE) + - srv_log_write_ahead_size + (5 * len) / 4; + log_sys.waits++; + log_sys.unlock_lsn(); - if (log_sys.buf_free + len_upper_limit <= srv_log_buffer_size) - break; - - mysql_mutex_unlock(&log_sys.mutex); - DEBUG_SYNC_C("log_buf_size_exceeded"); - - /* Not enough free space, do a write of the log buffer */ - log_write_up_to(log_sys.get_lsn(), false); - - srv_stats.log_waits.inc(); + if (ex) + log_sys.latch.wr_unlock(); + else + log_sys.latch.rd_unlock(); - ut_ad(++count < 50); + DEBUG_SYNC_C("log_buf_size_exceeded"); + log_buffer_flush_to_disk(log_sys.is_pmem()); - mysql_mutex_lock(&log_sys.mutex); - } + if (ex) + log_sys.latch.wr_lock(SRW_LOCK_CALL); + else + log_sys.latch.rd_lock(SRW_LOCK_CALL); - return log_sys.get_lsn(); + log_sys.lock_lsn(); } -/** Append data to the log buffer. */ -static void log_write_low(const void *str, size_t size) +/** Reserve space in the log buffer for appending data. +@tparam pmem log_sys.is_pmem() +@param size total length of the data to append(), in bytes +@param ex whether log_sys.latch is exclusively locked +@return the start LSN and the buffer position for append() */ +template<bool pmem> +inline +std::pair<lsn_t,byte*> log_t::append_prepare(size_t size, bool ex) noexcept { - mysql_mutex_assert_owner(&log_sys.mutex); - const ulint trailer_offset= log_sys.trailer_offset(); - - do +#ifndef SUX_LOCK_GENERIC + ut_ad(latch.is_locked()); +# ifndef _WIN32 // there is no accurate is_write_locked() on SRWLOCK + ut_ad(ex == latch.is_write_locked()); +# endif +#endif + ut_ad(pmem == is_pmem()); + const lsn_t checkpoint_margin{last_checkpoint_lsn + log_capacity - size}; + const size_t avail{(pmem ? size_t(capacity()) : buf_size) - size}; + lock_lsn(); + write_to_buf++; + + for (ut_d(int count= 50); + UNIV_UNLIKELY((pmem + ? size_t(get_lsn() - + get_flushed_lsn(std::memory_order_relaxed)) + : size_t{buf_free}) > avail); ) { - /* Calculate a part length */ - size_t len= size; - size_t data_len= (log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE) + size; - - if (data_len > trailer_offset) - { - data_len= trailer_offset; - len= trailer_offset - log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE; - } - - memcpy(log_sys.buf + log_sys.buf_free, str, len); - - size-= len; - str= static_cast<const char*>(str) + len; - - byte *log_block= static_cast<byte*>(ut_align_down(log_sys.buf + - log_sys.buf_free, - OS_FILE_LOG_BLOCK_SIZE)); - - log_block_set_data_len(log_block, data_len); - lsn_t lsn= log_sys.get_lsn(); - - if (data_len == trailer_offset) - { - /* This block became full */ - log_block_set_data_len(log_block, OS_FILE_LOG_BLOCK_SIZE); - log_block_set_checkpoint_no(log_block, log_sys.next_checkpoint_no); - len+= log_sys.framing_size(); - lsn+= len; - /* Initialize the next block header */ - log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, lsn); - } - else - lsn+= len; - - log_sys.set_lsn(lsn); - log_sys.buf_free+= len; - - ut_ad(log_sys.buf_free <= size_t{srv_log_buffer_size}); + append_prepare_wait(ex); + ut_ad(count--); } - while (size); + + const lsn_t l{lsn.load(std::memory_order_relaxed)}; + lsn.store(l + size, std::memory_order_relaxed); + const size_t b{buf_free}; + size_t new_buf_free{b}; + new_buf_free+= size; + if (pmem && new_buf_free >= file_size) + new_buf_free-= size_t(capacity()); + buf_free= new_buf_free; + unlock_lsn(); + + if (UNIV_UNLIKELY(l > checkpoint_margin) || + (!pmem && b >= max_buf_free)) + set_check_flush_or_checkpoint(); + + return {l, &buf[b]}; } -/** Close the log at mini-transaction commit. -@return whether buffer pool flushing is needed */ -static mtr_t::page_flush_ahead log_close(lsn_t lsn) +/** Finish appending data to the log. +@param lsn the end LSN of the log record +@return whether buf_flush_ahead() will have to be invoked */ +static mtr_t::page_flush_ahead log_close(lsn_t lsn) noexcept { - mysql_mutex_assert_owner(&log_sys.mutex); - ut_ad(lsn == log_sys.get_lsn()); - - byte *log_block= static_cast<byte*>(ut_align_down(log_sys.buf + - log_sys.buf_free, - OS_FILE_LOG_BLOCK_SIZE)); - - if (!log_block_get_first_rec_group(log_block)) - { - /* We initialized a new log block which was not written - full by the current mtr: the next mtr log record group - will start within this block at the offset data_len */ - log_block_set_first_rec_group(log_block, - log_block_get_data_len(log_block)); - } - - if (log_sys.buf_free > log_sys.max_buf_free) - log_sys.set_check_flush_or_checkpoint(); +#ifndef SUX_LOCK_GENERIC + ut_ad(log_sys.latch.is_locked()); +#endif const lsn_t checkpoint_age= lsn - log_sys.last_checkpoint_lsn; if (UNIV_UNLIKELY(checkpoint_age >= log_sys.log_capacity) && /* silence message on create_log_file() after the log had been deleted */ checkpoint_age != lsn) - { - time_t t= time(nullptr); - if (!log_close_warned || difftime(t, log_close_warn_time) > 15) - { - log_close_warned= true; - log_close_warn_time= t; - - ib::error() << "The age of the last checkpoint is " << checkpoint_age - << ", which exceeds the log capacity " - << log_sys.log_capacity << "."; - } - } + log_overwrite_warning(checkpoint_age, log_sys.log_capacity); else if (UNIV_LIKELY(checkpoint_age <= log_sys.max_modified_age_async)) return mtr_t::PAGE_FLUSH_NO; else if (UNIV_LIKELY(checkpoint_age <= log_sys.max_checkpoint_age)) @@ -1108,101 +1337,149 @@ struct WriteOPT_PAGE_CHECKSUM } }; -/** Write the block contents to the REDO log */ -struct mtr_write_log -{ - /** Append a block to the redo log buffer. - @return whether the appending should continue */ - bool operator()(const mtr_buf_t::block_t *block) const - { - log_write_low(block->begin(), block->used()); - return true; - } -}; - std::pair<lsn_t,mtr_t::page_flush_ahead> mtr_t::do_write() { - ut_ad(!recv_no_log_write); - ut_ad(is_logged()); + ut_ad(!recv_no_log_write); + ut_ad(is_logged()); +#ifndef SUX_LOCK_GENERIC + ut_ad(!m_latch_ex || log_sys.latch.is_write_locked()); +#endif - ulint len = m_log.size(); - ut_ad(len > 0); + size_t len= m_log.size() + 5; + ut_ad(len > 5); #ifndef DBUG_OFF - if (m_log_mode == MTR_LOG_ALL) { - do { - DBUG_EXECUTE_IF("skip_page_checksum", continue;); - m_memo.for_each_block(CIterate<WriteOPT_PAGE_CHECKSUM> - (*this)); - len = m_log.size(); - } while (0); - } + if (m_log_mode == MTR_LOG_ALL) + { + m_memo.for_each_block(CIterate<WriteOPT_PAGE_CHECKSUM>(*this)); + do + { + DBUG_EXECUTE_IF("skip_page_checksum", continue;); + m_memo.for_each_block(CIterate<WriteOPT_PAGE_CHECKSUM>(*this)); + len= m_log.size() + 5; + } + while (0); + } #endif - if (len > srv_log_buffer_size / 2) { - log_buffer_extend(ulong((len + 1) * 2)); - } - - fil_space_t* space = m_user_space; - - if (space != NULL && is_predefined_tablespace(space->id)) { - /* Omit FILE_MODIFY for predefined tablespaces. */ - space = NULL; - } - - mysql_mutex_lock(&log_sys.mutex); - - if (fil_names_write_if_was_clean(space)) { - len = m_log.size(); - } else { - /* This was not the first time of dirtying a - tablespace since the latest checkpoint. */ - ut_ad(len == m_log.size()); - } - - *m_log.push<byte*>(1) = 0; - len++; + if (log_sys.is_encrypted()) + { + len+= 8; + encrypt(); + } + else + { + m_crc= 0; + m_commit_lsn= 0; + m_log.for_each_block([this](const mtr_buf_t::block_t *b) + { m_crc= my_crc32c(m_crc, b->begin(), b->used()); return true; }); + } - /* check and attempt a checkpoint if exceeding capacity */ - log_margin_checkpoint_age(len); + if (!m_latch_ex) + log_sys.latch.rd_lock(SRW_LOCK_CALL); - return finish_write(len); + if (UNIV_UNLIKELY(m_user_space && !m_user_space->max_lsn && + !is_predefined_tablespace(m_user_space->id))) + { + if (!m_latch_ex) + { + m_latch_ex= true; + log_sys.latch.rd_unlock(); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + if (UNIV_UNLIKELY(m_user_space->max_lsn != 0)) + goto func_exit; + } + name_write(); + } +func_exit: + return finish_write(len); } -/** Append the redo log records to the redo log buffer. +/** Write the mini-transaction log to the redo log buffer. @param len number of bytes to write @return {start_lsn,flush_ahead} */ -inline std::pair<lsn_t,mtr_t::page_flush_ahead> mtr_t::finish_write(ulint len) +std::pair<lsn_t,mtr_t::page_flush_ahead> +mtr_t::finish_write(size_t len) { - ut_ad(is_logged()); - mysql_mutex_assert_owner(&log_sys.mutex); - ut_ad(m_log.size() == len); - ut_ad(len > 0); + ut_ad(!recv_no_log_write); + ut_ad(is_logged()); +#ifndef SUX_LOCK_GENERIC +# ifndef _WIN32 // there is no accurate is_write_locked() on SRWLOCK + ut_ad(m_latch_ex == log_sys.latch.is_write_locked()); +# endif +#endif - lsn_t start_lsn; + const size_t size{m_commit_lsn ? 5U + 8U : 5U}; + std::pair<lsn_t, byte*> start; - if (m_log.is_small()) { - const mtr_buf_t::block_t* front = m_log.front(); - ut_ad(len <= front->used()); + if (!log_sys.is_pmem()) + { + start= log_sys.append_prepare<false>(len, m_latch_ex); + m_log.for_each_block([&start](const mtr_buf_t::block_t *b) + { log_sys.append(start.second, b->begin(), b->used()); return true; }); - m_commit_lsn = log_reserve_and_write_fast(front->begin(), len, - &start_lsn); +#ifdef HAVE_PMEM + write_trailer: +#endif + *start.second++= log_sys.get_sequence_bit(start.first + len - size); + if (m_commit_lsn) + { + mach_write_to_8(start.second, m_commit_lsn); + m_crc= my_crc32c(m_crc, start.second, 8); + start.second+= 8; + } + mach_write_to_4(start.second, m_crc); + } +#ifdef HAVE_PMEM + else + { + start= log_sys.append_prepare<true>(len, m_latch_ex); + if (UNIV_LIKELY(start.second + len <= &log_sys.buf[log_sys.file_size])) + { + m_log.for_each_block([&start](const mtr_buf_t::block_t *b) + { log_sys.append(start.second, b->begin(), b->used()); return true; }); + goto write_trailer; + } + m_log.for_each_block([&start](const mtr_buf_t::block_t *b) + { + size_t size{b->used()}; + const size_t size_left(&log_sys.buf[log_sys.file_size] - start.second); + const byte *src= b->begin(); + if (size > size_left) + { + ::memcpy(start.second, src, size_left); + start.second= &log_sys.buf[log_sys.START_OFFSET]; + src+= size_left; + size-= size_left; + } + ::memcpy(start.second, src, size); + start.second+= size; + return true; + }); + const size_t size_left(&log_sys.buf[log_sys.file_size] - start.second); + if (size_left > size) + goto write_trailer; - if (!m_commit_lsn) { - goto piecewise; - } - } else { -piecewise: - /* Open the database log for log_write_low */ - start_lsn = log_reserve_and_open(len); - mtr_write_log write_log; - m_log.for_each_block(write_log); - m_commit_lsn = log_sys.get_lsn(); - } - page_flush_ahead flush= log_close(m_commit_lsn); - DBUG_EXECUTE_IF("ib_log_flush_ahead", flush = PAGE_FLUSH_SYNC;); + byte tail[5 + 8]; + tail[0]= log_sys.get_sequence_bit(start.first + len - size); + + if (m_commit_lsn) + { + mach_write_to_8(tail + 1, m_commit_lsn); + m_crc= my_crc32c(m_crc, tail + 1, 8); + mach_write_to_4(tail + 9, m_crc); + } + else + mach_write_to_4(tail + 1, m_crc); + + ::memcpy(start.second, tail, size_left); + ::memcpy(log_sys.buf + log_sys.START_OFFSET, tail + size_left, + size - size_left); + } +#endif - return std::make_pair(start_lsn, flush); + m_commit_lsn= start.first + len; + return {start.first, log_close(m_commit_lsn)}; } /** Find out whether a block was not X-latched by the mini-transaction */ @@ -1533,7 +1810,8 @@ void mtr_t::modify(const buf_block_t &block) } Iterate<FindModified> iteration((FindModified(block))); - if (UNIV_UNLIKELY(m_memo.for_each_block(iteration))) + m_memo.for_each_block(iteration); + if (UNIV_UNLIKELY(!iteration.functor.found)) { ut_ad("modifying an unlatched page" == 0); return; diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index b49723b6fc8..6e7943c8bc4 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -33,13 +33,14 @@ The interface to the operating system file i/o primitives Created 10/21/1995 Heikki Tuuri *******************************************************/ -#ifndef UNIV_INNOCHECKSUM #include "os0file.h" #include "sql_const.h" +#include "log.h" #ifdef __linux__ # include <sys/types.h> # include <sys/stat.h> +# include <sys/sysmacros.h> #endif #include "srv0mon.h" @@ -63,13 +64,6 @@ Created 10/21/1995 Heikki Tuuri # include <linux/falloc.h> #endif /* HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE */ -#if defined(__linux__) && defined(HAVE_SYS_IOCTL_H) -# include <sys/ioctl.h> -# ifndef DFS_IOCTL_ATOMIC_WRITE_SET -# define DFS_IOCTL_ATOMIC_WRITE_SET _IOW(0x95, 2, uint) -# endif -#endif - #ifdef _WIN32 #include <winioctl.h> #endif @@ -167,7 +161,6 @@ extern uint page_zip_level; #ifdef UNIV_PFS_IO /* Keys to register InnoDB I/O with performance schema */ mysql_pfs_key_t innodb_data_file_key; -mysql_pfs_key_t innodb_log_file_key; mysql_pfs_key_t innodb_temp_file_key; #endif @@ -758,18 +751,15 @@ os_file_get_last_error_low( } if (report_all_errors - || (err != ENOSPC && err != EEXIST && !on_error_silent)) { + || (err != ENOSPC && err != EEXIST && err != ENOENT + && !on_error_silent)) { ib::error() << "Operating system error number " << err << " in a file operation."; - if (err == ENOENT) { - ib::error() - << "The error means the system" - " cannot find the path specified."; - } else if (err == EACCES) { + if (err == EACCES) { ib::error() << "The error means mariadbd does not have" @@ -1050,7 +1040,15 @@ os_file_create_simple_func( OS caching (O_DIRECT) here as we do in os_file_create_func(), so we open the same file in the same mode, see man page of open(2). */ if (!srv_read_only_mode && *success) { - os_file_set_nocache(file, name, mode_str); + switch (srv_file_flush_method) { + case SRV_O_DSYNC: + case SRV_O_DIRECT: + case SRV_O_DIRECT_NO_FSYNC: + os_file_set_nocache(file, name, mode_str); + break; + default: + break; + } } #ifndef _WIN32 @@ -1224,23 +1222,89 @@ os_file_create_func( } while (retry); - /* We disable OS caching (O_DIRECT) only on data files */ - if (!read_only - && *success - && type != OS_LOG_FILE - && type != OS_DATA_FILE_NO_O_DIRECT) { - os_file_set_nocache(file, name, mode_str); + if (!*success) { + return file; } +#if (defined __sun__ && defined DIRECTIO_ON) || defined O_DIRECT + if (type == OS_DATA_FILE) { + switch (srv_file_flush_method) { + case SRV_O_DSYNC: + case SRV_O_DIRECT: + case SRV_O_DIRECT_NO_FSYNC: +# ifdef __linux__ +use_o_direct: +# endif + os_file_set_nocache(file, name, mode_str); + break; + default: + break; + } + } +# ifdef __linux__ + else if (type == OS_LOG_FILE && !log_sys.is_opened()) { + struct stat st; + char b[20 + sizeof "/sys/dev/block/" ":" + "/../queue/physical_block_size"]; + int f; + if (fstat(file, &st)) { + goto skip_o_direct; + } + MSAN_STAT_WORKAROUND(&st); + if (snprintf(b, sizeof b, + "/sys/dev/block/%u:%u/queue/physical_block_size", + major(st.st_dev), minor(st.st_dev)) + >= static_cast<int>(sizeof b)) { + goto skip_o_direct; + } + if ((f = open(b, O_RDONLY)) == -1) { + if (snprintf(b, sizeof b, + "/sys/dev/block/%u:%u/../queue/" + "physical_block_size", + major(st.st_dev), minor(st.st_dev)) + >= static_cast<int>(sizeof b)) { + goto skip_o_direct; + } + f = open(b, O_RDONLY); + } + if (f != -1) { + ssize_t l = read(f, b, sizeof b); + unsigned long s = 0; + + if (l > 0 && static_cast<size_t>(l) < sizeof b + && b[l - 1] == '\n') { + char* end = b; + s = strtoul(b, &end, 10); + if (b == end || *end != '\n') { + s = 0; + } + } + close(f); + if (s > 4096 || s < 64 || !ut_is_2pow(s)) { + goto skip_o_direct; + } + log_sys.log_maybe_unbuffered= true; + log_sys.set_block_size(uint32_t(s)); + if (!log_sys.log_buffered && !(st.st_size & (s - 1))) { + goto use_o_direct; + } + } else { +skip_o_direct: + log_sys.log_maybe_unbuffered= false; + log_sys.log_buffered= true; + log_sys.set_block_size(512); + } + } +# endif +#endif + #ifndef _WIN32 if (!read_only - && *success && create_mode != OS_FILE_OPEN_RAW && !my_disable_locking && os_file_lock(file, name)) { if (create_mode == OS_FILE_OPEN_RETRY) { - ib::info() << "Retrying to lock the first data file"; @@ -1759,29 +1823,26 @@ os_file_get_last_error_low( if (report_all_errors || (!on_error_silent && err != ERROR_DISK_FULL + && err != ERROR_FILE_NOT_FOUND && err != ERROR_FILE_EXISTS)) { ib::error() << "Operating system error number " << err << " in a file operation."; - if (err == ERROR_PATH_NOT_FOUND) { - ib::error() - << "The error means the system" - " cannot find the path specified."; - - } else if (err == ERROR_ACCESS_DENIED) { - + switch (err) { + case ERROR_PATH_NOT_FOUND: + break; + case ERROR_ACCESS_DENIED: ib::error() << "The error means mariadbd does not have" " the access rights to" " the directory. It may also be" " you have created a subdirectory" " of the same name as a data file."; - - } else if (err == ERROR_SHARING_VIOLATION - || err == ERROR_LOCK_VIOLATION) { - + break; + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: ib::error() << "The error means that another program" " is using InnoDB's files." @@ -1789,29 +1850,23 @@ os_file_get_last_error_low( " software or another instance" " of MariaDB." " Please close it to get rid of this error."; - - } else if (err == ERROR_WORKING_SET_QUOTA - || err == ERROR_NO_SYSTEM_RESOURCES) { - + break; + case ERROR_WORKING_SET_QUOTA: + case ERROR_NO_SYSTEM_RESOURCES: ib::error() << "The error means that there are no" " sufficient system resources or quota to" " complete the operation."; - - } else if (err == ERROR_OPERATION_ABORTED) { - + break; + case ERROR_OPERATION_ABORTED: ib::error() << "The error means that the I/O" " operation has been aborted" " because of either a thread exit" " or an application request." " Retry attempt is made."; - } else if (err == ERROR_PATH_NOT_FOUND) { - ib::error() - << "This error means that directory did not exist" - " during file creation."; - } else { - + break; + default: ib::info() << OPERATING_SYSTEM_ERROR_MSG; } } @@ -1995,32 +2050,20 @@ os_file_create_directory( return(true); } -/** Check that IO of specific size is possible for the file -opened with FILE_FLAG_NO_BUFFERING. - -The requirement is that IO is multiple of the disk sector size. - -@param[in] file file handle -@param[in] io_size expected io size -@return true - unbuffered io of requested size is possible, false otherwise. - -@note: this function only works correctly with Windows 8 or later, -(GetFileInformationByHandleEx with FileStorageInfo is only supported there). -It will return true on earlier Windows version. - */ -static bool unbuffered_io_possible(HANDLE file, size_t io_size) +/** Get disk sector size for a file. */ +static size_t get_sector_size(HANDLE file) { - FILE_STORAGE_INFO info; - if (GetFileInformationByHandleEx( - file, FileStorageInfo, &info, sizeof(info))) { - ULONG sector_size = info.LogicalBytesPerSector; - if (sector_size) - return io_size % sector_size == 0; - } - return true; + FILE_STORAGE_INFO fsi; + ULONG s= 4096; + if (GetFileInformationByHandleEx(file, FileStorageInfo, &fsi, sizeof fsi)) + { + s= fsi.PhysicalBytesPerSectorForPerformance; + if (s > 4096 || s < 64 || !ut_is_2pow(s)) + return 4096; + } + return s; } - /** NOTE! Use the corresponding macro os_file_create(), not directly this function! Opens an existing file or creates a new. @@ -2110,83 +2153,29 @@ os_file_create_func( return(OS_FILE_CLOSED); } - DWORD attributes = 0; - - if (purpose == OS_FILE_AIO) { - -#ifdef WIN_ASYNC_IO - /* If specified, use asynchronous (overlapped) io and no - buffering of writes in the OS */ - - if (srv_use_native_aio) { - attributes |= FILE_FLAG_OVERLAPPED; - } -#endif /* WIN_ASYNC_IO */ - - } else if (purpose == OS_FILE_NORMAL) { - - /* Use default setting. */ - - } else { - - ib::error() - << "Unknown purpose flag (" << purpose << ") " - << "while opening file '" << name << "'"; - - return(OS_FILE_CLOSED); - } + DWORD attributes = (purpose == OS_FILE_AIO && srv_use_native_aio) + ? FILE_FLAG_OVERLAPPED : 0; if (type == OS_LOG_FILE) { - /* There is not reason to use buffered write to logs.*/ - attributes |= FILE_FLAG_NO_BUFFERING; + if (!log_sys.is_opened() && !log_sys.log_buffered) { + attributes|= FILE_FLAG_NO_BUFFERING; + } + if (srv_file_flush_method == SRV_O_DSYNC) + attributes|= FILE_FLAG_WRITE_THROUGH; } - - switch (srv_file_flush_method) + else if (type == OS_DATA_FILE) { - case SRV_O_DSYNC: - if (type == OS_LOG_FILE) { - /* Map O_DSYNC to FILE_WRITE_THROUGH */ - attributes |= FILE_FLAG_WRITE_THROUGH; - } - break; - - case SRV_O_DIRECT_NO_FSYNC: - case SRV_O_DIRECT: - if (type != OS_DATA_FILE) { + switch (srv_file_flush_method) + { + case SRV_FSYNC: + case SRV_LITTLESYNC: + case SRV_NOSYNC: break; + default: + attributes|= FILE_FLAG_NO_BUFFERING; } - /* fall through */ - case SRV_ALL_O_DIRECT_FSYNC: - /*Traditional Windows behavior, no buffering for any files.*/ - if (type != OS_DATA_FILE_NO_O_DIRECT) { - attributes |= FILE_FLAG_NO_BUFFERING; - } - break; - - case SRV_FSYNC: - case SRV_LITTLESYNC: - break; - - case SRV_NOSYNC: - /* Let Windows cache manager handle all writes.*/ - attributes &= ~(FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING); - break; - - default: - ut_a(false); /* unknown flush mode.*/ } - - // TODO: Create a bug, this looks wrong. The flush log - // parameter is dynamic. - if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) { - /* Do not use unbuffered i/o for the log files because - value 2 denotes that we do not flush the log at every - commit, but only once per second */ - attributes &= ~(FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING); - } - - DWORD access = GENERIC_READ; if (!read_only) { @@ -2201,19 +2190,22 @@ os_file_create_func( name, access, share_mode, my_win_file_secattr(), create_flag, attributes, NULL); - /* If FILE_FLAG_NO_BUFFERING was set, check if this can work at all, - for expected IO sizes. Reopen without the unbuffered flag, if it is won't work*/ - if ((file != INVALID_HANDLE_VALUE) - && (attributes & FILE_FLAG_NO_BUFFERING) - && (type == OS_LOG_FILE) - && !unbuffered_io_possible(file, OS_FILE_LOG_BLOCK_SIZE)) { - ut_a(CloseHandle(file)); - attributes &= ~FILE_FLAG_NO_BUFFERING; - create_flag = OPEN_ALWAYS; - continue; + *success = file != INVALID_HANDLE_VALUE; + + if (*success && type == OS_LOG_FILE) { + uint32_t s = uint32_t(get_sector_size(file)); + log_sys.set_block_size(s); + if (attributes & FILE_FLAG_NO_BUFFERING) { + if (os_file_get_size(file) % s) { + attributes &= ~FILE_FLAG_NO_BUFFERING; + create_flag = OPEN_ALWAYS; + CloseHandle(file); + continue; + } + log_sys.log_buffered = false; + } } - *success = (file != INVALID_HANDLE_VALUE); if (*success) { break; } @@ -2370,16 +2362,15 @@ os_file_delete_if_exists_func( return(true); } - DWORD lasterr = GetLastError(); - - if (lasterr == ERROR_FILE_NOT_FOUND - || lasterr == ERROR_PATH_NOT_FOUND) { - + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: /* the file does not exist, this not an error */ if (exist != NULL) { *exist = false; } - + /* fall through */ + case ERROR_ACCESS_DENIED: return(true); } @@ -2509,18 +2500,12 @@ bool os_file_close_func(os_file_t file) /** Gets a file size. @param[in] file Handle to a file @return file size, or (os_offset_t) -1 on failure */ -os_offset_t -os_file_get_size( - os_file_t file) +os_offset_t os_file_get_size(os_file_t file) { - DWORD high; - DWORD low = GetFileSize(file, &high); - - if (low == 0xFFFFFFFF && GetLastError() != NO_ERROR) { - return((os_offset_t) -1); - } - - return(os_offset_t(low | (os_offset_t(high) << 32))); + LARGE_INTEGER li; + if (GetFileSizeEx(file, &li)) + return li.QuadPart; + return ((os_offset_t) -1); } /** Gets a file size. @@ -3031,9 +3016,14 @@ os_file_handle_error_cond_exit( case OS_FILE_PATH_ERROR: case OS_FILE_ALREADY_EXISTS: case OS_FILE_ACCESS_VIOLATION: - return(false); + case OS_FILE_NOT_FOUND: + if (!on_error_silent) { + sql_print_error("InnoDB: File %s was not found", name); + } + return false; + case OS_FILE_SHARING_VIOLATION: std::this_thread::sleep_for(std::chrono::seconds(10)); @@ -3080,15 +3070,6 @@ os_file_set_nocache( const char* file_name MY_ATTRIBUTE((unused)), const char* operation_name MY_ATTRIBUTE((unused))) { - const auto innodb_flush_method = srv_file_flush_method; - switch (innodb_flush_method) { - case SRV_O_DIRECT: - case SRV_O_DIRECT_NO_FSYNC: - break; - default: - return; - } - /* some versions of Solaris may not have DIRECTIO_ON */ #if defined(__sun__) && defined(DIRECTIO_ON) if (directio(fd, DIRECTIO_ON) == -1) { @@ -3765,8 +3746,9 @@ void os_aio_wait_until_no_pending_reads() dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n) { ut_ad(n > 0); - ut_ad((n % OS_FILE_LOG_BLOCK_SIZE) == 0); - ut_ad((offset % OS_FILE_LOG_BLOCK_SIZE) == 0); + ut_ad(!(n & 511)); /* payload of page_compressed tables */ + ut_ad((offset % UNIV_ZIP_SIZE_MIN) == 0); + ut_ad((reinterpret_cast<size_t>(buf) % UNIV_ZIP_SIZE_MIN) == 0); ut_ad(type.is_read() || type.is_write()); ut_ad(type.node); ut_ad(type.node->is_open()); @@ -3818,11 +3800,6 @@ func_exit: cb->m_opcode = type.is_read() ? tpool::aio_opcode::AIO_PREAD : tpool::aio_opcode::AIO_PWRITE; new (cb->m_userdata) IORequest{type}; - ut_a(reinterpret_cast<size_t>(cb->m_buffer) % OS_FILE_LOG_BLOCK_SIZE - == 0); - ut_a(cb->m_len % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_a(cb->m_offset % OS_FILE_LOG_BLOCK_SIZE == 0); - if (srv_thread_pool->submit_io(cb)) { slots->release(cb); os_file_handle_error(type.node->name, type.is_read() @@ -3845,10 +3822,8 @@ os_aio_print(FILE* file) time_elapsed = 0.001 + difftime(current_time, os_last_printout); fprintf(file, - "Pending flushes (fsync) log: " ULINTPF - "; buffer pool: " ULINTPF "\n" + "Pending flushes (fsync): " ULINTPF "\n" ULINTPF " OS file reads, %zu OS file writes, %zu OS fsyncs\n", - log_sys.get_pending_flushes(), ulint{fil_n_pending_tablespace_flushes}, ulint{os_n_file_reads}, static_cast<size_t>(os_n_file_writes), @@ -4227,5 +4202,3 @@ invalid: space->set_sizes(this->size); return true; } - -#endif /* !UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index 3b566e1d6f9..956256a2f43 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -84,7 +84,8 @@ page_cur_try_search_shortcut( low_match = up_match = std::min(*ilow_matched_fields, *iup_matched_fields); - if (cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match) < 0) { + if (cmp_dtuple_rec_with_match(tuple, rec, index, offsets, + &low_match) < 0) { goto exit_func; } @@ -97,7 +98,7 @@ page_cur_try_search_shortcut( index->n_core_fields, dtuple_get_n_fields(tuple), &heap); - if (cmp_dtuple_rec_with_match(tuple, next_rec, offsets, + if (cmp_dtuple_rec_with_match(tuple, next_rec, index, offsets, &up_match) >= 0) { goto exit_func; } @@ -404,7 +405,7 @@ page_cur_search_with_match( dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match( - tuple, mid_rec, offsets, &cur_matched_fields); + tuple, mid_rec, index, offsets, &cur_matched_fields); if (cmp > 0) { low_slot_match: @@ -470,7 +471,7 @@ corrupted: dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match( - tuple, mid_rec, offsets, &cur_matched_fields); + tuple, mid_rec, index, offsets, &cur_matched_fields); if (cmp > 0) { low_rec_match: diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index 28b63dc4209..3d4aaf9111f 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -2487,7 +2487,7 @@ page_find_rec_with_heap_no( @param[in] page index tree leaf page @return the last record, not delete-marked @retval infimum record if all records are delete-marked */ -const rec_t *page_find_rec_max_not_deleted(const page_t *page) +const rec_t *page_find_rec_last_not_deleted(const page_t *page) { ut_ad(page_is_leaf(page)); diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 7b603bb876b..8be0b17b5a8 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -29,7 +29,6 @@ Created June 2005 by Marko Makela #include "fsp0types.h" #include "page0page.h" #include "buf0checksum.h" -#include "ut0crc32.h" #include "zlib.h" #include "span.h" @@ -4602,11 +4601,11 @@ uint32_t page_zip_calc_checksum(const void *data, size_t size, bool use_adler) ut_ad(size > FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); if (!use_adler) { - return ut_crc32(s + FIL_PAGE_OFFSET, - FIL_PAGE_LSN - FIL_PAGE_OFFSET) - ^ ut_crc32(s + FIL_PAGE_TYPE, 2) - ^ ut_crc32(s + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, - size - FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + return my_crc32c(0, s + FIL_PAGE_OFFSET, + FIL_PAGE_LSN - FIL_PAGE_OFFSET) + ^ my_crc32c(0, s + FIL_PAGE_TYPE, 2) + ^ my_crc32c(0, s + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, + size - FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); } else { adler = adler32(0L, s + FIL_PAGE_OFFSET, FIL_PAGE_LSN - FIL_PAGE_OFFSET); diff --git a/storage/innobase/pars/pars0opt.cc b/storage/innobase/pars/pars0opt.cc index f3b71132998..44949ad0dda 100644 --- a/storage/innobase/pars/pars0opt.cc +++ b/storage/innobase/pars/pars0opt.cc @@ -356,6 +356,11 @@ opt_calc_index_goodness( n_fields = dict_index_get_n_unique_in_tree(index); for (j = 0; j < n_fields; j++) { + if (UNIV_UNLIKELY(index->fields[j].descending)) { + /* The internal InnoDB SQL parser does not + work with indexes that use DESC order. */ + return 0; + } col_no = dict_index_get_nth_col_no(index, j); diff --git a/storage/innobase/rem/rem0cmp.cc b/storage/innobase/rem/rem0cmp.cc index 7fb6fdac1ba..a77ddafd568 100644 --- a/storage/innobase/rem/rem0cmp.cc +++ b/storage/innobase/rem/rem0cmp.cc @@ -190,61 +190,68 @@ cmp_decimal(const byte* a, ulint a_length, const byte* b, ulint b_length) } /** Compare two data fields. -@param mtype main type -@param prtype precise type -@param data1 data field -@param len1 length of data1 in bytes, or UNIV_SQL_NULL -@param data2 data field -@param len2 length of data2 in bytes, or UNIV_SQL_NULL +@param mtype main type +@param prtype precise type +@param descending whether to use descending order +@param data1 data field +@param len1 length of data1 in bytes, or UNIV_SQL_NULL +@param data2 data field +@param len2 length of data2 in bytes, or UNIV_SQL_NULL @return the comparison result of data1 and data2 @retval 0 if data1 is equal to data2 @retval negative if data1 is less than data2 @retval positive if data1 is greater than data2 */ -static int cmp_data(ulint mtype, ulint prtype, const byte *data1, ulint len1, - const byte *data2, ulint len2) +int cmp_data(ulint mtype, ulint prtype, bool descending, + const byte *data1, size_t len1, const byte *data2, size_t len2) { ut_ad(len1 != UNIV_SQL_DEFAULT); ut_ad(len2 != UNIV_SQL_DEFAULT); + int cmp= 0; + if (len1 == UNIV_SQL_NULL || len2 == UNIV_SQL_NULL) { if (len1 == len2) return 0; /* We define the SQL null to be the smallest possible value of a field. */ - return len1 == UNIV_SQL_NULL ? -1 : 1; + cmp= len1 == UNIV_SQL_NULL ? -1 : 1; + func_exit: + return UNIV_UNLIKELY(descending) ? -cmp : cmp; } switch (mtype) { default: ib::fatal() << "Unknown data type number " << mtype; case DATA_DECIMAL: - return cmp_decimal(data1, len1, data2, len2); + cmp= cmp_decimal(data1, len1, data2, len2); + goto func_exit; case DATA_DOUBLE: { const double af= mach_double_read(data1), bf= mach_double_read(data2); - return af > bf ? 1 : bf > af ? -1 : 0; + cmp= af > bf ? 1 : bf > af ? -1 : 0; } + goto func_exit; case DATA_FLOAT: { const float af= mach_float_read(data1), bf= mach_float_read(data2); - return af > bf ? 1 : bf > af ? -1 : 0; + cmp= af > bf ? 1 : bf > af ? -1 : 0; } + goto func_exit; case DATA_FIXBINARY: case DATA_BINARY: if (dtype_get_charset_coll(prtype) != DATA_MYSQL_BINARY_CHARSET_COLL) { if (ulint len= std::min(len1, len2)) { - if (int cmp= memcmp(data1, data2, len)) - return cmp; + cmp= memcmp(data1, data2, len); + if (cmp) + goto func_exit; data1+= len; data2+= len; len1-= len; len2-= len; } - - int cmp= 0; if (len1) { const byte *end= &data1[len1]; @@ -259,7 +266,7 @@ static int cmp_data(ulint mtype, ulint prtype, const byte *data1, ulint len1, cmp= static_cast<int>(byte{0x20} - *data2++); while (cmp == 0 && data2 < end); } - return cmp; + goto func_exit; } /* fall through */ case DATA_INT: @@ -272,7 +279,8 @@ static int cmp_data(ulint mtype, ulint prtype, const byte *data1, ulint len1, { ut_ad(len1 == DATA_MBR_LEN); ut_ad(len2 == DATA_MBR_LEN); - return cmp_geometry_field(data1, data2); + cmp= cmp_geometry_field(data1, data2); + goto func_exit; } break; case DATA_BLOB: @@ -282,14 +290,20 @@ static int cmp_data(ulint mtype, ulint prtype, const byte *data1, ulint len1, case DATA_VARMYSQL: DBUG_ASSERT(is_strnncoll_compatible(prtype & DATA_MYSQL_TYPE_MASK)); if (CHARSET_INFO *cs= all_charsets[dtype_get_charset_coll(prtype)]) - return cs->coll->strnncollsp(cs, data1, len1, data2, len2); + { + cmp= cs->coll->strnncollsp(cs, data1, len1, data2, len2); + goto func_exit; + } no_collation: ib::fatal() << "Unable to find charset-collation for " << prtype; case DATA_MYSQL: DBUG_ASSERT(is_strnncoll_compatible(prtype & DATA_MYSQL_TYPE_MASK)); if (CHARSET_INFO *cs= all_charsets[dtype_get_charset_coll(prtype)]) - return cs->coll->strnncollsp_nchars(cs, data1, len1, data2, len2, - std::max(len1, len2)); + { + cmp= cs->coll->strnncollsp_nchars(cs, data1, len1, data2, len2, + std::max(len1, len2)); + goto func_exit; + } goto no_collation; case DATA_VARCHAR: case DATA_CHAR: @@ -297,62 +311,42 @@ static int cmp_data(ulint mtype, ulint prtype, const byte *data1, ulint len1, Because it is a fixed-length encoding (mbminlen=mbmaxlen=1), non-NULL CHAR(n) values will always occupy n bytes and we can invoke strnncollsp() instead of strnncollsp_nchars(). */ - return my_charset_latin1.strnncollsp(data1, len1, data2, len2); + cmp= my_charset_latin1.strnncollsp(data1, len1, data2, len2); + goto func_exit; } if (ulint len= std::min(len1, len2)) - if (int cmp= memcmp(data1, data2, len)) - return cmp; + { + cmp= memcmp(data1, data2, len); + if (cmp) + goto func_exit; + } - return len1 > len2 ? 1 : len2 > len1 ? -1 : 0; -} - -/** Compare two data fields. -@param[in] mtype main type -@param[in] prtype precise type -@param[in] data1 data field -@param[in] len1 length of data1 in bytes, or UNIV_SQL_NULL -@param[in] data2 data field -@param[in] len2 length of data2 in bytes, or UNIV_SQL_NULL -@return the comparison result of data1 and data2 -@retval 0 if data1 is equal to data2 -@retval negative if data1 is less than data2 -@retval positive if data1 is greater than data2 */ -int -cmp_data_data( - ulint mtype, - ulint prtype, - const byte* data1, - ulint len1, - const byte* data2, - ulint len2) -{ - return(cmp_data(mtype, prtype, data1, len1, data2, len2)); + cmp= int(len1 - len2); + goto func_exit; } /** Compare a data tuple to a physical record. -@param[in] dtuple data tuple -@param[in] rec B-tree record -@param[in] offsets rec_get_offsets(rec) -@param[in] n_cmp number of fields to compare -@param[in,out] matched_fields number of completely matched fields +@param dtuple data tuple +@param rec B-tree index record +@param index B-tree index +@param offsets rec_get_offsets(rec,index) +@param n_cmp number of fields to compare +@param matched_fields number of completely matched fields @return the comparison result of dtuple and rec @retval 0 if dtuple is equal to rec @retval negative if dtuple is less than rec @retval positive if dtuple is greater than rec */ -int -cmp_dtuple_rec_with_match_low( - const dtuple_t* dtuple, - const rec_t* rec, - const rec_offs* offsets, - ulint n_cmp, - ulint* matched_fields) +int cmp_dtuple_rec_with_match_low(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, + const rec_offs *offsets, + ulint n_cmp, ulint *matched_fields) { ulint cur_field; /* current field number */ - int ret; /* return value */ + int ret = 0; /* return value */ ut_ad(dtuple_check_typed(dtuple)); - ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(rec_offs_validate(rec, index, offsets)); cur_field = *matched_fields; @@ -366,6 +360,7 @@ cmp_dtuple_rec_with_match_low( rec_offs_comp(offsets)); ulint tup_info = dtuple_get_info_bits(dtuple); + /* The "infimum node pointer" is always first. */ if (UNIV_UNLIKELY(rec_info & REC_INFO_MIN_REC_FLAG)) { ret = !(tup_info & REC_INFO_MIN_REC_FLAG); goto order_resolved; @@ -406,7 +401,8 @@ cmp_dtuple_rec_with_match_low( ut_ad(!dfield_is_ext(dtuple_field)); - ret = cmp_data(type->mtype, type->prtype, + ret = cmp_data(type->mtype, type->prtype, !index->is_ibuf() + && index->fields[cur_field].descending, dtuple_b_ptr, dtuple_f_len, rec_b_ptr, rec_f_len); if (ret) { @@ -414,8 +410,6 @@ cmp_dtuple_rec_with_match_low( } } - ret = 0; /* If we ran out of fields, dtuple was equal to rec - up to the common fields */ order_resolved: *matched_fields = cur_field; return(ret); @@ -486,6 +480,7 @@ cmp_dtuple_rec_with_match_bytes( ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!(REC_INFO_MIN_REC_FLAG & dtuple_get_info_bits(dtuple))); + ut_ad(!index->is_ibuf()); if (UNIV_UNLIKELY(REC_INFO_MIN_REC_FLAG & rec_get_info_bits(rec, rec_offs_comp(offsets)))) { @@ -498,7 +493,7 @@ cmp_dtuple_rec_with_match_bytes( ulint cur_field = *matched_fields; ulint cur_bytes = *matched_bytes; ulint n_cmp = dtuple_get_n_fields_cmp(dtuple); - int ret; + int ret = 0; ut_ad(n_cmp <= dtuple_get_n_fields(dtuple)); ut_ad(cur_field <= n_cmp); @@ -559,7 +554,7 @@ cmp_dtuple_rec_with_match_bytes( } /* fall through */ default: - ret = cmp_data(type->mtype, type->prtype, + ret = cmp_data(type->mtype, type->prtype, false, dtuple_b_ptr, dtuple_f_len, rec_b_ptr, rec_f_len); @@ -623,62 +618,29 @@ next_field: ut_ad(cur_bytes == 0); - ret = 0; /* If we ran out of fields, dtuple was equal to rec - up to the common fields */ order_resolved: *matched_fields = cur_field; *matched_bytes = cur_bytes; - return(ret); + return !ret || UNIV_LIKELY(!index->fields[cur_field].descending) + ? ret : -ret; } -/** Compare a data tuple to a physical record. -@see cmp_dtuple_rec_with_match -@param[in] dtuple data tuple -@param[in] rec B-tree record -@param[in] offsets rec_get_offsets(rec); may be NULL -for ROW_FORMAT=REDUNDANT -@return the comparison result of dtuple and rec -@retval 0 if dtuple is equal to rec -@retval negative if dtuple is less than rec -@retval positive if dtuple is greater than rec */ -int -cmp_dtuple_rec( - const dtuple_t* dtuple, - const rec_t* rec, - const rec_offs* offsets) -{ - ulint matched_fields = 0; - - ut_ad(rec_offs_validate(rec, NULL, offsets)); - return(cmp_dtuple_rec_with_match(dtuple, rec, offsets, - &matched_fields)); -} - -/**************************************************************//** -Checks if a dtuple is a prefix of a record. The last field in dtuple -is allowed to be a prefix of the corresponding field in the record. -@return TRUE if prefix */ -ibool -cmp_dtuple_is_prefix_of_rec( -/*========================*/ - const dtuple_t* dtuple, /*!< in: data tuple */ - const rec_t* rec, /*!< in: physical record */ - const rec_offs* offsets)/*!< in: array returned by rec_get_offsets() */ +/** Check if a dtuple is a prefix of a record. +@param dtuple data tuple +@param rec index record +@param index index +@param offsets rec_get_offsets(rec) +@return whether dtuple is a prefix of rec */ +bool cmp_dtuple_is_prefix_of_rec(const dtuple_t *dtuple, const rec_t *rec, + const dict_index_t *index, + const rec_offs *offsets) { - ulint n_fields; - ulint matched_fields = 0; - - ut_ad(rec_offs_validate(rec, NULL, offsets)); - n_fields = dtuple_get_n_fields(dtuple); - - if (n_fields > rec_offs_n_fields(offsets)) { - ut_ad(0); - return(FALSE); - } - - cmp_dtuple_rec_with_match(dtuple, rec, offsets, &matched_fields); - return(matched_fields == n_fields); + ulint matched_fields= 0; + ulint n_fields= dtuple_get_n_fields(dtuple); + ut_ad(n_fields <= rec_offs_n_fields(offsets)); + cmp_dtuple_rec_with_match(dtuple, rec, index, offsets, &matched_fields); + return matched_fields == n_fields; } /*************************************************************//** @@ -701,7 +663,7 @@ cmp_rec_rec_simple_field( const byte* rec2_b_ptr; ulint rec1_f_len; ulint rec2_f_len; - const dict_col_t* col = dict_index_get_nth_col(index, n); + const dict_field_t* field = dict_index_get_nth_field(index, n); ut_ad(!rec_offs_nth_extern(offsets1, n)); ut_ad(!rec_offs_nth_extern(offsets2, n)); @@ -709,8 +671,9 @@ cmp_rec_rec_simple_field( rec1_b_ptr = rec_get_nth_field(rec1, offsets1, n, &rec1_f_len); rec2_b_ptr = rec_get_nth_field(rec2, offsets2, n, &rec2_f_len); - return(cmp_data(col->mtype, col->prtype, - rec1_b_ptr, rec1_f_len, rec2_b_ptr, rec2_f_len)); + return cmp_data(field->col->mtype, field->col->prtype, + field->descending, + rec1_b_ptr, rec1_f_len, rec2_b_ptr, rec2_f_len); } /** Compare two physical records that contain the same number of columns, @@ -868,16 +831,19 @@ cmp_rec_rec( for (; cur_field < n_fields; cur_field++) { ulint mtype; ulint prtype; + bool descending; if (UNIV_UNLIKELY(dict_index_is_ibuf(index))) { /* This is for the insert buffer B-tree. */ mtype = DATA_BINARY; prtype = 0; + descending = false; } else { - const dict_col_t* col = dict_index_get_nth_col( + const dict_field_t* field = dict_index_get_nth_field( index, cur_field); - mtype = col->mtype; - prtype = col->prtype; + descending = field->descending; + mtype = field->col->mtype; + prtype = field->col->prtype; if (UNIV_LIKELY(!dict_index_is_spatial(index))) { } else if (cur_field == 0) { @@ -913,9 +879,8 @@ cmp_rec_rec( goto order_resolved; } - ret = cmp_data(mtype, prtype, - rec1_b_ptr, rec1_f_len, - rec2_b_ptr, rec2_f_len); + ret = cmp_data(mtype, prtype, descending, + rec1_b_ptr, rec1_f_len, rec2_b_ptr, rec2_f_len); if (ret) { goto order_resolved; } @@ -930,28 +895,3 @@ order_resolved: } return ret; } - -#ifdef UNIV_COMPILE_TEST_FUNCS - -#ifdef HAVE_UT_CHRONO_T - -void -test_cmp_data_data(ulint len) -{ - int i; - static byte zeros[64]; - - if (len > sizeof zeros) { - len = sizeof zeros; - } - - ut_chrono_t ch(__func__); - - for (i = 1000000; i > 0; i--) { - i += cmp_data(DATA_INT, 0, zeros, len, zeros, len); - } -} - -#endif /* HAVE_UT_CHRONO_T */ - -#endif /* UNIV_COMPILE_TEST_FUNCS */ diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 86e9662439a..419a120c2af 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -96,6 +96,7 @@ row_merge_create_fts_sort_index( field = dict_index_get_nth_field(new_index, 0); field->name = NULL; field->prefix_len = 0; + field->descending = false; field->col = static_cast<dict_col_t*>( mem_heap_zalloc(new_index->heap, sizeof(dict_col_t))); field->col->prtype = idx_field->col->prtype | DATA_NOT_NULL; @@ -112,6 +113,7 @@ row_merge_create_fts_sort_index( field = dict_index_get_nth_field(new_index, 1); field->name = NULL; field->prefix_len = 0; + field->descending = false; field->col = static_cast<dict_col_t*>( mem_heap_zalloc(new_index->heap, sizeof(dict_col_t))); field->col->mtype = DATA_INT; @@ -151,6 +153,7 @@ row_merge_create_fts_sort_index( field = dict_index_get_nth_field(new_index, 2); field->name = NULL; field->prefix_len = 0; + field->descending = false; field->col = static_cast<dict_col_t*>( mem_heap_zalloc(new_index->heap, sizeof(dict_col_t))); field->col->mtype = DATA_INT; @@ -188,7 +191,6 @@ row_fts_psort_info_init( fts_psort_t* merge_info = NULL; ulint block_size; ibool ret = TRUE; - bool encrypted = false; ut_ad(ut_is_2pow(old_zip_size)); block_size = 3 * srv_sort_buf_size; @@ -219,10 +221,6 @@ row_fts_psort_info_init( pthread_cond_init(&common_info->sort_cond, nullptr); common_info->opt_doc_id_size = opt_doc_id_size; - if (log_tmp_is_encrypted()) { - encrypted = true; - } - ut_ad(trx->mysql_thd != NULL); const char* path = thd_innodb_tmpdir(trx->mysql_thd); /* There will be FTS_NUM_AUX_INDEX number of "sort buckets" for @@ -264,7 +262,7 @@ row_fts_psort_info_init( /* If tablespace is encrypted, allocate additional buffer for encryption/decryption. */ - if (encrypted) { + if (srv_encrypt_log) { /* Need to align memory for O_DIRECT write */ psort_info[j].crypt_block[i] = static_cast<row_merge_block_t*>( diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 5468f3aed34..e11f4e8a26d 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -4032,7 +4032,7 @@ page_corrupted: ut_ad(!comp == (size == srv_page_size)); ut_ad(!corrupt); mach_write_to_4(dest + (size - 4), - ut_crc32(dest, size - 4)); + my_crc32c(0, dest, size - 4)); } } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 9064b1c3c66..7f9fbe896ee 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1663,7 +1663,7 @@ row_ins_check_foreign_constraint( } } - cmp = cmp_dtuple_rec(entry, rec, offsets); + cmp = cmp_dtuple_rec(entry, rec, check_index, offsets); if (cmp == 0) { if (rec_get_deleted_flag(rec, @@ -1990,7 +1990,7 @@ row_ins_dupl_error_with_rec( matched_fields = 0; - cmp_dtuple_rec_with_match(entry, rec, offsets, &matched_fields); + cmp_dtuple_rec_with_match(entry, rec, index, offsets, &matched_fields); if (matched_fields < n_unique) { @@ -2119,7 +2119,7 @@ row_ins_scan_sec_index_for_duplicate( continue; } - cmp = cmp_dtuple_rec(entry, rec, offsets); + cmp = cmp_dtuple_rec(entry, rec, index, offsets); if (cmp == 0) { if (row_ins_dupl_error_with_rec(rec, entry, @@ -2156,18 +2156,20 @@ end_scan: } /** Checks for a duplicate when the table is being rebuilt online. +@param n_uniq index->db_trx_id() +@param entry entry being inserted +@param rec clustered index record at insert position +@param index clustered index +@param offsets rec_get_offsets(rec) @retval DB_SUCCESS when no duplicate is detected @retval DB_SUCCESS_LOCKED_REC when rec is an exact match of entry or a newer version of entry (the entry should not be inserted) @retval DB_DUPLICATE_KEY when entry is a duplicate of rec */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t -row_ins_duplicate_online( -/*=====================*/ - ulint n_uniq, /*!< in: offset of DB_TRX_ID */ - const dtuple_t* entry, /*!< in: entry that is being inserted */ - const rec_t* rec, /*!< in: clustered index record */ - rec_offs* offsets)/*!< in/out: rec_get_offsets(rec) */ +row_ins_duplicate_online(ulint n_uniq, const dtuple_t *entry, + const rec_t *rec, const dict_index_t *index, + rec_offs *offsets) { ulint fields = 0; @@ -2175,11 +2177,11 @@ row_ins_duplicate_online( in the new table. */ ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); ut_ad(dtuple_get_n_fields_cmp(entry) == n_uniq); + ut_ad(n_uniq == index->db_trx_id()); - /* Compare the PRIMARY KEY fields and the - DB_TRX_ID, DB_ROLL_PTR. */ - cmp_dtuple_rec_with_match_low( - entry, rec, offsets, n_uniq + 2, &fields); + /* Compare the PRIMARY KEY fields and the DB_TRX_ID, DB_ROLL_PTR. */ + cmp_dtuple_rec_with_match_low(entry, rec, index, offsets, n_uniq + 2, + &fields); if (fields < n_uniq) { /* Not a duplicate. */ @@ -2188,7 +2190,7 @@ row_ins_duplicate_online( ulint trx_id_len; - if (fields == n_uniq + 2 + if (fields == n_uniq && memcmp(rec_get_nth_field(rec, offsets, n_uniq, &trx_id_len), reset_trx_id, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)) { ut_ad(trx_id_len == DATA_TRX_ID_LEN); @@ -2224,7 +2226,8 @@ row_ins_duplicate_error_in_clust_online( *offsets = rec_get_offsets(rec, cursor->index, *offsets, cursor->index->n_fields, ULINT_UNDEFINED, heap); - err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets); + err = row_ins_duplicate_online(n_uniq, entry, + rec, cursor->index, *offsets); if (err != DB_SUCCESS) { return(err); } @@ -2238,7 +2241,8 @@ row_ins_duplicate_error_in_clust_online( *offsets = rec_get_offsets(rec, cursor->index, *offsets, cursor->index->n_fields, ULINT_UNDEFINED, heap); - err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets); + err = row_ins_duplicate_online(n_uniq, entry, + rec, cursor->index, *offsets); } return(err); diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index cfc3d6f18f2..ff190bd0779 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -385,7 +385,7 @@ start_log: /* If encryption is enabled encrypt buffer before writing it to file system. */ - if (log_tmp_is_encrypted()) { + if (srv_encrypt_log) { if (!log_tmp_block_encrypt( buf, srv_sort_buf_size, log->crypt_tail, byte_offset)) { @@ -520,7 +520,7 @@ row_log_table_close_func( /* If encryption is enabled encrypt buffer before writing it to file system. */ - if (log_tmp_is_encrypted()) { + if (srv_encrypt_log) { if (!log_tmp_block_encrypt( log->tail.block, srv_sort_buf_size, log->crypt_tail, byte_offset, @@ -2606,7 +2606,7 @@ all_done: goto corruption; } - if (log_tmp_is_encrypted()) { + if (srv_encrypt_log) { if (!log_tmp_block_decrypt( buf, srv_sort_buf_size, index->online_log->crypt_head, ofs)) { @@ -2959,7 +2959,7 @@ row_log_allocate( dict_index_set_online_status(index, ONLINE_INDEX_CREATION); - if (log_tmp_is_encrypted()) { + if (srv_encrypt_log) { log->crypt_head_size = log->crypt_tail_size = srv_sort_buf_size; log->crypt_head = static_cast<byte *>( my_large_malloc(&log->crypt_head_size, MYF(MY_WME))); @@ -3525,7 +3525,7 @@ all_done: goto corruption; } - if (log_tmp_is_encrypted()) { + if (srv_encrypt_log) { if (!log_tmp_block_decrypt( buf, srv_sort_buf_size, index->online_log->crypt_head, ofs)) { diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index c8e94991500..f9fef9747c6 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -932,6 +932,7 @@ static MY_ATTRIBUTE((warn_unused_result)) int row_merge_tuple_cmp( /*================*/ + const dict_index_t* index, /*< in: index tree */ ulint n_uniq, /*!< in: number of unique fields */ ulint n_field,/*!< in: number of fields */ const mtuple_t& a, /*!< in: first tuple to be compared */ @@ -943,6 +944,7 @@ row_merge_tuple_cmp( const dfield_t* af = a.fields; const dfield_t* bf = b.fields; ulint n = n_uniq; + const dict_field_t* f = index->fields; ut_ad(n_uniq > 0); ut_ad(n_uniq <= n_field); @@ -951,7 +953,7 @@ row_merge_tuple_cmp( found or we run out of fields to compare. If !cmp at the end, the tuples are equal. */ do { - cmp = cmp_dfield_dfield(af++, bf++); + cmp = cmp_dfield_dfield(af++, bf++, (f++)->descending); } while (!cmp && --n); if (cmp) { @@ -976,7 +978,7 @@ no_report: /* The n_uniq fields were equal, but we compare all fields so that we will get the same (internal) order as in the B-tree. */ for (n = n_field - n_uniq + 1; --n; ) { - cmp = cmp_dfield_dfield(af++, bf++); + cmp = cmp_dfield_dfield(af++, bf++, (f++)->descending); if (cmp) { return(cmp); } @@ -996,7 +998,7 @@ UT_SORT_FUNCTION_BODY(). @param low lower bound of the sorting area, inclusive @param high upper bound of the sorting area, inclusive */ #define row_merge_tuple_sort_ctx(tuples, aux, low, high) \ - row_merge_tuple_sort(n_uniq, n_field, dup, tuples, aux, low, high) + row_merge_tuple_sort(index,n_uniq,n_field,dup, tuples, aux, low, high) /** Wrapper for row_merge_tuple_cmp() to inject some more context to UT_SORT_FUNCTION_BODY(). @param a first tuple to be compared @@ -1004,7 +1006,7 @@ UT_SORT_FUNCTION_BODY(). @return positive, 0, negative, if a is greater, equal, less, than b, respectively */ #define row_merge_tuple_cmp_ctx(a,b) \ - row_merge_tuple_cmp(n_uniq, n_field, a, b, dup) + row_merge_tuple_cmp(index, n_uniq, n_field, a, b, dup) /**********************************************************************//** Merge sort the tuple buffer in main memory. */ @@ -1012,6 +1014,7 @@ static void row_merge_tuple_sort( /*=================*/ + const dict_index_t* index, /*!< in: index tree */ ulint n_uniq, /*!< in: number of unique fields */ ulint n_field,/*!< in: number of fields */ row_merge_dup_t* dup, /*!< in/out: reporter of duplicates @@ -1039,12 +1042,9 @@ row_merge_buf_sort( row_merge_dup_t* dup) /*!< in/out: reporter of duplicates (NULL if non-unique index) */ { - ut_ad(!dict_index_is_spatial(buf->index)); - - row_merge_tuple_sort(dict_index_get_n_unique(buf->index), - dict_index_get_n_fields(buf->index), - dup, - buf->tuples, buf->tmp_tuples, 0, buf->n_tuples); + ut_ad(!buf->index->is_spatial()); + row_merge_tuple_sort(buf->index, buf->index->n_uniq, buf->index->n_fields, + dup, buf->tuples, buf->tmp_tuples, 0, buf->n_tuples); } /** Write the blob field data to temporary file and fill the offset, @@ -1262,7 +1262,7 @@ row_merge_read( IORequestRead, fd, buf, ofs, srv_sort_buf_size, 0); /* If encryption is enabled decrypt buffer */ - if (success && log_tmp_is_encrypted()) { + if (success && srv_encrypt_log) { if (!log_tmp_block_decrypt(buf, srv_sort_buf_size, crypt_buf, ofs)) { DBUG_RETURN(false); @@ -1307,7 +1307,7 @@ row_merge_write( DBUG_EXECUTE_IF("row_merge_write_failure", DBUG_RETURN(FALSE);); /* For encrypted tables, encrypt data before writing */ - if (log_tmp_is_encrypted()) { + if (srv_encrypt_log) { if (!log_tmp_block_encrypt(static_cast<const byte*>(buf), buf_len, static_cast<byte*>(crypt_buf), @@ -1726,11 +1726,10 @@ row_mtuple_cmp( const mtuple_t* current_mtuple, row_merge_dup_t* dup) { - ut_ad(dict_index_is_clust(dup->index)); - const ulint n_unique = dict_index_get_n_unique(dup->index); - - return(row_merge_tuple_cmp( - n_unique, n_unique, *current_mtuple, *prev_mtuple, dup)); + ut_ad(dup->index->is_primary()); + const ulint n_uniq= dup->index->n_uniq; + return row_merge_tuple_cmp(dup->index, n_uniq, n_uniq, + *current_mtuple, *prev_mtuple, dup); } /** Insert cached spatial index rows. @@ -4572,7 +4571,8 @@ row_merge_create_index( name = dict_table_get_col_name(table, ifield->col_no); } - dict_mem_index_add_field(index, name, ifield->prefix_len); + dict_mem_index_add_field(index, name, ifield->prefix_len, + ifield->descending); } if (n_add_vcol) { @@ -4702,7 +4702,7 @@ row_merge_build_indexes( crypt_pfx.m_size = 0; /* silence bogus -Wmaybe-uninitialized */ TRASH_ALLOC(&crypt_pfx, sizeof crypt_pfx); - if (log_tmp_is_encrypted()) { + if (srv_encrypt_log) { crypt_block = static_cast<row_merge_block_t*>( alloc.allocate_large(block_size, &crypt_pfx)); @@ -5078,7 +5078,7 @@ dberr_t row_merge_bulk_t::alloc_block() m_crypt_pfx.m_size= 0; TRASH_ALLOC(&m_crypt_pfx, sizeof m_crypt_pfx); - if (log_tmp_is_encrypted()) + if (srv_encrypt_log) { m_crypt_block= static_cast<row_merge_block_t*>( m_alloc.allocate_large(3 * srv_sort_buf_size, &m_crypt_pfx)); diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 434ea7cfd20..b60b21d2aff 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -1357,7 +1357,7 @@ purge_node_t::validate_pcur() part in persistent cursor. Both cases we store n_uniq fields of the cluster index and so it is fine to do the comparison. We note this dependency here as pcur and ref belong to different modules. */ - int st = cmp_dtuple_rec(ref, pcur.old_rec, offsets); + int st = cmp_dtuple_rec(ref, pcur.old_rec, clust_index, offsets); if (st != 0) { ib::error() << "Purge node pcur validation failed"; diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 82079cbd06b..cf1aaedf240 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -152,7 +152,7 @@ row_sel_sec_rec_is_for_blob( return false; } - return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len)); + return !cmp_data(mtype, prtype, false, buf, len, sec_field, sec_len); } /** Function to read the secondary spatial index, calculate @@ -399,9 +399,8 @@ compare_blobs: } } - if (0 != cmp_data_data(col->mtype, col->prtype, - clust_field, len, - sec_field, sec_len)) { + if (cmp_data(col->mtype, col->prtype, false, + clust_field, len, sec_field, sec_len)) { return DB_SUCCESS; } } @@ -3321,7 +3320,7 @@ class Row_sel_get_clust_rec_for_mysql ulint len1, len2; const byte *b1= rec_get_nth_field(cached_clust_rec, offsets, n, &len1); const byte *b2= rec_get_nth_field(cached_old_vers, vers_offs, n, &len2); - ut_ad(!cmp_data_data(col->mtype, col->prtype, b1, len1, b2, len2)); + ut_ad(!cmp_data(col->mtype, col->prtype, false, b1, len1, b2, len2)); } } #endif @@ -5061,7 +5060,7 @@ wrong_offs: /* fputs("Comparing rec and search tuple\n", stderr); */ - if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) { + if (cmp_dtuple_rec(search_tuple, rec, index, offsets)) { if (set_also_gap_locks && !dict_index_is_spatial(index)) { @@ -5096,7 +5095,8 @@ wrong_offs: } else if (match_mode == ROW_SEL_EXACT_PREFIX) { - if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec, offsets)) { + if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec, + index, offsets)) { if (set_also_gap_locks && !dict_index_is_spatial(index)) { @@ -5217,7 +5217,7 @@ wrong_offs: && direction == 0 && dtuple_get_n_fields_cmp(search_tuple) == dict_index_get_n_unique(index) - && 0 == cmp_dtuple_rec(search_tuple, rec, offsets)) { + && !cmp_dtuple_rec(search_tuple, rec, index, offsets)) { no_gap_lock: lock_type = LOCK_REC_NOT_GAP; } @@ -6170,8 +6170,8 @@ compare_blobs: } } - if (cmp_data_data(ifield.col->mtype, ifield.col->prtype, - field, len, sec_field, sec_len)) + if (cmp_data(ifield.col->mtype, ifield.col->prtype, false, + field, len, sec_field, sec_len)) return DB_SUCCESS_LOCKED_REC; } @@ -6768,7 +6768,7 @@ count_row: if (prev_entry) { ulint matched_fields= 0; - int cmp= cmp_dtuple_rec_with_match(prev_entry, rec, offsets, + int cmp= cmp_dtuple_rec_with_match(prev_entry, rec, index, offsets, &matched_fields); const char* msg; @@ -6885,26 +6885,38 @@ row_search_get_max_rec( { btr_pcur_t pcur; const rec_t* rec; - /* Open at the high/right end (false), and init cursor */ - if (btr_pcur_open_at_index_side(false, index, BTR_SEARCH_LEAF, &pcur, + const bool desc = index->fields[0].descending; + + if (btr_pcur_open_at_index_side(desc, index, BTR_SEARCH_LEAF, &pcur, true, 0, mtr) != DB_SUCCESS) { return nullptr; } - do { - const page_t* page; - - page = btr_pcur_get_page(&pcur); - rec = page_find_rec_max_not_deleted(page); - - if (page_rec_is_user_rec(rec)) { - break; - } else { - rec = NULL; + if (desc) { + const bool comp = index->table->not_redundant(); + while (btr_pcur_move_to_next_user_rec(&pcur, mtr)) { + rec = btr_pcur_get_rec(&pcur); + if (rec_is_metadata(rec, *index)) { + continue; + } + if (!rec_get_deleted_flag(rec, comp)) { + goto found; + } } - btr_pcur_move_before_first_on_page(&pcur); - } while (btr_pcur_move_to_prev(&pcur, mtr)); + } else { + do { + rec = page_find_rec_last_not_deleted( + btr_pcur_get_page(&pcur)); + if (page_rec_is_user_rec(rec)) { + goto found; + } + btr_pcur_move_before_first_on_page(&pcur); + } while (btr_pcur_move_to_prev(&pcur, mtr)); + } + + rec = nullptr; +found: ut_ad(!rec || !(rec_get_info_bits(rec, dict_table_is_comp(index->table)) & (REC_INFO_MIN_REC_FLAG | REC_INFO_DELETED_FLAG))); diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 372d30149f0..a4b52fd2a2f 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -328,7 +328,7 @@ not_locked: /* We check if entry and rec are identified in the alphabetical ordering */ - if (0 == cmp_dtuple_rec(entry, rec, offsets)) { + if (0 == cmp_dtuple_rec(entry, rec, index, offsets)) { /* The delete marks of rec and prev_version should be equal for rec to be in the state required by prev_version */ @@ -346,7 +346,7 @@ not_locked: dtuple_set_types_binary( entry, dtuple_get_n_fields(entry)); - if (0 != cmp_dtuple_rec(entry, rec, offsets)) { + if (cmp_dtuple_rec(entry, rec, index, offsets)) { break; } @@ -741,7 +741,7 @@ row_vers_vc_matches_cluster( /* The index field mismatch */ if (v_heap - || cmp_dfield_dfield(field2, field1) != 0) { + || cmp_dfield_dfield(field2, field1)) { if (v_heap) { dtuple_dup_v_fld(*vrow, v_heap); } @@ -844,6 +844,21 @@ row_vers_build_cur_vrow( return(cur_vrow); } +/** @return whether two data tuples are equal */ +static bool dtuple_coll_eq(const dtuple_t &tuple1, const dtuple_t &tuple2) +{ + ut_ad(tuple1.magic_n == DATA_TUPLE_MAGIC_N); + ut_ad(tuple2.magic_n == DATA_TUPLE_MAGIC_N); + ut_ad(dtuple_check_typed(&tuple1)); + ut_ad(dtuple_check_typed(&tuple2)); + ut_ad(tuple1.n_fields == tuple2.n_fields); + + for (ulint i= 0; i < tuple1.n_fields; i++) + if (cmp_dfield_dfield(&tuple1.fields[i], &tuple2.fields[i])) + return false; + return true; +} + /** Finds out if a version of the record, where the version >= the current purge_sys.view, should have ientry as its secondary index entry. We check if there is any not delete marked version of the record where the trx @@ -944,7 +959,7 @@ row_vers_old_has_index_entry( entry = row_build_index_entry( row, ext, index, heap); - if (entry && !dtuple_coll_cmp(ientry, entry)) { + if (entry && dtuple_coll_eq(*ientry, *entry)) { goto unsafe_to_purge; } } else { @@ -999,7 +1014,7 @@ row_vers_old_has_index_entry( the clustered index record has already been updated to a different binary value in a char field, but the collation identifies the old and new value anyway! */ - if (entry && !dtuple_coll_cmp(ientry, entry)) { + if (entry && dtuple_coll_eq(*ientry, *entry)) { unsafe_to_purge: mem_heap_free(heap); @@ -1098,7 +1113,7 @@ unsafe_to_purge: a char field, but the collation identifies the old and new value anyway! */ - if (entry && !dtuple_coll_cmp(ientry, entry)) { + if (entry && dtuple_coll_eq(*ientry, *entry)) { goto unsafe_to_purge; } } diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 60fef24d183..581fd199195 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -651,24 +651,6 @@ static monitor_info_t innodb_counter_info[] = MONITOR_EXISTING | MONITOR_DEFAULT_ON), MONITOR_DEFAULT_START, MONITOR_OVLD_OS_LOG_WRITTEN}, - {"os_log_fsyncs", "os", - "Number of fsync log writes (innodb_os_log_fsyncs)", - static_cast<monitor_type_t>( - MONITOR_EXISTING | MONITOR_DEFAULT_ON), - MONITOR_DEFAULT_START, MONITOR_OVLD_OS_LOG_FSYNC}, - - {"os_log_pending_fsyncs", "os", - "Number of pending fsync write (innodb_os_log_pending_fsyncs)", - static_cast<monitor_type_t>( - MONITOR_EXISTING | MONITOR_DEFAULT_ON), - MONITOR_DEFAULT_START, MONITOR_OVLD_OS_LOG_PENDING_FSYNC}, - - {"os_log_pending_writes", "os", - "Number of pending log file writes (innodb_os_log_pending_writes)", - static_cast<monitor_type_t>( - MONITOR_EXISTING | MONITOR_DEFAULT_ON), - MONITOR_DEFAULT_START, MONITOR_OVLD_OS_LOG_PENDING_WRITES}, - /* ========== Counters for Transaction Module ========== */ {"module_trx", "transaction", "Transaction Manager", MONITOR_MODULE, @@ -769,8 +751,9 @@ static monitor_info_t innodb_counter_info[] = MONITOR_DEFAULT_START, MONITOR_MODULE_RECOVERY}, {"log_checkpoints", "recovery", "Number of checkpoints", - MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_NUM_CHECKPOINT}, + static_cast<monitor_type_t>( + MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT), + MONITOR_DEFAULT_START, MONITOR_OVLD_CHECKPOINTS}, {"log_lsn_last_flush", "recovery", "LSN of Last flush", static_cast<monitor_type_t>( @@ -805,21 +788,6 @@ static monitor_info_t innodb_counter_info[] = MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT), MONITOR_DEFAULT_START, MONITOR_OVLD_MAX_AGE_ASYNC}, - {"log_pending_log_flushes", "recovery", "Pending log flushes", - static_cast<monitor_type_t>( - MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT), - MONITOR_DEFAULT_START, MONITOR_PENDING_LOG_FLUSH}, - - {"log_pending_checkpoint_writes", "recovery", "Pending checkpoints", - static_cast<monitor_type_t>( - MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT), - MONITOR_DEFAULT_START, MONITOR_PENDING_CHECKPOINT_WRITE}, - - {"log_num_log_io", "recovery", "Number of log I/Os", - static_cast<monitor_type_t>( - MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT), - MONITOR_DEFAULT_START, MONITOR_LOG_IO}, - {"log_waits", "recovery", "Number of log waits due to small log buffer (innodb_log_waits)", static_cast<monitor_type_t>( @@ -838,12 +806,6 @@ static monitor_info_t innodb_counter_info[] = MONITOR_EXISTING | MONITOR_DEFAULT_ON), MONITOR_DEFAULT_START, MONITOR_OVLD_LOG_WRITES}, - {"log_padded", "recovery", - "Bytes of log padded for log write ahead", - static_cast<monitor_type_t>( - MONITOR_EXISTING | MONITOR_DEFAULT_ON), - MONITOR_DEFAULT_START, MONITOR_OVLD_LOG_PADDED}, - /* ========== Counters for Page Compression ========== */ {"module_compress", "compression", "Page Compression Info", MONITOR_MODULE, @@ -1392,6 +1354,7 @@ corresponding monitors are turned on/off/reset, and do appropriate mathematics to deduct the actual value. Please also refer to srv_export_innodb_status() for related global counters used by the existing status variables.*/ +TPOOL_SUPPRESS_TSAN void srv_mon_process_existing_counter( /*=============================*/ @@ -1426,7 +1389,7 @@ srv_mon_process_existing_counter( /* innodb_buffer_pool_write_requests, the number of write request */ case MONITOR_OVLD_BUF_POOL_WRITE_REQUEST: - value = srv_stats.buf_pool_write_requests; + value = buf_pool.flush_list_requests; break; /* innodb_buffer_pool_wait_free */ @@ -1543,43 +1506,22 @@ srv_mon_process_existing_counter( /* innodb_os_log_written */ case MONITOR_OVLD_OS_LOG_WRITTEN: - value = (mon_type_t) srv_stats.os_log_written; - break; - - /* innodb_os_log_fsyncs */ - case MONITOR_OVLD_OS_LOG_FSYNC: - value = log_sys.get_flushes(); - break; - - /* innodb_os_log_pending_fsyncs */ - case MONITOR_OVLD_OS_LOG_PENDING_FSYNC: - value = log_sys.get_pending_flushes(); - update_min = TRUE; - break; - - /* innodb_os_log_pending_writes */ - case MONITOR_OVLD_OS_LOG_PENDING_WRITES: - value = srv_stats.os_log_pending_writes; - update_min = TRUE; + value = log_sys.get_lsn() - recv_sys.lsn; break; /* innodb_log_waits */ case MONITOR_OVLD_LOG_WAITS: - value = srv_stats.log_waits; + value = log_sys.waits; break; /* innodb_log_write_requests */ case MONITOR_OVLD_LOG_WRITE_REQUEST: - value = srv_stats.log_write_requests; + value = log_sys.write_to_buf; break; /* innodb_log_writes */ case MONITOR_OVLD_LOG_WRITES: - value = srv_stats.log_writes; - break; - - case MONITOR_OVLD_LOG_PADDED: - value = srv_stats.log_padded; + value = log_sys.write_to_log; break; /* innodb_dblwr_writes */ @@ -1737,26 +1679,15 @@ srv_mon_process_existing_counter( value = log_sys.get_lsn(); break; - case MONITOR_PENDING_LOG_FLUSH: - value = static_cast<mon_type_t>(log_sys.pending_flushes); - - break; - - case MONITOR_PENDING_CHECKPOINT_WRITE: - value = log_sys.checkpoint_pending; - break; - - case MONITOR_LOG_IO: - mysql_mutex_lock(&log_sys.mutex); - value = static_cast<mon_type_t>(log_sys.n_log_ios); - mysql_mutex_unlock(&log_sys.mutex); + case MONITOR_OVLD_CHECKPOINTS: + value = log_sys.next_checkpoint_no; break; case MONITOR_LSN_CHECKPOINT_AGE: - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.rd_lock(SRW_LOCK_CALL); value = static_cast<mon_type_t>(log_sys.get_lsn() - log_sys.last_checkpoint_lsn); - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.rd_unlock(); break; case MONITOR_OVLD_BUF_OLDEST_LSN: diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 10b22c9de7d..827c02592f2 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -61,7 +61,6 @@ Created 10/8/1995 Heikki Tuuri #include "srv0start.h" #include "trx0i_s.h" #include "trx0purge.h" -#include "ut0crc32.h" #include "btr0defragment.h" #include "ut0mem.h" #include "fil0fil.h" @@ -153,8 +152,6 @@ char* srv_log_group_home_dir; /** The InnoDB redo log file size, or 0 when changing the redo log format at startup (while disallowing writes to the redo log). */ ulonglong srv_log_file_size; -/** innodb_log_buffer_size, in bytes */ -ulong srv_log_buffer_size; /** innodb_flush_log_at_trx_commit */ ulong srv_flush_log_at_trx_commit; /** innodb_flush_log_at_timeout */ @@ -163,8 +160,6 @@ uint srv_flush_log_at_timeout; ulong srv_page_size; /** log2 of innodb_page_size; @see innodb_init_params() */ uint32_t srv_page_size_shift; -/** innodb_log_write_ahead_size */ -ulong srv_log_write_ahead_size; /** innodb_adaptive_flushing; try to flush dirty pages so as to avoid IO bursts at the checkpoints. */ @@ -188,9 +183,8 @@ with mysql_mutex_lock(), which will wait until it gets the mutex. */ /** copy of innodb_buffer_pool_size */ ulint srv_buf_pool_size; -/** Requested buffer pool chunk size. Each buffer pool instance consists -of one or more chunks. */ -ulong srv_buf_pool_chunk_unit; +/** Requested buffer pool chunk size */ +size_t srv_buf_pool_chunk_unit; /** innodb_lru_scan_depth; number of blocks scanned in LRU flush batch */ ulong srv_LRU_scan_depth; /** innodb_flush_neighbors; whether or not to flush neighbors of a block */ @@ -716,8 +710,6 @@ static void srv_refresh_innodb_monitor_stats(time_t current_time) btr_cur_n_non_sea_old = btr_cur_n_non_sea; #endif /* BTR_CUR_HASH_ADAPT */ - log_refresh_stats(); - buf_refresh_io_stats(); srv_n_rows_inserted_old = srv_stats.n_rows_inserted; @@ -1008,12 +1000,6 @@ srv_export_innodb_status(void) export_vars.innodb_data_pending_writes = ulint(MONITOR_VALUE(MONITOR_OS_PENDING_WRITES)); - export_vars.innodb_data_pending_fsyncs = - log_sys.get_pending_flushes() - + fil_n_pending_tablespace_flushes; - - export_vars.innodb_data_fsyncs = os_n_fsyncs; - export_vars.innodb_data_read = srv_stats.data_read; export_vars.innodb_data_reads = os_n_file_reads; @@ -1035,9 +1021,6 @@ srv_export_innodb_status(void) export_vars.innodb_buffer_pool_read_requests = buf_pool.stat.n_page_gets; - export_vars.innodb_buffer_pool_write_requests = - srv_stats.buf_pool_write_requests; - export_vars.innodb_buffer_pool_reads = srv_stats.buf_pool_reads; export_vars.innodb_buffer_pool_read_ahead_rnd = @@ -1087,22 +1070,6 @@ srv_export_innodb_status(void) export_vars.innodb_max_trx_id = trx_sys.get_max_trx_id(); export_vars.innodb_history_list_length = trx_sys.history_size_approx(); - export_vars.innodb_log_waits = srv_stats.log_waits; - - export_vars.innodb_os_log_written = srv_stats.os_log_written; - - export_vars.innodb_os_log_fsyncs = log_sys.get_flushes(); - - export_vars.innodb_os_log_pending_fsyncs - = log_sys.get_pending_flushes(); - - export_vars.innodb_os_log_pending_writes = - srv_stats.os_log_pending_writes; - - export_vars.innodb_log_write_requests = srv_stats.log_write_requests; - - export_vars.innodb_log_writes = srv_stats.log_writes; - mysql_mutex_lock(&lock_sys.wait_mutex); export_vars.innodb_row_lock_waits = lock_sys.get_wait_cumulative(); @@ -1190,13 +1157,15 @@ srv_export_innodb_status(void) mysql_mutex_unlock(&srv_innodb_monitor_mutex); - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.rd_lock(SRW_LOCK_CALL); export_vars.innodb_lsn_current = log_sys.get_lsn(); export_vars.innodb_lsn_flushed = log_sys.get_flushed_lsn(); export_vars.innodb_lsn_last_checkpoint = log_sys.last_checkpoint_lsn; export_vars.innodb_checkpoint_max_age = static_cast<ulint>( log_sys.max_checkpoint_age); - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.rd_unlock(); + export_vars.innodb_os_log_written = export_vars.innodb_lsn_current + - recv_sys.lsn; export_vars.innodb_checkpoint_age = static_cast<ulint>( export_vars.innodb_lsn_current @@ -1274,7 +1243,7 @@ static void srv_monitor() void srv_monitor_task(void*) { /* number of successive fatal timeouts observed */ - static lsn_t old_lsn = recv_sys.recovered_lsn; + static lsn_t old_lsn = recv_sys.lsn; ut_ad(!srv_read_only_mode); @@ -1839,10 +1808,10 @@ void purge_coordinator_state::refresh(bool full) lsn_hwm= adaptive_purge_threshold + series[n_threads]; } - mysql_mutex_lock(&log_sys.mutex); + log_sys.latch.rd_lock(SRW_LOCK_CALL); const lsn_t last= log_sys.last_checkpoint_lsn, max_age= log_sys.max_checkpoint_age; - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.rd_unlock(); lsn_age_factor= ulint(((log_sys.get_lsn() - last) * 100) / max_age); } diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index e3dfc75ec7e..d8f4adc801f 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -96,7 +96,7 @@ Created 2/16/1996 Heikki Tuuri #include "row0mysql.h" #include "btr0pcur.h" #include "zlib.h" -#include "ut0crc32.h" +#include "log.h" /** We are prepared for a situation that we have this many threads waiting for a transactional lock inside InnoDB. srv_start() sets the value. */ @@ -121,14 +121,15 @@ bool srv_startup_is_before_trx_rollback_phase; bool srv_is_being_started; /** TRUE if the server was successfully started */ bool srv_was_started; -/** The original value of srv_log_file_size (innodb_log_file_size) */ -static ulonglong srv_log_file_size_requested; /** whether srv_start() has been called */ static bool srv_start_has_been_called; /** Whether any undo log records can be generated */ bool srv_undo_sources; +/** innodb_encrypt_log */ +my_bool srv_encrypt_log; + #ifdef UNIV_DEBUG /** InnoDB system tablespace to set during recovery */ uint srv_sys_space_size_debug; @@ -170,160 +171,68 @@ static PSI_stage_info* srv_stages[] = }; #endif /* HAVE_PSI_STAGE_INTERFACE */ -/*********************************************************************//** -Check if a file can be opened in read-write mode. -@return true if it doesn't exist or can be opened in rw mode. */ -static -bool -srv_file_check_mode( -/*================*/ - const char* name) /*!< in: filename to check */ +/** Delete any garbage log files */ +static void delete_log_files() { - os_file_stat_t stat; - - memset(&stat, 0x0, sizeof(stat)); - - dberr_t err = os_file_get_status( - name, &stat, true, srv_read_only_mode); - - if (err == DB_FAIL) { - ib::error() << "os_file_get_status() failed on '" << name - << "'. Can't determine file permissions."; - return(false); - - } else if (err == DB_SUCCESS) { - - /* Note: stat.rw_perm is only valid of files */ - - if (stat.type == OS_FILE_TYPE_FILE) { - - if (!stat.rw_perm) { - const char* mode = srv_read_only_mode - ? "read" : "read-write"; - ib::error() << name << " can't be opened in " - << mode << " mode."; - return(false); - } - } else { - /* Not a regular file, bail out. */ - ib::error() << "'" << name << "' not a regular file."; - - return(false); - } - } else { - - /* This is OK. If the file create fails on RO media, there - is nothing we can do. */ - - ut_a(err == DB_NOT_FOUND); - } - - return(true); + for (size_t i= 1; i < 102; i++) + delete_log_file(std::to_string(i).c_str()); } -/** Initial number of the redo log file */ -static const char INIT_LOG_FILE0[]= "101"; - /** Creates log file. -@param[in] create_new_db whether the database is being initialized -@param[in] lsn FIL_PAGE_FILE_FLUSH_LSN value -@param[out] logfile0 name of the log file +@param create_new_db whether the database is being initialized +@param lsn log sequence number +@param logfile0 name of the log file @return DB_SUCCESS or error code */ -static dberr_t create_log_file(bool create_new_db, lsn_t lsn, - std::string& logfile0) +static dberr_t create_log_file(bool create_new_db, lsn_t lsn) { - if (srv_read_only_mode) { - ib::error() << "Cannot create log file in read-only mode"; - return DB_READ_ONLY; - } + ut_ad(!srv_read_only_mode); - if (!log_set_capacity(srv_log_file_size_requested)) { - return(DB_ERROR); - } - - /* Crashing after deleting the first file should be - recoverable. The buffer pool was clean, and we can simply - create log file from the scratch. */ - DBUG_EXECUTE_IF("innodb_log_abort_6", delete_log_file("0"); - return DB_ERROR;); - - for (size_t i = 0; i < 102; i++) { - delete_log_file(std::to_string(i).c_str()); - } + /* We will retain ib_logfile0 until we have written a new logically + empty log as ib_logfile101 and atomically renamed it to + ib_logfile0 in log_t::rename_resized(). */ + delete_log_files(); - DBUG_PRINT("ib_log", ("After innodb_log_abort_6")); DBUG_ASSERT(!buf_pool.any_io_pending()); - DBUG_EXECUTE_IF("innodb_log_abort_7", return DB_ERROR;); - DBUG_PRINT("ib_log", ("After innodb_log_abort_7")); - - logfile0 = get_log_file_path(LOG_FILE_NAME_PREFIX) - .append(INIT_LOG_FILE0); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + log_sys.set_capacity(); + std::string logfile0{get_log_file_path("ib_logfile101")}; bool ret; - pfs_os_file_t file = os_file_create( - innodb_log_file_key, logfile0.c_str(), - OS_FILE_CREATE|OS_FILE_ON_ERROR_NO_EXIT, OS_FILE_NORMAL, - OS_LOG_FILE, srv_read_only_mode, &ret); + os_file_t file{ + os_file_create_func(logfile0.c_str(), + OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT, + OS_FILE_NORMAL, OS_LOG_FILE, false, &ret) + }; if (!ret) { - ib::error() << "Cannot create " << logfile0; + sql_print_error("InnoDB: Cannot create %.*s", + int(logfile0.size()), logfile0.data()); +err_exit: + log_sys.latch.wr_unlock(); return DB_ERROR; } - ib::info() << "Setting log file " << logfile0 << " size to " - << srv_log_file_size << " bytes"; - ret = os_file_set_size(logfile0.c_str(), file, srv_log_file_size); if (!ret) { - os_file_close(file); + os_file_close_func(file); ib::error() << "Cannot set log file " << logfile0 - << " size to " << srv_log_file_size << " bytes"; - return DB_ERROR; + << " size to " << ib::bytes_iec{srv_log_file_size}; + goto err_exit; } - ret = os_file_close(file); - ut_a(ret); - - DBUG_EXECUTE_IF("innodb_log_abort_8", return(DB_ERROR);); - DBUG_PRINT("ib_log", ("After innodb_log_abort_8")); - - /* We did not create the first log file initially as LOG_FILE_NAME, so - that crash recovery cannot find it until it has been completed and - renamed. */ - - log_sys.log.create(); - - log_sys.log.open_file(logfile0); + log_sys.set_latest_format(srv_encrypt_log); + log_sys.attach(file, srv_log_file_size); if (!fil_system.sys_space->open(create_new_db)) { - return DB_ERROR; + goto err_exit; } /* Create a log checkpoint. */ - mysql_mutex_lock(&log_sys.mutex); if (log_sys.is_encrypted() && !log_crypt_init()) { - return DB_ERROR; + goto err_exit; } ut_d(recv_no_log_write = false); - lsn = ut_uint64_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE); - log_sys.set_lsn(lsn + LOG_BLOCK_HDR_SIZE); - log_sys.log.set_lsn(lsn); - log_sys.log.set_lsn_offset(LOG_FILE_HDR_SIZE); - - log_sys.buf_next_to_write = 0; - log_sys.write_lsn = lsn; - - log_sys.next_checkpoint_no = 0; - log_sys.last_checkpoint_lsn = 0; - - memset(log_sys.buf, 0, srv_log_buffer_size); - log_block_init(log_sys.buf, lsn); - log_block_set_first_rec_group(log_sys.buf, LOG_BLOCK_HDR_SIZE); - memset(log_sys.flush_buf, 0, srv_log_buffer_size); - - log_sys.buf_free = LOG_BLOCK_HDR_SIZE; - - log_sys.log.write_header_durable(lsn); + log_sys.create(lsn); ut_ad(srv_startup_is_before_trx_rollback_phase); if (create_new_db) { @@ -332,7 +241,7 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn, /* Enable checkpoints in buf_flush_page_cleaner(). */ recv_sys.recovery_on = false; - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.wr_unlock(); log_make_checkpoint(); log_buffer_flush_to_disk(); @@ -340,42 +249,29 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn, return DB_SUCCESS; } -/** Rename the first redo log file. -@param[in] lsn FIL_PAGE_FILE_FLUSH_LSN value -@param[in,out] logfile0 name of the first log file -@return error code -@retval DB_SUCCESS on successful operation */ -MY_ATTRIBUTE((warn_unused_result)) -static dberr_t create_log_file_rename(lsn_t lsn, std::string &logfile0) +/** Rename the redo log file after resizing. +@return whether an error occurred */ +bool log_t::rename_resized() noexcept { ut_ad(!srv_log_file_created); ut_d(srv_log_file_created= true); - DBUG_EXECUTE_IF("innodb_log_abort_9", return (DB_ERROR);); - DBUG_PRINT("ib_log", ("After innodb_log_abort_9")); - - /* Rename the first log file, now that a log checkpoint has been created. */ - auto new_name = get_log_file_path(); + std::string old_name{get_log_file_path("ib_logfile101")}; + std::string new_name{get_log_file_path()}; - ib::info() << "Renaming log file " << logfile0 << " to " << new_name; + if (IF_WIN(MoveFileEx(old_name.c_str(), new_name.c_str(), + MOVEFILE_REPLACE_EXISTING), + !rename(old_name.c_str(), new_name.c_str()))) + return false; - mysql_mutex_lock(&log_sys.mutex); - ut_ad(logfile0.size() == 2 + new_name.size()); - logfile0= new_name; - dberr_t err= log_sys.log.rename(std::move(new_name)); - - mysql_mutex_unlock(&log_sys.mutex); - - DBUG_EXECUTE_IF("innodb_log_abort_10", err= DB_ERROR;); - - if (err == DB_SUCCESS) - ib::info() << "New log file created, LSN=" << lsn; - - return err; + sql_print_error("InnoDB: Failed to rename log from %.*s to %.*s", + int(old_name.size()), old_name.data(), + int(new_name.size()), new_name.data()); + return true; } /** Create an undo tablespace file -@param[in] name file name +@param[in] name file name @return DB_SUCCESS or error code */ static dberr_t srv_undo_tablespace_create(const char* name) { @@ -413,7 +309,8 @@ static dberr_t srv_undo_tablespace_create(const char* name) " be created"; ib::info() << "Setting file " << name << " size to " - << (SRV_UNDO_TABLESPACE_SIZE_IN_PAGES >> (20 - srv_page_size_shift)) << " MB"; + << ib::bytes_iec{SRV_UNDO_TABLESPACE_SIZE_IN_PAGES + << srv_page_size_shift}; ib::info() << "Database physically writes the file full: " << "wait..."; @@ -443,8 +340,8 @@ static dberr_t srv_validate_undo_tablespaces() if (srv_undo_tablespaces > srv_undo_tablespaces_open) { ib::error() << "Expected to open innodb_undo_tablespaces=" - << srv_undo_tablespaces - << " but was able to find only " + << srv_undo_tablespaces + << " but was able to find only " << srv_undo_tablespaces_open; return DB_ERROR; @@ -452,11 +349,11 @@ static dberr_t srv_validate_undo_tablespaces() else if (srv_undo_tablespaces_open > 0) { ib::info() << "Opened " << srv_undo_tablespaces_open - << " undo tablespaces"; + << " undo tablespaces"; if (srv_undo_tablespaces == 0) ib::warn() << "innodb_undo_tablespaces=0 disables" - " dedicated undo log tablespaces"; + " dedicated undo log tablespaces"; } return DB_SUCCESS; } @@ -471,8 +368,8 @@ static uint32_t trx_rseg_get_n_undo_tablespaces() if (const buf_block_t *sys_header= trx_sysf_get(&mtr, false)) for (ulint rseg_id= 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) if (trx_sysf_rseg_get_page_no(sys_header, rseg_id) != FIL_NULL) - if (uint32_t space= trx_sysf_rseg_get_space(sys_header, rseg_id)) - space_ids.insert(space); + if (uint32_t space= trx_sysf_rseg_get_space(sys_header, rseg_id)) + space_ids.insert(space); mtr.commit(); return static_cast<uint32_t>(space_ids.size()); } @@ -559,7 +456,7 @@ err_exit: fil_set_max_space_id_if_bigger(space_id); fil_space_t *space= fil_space_t::create(space_id, fsp_flags, - FIL_TYPE_TABLESPACE, NULL); + FIL_TYPE_TABLESPACE, NULL); ut_a(fil_validate()); ut_a(space); @@ -592,7 +489,7 @@ dberr_t srv_check_undo_redo_logs_exists() { bool ret; - pfs_os_file_t fh; + os_file_t fh; char name[OS_FILE_MAX_PATH]; /* Check if any undo tablespaces exist */ @@ -600,8 +497,8 @@ srv_check_undo_redo_logs_exists() snprintf(name, sizeof name, "%s/undo%03zu", srv_undo_dir, i); - fh = os_file_create( - innodb_data_file_key, name, + fh = os_file_create_func( + name, OS_FILE_OPEN_RETRY | OS_FILE_ON_ERROR_NO_EXIT | OS_FILE_ON_ERROR_SILENT, @@ -611,7 +508,7 @@ srv_check_undo_redo_logs_exists() &ret); if (ret) { - os_file_close(fh); + os_file_close_func(fh); ib::error() << "undo tablespace '" << name << "' exists." " Creating system tablespace with existing undo" @@ -625,14 +522,14 @@ srv_check_undo_redo_logs_exists() /* Check if redo log file exists */ auto logfilename = get_log_file_path(); - fh = os_file_create(innodb_log_file_key, logfilename.c_str(), - OS_FILE_OPEN_RETRY | OS_FILE_ON_ERROR_NO_EXIT - | OS_FILE_ON_ERROR_SILENT, - OS_FILE_NORMAL, OS_LOG_FILE, srv_read_only_mode, - &ret); + fh = os_file_create_func(logfilename.c_str(), + OS_FILE_OPEN_RETRY | OS_FILE_ON_ERROR_NO_EXIT + | OS_FILE_ON_ERROR_SILENT, + OS_FILE_NORMAL, OS_LOG_FILE, + srv_read_only_mode, &ret); if (ret) { - os_file_close(fh); + os_file_close_func(fh); ib::error() << "redo log file '" << logfilename << "' exists. Creating system tablespace with" " existing redo log file is not recommended." @@ -645,7 +542,7 @@ srv_check_undo_redo_logs_exists() } static dberr_t srv_all_undo_tablespaces_open(bool create_new_db, - uint32_t n_undo) + uint32_t n_undo) { /* Open all the undo tablespaces that are currently in use. If we fail to open any of these it is a fatal error. The tablespace ids @@ -662,7 +559,7 @@ static dberr_t srv_all_undo_tablespaces_open(bool create_new_db, if (!space_id) { if (!create_new_db) - break; + break; ib::error() << "Unable to open create tablespace '" << name << "'."; return DB_ERROR; } @@ -723,8 +620,8 @@ dberr_t srv_undo_tablespaces_init(bool create_new_db) snprintf(name, sizeof name, "%s/undo%03zu", srv_undo_dir, i + 1); if (dberr_t err= srv_undo_tablespace_create(name)) { - ib::error() << "Could not create undo tablespace '" << name << "'."; - return err; + ib::error() << "Could not create undo tablespace '" << name << "'."; + return err; } } } @@ -736,7 +633,7 @@ dberr_t srv_undo_tablespaces_init(bool create_new_db) srv_undo_tablespaces_active= srv_undo_tablespaces; uint32_t n_undo= (create_new_db || srv_operation == SRV_OPERATION_BACKUP || - srv_operation == SRV_OPERATION_RESTORE_DELTA) + srv_operation == SRV_OPERATION_RESTORE_DELTA) ? srv_undo_tablespaces : TRX_SYS_N_RSEGS; if (dberr_t err= srv_all_undo_tablespaces_open(create_new_db, n_undo)) @@ -779,8 +676,6 @@ srv_open_tmp_tablespace(bool create_new_db) srv_tmp_space.delete_files(); srv_tmp_space.set_ignore_read_only(true); - ib::info() << "Creating shared tablespace for temporary tables"; - bool create_new_temp_space; srv_tmp_space.set_space_id(SRV_TMP_SPACE_ID); @@ -795,7 +690,7 @@ srv_open_tmp_tablespace(bool create_new_db) } else if (err != DB_SUCCESS) { ib::error() << "Could not create the shared innodb_temporary."; } else if ((err = srv_tmp_space.open_or_create( - true, create_new_db, &sum_of_new_sizes, NULL)) + true, create_new_db, &sum_of_new_sizes)) != DB_SUCCESS) { ib::error() << "Unable to create the shared innodb_temporary"; } else if (fil_system.temp_space->open(true)) { @@ -887,7 +782,7 @@ srv_init_abort_low( " with error " << err << ". You may need" " to delete the ibdata1 file before trying to start" " up again."; - } else { + } else if (srv_operation == SRV_OPERATION_NORMAL) { ib::error() << "Plugin initialization aborted" #ifdef UNIV_DEBUG " at " << innobase_basename(file) << "[" << line << "]" @@ -902,9 +797,8 @@ srv_init_abort_low( /** Prepare to delete the redo log file. Flush the dirty pages from all the buffer pools. Flush the redo log buffer to the redo log file. -@param[in] old_exists old redo log file exists @return lsn upto which data pages have been flushed. */ -static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists) +static lsn_t srv_prepare_to_delete_redo_log_file() { DBUG_ENTER("srv_prepare_to_delete_redo_log_file"); @@ -915,33 +809,33 @@ static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists) /* Clean the buffer pool. */ buf_flush_sync(); - if (log_sys.log.subformat != 2) - srv_log_file_size= 0; - DBUG_EXECUTE_IF("innodb_log_abort_1", DBUG_RETURN(0);); DBUG_PRINT("ib_log", ("After innodb_log_abort_1")); - mysql_mutex_lock(&log_sys.mutex); - const bool latest_format= (log_sys.log.format & ~log_t::FORMAT_ENCRYPTED) == - log_t::FORMAT_10_5; - lsn_t flushed_lsn= log_sys.get_lsn(); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + const bool latest_format{log_sys.is_latest()}; + lsn_t flushed_lsn{log_sys.get_lsn()}; - if (latest_format) + if (latest_format && !(log_sys.file_size & 4095) && + flushed_lsn != log_sys.next_checkpoint_lsn + + (log_sys.is_encrypted() + ? SIZE_OF_FILE_CHECKPOINT + 8 + : SIZE_OF_FILE_CHECKPOINT)) { - fil_names_clear(flushed_lsn, false); + fil_names_clear(flushed_lsn); flushed_lsn= log_sys.get_lsn(); } { const char *msg; - if (!latest_format || srv_log_file_size == 0) + if (!latest_format) { msg= "Upgrading redo log: "; same_size: - ib::info() << msg << srv_log_file_size_requested << " bytes; LSN=" - << flushed_lsn; + ib::info() << msg << ib::bytes_iec(srv_log_file_size) + << "; LSN=" << flushed_lsn; } - else if (old_exists && srv_log_file_size == srv_log_file_size_requested) + else if (srv_log_file_size == log_sys.file_size) { msg= srv_encrypt_log ? "Encrypting redo log: " : "Removing redo log encryption: "; @@ -956,19 +850,16 @@ same_size: ? "Encrypting and resizing" : "Removing encryption and resizing"; - ib::info() << msg << " redo log from " << srv_log_file_size << " to " - << srv_log_file_size_requested - << " bytes; LSN=" << flushed_lsn; + ib::info() << msg << " redo log from " + << ib::bytes_iec{log_sys.file_size} << " to " + << ib::bytes_iec{srv_log_file_size} + << "; LSN=" << flushed_lsn; } } - mysql_mutex_unlock(&log_sys.mutex); + log_sys.latch.wr_unlock(); - if (flushed_lsn != log_sys.get_flushed_lsn()) - { - log_write_up_to(flushed_lsn, false); - log_sys.log.flush(); - } + log_write_up_to(flushed_lsn, false); ut_ad(flushed_lsn == log_sys.get_lsn()); ut_ad(!buf_pool.any_io_pending()); @@ -976,88 +867,17 @@ same_size: DBUG_RETURN(flushed_lsn); } -/** Tries to locate LOG_FILE_NAME and check it's size, etc -@param[out] log_file_found returns true here if correct file was found -@return dberr_t with DB_SUCCESS or some error */ -static dberr_t find_and_check_log_file(bool &log_file_found) -{ - log_file_found= false; - - auto logfile0= get_log_file_path(); - os_file_stat_t stat_info; - const dberr_t err= os_file_get_status(logfile0.c_str(), &stat_info, false, - srv_read_only_mode); - - auto is_operation_restore= []() -> bool { - return srv_operation == SRV_OPERATION_RESTORE || - srv_operation == SRV_OPERATION_RESTORE_EXPORT; - }; - - if (err == DB_NOT_FOUND) - { - if (is_operation_restore()) - return DB_NOT_FOUND; - - /* This might be first start after mariabackup - copy-back or move-back. */ - srv_start_after_restore= true; - return DB_SUCCESS; - } - - if (stat_info.type != OS_FILE_TYPE_FILE) - return DB_SUCCESS; - - if (!srv_file_check_mode(logfile0.c_str())) - return DB_ERROR; - - const os_offset_t size= stat_info.size; - ut_a(size != (os_offset_t) -1); - - if (size % OS_FILE_LOG_BLOCK_SIZE) - { - ib::error() << "Log file " << logfile0 << " size " << size - << " is not a multiple of " << OS_FILE_LOG_BLOCK_SIZE - << " bytes"; - return DB_ERROR; - } - - if (size == 0 && is_operation_restore()) - { - /* Tolerate an empty LOG_FILE_NAME from a previous run of - mariabackup --prepare. */ - return DB_NOT_FOUND; - } - /* The first log file must consist of at least the following 512-byte pages: - header, checkpoint page 1, empty, checkpoint page 2, redo log page(s). - - Mariabackup --prepare would create an empty LOG_FILE_NAME. Tolerate it. */ - if (size == 0) - srv_start_after_restore= true; - else if (size <= OS_FILE_LOG_BLOCK_SIZE * 4) - { - ib::error() << "Log file " << logfile0 << " size " << size - << " is too small"; - return DB_ERROR; - } - srv_log_file_size= size; - - log_file_found= true; - return DB_SUCCESS; -} - static tpool::task_group rollback_all_recovered_group(1); static tpool::task rollback_all_recovered_task(trx_rollback_all_recovered, - nullptr, - &rollback_all_recovered_group); + nullptr, + &rollback_all_recovered_group); /** Start InnoDB. @param[in] create_new_db whether to create a new database @return DB_SUCCESS or error code */ dberr_t srv_start(bool create_new_db) { - lsn_t flushed_lsn; dberr_t err = DB_SUCCESS; - bool srv_log_file_found = true; mtr_t mtr; ut_ad(srv_operation == SRV_OPERATION_NORMAL @@ -1216,8 +1036,8 @@ dberr_t srv_start(bool create_new_db) fil_system.create(srv_file_per_table ? 50000 : 5000); ib::info() << "Initializing buffer pool, total size = " - << srv_buf_pool_size - << ", chunk size = " << srv_buf_pool_chunk_unit; + << ib::bytes_iec{srv_buf_pool_size} + << ", chunk size = " << ib::bytes_iec{srv_buf_pool_chunk_unit}; if (buf_pool.create()) { ib::error() << "Cannot allocate memory for the buffer pool"; @@ -1234,8 +1054,8 @@ dberr_t srv_start(bool create_new_db) if (srv_buf_pool_size <= 5 * 1024 * 1024) { ib::info() << "Small buffer pool size (" - << srv_buf_pool_size / 1024 / 1024 - << "M), the flst_validate() debug function can cause a" + << ib::bytes_iec{srv_buf_pool_size} + << "), the flst_validate() debug function can cause a" << " deadlock if the buffer pool fills up."; } #endif /* UNIV_DEBUG */ @@ -1265,7 +1085,7 @@ dberr_t srv_start(bool create_new_db) ulint sum_of_new_sizes; err = srv_sys_space.open_or_create( - false, create_new_db, &sum_of_new_sizes, &flushed_lsn); + false, create_new_db, &sum_of_new_sizes); switch (err) { case DB_SUCCESS: @@ -1287,87 +1107,26 @@ dberr_t srv_start(bool create_new_db) return(srv_init_abort(err)); } - srv_log_file_size_requested = srv_log_file_size; - if (innodb_encrypt_temporary_tables && !log_crypt_init()) { return srv_init_abort(DB_ERROR); } - std::string logfile0; - bool create_new_log = create_new_db; if (create_new_db) { - flushed_lsn = log_sys.get_lsn(); - log_sys.set_flushed_lsn(flushed_lsn); + lsn_t flushed_lsn = log_sys.init_lsn(); - err = create_log_file(true, flushed_lsn, logfile0); + err = create_log_file(true, flushed_lsn); if (err != DB_SUCCESS) { - for (Tablespace::const_iterator - i = srv_sys_space.begin(); - i != srv_sys_space.end(); i++) { + for (const Datafile &file: srv_sys_space) { os_file_delete(innodb_data_file_key, - i->filepath()); - } - return(srv_init_abort(err)); - } - } else { - srv_log_file_size = 0; - - bool log_file_found; - if (dberr_t err = find_and_check_log_file(log_file_found)) { - if (err == DB_NOT_FOUND) { - return DB_SUCCESS; + file.filepath()); } return srv_init_abort(err); } - - create_new_log = srv_log_file_size == 0; - if (create_new_log) { - if (flushed_lsn < lsn_t(1000)) { - ib::error() - << "Cannot create log file because" - " data files are corrupt or the" - " database was not shut down cleanly" - " after creating the data files."; - return srv_init_abort(DB_ERROR); - } - - srv_log_file_size = srv_log_file_size_requested; - - err = create_log_file(false, flushed_lsn, logfile0); - - if (err == DB_SUCCESS) { - err = create_log_file_rename(flushed_lsn, - logfile0); - } - - if (err != DB_SUCCESS) { - return(srv_init_abort(err)); - } - - /* Suppress the message about - crash recovery. */ - flushed_lsn = log_sys.get_lsn(); - goto file_checked; - } - - srv_log_file_found = log_file_found; - - log_sys.log.open_file(get_log_file_path()); - - log_sys.log.create(); - - if (!log_set_capacity(srv_log_file_size_requested)) { - return(srv_init_abort(DB_ERROR)); - } - - /* Enable checkpoints in the page cleaner. */ - recv_sys.recovery_on = false; } -file_checked: /* Open log file and data files in the systemtablespace: we keep - them open until database shutdown */ + them open until database shutdown */ ut_d(fil_system.sys_space->recv_size = srv_sys_space_size_debug); err = fil_system.sys_space->open(create_new_db) @@ -1432,16 +1191,8 @@ file_checked: buf_flush_sync(); - flushed_lsn = log_sys.get_lsn(); - - err = fil_write_flushed_lsn(flushed_lsn); - - if (err == DB_SUCCESS) { - err = create_log_file_rename(flushed_lsn, logfile0); - } - - if (err != DB_SUCCESS) { - return(srv_init_abort(err)); + if (log_sys.rename_resized()) { + return(srv_init_abort(DB_ERROR)); } } else { /* Suppress warnings in fil_space_t::create() for files @@ -1452,9 +1203,7 @@ file_checked: /* We always try to do a recovery, even if the database had been shut down normally: this is the normal startup path */ - err = create_new_log - ? DB_SUCCESS - : recv_recovery_from_checkpoint_start(flushed_lsn); + err = recv_recovery_from_checkpoint_start(); recv_sys.close_files(); recv_sys.dblwr.pages.clear(); @@ -1499,7 +1248,9 @@ file_checked: respective file pages, for the last batch of recv_group_scan_log_recs(). */ + mysql_mutex_lock(&recv_sys.mutex); recv_sys.apply(true); + mysql_mutex_unlock(&recv_sys.mutex); if (recv_sys.is_corrupt_log() || recv_sys.is_corrupt_fs()) { @@ -1602,29 +1353,9 @@ file_checked: recv_sys.debug_free(); - if (srv_operation == SRV_OPERATION_RESTORE - || srv_operation == SRV_OPERATION_RESTORE_EXPORT) { - /* After applying the redo log from - SRV_OPERATION_BACKUP, flush the changes - to the data files and truncate or delete the log. - Unless --export is specified, no further change to - InnoDB files is needed. */ - ut_ad(srv_force_recovery <= SRV_FORCE_IGNORE_CORRUPT); - ut_ad(recv_no_log_write); - err = fil_write_flushed_lsn(log_sys.get_lsn()); - DBUG_ASSERT(!buf_pool.any_io_pending()); - log_sys.log.close_file(); - if (err == DB_SUCCESS) { - bool trunc = srv_operation - == SRV_OPERATION_RESTORE; - if (!trunc) { - delete_log_file("0"); - } else { - auto logfile0 = get_log_file_path(); - /* Truncate the first log file. */ - fclose(fopen(logfile0.c_str(), "w")); - } - } + if (srv_operation != SRV_OPERATION_NORMAL) { + ut_ad(srv_operation == SRV_OPERATION_RESTORE_EXPORT + || srv_operation == SRV_OPERATION_RESTORE); return(err); } @@ -1636,19 +1367,17 @@ file_checked: /* Completely ignore the redo log. */ } else if (srv_read_only_mode) { /* Leave the redo log alone. */ - } else if (srv_log_file_size_requested == srv_log_file_size - && srv_log_file_found - && log_sys.log.format + } else if (log_sys.file_size == srv_log_file_size + && log_sys.format == (srv_encrypt_log - ? log_t::FORMAT_ENC_10_5 - : log_t::FORMAT_10_5) - && log_sys.log.subformat == 2) { + ? log_t::FORMAT_ENC_10_8 + : log_t::FORMAT_10_8)) { /* No need to add or remove encryption, - upgrade, downgrade, or resize. */ + upgrade, or resize. */ + delete_log_files(); } else { /* Prepare to delete the old redo log file */ - flushed_lsn = srv_prepare_to_delete_redo_log_file( - srv_log_file_found); + const lsn_t lsn{srv_prepare_to_delete_redo_log_file()}; DBUG_EXECUTE_IF("innodb_log_abort_1", return(srv_init_abort(DB_ERROR));); @@ -1658,37 +1387,17 @@ file_checked: ut_d(recv_no_log_write = true); DBUG_ASSERT(!buf_pool.any_io_pending()); - DBUG_EXECUTE_IF("innodb_log_abort_3", - return(srv_init_abort(DB_ERROR));); - DBUG_PRINT("ib_log", ("After innodb_log_abort_3")); - - /* Stamp the LSN to the data files. */ - err = fil_write_flushed_lsn(flushed_lsn); - - DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;); - DBUG_PRINT("ib_log", ("After innodb_log_abort_4")); - - if (err != DB_SUCCESS) { - return(srv_init_abort(err)); - } - /* Close the redo log file, so that we can replace it */ - log_sys.log.close_file(); + log_sys.close_file(); DBUG_EXECUTE_IF("innodb_log_abort_5", return(srv_init_abort(DB_ERROR));); DBUG_PRINT("ib_log", ("After innodb_log_abort_5")); - ib::info() - << "Starting to delete and rewrite log file."; - - srv_log_file_size = srv_log_file_size_requested; - - err = create_log_file(false, flushed_lsn, logfile0); + err = create_log_file(false, lsn); - if (err == DB_SUCCESS) { - err = create_log_file_rename(flushed_lsn, - logfile0); + if (err == DB_SUCCESS && log_sys.rename_resized()) { + err = DB_ERROR; } if (err != DB_SUCCESS) { @@ -1876,10 +1585,18 @@ skip_monitors: srv_is_being_started = false; if (srv_print_verbose_log) { - ib::info() << INNODB_VERSION_STR - << " started; log sequence number " - << recv_sys.recovered_lsn - << "; transaction id " << trx_sys.get_max_trx_id(); + sql_print_information("InnoDB: " + "log sequence number " LSN_PF +#ifdef HAVE_PMEM + "%s" +#endif + "; transaction id " TRX_ID_FMT, + recv_sys.lsn, +#ifdef HAVE_PMEM + log_sys.is_pmem() + ? " (memory-mapped)" : "", +#endif + trx_sys.get_max_trx_id()); } if (srv_force_recovery == 0) { diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index b7d41b23825..56bdac29694 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1152,29 +1152,20 @@ static void trx_flush_log_if_needed_low(lsn_t lsn, const trx_t *trx) if (!srv_flush_log_at_trx_commit) return; - if (log_sys.get_flushed_lsn() > lsn) + if (log_sys.get_flushed_lsn(std::memory_order_relaxed) >= lsn) return; - const bool flush= srv_file_flush_method != SRV_NOSYNC && - (srv_flush_log_at_trx_commit & 1); + completion_callback cb, *callback= nullptr; - if (trx->state == TRX_STATE_PREPARED) + if (trx->state != TRX_STATE_PREPARED && !log_sys.is_pmem() && + (cb.m_param= thd_increment_pending_ops(trx->mysql_thd))) { - /* XA, which is used with binlog as well. - Be conservative, use synchronous wait.*/ -sync: - log_write_up_to(lsn, flush); - return; + cb.m_callback= (void (*)(void *)) thd_decrement_pending_ops; + callback= &cb; } - completion_callback cb; - if ((cb.m_param = thd_increment_pending_ops(trx->mysql_thd))) - { - cb.m_callback = (void (*)(void *)) thd_decrement_pending_ops; - log_write_up_to(lsn, flush, false, &cb); - } - else - goto sync; + log_write_up_to(lsn, srv_file_flush_method != SRV_NOSYNC && + (srv_flush_log_at_trx_commit & 1), callback); } /**********************************************************************//** diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 545c54fde66..7b69042c0a5 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -474,6 +474,18 @@ ut_strerr( namespace ib { +std::ostream &operator<<(std::ostream &lhs, const bytes_iec &rhs) +{ + static const char *sizes[]= {"B", "KiB", "MiB", "GiB", "TiB", "PiB", + "EiB", "ZiB", "YiB"}; + size_t i= 0; + double d= rhs.get_double(); + for (; d > 512.0 && i < array_elements(sizes); i++, d/= 1024.0); + lhs.precision(3); + lhs << std::fixed << d << sizes[i]; + return lhs; +} + ATTRIBUTE_COLD logger& logger::operator<<(dberr_t err) { m_oss << ut_strerr(err); diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 1e6680d30de..abe7834f36d 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -3349,6 +3349,7 @@ void ha_maria::get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nr; int error; uchar key[MARIA_MAX_KEY_BUFF]; + enum ha_rkey_function search_flag= HA_READ_PREFIX_LAST; if (!table->s->next_number_key_offset) { // Autoincrement at key-start @@ -3362,13 +3363,18 @@ void ha_maria::get_auto_increment(ulonglong offset, ulonglong increment, /* it's safe to call the following if bulk_insert isn't on */ maria_flush_bulk_insert(file, table->s->next_number_index); + if (unlikely(table->key_info[table->s->next_number_index]. + key_part[table->s->next_number_keypart].key_part_flag & + HA_REVERSE_SORT)) + search_flag= HA_READ_KEY_EXACT; + (void) extra(HA_EXTRA_KEYREAD); key_copy(key, table->record[0], table->key_info + table->s->next_number_index, table->s->next_number_key_offset); error= maria_rkey(file, table->record[1], (int) table->s->next_number_index, key, make_prev_keypart_map(table->s->next_number_keypart), - HA_READ_PREFIX_LAST); + search_flag); if (error) nr= 1; else diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c index 63c11632969..e6f8b6bc887 100644 --- a/storage/maria/ma_search.c +++ b/storage/maria/ma_search.c @@ -452,6 +452,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, MARIA_KEYDEF *keyinfo= key->keyinfo; MARIA_SHARE *share= keyinfo->share; const uchar *sort_order= keyinfo->seg->charset->sort_order; + const int reverse = keyinfo->seg->flag & HA_REVERSE_SORT; DBUG_ENTER("_ma_prefix_search"); t_buff[0]=0; /* Avoid bugs */ @@ -585,7 +586,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, /* If prefix_len > cmplen then we are in the end-space comparison - phase. Do not try to acces the key any more ==> left= 0. + phase. Do not try to access the key any more ==> left= 0. */ left= ((len <= cmplen) ? suffix_len : ((prefix_len < cmplen) ? cmplen - prefix_len : 0)); @@ -605,8 +606,6 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, break; } - if (my_flag>0) /* mismatch */ - break; if (my_flag==0) /* match */ { /* @@ -632,12 +631,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, for ( ; k < k_end && *k == ' '; k++) ; if (k == k_end) goto cmp_rest; /* should never happen */ - if ((uchar) *k < (uchar) ' ') - { - my_flag= 1; /* Compared string is smaller */ - break; - } - my_flag= -1; /* Continue searching */ + my_flag= (uchar)' ' - *k; } } else if (len > cmplen) @@ -651,13 +645,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, vseg < vseg_end && *vseg == (uchar) ' '; vseg++, matched++) ; DBUG_ASSERT(vseg < vseg_end); - - if ((uchar) *vseg > (uchar) ' ') - { - my_flag= 1; /* Compared string is smaller */ - break; - } - my_flag= -1; /* Continue searching */ + my_flag= *vseg - (uchar)' '; } else { @@ -685,6 +673,8 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, } } } + if ((reverse ? -my_flag : my_flag) > 0) /* mismatch */ + break; matched-=left; } /* else (matched < prefix_len) ---> do nothing. */ @@ -696,7 +686,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, *ret_pos=page; } if (my_flag) - flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag; + flag= reverse ? -my_flag : my_flag; if (flag == 0) { memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len); @@ -2055,7 +2045,7 @@ _ma_calc_var_pack_key_length(const MARIA_KEY *int_key, uint nod_flag, DBUG_PRINT("test",("tot_length: %u length: %d uniq_key_length: %u", key_length, length, s_temp->key_length)); - /* If something after that hasn't length=0, test if we can combine */ + /* If something after that hasn't length=0, test if we can combine */ if ((s_temp->next_key_pos=next_key)) { uint packed,n_length; @@ -2068,7 +2058,7 @@ _ma_calc_var_pack_key_length(const MARIA_KEY *int_key, uint nod_flag, } else n_length= *next_key++ & 127; - if (!packed) + if (!packed && n_length) n_length-= s_temp->store_not_null; if (n_length || packed) /* Don't pack 0 length keys */ @@ -2368,7 +2358,7 @@ void _ma_store_var_pack_key(MARIA_KEYDEF *keyinfo __attribute__((unused)), store_key_length_inc(key_pos,s_temp->n_length); } } - else + else if (s_temp->n_length) { s_temp->n_length+= s_temp->store_not_null; store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_length); diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index f7cb81fee66..7787f8b83b5 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -3844,6 +3844,14 @@ int ha_mroonga::storage_create_validate_index(TABLE *table) KEY *key_info = &(table->s->key_info[i]); // must be single column key int key_parts = KEY_N_KEY_PARTS(key_info); + for (int j = 0; j < key_parts; j++) { + if (key_info->key_part[j].key_part_flag & HA_REVERSE_SORT) { + GRN_LOG(ctx, GRN_LOG_ERROR, "DESC indexes are not supported"); + error = ER_CANT_CREATE_TABLE; + my_message(error, "DESC indexes are not supported", MYF(0)); + DBUG_RETURN(error); + } + } if (key_parts != 1) { continue; } diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_desc.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_desc.result new file mode 100644 index 00000000000..350ad0a3eeb --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_desc.result @@ -0,0 +1,9 @@ +# +# MDEV-27408 DESC index on a Mroonga table causes wrong order of result set +# +create table t1 (a int, key(a desc)); +ERROR HY000: DESC indexes are not supported +show warnings; +Level Code Message +Error 1005 DESC indexes are not supported +Warning 1030 Got error 1005 "Unknown error 1005" from storage engine Mroonga diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_desc.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_desc.test new file mode 100644 index 00000000000..388497bb0c3 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_desc.test @@ -0,0 +1,15 @@ +--source ../../include/mroonga/have_mroonga.inc + +--echo # +--echo # MDEV-27408 DESC index on a Mroonga table causes wrong order of result set +--echo # + +--error ER_CANT_CREATE_TABLE +create table t1 (a int, key(a desc)); +show warnings; +#show create table t1; +#insert into t1 values (1),(3),(2); +#select * from t1 order by a; +#drop table t1; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 2c5d106816e..a1de9edd997 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -577,7 +577,8 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, t1_keysegs_j__type != t2_keysegs[j].type || t1_keysegs[j].null_bit != t2_keysegs[j].null_bit || t1_keysegs[j].length != t2_keysegs[j].length || - t1_keysegs[j].start != t2_keysegs[j].start) + t1_keysegs[j].start != t2_keysegs[j].start || + (t1_keysegs[j].flag ^ t2_keysegs[j].flag) & HA_REVERSE_SORT) { DBUG_PRINT("error", ("Key segment %d (key %d) has different " "definition", j, i)); @@ -2343,6 +2344,7 @@ void ha_myisam::get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nr; int error; uchar key[HA_MAX_KEY_LENGTH]; + enum ha_rkey_function search_flag= HA_READ_PREFIX_LAST; if (!table->s->next_number_key_offset) { // Autoincrement at key-start @@ -2356,13 +2358,18 @@ void ha_myisam::get_auto_increment(ulonglong offset, ulonglong increment, /* it's safe to call the following if bulk_insert isn't on */ mi_flush_bulk_insert(file, table->s->next_number_index); + if (unlikely(table->key_info[table->s->next_number_index]. + key_part[table->s->next_number_keypart].key_part_flag & + HA_REVERSE_SORT)) + search_flag= HA_READ_KEY_EXACT; + (void) extra(HA_EXTRA_KEYREAD); key_copy(key, table->record[0], table->key_info + table->s->next_number_index, table->s->next_number_key_offset); error= mi_rkey(file, table->record[1], (int) table->s->next_number_index, key, make_prev_keypart_map(table->s->next_number_keypart), - HA_READ_PREFIX_LAST); + search_flag); if (error) nr= 1; else diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index 14286e3591d..dbad6aa7a77 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -309,6 +309,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, uchar *UNINIT_VAR(saved_vseg); uint saved_length=0, saved_prefix_len=0; uint length_pack; + const int reverse = keyinfo->seg->flag & HA_REVERSE_SORT; DBUG_ENTER("_mi_prefix_search"); t_buff[0]=0; /* Avoid bugs */ @@ -452,8 +453,6 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, break; } - if (my_flag>0) /* mismatch */ - break; if (my_flag==0) /* match */ { /* @@ -478,12 +477,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, for ( ; k < k_end && *k == ' '; k++) ; if (k == k_end) goto cmp_rest; /* should never happen */ - if (*k < (uchar) ' ') - { - my_flag= 1; /* Compared string is smaller */ - break; - } - my_flag= -1; /* Continue searching */ + my_flag= (uchar)' ' - *k; } } else if (len > cmplen) @@ -498,12 +492,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, vseg++, matched++) ; DBUG_ASSERT(vseg < vseg_end); - if (*vseg > (uchar) ' ') - { - my_flag= 1; /* Compared string is smaller */ - break; - } - my_flag= -1; /* Continue searching */ + my_flag= *vseg - (uchar)' '; } else { @@ -530,6 +519,8 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, } } } + if ((reverse ? -my_flag : my_flag) > 0) /* mismatch */ + break; matched-=left; } /* else (matched < prefix_len) ---> do nothing. */ @@ -541,7 +532,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, *ret_pos=page; } if (my_flag) - flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag; + flag= reverse ? -my_flag : my_flag; if (flag == 0) { memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len); @@ -1608,7 +1599,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, } else n_length= *next_key++ & 127; - if (!packed) + if (!packed && n_length) n_length-= s_temp->store_not_null; if (n_length || packed) /* Don't pack 0 length keys */ @@ -1897,7 +1888,7 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)), return; /* Identical key */ store_key_length(key_pos,s_temp->n_length); } - else + else if (s_temp->n_length) { s_temp->n_length+= s_temp->store_not_null; store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_length); diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 1168427a458..fa9feb2c43b 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -7580,8 +7580,7 @@ int ha_rocksdb::create_key_def(const TABLE *const table_arg, const uint i, (*new_key_def)->m_ttl_column = ttl_column; } // initialize key_def - (*new_key_def)->setup(table_arg, tbl_def_arg); - DBUG_RETURN(HA_EXIT_SUCCESS); + DBUG_RETURN((*new_key_def)->setup(table_arg, tbl_def_arg)); } int rdb_normalize_tablename(const std::string &tablename, diff --git a/storage/rocksdb/mysql-test/rocksdb/r/index_key_block_size.result b/storage/rocksdb/mysql-test/rocksdb/r/index_key_block_size.result index 4695d94b3fe..c74ce6878c7 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/index_key_block_size.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/index_key_block_size.result @@ -23,6 +23,11 @@ CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY ind2(b(1) DESC) KEY_BLOCK_SIZE=32768 COMMENT 'big key_block_size value' ) ENGINE=rocksdb; +ERROR HY000: Table storage engine 'ROCKSDB' does not support the create option 'DESC' +CREATE TABLE t1 (a INT, +b CHAR(8), +PRIMARY KEY ind2(b(1)) KEY_BLOCK_SIZE=32768 COMMENT 'big key_block_size value' +) ENGINE=rocksdb; Warnings: Warning 1280 Name 'ind2' ignored for PRIMARY key. SHOW INDEX IN t1; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result index 1b3b43c0304..45c87cc7313 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result @@ -136,9 +136,6 @@ os_data_fsyncs os 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status os_pending_reads os 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of reads pending os_pending_writes os 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of writes pending os_log_bytes_written os 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Bytes of log written (innodb_os_log_written) -os_log_fsyncs os 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of fsync log writes (innodb_os_log_fsyncs) -os_log_pending_fsyncs os 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of pending fsync write (innodb_os_log_pending_fsyncs) -os_log_pending_writes os 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of pending log file writes (innodb_os_log_pending_writes) trx_rw_commits transaction 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of read-write transactions committed trx_ro_commits transaction 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of read-only transactions committed trx_nl_ro_commits transaction 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of non-locking auto-commit read-only transactions committed @@ -156,20 +153,16 @@ purge_undo_log_pages purge 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL purge_dml_delay_usec purge 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Microseconds DML to be delayed due to purge lagging purge_stop_count purge 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of times purge was stopped purge_resume_count purge 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of times purge was resumed -log_checkpoints recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of checkpoints +log_checkpoints recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of checkpoints log_lsn_last_flush recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value LSN of Last flush log_lsn_last_checkpoint recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value LSN at last checkpoint log_lsn_current recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Current LSN value log_lsn_checkpoint_age recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Current LSN value minus LSN at last checkpoint log_lsn_buf_pool_oldest recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value The oldest modified block LSN in the buffer pool log_max_modified_age_async recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Maximum LSN difference; when exceeded, start asynchronous preflush -log_pending_log_flushes recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Pending log flushes -log_pending_checkpoint_writes recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Pending checkpoints -log_num_log_io recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of log I/Os log_waits recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of log waits due to small log buffer (innodb_log_waits) log_write_requests recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of log write requests (innodb_log_write_requests) log_writes recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of log writes (innodb_log_writes) -log_padded recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Bytes of log padded for log write ahead compress_pages_compressed compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages compressed compress_pages_decompressed compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages decompressed compression_pad_increments compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times padding is incremented to avoid compression failures diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result index 101e159eaf3..f9e3129c73f 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result @@ -47,18 +47,22 @@ EXPLAIN { "query_block": { "select_id": 1, - "table": { - "table_name": "t3", - "access_type": "range", - "possible_keys": ["kp1"], - "key": "kp1", - "key_length": "5", - "used_key_parts": ["kp1"], - "rows": 1000, - "filtered": 100, - "index_condition": "t3.kp1 between 2 and 4 and t3.kp1 MOD 3 = 0", - "attached_condition": "t3.kp2 like '%foo%'" - } + "nested_loop": [ + { + "table": { + "table_name": "t3", + "access_type": "range", + "possible_keys": ["kp1"], + "key": "kp1", + "key_length": "5", + "used_key_parts": ["kp1"], + "rows": 1000, + "filtered": 100, + "index_condition": "t3.kp1 between 2 and 4 and t3.kp1 MOD 3 = 0", + "attached_condition": "t3.kp2 like '%foo%'" + } + } + ] } } # Check that we handle the case where out-of-range is encountered sooner diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result index b00e0e14e46..3634f8c023e 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result @@ -47,18 +47,22 @@ EXPLAIN { "query_block": { "select_id": 1, - "table": { - "table_name": "t3", - "access_type": "range", - "possible_keys": ["kp1"], - "key": "kp1", - "key_length": "5", - "used_key_parts": ["kp1"], - "rows": 1000, - "filtered": 100, - "index_condition": "t3.kp1 between 2 and 4 and t3.kp1 MOD 3 = 0", - "attached_condition": "t3.kp2 like '%foo%'" - } + "nested_loop": [ + { + "table": { + "table_name": "t3", + "access_type": "range", + "possible_keys": ["kp1"], + "key": "kp1", + "key_length": "5", + "used_key_parts": ["kp1"], + "rows": 1000, + "filtered": 100, + "index_condition": "t3.kp1 between 2 and 4 and t3.kp1 MOD 3 = 0", + "attached_condition": "t3.kp2 like '%foo%'" + } + } + ] } } # Check that we handle the case where out-of-range is encountered sooner diff --git a/storage/rocksdb/mysql-test/rocksdb/t/index_key_block_size.test b/storage/rocksdb/mysql-test/rocksdb/t/index_key_block_size.test index f156aec0021..4edf684383a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/index_key_block_size.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/index_key_block_size.test @@ -28,11 +28,17 @@ CREATE TABLE t1 (a INT, SHOW INDEX IN t1; DROP TABLE t1; +--error ER_ILLEGAL_HA_CREATE_OPTION CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY ind2(b(1) DESC) KEY_BLOCK_SIZE=32768 COMMENT 'big key_block_size value' ) ENGINE=rocksdb; +CREATE TABLE t1 (a INT, + b CHAR(8), + PRIMARY KEY ind2(b(1)) KEY_BLOCK_SIZE=32768 COMMENT 'big key_block_size value' +) ENGINE=rocksdb; + --replace_column 7 # SHOW INDEX IN t1; diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index 9e7983dc634..9afc2100069 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -390,7 +390,7 @@ Rdb_key_def::~Rdb_key_def() { m_pack_info = nullptr; } -void Rdb_key_def::setup(const TABLE *const tbl, +uint Rdb_key_def::setup(const TABLE *const tbl, const Rdb_tbl_def *const tbl_def) { DBUG_ASSERT(tbl != nullptr); DBUG_ASSERT(tbl_def != nullptr); @@ -406,7 +406,7 @@ void Rdb_key_def::setup(const TABLE *const tbl, RDB_MUTEX_LOCK_CHECK(m_mutex); if (m_maxlength != 0) { RDB_MUTEX_UNLOCK_CHECK(m_mutex); - return; + return HA_EXIT_SUCCESS; } KEY *key_info = nullptr; @@ -488,6 +488,14 @@ void Rdb_key_def::setup(const TABLE *const tbl, for (uint src_i = 0; src_i < m_key_parts; src_i++, keypart_to_set++) { Field *const field = key_part ? key_part->field : nullptr; + if (key_part && key_part->key_part_flag & HA_REVERSE_SORT) + { + my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0), + "ROCKSDB", "DESC"); + RDB_MUTEX_UNLOCK_CHECK(m_mutex); + return HA_EXIT_FAILURE; + } + if (simulating_extkey && !hidden_pk_exists) { DBUG_ASSERT(secondary_key); /* Check if this field is already present in the key definition */ @@ -591,6 +599,7 @@ void Rdb_key_def::setup(const TABLE *const tbl, RDB_MUTEX_UNLOCK_CHECK(m_mutex); } + return HA_EXIT_SUCCESS; } /* diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h index fb368a17fba..899c6f70071 100644 --- a/storage/rocksdb/rdb_datadic.h +++ b/storage/rocksdb/rdb_datadic.h @@ -593,7 +593,7 @@ class Rdb_key_def { SECONDARY_FORMAT_VERSION_UPDATE3 = 65535, }; - void setup(const TABLE *const table, const Rdb_tbl_def *const tbl_def); + uint setup(const TABLE *const table, const Rdb_tbl_def *const tbl_def); static uint extract_ttl_duration(const TABLE *const table_arg, const Rdb_tbl_def *const tbl_def_arg, diff --git a/storage/spider/CMakeLists.txt b/storage/spider/CMakeLists.txt index 898421fa532..bc682e96609 100644 --- a/storage/spider/CMakeLists.txt +++ b/storage/spider/CMakeLists.txt @@ -17,10 +17,7 @@ SET(SPIDER_SOURCES spd_param.cc spd_sys_table.cc spd_trx.cc spd_db_conn.cc spd_conn.cc spd_table.cc spd_direct_sql.cc spd_udf.cc spd_ping_table.cc spd_copy_tables.cc spd_i_s.cc spd_malloc.cc ha_spider.cc spd_udf.def - spd_db_mysql.cc spd_db_handlersocket.cc spd_db_oracle.cc - spd_group_by_handler.cc spd_db_include.cc - hs_client/config.cpp hs_client/escape.cpp hs_client/fatal.cpp - hs_client/hstcpcli.cpp hs_client/socket.cpp hs_client/string_util.cpp + spd_db_mysql.cc spd_db_oracle.cc spd_group_by_handler.cc spd_db_include.cc ) IF(DEFINED ENV{ORACLE_HOME}) diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 712397ffb92..7309c0499f2 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -82,10 +82,6 @@ ha_spider::ha_spider( conn_keys = NULL; spider_thread_id = 0; trx_conn_adjustment = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - trx_hs_r_conn_adjustment = 0; - trx_hs_w_conn_adjustment = 0; -#endif search_link_query_id = 0; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_handler = NULL; @@ -115,14 +111,6 @@ ha_spider::ha_spider( use_pre_action = FALSE; #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS do_direct_update = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - hs_pushed_ret_fields_num = MAX_FIELDS; - hs_pushed_ret_fields = NULL; - hs_pushed_ret_fields_size = 0; - hs_increment = FALSE; - hs_decrement = FALSE; - hs_pushed_strref_num = 0; -#endif #endif #ifdef HA_CAN_BULK_ACCESS is_bulk_access_clone = FALSE; @@ -145,16 +133,10 @@ ha_spider::ha_spider( result_list.insert_sqls = NULL; result_list.update_sqls = NULL; result_list.tmp_sqls = NULL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - result_list.hs_result_buf = NULL; -#endif result_list.tmp_tables_created = FALSE; result_list.bgs_working = FALSE; result_list.direct_order_limit = FALSE; result_list.direct_limit_offset = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - result_list.hs_has_result = FALSE; -#endif result_list.set_split_read = FALSE; result_list.insert_dup_update_pushdown = FALSE; result_list.tmp_pos_row_first = NULL; @@ -185,10 +167,6 @@ ha_spider::ha_spider( conn_keys = NULL; spider_thread_id = 0; trx_conn_adjustment = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - trx_hs_r_conn_adjustment = 0; - trx_hs_w_conn_adjustment = 0; -#endif search_link_query_id = 0; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_handler = NULL; @@ -218,14 +196,6 @@ ha_spider::ha_spider( use_pre_action = FALSE; #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS do_direct_update = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - hs_pushed_ret_fields_num = MAX_FIELDS; - hs_pushed_ret_fields = NULL; - hs_pushed_ret_fields_size = 0; - hs_increment = FALSE; - hs_decrement = FALSE; - hs_pushed_strref_num = 0; -#endif #endif #ifdef HA_CAN_BULK_ACCESS is_bulk_access_clone = FALSE; @@ -248,16 +218,10 @@ ha_spider::ha_spider( result_list.insert_sqls = NULL; result_list.update_sqls = NULL; result_list.tmp_sqls = NULL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - result_list.hs_result_buf = NULL; -#endif result_list.tmp_tables_created = FALSE; result_list.bgs_working = FALSE; result_list.direct_order_limit = FALSE; result_list.direct_limit_offset = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - result_list.hs_has_result = FALSE; -#endif result_list.set_split_read = FALSE; result_list.insert_dup_update_pushdown = FALSE; result_list.tmp_pos_row_first = NULL; @@ -748,25 +712,8 @@ int ha_spider::close() delete [] result_list.tmp_sqls; result_list.tmp_sqls = NULL; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (result_list.hs_result_buf) - { - delete result_list.hs_result_buf; - result_list.hs_result_buf = NULL; - } -#endif spider_free_share(share); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if (hs_pushed_ret_fields) - { - spider_free(spider_current_trx, hs_pushed_ret_fields, MYF(0)); - hs_pushed_ret_fields = NULL; - hs_pushed_ret_fields_size = 0; - } -#endif -#endif is_clone = FALSE; pt_clone_source_handler = NULL; share = NULL; @@ -785,84 +732,6 @@ int ha_spider::check_access_kind_for_connection( conn_kinds = 0; switch (wide_handler->sql_command) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - case SQLCOM_HS_READ: - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) - { - if (!write_request) - { - DBUG_PRINT("info",("spider spider_use_hs_read=%d", - spider_param_use_hs_read(thd, share->use_hs_reads[roop_count]))); - DBUG_PRINT("info",("spider use_hs_reads[%d]=%ld", roop_count, - share->use_hs_reads[roop_count])); - if (spider_param_use_hs_read(thd, share->use_hs_reads[roop_count])) - { - DBUG_PRINT("info",("spider set %d to HS_READ", roop_count)); - conn_kinds |= SPIDER_CONN_KIND_HS_READ; - conn_kind[roop_count] = SPIDER_CONN_KIND_HS_READ; - } else { - conn_kinds |= SPIDER_CONN_KIND_MYSQL; - conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; - } - } else if (share->hs_write_to_reads[roop_count]) - { - DBUG_PRINT("info",("spider spider_use_hs_write=%d", - spider_param_use_hs_write(thd, share->use_hs_writes[roop_count]))); - DBUG_PRINT("info",("spider use_hs_write[%d]=%ld", roop_count, - share->use_hs_writes[roop_count])); - if (spider_param_use_hs_write(thd, share->use_hs_writes[roop_count])) - { - DBUG_PRINT("info",("spider set %d to HS_WRITE", roop_count)); - conn_kinds |= SPIDER_CONN_KIND_HS_READ; - conn_kind[roop_count] = SPIDER_CONN_KIND_HS_READ; - } else { - conn_kinds |= SPIDER_CONN_KIND_MYSQL; - conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; - } - } else { - DBUG_PRINT("info",("spider spider_use_hs_write=%d", - spider_param_use_hs_write(thd, share->use_hs_writes[roop_count]))); - DBUG_PRINT("info",("spider use_hs_write[%d]=%ld", roop_count, - share->use_hs_writes[roop_count])); - if (spider_param_use_hs_write(thd, share->use_hs_writes[roop_count])) - { - DBUG_PRINT("info",("spider set %d to HS_WRITE", roop_count)); - conn_kinds |= SPIDER_CONN_KIND_HS_WRITE; - conn_kind[roop_count] = SPIDER_CONN_KIND_HS_WRITE; - } else { - conn_kinds |= SPIDER_CONN_KIND_MYSQL; - conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; - } - } - } - break; - case SQLCOM_HS_UPDATE: - case SQLCOM_HS_DELETE: - conn_kinds |= SPIDER_CONN_KIND_MYSQL; - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) - { - conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; - } - break; - case SQLCOM_HS_INSERT: - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) - { - DBUG_PRINT("info",("spider spider_use_hs_write=%d", - spider_param_use_hs_write(thd, share->use_hs_writes[roop_count]))); - DBUG_PRINT("info",("spider use_hs_write[%d]=%ld", roop_count, - share->use_hs_writes[roop_count])); - if (spider_param_use_hs_write(thd, share->use_hs_writes[roop_count])) - { - DBUG_PRINT("info",("spider set %d to HS_WRITE", roop_count)); - conn_kinds |= SPIDER_CONN_KIND_HS_WRITE; - conn_kind[roop_count] = SPIDER_CONN_KIND_HS_WRITE; - } else { - conn_kinds |= SPIDER_CONN_KIND_MYSQL; - conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; - } - } - break; -#endif case SQLCOM_UPDATE: case SQLCOM_UPDATE_MULTI: case SQLCOM_DELETE: @@ -875,12 +744,6 @@ int ha_spider::check_access_kind_for_connection( } break; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_strs_pos(SPIDER_SQL_TYPE_UPDATE_HS))) - { - DBUG_RETURN(error_num); - } -#endif if ((error_num = spider_check_trx_and_get_conn(thd, this, TRUE))) { DBUG_RETURN(error_num); @@ -915,17 +778,9 @@ void ha_spider::check_access_kind( DBUG_PRINT("info",("spider sql_command=%u", wide_handler->sql_command)); DBUG_PRINT("info",("spider thd->query_id=%lld", thd->query_id)); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -#ifdef HS_HAS_SQLCOM - if (wide_handler->sql_command == SQLCOM_HS_UPDATE) - wide_handler->update_request = TRUE; - else -#endif wide_handler->update_request = FALSE; #else if ( -#ifdef HS_HAS_SQLCOM - wide_handler->sql_command == SQLCOM_HS_UPDATE || -#endif wide_handler->sql_command == SQLCOM_UPDATE || wide_handler->sql_command == SQLCOM_UPDATE_MULTI || /* for triggers */ @@ -1008,9 +863,6 @@ THR_LOCK_DATA **ha_spider::store_lock( { case SQLCOM_SELECT: case SQLCOM_HA_READ: -#ifdef HS_HAS_SQLCOM - case SQLCOM_HS_READ: -#endif if (lock_type == TL_READ_WITH_SHARED_LOCKS) wide_handler->lock_mode = 1; else if (lock_type <= TL_READ_NO_INSERT) @@ -1023,9 +875,6 @@ THR_LOCK_DATA **ha_spider::store_lock( break; case SQLCOM_UPDATE: case SQLCOM_UPDATE_MULTI: -#ifdef HS_HAS_SQLCOM - case SQLCOM_HS_UPDATE: -#endif case SQLCOM_CREATE_TABLE: case SQLCOM_INSERT: case SQLCOM_INSERT_SELECT: @@ -1034,10 +883,6 @@ THR_LOCK_DATA **ha_spider::store_lock( case SQLCOM_REPLACE: case SQLCOM_REPLACE_SELECT: case SQLCOM_DELETE_MULTI: -#ifdef HS_HAS_SQLCOM - case SQLCOM_HS_INSERT: - case SQLCOM_HS_DELETE: -#endif if (lock_type >= TL_READ && lock_type <= TL_READ_NO_INSERT) { wide_handler->lock_mode = -2; @@ -1477,13 +1322,6 @@ int ha_spider::reset() ft_count = 0; ft_init_without_index_init = FALSE; sql_kinds = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - hs_pushed_ret_fields_num = MAX_FIELDS; - hs_increment = FALSE; - hs_decrement = FALSE; -#endif -#endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS do_direct_update = FALSE; #endif @@ -1491,10 +1329,6 @@ int ha_spider::reset() result_list.have_sql_kind_backup = FALSE; result_list.direct_order_limit = FALSE; result_list.direct_limit_offset = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num2 = reset_hs_strs(SPIDER_SQL_TYPE_UPDATE_HS))) - error_num = error_num2; -#endif result_list.set_split_read = FALSE; result_list.insert_dup_update_pushdown = FALSE; use_spatial_index = FALSE; @@ -1689,12 +1523,6 @@ int ha_spider::index_init( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_sql(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); - if ((error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); -#endif result_list.check_direct_order_limit = FALSE; prev_index_rnd_init = SPD_INDEX; DBUG_RETURN(0); @@ -1803,10 +1631,6 @@ int ha_spider::index_read_map_internal( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); -#endif #ifndef WITHOUT_SPIDER_BG_SEARCH if ((error_num = spider_set_conn_bg_param(this))) DBUG_RETURN(error_num); @@ -1894,18 +1718,6 @@ int ha_spider::index_read_map_internal( DBUG_RETURN(error_num); } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (sql_kinds & SPIDER_SQL_KIND_HS) - { - if ((error_num = append_limit_hs_part( - result_list.internal_offset, - result_list.limit_num, - SPIDER_SQL_TYPE_SELECT_HS))) - { - DBUG_RETURN(error_num); - } - } -#endif int roop_start, roop_end, lock_mode, link_ok; lock_mode = spider_conn_lock_mode(this); @@ -1966,10 +1778,6 @@ int ha_spider::index_read_map_internal( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -1977,15 +1785,6 @@ int ha_spider::index_read_map_internal( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -2232,19 +2031,7 @@ int ha_spider::index_read_map( conn_link_idx, roop_count, share->link_count, SPIDER_LINK_STATUS_RECOVERY) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - } -#endif if ((tmp_error_num = spider_db_bulk_store_result(this, conn, roop_count, (roop_count != link_ok)))) { @@ -2318,14 +2105,7 @@ int ha_spider::index_read_last_map_internal( spider_db_free_one_result_for_start_next(this); */ if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ( - result_list.hs_has_result || -#endif result_list.current -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) -#endif && (error_num = spider_db_free_result(this, FALSE)) ) @@ -2338,10 +2118,6 @@ int ha_spider::index_read_last_map_internal( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); -#endif #ifndef WITHOUT_SPIDER_BG_SEARCH if ((error_num = spider_set_conn_bg_param(this))) DBUG_RETURN(error_num); @@ -2477,10 +2253,6 @@ int ha_spider::index_read_last_map_internal( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -2488,15 +2260,6 @@ int ha_spider::index_read_last_map_internal( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -2810,9 +2573,6 @@ int ha_spider::index_first_internal( pt_clone_source_handler->pt_clone_last_searcher = this; } if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - result_list.hs_has_result || -#endif sql_is_empty(SPIDER_SQL_TYPE_HANDLER) || sql_is_empty(SPIDER_SQL_TYPE_SELECT_SQL) ) { @@ -2962,10 +2722,6 @@ int ha_spider::index_first_internal( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -2973,15 +2729,6 @@ int ha_spider::index_first_internal( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -3213,9 +2960,6 @@ int ha_spider::index_last_internal( pt_clone_source_handler->pt_clone_last_searcher = this; } if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - result_list.hs_has_result || -#endif sql_is_empty(SPIDER_SQL_TYPE_HANDLER) || sql_is_empty(SPIDER_SQL_TYPE_SELECT_SQL) ) { @@ -3365,10 +3109,6 @@ int ha_spider::index_last_internal( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -3376,15 +3116,6 @@ int ha_spider::index_last_internal( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -3688,10 +3419,6 @@ int ha_spider::read_range_first_internal( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); -#endif #ifndef WITHOUT_SPIDER_BG_SEARCH if ((error_num = spider_set_conn_bg_param(this))) DBUG_RETURN(error_num); @@ -3828,10 +3555,6 @@ int ha_spider::read_range_first_internal( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -3839,15 +3562,6 @@ int ha_spider::read_range_first_internal( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -4087,26 +3801,11 @@ void ha_spider::reset_no_where_cond() { uint roop_count; DBUG_ENTER("ha_spider::reset_no_where_cond"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (sql_kinds & (SPIDER_SQL_KIND_SQL | SPIDER_SQL_KIND_HANDLER)) - { -#endif for (roop_count = 0; roop_count < share->use_sql_dbton_count; roop_count++) { dbton_handler[share->use_sql_dbton_ids[roop_count]]->no_where_cond = FALSE; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } - if (sql_kinds & SPIDER_SQL_KIND_HS) - { - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_handler[share->use_hs_dbton_ids[roop_count]]->no_where_cond = - FALSE; - } - } -#endif DBUG_VOID_RETURN; } @@ -4114,10 +3813,6 @@ bool ha_spider::check_no_where_cond() { uint roop_count; DBUG_ENTER("ha_spider::check_no_where_cond"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (sql_kinds & (SPIDER_SQL_KIND_SQL | SPIDER_SQL_KIND_HANDLER)) - { -#endif for (roop_count = 0; roop_count < share->use_sql_dbton_count; roop_count++) { if (dbton_handler[share->use_sql_dbton_ids[roop_count]]->no_where_cond) @@ -4125,19 +3820,6 @@ bool ha_spider::check_no_where_cond() DBUG_RETURN(TRUE); } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } - if (sql_kinds & SPIDER_SQL_KIND_HS) - { - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - if (dbton_handler[share->use_hs_dbton_ids[roop_count]]->no_where_cond) - { - DBUG_RETURN(TRUE); - } - } - } -#endif DBUG_RETURN(FALSE); } @@ -4369,10 +4051,6 @@ int ha_spider::read_multi_range_first_internal( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); -#endif result_list.desc_flg = FALSE; #ifdef HA_MRR_USE_DEFAULT_IMPL result_list.sorted = mrr_is_output_sorted; @@ -4534,10 +4212,6 @@ int ha_spider::read_multi_range_first_internal( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -4545,15 +4219,6 @@ int ha_spider::read_multi_range_first_internal( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -4904,9 +4569,6 @@ int ha_spider::read_multi_range_first_internal( result_list.tmp_reuse_sql = FALSE; if (bka_mode && have_multi_range && -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - !(sql_kinds & SPIDER_SQL_KIND_HS) && -#endif #ifdef HA_MRR_USE_DEFAULT_IMPL SPIDER_TEST(mrr_cur_range.range_flag & EQ_RANGE) #else @@ -5359,10 +5021,6 @@ int ha_spider::read_multi_range_first_internal( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -5370,15 +5028,6 @@ int ha_spider::read_multi_range_first_internal( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -5699,10 +5348,6 @@ int ha_spider::read_multi_range_first_internal( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); -#endif #ifdef HA_MRR_USE_DEFAULT_IMPL #else multi_range_ranges = multi_range_curr; @@ -6036,10 +5681,6 @@ int ha_spider::read_multi_range_next( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -6047,15 +5688,6 @@ int ha_spider::read_multi_range_next( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -6377,10 +6009,6 @@ int ha_spider::read_multi_range_next( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); -#endif #ifdef HA_MRR_USE_DEFAULT_IMPL #else multi_range_ranges = multi_range_curr; @@ -6417,9 +6045,6 @@ int ha_spider::read_multi_range_next( result_list.tmp_reuse_sql = FALSE; if (bka_mode && have_multi_range && -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - !(sql_kinds & SPIDER_SQL_KIND_HS) && -#endif #ifdef HA_MRR_USE_DEFAULT_IMPL SPIDER_TEST(mrr_cur_range.range_flag & EQ_RANGE) #else @@ -6856,10 +6481,6 @@ int ha_spider::read_multi_range_next( } else { #endif ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = conns[roop_count]; if (sql_kind[roop_count] == SPIDER_SQL_KIND_SQL) { @@ -6867,15 +6488,6 @@ int ha_spider::read_multi_range_next( } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - conn = hs_r_conns[roop_count]; - else - conn = hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -7190,12 +6802,6 @@ int ha_spider::read_multi_range_next( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - (error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS)) - ) - DBUG_RETURN(error_num); -#endif #ifdef HA_MRR_USE_DEFAULT_IMPL #else multi_range_ranges = multi_range_curr; @@ -7310,13 +6916,6 @@ int ha_spider::rnd_init( if ((error_num = reset_sql_sql( SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - (error_num = reset_hs_sql(SPIDER_SQL_TYPE_SELECT_HS)) || - (error_num = reset_hs_keys(SPIDER_SQL_TYPE_SELECT_HS)) - ) - DBUG_RETURN(error_num); -#endif result_list.check_direct_order_limit = FALSE; } } @@ -7388,10 +6987,6 @@ int ha_spider::rnd_next_internal( if (rnd_scan_and_first) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (sql_kinds & SPIDER_SQL_KIND_HS) - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -#endif #ifndef WITHOUT_SPIDER_BG_SEARCH if ((error_num = spider_set_conn_bg_param(this))) DBUG_RETURN(error_num); @@ -9431,11 +9026,6 @@ ulonglong ha_spider::table_flags() const #ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON HA_CAN_TABLE_CONDITION_PUSHDOWN | #endif -#ifdef HA_CAN_BULK_ACCESS -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (support_bulk_access_hs() ? HA_CAN_BULK_ACCESS : 0) | -#endif -#endif SPIDER_CAN_BG_SEARCH | SPIDER_CAN_BG_INSERT | SPIDER_CAN_BG_UPDATE | @@ -9674,6 +9264,9 @@ void ha_spider::get_auto_increment( THD *thd = ha_thd(); int auto_increment_mode = spider_param_auto_increment_mode(thd, share->auto_increment_mode); + bool rev= table->key_info[table->s->next_number_index]. + key_part[table->s->next_number_keypart].key_part_flag & + HA_REVERSE_SORT; DBUG_ENTER("ha_spider::get_auto_increment"); DBUG_PRINT("info",("spider this=%p", this)); *nb_reserved_values = ULONGLONG_MAX; @@ -9693,7 +9286,9 @@ void ha_spider::get_auto_increment( table_share->next_number_key_offset); error_num = index_read_last_map(table->record[1], key, make_prev_keypart_map(table_share->next_number_keypart)); - } else + } else if (rev) + error_num = index_first(table->record[1]); + else error_num = index_last(table->record[1]); if (error_num) @@ -9968,32 +9563,9 @@ void ha_spider::direct_update_init( THD *thd, bool hs_request ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint roop_count; -#endif DBUG_ENTER("ha_spider::direct_update_init"); DBUG_PRINT("info",("spider this=%p", this)); do_direct_update = TRUE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (hs_request) - { - maybe_do_hs_direct_update = TRUE; - memset(do_hs_direct_update, 0, share->link_bitmap_size); - for (roop_count = 0; roop_count < share->link_count; roop_count++) - { - if (spider_param_use_hs_write(thd, share->use_hs_writes[roop_count])) - { - DBUG_PRINT("info",("spider do_hs_direct_update[%d]=TRUE", - roop_count)); - spider_set_bit(do_hs_direct_update, roop_count); - } else { - maybe_do_hs_direct_update = FALSE; - } - } - } else { - maybe_do_hs_direct_update = FALSE; - } -#endif DBUG_VOID_RETURN; } #endif @@ -10195,9 +9767,6 @@ int ha_spider::direct_update_rows_init( ) #endif { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int error_num; -#endif st_select_lex *select_lex; longlong select_limit; longlong offset_limit; @@ -10239,11 +9808,7 @@ int ha_spider::direct_update_rows_init( } direct_update_init( thd, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - sql_command == SQLCOM_HS_UPDATE -#else FALSE -#endif ); if (!condition) cond_check = FALSE; @@ -10295,41 +9860,14 @@ int ha_spider::direct_update_rows_init( DBUG_PRINT("info",("spider offset_limit=%lld", offset_limit)); DBUG_PRINT("info",("spider mode=%u", mode)); DBUG_PRINT("info",("spider sql_command=%u", sql_command)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - DBUG_PRINT("info",("spider maybe_do_hs_direct_update=%s", - maybe_do_hs_direct_update ? "TRUE" : "FALSE")); - DBUG_PRINT("info",("spider hs_pushed_ret_fields_num=%zu", - hs_pushed_ret_fields_num)); -#endif DBUG_PRINT("info",("spider do_direct_update=%s", do_direct_update ? "TRUE" : "FALSE")); if ( ( !offset_limit -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - || (mode == 2 && maybe_do_hs_direct_update) -#endif ) && -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - sql_command == SQLCOM_HS_UPDATE && - hs_pushed_ret_fields_num < MAX_FIELDS && -#endif do_direct_update ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - DBUG_PRINT("info",("spider pk_update=%s", pk_update ? "TRUE" : "FALSE")); - DBUG_PRINT("info",("spider start_key=%p", &ranges->start_key)); - if (pk_update && spider_check_hs_pk_update(this, &ranges->start_key)) - { - DBUG_PRINT("info",("spider FALSE by pk_update")); - do_direct_update = FALSE; - DBUG_RETURN(HA_ERR_WRONG_COMMAND); - } - if ((error_num = spider_check_trx_and_get_conn(thd, this, TRUE))) - { - DBUG_RETURN(error_num); - } -#endif wide_handler->trx->direct_update_count++; DBUG_PRINT("info",("spider OK")); DBUG_RETURN(0); @@ -10827,9 +10365,6 @@ int ha_spider::direct_delete_rows_init( uint range_count, bool sorted ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int error_num; -#endif st_select_lex *select_lex; longlong select_limit; longlong offset_limit; @@ -10864,11 +10399,7 @@ int ha_spider::direct_delete_rows_init( } direct_update_init( thd, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - sql_command == SQLCOM_HS_DELETE -#else FALSE -#endif ); if (!condition) cond_check = FALSE; @@ -10917,21 +10448,9 @@ int ha_spider::direct_delete_rows_init( if ( ( !offset_limit -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - || (mode == 2 && maybe_do_hs_direct_update) -#endif ) && -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - sql_command == SQLCOM_HS_DELETE && -#endif do_direct_update ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = spider_check_trx_and_get_conn(thd, this, TRUE))) - { - DBUG_RETURN(error_num); - } -#endif wide_handler->trx->direct_delete_count++; DBUG_PRINT("info",("spider OK")); DBUG_RETURN(0); @@ -12267,9 +11786,6 @@ int ha_spider::info_push( #ifdef HA_CAN_BULK_ACCESS if ( #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - info_type != INFO_KIND_HS_RET_FIELDS && -#endif #endif info_type != INFO_KIND_BULK_ACCESS_BEGIN && info_type != INFO_KIND_BULK_ACCESS_CURRENT && @@ -12296,144 +11812,6 @@ int ha_spider::info_push( switch (info_type) { #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - case INFO_KIND_HS_RET_FIELDS: - { - DBUG_PRINT("info",("spider INFO_KIND_HS_RET_FIELDS")); - size_t roop_count; - Field *field; - SPIDER_HS_UINT32_INFO *tmp_info = (SPIDER_HS_UINT32_INFO *) info; - wide_handler->hs_pushed_ret_fields_num = tmp_info->info_size; - if (wide_handler->hs_pushed_ret_fields_size < - wide_handler->hs_pushed_ret_fields_num) - { - if (wide_handler->hs_pushed_ret_fields) - spider_free(spider_current_trx, wide_handler->hs_pushed_ret_fields, - MYF(0)); - if (!(wide_handler->hs_pushed_ret_fields = (uint32 *) - spider_bulk_malloc(spider_current_trx, 17, MYF(MY_WME), - &wide_handler->hs_pushed_ret_fields, - sizeof(uint32) * wide_handler->hs_pushed_ret_fields_num, - NullS)) - ) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - wide_handler->hs_pushed_ret_fields_size = - wide_handler->hs_pushed_ret_fields_num; - } - memcpy(wide_handler->hs_pushed_ret_fields, tmp_info->info, - sizeof(uint32) * wide_handler->hs_pushed_ret_fields_num); - bitmap_clear_all(table->read_set); - bitmap_clear_all(table->write_set); - wide_handler->hs_pushed_lcl_fields_num = 0; - for (roop_count = 0; roop_count < wide_handler->hs_pushed_ret_fields_num; - roop_count++) - { - field = get_top_table_field( - wide_handler->hs_pushed_ret_fields[roop_count]); - if ((field = field_exchange(field))) - { - if (!bitmap_is_set(table->read_set, field->field_index)) - { - ++wide_handler->hs_pushed_lcl_fields_num; - bitmap_set_bit(table->read_set, field->field_index); - bitmap_set_bit(table->write_set, field->field_index); - } - } - } - } - break; - case INFO_KIND_HS_APPEND_STRING_REF: - { - DBUG_PRINT("info",("spider INFO_KIND_HS_APPEND_STRING_REF")); -#ifndef DBUG_OFF - SPIDER_HS_STRING_REF *tmp_ref = (SPIDER_HS_STRING_REF*) info; - char print_buf[MAX_FIELD_WIDTH]; - if (tmp_ref->size() < MAX_FIELD_WIDTH) - { - memcpy(print_buf, tmp_ref->begin(), tmp_ref->size()); - print_buf[tmp_ref->size()] = '\0'; - DBUG_PRINT("info",("spider info=%s", print_buf)); - } -#endif - Field *field; - if (wide_handler->hs_pushed_ret_fields) - { - field = get_top_table_field( - wide_handler->hs_pushed_ret_fields[ - wide_handler->hs_pushed_strref_num]); - } else { - field = get_top_table_field( - pt_clone_source_handler->wide_handler->hs_pushed_ret_fields[ - wide_handler->hs_pushed_strref_num]); - } - if (!field_exchange(field)) - { - wide_handler->hs_pushed_strref_num++; - break; - } - wide_handler->hs_pushed_strref_num++; - if (partition_handler && partition_handler->handlers) - { - size_t roop_count; - ha_spider **handlers = partition_handler->handlers; - for (roop_count = 0; roop_count < partition_handler->no_parts; - ++roop_count) - { - if ((error_num = handlers[roop_count]->push_back_hs_upds( - *((SPIDER_HS_STRING_REF*) info)))) - { - DBUG_RETURN(error_num); - } - } - } else { - if ((error_num = push_back_hs_upds(*((SPIDER_HS_STRING_REF*) info)))) - { - DBUG_RETURN(error_num); - } - } - break; - } - case INFO_KIND_HS_CLEAR_STRING_REF: - DBUG_PRINT("info",("spider INFO_KIND_HS_CLEAR_STRING_REF")); - wide_handler->hs_pushed_strref_num = 0; - if (partition_handler && partition_handler->handlers) - { - size_t roop_count; - ha_spider **handlers = partition_handler->handlers; - for (roop_count = 0; roop_count < partition_handler->no_parts; - ++roop_count) - { - if ((error_num = handlers[roop_count]->reset_hs_upds( - SPIDER_SQL_TYPE_UPDATE_HS))) - { - DBUG_RETURN(error_num); - } - } - } else { - if ((error_num = reset_hs_upds(SPIDER_SQL_TYPE_UPDATE_HS))) - { - DBUG_RETURN(error_num); - } - } - break; - case INFO_KIND_HS_INCREMENT_BEGIN: - DBUG_PRINT("info",("spider INFO_KIND_HS_INCREMENT_BEGIN")); - wide_handler->hs_increment = TRUE; - break; - case INFO_KIND_HS_INCREMENT_END: - DBUG_PRINT("info",("spider INFO_KIND_HS_INCREMENT_END")); - wide_handler->hs_increment = FALSE; - break; - case INFO_KIND_HS_DECREMENT_BEGIN: - DBUG_PRINT("info",("spider INFO_KIND_HS_DECREMENT_BEGIN")); - wide_handler->hs_decrement = TRUE; - break; - case INFO_KIND_HS_DECREMENT_END: - DBUG_PRINT("info",("spider INFO_KIND_HS_DECREMENT_END")); - wide_handler->hs_decrement = FALSE; - break; -#endif #ifdef INFO_KIND_UPDATE_FIELDS case INFO_KIND_UPDATE_FIELDS: DBUG_PRINT("info",("spider INFO_KIND_UPDATE_FIELDS")); @@ -13252,22 +12630,7 @@ bool ha_spider::handler_opened( DBUG_PRINT("info",("spider link_idx=%d", link_idx)); DBUG_PRINT("info",("spider tgt_conn_kind=%u", tgt_conn_kind)); if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ( - tgt_conn_kind == SPIDER_CONN_KIND_MYSQL && -#endif spider_bit_is_set(m_handler_opened, link_idx) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) || - ( - tgt_conn_kind == SPIDER_CONN_KIND_HS_READ && - spider_bit_is_set(r_handler_opened, link_idx) - ) || - ( - tgt_conn_kind == SPIDER_CONN_KIND_HS_WRITE && - spider_bit_is_set(w_handler_opened, link_idx) - ) -#endif ) { DBUG_PRINT("info",("spider TRUE")); DBUG_RETURN(TRUE); @@ -13281,16 +12644,7 @@ void ha_spider::set_handler_opened( ) { DBUG_ENTER("ha_spider::set_handler_opened"); DBUG_PRINT("info",("spider this=%p", this)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL) -#endif spider_set_bit(m_handler_opened, link_idx); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else if (conn_kind[link_idx] == SPIDER_CONN_KIND_HS_READ) - spider_set_bit(r_handler_opened, link_idx); - else - spider_set_bit(w_handler_opened, link_idx); -#endif DBUG_VOID_RETURN; } @@ -13300,16 +12654,7 @@ void ha_spider::clear_handler_opened( ) { DBUG_ENTER("ha_spider::clear_handler_opened"); DBUG_PRINT("info",("spider this=%p", this)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (tgt_conn_kind == SPIDER_CONN_KIND_MYSQL) -#endif spider_clear_bit(m_handler_opened, link_idx); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else if (tgt_conn_kind == SPIDER_CONN_KIND_HS_READ) - spider_clear_bit(r_handler_opened, link_idx); - else - spider_clear_bit(w_handler_opened, link_idx); -#endif DBUG_VOID_RETURN; } @@ -13357,96 +12702,6 @@ int ha_spider::close_opened_handler( conns[link_idx] = NULL; } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider_bit_is_set(r_handler_opened, link_idx)) - { - if ((error_num2 = spider_db_close_handler(this, - hs_r_conns[link_idx], link_idx, SPIDER_CONN_KIND_HS_READ)) - ) { - if ( - share->monitoring_kind[link_idx] && - need_mons[link_idx] - ) { - error_num2 = spider_ping_table_mon_from_table( - wide_handler->trx, - wide_handler->trx->thd, - share, - link_idx, - (uint32) share->monitoring_sid[link_idx], - share->table_name, - share->table_name_length, - conn_link_idx[link_idx], - NULL, - 0, - share->monitoring_kind[link_idx], - share->monitoring_limit[link_idx], - share->monitoring_flag[link_idx], - TRUE - ); - } - error_num = error_num2; - } - spider_clear_bit(r_handler_opened, link_idx); - if (release_conn && !hs_w_conns[link_idx]->join_trx) - { - if ( - !hs_r_conns[link_idx]->opened_handlers && - wide_handler->trx->trx_hs_r_conn_adjustment == - trx_hs_r_conn_adjustment && - spider_param_hs_r_conn_recycle_mode(wide_handler->trx->thd) != 2 - ) { - wide_handler->trx->trx_hs_r_conn_adjustment++; - } - spider_free_conn_from_trx(wide_handler->trx, hs_r_conns[link_idx], - FALSE, FALSE, NULL); - hs_r_conns[link_idx] = NULL; - } - } - if (spider_bit_is_set(w_handler_opened, link_idx)) - { - if ((error_num2 = spider_db_close_handler(this, - hs_w_conns[link_idx], link_idx, SPIDER_CONN_KIND_HS_WRITE)) - ) { - if ( - share->monitoring_kind[link_idx] && - need_mons[link_idx] - ) { - error_num2 = spider_ping_table_mon_from_table( - wide_handler->trx, - wide_handler->trx->thd, - share, - link_idx, - (uint32) share->monitoring_sid[link_idx], - share->table_name, - share->table_name_length, - conn_link_idx[link_idx], - NULL, - 0, - share->monitoring_kind[link_idx], - share->monitoring_limit[link_idx], - share->monitoring_flag[link_idx], - TRUE - ); - } - error_num = error_num2; - } - spider_clear_bit(w_handler_opened, link_idx); - if (release_conn && !hs_w_conns[link_idx]->join_trx) - { - if ( - !hs_w_conns[link_idx]->opened_handlers && - wide_handler->trx->trx_hs_w_conn_adjustment == - trx_hs_w_conn_adjustment && - spider_param_hs_w_conn_recycle_mode(wide_handler->trx->thd) != 2 - ) { - wide_handler->trx->trx_hs_w_conn_adjustment++; - } - spider_free_conn_from_trx(wide_handler->trx, hs_w_conns[link_idx], - FALSE, FALSE, NULL); - hs_w_conns[link_idx] = NULL; - } - } -#endif DBUG_RETURN(error_num); } @@ -13484,31 +12739,8 @@ int ha_spider::index_handler_init() spider_conn_use_handler(this, lock_mode, roop_count) && spider_conn_need_open_handler(this, active_index, roop_count) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint tmp_conn_kind1; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if ( - do_direct_update && - spider_bit_is_set(do_hs_direct_update, roop_count) - ) { - tmp_conn_kind1 = SPIDER_CONN_KIND_HS_WRITE; - } else { -#endif - tmp_conn_kind1 = conn_kind[roop_count]; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - } -#endif -#endif if ((error_num = spider_db_open_handler(this, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (tmp_conn_kind1 == SPIDER_CONN_KIND_MYSQL ? -#endif conns[roop_count] -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - : tmp_conn_kind1 == SPIDER_CONN_KIND_HS_READ ? - hs_r_conns[roop_count] : hs_w_conns[roop_count] - ) -#endif , roop_count)) ) { if ( @@ -13534,18 +12766,7 @@ int ha_spider::index_handler_init() } DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - uint tmp_conn_kind2 = conn_kind[roop_count]; - conn_kind[roop_count] = tmp_conn_kind1; -#endif -#endif set_handler_opened(roop_count); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - conn_kind[roop_count] = tmp_conn_kind2; -#endif -#endif } } if (sql_kinds & SPIDER_SQL_KIND_HANDLER) @@ -13607,15 +12828,7 @@ int ha_spider::rnd_handler_init() spider_conn_need_open_handler(this, MAX_KEY, roop_count) ) { if ((error_num = spider_db_open_handler(this, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL ? -#endif conns[roop_count] -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - : conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ ? - hs_r_conns[roop_count] : hs_w_conns[roop_count] - ) -#endif , roop_count)) ) { if ( @@ -13721,9 +12934,6 @@ void ha_spider::set_error_mode() case SQLCOM_SHOW_CREATE_TRIGGER: case SQLCOM_SHOW_PROFILE: case SQLCOM_SHOW_PROFILES: -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - case SQLCOM_HS_READ: -#endif error_mode = spider_param_error_read_mode(thd, share->error_read_mode); DBUG_PRINT("info",("spider read error_mode=%d", error_mode)); break; @@ -13939,10 +13149,6 @@ int ha_spider::sync_from_clone_source( DBUG_PRINT("info",("spider synced from clone source all")); wide_handler->trx = spider->wide_handler->trx; sql_command = spider->sql_command; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - conn_kinds = spider->conn_kinds; - memcpy(conn_kind, spider->conn_kind, sizeof(uint) * share->link_count); -#endif wide_handler->external_lock_type = spider->wide_handler->external_lock_type; selupd_lock_mode = spider->selupd_lock_mode; @@ -13952,18 +13158,8 @@ int ha_spider::sync_from_clone_source( low_priority = spider->low_priority; memcpy(conns, spider->conns, sizeof(SPIDER_CONN *) * share->link_count); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - memcpy(hs_r_conns, spider->hs_r_conns, - sizeof(SPIDER_CONN *) * share->link_count); - memcpy(hs_w_conns, spider->hs_w_conns, - sizeof(SPIDER_CONN *) * share->link_count); -#endif spider_thread_id = spider->spider_thread_id; trx_conn_adjustment = spider->trx_conn_adjustment; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - trx_hs_r_conn_adjustment = spider->trx_hs_r_conn_adjustment; - trx_hs_w_conn_adjustment = spider->trx_hs_w_conn_adjustment; -#endif search_link_idx = spider->search_link_idx; external_lock_cnt = spider->external_lock_cnt; uint roop_count, dbton_id; @@ -13980,10 +13176,6 @@ int ha_spider::sync_from_clone_source( { DBUG_PRINT("info",("spider synced from clone source")); sql_command = spider->sql_command; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - conn_kinds = spider->conn_kinds; - memcpy(conn_kind, spider->conn_kind, sizeof(uint) * share->link_count); -#endif wide_handler->external_lock_type = spider->wide_handler->external_lock_type; selupd_lock_mode = spider->selupd_lock_mode; @@ -14001,20 +13193,6 @@ int ha_spider::sync_from_clone_source( external_lock_cnt = spider->external_lock_cnt; } -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->hs_pushed_ret_fields_num < MAX_FIELDS) - { - SPIDER_HS_UINT32_INFO tmp_info; - tmp_info.info_size = spider->hs_pushed_ret_fields_num; - tmp_info.info = spider->hs_pushed_ret_fields; - if ((error_num = info_push(INFO_KIND_HS_RET_FIELDS, &tmp_info))) - { - DBUG_RETURN(error_num); - } - } -#endif -#endif DBUG_PRINT("info",("spider bulk_access_link->spider->dbton_handler=%p", dbton_handler)); DBUG_PRINT("info",("spider ptr bulk_access_link->spider->dbton_handler=%p", @@ -14075,21 +13253,6 @@ void ha_spider::set_first_link_idx() dbton_hdl->strict_group_by = TRUE; } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - dbton_id = share->hs_dbton_ids[all_link_idx]; - if (dbton_id < SPIDER_DBTON_SIZE) - { - dbton_hdl = dbton_handler[dbton_id]; - if (dbton_hdl->first_link_idx == -1) - { - dbton_hdl->first_link_idx = roop_count; - } - if (share->strict_group_bys[all_link_idx]) - { - dbton_hdl->strict_group_by = TRUE; - } - } -#endif } DBUG_VOID_RETURN; } @@ -14120,17 +13283,6 @@ void ha_spider::reset_first_link_idx() dbton_hdl->first_link_idx = search_link_idx; } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - dbton_id = share->hs_dbton_ids[all_link_idx]; - if (dbton_id < SPIDER_DBTON_SIZE) - { - dbton_hdl = dbton_handler[dbton_id]; - if (dbton_hdl->first_link_idx == -1) - { - dbton_hdl->first_link_idx = search_link_idx; - } - } -#endif } DBUG_VOID_RETURN; } @@ -14160,110 +13312,6 @@ int ha_spider::reset_sql_sql( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int ha_spider::reset_hs_sql( - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - DBUG_ENTER("ha_spider::reset_hs_sql"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - if ((error_num = dbton_handler[dbton_id]->reset_sql(sql_type))) - { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} - -int ha_spider::reset_hs_keys( - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - DBUG_ENTER("ha_spider::reset_hs_keys"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - if ((error_num = dbton_handler[dbton_id]->reset_keys(sql_type))) - { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} - -int ha_spider::reset_hs_upds( - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - DBUG_ENTER("ha_spider::reset_hs_upds"); - for (roop_count = 0; roop_count < share->use_dbton_count; roop_count++) - { - dbton_id = share->use_dbton_ids[roop_count]; - if ((error_num = dbton_handler[dbton_id]->reset_upds(sql_type))) - { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} - -int ha_spider::reset_hs_strs( - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - DBUG_ENTER("ha_spider::reset_hs_strs"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - if ((error_num = dbton_handler[dbton_id]->reset_strs(sql_type))) - { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} - -int ha_spider::reset_hs_strs_pos( - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - DBUG_ENTER("ha_spider::reset_hs_strs_pos"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - if ((error_num = dbton_handler[dbton_id]->reset_strs_pos(sql_type))) - { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} - -int ha_spider::push_back_hs_upds( - SPIDER_HS_STRING_REF &info -) { - int error_num; - uint roop_count, dbton_id; - DBUG_ENTER("ha_spider::push_back_hs_upds"); - for (roop_count = 0; roop_count < share->use_dbton_count; roop_count++) - { - dbton_id = share->use_dbton_ids[roop_count]; - if ((error_num = dbton_handler[dbton_id]->push_back_upds(info))) - { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} -#endif - int ha_spider::append_tmp_table_and_sql_for_bka( const key_range *start_key ) { @@ -14386,30 +13434,6 @@ int ha_spider::append_update_sql_part() DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -int ha_spider::append_increment_update_set_sql_part() -{ - int error_num; - uint roop_count, dbton_id; - spider_db_handler *dbton_hdl; - DBUG_ENTER("ha_spider::append_increment_update_set_sql_part"); - for (roop_count = 0; roop_count < share->use_sql_dbton_count; roop_count++) - { - dbton_id = share->use_sql_dbton_ids[roop_count]; - dbton_hdl = dbton_handler[dbton_id]; - if ( - dbton_hdl->first_link_idx >= 0 && - (error_num = dbton_hdl->append_increment_update_set_part()) - ) { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} -#endif -#endif - int ha_spider::append_update_set_sql_part() { int error_num; @@ -14450,28 +13474,6 @@ int ha_spider::append_direct_update_set_sql_part() } DBUG_RETURN(0); } - -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int ha_spider::append_direct_update_set_hs_part() -{ - int error_num; - uint roop_count, dbton_id; - spider_db_handler *dbton_hdl; - DBUG_ENTER("ha_spider::append_direct_update_set_hs_part"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - dbton_hdl = dbton_handler[dbton_id]; - if ( - dbton_hdl->first_link_idx >= 0 && - (error_num = dbton_hdl->append_direct_update_set_part()) - ) { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} -#endif #endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS @@ -14902,32 +13904,6 @@ int ha_spider::append_key_where_sql_part( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int ha_spider::append_key_where_hs_part( - const key_range *start_key, - const key_range *end_key, - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - spider_db_handler *dbton_hdl; - DBUG_ENTER("ha_spider::append_key_where_hs_part"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - dbton_hdl = dbton_handler[dbton_id]; - if ( - dbton_hdl->first_link_idx >= 0 && - (error_num = dbton_hdl->append_key_where_part(start_key, end_key, - sql_type)) - ) { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} -#endif - int ha_spider::append_match_where_sql_part( ulong sql_type ) { @@ -15203,31 +14179,6 @@ int ha_spider::append_limit_sql_part( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int ha_spider::append_limit_hs_part( - longlong offset, - longlong limit, - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - spider_db_handler *dbton_hdl; - DBUG_ENTER("ha_spider::append_limit_hs_part"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - dbton_hdl = dbton_handler[dbton_id]; - if ( - dbton_hdl->first_link_idx >= 0 && - (error_num = dbton_hdl->append_limit_part(offset, limit, sql_type)) - ) { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} -#endif - int ha_spider::reappend_limit_sql_part( longlong offset, longlong limit, @@ -15293,29 +14244,6 @@ int ha_spider::append_insert_values_sql_part( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int ha_spider::append_insert_values_hs_part( - ulong sql_type -) { - int error_num; - uint roop_count, dbton_id; - spider_db_handler *dbton_hdl; - DBUG_ENTER("ha_spider::append_insert_values_hs_part"); - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - dbton_hdl = dbton_handler[dbton_id]; - if ( - dbton_hdl->first_link_idx >= 0 && - (error_num = dbton_hdl->append_insert_values_part(sql_type)) - ) { - DBUG_RETURN(error_num); - } - } - DBUG_RETURN(0); -} -#endif - int ha_spider::append_into_sql_part( ulong sql_type ) { @@ -15359,10 +14287,6 @@ bool ha_spider::is_bulk_insert_exec_period( uint roop_count, dbton_id; spider_db_handler *dbton_hdl; DBUG_ENTER("ha_spider::is_bulk_insert_exec_period"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (sql_kinds & SPIDER_SQL_KIND_SQL) - { -#endif for (roop_count = 0; roop_count < share->use_sql_dbton_count; roop_count++) { dbton_id = share->use_sql_dbton_ids[roop_count]; @@ -15374,23 +14298,6 @@ bool ha_spider::is_bulk_insert_exec_period( DBUG_RETURN(TRUE); } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } - if (sql_kinds & SPIDER_SQL_KIND_HS) - { - for (roop_count = 0; roop_count < share->use_hs_dbton_count; roop_count++) - { - dbton_id = share->use_hs_dbton_ids[roop_count]; - dbton_hdl = dbton_handler[dbton_id]; - if ( - dbton_hdl->first_link_idx >= 0 && - dbton_hdl->is_bulk_insert_exec_period(bulk_end) - ) { - DBUG_RETURN(TRUE); - } - } - } -#endif DBUG_RETURN(FALSE); } @@ -16101,22 +15008,6 @@ bool ha_spider::support_use_handler_sql( DBUG_RETURN(TRUE); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -bool ha_spider::support_bulk_access_hs() const -{ - uint roop_count; - DBUG_ENTER("ha_spider::support_bulk_access_hs"); - if (!share) - DBUG_RETURN(FALSE); - for (roop_count = 0; roop_count < share->all_link_count; roop_count++) - { - if (share->hs_dbton_ids[roop_count] == SPIDER_DBTON_SIZE) - DBUG_RETURN(FALSE); - } - DBUG_RETURN(TRUE); -} -#endif - int ha_spider::init_union_table_name_pos_sql() { int error_num; @@ -16234,10 +15125,6 @@ int ha_spider::lock_tables() DBUG_PRINT("info",("spider lock_table_type=%u", wide_handler->lock_table_type)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((conn_kinds & SPIDER_CONN_KIND_MYSQL)) - { -#endif if (!conns[search_link_idx]) { my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM, @@ -16356,9 +15243,6 @@ int ha_spider::lock_tables() } } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif DBUG_RETURN(0); } @@ -16379,10 +15263,6 @@ int ha_spider::dml_init() { DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((conn_kinds & SPIDER_CONN_KIND_MYSQL)) - { -#endif if (!conns[search_link_idx]) { my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM, @@ -16473,91 +15353,6 @@ int ha_spider::dml_init() conns[roop_count]->semi_trx_isolation = -1; } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - reset_first_link_idx(); - } - if ((conn_kinds & SPIDER_CONN_KIND_HS_READ)) - { - SPIDER_CONN *hs_conn; - for ( - roop_count = spider_conn_link_idx_next(share->link_statuses, - conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_count < (int) share->link_count; - roop_count = spider_conn_link_idx_next(share->link_statuses, - conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - hs_conn = hs_r_conns[roop_count]; - if ( - hs_conn && - hs_conn->hsc_query_id != thd->query_id && - hs_conn->hs_pre_age == hs_conn->hs_age - ) { - double interval = spider_param_hs_ping_interval(thd); - time_t tmp_time = (time_t) time((time_t*) 0); - DBUG_PRINT("info", - ("spider difftime=%f", difftime(tmp_time, hs_conn->ping_time))); - DBUG_PRINT("info", ("spider interval=%f", interval)); - if ( - hs_conn->server_lost || - difftime(tmp_time, hs_conn->ping_time) >= interval - ) { - DBUG_PRINT("info", ("spider hsr[%d] need reconnect", roop_count)); - hs_conn->hs_pre_age++; - hs_conn->ping_time = tmp_time; - } - hs_conn->hsc_query_id = thd->query_id; - } - } - } - if ( -#if defined(HS_HAS_SQLCOM) && defined(HANDLER_HAS_DIRECT_UPDATE_ROWS) - ( -#endif - conn_kinds & SPIDER_CONN_KIND_HS_WRITE -#if defined(HS_HAS_SQLCOM) && defined(HANDLER_HAS_DIRECT_UPDATE_ROWS) - ) || - /* for direct_update */ - wide_handler->sql_command == SQLCOM_HS_UPDATE || - wide_handler->sql_command == SQLCOM_HS_DELETE -#endif - ) { - SPIDER_CONN *hs_conn; - for ( - roop_count = spider_conn_link_idx_next(share->link_statuses, - conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_count < (int) share->link_count; - roop_count = spider_conn_link_idx_next(share->link_statuses, - conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - hs_conn = hs_w_conns[roop_count]; - if ( - hs_conn && - hs_conn->hsc_query_id != thd->query_id && - hs_conn->hs_pre_age == hs_conn->hs_age - ) { - double interval = spider_param_hs_ping_interval(thd); - time_t tmp_time = (time_t) time((time_t*) 0); - DBUG_PRINT("info", - ("spider difftime=%f", difftime(tmp_time, hs_conn->ping_time))); - DBUG_PRINT("info", ("spider interval=%f", interval)); - if ( - hs_conn->server_lost || - difftime(tmp_time, hs_conn->ping_time) >= interval - ) { - DBUG_PRINT("info", ("spider hsw[%d] need reconnect", roop_count)); - hs_conn->hs_pre_age++; - hs_conn->ping_time = tmp_time; - } - hs_conn->hsc_query_id = thd->query_id; - } - } - } -#endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS if (wide_handler->insert_with_update) { @@ -16610,14 +15405,6 @@ int ha_spider::bulk_access_begin( ) { DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - memset( - bulk_access_link_current->spider->result_list.hs_r_bulk_open_index, 0, - share->link_bitmap_size); - memset( - bulk_access_link_current->spider->result_list.hs_w_bulk_open_index, 0, - share->link_bitmap_size); -#endif bulk_access_link_current->spider->bulk_access_executing = FALSE; bulk_access_link_current->spider->bulk_access_pre_called = FALSE; bulk_access_link_current->used = TRUE; diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index 3036f8d522a..cd847760bcf 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -55,10 +55,6 @@ public: SPIDER_SHARE *share; ulonglong spider_thread_id; ulonglong trx_conn_adjustment; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ulonglong trx_hs_r_conn_adjustment; - ulonglong trx_hs_w_conn_adjustment; -#endif uint mem_calc_id; const char *mem_calc_func_name; const char *mem_calc_file_name; @@ -71,14 +67,6 @@ public: char *conn_keys_first_ptr; char **conn_keys; SPIDER_CONN **conns; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char **hs_r_conn_keys; - SPIDER_CONN **hs_r_conns; - ulonglong *hs_r_conn_ages; - char **hs_w_conn_keys; - SPIDER_CONN **hs_w_conns; - ulonglong *hs_w_conn_ages; -#endif /* for active-standby mode */ uint *conn_link_idx; uchar *conn_can_fo; @@ -182,27 +170,8 @@ public: uchar *m_handler_opened; uint *m_handler_id; char **m_handler_cid; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uchar *r_handler_opened; - uint *r_handler_id; - uint *r_handler_index; - uchar *w_handler_opened; - uint *w_handler_id; - uint *w_handler_index; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - uchar *do_hs_direct_update; - uint32 **hs_r_ret_fields; - uint32 **hs_w_ret_fields; - size_t *hs_r_ret_fields_num; - size_t *hs_w_ret_fields_num; - uchar *tmp_column_bitmap; -#endif -#endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS bool do_direct_update; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - bool maybe_do_hs_direct_update; -#endif uint direct_update_kinds; #endif spider_index_rnd_init prev_index_rnd_init; @@ -974,26 +943,6 @@ public: int reset_sql_sql( ulong sql_type ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int reset_hs_sql( - ulong sql_type - ); - int reset_hs_keys( - ulong sql_type - ); - int reset_hs_upds( - ulong sql_type - ); - int reset_hs_strs( - ulong sql_type - ); - int reset_hs_strs_pos( - ulong sql_type - ); - int push_back_hs_upds( - SPIDER_HS_STRING_REF &info - ); -#endif int append_tmp_table_and_sql_for_bka( const key_range *start_key ); @@ -1004,17 +953,9 @@ public: int reuse_union_table_and_sql_for_bka(); int append_insert_sql_part(); int append_update_sql_part(); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - int append_increment_update_set_sql_part(); -#endif -#endif int append_update_set_sql_part(); #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS int append_direct_update_set_sql_part(); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int append_direct_update_set_hs_part(); -#endif #endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS int append_dup_update_pushdown_sql_part( @@ -1081,13 +1022,6 @@ public: const key_range *end_key, ulong sql_type ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int append_key_where_hs_part( - const key_range *start_key, - const key_range *end_key, - ulong sql_type - ); -#endif int append_match_where_sql_part( ulong sql_type ); @@ -1142,13 +1076,6 @@ public: longlong limit, ulong sql_type ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int append_limit_hs_part( - longlong offset, - longlong limit, - ulong sql_type - ); -#endif int reappend_limit_sql_part( longlong offset, longlong limit, @@ -1160,11 +1087,6 @@ public: int append_insert_values_sql_part( ulong sql_type ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int append_insert_values_hs_part( - ulong sql_type - ); -#endif int append_into_sql_part( ulong sql_type ); @@ -1233,9 +1155,6 @@ public: bool support_use_handler_sql( int use_handler ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - bool support_bulk_access_hs() const; -#endif int init_union_table_name_pos_sql(); int set_union_table_name_pos_sql(); int append_lock_tables_list(); diff --git a/storage/spider/hs_client/allocator.hpp b/storage/spider/hs_client/allocator.hpp deleted file mode 100644 index c302e07804e..00000000000 --- a/storage/spider/hs_client/allocator.hpp +++ /dev/null @@ -1,43 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_ALLOCATOR_HPP -#define DENA_ALLOCATOR_HPP - -#if 0 -extern "C" { -#include <tlsf.h> -}; -#define DENA_MALLOC(x) tlsf_malloc(x) -#define DENA_REALLOC(x, y) tlsf_realloc(x, y) -#define DENA_FREE(x) tlsf_free(x) -#define DENA_NEWCHAR(x) static_cast<char *>(tlsf_malloc(x)) -#define DENA_DELETE(x) tlsf_free(x) -#endif - -#if 1 -#define DENA_MALLOC(x) malloc(x) -#define DENA_REALLOC(x, y) realloc(x, y) -#define DENA_FREE(x) free(x) -#define DENA_NEWCHAR(x) (new char[x]) -#define DENA_DELETE(x) (delete [] x) -#endif - -#if 1 -#define DENA_ALLOCA_ALLOCATE(typ, len) \ - (typ *) (alloca((len) * sizeof(typ))) -#define DENA_ALLOCA_FREE(x) -#else -#define DENA_ALLOCA_ALLOCATE(typ, len) \ - (typ *) (malloc((len) * sizeof(typ))) -#define DENA_ALLOCA_FREE(x) free(x) -#endif - -#endif - diff --git a/storage/spider/hs_client/auto_addrinfo.hpp b/storage/spider/hs_client/auto_addrinfo.hpp deleted file mode 100644 index 26e5dee933e..00000000000 --- a/storage/spider/hs_client/auto_addrinfo.hpp +++ /dev/null @@ -1,49 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_AUTO_ADDRINFO_HPP -#define DENA_AUTO_ADDRINFO_HPP - -#ifndef _WIN32 -#include <netdb.h> -#endif - -#include "util.hpp" - -namespace dena { - -struct auto_addrinfo : private noncopyable { - auto_addrinfo() : addr(0) { } - ~auto_addrinfo() { - reset(); - } - void reset(addrinfo *a = 0) { - if (addr != 0) { - freeaddrinfo(addr); - } - addr = a; - } - const addrinfo *get() const { return addr; } - int resolve(const char *node, const char *service, int flags = 0, - int family = AF_UNSPEC, int socktype = SOCK_STREAM, int protocol = 0) { - reset(); - addrinfo hints; - hints.ai_flags = flags; - hints.ai_family = family; - hints.ai_socktype = socktype; - hints.ai_protocol = protocol; - return getaddrinfo(node, service, &hints, &addr); - } - private: - addrinfo *addr; -}; - -}; - -#endif - diff --git a/storage/spider/hs_client/auto_file.hpp b/storage/spider/hs_client/auto_file.hpp deleted file mode 100644 index 44903f5fc4a..00000000000 --- a/storage/spider/hs_client/auto_file.hpp +++ /dev/null @@ -1,67 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_AUTO_FILE_HPP -#define DENA_AUTO_FILE_HPP - -/* -#ifndef _WIN32 -#include <dirent.h> -#endif -*/ - -#include "util.hpp" - -namespace dena { - -struct auto_file : private noncopyable { - auto_file() : fd(-1) { } - ~auto_file() { - reset(); - } - int get() const { return fd; } - int close() { - if (fd < 0) { - return 0; - } - const int r = ::close(fd); - fd = -1; - return r; - } - void reset(int x = -1) { - if (fd >= 0) { - this->close(); - } - fd = x; - } - private: - int fd; -}; - -/* -struct auto_dir : private noncopyable { - auto_dir() : dp(0) { } - ~auto_dir() { - reset(); - } - DIR *get() const { return dp; } - void reset(DIR *d = 0) { - if (dp != 0) { - closedir(dp); - } - dp = d; - } - private: - DIR *dp; -}; -*/ - -}; - -#endif - diff --git a/storage/spider/hs_client/auto_ptrcontainer.hpp b/storage/spider/hs_client/auto_ptrcontainer.hpp deleted file mode 100644 index 3629f19c8ea..00000000000 --- a/storage/spider/hs_client/auto_ptrcontainer.hpp +++ /dev/null @@ -1,70 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_AUTO_PTRCONTAINER_HPP -#define DENA_AUTO_PTRCONTAINER_HPP - -namespace dena { - -/* -template <typename Tcnt> -struct auto_ptrcontainer { - typedef Tcnt container_type; - typedef typename container_type::value_type value_type; - typedef typename container_type::pointer pointer; - typedef typename container_type::reference reference; - typedef typename container_type::const_reference const_reference; - typedef typename container_type::size_type size_type; - typedef typename container_type::difference_type difference_type; - typedef typename container_type::iterator iterator; - typedef typename container_type::const_iterator const_iterator; - typedef typename container_type::reverse_iterator reverse_iterator; - typedef typename container_type::const_reverse_iterator - const_reverse_iterator; - iterator begin() { return cnt.begin(); } - const_iterator begin() const { return cnt.begin(); } - iterator end() { return cnt.end(); } - const_iterator end() const { return cnt.end(); } - reverse_iterator rbegin() { return cnt.rbegin(); } - reverse_iterator rend() { return cnt.rend(); } - const_reverse_iterator rbegin() const { return cnt.rbegin(); } - const_reverse_iterator rend() const { return cnt.rend(); } - size_type size() const { return cnt.size(); } - size_type max_size() const { return cnt.max_size(); } - bool empty() const { return cnt.empty(); } - reference front() { return cnt.front(); } - const_reference front() const { cnt.front(); } - reference back() { return cnt.back(); } - const_reference back() const { cnt.back(); } - void swap(auto_ptrcontainer& x) { cnt.swap(x.cnt); } - ~auto_ptrcontainer() { - for (iterator i = begin(); i != end(); ++i) { - delete *i; - } - } - template <typename Tap> void push_back_ptr(Tap& ap) { - cnt.push_back(ap.get()); - ap.release(); - } - void erase_ptr(iterator i) { - delete *i; - cnt.erase(i); - } - reference operator [](size_type n) { return cnt[n]; } - const_reference operator [](size_type n) const { return cnt[n]; } - void clear() { cnt.clear(); } - private: - Tcnt cnt; -}; -*/ - -}; - -#endif - diff --git a/storage/spider/hs_client/config.cpp b/storage/spider/hs_client/config.cpp deleted file mode 100644 index 0003c3fd645..00000000000 --- a/storage/spider/hs_client/config.cpp +++ /dev/null @@ -1,292 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#include <my_global.h> -#include "mysql_version.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#endif - -#include "config.hpp" - -namespace dena { - -unsigned int verbose_level = 0; - -uchar * -conf_get_key( - conf_param *param, - size_t *length, - my_bool not_used __attribute__ ((unused)) -) { - *length = param->key.length(); - return (uchar*) param->key.ptr(); -} - -config::config() -{ - if (my_hash_init(PSI_INSTRUMENT_ME, &conf_hash, &my_charset_bin, 32, 0, 0, - (my_hash_get_key) conf_get_key, 0, 0)) - init = FALSE; - else - init = TRUE; - return; -} - -config::~config() -{ - if (init) - { - conf_param *param; - while ((param = (conf_param *) my_hash_element(&conf_hash, 0))) - { - my_hash_delete(&conf_hash, (uchar*) param); - delete param; - } - my_hash_free(&conf_hash); - } -} - -conf_param * -config::find(const String& key) const -{ - if (init) - return (conf_param *) my_hash_search(&conf_hash, (const uchar*) key.ptr(), - key.length()); - else - return NULL; -} - -conf_param * -config::find(const char *key) const -{ - if (init) - return (conf_param *) my_hash_search(&conf_hash, (const uchar*) key, - strlen(key)); - else - return NULL; -} - -String -config::get_str(const String& key, const String& def) const -{ - DENA_VERBOSE(30, list_all_params()); - conf_param *param = find(key); - if (!param) { - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(default)\n", key.ptr(), - def.ptr())); - return def; - } - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n", key.ptr(), - param->val.ptr())); - return param->val; -} - -String -config::get_str(const char *key, const char *def) const -{ - DENA_VERBOSE(30, list_all_params()); - conf_param *param = find(key); - if (!param) { - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(default)\n", key, def)); - return String(def, strlen(def), &my_charset_bin); - } - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n", - key, param->val.ptr())); - return param->val; -} - -long long -config::get_int(const String& key, long long def) const -{ - int err; - DENA_VERBOSE(30, list_all_params()); - conf_param *param = find(key); - if (!param) { - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(default)\n", key.ptr(), - def)); - return def; - } - const long long r = my_strtoll10(param->val.ptr(), (char**) NULL, &err); - if (err) { - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(err)\n", key.ptr(), - def)); - return def; - } - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld\n", key.ptr(), r)); - return r; -} - -long long -config::get_int(const char *key, long long def) const -{ - int err; - DENA_VERBOSE(30, list_all_params()); - conf_param *param = find(key); - if (!param) { - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(default)\n", key, def)); - return def; - } - const long long r = my_strtoll10(param->val.ptr(), (char**) NULL, &err); - if (err) { - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(err)\n", key, def)); - return def; - } - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld\n", key, r)); - return r; -} - -bool -config::replace(const char *key, const char *val) -{ - uint32 val_len = strlen(val); - conf_param *param = find(key); - if (!param) { - /* create */ - if (!(param = new conf_param())) - return TRUE; - uint32 key_len = strlen(key); - if ( - param->key.reserve(key_len + 1) || - param->val.reserve(val_len + 1) - ) { - delete param; - return TRUE; - } - param->key.q_append(key, key_len); - param->val.q_append(val, val_len); - param->key.c_ptr_safe(); - param->val.c_ptr_safe(); - if (my_hash_insert(&conf_hash, (uchar*) param)) - { - delete param; - return TRUE; - } - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(create)\n", - param->key.ptr(), param->val.ptr())); - return FALSE; - } - /* replace */ - param->val.length(0); - if (param->val.reserve(val_len + 1)) - return TRUE; - param->val.q_append(val, val_len); - param->val.c_ptr_safe(); - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(replace)\n", - param->key.ptr(), param->val.ptr())); - return FALSE; -} - -bool -config::replace(const char *key, long long val) -{ - char val_str[22]; - sprintf(val_str, "%lld", val); - return replace(key, val_str); -} - -bool -config::compare(const char *key, const char *val) -{ - conf_param *param = find(key); - if (!param) - return FALSE; - return !strcmp(param->val.ptr(), val); -} - -void -config::list_all_params() const -{ - conf_param *param; - DENA_VERBOSE(10, fprintf(stderr, "list_all_params start\n")); - for(ulong i = 0; i < conf_hash.records; i++) - { - if ((param = (conf_param *) my_hash_element((HASH *) &conf_hash, i))) - { - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n", - param->key.ptr(), param->val.ptr())); - } - } - DENA_VERBOSE(10, fprintf(stderr, "list_all_params end\n")); -} - -config& -config::operator =(const config& x) -{ - DENA_VERBOSE(10, fprintf(stderr, "config operator = start")); - if (this != &x && init && x.init) { - conf_param *param, *new_param; - for(ulong i = 0; i < x.conf_hash.records; i++) - { - if ( - (param = (conf_param *) my_hash_element((HASH *) &x.conf_hash, i)) && - (new_param = new conf_param()) - ) { - if ( - !new_param->key.copy(param->key) && - !new_param->val.copy(param->val) - ) { - new_param->key.c_ptr_safe(); - new_param->val.c_ptr_safe(); - DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n", - new_param->key.ptr(), new_param->val.ptr())); - if (my_hash_insert(&conf_hash, (uchar*) new_param)) - delete new_param; - } else - delete new_param; - } - } - } - DENA_VERBOSE(10, fprintf(stderr, "config operator = end %p", this)); - return *this; -} - -void -parse_args(int argc, char **argv, config& conf) -{ - conf_param *param; - for (int i = 1; i < argc; ++i) { - const char *const arg = argv[i]; - const char *const eq = strchr(arg, '='); - if (eq == 0) { - continue; - } - if (!(param = new conf_param())) - continue; - uint32 key_len = (uint32)(eq - arg); - uint32 val_len = strlen(eq + 1); - if ( - param->key.reserve(key_len + 1) || - param->val.reserve(val_len + 1) - ) { - delete param; - continue; - } - param->key.q_append(arg, key_len); - param->val.q_append(eq + 1, val_len); - param->key.c_ptr_safe(); - param->val.c_ptr_safe(); - if (my_hash_insert(&conf.conf_hash, (uchar*) param)) - { - delete param; - continue; - } - } - param = conf.find("verbose"); - if (param) { - verbose_level = atoi(param->val.c_ptr()); - } -} - -}; - diff --git a/storage/spider/hs_client/config.hpp b/storage/spider/hs_client/config.hpp deleted file mode 100644 index 6d85c7e3d7c..00000000000 --- a/storage/spider/hs_client/config.hpp +++ /dev/null @@ -1,81 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_CONFIG_HPP -#define DENA_CONFIG_HPP - -#include "mysql_version.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#include "sql_class.h" -#endif - -#define DENA_VERBOSE(lv, x) if (dena::verbose_level >= (lv)) { (x); } - -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -#define INFO_KIND_HS_RET_FIELDS 1 -#define INFO_KIND_HS_APPEND_STRING_REF 3 -#define INFO_KIND_HS_CLEAR_STRING_REF 4 -#define INFO_KIND_HS_INCREMENT_BEGIN 5 -#define INFO_KIND_HS_INCREMENT_END 6 -#define INFO_KIND_HS_DECREMENT_BEGIN 7 -#define INFO_KIND_HS_DECREMENT_END 8 -#endif - -namespace dena { - -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -struct uint32_info { - size_t info_size; - uint32 *info; -}; -#endif - -struct conf_param { - String key; - String val; -}; - -uchar *conf_get_key( - conf_param *share, - size_t *length, - my_bool not_used __attribute__ ((unused)) -); - -struct config { - bool init; - HASH conf_hash; - config(); - ~config(); - conf_param *find(const String& key) const; - conf_param *find(const char *key) const; - String get_str(const String& key, const String& def = - String("", 0, &my_charset_bin)) const; - String get_str(const char *key, const char *def = "") const; - long long get_int(const String& key, long long def = 0) const; - long long get_int(const char *key, long long def = 0) const; - bool replace(const char *key, const char *val); - bool replace(const char *key, long long val); - bool compare(const char *key, const char *val); - void list_all_params() const; - config& operator =(const config& x); -}; - -void parse_args(int argc, char **argv, config& conf); - -extern unsigned int verbose_level; - -}; - -#endif - diff --git a/storage/spider/hs_client/escape.cpp b/storage/spider/hs_client/escape.cpp deleted file mode 100644 index f3e60afc387..00000000000 --- a/storage/spider/hs_client/escape.cpp +++ /dev/null @@ -1,129 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#include <my_global.h> -#include "mysql_version.h" -#include "hs_compat.h" -#include "escape.hpp" -#include "string_buffer.hpp" -#include "fatal.hpp" -#include "string_util.hpp" - -#define DBG_OP(x) -#define DBG_BUF(x) - -namespace dena { - -enum special_char_t { - special_char_escape_prefix = 0x01, /* SOH */ - special_char_noescape_min = 0x10, /* DLE */ - special_char_escape_shift = 0x40, /* '@' */ -}; - -void -escape_string(char *& wp, const char *start, const char *finish) -{ - while (start != finish) { - const unsigned char c = *start; - if (c >= special_char_noescape_min) { - wp[0] = c; /* no need to escape */ - } else { - wp[0] = special_char_escape_prefix; - ++wp; - wp[0] = c + special_char_escape_shift; - } - ++start; - ++wp; - } -} - -void -escape_string(string_buffer& ar, const char *start, const char *finish) -{ - const size_t buflen = (finish - start) * 2; - char *const wp_begin = ar.make_space(buflen); - char *wp = wp_begin; - escape_string(wp, start, finish); - ar.space_wrote(wp - wp_begin); -} - -bool -unescape_string(char *& wp, const char *start, const char *finish) -{ - /* works even if wp == start */ - while (start != finish) { - const unsigned char c = *start; - if (c != special_char_escape_prefix) { - wp[0] = c; - } else if (start + 1 != finish) { - ++start; - const unsigned char cn = *start; - if (cn < special_char_escape_shift) { - return false; - } - wp[0] = cn - special_char_escape_shift; - } else { - return false; - } - ++start; - ++wp; - } - return true; -} - -bool -unescape_string(string_buffer& ar, const char *start, const char *finish) -{ - const size_t buflen = finish - start; - char *const wp_begin = ar.make_space(buflen); - char *wp = wp_begin; - const bool r = unescape_string(wp, start, finish); - ar.space_wrote(wp - wp_begin); - return r; -} - -uint32 -read_ui32(char *& start, char *finish) -{ - char *const n_begin = start; - read_token(start, finish); - char *const n_end = start; - uint32 v = 0; - for (char *p = n_begin; p != n_end; ++p) { - const char ch = p[0]; - if (ch >= '0' && ch <= '9') { - v *= 10; - v += (ch - '0'); - } - } - return v; -} - -void -write_ui32(string_buffer& buf, uint32 v) -{ - char *wp = buf.make_space(12); - int len = snprintf(wp, 12, "%u", v); - if (len > 0) { - buf.space_wrote(len); - } -} - -void -write_ui64(string_buffer& buf, uint64 v) -{ - char *wp = buf.make_space(22); - int len = snprintf(wp, 22, "%llu", static_cast<unsigned long long>(v)); - if (len > 0) { - buf.space_wrote(len); - } -} - -}; - diff --git a/storage/spider/hs_client/escape.hpp b/storage/spider/hs_client/escape.hpp deleted file mode 100644 index 4c23e16701c..00000000000 --- a/storage/spider/hs_client/escape.hpp +++ /dev/null @@ -1,64 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved. - * See COPYRIGHT.txt for details. - */ - -#include "string_buffer.hpp" -#include "string_ref.hpp" -#include "string_util.hpp" - -#ifndef DENA_ESCAPE_HPP -#define DENA_ESCAPE_HPP - -namespace dena { - -void escape_string(char *& wp, const char *start, const char *finish); -void escape_string(string_buffer& ar, const char *start, const char *finish); -bool unescape_string(char *& wp, const char *start, const char *finish); - /* unescaped_string() works even if wp == start */ -bool unescape_string(string_buffer& ar, const char *start, const char *finish); - -uint32 read_ui32(char *& start, char *finish); -void write_ui32(string_buffer& buf, uint32 v); -void write_ui64(string_buffer& buf, uint64 v); - -inline bool -is_null_expression(const char *start, const char *finish) -{ - return (finish == start + 1 && start[0] == 0); -} - -inline void -read_token(char *& start, char *finish) -{ - char *const p = memchr_char(start, '\t', finish - start); - if (p == 0) { - start = finish; - } else { - start = p; - } -} - -inline void -skip_token_delim_fold(char *& start, char *finish) -{ - while (start != finish && start[0] == '\t') { - ++start; - } -} - -inline void -skip_one(char *& start, char *finish) -{ - if (start != finish) { - ++start; - } -} - -}; - -#endif - diff --git a/storage/spider/hs_client/fatal.cpp b/storage/spider/hs_client/fatal.cpp deleted file mode 100644 index cfbc14df64a..00000000000 --- a/storage/spider/hs_client/fatal.cpp +++ /dev/null @@ -1,49 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#include <my_global.h> -#include "mysql_version.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#endif - -#include "fatal.hpp" - -namespace dena { - -/* -const int opt_syslog = LOG_ERR | LOG_PID | LOG_CONS; -*/ - -void -fatal_abort(const String& message) -{ - fprintf(stderr, "FATAL_COREDUMP: %s\n", message.ptr()); -/* - syslog(opt_syslog, "FATAL_COREDUMP: %s", message.ptr()); -*/ - abort(); -} - -void -fatal_abort(const char *message) -{ - fprintf(stderr, "FATAL_COREDUMP: %s\n", message); -/* - syslog(opt_syslog, "FATAL_COREDUMP: %s", message); -*/ - abort(); -} - -}; - diff --git a/storage/spider/hs_client/fatal.hpp b/storage/spider/hs_client/fatal.hpp deleted file mode 100644 index 38fc149e98e..00000000000 --- a/storage/spider/hs_client/fatal.hpp +++ /dev/null @@ -1,31 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_FATAL_HPP -#define DENA_FATAL_HPP - -#include "mysql_version.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#include "sql_class.h" -#endif - -namespace dena { - -void fatal_abort(const String& message); -void fatal_abort(const char *message); - -}; - -#endif - diff --git a/storage/spider/hs_client/hs_compat.h b/storage/spider/hs_client/hs_compat.h deleted file mode 100644 index fb9b02ad4f0..00000000000 --- a/storage/spider/hs_client/hs_compat.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2013-2018 Kentoku Shiba - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ - -#ifndef HS_COMPAT_H -#define HS_COMPAT_H - -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100500 -#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \ - my_init_dynamic_array2(PSI_INSTRUMENT_ME, A, B, C, D, E, F) -#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ - init_alloc_root(PSI_INSTRUMENT_ME, A, B, C, D) -#elif defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100213 -#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \ - my_init_dynamic_array2(A, B, C, D, E, F) -#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ - init_alloc_root(A, "spider", B, C, D) -#elif defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 -#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \ - my_init_dynamic_array2(A, B, C, D, E, F) -#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ - init_alloc_root(A, B, C, D) -#else -#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \ - my_init_dynamic_array2(A, B, C, D, E) -#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ - init_alloc_root(A, B, C) -#endif - -#endif diff --git a/storage/spider/hs_client/hstcpcli.cpp b/storage/spider/hs_client/hstcpcli.cpp deleted file mode 100644 index b3dea208f8f..00000000000 --- a/storage/spider/hs_client/hstcpcli.cpp +++ /dev/null @@ -1,667 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#include <my_global.h> -#include "mysql_version.h" -#include "hs_compat.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#include "sql_class.h" -#endif - -#include "hstcpcli.hpp" -#include "auto_file.hpp" -#include "string_util.hpp" -#include "auto_addrinfo.hpp" -#include "escape.hpp" -#include "util.hpp" - -/* TODO */ -#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(MSG_NOSIGNAL) -#define MSG_NOSIGNAL 0 -#endif - -#define DBG(x) - -namespace dena { - -hstresult::hstresult() -{ - SPD_INIT_DYNAMIC_ARRAY2(&flds, sizeof(string_ref), NULL, 16, 16, - MYF(MY_WME)); -} - -hstresult::~hstresult() -{ - delete_dynamic(&flds); -} - -struct hstcpcli : public hstcpcli_i, private noncopyable { - hstcpcli(const socket_args& args); - virtual ~hstcpcli(); - virtual void close(); - virtual int reconnect(); - virtual bool stable_point(); - virtual void request_buf_open_index(size_t pst_id, const char *dbn, - const char *tbl, const char *idx, const char *retflds, const char *filflds); - virtual void request_buf_auth(const char *secret, const char *typ); - virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op, - const string_ref *kvs, size_t kvslen, uint32 limit, uint32 skip, - const string_ref& mod_op, const string_ref *mvs, size_t mvslen, - const hstcpcli_filter *fils, size_t filslen, int invalues_keypart, - const string_ref *invalues, size_t invalueslen); - virtual size_t request_buf_append(const char *start, const char *finish); - virtual void request_reset(); - virtual int request_send(); - virtual int response_recv(size_t& num_flds_r); - virtual int get_result(hstresult& result); - virtual const string_ref *get_next_row(); - virtual const string_ref *get_next_row_from_result(hstresult& result); - virtual size_t get_row_size(); - virtual size_t get_row_size_from_result(hstresult& result); - virtual void response_buf_remove(); - virtual int get_error_code(); - virtual String& get_error(); - virtual void clear_error(); - virtual int set_timeout(int send_timeout, int recv_timeout); - virtual size_t get_num_req_bufd() { return num_req_bufd; } - virtual size_t get_num_req_sent() { return num_req_sent; } - virtual size_t get_num_req_rcvd() { return num_req_rcvd; } - virtual size_t get_response_end_offset() { return response_end_offset; } - virtual const char *get_readbuf_begin() { return readbuf.begin(); } - virtual const char *get_readbuf_end() { return readbuf.end(); } - virtual const char *get_writebuf_begin() { return writebuf.begin(); } - virtual size_t get_writebuf_size() { return writebuf.size(); } - virtual void write_error_to_log(const char *func_name, const char *file_name, - ulong line_no); - private: - int read_more(); - int set_error(int code, const String& str); - int set_error(int code, const char *str); - private: - auto_file fd; - socket_args sargs; - string_buffer readbuf; - string_buffer writebuf; - size_t response_end_offset; /* incl newline */ - size_t cur_row_offset; - size_t cur_row_size; - size_t num_flds; - size_t num_req_bufd; /* buffered but not yet sent */ - size_t num_req_sent; /* sent but not yet received */ - size_t num_req_rcvd; /* received but not yet removed */ - int error_code; - String error_str; - DYNAMIC_ARRAY flds; - int errno_buf; -}; - -hstcpcli::hstcpcli(const socket_args& args) - : sargs(args), response_end_offset(0), cur_row_offset(0), cur_row_size(0), - num_flds(0), num_req_bufd(0), num_req_sent(0), num_req_rcvd(0), - error_code(0), errno_buf(0) -{ - String err; - SPD_INIT_DYNAMIC_ARRAY2(&flds, sizeof(string_ref), NULL, 16, 16, MYF(MY_WME)); - if (socket_connect(fd, sargs, err) != 0) { - set_error(-1, err); - } -} - -hstcpcli::~hstcpcli() -{ - delete_dynamic(&flds); -} - -void -hstcpcli::close() -{ - fd.close(); - readbuf.clear(); - writebuf.clear(); - response_end_offset = 0; - cur_row_offset = 0; - num_flds = 0; - num_req_bufd = 0; - num_req_sent = 0; - num_req_rcvd = 0; -} - -int -hstcpcli::reconnect() -{ - clear_error(); - close(); - String err; - if (socket_connect(fd, sargs, err) != 0) { - set_error(-1, err); - } - return error_code; -} - -int -hstcpcli::set_timeout(int send_timeout, int recv_timeout) -{ - String err; - sargs.send_timeout = send_timeout; - sargs.recv_timeout = recv_timeout; - if (socket_set_timeout(fd, sargs, err) != 0) { - set_error(-1, err); - } - return error_code; -} - -bool -hstcpcli::stable_point() -{ - /* returns true if cli can send a new request */ - return fd.get() >= 0 && num_req_bufd == 0 && num_req_sent == 0 && - num_req_rcvd == 0 && response_end_offset == 0; -} - -int -hstcpcli::get_error_code() -{ - return error_code; -} - -String& -hstcpcli::get_error() -{ - return error_str; -} - -int -hstcpcli::read_more() -{ - const size_t block_size = 4096; // FIXME - char *const wp = readbuf.make_space(block_size); - int rlen; - errno = 0; - while ((rlen = read(fd.get(), wp, block_size)) <= 0) { - errno_buf = errno; - if (rlen < 0) { - if (errno == EINTR || errno == EAGAIN) - { - errno = 0; - continue; - } - error_str = String(STRING_WITH_LEN("read: failed"), &my_charset_bin); - } else { - error_str = String(STRING_WITH_LEN("read: eof"), &my_charset_bin); - } - return rlen; - } - readbuf.space_wrote(rlen); - return rlen; -} - -void -hstcpcli::clear_error() -{ - DBG(fprintf(stderr, "CLEAR_ERROR: %d\n", error_code)); - error_code = 0; - error_str.length(0); -} - -int -hstcpcli::set_error(int code, const String& str) -{ - DBG(fprintf(stderr, "SET_ERROR: %d\n", code)); - error_code = code; - error_str = str; - return error_code; -} - -int -hstcpcli::set_error(int code, const char *str) -{ - uint32 str_len = strlen(str); - DBG(fprintf(stderr, "SET_ERROR: %d\n", code)); - error_code = code; - error_str.length(0); - if (error_str.reserve(str_len + 1)) - return 0; - error_str.q_append(str, str_len); - error_str.c_ptr_safe(); - return error_code; -} - -void -hstcpcli::request_buf_open_index(size_t pst_id, const char *dbn, - const char *tbl, const char *idx, const char *retflds, const char *filflds) -{ -/* - if (num_req_sent > 0 || num_req_rcvd > 0) { -*/ - if (num_req_rcvd > 0) { - close(); - set_error(-1, "request_buf_open_index: protocol out of sync"); - return; - } - const string_ref dbn_ref(dbn, strlen(dbn)); - const string_ref tbl_ref(tbl, strlen(tbl)); - const string_ref idx_ref(idx, strlen(idx)); - const string_ref rfs_ref(retflds, strlen(retflds)); - writebuf.append_literal("P\t"); - append_uint32(writebuf, pst_id); // FIXME size_t ? - writebuf.append_literal("\t"); - writebuf.append(dbn_ref.begin(), dbn_ref.end()); - writebuf.append_literal("\t"); - writebuf.append(tbl_ref.begin(), tbl_ref.end()); - writebuf.append_literal("\t"); - writebuf.append(idx_ref.begin(), idx_ref.end()); - writebuf.append_literal("\t"); - writebuf.append(rfs_ref.begin(), rfs_ref.end()); - if (filflds != 0) { - const string_ref fls_ref(filflds, strlen(filflds)); - writebuf.append_literal("\t"); - writebuf.append(fls_ref.begin(), fls_ref.end()); - } - writebuf.append_literal("\n"); - ++num_req_bufd; -} - -void -hstcpcli::request_buf_auth(const char *secret, const char *typ) -{ -/* - if (num_req_sent > 0 || num_req_rcvd > 0) { -*/ - if (num_req_rcvd > 0) { - close(); - set_error(-1, "request_buf_auth: protocol out of sync"); - return; - } - if (typ == 0) { - typ = "1"; - } - const string_ref typ_ref(typ, strlen(typ)); - const string_ref secret_ref(secret, strlen(secret)); - writebuf.append_literal("A\t"); - writebuf.append(typ_ref.begin(), typ_ref.end()); - writebuf.append_literal("\t"); - writebuf.append(secret_ref.begin(), secret_ref.end()); - writebuf.append_literal("\n"); - ++num_req_bufd; -} - -namespace { - -void -append_delim_value(string_buffer& buf, const char *start, const char *finish) -{ - if (start == 0) { - /* null */ - const char t[] = "\t\0"; - buf.append(t, t + 2); - } else { - /* non-null */ - buf.append_literal("\t"); - escape_string(buf, start, finish); - } -} - -}; - -void -hstcpcli::request_buf_exec_generic(size_t pst_id, const string_ref& op, - const string_ref *kvs, size_t kvslen, uint32 limit, uint32 skip, - const string_ref& mod_op, const string_ref *mvs, size_t mvslen, - const hstcpcli_filter *fils, size_t filslen, int invalues_keypart, - const string_ref *invalues, size_t invalueslen) -{ -/* - if (num_req_sent > 0 || num_req_rcvd > 0) { -*/ - if (num_req_rcvd > 0) { - close(); - set_error(-1, "request_buf_exec_generic: protocol out of sync"); - return; - } - append_uint32(writebuf, pst_id); // FIXME size_t ? - writebuf.append_literal("\t"); - writebuf.append(op.begin(), op.end()); - writebuf.append_literal("\t"); - append_uint32(writebuf, kvslen); // FIXME size_t ? - for (size_t i = 0; i < kvslen; ++i) { - const string_ref& kv = kvs[i]; - append_delim_value(writebuf, kv.begin(), kv.end()); - } - if (limit != 0 || skip != 0 || invalues_keypart >= 0 || - mod_op.size() != 0 || filslen != 0) { - /* has more option */ - writebuf.append_literal("\t"); - append_uint32(writebuf, limit); // FIXME size_t ? - if (skip != 0 || invalues_keypart >= 0 || - mod_op.size() != 0 || filslen != 0) { - writebuf.append_literal("\t"); - append_uint32(writebuf, skip); // FIXME size_t ? - } - if (invalues_keypart >= 0) { - writebuf.append_literal("\t@\t"); - append_uint32(writebuf, invalues_keypart); - writebuf.append_literal("\t"); - append_uint32(writebuf, invalueslen); - for (size_t i = 0; i < invalueslen; ++i) { - const string_ref& s = invalues[i]; - append_delim_value(writebuf, s.begin(), s.end()); - } - } - for (size_t i = 0; i < filslen; ++i) { - const hstcpcli_filter& f = fils[i]; - writebuf.append_literal("\t"); - writebuf.append(f.filter_type.begin(), f.filter_type.end()); - writebuf.append_literal("\t"); - writebuf.append(f.op.begin(), f.op.end()); - writebuf.append_literal("\t"); - append_uint32(writebuf, f.ff_offset); - append_delim_value(writebuf, f.val.begin(), f.val.end()); - } - if (mod_op.size() != 0) { - writebuf.append_literal("\t"); - writebuf.append(mod_op.begin(), mod_op.end()); - for (size_t i = 0; i < mvslen; ++i) { - const string_ref& mv = mvs[i]; - append_delim_value(writebuf, mv.begin(), mv.end()); - } - } - } - writebuf.append_literal("\n"); - ++num_req_bufd; -} - -size_t -hstcpcli::request_buf_append(const char *start, const char *finish) -{ -/* - if (num_req_sent > 0 || num_req_rcvd > 0) { -*/ - if (num_req_rcvd > 0) { - close(); - set_error(-1, "request_buf_append: protocol out of sync"); - return 0; - } - const char *nl = start; - size_t num_req = 0; - while ((nl = memchr_char(nl, '\n', finish - nl))) { - if (nl == finish) - break; - num_req++; - nl++; - } - num_req++; - writebuf.append(start, finish); - if (*(finish - 1) != '\n') - writebuf.append_literal("\n"); - num_req_bufd += num_req; - return num_req; -} - -void -hstcpcli::request_reset() -{ - if (num_req_bufd) { - writebuf.erase_front(writebuf.size()); - num_req_bufd = 0; - } -} - -int -hstcpcli::request_send() -{ - if (error_code < 0) { - return error_code; - } - clear_error(); - if (fd.get() < 0) { - close(); - return set_error(-1, "write: closed"); - } -/* - if (num_req_bufd == 0 || num_req_sent > 0 || num_req_rcvd > 0) { -*/ - if (num_req_bufd == 0 || num_req_rcvd > 0) { - close(); - return set_error(-1, "request_send: protocol out of sync"); - } - const size_t wrlen = writebuf.size(); - const ssize_t r = send(fd.get(), writebuf.begin(), wrlen, MSG_NOSIGNAL); - if (r <= 0) { - close(); - return set_error(-1, r < 0 ? "write: failed" : "write: eof"); - } - writebuf.erase_front(r); - if (static_cast<size_t>(r) != wrlen) { - close(); - return set_error(-1, "write: incomplete"); - } - num_req_sent += num_req_bufd; - num_req_bufd = 0; - DBG(fprintf(stderr, "REQSEND 0\n")); - return 0; -} - -int -hstcpcli::response_recv(size_t& num_flds_r) -{ - if (error_code < 0) { - return error_code; - } - clear_error(); - if (num_req_bufd > 0 || num_req_sent == 0 || num_req_rcvd > 0 || - response_end_offset != 0) { - close(); - return set_error(-1, "response_recv: protocol out of sync"); - } - cur_row_offset = 0; - num_flds_r = num_flds = 0; - if (fd.get() < 0) { - return set_error(-1, "read: closed"); - } - size_t offset = 0; - while (true) { - const char *const lbegin = readbuf.begin() + offset; - const char *const lend = readbuf.end(); - if (lbegin < lend) - { - const char *const nl = memchr_char(lbegin, '\n', lend - lbegin); - if (nl != 0) { - offset += (nl + 1) - lbegin; - break; - } - offset += lend - lbegin; - } - if (read_more() <= 0) { - close(); - error_code = -1; - return error_code; - } - } - response_end_offset = offset; - --num_req_sent; - ++num_req_rcvd; - char *start = readbuf.begin(); - char *const finish = start + response_end_offset - 1; - const size_t resp_code = read_ui32(start, finish); - skip_one(start, finish); - num_flds_r = num_flds = read_ui32(start, finish); - if (resp_code != 0) { - skip_one(start, finish); - char *const err_begin = start; - read_token(start, finish); - char *const err_end = start; - String e = String(err_begin, (uint32)(err_end - err_begin), &my_charset_bin); - if (!e.length()) { - e = String(STRING_WITH_LEN("unknown_error"), &my_charset_bin); - } - return set_error(resp_code, e); - } - cur_row_size = 0; - cur_row_offset = start - readbuf.begin(); - DBG(fprintf(stderr, "[%s] ro=%zu eol=%zu\n", - String(readbuf.begin(), readbuf.begin() + response_end_offset) - .c_str(), - cur_row_offset, response_end_offset)); - DBG(fprintf(stderr, "RES 0\n")); - if (flds.max_element < num_flds) - { - if (allocate_dynamic(&flds, num_flds)) - return set_error(-1, "out of memory"); - } - flds.elements = num_flds; - return 0; -} - -int -hstcpcli::get_result(hstresult& result) -{ -/* - readbuf.swap(result.readbuf); -*/ - char *const wp = result.readbuf.make_space(response_end_offset); - memcpy(wp, readbuf.begin(), response_end_offset); - result.readbuf.space_wrote(response_end_offset); - result.response_end_offset = response_end_offset; - result.num_flds = num_flds; - result.cur_row_size = cur_row_size; - result.cur_row_offset = cur_row_offset; - if (result.flds.max_element < num_flds) - { - if (allocate_dynamic(&result.flds, num_flds)) - return set_error(-1, "out of memory"); - } - result.flds.elements = num_flds; - return 0; -} - -const string_ref * -hstcpcli::get_next_row() -{ - if (num_flds == 0 || flds.elements < num_flds) { - DBG(fprintf(stderr, "GNR NF 0\n")); - return 0; - } - char *start = readbuf.begin() + cur_row_offset; - char *const finish = readbuf.begin() + response_end_offset - 1; - if (start >= finish) { /* start[0] == nl */ - DBG(fprintf(stderr, "GNR FIN 0 %p %p\n", start, finish)); - return 0; - } - for (size_t i = 0; i < num_flds; ++i) { - skip_one(start, finish); - char *const fld_begin = start; - read_token(start, finish); - char *const fld_end = start; - char *wp = fld_begin; - if (is_null_expression(fld_begin, fld_end)) { - /* null */ - ((string_ref *) flds.buffer)[i] = string_ref(); - } else { - unescape_string(wp, fld_begin, fld_end); /* in-place */ - ((string_ref *) flds.buffer)[i] = string_ref(fld_begin, wp); - } - } - cur_row_size = start - (readbuf.begin() + cur_row_offset); - cur_row_offset = start - readbuf.begin(); - return (string_ref *) flds.buffer; -} - -const string_ref * -hstcpcli::get_next_row_from_result(hstresult& result) -{ - if (result.num_flds == 0 || result.flds.elements < result.num_flds) { - DBG(fprintf(stderr, "GNR NF 0\n")); - return 0; - } - char *start = result.readbuf.begin() + result.cur_row_offset; - char *const finish = result.readbuf.begin() + result.response_end_offset - 1; - if (start >= finish) { /* start[0] == nl */ - DBG(fprintf(stderr, "GNR FIN 0 %p %p\n", start, finish)); - return 0; - } - for (size_t i = 0; i < result.num_flds; ++i) { - skip_one(start, finish); - char *const fld_begin = start; - read_token(start, finish); - char *const fld_end = start; - char *wp = fld_begin; - if (is_null_expression(fld_begin, fld_end)) { - /* null */ - ((string_ref *) result.flds.buffer)[i] = string_ref(); - } else { - unescape_string(wp, fld_begin, fld_end); /* in-place */ - ((string_ref *) result.flds.buffer)[i] = string_ref(fld_begin, wp); - } - } - result.cur_row_size = - start - (result.readbuf.begin() + result.cur_row_offset); - result.cur_row_offset = start - result.readbuf.begin(); - return (string_ref *) result.flds.buffer; -} - -size_t -hstcpcli::get_row_size() -{ - return cur_row_size; -} - -size_t -hstcpcli::get_row_size_from_result(hstresult& result) -{ - return result.cur_row_size; -} - -void -hstcpcli::response_buf_remove() -{ - if (response_end_offset == 0) { - close(); - set_error(-1, "response_buf_remove: protocol out of sync"); - return; - } - readbuf.erase_front(response_end_offset); - response_end_offset = 0; - --num_req_rcvd; - cur_row_offset = 0; - num_flds = 0; -} - -void -hstcpcli::write_error_to_log( - const char *func_name, - const char *file_name, - ulong line_no -) { - if (errno_buf) { - time_t cur_time = (time_t) time((time_t*) 0); - struct tm lt; - struct tm *l_time = localtime_r(&cur_time, <); - fprintf(stderr, - "%04d%02d%02d %02d:%02d:%02d [ERROR] hstcpcli: [%d][%s]" - " [%s][%s][%lu] errno=%d\n", - l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, - l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - error_code, error_str.c_ptr_safe(), - func_name, file_name, line_no, errno_buf); - } -} - -hstcpcli_ptr -hstcpcli_i::create(const socket_args& args) -{ - return hstcpcli_ptr(new hstcpcli(args)); -} - -}; - diff --git a/storage/spider/hs_client/hstcpcli.hpp b/storage/spider/hs_client/hstcpcli.hpp deleted file mode 100644 index 6894716e469..00000000000 --- a/storage/spider/hs_client/hstcpcli.hpp +++ /dev/null @@ -1,98 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_HSTCPCLI_HPP -#define DENA_HSTCPCLI_HPP - -#define HANDLERSOCKET_MYSQL_UTIL 1 - -#include "mysql_version.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#endif - -#include "config.hpp" -#include "socket.hpp" -#include "string_ref.hpp" -#include "string_buffer.hpp" - -namespace dena { - -struct hstcpcli_filter { - string_ref filter_type; - string_ref op; - size_t ff_offset; - string_ref val; - hstcpcli_filter() : ff_offset(0) { } -}; - -struct hstcpcli_i; -typedef hstcpcli_i *hstcpcli_ptr; - -struct hstresult { - hstresult(); - virtual ~hstresult(); - string_buffer readbuf; - size_t response_end_offset; - size_t num_flds; - size_t cur_row_offset; - size_t cur_row_size; - DYNAMIC_ARRAY flds; -}; - -struct hstcpcli_i { - virtual ~hstcpcli_i() { } - virtual void close() = 0; - virtual int reconnect() = 0; - virtual bool stable_point() = 0; - virtual void request_buf_auth(const char *secret, const char *typ) = 0; - virtual void request_buf_open_index(size_t pst_id, const char *dbn, - const char *tbl, const char *idx, const char *retflds, - const char *filflds = 0) = 0; - virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op, - const string_ref *kvs, size_t kvslen, uint32 limit, uint32 skip, - const string_ref& mod_op, const string_ref *mvs, size_t mvslen, - const hstcpcli_filter *fils = 0, size_t filslen = 0, - int invalues_keypart = -1, const string_ref *invalues = 0, - size_t invalueslen = 0) = 0; // FIXME: too long - virtual size_t request_buf_append(const char *start, const char *finish) = 0; - virtual void request_reset() = 0; - virtual int request_send() = 0; - virtual int response_recv(size_t& num_flds_r) = 0; - virtual int get_result(hstresult& result) = 0; - virtual const string_ref *get_next_row() = 0; - virtual const string_ref *get_next_row_from_result(hstresult& result) = 0; - virtual size_t get_row_size() = 0; - virtual size_t get_row_size_from_result(hstresult& result) = 0; - virtual void response_buf_remove() = 0; - virtual int get_error_code() = 0; - virtual String& get_error() = 0; - virtual void clear_error() = 0; - virtual int set_timeout(int send_timeout, int recv_timeout) = 0; - virtual size_t get_num_req_bufd() = 0; - virtual size_t get_num_req_sent() = 0; - virtual size_t get_num_req_rcvd() = 0; - virtual size_t get_response_end_offset() = 0; - virtual const char *get_readbuf_begin() = 0; - virtual const char *get_readbuf_end() = 0; - virtual const char *get_writebuf_begin() = 0; - virtual size_t get_writebuf_size() = 0; - virtual void write_error_to_log(const char *func_name, const char *file_name, - ulong line_no) = 0; - static hstcpcli_ptr create(const socket_args& args); -}; - -}; - -#endif - diff --git a/storage/spider/hs_client/mutex.hpp b/storage/spider/hs_client/mutex.hpp deleted file mode 100644 index 8e331fb6ab2..00000000000 --- a/storage/spider/hs_client/mutex.hpp +++ /dev/null @@ -1,48 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_MUTEX_HPP -#define DENA_MUTEX_HPP - -#include "fatal.hpp" -#include "util.hpp" - -namespace dena { - -struct condition; - -struct mutex : private noncopyable { - friend struct condition; - mutex() { - if (pthread_mutex_init(&mtx, 0) != 0) { - fatal_abort("pthread_mutex_init"); - } - } - ~mutex() { - if (pthread_mutex_destroy(&mtx) != 0) { - fatal_abort("pthread_mutex_destroy"); - } - } - void lock() const { - if (pthread_mutex_lock(&mtx) != 0) { - fatal_abort("pthread_mutex_lock"); - } - } - void unlock() const { - if (pthread_mutex_unlock(&mtx) != 0) { - fatal_abort("pthread_mutex_unlock"); - } - } - private: - mutable pthread_mutex_t mtx; -}; - -}; - -#endif - diff --git a/storage/spider/hs_client/socket.cpp b/storage/spider/hs_client/socket.cpp deleted file mode 100644 index 9a2ecddedd7..00000000000 --- a/storage/spider/hs_client/socket.cpp +++ /dev/null @@ -1,314 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#include <my_global.h> -#include <my_config.h> -#ifndef _WIN32 -#include <sys/types.h> -#include <sys/un.h> -#endif - -#include "mysql_version.h" -#include "hs_compat.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 -#include <my_global.h> -#endif -#include "sql_priv.h" -#include "probes_mysql.h" -#endif - -#include "socket.hpp" -#include "string_util.hpp" -#include "fatal.hpp" - -/* -struct sockaddr_un { - short sun_family; - char sun_path[108]; -}; -*/ - -namespace dena { - -void -ignore_sigpipe() -{ -#if defined(SIGPIPE) && !defined(_WIN32) - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { - fatal_abort("SIGPIPE SIG_IGN"); - } -#endif -} - -void -socket_args::set(const config& conf) -{ - timeout = (int) conf.get_int("timeout", 600); - listen_backlog = (int) conf.get_int("listen_backlog", 256); - String node = conf.get_str("host", ""); - String port = conf.get_str("port", ""); - if (node.length() || port.length()) { - if (family == AF_UNIX || !strcmp(node.c_ptr(), "/")) { - set_unix_domain(port.c_ptr()); - } else { - const char *nd = !node.length() ? 0 : node.c_ptr(); - if (resolve(nd, port.c_ptr()) != 0) { - String message(STRING_WITH_LEN("getaddrinfo failed: "), - &my_charset_bin); - message.reserve(node.length() + sizeof(":") - 1 + port.length()); - message.append(node); - message.q_append(":", sizeof(":") - 1); - message.append(port); - fatal_abort(message); - } - } - } - sndbuf = (int) conf.get_int("sndbuf", 0); - rcvbuf = (int) conf.get_int("rcvbuf", 0); -} - -void -socket_args::set_unix_domain(const char *path) -{ -#ifndef _WIN32 - family = AF_UNIX; - addr = sockaddr_storage(); - addrlen = sizeof(sockaddr_un); - sockaddr_un *const ap = reinterpret_cast<sockaddr_un *>(&addr); - ap->sun_family = AF_UNIX; - strncpy(ap->sun_path, path, sizeof(ap->sun_path) - 1); -#endif -} - -int -socket_args::resolve(const char *node, const char *service) -{ - const int flags = (node == 0) ? AI_PASSIVE : 0; - auto_addrinfo ai; - addr = sockaddr_storage(); - addrlen = 0; - const int r = ai.resolve(node, service, flags, family, socktype, protocol); - if (r != 0) { - return r; - } - memcpy(&addr, ai.get()->ai_addr, ai.get()->ai_addrlen); - addrlen = ai.get()->ai_addrlen; - return 0; -} - -int -socket_set_timeout(auto_file& fd, const socket_args& args, String& err_r) -{ - if (!args.nonblocking) { -#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) - if (args.recv_timeout != 0) { -#ifndef _WIN32 - struct timeval tv; - tv.tv_sec = args.recv_timeout; - tv.tv_usec = 0; -#else - int tv = args.recv_timeout * 1000; -#endif - if (setsockopt(fd.get(), SOL_SOCKET, SO_RCVTIMEO, -#ifndef _WIN32 - (const void *) &tv, -#else - (const char *) &tv, -#endif - sizeof(tv)) != 0) { - return errno_string("setsockopt SO_RCVTIMEO", errno, err_r); - } - } - if (args.send_timeout != 0) { -#ifndef _WIN32 - struct timeval tv; - tv.tv_sec = args.send_timeout; - tv.tv_usec = 0; -#else - int tv = args.send_timeout * 1000; -#endif - if (setsockopt(fd.get(), SOL_SOCKET, SO_SNDTIMEO, -#ifndef _WIN32 - (const void *) &tv, -#else - (const char *) &tv, -#endif - sizeof(tv)) != 0) { - return errno_string("setsockopt SO_SNDTIMEO", errno, err_r); - } - } -#endif - } - return 0; -} - -int -socket_set_options(auto_file& fd, const socket_args& args, String& err_r) -{ - if (args.timeout != 0 && !args.nonblocking) { -#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) -#ifndef _WIN32 - struct timeval tv; - tv.tv_sec = args.timeout; - tv.tv_usec = 0; -#else - int tv = args.timeout * 1000; -#endif - if (setsockopt(fd.get(), SOL_SOCKET, SO_RCVTIMEO, -#ifndef _WIN32 - (const void *) &tv, -#else - (const char *) &tv, -#endif - sizeof(tv)) != 0) { - return errno_string("setsockopt SO_RCVTIMEO", errno, err_r); - } -#ifndef _WIN32 - tv.tv_sec = args.timeout; - tv.tv_usec = 0; -#else - tv = args.timeout * 1000; -#endif - if (setsockopt(fd.get(), SOL_SOCKET, SO_SNDTIMEO, -#ifndef _WIN32 - (const void *) &tv, -#else - (const char *) &tv, -#endif - sizeof(tv)) != 0) { - return errno_string("setsockopt SO_RCVTIMEO", errno, err_r); - } -#endif - } -#ifndef _WIN32 - if (args.nonblocking && fcntl(fd.get(), F_SETFL, O_NONBLOCK) != 0) { - return errno_string("fcntl O_NONBLOCK", errno, err_r); - } -#endif - if (args.sndbuf != 0) { - const int v = args.sndbuf; - if (setsockopt(fd.get(), SOL_SOCKET, SO_SNDBUF, -#ifndef _WIN32 - (const void *) &v, -#else - (const char *) &v, -#endif - sizeof(v)) != 0) { - return errno_string("setsockopt SO_SNDBUF", errno, err_r); - } - } - if (args.rcvbuf != 0) { - const int v = args.rcvbuf; - if (setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, -#ifndef _WIN32 - (const void *) &v, -#else - (const char *) &v, -#endif - sizeof(v)) != 0) { - return errno_string("setsockopt SO_RCVBUF", errno, err_r); - } - } - return 0; -} - -int -socket_open(auto_file& fd, const socket_args& args, String& err_r) -{ - fd.reset((int) socket(args.family, args.socktype, args.protocol)); - if (fd.get() < 0) { - return errno_string("socket", errno, err_r); - } - return socket_set_options(fd, args, err_r); -} - -int -socket_connect(auto_file& fd, const socket_args& args, String& err_r) -{ - int r = 0; - if ((r = socket_open(fd, args, err_r)) != 0) { - return r; - } - if (connect(fd.get(), reinterpret_cast<const sockaddr *>(&args.addr), - args.addrlen) != 0) { - if (!args.nonblocking -#ifndef _WIN32 - || errno != EINPROGRESS -#endif - ) { - return errno_string("connect", errno, err_r); - } - } - return 0; -} - -int -socket_bind(auto_file& fd, const socket_args& args, String& err_r) -{ - fd.reset((int) socket(args.family, args.socktype, args.protocol)); - if (fd.get() < 0) { - return errno_string("socket", errno, err_r); - } - if (args.reuseaddr) { -#ifndef _WIN32 - if (args.family == AF_UNIX) { - const sockaddr_un *const ap = - reinterpret_cast<const sockaddr_un *>(&args.addr); - if (unlink(ap->sun_path) != 0 && errno != ENOENT) { - return errno_string("unlink uds", errno, err_r); - } - } else { -#endif - int v = 1; - if (setsockopt(fd.get(), SOL_SOCKET, SO_REUSEADDR, -#ifndef _WIN32 - (const void *) &v, -#else - (const char *) &v, -#endif - sizeof(v)) != 0) { - return errno_string("setsockopt SO_REUSEADDR", errno, err_r); - } -#ifndef _WIN32 - } -#endif - } - if (bind(fd.get(), reinterpret_cast<const sockaddr *>(&args.addr), - args.addrlen) != 0) { - return errno_string("bind", errno, err_r); - } - if (listen(fd.get(), args.listen_backlog) != 0) { - return errno_string("listen", errno, err_r); - } -#ifndef _WIN32 - if (args.nonblocking && fcntl(fd.get(), F_SETFL, O_NONBLOCK) != 0) { - return errno_string("fcntl O_NONBLOCK", errno, err_r); - } -#endif - return 0; -} - -int -socket_accept(int listen_fd, auto_file& fd, const socket_args& args, - sockaddr_storage& addr_r, socklen_t& addrlen_r, String& err_r) -{ - fd.reset((int) accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r), - &addrlen_r)); - if (fd.get() < 0) { - return errno_string("accept", errno, err_r); - } - return socket_set_options(fd, args, err_r); -} - -}; - diff --git a/storage/spider/hs_client/socket.hpp b/storage/spider/hs_client/socket.hpp deleted file mode 100644 index a3e6527a46d..00000000000 --- a/storage/spider/hs_client/socket.hpp +++ /dev/null @@ -1,62 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_SOCKET_HPP -#define DENA_SOCKET_HPP - -#include "mysql_version.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#endif - -#include "auto_addrinfo.hpp" -#include "auto_file.hpp" -#include "config.hpp" - -namespace dena { - -struct socket_args { - sockaddr_storage addr; - socklen_t addrlen; - int family; - int socktype; - int protocol; - int timeout; - int send_timeout; - int recv_timeout; - int listen_backlog; - bool reuseaddr; - bool nonblocking; - bool use_epoll; - int sndbuf; - int rcvbuf; - socket_args() : addr(), addrlen(0), family(AF_INET), socktype(SOCK_STREAM), - protocol(0), timeout(600), send_timeout(600), recv_timeout(600), - listen_backlog(256), reuseaddr(true), nonblocking(false), use_epoll(false), - sndbuf(0), rcvbuf(0) { } - void set(const config& conf); - void set_unix_domain(const char *path); - int resolve(const char *node, const char *service); -}; - -void ignore_sigpipe(); -int socket_set_timeout(auto_file& fd, const socket_args& args, String& err_r); -int socket_bind(auto_file& fd, const socket_args& args, String& err_r); -int socket_connect(auto_file& fd, const socket_args& args, String& err_r); -int socket_accept(int listen_fd, auto_file& fd, const socket_args& args, - sockaddr_storage& addr_r, socklen_t& addrlen_r, String& err_r); - -}; - -#endif - diff --git a/storage/spider/hs_client/string_buffer.hpp b/storage/spider/hs_client/string_buffer.hpp deleted file mode 100644 index c9a6074819b..00000000000 --- a/storage/spider/hs_client/string_buffer.hpp +++ /dev/null @@ -1,146 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_STRING_BUFFER_HPP -#define DENA_STRING_BUFFER_HPP - -/* -#include <stdlib.h> -#include <string.h> -*/ - -#include "util.hpp" -#include "allocator.hpp" -#include "fatal.hpp" - -namespace dena { - -struct string_buffer : private noncopyable { - string_buffer() : buffer(0), begin_offset(0), end_offset(0), alloc_size(0) { } - ~string_buffer() { - real_free(); - } - void real_free() { - if (alloc_size) { - DENA_FREE(buffer); - buffer = 0; - begin_offset = 0; - end_offset = 0; - alloc_size = 0; - } - } - size_t real_size() { - return alloc_size; - } - const char *begin() const { - return buffer + begin_offset; - } - const char *end() const { - return buffer + end_offset; - } - char *begin() { - return buffer + begin_offset; - } - char *end() { - return buffer + end_offset; - } - size_t size() const { - return end_offset - begin_offset; - } - void clear() { - begin_offset = end_offset = 0; - } - void resize(size_t len) { - if (size() < len) { - reserve(len); - memset(buffer + end_offset, 0, len - size()); - } - end_offset = begin_offset + len; - } - void reserve(size_t len) { - if (alloc_size >= begin_offset + len) { - return; - } - size_t asz = alloc_size; - while (asz < begin_offset + len) { - if (asz == 0) { - asz = 16; - } - const size_t asz_n = asz << 1; - if (asz_n < asz) { - fatal_abort("string_buffer::resize() overflow"); - } - asz = asz_n; - } - void *const p = DENA_REALLOC(buffer, asz); - if (p == 0) { - fatal_abort("string_buffer::resize() realloc"); - } - buffer = static_cast<char *>(p); - alloc_size = asz; - } - void erase_front(size_t len) { - if (len >= size()) { - clear(); - } else { - begin_offset += len; - } - } - char *make_space(size_t len) { - reserve(size() + len); - return buffer + end_offset; - } - void space_wrote(size_t len) { - len = len < alloc_size - end_offset ? len : alloc_size - end_offset; - end_offset += len; - } - template <size_t N> - void append_literal(const char (& str)[N]) { - append(str, str + N - 1); - } - void append(const char *start, const char *finish) { - const size_t len = finish - start; - reserve(size() + len); - memcpy(buffer + end_offset, start, len); - end_offset += len; - } - void append_2(const char *s1, const char *f1, const char *s2, - const char *f2) { - const size_t l1 = f1 - s1; - const size_t l2 = f2 - s2; - reserve(end_offset + l1 + l2); - memcpy(buffer + end_offset, s1, l1); - memcpy(buffer + end_offset + l1, s2, l2); - end_offset += l1 + l2; - } - void swap(string_buffer& sb) { - char *tmp_buffer = buffer; - size_t tmp_begin_offset = begin_offset; - size_t tmp_end_offset = end_offset; - size_t tmp_alloc_size = alloc_size; - buffer = sb.buffer; - begin_offset = sb.begin_offset; - end_offset = sb.end_offset; - alloc_size = sb.alloc_size; - sb.buffer = tmp_buffer; - sb.begin_offset = tmp_begin_offset; - sb.end_offset = tmp_end_offset; - sb.alloc_size = tmp_alloc_size; - } - private: - char *buffer; - size_t begin_offset; - size_t end_offset; - size_t alloc_size; -}; - -}; - -#endif - diff --git a/storage/spider/hs_client/string_ref.hpp b/storage/spider/hs_client/string_ref.hpp deleted file mode 100644 index 028c4146c73..00000000000 --- a/storage/spider/hs_client/string_ref.hpp +++ /dev/null @@ -1,106 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_STRING_REF_HPP -#define DENA_STRING_REF_HPP - -namespace dena { - -struct string_wref { - typedef char value_type; - char *begin() const { return start; } - char *end() const { return start + length; } - size_t size() const { return length; } - private: - char *start; - size_t length; - public: - string_wref(char *s = 0, size_t len = 0) : start(s), length(len) { } -}; - -struct string_ref { - typedef const char value_type; - const char *begin() const { return start; } - const char *end() const { return start + length; } - size_t size() const { return length; } - void set(const char *s, size_t len) { start = s; length = len; } - void set(const char *s, const char *f) { start = s; length = f - s; } - private: - const char *start; - size_t length; - public: - string_ref(const char *s = 0, size_t len = 0) : start(s), length(len) { } - string_ref(const char *s, const char *f) : start(s), length(f - s) { } - string_ref(const string_wref& w) : start(w.begin()), length(w.size()) { } -}; - -template <size_t N> inline bool -operator ==(const string_ref& x, const char (& y)[N]) { - return (x.size() == N - 1) && (::memcmp(x.begin(), y, N - 1) == 0); -} - -inline bool -operator ==(const string_ref& x, const string_ref& y) { - return (x.size() == y.size()) && - (::memcmp(x.begin(), y.begin(), x.size()) == 0); -} - -inline bool -operator !=(const string_ref& x, const string_ref& y) { - return (x.size() != y.size()) || - (::memcmp(x.begin(), y.begin(), x.size()) != 0); -} - -struct string_ref_list_wrap { - string_ref_list_wrap() { - if (SPD_INIT_DYNAMIC_ARRAY2(&string_ref_list, sizeof(string_ref), - NULL, 16, 16, MYF(MY_WME))) - string_ref_list_init = FALSE; - else - string_ref_list_init = TRUE; - } - virtual ~string_ref_list_wrap() { - if (string_ref_list_init) delete_dynamic(&string_ref_list); } - void clear() { - if (string_ref_list_init) string_ref_list.elements = 0; } - void push_back(string_ref &e) { - if (string_ref_list_init) insert_dynamic(&string_ref_list, (uchar*) &e); - return; } - size_t size() { - return string_ref_list_init ? string_ref_list.elements : 0; } - bool resize(size_t new_size) { - if (string_ref_list_init) { - if (string_ref_list.max_element < new_size && allocate_dynamic( - &string_ref_list, new_size)) return TRUE; - string_ref_list.elements = new_size; - return FALSE; - } - return TRUE; - } - bool empty() { - return string_ref_list_init ? string_ref_list.elements ? - FALSE : TRUE : TRUE; } - string_ref &operator [](size_t n) { - return ((string_ref *) (string_ref_list.buffer + - string_ref_list.size_of_element * n))[0]; } - bool string_ref_list_init; - DYNAMIC_ARRAY string_ref_list; -}; - -inline String * -q_append_str(String *str, const char *p) { - uint32 p_len = strlen(p); - if (str->reserve(p_len)) return NULL; - str->q_append(p, p_len); return str; -} - -}; - -#endif - diff --git a/storage/spider/hs_client/string_util.cpp b/storage/spider/hs_client/string_util.cpp deleted file mode 100644 index 39934148cb8..00000000000 --- a/storage/spider/hs_client/string_util.cpp +++ /dev/null @@ -1,207 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011-2017 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#include <my_global.h> -#include "mysql_version.h" -#include "hs_compat.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#endif - -#include "string_util.hpp" - -namespace dena { - -string_wref -get_token(char *& wp, char *wp_end, char delim) -{ - char *const wp_begin = wp; - char *const p = memchr_char(wp_begin, delim, wp_end - wp_begin); - if (p == 0) { - wp = wp_end; - return string_wref(wp_begin, wp_end - wp_begin); - } - wp = p + 1; - return string_wref(wp_begin, p - wp_begin); -} - -uint32 -atoi_uint32_nocheck(const char *start, const char *finish) -{ - uint32 v = 0; - for (; start != finish; ++start) { - const char c = *start; - if (c < '0' || c > '9') { - break; - } - v *= 10; - v += (uint32) (c - '0'); - } - return v; -} - -long long -atoll_nocheck(const char *start, const char *finish) -{ - long long v = 0; - bool negative = false; - if (start != finish) { - if (start[0] == '-') { - ++start; - negative = true; - } else if (start[0] == '+') { - ++start; - } - } - for (; start != finish; ++start) { - const char c = *start; - if (c < '0' || c > '9') { - break; - } - v *= 10; - if (negative) { - v -= (long long) (c - '0'); - } else { - v += (long long) (c - '0'); - } - } - return v; -} - -void -append_uint32(string_buffer& buf, uint32 v) -{ - char *const wp = buf.make_space(64); - const int len = snprintf(wp, 64, "%lu", static_cast<unsigned long>(v)); - if (len > 0) { - buf.space_wrote(len); - } -} - -/* -String * -to_stdstring(uint32 v) -{ - char buf[64]; - int str_len; - String *str; - str_len = snprintf(buf, sizeof(buf), "%lu", static_cast<unsigned long>(v)); - if ((str = new String(str_len + 1))) - str->q_append(buf, str_len); - return str; -} -*/ - -int -errno_string(const char *s, int en, String& err_r) -{ - char buf[64]; - int str_len; - str_len = snprintf(buf, sizeof(buf), "%s: %d", s, en); - if (!err_r.reserve(str_len + 1)) - err_r.q_append(buf, str_len); - return en; -} - -size_t -split(char delim, const string_ref& buf, string_ref *parts, - size_t parts_len) -{ - size_t i = 0; - const char *start = buf.begin(); - const char *const finish = buf.end(); - for (i = 0; i < parts_len; ++i) { - const char *const p = memchr_char(start, delim, finish - start); - if (p == 0) { - parts[i] = string_ref(start, finish - start); - ++i; - break; - } - parts[i] = string_ref(start, p - start); - start = p + 1; - } - const size_t r = i; - for (; i < parts_len; ++i) { - parts[i] = string_ref(); - } - return r; -} - -size_t -split(char delim, const string_wref& buf, string_wref *parts, - size_t parts_len) -{ - size_t i = 0; - char *start = buf.begin(); - char *const finish = buf.end(); - for (i = 0; i < parts_len; ++i) { - char *const p = memchr_char(start, delim, finish - start); - if (p == 0) { - parts[i] = string_wref(start, finish - start); - ++i; - break; - } - parts[i] = string_wref(start, p - start); - start = p + 1; - } - const size_t r = i; - for (; i < parts_len; ++i) { - parts[i] = string_wref(); - } - return r; -} - -size_t -split(char delim, const string_ref& buf, DYNAMIC_ARRAY& parts_r) -{ - size_t i = 0; - const char *start = buf.begin(); - const char *finish = buf.end(); - while (true) { - const char *p = memchr_char(start, delim, finish - start); - if (p == 0) { - string_ref param(start, finish - start); - insert_dynamic(&parts_r, (uchar *) ¶m); - break; - } - string_ref param(start, p - start); - insert_dynamic(&parts_r, (uchar *) ¶m); - start = p + 1; - } - const size_t r = i; - return r; -} - -size_t -split(char delim, const string_wref& buf, DYNAMIC_ARRAY& parts_r) -{ - size_t i = 0; - char *start = buf.begin(); - char *finish = buf.end(); - while (true) { - char *p = memchr_char(start, delim, finish - start); - if (p == 0) { - string_wref param(start, finish - start); - insert_dynamic(&parts_r, (uchar *) ¶m); - break; - } - string_wref param(start, p - start); - insert_dynamic(&parts_r, (uchar *) ¶m); - start = p + 1; - } - const size_t r = i; - return r; -} - -}; - diff --git a/storage/spider/hs_client/string_util.hpp b/storage/spider/hs_client/string_util.hpp deleted file mode 100644 index b886addecfb..00000000000 --- a/storage/spider/hs_client/string_util.hpp +++ /dev/null @@ -1,51 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_STRING_UTIL_HPP -#define DENA_STRING_UTIL_HPP - -#include "string_buffer.hpp" -#include "string_ref.hpp" - -namespace dena { - -inline const char * -memchr_char(const char *s, int c, size_t n) -{ - return static_cast<const char *>(memchr(s, c, n)); -} - -inline char * -memchr_char(char *s, int c, size_t n) -{ - return static_cast<char *>(memchr(s, c, n)); -} - -string_wref get_token(char *& wp, char *wp_end, char delim); -uint32 atoi_uint32_nocheck(const char *start, const char *finish); -/* -String *to_stdstring(uint32 v); -*/ -void append_uint32(string_buffer& buf, uint32 v); -long long atoll_nocheck(const char *start, const char *finish); - -int errno_string(const char *s, int en, String& err_r); - -size_t split(char delim, const string_ref& buf, string_ref *parts, - size_t parts_len); -size_t split(char delim, const string_wref& buf, string_wref *parts, - size_t parts_len); -size_t split(char delim, const string_ref& buf, - DYNAMIC_ARRAY& parts_r); -size_t split(char delim, const string_wref& buf, - DYNAMIC_ARRAY& parts_r); -}; - -#endif - diff --git a/storage/spider/hs_client/thread.hpp b/storage/spider/hs_client/thread.hpp deleted file mode 100644 index 79fba706a42..00000000000 --- a/storage/spider/hs_client/thread.hpp +++ /dev/null @@ -1,84 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. - * Copyright (C) 2011 Kentoku SHIBA - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_THREAD_HPP -#define DENA_THREAD_HPP - -#include "fatal.hpp" - -namespace dena { - -/* -template <typename T> -struct thread : private noncopyable { - template <typename Ta> thread(const Ta& arg, size_t stack_sz = 256 * 1024) - : obj(arg), thr(0), need_join(false), stack_size(stack_sz) { } - template <typename Ta0, typename Ta1> thread(const Ta0& a0, - volatile Ta1& a1, size_t stack_sz = 256 * 1024) - : obj(a0, a1), thr(0), need_join(false), stack_size(stack_sz) { } - ~thread() { - join(); - } - void start() { - if (!start_nothrow()) { - fatal_abort("thread::start"); - } - } - bool start_nothrow() { - if (need_join) { - return need_join; - } - void *const arg = this; - pthread_attr_t attr; - if (pthread_attr_init(&attr) != 0) { - fatal_abort("pthread_attr_init"); - } - if (pthread_attr_setstacksize(&attr, stack_size) != 0) { - fatal_abort("pthread_attr_setstacksize"); - } - const int r = pthread_create(&thr, &attr, thread_main, arg); - if (pthread_attr_destroy(&attr) != 0) { - fatal_abort("pthread_attr_destroy"); - } - if (r != 0) { - return need_join; - } - need_join = true; - return need_join; - } - void join() { - if (!need_join) { - return; - } - int e = 0; - if ((e = pthread_join(thr, 0)) != 0) { - fatal_abort("pthread_join"); - } - need_join = false; - } - T& operator *() { return obj; } - T *operator ->() { return &obj; } - private: - static void *thread_main(void *arg) { - thread *p = static_cast<thread *>(arg); - p->obj(); - return 0; - } - private: - T obj; - pthread_t thr; - bool need_join; - size_t stack_size; -}; -*/ - -}; - -#endif - diff --git a/storage/spider/hs_client/util.hpp b/storage/spider/hs_client/util.hpp deleted file mode 100644 index 93d78cc7dc0..00000000000 --- a/storage/spider/hs_client/util.hpp +++ /dev/null @@ -1,25 +0,0 @@ - -// vim:sw=2:ai - -/* - * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved. - * See COPYRIGHT.txt for details. - */ - -#ifndef DENA_UTIL_HPP -#define DENA_UTIL_HPP - -namespace dena { - -/* boost::noncopyable */ -struct noncopyable { - noncopyable() { } - private: - noncopyable(const noncopyable&); - noncopyable& operator =(const noncopyable&); -}; - -}; - -#endif - diff --git a/storage/spider/mysql-test/spider/bugfix/r/index.result b/storage/spider/mysql-test/spider/bugfix/r/index.result new file mode 100644 index 00000000000..2aa0b56ef06 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/index.result @@ -0,0 +1,105 @@ +for master_1 +connect master_1, localhost, root, , , $MASTER_1_MYPORT, $MASTER_1_MYSOCK; +connection master_1; +CALL mtr.add_suppression("unknown variable"); +SET SESSION sql_log_bin= 0; +INSTALL PLUGIN spider SONAME 'ha_spider'; +CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( +HOST 'localhost', +DATABASE 'auto_test_local', +USER 'root', +PASSWORD '', +SOCKET '$MASTER_1_MYSOCK' + ); +SET spider_internal_sql_log_off= 0; +SET spider_direct_order_limit= 10000; +SET spider_init_sql_alloc_size= 1; +Warnings: +Warning 1287 '@@spider_init_sql_alloc_size' is deprecated and will be removed in a future release +for child2 +for child3 +create database auto_test_local; +set spider_same_server_link= on; +# +# MDEV-27590 Auto-increment on Spider tables with DESC PK does not work properly +# +select @@spider_auto_increment_mode; +@@spider_auto_increment_mode +0 +create or replace table auto_test_local.t (id int primary key) engine=InnoDB; +create or replace table t_sp1 (id int auto_increment, primary key(id desc)) +engine=Spider COMMENT='wrapper "mysql", srv "s_1", table "t"'; +insert into t_sp1 () values (),(),(); +insert into t_sp1 () values (),(),(); +select * from t_sp1; +id +1 +2 +3 +4 +5 +6 +drop table t_sp1, auto_test_local.t; +# +# MDEV-27581 Wrong result with DESC key on partitioned Spider table +# +create table auto_test_local.t1 (a int primary key); +create table auto_test_local.t2 (a int primary key); +create table t (a int, primary key (a desc)) engine=spider +engine=spider comment='wrapper "mysql", srv "s_1"' +partition by range (a) +(partition p1 values less than (4) comment "table 't1'", +partition p2 values less than (maxvalue) comment "table 't2'"); +insert into t values (1),(2),(10),(11); +select * from t where a > 1 order by a; +a +2 +10 +11 +drop table t, auto_test_local.t1, auto_test_local.t2; +# +# MDEV-27617 HANDLER KEY > (x) does not work with DESC keys, Spider is affected and returns wrong results +# +create table auto_test_local.t (a int, b char(1), primary key(a desc)); +insert into auto_test_local.t VALUES (1,'f'),(2,'g'),(3,'j'), (4,'i'),(5,'h'); +create table ts (a int, b char(1), primary key(a desc)) +engine=spider comment='wrapper "mysql", srv "s_1", table "t"'; +set spider_use_handler=3; +Warnings: +Warning 1287 '@@spider_use_handler' is deprecated and will be removed in a future release +select a, b from ts where a > 0 and b = 'g' order by a; +a b +2 g +set spider_use_handler=default; +Warnings: +Warning 1287 '@@spider_use_handler' is deprecated and will be removed in a future release +select a, b from ts where a > 0 and b = 'g' order by a; +a b +2 g +drop table ts, auto_test_local.t; +drop database auto_test_local; +for master_1 +connection master_1; +DROP FUNCTION spider_flush_table_mon_cache; +DROP FUNCTION spider_copy_tables; +DROP FUNCTION spider_ping_table; +DROP FUNCTION spider_bg_direct_sql; +DROP FUNCTION spider_direct_sql; +UNINSTALL PLUGIN spider_wrapper_protocols; +UNINSTALL PLUGIN spider_alloc_mem; +UNINSTALL PLUGIN spider; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown +DROP TABLE IF EXISTS mysql.spider_xa; +DROP TABLE IF EXISTS mysql.spider_xa_member; +DROP TABLE IF EXISTS mysql.spider_xa_failed_log; +DROP TABLE IF EXISTS mysql.spider_tables; +DROP TABLE IF EXISTS mysql.spider_link_mon_servers; +DROP TABLE IF EXISTS mysql.spider_link_failed_log; +DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery; +DROP TABLE IF EXISTS mysql.spider_table_sts; +DROP TABLE IF EXISTS mysql.spider_table_crd; +DROP SERVER s_1; +disconnect master_1; +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/index.test b/storage/spider/mysql-test/spider/bugfix/t/index.test new file mode 100644 index 00000000000..5167e40e8c4 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/index.test @@ -0,0 +1,48 @@ +--source ../t/test_init.inc +create database auto_test_local; +set spider_same_server_link= on; + +--echo # +--echo # MDEV-27590 Auto-increment on Spider tables with DESC PK does not work properly +--echo # + +select @@spider_auto_increment_mode; +create or replace table auto_test_local.t (id int primary key) engine=InnoDB; +create or replace table t_sp1 (id int auto_increment, primary key(id desc)) +engine=Spider COMMENT='wrapper "mysql", srv "s_1", table "t"'; +insert into t_sp1 () values (),(),(); +insert into t_sp1 () values (),(),(); +select * from t_sp1; +drop table t_sp1, auto_test_local.t; + +--echo # +--echo # MDEV-27581 Wrong result with DESC key on partitioned Spider table +--echo # +create table auto_test_local.t1 (a int primary key); +create table auto_test_local.t2 (a int primary key); +create table t (a int, primary key (a desc)) engine=spider +engine=spider comment='wrapper "mysql", srv "s_1"' +partition by range (a) +(partition p1 values less than (4) comment "table 't1'", + partition p2 values less than (maxvalue) comment "table 't2'"); + +insert into t values (1),(2),(10),(11); +select * from t where a > 1 order by a; +drop table t, auto_test_local.t1, auto_test_local.t2; + +--echo # +--echo # MDEV-27617 HANDLER KEY > (x) does not work with DESC keys, Spider is affected and returns wrong results +--echo # + +create table auto_test_local.t (a int, b char(1), primary key(a desc)); +insert into auto_test_local.t VALUES (1,'f'),(2,'g'),(3,'j'), (4,'i'),(5,'h'); +create table ts (a int, b char(1), primary key(a desc)) +engine=spider comment='wrapper "mysql", srv "s_1", table "t"'; +set spider_use_handler=3; +select a, b from ts where a > 0 and b = 'g' order by a; +set spider_use_handler=default; +select a, b from ts where a > 0 and b = 'g' order by a; +drop table ts, auto_test_local.t; + +drop database auto_test_local; +--source ../t/test_deinit.inc diff --git a/storage/spider/mysql-test/spider/feature/r/engine_defined_attributes.result b/storage/spider/mysql-test/spider/feature/r/engine_defined_attributes.result new file mode 100644 index 00000000000..c772ecf797a --- /dev/null +++ b/storage/spider/mysql-test/spider/feature/r/engine_defined_attributes.result @@ -0,0 +1,236 @@ +# +# MDEV-27106 Spider: specify connection to data node by engine-defined attributes +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +connection child2_2; +CREATE DATABASE auto_test_remote2; +USE auto_test_remote2; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +# Single data node +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a"; +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +3 ccc +4 ddd +DELETE FROM tbl_a; +DROP TABLE tbl_a; +# Multiple data nodes with high availability setting +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +REMOTE_SERVER="s_2_1 s_2_2" REMOTE_TABLE="tbl_a"; +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +3 ccc +4 ddd +connection child2_1; +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +3 ccc +4 ddd +connection child2_2; +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +3 ccc +4 ddd +connection master_1; +DELETE FROM tbl_a; +DROP TABLE tbl_a; +# Multiple data nodes with partition options +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +PARTITION BY RANGE (a) ( +PARTITION p1 VALUES LESS THAN (3) REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a", +PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" REMOTE_TABLE="tbl_a" +); +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +3 ccc +4 ddd +DELETE FROM tbl_a; +DROP TABLE tbl_a; +# Multiple data nodes with table options + partition options +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a" +PARTITION BY RANGE (a) ( +PARTITION p1 VALUES LESS THAN (3), +PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" +); +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +3 ccc +4 ddd +connection child2_1; +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +connection master_1; +DELETE FROM tbl_a; +DROP TABLE tbl_a; +# COMMENT + engine-defined option +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +COMMENT='tbl "tbl_a"' +PARTITION BY RANGE (a) ( +PARTITION p1 VALUES LESS THAN (3) COMMENT='srv "s_2_1"', +PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" +); +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +3 ccc +4 ddd +connection child2_1; +SELECT * FROM tbl_a; +a b +1 aaa +2 bbb +connection master_1; +DELETE FROM tbl_a; +DROP TABLE tbl_a; +# COMMENT + engine-defined option (invalid) +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a" COMMENT='tbl "tbl_b"'; +ERROR HY000: Can't create table `auto_test_local`.`tbl_a` (errno: 12501 "Unknown error 12501") +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +COMMENT='srv "s_2_1"' REMOTE_TABLE="tbl_a" +PARTITION BY RANGE (a) ( +PARTITION p1 VALUES LESS THAN (3), +PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" +); +ERROR HY000: Can't create table `auto_test_local`.`tbl_a` (errno: 12501 "Unknown error 12501") +# Various combinations of COMMENTs and options +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +REMOTE_SERVER="s_2_1" REMOTE_DATABASE="auto_test_remote" REMOTE_TABLE="tbl_a"; +SELECT * FROM tbl_a; +a b +DROP TABLE tbl_a; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +REMOTE_TABLE="tbl_a" +PARTITION BY RANGE (a) ( +PARTITION p1 VALUES LESS THAN (3) +REMOTE_SERVER="s_2_1" COMMENT='database "auto_test_remote"', +PARTITION p2 VALUES LESS THAN MAXVALUE +REMOTE_SERVER="s_2_2" REMOTE_DATABASE="auto_test_remote2" +); +SELECT * FROM tbl_a; +a b +DROP TABLE tbl_a; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(255), +PRIMARY KEY(a) +) ENGINE=Spider DEFAULT CHARSET=utf8 +COMMENT='tbl "tbl_a"' +PARTITION BY RANGE (a) ( +PARTITION p1 VALUES LESS THAN (3) +REMOTE_SERVER="s_2_1" REMOTE_DATABASE="auto_test_remote", +PARTITION p2 VALUES LESS THAN MAXVALUE +REMOTE_SERVER="s_2_2" REMOTE_DATABASE="auto_test_remote2" +); +SELECT * FROM tbl_a; +a b +DROP TABLE tbl_a; +CREATE TABLE tbl_a ( +a INT +) ENGINE=Spider DEFAULT CHARSET=utf8 +PARTITION BY HASH (a) PARTITIONS 2; +SELECT * FROM tbl_a; +ERROR HY000: Unable to connect to foreign data source: localhost +DROP TABLE tbl_a; +# MDEV-27860 SIGSEGV in spider_parse_connect_info on CREATE TABLE +CREATE TABLE tbl_a ENGINE=SPIDER COMMENT="TABLE 'unknown_table'" +PARTITION BY LIST COLUMNS (c) ( +PARTITION p DEFAULT COMMENT="srv 'unknown_server'" ENGINE=SPIDER +); +ERROR HY000: The foreign server name you are trying to reference does not exist. Data source error: unknown_server +connection child2_1; +DROP DATABASE auto_test_remote; +connection child2_2; +DROP DATABASE auto_test_remote2; +connection master_1; +DROP DATABASE auto_test_local; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/feature/t/engine_defined_attributes.cnf b/storage/spider/mysql-test/spider/feature/t/engine_defined_attributes.cnf new file mode 100644 index 00000000000..e0ffb99c38e --- /dev/null +++ b/storage/spider/mysql-test/spider/feature/t/engine_defined_attributes.cnf @@ -0,0 +1,4 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf +!include ../my_2_2.cnf diff --git a/storage/spider/mysql-test/spider/feature/t/engine_defined_attributes.test b/storage/spider/mysql-test/spider/feature/t/engine_defined_attributes.test new file mode 100644 index 00000000000..0d5c849045f --- /dev/null +++ b/storage/spider/mysql-test/spider/feature/t/engine_defined_attributes.test @@ -0,0 +1,227 @@ +--echo # +--echo # MDEV-27106 Spider: specify connection to data node by engine-defined attributes +--echo # + +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +--connection child2_2 +CREATE DATABASE auto_test_remote2; +USE auto_test_remote2; +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +--echo # Single data node +--connection master_1 +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a"; + +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; + +DELETE FROM tbl_a; +DROP TABLE tbl_a; + +--echo # Multiple data nodes with high availability setting +--connection master_1 +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +REMOTE_SERVER="s_2_1 s_2_2" REMOTE_TABLE="tbl_a"; + +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; + +--connection child2_1 +SELECT * FROM tbl_a; + +--connection child2_2 +SELECT * FROM tbl_a; + +--connection master_1 +DELETE FROM tbl_a; +DROP TABLE tbl_a; + +--echo # Multiple data nodes with partition options +--connection master_1 +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +PARTITION BY RANGE (a) ( + PARTITION p1 VALUES LESS THAN (3) REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a", + PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" REMOTE_TABLE="tbl_a" +); + +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; + +DELETE FROM tbl_a; +DROP TABLE tbl_a; + +--echo # Multiple data nodes with table options + partition options +--connection master_1 +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a" +PARTITION BY RANGE (a) ( + PARTITION p1 VALUES LESS THAN (3), + PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" +); + +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; + +--connection child2_1 +SELECT * FROM tbl_a; + +--connection master_1 +DELETE FROM tbl_a; +DROP TABLE tbl_a; + +--echo # COMMENT + engine-defined option +--connection master_1 +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +COMMENT='tbl "tbl_a"' +PARTITION BY RANGE (a) ( + PARTITION p1 VALUES LESS THAN (3) COMMENT='srv "s_2_1"', + PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" +); + +INSERT INTO tbl_a VALUES (1, "aaa"), (2, "bbb"), (3, "ccc"), (4, "ddd"); +SELECT * FROM tbl_a; + +--connection child2_1 +SELECT * FROM tbl_a; + +--connection master_1 +DELETE FROM tbl_a; +DROP TABLE tbl_a; + +--echo # COMMENT + engine-defined option (invalid) +--connection master_1 + +--replace_result error: error +--error ER_CANT_CREATE_TABLE +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +REMOTE_SERVER="s_2_1" REMOTE_TABLE="tbl_a" COMMENT='tbl "tbl_b"'; + +--replace_result error: error +--error ER_CANT_CREATE_TABLE +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +COMMENT='srv "s_2_1"' REMOTE_TABLE="tbl_a" +PARTITION BY RANGE (a) ( + PARTITION p1 VALUES LESS THAN (3), + PARTITION p2 VALUES LESS THAN MAXVALUE REMOTE_SERVER="s_2_2" +); + +--echo # Various combinations of COMMENTs and options +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +REMOTE_SERVER="s_2_1" REMOTE_DATABASE="auto_test_remote" REMOTE_TABLE="tbl_a"; +SELECT * FROM tbl_a; +DROP TABLE tbl_a; + +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +REMOTE_TABLE="tbl_a" +PARTITION BY RANGE (a) ( + PARTITION p1 VALUES LESS THAN (3) + REMOTE_SERVER="s_2_1" COMMENT='database "auto_test_remote"', + PARTITION p2 VALUES LESS THAN MAXVALUE + REMOTE_SERVER="s_2_2" REMOTE_DATABASE="auto_test_remote2" +); +SELECT * FROM tbl_a; +DROP TABLE tbl_a; + +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(255), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +COMMENT='tbl "tbl_a"' +PARTITION BY RANGE (a) ( + PARTITION p1 VALUES LESS THAN (3) + REMOTE_SERVER="s_2_1" REMOTE_DATABASE="auto_test_remote", + PARTITION p2 VALUES LESS THAN MAXVALUE + REMOTE_SERVER="s_2_2" REMOTE_DATABASE="auto_test_remote2" +); +SELECT * FROM tbl_a; +DROP TABLE tbl_a; + +eval CREATE TABLE tbl_a ( + a INT +) $MASTER_1_ENGINE $MASTER_1_CHARSET +PARTITION BY HASH (a) PARTITIONS 2; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +SELECT * FROM tbl_a; +DROP TABLE tbl_a; + +--echo # MDEV-27860 SIGSEGV in spider_parse_connect_info on CREATE TABLE +--error ER_FOREIGN_SERVER_DOESNT_EXIST +CREATE TABLE tbl_a ENGINE=SPIDER COMMENT="TABLE 'unknown_table'" +PARTITION BY LIST COLUMNS (c) ( + PARTITION p DEFAULT COMMENT="srv 'unknown_server'" ENGINE=SPIDER +); + +--connection child2_1 +DROP DATABASE auto_test_remote; + +--connection child2_2 +DROP DATABASE auto_test_remote2; + +--connection master_1 +DROP DATABASE auto_test_local; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/include/init_spider.inc b/storage/spider/mysql-test/spider/include/init_spider.inc index b3fb4df239b..b4ce7c8f035 100644 --- a/storage/spider/mysql-test/spider/include/init_spider.inc +++ b/storage/spider/mysql-test/spider/include/init_spider.inc @@ -2,10 +2,10 @@ let $VERSION_COMPILE_OS_WIN= `SELECT IF(@@version_compile_os like 'Win%', 1, 0)`; if ($VERSION_COMPILE_OS_WIN) { - INSTALL PLUGIN spider SONAME 'ha_spider.dll'; + INSTALL PLUGIN spider SONAME 'ha_spider'; if ($MASTER_1_MYPORT) { - eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', @@ -15,7 +15,7 @@ if ($VERSION_COMPILE_OS_WIN) } if ($CHILD2_1_MYPORT) { - eval CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_remote', USER 'root', @@ -25,7 +25,7 @@ if ($VERSION_COMPILE_OS_WIN) } if ($CHILD2_2_MYPORT) { - eval CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_remote2', USER 'root', @@ -35,7 +35,7 @@ if ($VERSION_COMPILE_OS_WIN) } if ($CHILD2_3_MYPORT) { - eval CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_remote3', USER 'root', @@ -45,7 +45,7 @@ if ($VERSION_COMPILE_OS_WIN) } if ($CHILD3_1_MYPORT) { - eval CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', @@ -55,7 +55,7 @@ if ($VERSION_COMPILE_OS_WIN) } if ($CHILD3_2_MYPORT) { - eval CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', @@ -65,7 +65,7 @@ if ($VERSION_COMPILE_OS_WIN) } if ($CHILD2_3_MYPORT) { - eval CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', @@ -76,10 +76,10 @@ if ($VERSION_COMPILE_OS_WIN) } if (!$VERSION_COMPILE_OS_WIN) { - INSTALL PLUGIN spider SONAME 'ha_spider.so'; + INSTALL PLUGIN spider SONAME 'ha_spider'; if ($MASTER_1_MYSOCK) { - eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', @@ -89,7 +89,7 @@ if (!$VERSION_COMPILE_OS_WIN) } if ($CHILD2_1_MYSOCK) { - eval CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_remote', USER 'root', @@ -99,7 +99,7 @@ if (!$VERSION_COMPILE_OS_WIN) } if ($CHILD2_2_MYSOCK) { - eval CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_remote2', USER 'root', @@ -109,7 +109,7 @@ if (!$VERSION_COMPILE_OS_WIN) } if ($CHILD2_3_MYSOCK) { - eval CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_remote3', USER 'root', @@ -119,7 +119,7 @@ if (!$VERSION_COMPILE_OS_WIN) } if ($CHILD3_1_MYSOCK) { - eval CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', @@ -129,7 +129,7 @@ if (!$VERSION_COMPILE_OS_WIN) } if ($CHILD3_2_MYSOCK) { - eval CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', @@ -139,7 +139,7 @@ if (!$VERSION_COMPILE_OS_WIN) } if ($CHILD3_3_MYSOCK) { - eval CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS ( + evalp CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS ( HOST 'localhost', DATABASE 'auto_test_local', USER 'root', diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index 2f1711ad59e..9b040384cd6 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -108,20 +108,6 @@ const char *spider_open_connections_func_name; const char *spider_open_connections_file_name; ulong spider_open_connections_line_no; pthread_mutex_t spider_conn_mutex; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -HASH spider_hs_r_conn_hash; -uint spider_hs_r_conn_hash_id; -const char *spider_hs_r_conn_hash_func_name; -const char *spider_hs_r_conn_hash_file_name; -ulong spider_hs_r_conn_hash_line_no; -pthread_mutex_t spider_hs_r_conn_mutex; -HASH spider_hs_w_conn_hash; -uint spider_hs_w_conn_hash_id; -const char *spider_hs_w_conn_hash_func_name; -const char *spider_hs_w_conn_hash_file_name; -ulong spider_hs_w_conn_hash_line_no; -pthread_mutex_t spider_hs_w_conn_mutex; -#endif /* for spider_open_connections and trx_conn_hash */ uchar *spider_conn_get_key( @@ -320,10 +306,6 @@ void spider_free_conn_from_trx( spider_conn_clear_queue(conn); conn->use_for_active_standby = FALSE; conn->error_mode = 1; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif if ( trx_free || ( @@ -422,134 +404,6 @@ void spider_free_conn_from_trx( } } else if (roop_count) (*roop_count)++; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn->conn_kind == SPIDER_CONN_KIND_HS_READ) - { - spider_db_hs_request_buf_reset(conn); - if ( - trx_free || - ( - ( - conn->server_lost || - spider_param_hs_r_conn_recycle_mode(trx->thd) != 2 - ) && - !conn->opened_handlers - ) - ) { - conn->thd = NULL; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&trx->trx_hs_r_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&trx->trx_hs_r_conn_hash, (uchar*) conn); -#endif - - DBUG_ASSERT(conn->opened_handlers == - conn->db_conn->get_opened_handler_count()); - if (conn->db_conn->get_opened_handler_count()) - { - conn->db_conn->reset_opened_handler(); - } - - if ( - !trx_free && - !conn->server_lost && - !conn->queued_connect && - spider_param_hs_r_conn_recycle_mode(trx->thd) == 1 - ) { - /* conn_recycle_mode == 1 */ - *conn->conn_key = '0'; - pthread_mutex_lock(&spider_hs_r_conn_mutex); - uint old_elements = spider_hs_r_conn_hash.array.max_element; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - if (my_hash_insert_with_hash_value(&spider_hs_r_conn_hash, - conn->conn_key_hash_value, (uchar*) conn)) -#else - if (my_hash_insert(&spider_hs_r_conn_hash, (uchar*) conn)) -#endif - { - pthread_mutex_unlock(&spider_hs_r_conn_mutex); - spider_free_conn(conn); - } else { - if (spider_hs_r_conn_hash.array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - spider_hs_r_conn_hash, - (spider_hs_r_conn_hash.array.max_element - old_elements) * - spider_hs_r_conn_hash.array.size_of_element); - } - pthread_mutex_unlock(&spider_hs_r_conn_mutex); - } - } else { - /* conn_recycle_mode == 0 */ - spider_free_conn(conn); - } - } else if (roop_count) - (*roop_count)++; - } else { - spider_db_hs_request_buf_reset(conn); - if ( - trx_free || - ( - ( - conn->server_lost || - spider_param_hs_w_conn_recycle_mode(trx->thd) != 2 - ) && - !conn->opened_handlers - ) - ) { - conn->thd = NULL; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&trx->trx_hs_w_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&trx->trx_hs_w_conn_hash, (uchar*) conn); -#endif - - DBUG_ASSERT(conn->opened_handlers == - conn->db_conn->get_opened_handler_count()); - if (conn->db_conn->get_opened_handler_count()) - { - conn->db_conn->reset_opened_handler(); - } - - if ( - !trx_free && - !conn->server_lost && - !conn->queued_connect && - spider_param_hs_w_conn_recycle_mode(trx->thd) == 1 - ) { - /* conn_recycle_mode == 1 */ - *conn->conn_key = '0'; - pthread_mutex_lock(&spider_hs_w_conn_mutex); - uint old_elements = spider_hs_w_conn_hash.array.max_element; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - if (my_hash_insert_with_hash_value(&spider_hs_w_conn_hash, - conn->conn_key_hash_value, (uchar*) conn)) -#else - if (my_hash_insert(&spider_hs_w_conn_hash, (uchar*) conn)) -#endif - { - pthread_mutex_unlock(&spider_hs_w_conn_mutex); - spider_free_conn(conn); - } else { - if (spider_hs_w_conn_hash.array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - spider_hs_w_conn_hash, - (spider_hs_w_conn_hash.array.max_element - old_elements) * - spider_hs_w_conn_hash.array.size_of_element); - } - pthread_mutex_unlock(&spider_hs_w_conn_mutex); - } - } else { - /* conn_recycle_mode == 0 */ - spider_free_conn(conn); - } - } else if (roop_count) - (*roop_count)++; - } -#endif DBUG_VOID_RETURN; } @@ -577,10 +431,6 @@ SPIDER_CONN *spider_create_conn( UTC = my_tz_find(current_thd, &tz_00_name); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif bool tables_on_different_db_are_joinable; if (share->sql_dbton_ids[link_idx] != SPIDER_DBTON_SIZE) { @@ -752,113 +602,13 @@ SPIDER_CONN *spider_create_conn( conn->tgt_port = share->tgt_ports[link_idx]; conn->tgt_ssl_vsc = share->tgt_ssl_vscs[link_idx]; conn->dbton_id = share->sql_dbton_ids[link_idx]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn_kind == SPIDER_CONN_KIND_HS_READ) { - if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 19, MYF(MY_WME | MY_ZEROFILL), - &conn, (uint) (sizeof(*conn)), - &tmp_name, (uint) (share->hs_read_conn_keys_lengths[link_idx] + 1), - &tmp_host, (uint) (share->tgt_hosts_lengths[link_idx] + 1), - &tmp_socket, (uint) (share->hs_read_socks_lengths[link_idx] + 1), - &tmp_wrapper, - (uint) (share->tgt_wrappers_lengths[link_idx] + 1), - &need_mon, (uint) (sizeof(int)), - NullS)) - ) { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_alloc_conn; - } - - conn->default_database.init_calc_mem(76); - conn->conn_key_length = share->hs_read_conn_keys_lengths[link_idx]; - conn->conn_key = tmp_name; - memcpy(conn->conn_key, share->hs_read_conn_keys[link_idx], - share->hs_read_conn_keys_lengths[link_idx]); -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - conn->conn_key_hash_value = share->hs_read_conn_keys_hash_value[link_idx]; -#endif - conn->tgt_host_length = share->tgt_hosts_lengths[link_idx]; - conn->tgt_host = tmp_host; - memcpy(conn->tgt_host, share->tgt_hosts[link_idx], - share->tgt_hosts_lengths[link_idx]); - conn->hs_sock_length = share->hs_read_socks_lengths[link_idx]; - if (conn->hs_sock_length) - { - conn->hs_sock = tmp_socket; - memcpy(conn->hs_sock, share->hs_read_socks[link_idx], - share->hs_read_socks_lengths[link_idx]); - } else - conn->hs_sock = NULL; - conn->tgt_wrapper_length = share->tgt_wrappers_lengths[link_idx]; - conn->tgt_wrapper = tmp_wrapper; - memcpy(conn->tgt_wrapper, share->tgt_wrappers[link_idx], - share->tgt_wrappers_lengths[link_idx]); - conn->hs_port = share->hs_read_ports[link_idx]; - conn->dbton_id = share->hs_dbton_ids[link_idx]; - } else { - if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 20, MYF(MY_WME | MY_ZEROFILL), - &conn, (uint) (sizeof(*conn)), - &tmp_name, (uint) (share->hs_write_conn_keys_lengths[link_idx] + 1), - &tmp_host, (uint) (share->tgt_hosts_lengths[link_idx] + 1), - &tmp_socket, (uint) (share->hs_write_socks_lengths[link_idx] + 1), - &tmp_wrapper, - (uint) (share->tgt_wrappers_lengths[link_idx] + 1), - &need_mon, (uint) (sizeof(int)), - NullS)) - ) { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_alloc_conn; - } - - conn->default_database.init_calc_mem(77); - conn->conn_key_length = share->hs_write_conn_keys_lengths[link_idx]; - conn->conn_key = tmp_name; - memcpy(conn->conn_key, share->hs_write_conn_keys[link_idx], - share->hs_write_conn_keys_lengths[link_idx]); -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - conn->conn_key_hash_value = share->hs_write_conn_keys_hash_value[link_idx]; -#endif - conn->tgt_host_length = share->tgt_hosts_lengths[link_idx]; - conn->tgt_host = tmp_host; - memcpy(conn->tgt_host, share->tgt_hosts[link_idx], - share->tgt_hosts_lengths[link_idx]); - conn->hs_sock_length = share->hs_write_socks_lengths[link_idx]; - if (conn->hs_sock_length) - { - conn->hs_sock = tmp_socket; - memcpy(conn->hs_sock, share->hs_write_socks[link_idx], - share->hs_write_socks_lengths[link_idx]); - } else - conn->hs_sock = NULL; - conn->tgt_wrapper_length = share->tgt_wrappers_lengths[link_idx]; - conn->tgt_wrapper = tmp_wrapper; - memcpy(conn->tgt_wrapper, share->tgt_wrappers[link_idx], - share->tgt_wrappers_lengths[link_idx]); - conn->hs_port = share->hs_write_ports[link_idx]; - conn->dbton_id = share->hs_dbton_ids[link_idx]; - } -#endif if (conn->dbton_id == SPIDER_DBTON_SIZE) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif my_printf_error( ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM, ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR, MYF(0), conn->tgt_wrapper); *error_num = ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - my_printf_error( - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM, - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR, - MYF(0), conn->tgt_wrapper); - *error_num = ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM; - } -#endif goto error_invalid_wrapper; } if (!(conn->db_conn = spider_dbton[conn->dbton_id].create_db_conn(conn))) @@ -986,33 +736,11 @@ SPIDER_CONN *spider_get_conn( DBUG_PRINT("info",("spider link_idx=%u", link_idx)); DBUG_PRINT("info",("spider base_link_idx=%u", base_link_idx)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif #ifndef DBUG_OFF spider_print_keys(conn_key, share->conn_keys_lengths[link_idx]); #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn_kind == SPIDER_CONN_KIND_HS_READ) - { - conn_key = share->hs_read_conn_keys[link_idx]; -#ifndef DBUG_OFF - spider_print_keys(conn_key, share->hs_read_conn_keys_lengths[link_idx]); -#endif - } else { - conn_key = share->hs_write_conn_keys[link_idx]; -#ifndef DBUG_OFF - spider_print_keys(conn_key, share->hs_write_conn_keys_lengths[link_idx]); -#endif - } -#endif #ifdef SPIDER_HAS_HASH_VALUE_TYPE if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (conn_kind == SPIDER_CONN_KIND_MYSQL && - ( -#endif (another && !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( &trx->trx_another_conn_hash, @@ -1023,79 +751,25 @@ SPIDER_CONN *spider_get_conn( &trx->trx_conn_hash, share->conn_keys_hash_value[link_idx], (uchar*) conn_key, share->conn_keys_lengths[link_idx]))) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) - ) || - (conn_kind == SPIDER_CONN_KIND_HS_READ && - !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( - &trx->trx_hs_r_conn_hash, - share->hs_read_conn_keys_hash_value[link_idx], - (uchar*) conn_key, share->hs_read_conn_keys_lengths[link_idx])) - ) || - (conn_kind == SPIDER_CONN_KIND_HS_WRITE && - !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( - &trx->trx_hs_w_conn_hash, - share->hs_write_conn_keys_hash_value[link_idx], - (uchar*) conn_key, share->hs_write_conn_keys_lengths[link_idx])) - ) -#endif ) #else if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (conn_kind == SPIDER_CONN_KIND_MYSQL && - ( -#endif (another && !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_another_conn_hash, (uchar*) conn_key, share->conn_keys_lengths[link_idx]))) || (!another && !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_conn_hash, (uchar*) conn_key, share->conn_keys_lengths[link_idx]))) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) - ) || - (conn_kind == SPIDER_CONN_KIND_HS_READ && - !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_hs_r_conn_hash, - (uchar*) conn_key, share->hs_read_conn_keys_lengths[link_idx])) - ) || - (conn_kind == SPIDER_CONN_KIND_HS_WRITE && - !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_hs_w_conn_hash, - (uchar*) conn_key, share->hs_write_conn_keys_lengths[link_idx])) - ) -#endif ) #endif { if ( !trx->thd || -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (conn_kind == SPIDER_CONN_KIND_MYSQL && -#endif ( (spider_param_conn_recycle_mode(trx->thd) & 1) || spider_param_conn_recycle_strict(trx->thd) ) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) || - (conn_kind == SPIDER_CONN_KIND_HS_READ && - ( - (spider_param_hs_r_conn_recycle_mode(trx->thd) & 1) || - spider_param_hs_r_conn_recycle_strict(trx->thd) - ) - ) || - (conn_kind == SPIDER_CONN_KIND_HS_WRITE && - ( - (spider_param_hs_w_conn_recycle_mode(trx->thd) & 1) || - spider_param_hs_w_conn_recycle_strict(trx->thd) - ) - ) -#endif ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif pthread_mutex_lock(&spider_conn_mutex); #ifdef SPIDER_HAS_HASH_VALUE_TYPE if (!(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( @@ -1147,94 +821,6 @@ SPIDER_CONN *spider_get_conn( conn->use_for_active_standby = TRUE; } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn_kind == SPIDER_CONN_KIND_HS_READ) - { - pthread_mutex_lock(&spider_hs_r_conn_mutex); -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - if (!(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( - &spider_hs_r_conn_hash, - share->hs_read_conn_keys_hash_value[link_idx], - (uchar*) share->hs_read_conn_keys[link_idx], - share->hs_read_conn_keys_lengths[link_idx]))) -#else - if (!(conn = (SPIDER_CONN*) my_hash_search(&spider_hs_r_conn_hash, - (uchar*) share->hs_read_conn_keys[link_idx], - share->hs_read_conn_keys_lengths[link_idx]))) -#endif - { - pthread_mutex_unlock(&spider_hs_r_conn_mutex); - DBUG_PRINT("info",("spider create new hs r conn")); - if (!(conn = spider_create_conn(share, spider, link_idx, - base_link_idx, conn_kind, error_num))) - goto error; - *conn->conn_key = *conn_key; - if (spider) - { - spider->hs_r_conns[base_link_idx] = conn; - if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) - conn->use_for_active_standby = TRUE; - } - } else { -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&spider_hs_r_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&spider_hs_r_conn_hash, (uchar*) conn); -#endif - pthread_mutex_unlock(&spider_hs_r_conn_mutex); - DBUG_PRINT("info",("spider get global hs r conn")); - if (spider) - { - spider->hs_r_conns[base_link_idx] = conn; - if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) - conn->use_for_active_standby = TRUE; - } - } - } else { - pthread_mutex_lock(&spider_hs_w_conn_mutex); -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - if (!(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( - &spider_hs_w_conn_hash, - share->hs_write_conn_keys_hash_value[link_idx], - (uchar*) share->hs_write_conn_keys[link_idx], - share->hs_write_conn_keys_lengths[link_idx]))) -#else - if (!(conn = (SPIDER_CONN*) my_hash_search(&spider_hs_w_conn_hash, - (uchar*) share->hs_write_conn_keys[link_idx], - share->hs_write_conn_keys_lengths[link_idx]))) -#endif - { - pthread_mutex_unlock(&spider_hs_w_conn_mutex); - DBUG_PRINT("info",("spider create new hs w conn")); - if (!(conn = spider_create_conn(share, spider, link_idx, - base_link_idx, conn_kind, error_num))) - goto error; - *conn->conn_key = *conn_key; - if (spider) - { - spider->hs_w_conns[base_link_idx] = conn; - if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) - conn->use_for_active_standby = TRUE; - } - } else { -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&spider_hs_w_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&spider_hs_w_conn_hash, (uchar*) conn); -#endif - pthread_mutex_unlock(&spider_hs_w_conn_mutex); - DBUG_PRINT("info",("spider get global hs w conn")); - if (spider) - { - spider->hs_w_conns[base_link_idx] = conn; - if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) - conn->use_for_active_standby = TRUE; - } - } - } -#endif } else { DBUG_PRINT("info",("spider create new conn")); /* conn_recycle_strict = 0 and conn_recycle_mode = 0 or 2 */ @@ -1244,19 +830,7 @@ SPIDER_CONN *spider_get_conn( *conn->conn_key = *conn_key; if (spider) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif spider->conns[base_link_idx] = conn; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn_kind == SPIDER_CONN_KIND_HS_READ) - { - spider->hs_r_conns[base_link_idx] = conn; - } else { - spider->hs_w_conns[base_link_idx] = conn; - } -#endif if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) conn->use_for_active_standby = TRUE; } @@ -1264,10 +838,6 @@ SPIDER_CONN *spider_get_conn( conn->thd = trx->thd; conn->priority = share->priority; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif if (another) { uint old_elements = trx->trx_another_conn_hash.array.max_element; @@ -1312,67 +882,9 @@ SPIDER_CONN *spider_get_conn( trx->trx_conn_hash.array.size_of_element); } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn_kind == SPIDER_CONN_KIND_HS_READ) - { - uint old_elements = trx->trx_hs_r_conn_hash.array.max_element; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - if (my_hash_insert_with_hash_value(&trx->trx_hs_r_conn_hash, - share->hs_read_conn_keys_hash_value[link_idx], - (uchar*) conn)) -#else - if (my_hash_insert(&trx->trx_hs_r_conn_hash, (uchar*) conn)) -#endif - { - spider_free_conn(conn); - *error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - if (trx->trx_hs_r_conn_hash.array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - trx->trx_hs_r_conn_hash, - (trx->trx_hs_r_conn_hash.array.max_element - old_elements) * - trx->trx_hs_r_conn_hash.array.size_of_element); - } - } else { - uint old_elements = trx->trx_hs_w_conn_hash.array.max_element; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - if (my_hash_insert_with_hash_value(&trx->trx_hs_w_conn_hash, - share->hs_write_conn_keys_hash_value[link_idx], - (uchar*) conn)) -#else - if (my_hash_insert(&trx->trx_hs_w_conn_hash, (uchar*) conn)) -#endif - { - spider_free_conn(conn); - *error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - if (trx->trx_hs_w_conn_hash.array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - trx->trx_hs_w_conn_hash, - (trx->trx_hs_w_conn_hash.array.max_element - old_elements) * - trx->trx_hs_w_conn_hash.array.size_of_element); - } - } -#endif } else if (spider) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif spider->conns[base_link_idx] = conn; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn_kind == SPIDER_CONN_KIND_HS_READ) - { - spider->hs_r_conns[base_link_idx] = conn; - } else { - spider->hs_w_conns[base_link_idx] = conn; - } -#endif if (spider_bit_is_set(spider->conn_can_fo, base_link_idx)) conn->use_for_active_standby = TRUE; } @@ -1389,19 +901,12 @@ SPIDER_CONN *spider_get_conn( conn->queued_ping = FALSE; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif if (unlikely(spider && spider->wide_handler->top_share && (*error_num = spider_conn_queue_loop_check( conn, spider, base_link_idx)))) { goto error; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif DBUG_PRINT("info",("spider conn=%p", conn)); DBUG_RETURN(conn); @@ -2409,14 +1914,6 @@ int spider_set_conn_bg_param( ) { if ((error_num = spider_create_conn_thread(spider->conns[roop_count]))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = spider_create_conn_thread( - spider->hs_r_conns[roop_count]))) - DBUG_RETURN(error_num); - if ((error_num = spider_create_conn_thread( - spider->hs_w_conns[roop_count]))) - DBUG_RETURN(error_num); -#endif } #ifdef SPIDER_HAS_GROUP_BY_HANDLER } @@ -2767,19 +2264,9 @@ int spider_bg_conn_search( bool with_lock = FALSE; DBUG_ENTER("spider_bg_conn_search"); DBUG_PRINT("info",("spider spider=%p", spider)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = spider->conns[link_idx]; with_lock = (spider_conn_lock_mode(spider) != SPIDER_LOCK_MODE_NO_LOCK); first_conn = spider->conns[first_link_idx]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_HS_READ) - conn = spider->hs_r_conns[link_idx]; - else - conn = spider->hs_w_conns[link_idx]; -#endif if (first) { if (spider->use_pre_call) @@ -3238,21 +2725,12 @@ void *spider_bg_conn_action( !result_list->bgs_current->result ) { ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif if (spider->sql_kind[conn->link_idx] == SPIDER_SQL_KIND_SQL) { sql_type = SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_TMP_SQL; } else { sql_type = SPIDER_SQL_TYPE_HANDLER; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - sql_type = SPIDER_SQL_TYPE_SELECT_HS; - } -#endif pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) { @@ -3602,27 +3080,12 @@ void *spider_bg_sts_action( uint *conn_link_idx; uchar *conn_can_fo; char **conn_keys; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char **hs_r_conn_keys; - char **hs_w_conn_keys; -#endif spider_db_handler **dbton_hdl; THD *thd; my_thread_init(); DBUG_ENTER("spider_bg_sts_action"); /* init start */ char *ptr; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ptr = (char *) my_alloca( - (sizeof(int) * share->link_count) + - (sizeof(SPIDER_CONN *) * share->link_count) + - (sizeof(uint) * share->link_count) + - (sizeof(uchar) * share->link_bitmap_size) + - (sizeof(char *) * share->link_count) + - (sizeof(char *) * share->link_count) + - (sizeof(char *) * share->link_count) + - (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); -#else ptr = (char *) my_alloca( (sizeof(int) * share->link_count) + (sizeof(SPIDER_CONN *) * share->link_count) + @@ -3630,7 +3093,6 @@ void *spider_bg_sts_action( (sizeof(uchar) * share->link_bitmap_size) + (sizeof(char *) * share->link_count) + (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); -#endif if (!ptr) { pthread_mutex_lock(&share->sts_mutex); @@ -3651,12 +3113,6 @@ void *spider_bg_sts_action( ptr += (sizeof(uchar) * share->link_bitmap_size); conn_keys = (char **) ptr; ptr += (sizeof(char *) * share->link_count); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - hs_r_conn_keys = (char **) ptr; - ptr += (sizeof(char *) * share->link_count); - hs_w_conn_keys = (char **) ptr; - ptr += (sizeof(char *) * share->link_count); -#endif dbton_hdl = (spider_db_handler **) ptr; pthread_mutex_lock(&share->sts_mutex); if (!(thd = SPIDER_new_THD(next_thread_id()))) @@ -3699,10 +3155,6 @@ void *spider_bg_sts_action( spider.need_mons = need_mons; spider.conn_keys_first_ptr = share->conn_keys[0]; spider.conn_keys = conn_keys; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider.hs_r_conn_keys = hs_r_conn_keys; - spider.hs_w_conn_keys = hs_w_conn_keys; -#endif spider.dbton_handler = dbton_hdl; memset(conns, 0, sizeof(SPIDER_CONN *) * share->link_count); memset(need_mons, 0, sizeof(int) * share->link_count); @@ -3970,27 +3422,12 @@ void *spider_bg_crd_action( uint *conn_link_idx; uchar *conn_can_fo; char **conn_keys; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char **hs_r_conn_keys; - char **hs_w_conn_keys; -#endif spider_db_handler **dbton_hdl; THD *thd; my_thread_init(); DBUG_ENTER("spider_bg_crd_action"); /* init start */ char *ptr; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ptr = (char *) my_alloca( - (sizeof(int) * share->link_count) + - (sizeof(SPIDER_CONN *) * share->link_count) + - (sizeof(uint) * share->link_count) + - (sizeof(uchar) * share->link_bitmap_size) + - (sizeof(char *) * share->link_count) + - (sizeof(char *) * share->link_count) + - (sizeof(char *) * share->link_count) + - (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); -#else ptr = (char *) my_alloca( (sizeof(int) * share->link_count) + (sizeof(SPIDER_CONN *) * share->link_count) + @@ -3998,7 +3435,6 @@ void *spider_bg_crd_action( (sizeof(uchar) * share->link_bitmap_size) + (sizeof(char *) * share->link_count) + (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE)); -#endif if (!ptr) { pthread_mutex_lock(&share->crd_mutex); @@ -4019,12 +3455,6 @@ void *spider_bg_crd_action( ptr += (sizeof(uchar) * share->link_bitmap_size); conn_keys = (char **) ptr; ptr += (sizeof(char *) * share->link_count); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - hs_r_conn_keys = (char **) ptr; - ptr += (sizeof(char *) * share->link_count); - hs_w_conn_keys = (char **) ptr; - ptr += (sizeof(char *) * share->link_count); -#endif dbton_hdl = (spider_db_handler **) ptr; pthread_mutex_lock(&share->crd_mutex); if (!(thd = SPIDER_new_THD(next_thread_id()))) @@ -4071,10 +3501,6 @@ void *spider_bg_crd_action( spider.need_mons = need_mons; spider.conn_keys_first_ptr = share->conn_keys[0]; spider.conn_keys = conn_keys; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider.hs_r_conn_keys = hs_r_conn_keys; - spider.hs_w_conn_keys = hs_w_conn_keys; -#endif spider.dbton_handler = dbton_hdl; memset(conns, 0, sizeof(SPIDER_CONN *) * share->link_count); memset(need_mons, 0, sizeof(int) * share->link_count); @@ -4783,51 +4209,14 @@ bool spider_conn_use_handler( DBUG_PRINT("info",("spider use_handler=%d", use_handler)); DBUG_PRINT("info",("spider spider->conn_kind[link_idx]=%u", spider->conn_kind[link_idx])); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[link_idx] != SPIDER_CONN_KIND_MYSQL) - { - DBUG_PRINT("info",("spider TRUE by HS")); - spider->sql_kinds |= SPIDER_SQL_KIND_HS; - spider->sql_kind[link_idx] = SPIDER_SQL_KIND_HS; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if ( - spider->do_direct_update && - spider_bit_is_set(spider->do_hs_direct_update, link_idx) - ) { - DBUG_PRINT("info",("spider using HS direct_update")); - spider->direct_update_kinds |= SPIDER_SQL_KIND_HS; - } -#endif - DBUG_RETURN(TRUE); - } -#endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS if (spider->do_direct_update) { spider->sql_kinds |= SPIDER_SQL_KIND_SQL; spider->sql_kind[link_idx] = SPIDER_SQL_KIND_SQL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider_bit_is_set(spider->do_hs_direct_update, link_idx)) - { - spider->direct_update_kinds |= SPIDER_SQL_KIND_HS; - DBUG_PRINT("info",("spider TRUE by using HS direct_update")); - DBUG_RETURN(TRUE); - } else { -#endif spider->direct_update_kinds |= SPIDER_SQL_KIND_SQL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } - if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif DBUG_PRINT("info",("spider FALSE by using direct_update")); DBUG_RETURN(FALSE); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - DBUG_PRINT("info",("spider TRUE by using BOTH")); - DBUG_RETURN(TRUE); - } -#endif } #endif if (spider->use_spatial_index) @@ -4885,173 +4274,12 @@ bool spider_conn_need_open_handler( uint idx, int link_idx ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_CONN *conn; -#endif DBUG_ENTER("spider_conn_need_open_handler"); DBUG_PRINT("info",("spider spider=%p", spider)); if (spider->handler_opened(link_idx, spider->conn_kind[link_idx])) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if ( - spider->do_direct_update && - spider_bit_is_set(spider->do_hs_direct_update, link_idx) - ) { - conn = spider->hs_w_conns[link_idx]; - if ( - !conn->server_lost && - conn->hs_pre_age == spider->hs_w_conn_ages[link_idx] - ) { - DBUG_PRINT("info",("spider hs_write is already opened")); - DBUG_RETURN(FALSE); - } - } else -#endif - if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif DBUG_PRINT("info",("spider HA already opened")); DBUG_RETURN(FALSE); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_HS_READ) - { - DBUG_PRINT("info",("spider r_handler_index[%d]=%d", - link_idx, spider->r_handler_index[link_idx])); - DBUG_PRINT("info",("spider idx=%d", idx)); - DBUG_PRINT("info",("spider hs_pushed_ret_fields_num=%zu", - spider->hs_pushed_ret_fields_num)); - DBUG_PRINT("info",("spider hs_r_ret_fields_num[%d]=%lu", - link_idx, spider->hs_r_ret_fields_num[link_idx])); - DBUG_PRINT("info",("spider hs_r_ret_fields[%d]=%p", - link_idx, spider->hs_r_ret_fields[link_idx])); -#ifndef DBUG_OFF - if ( - spider->hs_pushed_ret_fields_num < MAX_FIELDS && - spider->hs_r_ret_fields[link_idx] && - spider->hs_pushed_ret_fields_num == - spider->hs_r_ret_fields_num[link_idx] - ) { - int roop_count; - for (roop_count = 0; roop_count < (int) spider->hs_pushed_ret_fields_num; - ++roop_count) - { - DBUG_PRINT("info",("spider hs_pushed_ret_fields[%d]=%u", - roop_count, spider->hs_pushed_ret_fields[roop_count])); - DBUG_PRINT("info",("spider hs_r_ret_fields[%d][%d]=%u", - link_idx, roop_count, - spider->hs_r_ret_fields[link_idx][roop_count])); - } - } -#endif - if ( - spider->r_handler_index[link_idx] == idx -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - && ( - ( - spider->hs_pushed_ret_fields_num == MAX_FIELDS && - spider->hs_r_ret_fields_num[link_idx] == MAX_FIELDS - ) || - ( - spider->hs_pushed_ret_fields_num < MAX_FIELDS && - spider->hs_r_ret_fields[link_idx] && - spider->hs_pushed_ret_fields_num == - spider->hs_r_ret_fields_num[link_idx] && - !memcmp(spider->hs_pushed_ret_fields, - spider->hs_r_ret_fields[link_idx], - sizeof(uint32) * spider->hs_pushed_ret_fields_num) - ) - ) -#endif - ) { - SPIDER_CONN *conn = spider->hs_r_conns[link_idx]; - DBUG_PRINT("info",("spider conn=%p", conn)); - DBUG_PRINT("info",("spider conn->conn_id=%llu", conn->conn_id)); - DBUG_PRINT("info",("spider conn->connection_id=%llu", - conn->connection_id)); - DBUG_PRINT("info",("spider conn->server_lost=%s", - conn->server_lost ? "TRUE" : "FALSE")); - DBUG_PRINT("info",("spider conn->hs_pre_age=%llu", conn->hs_pre_age)); - DBUG_PRINT("info",("spider hs_w_conn_ages[%d]=%llu", - link_idx, spider->hs_w_conn_ages[link_idx])); - if ( - !conn->server_lost && - conn->hs_pre_age == spider->hs_r_conn_ages[link_idx] - ) { - DBUG_PRINT("info",("spider hs_r same idx")); - DBUG_RETURN(FALSE); - } - } - } else if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_HS_WRITE) - { - DBUG_PRINT("info",("spider w_handler_index[%d]=%d", - link_idx, spider->w_handler_index[link_idx])); - DBUG_PRINT("info",("spider idx=%d", idx)); - DBUG_PRINT("info",("spider hs_pushed_ret_fields_num=%zu", - spider->hs_pushed_ret_fields_num)); - DBUG_PRINT("info",("spider hs_w_ret_fields_num[%d]=%lu", - link_idx, spider->hs_w_ret_fields_num[link_idx])); - DBUG_PRINT("info",("spider hs_w_ret_fields[%d]=%p", - link_idx, spider->hs_w_ret_fields[link_idx])); -#ifndef DBUG_OFF - if ( - spider->hs_pushed_ret_fields_num < MAX_FIELDS && - spider->hs_w_ret_fields[link_idx] && - spider->hs_pushed_ret_fields_num == - spider->hs_w_ret_fields_num[link_idx] - ) { - int roop_count; - for (roop_count = 0; roop_count < (int) spider->hs_pushed_ret_fields_num; - ++roop_count) - { - DBUG_PRINT("info",("spider hs_pushed_ret_fields[%d]=%u", - roop_count, spider->hs_pushed_ret_fields[roop_count])); - DBUG_PRINT("info",("spider hs_w_ret_fields[%d][%d]=%u", - link_idx, roop_count, - spider->hs_w_ret_fields[link_idx][roop_count])); - } - } -#endif - if ( - spider->w_handler_index[link_idx] == idx -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - && ( - ( - spider->hs_pushed_ret_fields_num == MAX_FIELDS && - spider->hs_w_ret_fields_num[link_idx] == MAX_FIELDS - ) || - ( - spider->hs_pushed_ret_fields_num < MAX_FIELDS && - spider->hs_w_ret_fields[link_idx] && - spider->hs_pushed_ret_fields_num == - spider->hs_w_ret_fields_num[link_idx] && - !memcmp(spider->hs_pushed_ret_fields, - spider->hs_w_ret_fields[link_idx], - sizeof(uint32) * spider->hs_pushed_ret_fields_num) - ) - ) -#endif - ) { - SPIDER_CONN *conn = spider->hs_w_conns[link_idx]; - DBUG_PRINT("info",("spider conn=%p", conn)); - DBUG_PRINT("info",("spider conn->conn_id=%llu", conn->conn_id)); - DBUG_PRINT("info",("spider conn->connection_id=%llu", - conn->connection_id)); - DBUG_PRINT("info",("spider conn->server_lost=%s", - conn->server_lost ? "TRUE" : "FALSE")); - DBUG_PRINT("info",("spider conn->hs_pre_age=%llu", conn->hs_pre_age)); - DBUG_PRINT("info",("spider hs_w_conn_ages[%d]=%llu", - link_idx, spider->hs_w_conn_ages[link_idx])); - if ( - !conn->server_lost && - conn->hs_pre_age == spider->hs_w_conn_ages[link_idx] - ) { - DBUG_PRINT("info",("spider hs_w same idx")); - DBUG_RETURN(FALSE); - } - } - } -#endif } DBUG_RETURN(TRUE); } diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 15e4c0e909d..ac1346349e7 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -143,36 +143,16 @@ int spider_db_connect( DBUG_PRINT("info",("spider net_read_timeout=%u", conn->net_read_timeout)); DBUG_PRINT("info",("spider net_write_timeout=%u", conn->net_write_timeout)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif if ((error_num = spider_reset_conn_setted_parameter(conn, thd))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif if (conn->dbton_id == SPIDER_DBTON_SIZE) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif my_printf_error( ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM, ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR, MYF(0), conn->tgt_wrapper); DBUG_RETURN(ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - my_printf_error( - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM, - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR, - MYF(0), conn->tgt_wrapper); - DBUG_RETURN(ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM); - } -#endif } if ((error_num = conn->db_conn->connect( @@ -302,10 +282,6 @@ int spider_db_conn_queue_action( } pthread_mutex_assert_owner(&conn->mta_conn_mutex); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif if (conn->queued_ping) { if ((error_num = spider_db_ping(conn->queued_ping_spider, conn, @@ -602,13 +578,6 @@ int spider_db_conn_queue_action( conn->db_conn->fin_loop_check(); } spider_conn_clear_queue(conn); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (conn->server_lost) - { - DBUG_PRINT("info", ("spider no connect queue")); - DBUG_RETURN(CR_SERVER_GONE_ERROR); - } -#endif DBUG_RETURN(0); } @@ -692,10 +661,6 @@ int spider_db_query( int error_num; DBUG_ENTER("spider_db_query"); pthread_mutex_assert_owner(&conn->mta_conn_mutex); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif DBUG_PRINT("info", ("spider conn->db_conn %p", conn->db_conn)); if ( !conn->in_before_query && @@ -715,17 +680,6 @@ int spider_db_query( if ((error_num = conn->db_conn->exec_query(query, length, quick_mode))) DBUG_RETURN(error_num); DBUG_RETURN(0); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn->queued_net_timeout) - { - if (conn->db_conn->set_net_timeout()) - DBUG_RETURN(ER_SPIDER_HS_NUM); - conn->queued_net_timeout = FALSE; - } - DBUG_RETURN(conn->db_conn->exec_query(NULL, 0, quick_mode)); - } -#endif } int spider_db_errorno( @@ -735,10 +689,6 @@ int spider_db_errorno( DBUG_ENTER("spider_db_errorno"); DBUG_ASSERT(conn->need_mon); pthread_mutex_assert_owner(&conn->mta_conn_mutex); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif if (conn->server_lost) { *conn->need_mon = ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM; @@ -838,57 +788,6 @@ int spider_db_errorno( } DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (conn->db_conn->is_server_gone_error(0)) - { - my_printf_error(ER_SPIDER_HS_NUM, ER_SPIDER_HS_STR, MYF(0), - conn->db_conn->get_errno(), conn->db_conn->get_error()); - *conn->need_mon = ER_SPIDER_HS_NUM; - DBUG_PRINT("info", ("spider conn=%p SERVER_LOST", conn)); - conn->server_lost = TRUE; - if (!conn->mta_conn_mutex_unlock_later) - { - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - } - DBUG_RETURN(ER_SPIDER_HS_NUM); - } else if (conn->db_conn->is_dup_entry_error(0)) - { - *conn->need_mon = 0; - if (!conn->mta_conn_mutex_unlock_later) - { - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - } - DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY); - } - my_printf_error(ER_SPIDER_HS_NUM, ER_SPIDER_HS_STR, MYF(0), - conn->db_conn->get_errno(), conn->db_conn->get_error()); - if (spider_param_log_result_errors() >= 1) - { - time_t cur_time = (time_t) time((time_t*) 0); - struct tm lt; - struct tm *l_time = localtime_r(&cur_time, <); - fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [ERROR SPIDER RESULT] " - "to %ld: %d %s\n", - l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, - l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - (ulong) current_thd->thread_id, conn->db_conn->get_errno(), - conn->db_conn->get_error()); - } - *conn->need_mon = ER_SPIDER_HS_NUM; - if (!conn->mta_conn_mutex_unlock_later) - { - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - } - DBUG_RETURN(ER_SPIDER_HS_NUM); - } -#endif if (!conn->mta_conn_mutex_unlock_later) { DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); @@ -915,10 +814,6 @@ int spider_db_set_names_internal( int *need_mon ) { DBUG_ENTER("spider_db_set_names_internal"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif pthread_mutex_assert_owner(&conn->mta_conn_mutex); DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name); DBUG_ASSERT(conn->mta_conn_mutex_lock_already); @@ -962,9 +857,6 @@ int spider_db_set_names_internal( share->tgt_dbs_lengths[all_link_idx] + 1); conn->default_database.length(share->tgt_dbs_lengths[all_link_idx]); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif DBUG_RETURN(0); } @@ -1718,14 +1610,6 @@ int spider_db_append_key_where_internal( case SPIDER_SQL_TYPE_HANDLER: sql_kind = SPIDER_SQL_KIND_HANDLER; break; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - case SPIDER_SQL_TYPE_SELECT_HS: - case SPIDER_SQL_TYPE_INSERT_HS: - case SPIDER_SQL_TYPE_UPDATE_HS: - case SPIDER_SQL_TYPE_DELETE_HS: - sql_kind = SPIDER_SQL_KIND_HS; - break; -#endif default: sql_kind = SPIDER_SQL_KIND_SQL; break; @@ -1848,6 +1732,7 @@ int spider_db_append_key_where_internal( key_count++ ) { DBUG_PRINT("info", ("spider tgt_key_part_map=%lu", tgt_key_part_map)); + bool rev = key_part->key_part_flag & HA_REVERSE_SORT; store_length = key_part->store_length; field = key_part->field; key_name_length = dbton_share->get_column_name_length(field->field_index); @@ -1946,14 +1831,6 @@ int spider_db_append_key_where_internal( #endif } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else { - if (spider_dbton[share->use_hs_dbton_ids[0]].db_util-> - append_column_value(spider, NULL, field, ptr, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } -#endif } else { DBUG_PRINT("info", ("spider start_key->flag=%d", start_key->flag)); switch (start_key->flag) @@ -2026,17 +1903,6 @@ int spider_db_append_key_where_internal( #endif } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else { - if (spider_dbton[share->use_hs_dbton_ids[0]].db_util-> - append_column_value(spider, NULL, field, ptr, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (str->reserve(SPIDER_SQL_HS_EQUAL_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_HS_EQUAL_STR, SPIDER_SQL_HS_EQUAL_LEN); - } -#endif break; case HA_READ_AFTER_KEY: if (sql_kind == SPIDER_SQL_KIND_SQL) @@ -2044,11 +1910,11 @@ int spider_db_append_key_where_internal( const char* op_str; uint32 op_len; if (start_key_part_map == 1) { - op_str = SPIDER_SQL_GT_STR; - op_len = SPIDER_SQL_GT_LEN; + op_str = rev ? SPIDER_SQL_LT_STR : SPIDER_SQL_GT_STR; + op_len = rev ? SPIDER_SQL_LT_LEN : SPIDER_SQL_GT_LEN; } else { - op_str = SPIDER_SQL_GTEQUAL_STR; - op_len = SPIDER_SQL_GTEQUAL_LEN; + op_str = rev ? SPIDER_SQL_LTEQUAL_STR : SPIDER_SQL_GTEQUAL_STR; + op_len = rev ? SPIDER_SQL_LTEQUAL_LEN : SPIDER_SQL_GTEQUAL_LEN; } if (str->reserve(store_length + key_name_length + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len)) @@ -2072,10 +1938,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_GT_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); - str_part2->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str_part2, field, ptr, FALSE, - share->access_charset)) + if (rev) + str_part2->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); + else + str_part2->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -2105,17 +1974,6 @@ int spider_db_append_key_where_internal( #endif } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else { - if (spider_dbton[share->use_hs_dbton_ids[0]].db_util-> - append_column_value(spider, NULL, field, ptr, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (str->reserve(SPIDER_SQL_HS_GT_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_HS_GT_STR, SPIDER_SQL_HS_GT_LEN); - } -#endif break; case HA_READ_BEFORE_KEY: result_list->desc_flg = TRUE; @@ -2124,11 +1982,11 @@ int spider_db_append_key_where_internal( const char* op_str; uint32 op_len; if (start_key_part_map == 1) { - op_str = SPIDER_SQL_LT_STR; - op_len = SPIDER_SQL_LT_LEN; + op_str = rev ? SPIDER_SQL_GT_STR : SPIDER_SQL_LT_STR; + op_len = rev ? SPIDER_SQL_GT_LEN : SPIDER_SQL_LT_LEN; } else { - op_str = SPIDER_SQL_LTEQUAL_STR; - op_len = SPIDER_SQL_LTEQUAL_LEN; + op_str = rev ? SPIDER_SQL_GTEQUAL_STR : SPIDER_SQL_LTEQUAL_STR; + op_len = rev ? SPIDER_SQL_GTEQUAL_LEN : SPIDER_SQL_LTEQUAL_LEN; } if (str->reserve(store_length + key_name_length + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len)) @@ -2152,10 +2010,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_LT_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); - str_part2->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str_part2, field, ptr, FALSE, - share->access_charset)) + if (rev) + str_part2->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN); + else + str_part2->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -2185,17 +2046,6 @@ int spider_db_append_key_where_internal( #endif } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else { - if (spider_dbton[share->use_hs_dbton_ids[0]].db_util-> - append_column_value(spider, NULL, field, ptr, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (str->reserve(SPIDER_SQL_HS_LT_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_HS_LT_STR, SPIDER_SQL_HS_LT_LEN); - } -#endif break; #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 #else @@ -2213,9 +2063,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str, field, ptr, FALSE, share->access_charset)) + if (rev) + str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); + else + str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (!set_order) { @@ -2229,11 +2083,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); - str_part2->q_append(SPIDER_SQL_LTEQUAL_STR, - SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str_part2, field, ptr, false, - share->access_charset)) + if (rev) + str_part2->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); + else + str_part2->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -2243,8 +2099,7 @@ int spider_db_append_key_where_internal( { if (str->reserve(SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_LTEQUAL_STR, - SPIDER_SQL_LTEQUAL_LEN); + str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); } if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str_part, field, ptr, false, @@ -2255,8 +2110,7 @@ int spider_db_append_key_where_internal( { if (str->reserve(SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_LTEQUAL_STR, - SPIDER_SQL_LTEQUAL_LEN); + str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str_part, field, ptr, false, share->access_charset)) @@ -2265,18 +2119,6 @@ int spider_db_append_key_where_internal( #endif } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else { - if (spider_dbton[share->use_hs_dbton_ids[0]].db_util-> - append_column_value(spider, NULL, field, ptr, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (str->reserve(SPIDER_SQL_HS_LTEQUAL_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_HS_LTEQUAL_STR, - SPIDER_SQL_HS_LTEQUAL_LEN); - } -#endif break; case HA_READ_MBR_CONTAIN: if (str->reserve(SPIDER_SQL_MBR_CONTAIN_LEN)) @@ -2365,9 +2207,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_GTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str, field, ptr, FALSE, share->access_charset)) + if (rev) + str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); + else + str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (!set_order) { @@ -2381,11 +2227,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_GTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); - str_part2->q_append(SPIDER_SQL_GTEQUAL_STR, - SPIDER_SQL_GTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str_part2, field, ptr, false, - share->access_charset)) + if (rev) + str_part2->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); + else + str_part2->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -2395,8 +2243,7 @@ int spider_db_append_key_where_internal( { if (str->reserve(SPIDER_SQL_GTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_GTEQUAL_STR, - SPIDER_SQL_GTEQUAL_LEN); + str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); } if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str_part, field, ptr, false, @@ -2407,8 +2254,7 @@ int spider_db_append_key_where_internal( { if (str->reserve(SPIDER_SQL_GTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_GTEQUAL_STR, - SPIDER_SQL_GTEQUAL_LEN); + str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str_part, field, ptr, false, share->access_charset)) @@ -2417,18 +2263,6 @@ int spider_db_append_key_where_internal( #endif } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else { - if (spider_dbton[share->use_hs_dbton_ids[0]].db_util-> - append_column_value(spider, NULL, field, ptr, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (str->reserve(SPIDER_SQL_HS_GTEQUAL_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_HS_GTEQUAL_STR, - SPIDER_SQL_HS_GTEQUAL_LEN); - } -#endif break; } } @@ -2456,10 +2290,6 @@ int spider_db_append_key_where_internal( } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (sql_kind != SPIDER_SQL_KIND_HS) - { -#endif if ( (key_eq && use_key == end_key) || (!key_eq && end_key_part_map) @@ -2536,11 +2366,11 @@ int spider_db_append_key_where_internal( const char* op_str; uint32 op_len; if (end_key_part_map == 1) { - op_str = SPIDER_SQL_LT_STR; - op_len = SPIDER_SQL_LT_LEN; + op_str = rev ? SPIDER_SQL_GT_STR : SPIDER_SQL_LT_STR; + op_len = rev ? SPIDER_SQL_GT_LEN : SPIDER_SQL_LT_LEN; } else { - op_str = SPIDER_SQL_LTEQUAL_STR; - op_len = SPIDER_SQL_LTEQUAL_LEN; + op_str = rev ? SPIDER_SQL_GTEQUAL_STR : SPIDER_SQL_LTEQUAL_STR; + op_len = rev ? SPIDER_SQL_GTEQUAL_LEN : SPIDER_SQL_LTEQUAL_LEN; } if (str->reserve(store_length + key_name_length + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len)) @@ -2563,10 +2393,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_LT_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); - str_part2->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str_part2, field, ptr, false, - share->access_charset)) + if (rev) + str_part2->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN); + else + str_part2->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == end_key) @@ -2605,9 +2438,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str, field, ptr, FALSE, share->access_charset)) + if (rev) + str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); + else + str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (!set_order) { @@ -2620,11 +2457,13 @@ int spider_db_append_key_where_internal( SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); - str_part2->q_append(SPIDER_SQL_LTEQUAL_STR, - SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util->append_column_value( - spider, str_part2, field, ptr, false, - share->access_charset)) + if (rev) + str_part2->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); + else + str_part2->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); + if (spider_dbton[dbton_id].db_util-> + append_column_value(spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == end_key) @@ -2634,8 +2473,7 @@ int spider_db_append_key_where_internal( { if (str->reserve(SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_LTEQUAL_STR, - SPIDER_SQL_LTEQUAL_LEN); + str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); } if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str_part, field, ptr, false, @@ -2646,8 +2484,7 @@ int spider_db_append_key_where_internal( { if (str->reserve(SPIDER_SQL_LTEQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_LTEQUAL_STR, - SPIDER_SQL_LTEQUAL_LEN); + str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str_part, field, ptr, false, share->access_charset)) @@ -2683,9 +2520,6 @@ int spider_db_append_key_where_internal( } if (use_both && (!start_key_part_map || !end_key_part_map)) break; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif } if ((error_num = dbton_hdl->append_where_terminator_part(sql_type, set_order, key_count))) @@ -2729,15 +2563,6 @@ int spider_db_append_key_where( SPIDER_SQL_TYPE_HANDLER))) DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((spider->sql_kinds & SPIDER_SQL_KIND_HS)) - { - DBUG_PRINT("info",("spider call internal by SPIDER_SQL_KIND_HS")); - if ((error_num = spider->append_key_where_hs_part(start_key, end_key, - SPIDER_SQL_TYPE_SELECT_HS))) - DBUG_RETURN(error_num); - } -#endif DBUG_RETURN(0); } @@ -3130,10 +2955,6 @@ int spider_db_fetch_table( SPIDER_DB_ROW *row; Field **field; DBUG_ENTER("spider_db_fetch_table"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[spider->result_link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif if (result_list->quick_mode == 0) { SPIDER_DB_RESULT *result = current->result; @@ -3216,21 +3037,7 @@ int spider_db_fetch_table( #ifdef SPIDER_HAS_GROUP_BY_HANDLER } #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (!(row = result_list->hs_result->fetch_row_from_result_buffer( - result_list->hs_result_buf))) - { - table->status = STATUS_NOT_FOUND; - DBUG_RETURN(HA_ERR_END_OF_FILE); - } - } -#endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[spider->result_link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif for ( field = table->field; *field; @@ -3258,68 +3065,6 @@ int spider_db_fetch_table( } row->next(); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if (spider->hs_pushed_ret_fields_num == MAX_FIELDS) - { -#endif - spider_db_handler *dbton_hdl = spider->dbton_handler[row->dbton_id]; - for ( - field = table->field; - *field; - field++ - ) { - if (dbton_hdl->minimum_select_bit_is_set((*field)->field_index)) - { -#ifndef DBUG_OFF - my_bitmap_map *tmp_map = - dbug_tmp_use_all_columns(table, table->write_set); -#endif - if ((error_num = spider_db_fetch_row(share, *field, row, ptr_diff))) - DBUG_RETURN(error_num); -#ifndef DBUG_OFF - dbug_tmp_restore_column_map(table->write_set, tmp_map); -#endif - row->next(); - } - } -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - } else { - uint32 *field_idxs = spider->hs_pushed_ret_fields; - size_t field_idxs_num = spider->hs_pushed_ret_fields_num; - Field *tf; - int roop_count; - if (spider->hs_pushed_lcl_fields_num != - result_list->hs_result->num_fields()) - { - DBUG_PRINT("info", ("spider different field_num %zu %u", - spider->hs_pushed_lcl_fields_num, - result_list->hs_result->num_fields())); - DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM); - } - for (roop_count = 0; roop_count < (int) field_idxs_num; - roop_count++) - { - tf = spider->get_top_table_field(field_idxs[roop_count]); - if ((tf = spider->field_exchange(tf))) - { -#ifndef DBUG_OFF - my_bitmap_map *tmp_map = - dbug_tmp_use_all_columns(table, table->write_set); -#endif - if ((error_num = spider_db_fetch_row(share, tf, row, ptr_diff))) - DBUG_RETURN(error_num); -#ifndef DBUG_OFF - dbug_tmp_restore_column_map(table->write_set, tmp_map); -#endif - row->next(); - } - } - } -#endif - } -#endif table->status = 0; DBUG_RETURN(0); } @@ -3572,10 +3317,6 @@ void spider_db_free_one_result_for_start_next( DBUG_ENTER("spider_db_free_one_result_for_start_next"); spider_bg_all_conn_break(spider); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[spider->result_link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif if (result_list->low_mem_read) { if (result) @@ -3604,24 +3345,6 @@ void spider_db_free_one_result_for_start_next( result = (SPIDER_RESULT *) result->next; } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (result_list->hs_has_result) - { - if (result_list->hs_result) - { - result_list->hs_result->free_result(); - delete result_list->hs_result; - result_list->hs_result = NULL; - } - if (result_list->hs_result_buf) - { - result_list->hs_result_buf->clear(); - } - result_list->hs_has_result = FALSE; - } - } -#endif DBUG_VOID_RETURN; } @@ -3730,28 +3453,6 @@ int spider_db_free_result( delete tmp_pos_row; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (result_list->hs_has_result) - { - if (result_list->hs_result) - { - result_list->hs_result->free_result(); - delete result_list->hs_result; - result_list->hs_result = NULL; - } - if (result_list->hs_result_buf) - { - if (result_list->hs_result_buf->check_size( - spider_param_hs_result_free_size(trx->thd, share->hs_result_free_size)) - ) { - trx->hs_result_free_count++; - } - result_list->hs_result_buf->clear(); - } - result_list->hs_has_result = FALSE; - } -#endif - if ( final || spider_param_reset_sql_alloc(trx->thd, share->reset_sql_alloc) == 1 @@ -3940,10 +3641,6 @@ int spider_db_store_result( SPIDER_RESULT_LIST *result_list = &spider->result_list; SPIDER_RESULT *current; DBUG_ENTER("spider_db_store_result"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = spider->conns[link_idx]; DBUG_PRINT("info",("spider conn->connection_id=%llu", conn->connection_id)); @@ -4427,66 +4124,6 @@ int spider_db_store_result( DBUG_PRINT("info", ("spider first_position[]=%p", ¤t->first_position[result_list->current_row_num])); DBUG_PRINT("info", ("spider row=%p", current->first_position[result_list->current_row_num].row)); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_HS_READ) - conn = spider->hs_r_conns[link_idx]; - else - conn = spider->hs_w_conns[link_idx]; - DBUG_PRINT("info",("spider conn=%p", conn)); - DBUG_PRINT("info",("spider conn->connection_id=%llu", - conn->connection_id)); - DBUG_PRINT("info",("spider spider->connection_ids[%d]=%llu", - link_idx, spider->connection_ids[link_idx])); - if (conn->connection_id != spider->connection_ids[link_idx]) - { - my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM, - ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0)); - if (!conn->mta_conn_mutex_unlock_later) - { - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - } - DBUG_RETURN(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM); - } - if (spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_clear_bit(spider->db_request_phase, link_idx); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - if (!(result_list->hs_result = conn->db_conn->store_result( - &result_list->hs_result_buf, &request_key, &error_num))) - { - if (!error_num) - { - spider_db_errorno(conn); - DBUG_RETURN(ER_SPIDER_HS_NUM); - } else { - if (!conn->mta_conn_mutex_unlock_later) - { - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - } - } - DBUG_RETURN(error_num); - } - result_list->hs_conn = conn->db_conn; - result_list->hs_has_result = TRUE; - if (!conn->mta_conn_mutex_unlock_later) - { - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - } - } -#endif DBUG_RETURN(0); } @@ -4500,9 +4137,6 @@ int spider_db_store_result_for_reuse_cursor( SPIDER_RESULT_LIST *result_list = &spider->result_list; SPIDER_RESULT *current; DBUG_ENTER("spider_db_store_result_for_reuse_cursor"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - DBUG_ASSERT(spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL); -#endif conn = spider->conns[link_idx]; DBUG_PRINT("info",("spider conn->connection_id=%llu", conn->connection_id)); @@ -5032,9 +4666,6 @@ int spider_db_seek_next( SPIDER_RESULT_LIST *result_list = &spider->result_list; DBUG_ENTER("spider_db_seek_next"); if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider->conn_kind[spider->result_link_idx] == SPIDER_CONN_KIND_MYSQL && -#endif result_list->current_row_num >= result_list->current->record_num ) { DBUG_PRINT("info",("spider result_list->current_row_num=%lld", @@ -6551,9 +6182,6 @@ int spider_db_bulk_insert_init( DBUG_ENTER("spider_db_bulk_insert_init"); spider->sql_kinds = 0; spider->reset_sql_sql(SPIDER_SQL_TYPE_INSERT_SQL); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider->reset_hs_sql(SPIDER_SQL_TYPE_OTHER_HS); -#endif for ( roop_count = spider_conn_link_idx_next(share->link_statuses, spider->conn_link_idx, -1, share->link_count, @@ -6566,67 +6194,15 @@ int spider_db_bulk_insert_init( if (spider->conns[roop_count]) spider->conns[roop_count]->ignore_dup_key = spider->wide_handler->ignore_dup_key; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - spider_conn_use_handler(spider, spider->lock_mode, roop_count) && - ( - !spider->handler_opened(roop_count, SPIDER_CONN_KIND_HS_WRITE) || -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - spider->hs_w_ret_fields_num[roop_count] < MAX_FIELDS || -#endif - spider->hs_w_conns[roop_count]->server_lost - ) - ) { - if ((error_num = spider_db_open_handler(spider, - spider->hs_w_conns[roop_count], roop_count))) - { - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - error_num = spider_ping_table_mon_from_table( - spider->wide_handler->trx, - spider->wide_handler->trx->thd, - share, - roop_count, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - TRUE - ); - } - DBUG_RETURN(error_num); - } - spider->set_handler_opened(roop_count); - } -#else spider_conn_use_handler(spider, spider->wide_handler->lock_mode, roop_count); -#endif } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) - { -#endif if ( (error_num = spider->append_insert_sql_part()) || (error_num = spider->append_into_sql_part( SPIDER_SQL_TYPE_INSERT_SQL)) ) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } - if (spider->sql_kinds & SPIDER_SQL_KIND_HS) - { - spider->result_list.hs_upd_rows = 0; - } -#endif DBUG_RETURN(0); } @@ -6637,19 +6213,12 @@ int spider_db_bulk_insert( bool bulk_end ) { int error_num, first_insert_link_idx = -1; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_RESULT_LIST *result_list = &spider->result_list; -#endif SPIDER_SHARE *share = spider->share; THD *thd = spider->wide_handler->trx->thd; DBUG_ENTER("spider_db_bulk_insert"); if (!bulk_end) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) - { -#endif if ((error_num = spider->append_insert_values_sql_part( SPIDER_SQL_TYPE_INSERT_SQL))) { @@ -6657,16 +6226,6 @@ int spider_db_bulk_insert( spider->set_insert_to_pos_sql(SPIDER_SQL_TYPE_INSERT_SQL); DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } - if (spider->sql_kinds & SPIDER_SQL_KIND_HS) - { - if ((error_num = spider->append_insert_values_hs_part( - SPIDER_SQL_TYPE_INSERT_HS))) - DBUG_RETURN(error_num); - result_list->hs_upd_rows++; - } -#endif } if (spider->is_bulk_insert_exec_period(bulk_end)) @@ -6696,10 +6255,6 @@ int spider_db_bulk_insert( ) { ulong sql_type; spider_db_handler *dbton_handler; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[roop_count2] == SPIDER_CONN_KIND_MYSQL) - { -#endif sql_type = SPIDER_SQL_TYPE_INSERT_SQL; conn = spider->conns[roop_count2]; dbton_handler = spider->dbton_handler[conn->dbton_id]; @@ -6726,16 +6281,6 @@ int spider_db_bulk_insert( pthread_mutex_lock(&conn->mta_conn_mutex); SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - sql_type = SPIDER_SQL_TYPE_INSERT_HS; - conn = spider->hs_w_conns[roop_count2]; - dbton_handler = spider->dbton_handler[conn->dbton_id]; - pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - } -#endif conn->need_mon = &spider->need_mons[roop_count2]; DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); @@ -6831,43 +6376,6 @@ int spider_db_bulk_insert( insert_info = conn->db_conn->inserted_info(dbton_handler, copy_info); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind != SPIDER_CONN_KIND_MYSQL) - { - uint roop_count; - DBUG_PRINT("info",("spider conn=%p", conn)); - DBUG_PRINT("info",("spider result_list->hs_upd_rows=%llu", - result_list->hs_upd_rows)); - for (roop_count = 0; roop_count < result_list->hs_upd_rows; - roop_count++) - { - SPIDER_DB_RESULT *result; - if (spider_bit_is_set(spider->db_request_phase, roop_count2)) - { - spider_clear_bit(spider->db_request_phase, roop_count2); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = - spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[roop_count2]; - request_key.next = NULL; - if ((result = conn->db_conn->use_result(spider, &request_key, - &error_num))) - { - result->free_result(); - delete result; - } else { - if (!error_num) - { - error_num = spider_db_errorno(conn); - } - DBUG_RETURN(error_num); - } - } - } -#endif SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); pthread_mutex_unlock(&conn->mta_conn_mutex); if (first_insert_link_idx == -1) @@ -6968,16 +6476,7 @@ int spider_db_bulk_bulk_insert( spider->conn_link_idx, roop_count2, share->link_count, SPIDER_LINK_STATUS_RECOVERY) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[roop_count2] == SPIDER_CONN_KIND_MYSQL) - { -#endif conn = spider->conns[roop_count2]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - conn = spider->hs_w_conns[roop_count2]; - } -#endif pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); pthread_mutex_lock(&conn->mta_conn_mutex); SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); @@ -6994,44 +6493,6 @@ int spider_db_bulk_bulk_insert( DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); conn->mta_conn_mutex_lock_already = FALSE; conn->mta_conn_mutex_unlock_later = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind != SPIDER_CONN_KIND_MYSQL) - { - uint roop_count; - SPIDER_RESULT_LIST *result_list = &spider->result_list; - DBUG_PRINT("info",("spider conn=%p", conn)); - DBUG_PRINT("info",("spider result_list->hs_upd_rows=%llu", - result_list->hs_upd_rows)); - for (roop_count = 0; roop_count < result_list->hs_upd_rows; - roop_count++) - { - SPIDER_DB_RESULT *result; - if (spider_bit_is_set(spider->db_request_phase, roop_count2)) - { - spider_clear_bit(spider->db_request_phase, roop_count2); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = - spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[roop_count2]; - request_key.next = NULL; - if ((result = conn->db_conn->use_result(spider, &request_key, - &error_num))) - { - result->free_result(); - delete result; - } else { - if (!error_num) - { - error_num = spider_db_errorno(conn); - } - DBUG_RETURN(error_num); - } - } - } -#endif SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); pthread_mutex_unlock(&conn->mta_conn_mutex); if (first_insert_link_idx == -1) @@ -7102,16 +6563,7 @@ int spider_db_update_auto_increment( (auto_increment_mode == 3 && !table->auto_increment_field_not_null) ) { last_insert_id = spider->conns[link_idx]->db_conn->last_insert_id(); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_MYSQL) - { -#endif affected_rows = spider->conns[link_idx]->db_conn->affected_rows(); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - affected_rows = spider->result_list.hs_upd_rows; - } -#endif DBUG_PRINT("info",("spider last_insert_id=%llu", last_insert_id)); share->lgtm_tblhnd_share->auto_increment_value = last_insert_id + affected_rows; @@ -7653,27 +7105,8 @@ int spider_db_direct_update( spider->do_direct_update ? "TRUE" : "FALSE")); DBUG_PRINT("info", ("spider direct_update_kinds=%u", spider->direct_update_kinds)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - ( - spider->do_direct_update && - (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) - ) || - ( - !spider->do_direct_update && -#endif - (spider->sql_kinds & SPIDER_SQL_KIND_SQL) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - ) -#endif - ) { -#endif if ((error_num = spider->append_update_sql_part())) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif /* SQL access -> SQL remote access @@ -7694,17 +7127,6 @@ int spider_db_direct_update( (spider->direct_update_kinds & SPIDER_SQL_KIND_HS) */ -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->hs_increment || spider->hs_decrement) - { - if ( - (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) && - (error_num = spider->append_increment_update_set_sql_part()) - ) { - DBUG_RETURN(error_num); - } - } else { -#endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS if (!spider->do_direct_update) { @@ -7723,19 +7145,8 @@ int spider_db_direct_update( ) { DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - (spider->direct_update_kinds & SPIDER_SQL_KIND_HS) && - (error_num = spider->append_direct_update_set_hs_part()) - ) { - DBUG_RETURN(error_num); - } -#endif } #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif result_list->desc_flg = FALSE; result_list->sorted = TRUE; @@ -7765,22 +7176,6 @@ int spider_db_direct_update( DBUG_RETURN(error_num); } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->direct_update_kinds & SPIDER_SQL_KIND_HS) - { - if ( - (error_num = spider->append_key_where_hs_part( - (ranges && ranges->start_key.key) ? &ranges->start_key : NULL, - (ranges && ranges->end_key.key) ? &ranges->end_key : NULL, - SPIDER_SQL_TYPE_UPDATE_HS)) || - (error_num = spider->append_limit_hs_part( - result_list->internal_offset, result_list->limit_num, - SPIDER_SQL_TYPE_UPDATE_HS)) - ) { - DBUG_RETURN(error_num); - } - } -#endif for ( roop_count = spider_conn_link_idx_next(share->link_statuses, @@ -7792,20 +7187,9 @@ int spider_db_direct_update( SPIDER_LINK_STATUS_RECOVERY) ) { ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!spider_bit_is_set(spider->do_hs_direct_update, roop_count)) - { -#endif DBUG_PRINT("info", ("spider exec sql")); conn = spider->conns[roop_count]; sql_type = SPIDER_SQL_TYPE_UPDATE_SQL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - DBUG_PRINT("info", ("spider exec hs")); - conn = spider->hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_UPDATE_HS; - } -#endif spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -7913,10 +7297,6 @@ int spider_db_direct_update( } DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!spider_bit_is_set(spider->do_hs_direct_update, roop_count)) - { -#endif if (!counted) { *update_rows = spider->conns[roop_count]->db_conn->affected_rows(); @@ -7925,48 +7305,6 @@ int spider_db_direct_update( DBUG_PRINT("info", ("spider found_rows = %llu", *found_rows)); counted = TRUE; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - SPIDER_DB_RESULT *result; - if (spider_bit_is_set(spider->db_request_phase, roop_count)) - { - spider_clear_bit(spider->db_request_phase, roop_count); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = - spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[roop_count]; - request_key.next = NULL; - if ((result = conn->db_conn->use_result(spider, &request_key, - &error_num))) - { - if (!counted) - { - *update_rows = conn->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows)); - *found_rows = conn->db_conn->matched_rows(); - DBUG_PRINT("info", ("spider found_rows = %llu", *found_rows)); - counted = TRUE; - } - result->free_result(); - delete result; - } else { - if (!error_num) - { - error_num = spider_db_errorno(conn); - } - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - } -#endif DBUG_ASSERT(conn->mta_conn_mutex_lock_already); DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); conn->mta_conn_mutex_lock_already = FALSE; @@ -7978,11 +7316,6 @@ int spider_db_direct_update( pthread_mutex_unlock(&conn->mta_conn_mutex); } spider->reset_sql_sql(SPIDER_SQL_TYPE_UPDATE_SQL); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider->reset_hs_sql(SPIDER_SQL_TYPE_UPDATE_HS); - spider->reset_hs_keys(SPIDER_SQL_TYPE_UPDATE_HS); - spider->reset_hs_upds(SPIDER_SQL_TYPE_UPDATE_HS); -#endif DBUG_RETURN(0); } #else @@ -8237,18 +7570,8 @@ int spider_db_bulk_direct_update( spider->conn_link_idx, roop_count, share->link_count, SPIDER_LINK_STATUS_RECOVERY) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!spider_bit_is_set(spider->do_hs_direct_update, roop_count)) - { -#endif DBUG_PRINT("info", ("spider exec sql")); conn = spider->conns[roop_count]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - DBUG_PRINT("info", ("spider exec hs")); - conn = spider->hs_w_conns[roop_count]; - } -#endif pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); pthread_mutex_lock(&conn->mta_conn_mutex); SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); @@ -8261,10 +7584,6 @@ int spider_db_bulk_direct_update( { error_num = tmp_error_num; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!spider_bit_is_set(spider->do_hs_direct_update, roop_count)) - { -#endif if (!counted) { *update_rows = spider->conns[roop_count]->db_conn->affected_rows(); @@ -8273,48 +7592,6 @@ int spider_db_bulk_direct_update( DBUG_PRINT("info", ("spider found_rows = %llu", *found_rows)); counted = TRUE; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - SPIDER_DB_RESULT *result; - if (spider_bit_is_set(spider->db_request_phase, roop_count)) - { - spider_clear_bit(spider->db_request_phase, roop_count); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = - spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[roop_count]; - request_key.next = NULL; - if ((result = conn->db_conn->use_result(spider, &request_key, - &error_num))) - { - if (!counted) - { - *update_rows = conn->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider update_rows = %llu", *update_rows)); - *found_rows = conn->db_conn->matched_rows(); - DBUG_PRINT("info", ("spider found_rows = %llu", *found_rows)); - counted = TRUE; - } - result->free_result(); - delete result; - } else { - if (!error_num) - { - error_num = spider_db_errorno(conn); - } - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - } -#endif DBUG_ASSERT(conn->mta_conn_mutex_lock_already); DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); conn->mta_conn_mutex_lock_already = FALSE; @@ -8488,22 +7765,6 @@ int spider_db_direct_delete( DBUG_RETURN(error_num); } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->direct_update_kinds & SPIDER_SQL_KIND_HS) - { - if ( - (error_num = spider->append_key_where_hs_part( - (ranges && ranges->start_key.key) ? &ranges->start_key : NULL, - (ranges && ranges->end_key.key) ? &ranges->end_key : NULL, - SPIDER_SQL_TYPE_DELETE_HS)) || - (error_num = spider->append_limit_hs_part( - result_list->internal_offset, result_list->limit_num, - SPIDER_SQL_TYPE_DELETE_HS)) - ) { - DBUG_RETURN(error_num); - } - } -#endif for ( roop_count = spider_conn_link_idx_next(share->link_statuses, @@ -8515,20 +7776,9 @@ int spider_db_direct_delete( SPIDER_LINK_STATUS_RECOVERY) ) { ulong sql_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!spider_bit_is_set(spider->do_hs_direct_update, roop_count)) - { -#endif DBUG_PRINT("info", ("spider exec sql")); conn = spider->conns[roop_count]; sql_type = SPIDER_SQL_TYPE_DELETE_SQL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - DBUG_PRINT("info", ("spider exec hs")); - conn = spider->hs_w_conns[roop_count]; - sql_type = SPIDER_SQL_TYPE_DELETE_HS; - } -#endif spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type)) @@ -8634,50 +7884,12 @@ int spider_db_direct_delete( DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); conn->mta_conn_mutex_lock_already = FALSE; conn->mta_conn_mutex_unlock_later = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!spider_bit_is_set(spider->do_hs_direct_update, roop_count)) - { -#endif if (!counted) { *delete_rows = spider->conns[roop_count]->db_conn->affected_rows(); DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows)); counted = TRUE; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - SPIDER_DB_RESULT *result; - if (spider_bit_is_set(spider->db_request_phase, roop_count)) - { - spider_clear_bit(spider->db_request_phase, roop_count); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = - spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[roop_count]; - request_key.next = NULL; - if ((result = conn->db_conn->use_result(spider, &request_key, - &error_num))) - { - if (!counted) - { - *delete_rows = conn->db_conn->affected_rows(); - DBUG_PRINT("info", ("spider delete_rows = %llu", *delete_rows)); - counted = TRUE; - } - result->free_result(); - delete result; - } else { - if (!error_num) - { - error_num = spider_db_errorno(conn); - } - DBUG_RETURN(error_num); - } - } -#endif #ifdef HA_CAN_BULK_ACCESS } #endif @@ -8690,15 +7902,6 @@ int spider_db_direct_delete( if ((error_num = spider->reset_sql_sql(SPIDER_SQL_TYPE_DELETE_SQL))) error_num2 = error_num; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider->direct_update_kinds & SPIDER_SQL_KIND_HS) - { - if ((error_num = spider->reset_hs_sql(SPIDER_SQL_TYPE_DELETE_HS))) - error_num2 = error_num; - if ((error_num = spider->reset_hs_keys(SPIDER_SQL_TYPE_DELETE_HS))) - error_num2 = error_num; - } -#endif DBUG_RETURN(error_num2); } #else @@ -10780,36 +9983,16 @@ int spider_db_udf_direct_sql_connect( DBUG_PRINT("info",("spider net_read_timeout=%u", conn->net_read_timeout)); DBUG_PRINT("info",("spider net_write_timeout=%u", conn->net_write_timeout)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif if ((error_num = spider_reset_conn_setted_parameter(conn, thd))) DBUG_RETURN(error_num); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif if (conn->dbton_id == SPIDER_DBTON_SIZE) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif my_printf_error( ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM, ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR, MYF(0), conn->tgt_wrapper); DBUG_RETURN(ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - my_printf_error( - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM, - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR, - MYF(0), conn->tgt_wrapper); - DBUG_RETURN(ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM); - } -#endif } /* @@ -10846,10 +10029,6 @@ int spider_db_udf_direct_sql_ping( DBUG_RETURN(error_num); conn->server_lost = FALSE; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif if ((error_num = conn->db_conn->ping())) { spider_db_disconnect(conn); @@ -10867,9 +10046,6 @@ int spider_db_udf_direct_sql_ping( DBUG_RETURN(error_num); } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif conn->ping_time = (time_t) time((time_t*) 0); DBUG_RETURN(0); } @@ -10979,26 +10155,6 @@ int spider_db_udf_direct_sql( !(error_num = spider_db_udf_direct_sql_set_names(direct_sql, trx, conn)) && !(error_num = spider_db_udf_direct_sql_select_db(direct_sql, conn)) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode != 0) - { - st_spider_db_request_key request_key; - request_key.spider_thread_id = direct_sql->trx->spider_thread_id; - request_key.query_id = direct_sql->trx->thd->query_id; - request_key.handler = direct_sql; - request_key.request_id = 1; - request_key.next = NULL; - if ((error_num = conn->db_conn->append_sql( - direct_sql->sql, direct_sql->sql_length, &request_key))) - { -#if MYSQL_VERSION_ID < 50500 -#else - c_thd->lex->sql_command = sql_command_backup; -#endif - DBUG_RETURN(error_num); - } - } -#endif spider_conn_set_timeout_from_direct_sql(conn, thd, direct_sql); if (spider_db_query( conn, @@ -11267,9 +10423,6 @@ int spider_db_udf_direct_sql_select_db( DBUG_ENTER("spider_db_udf_direct_sql_select_db"); pthread_mutex_assert_owner(&conn->mta_conn_mutex); if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - direct_sql->access_mode == 0 && -#endif spider_dbton[conn->dbton_id].db_util->database_has_default_value() ) { DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name); @@ -11315,10 +10468,6 @@ int spider_db_udf_direct_sql_set_names( int error_num, need_mon = 0; DBUG_ENTER("spider_db_udf_direct_sql_set_names"); pthread_mutex_assert_owner(&conn->mta_conn_mutex); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name); if ( !conn->access_charset || @@ -11342,9 +10491,6 @@ int spider_db_udf_direct_sql_set_names( } conn->access_charset = trx->udf_access_charset; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif DBUG_RETURN(0); } @@ -12412,15 +11558,7 @@ int spider_db_open_handler( int error_num; SPIDER_SHARE *share = spider->share; uint *handler_id_ptr = -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - conn->conn_kind == SPIDER_CONN_KIND_MYSQL ? -#endif &spider->m_handler_id[link_idx] -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - : conn->conn_kind == SPIDER_CONN_KIND_HS_READ ? - &spider->r_handler_id[link_idx] : - &spider->w_handler_id[link_idx] -#endif ; spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id]; DBUG_ENTER("spider_db_open_handler"); @@ -12435,182 +11573,32 @@ int spider_db_open_handler( conn->mta_conn_mutex_unlock_later = TRUE; if (!spider->handler_opened(link_idx, conn->conn_kind)) *handler_id_ptr = conn->opened_handlers; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif - if (!spider->handler_opened(link_idx, conn->conn_kind)) - my_sprintf(spider->m_handler_cid[link_idx], - (spider->m_handler_cid[link_idx], SPIDER_SQL_HANDLER_CID_FORMAT, - *handler_id_ptr)); - - if ((error_num = dbton_hdl->append_open_handler_part( - SPIDER_SQL_TYPE_HANDLER, *handler_id_ptr, conn, link_idx))) - { - goto error; - } - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if (dbton_hdl->execute_sql( - SPIDER_SQL_TYPE_HANDLER, - conn, - -1, - &spider->need_mons[link_idx]) - ) { - error_num = spider_db_errorno(conn); - goto error; - } - dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - uint reconnect = 0; - if (conn->hs_pre_age != conn->hs_age && conn->server_lost) - { - spider_conn_queue_connect(share, conn, link_idx); - reconnect |= 1; - } - if ((error_num = spider_db_conn_queue_action(conn))) - { - goto error; - } - if (conn->hs_pre_age != conn->hs_age) - { - if (conn->db_conn->ping()) - { - my_printf_error(ER_SPIDER_HS_NUM, ER_SPIDER_HS_STR, MYF(0), - conn->db_conn->get_errno(), conn->db_conn->get_error()); - spider->need_mons[link_idx] = ER_SPIDER_HS_NUM; - error_num = ER_SPIDER_HS_NUM; - goto error; - } - conn->opened_handlers = 0; - conn->db_conn->reset_opened_handler(); - conn->hs_age = conn->hs_pre_age; - reconnect |= 2; - } - if (conn->conn_kind == SPIDER_CONN_KIND_HS_READ) - { - if (spider->hs_r_conn_ages[link_idx] != conn->hs_age) - { - spider->clear_handler_opened(link_idx, SPIDER_CONN_KIND_HS_READ); - *handler_id_ptr = conn->opened_handlers; - } - } else { - if (spider->hs_w_conn_ages[link_idx] != conn->hs_age) - { - spider->clear_handler_opened(link_idx, SPIDER_CONN_KIND_HS_WRITE); - *handler_id_ptr = conn->opened_handlers; - } - } + if (!spider->handler_opened(link_idx, conn->conn_kind)) + my_sprintf(spider->m_handler_cid[link_idx], + (spider->m_handler_cid[link_idx], SPIDER_SQL_HANDLER_CID_FORMAT, + *handler_id_ptr)); -#ifdef HA_CAN_BULK_ACCESS - if (!spider->is_bulk_access_clone) - { -#endif - conn->db_conn->reset_request_queue(); -#ifdef HA_CAN_BULK_ACCESS - } else if (!spider->bulk_access_executing) - { - if (conn->conn_kind == SPIDER_CONN_KIND_HS_READ) - { - spider_set_bit(spider->result_list.hs_r_bulk_open_index, link_idx); - } else { - spider_set_bit(spider->result_list.hs_w_bulk_open_index, link_idx); - } - } -#endif - if ((error_num = dbton_hdl->append_open_handler_part( - SPIDER_SQL_TYPE_OTHER_HS, *handler_id_ptr, conn, link_idx))) - { - goto error; - } -#ifdef HA_CAN_BULK_ACCESS - if (spider->is_bulk_access_clone && !spider->bulk_access_executing) - { - spider->connection_ids[link_idx] = conn->connection_id; - spider_trx_add_bulk_access_conn(spider->wide_handler->trx, conn); - } else { -#endif - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if (dbton_hdl->execute_sql( - SPIDER_SQL_TYPE_SELECT_HS, - conn, - -1, - &spider->need_mons[link_idx]) - ) { - error_num = spider_db_errorno(conn); - goto error; - } + if ((error_num = dbton_hdl->append_open_handler_part( + SPIDER_SQL_TYPE_HANDLER, *handler_id_ptr, conn, link_idx))) + { + goto error; + } - SPIDER_DB_RESULT *result; - if (spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_clear_bit(spider->db_request_phase, link_idx); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = - spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - if (!(result = conn->db_conn->use_result(spider, &request_key, - &error_num))) - { - if (!error_num) - { - spider_db_errorno(conn); - error_num = ER_SPIDER_HS_NUM; - } - goto error; - } else { - conn->ping_time = (time_t) time((time_t*) 0); - } - result->free_result(); - delete result; -#ifdef HA_CAN_BULK_ACCESS - } -#endif - if (conn->conn_kind == SPIDER_CONN_KIND_HS_READ) - { - spider->r_handler_index[link_idx] = spider->active_index; - spider->hs_r_conn_ages[link_idx] = conn->hs_age; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if ( - spider->sql_command != SQLCOM_HS_INSERT && - spider->hs_pushed_ret_fields_num < MAX_FIELDS - ) { - spider->hs_r_ret_fields_num[link_idx] = - spider->hs_pushed_ret_fields_num; - memcpy(spider->hs_r_ret_fields[link_idx], spider->hs_pushed_ret_fields, - sizeof(uint32) * spider->hs_pushed_ret_fields_num); - } else { - spider->hs_r_ret_fields_num[link_idx] = MAX_FIELDS; - } -#endif - } else { - spider->w_handler_index[link_idx] = spider->active_index; - spider->hs_w_conn_ages[link_idx] = conn->hs_age; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if ( - spider->sql_command != SQLCOM_HS_INSERT && - spider->hs_pushed_ret_fields_num < MAX_FIELDS - ) { - spider->hs_w_ret_fields_num[link_idx] = - spider->hs_pushed_ret_fields_num; - memcpy(spider->hs_w_ret_fields[link_idx], spider->hs_pushed_ret_fields, - sizeof(uint32) * spider->hs_pushed_ret_fields_num); - } else { - spider->hs_w_ret_fields_num[link_idx] = MAX_FIELDS; - } -#endif - } + spider_conn_set_timeout_from_share(conn, link_idx, + spider->wide_handler->trx->thd, + share); + if (dbton_hdl->execute_sql( + SPIDER_SQL_TYPE_HANDLER, + conn, + -1, + &spider->need_mons[link_idx]) + ) { + error_num = spider_db_errorno(conn); + goto error; } -#endif + dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER); + if (!spider->handler_opened(link_idx, conn->conn_kind)) { if ((error_num = dbton_hdl->insert_opened_handler(conn, link_idx))) @@ -12644,74 +11632,10 @@ int spider_db_bulk_open_handler( int link_idx ) { int error_num = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - bool opening_index = FALSE; -#endif DBUG_ENTER("spider_db_bulk_open_handler"); DBUG_PRINT("info",("spider spider=%p", spider)); DBUG_PRINT("info",("spider conn=%p", conn)); DBUG_PRINT("info",("spider link_idx=%d", link_idx)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - DBUG_ASSERT(conn->conn_kind != SPIDER_CONN_KIND_MYSQL); - if (conn->conn_kind == SPIDER_CONN_KIND_HS_READ) - { - if (spider_bit_is_set(spider->result_list.hs_r_bulk_open_index, link_idx)) - { - DBUG_PRINT("info",("spider SPIDER_CONN_KIND_HS_READ")); - spider_clear_bit(spider->result_list.hs_r_bulk_open_index, link_idx); - opening_index = TRUE; - } - } else { - if (spider_bit_is_set(spider->result_list.hs_w_bulk_open_index, link_idx)) - { - DBUG_PRINT("info",("spider SPIDER_CONN_KIND_HS_WRITE")); - spider_clear_bit(spider->result_list.hs_w_bulk_open_index, link_idx); - opening_index = TRUE; - } - } - if (opening_index) - { - DBUG_PRINT("info",("spider conn->connection_id=%llu", - conn->connection_id)); - DBUG_PRINT("info",("spider spider->connection_ids[%d]=%llu", - link_idx, spider->connection_ids[link_idx])); - if (conn->connection_id != spider->connection_ids[link_idx]) - { - my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM, - ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0)); - DBUG_RETURN(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM); - } - - bool tmp_mta_conn_mutex_unlock_later; - pthread_mutex_assert_owner(&conn->mta_conn_mutex); - tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later; - conn->mta_conn_mutex_unlock_later = TRUE; - SPIDER_DB_RESULT *result; - if (spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_clear_bit(spider->db_request_phase, link_idx); - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - if (!(result = conn->db_conn->use_result(spider, &request_key, - &error_num))) - { - if (!error_num) - { - spider_db_errorno(conn); - error_num = ER_SPIDER_HS_NUM; - } - } else { - result->free_result(); - delete result; - } - conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later; - } -#endif DBUG_RETURN(error_num); } #endif @@ -12736,10 +11660,6 @@ int spider_db_close_handler( conn->mta_conn_mutex_unlock_later = TRUE; if (spider->handler_opened(link_idx, tgt_conn_kind)) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL) - { -#endif dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER); if ((error_num = dbton_hdl->append_close_handler_part( SPIDER_SQL_TYPE_HANDLER, link_idx))) @@ -12766,14 +11686,6 @@ int spider_db_close_handler( goto error; } dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { -/* - conn->hs_conn->close(); - conn->server_lost = TRUE; -*/ - } -#endif if ((error_num = dbton_hdl->delete_opened_handler(conn, link_idx))) goto error; conn->opened_handlers--; @@ -12797,23 +11709,6 @@ error: DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -void spider_db_hs_request_buf_reset( - SPIDER_CONN *conn -) { - DBUG_ENTER("spider_db_hs_request_buf_reset"); - if (conn->bulk_access_requests) - { - if (conn->db_conn->is_connected()) - { - conn->db_conn->reset_request_queue(); - } - conn->bulk_access_requests = 0; - } - DBUG_VOID_RETURN; -} -#endif - bool spider_db_conn_is_network_error( int error_num ) { diff --git a/storage/spider/spd_db_conn.h b/storage/spider/spd_db_conn.h index 996e6e24419..b87c57bc4ab 100644 --- a/storage/spider/spd_db_conn.h +++ b/storage/spider/spd_db_conn.h @@ -1217,12 +1217,6 @@ int spider_db_close_handler( uint tgt_conn_kind ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -void spider_db_hs_request_buf_reset( - SPIDER_CONN *conn -); -#endif - bool spider_db_conn_is_network_error( int error_num ); diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc deleted file mode 100644 index 030201e61ae..00000000000 --- a/storage/spider/spd_db_handlersocket.cc +++ /dev/null @@ -1,6362 +0,0 @@ -/* Copyright (C) 2012-2018 Kentoku Shiba - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ - -#define MYSQL_SERVER 1 -#include <my_global.h> -#include "mysql_version.h" -#include "spd_environ.h" -#if MYSQL_VERSION_ID < 50500 -#include "mysql_priv.h" -#include <mysql/plugin.h> -#else -#include "sql_priv.h" -#include "probes_mysql.h" -#include "sql_analyse.h" -#endif - -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#include "spd_err.h" -#include "spd_param.h" -#include "spd_db_include.h" -#include "spd_include.h" -#include "spd_db_handlersocket.h" -#include "ha_spider.h" -#include "spd_db_conn.h" -#include "spd_trx.h" -#include "spd_conn.h" -#include "spd_malloc.h" - -extern handlerton *spider_hton_ptr; -extern HASH spider_open_connections; -extern HASH spider_ipport_conns; -extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; -extern const char spider_dig_upper[]; - -#define SPIDER_SQL_INTERVAL_STR " + interval " -#define SPIDER_SQL_INTERVAL_LEN (sizeof(SPIDER_SQL_INTERVAL_STR) - 1) -#define SPIDER_SQL_NEGINTERVAL_STR " - interval " -#define SPIDER_SQL_NEGINTERVAL_LEN (sizeof(SPIDER_SQL_NEGINTERVAL_STR) - 1) - -#define SPIDER_SQL_NAME_QUOTE_STR "" -#define SPIDER_SQL_NAME_QUOTE_LEN (sizeof(SPIDER_SQL_NAME_QUOTE_STR) - 1) -static const char *name_quote_str = SPIDER_SQL_NAME_QUOTE_STR; - -#define SPIDER_SQL_TYPE_FULL_HS (SPIDER_SQL_TYPE_SELECT_HS | \ - SPIDER_SQL_TYPE_INSERT_HS | SPIDER_SQL_TYPE_UPDATE_HS | \ - SPIDER_SQL_TYPE_DELETE_HS | SPIDER_SQL_TYPE_OTHER_HS) - -static uchar SPIDER_SQL_LINESTRING_HEAD_STR[] = - {0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00}; -#define SPIDER_SQL_LINESTRING_HEAD_LEN sizeof(SPIDER_SQL_LINESTRING_HEAD_STR) - -static const char *spider_db_timefunc_interval_str[] = -{ - " year", " quarter", " month", " week", " day", - " hour", " minute", " second", " microsecond", - " year_month", " day_hour", " day_minute", - " day_second", " hour_minute", " hour_second", - " minute_second", " day_microsecond", " hour_microsecond", - " minute_microsecond", " second_microsecond" -}; - -static SPIDER_HS_STRING_REF spider_null_string_ref = SPIDER_HS_STRING_REF(); - -int spider_handlersocket_init() -{ - DBUG_ENTER("spider_handlersocket_init"); - DBUG_RETURN(0); -} - -int spider_handlersocket_deinit() -{ - DBUG_ENTER("spider_handlersocket_deinit"); - DBUG_RETURN(0); -} - -spider_db_share *spider_handlersocket_create_share( - SPIDER_SHARE *share -) { - DBUG_ENTER("spider_handlersocket_create_share"); - DBUG_RETURN(new spider_handlersocket_share(share)); -} - -spider_db_handler *spider_handlersocket_create_handler( - ha_spider *spider, - spider_db_share *db_share -) { - DBUG_ENTER("spider_handlersocket_create_handler"); - DBUG_RETURN(new spider_handlersocket_handler(spider, - (spider_handlersocket_share *) db_share)); -} - -SPIDER_DB_CONN *spider_handlersocket_create_conn( - SPIDER_CONN *conn -) { - DBUG_ENTER("spider_handlersocket_create_conn"); - DBUG_RETURN(new spider_db_handlersocket(conn)); -} - -bool spider_handlersocket_support_direct_join( -) { - DBUG_ENTER("spider_handlersocket_support_direct_join"); - DBUG_RETURN(FALSE); -} - -spider_db_handlersocket_util spider_db_handlersocket_utility; - -SPIDER_DBTON spider_dbton_handlersocket = { - 0, - SPIDER_DB_WRAPPER_MYSQL, - SPIDER_DB_ACCESS_TYPE_NOSQL, - spider_handlersocket_init, - spider_handlersocket_deinit, - spider_handlersocket_create_share, - spider_handlersocket_create_handler, - NULL, - spider_handlersocket_create_conn, - spider_handlersocket_support_direct_join, - &spider_db_handlersocket_utility, - "For communicating using the handlersocket protocol", - "0.1.0", - SPIDER_MATURITY_BETA -}; - -#ifndef HANDLERSOCKET_MYSQL_UTIL -spider_db_hs_string_ref_buffer::spider_db_hs_string_ref_buffer() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::spider_db_hs_string_ref_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -spider_db_hs_string_ref_buffer::~spider_db_hs_string_ref_buffer() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::~spider_db_hs_string_ref_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -int spider_db_hs_string_ref_buffer::init() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::init"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -void spider_db_hs_string_ref_buffer::clear() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::clear"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_conds.clear(); - DBUG_VOID_RETURN; -} - -int spider_db_hs_string_ref_buffer::push_back( - SPIDER_HS_STRING_REF &cond -) { - DBUG_ENTER("spider_db_hs_string_ref_buffer::push_back"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_conds.push_back(cond); - DBUG_RETURN(0); -} - -SPIDER_HS_STRING_REF *spider_db_hs_string_ref_buffer::ptr() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::ptr"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(&hs_conds[0]); -} - -uint spider_db_hs_string_ref_buffer::size() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::size"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN((uint) hs_conds.size()); -} -#else -spider_db_hs_string_ref_buffer::spider_db_hs_string_ref_buffer() : hs_da_init(FALSE) -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::spider_db_hs_string_ref_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -spider_db_hs_string_ref_buffer::~spider_db_hs_string_ref_buffer() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::~spider_db_hs_string_ref_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - if (hs_da_init) - { - spider_free_mem_calc(spider_current_trx, - hs_conds_id, hs_conds.max_element * hs_conds.size_of_element); - delete_dynamic(&hs_conds); - } - DBUG_VOID_RETURN; -} - -int spider_db_hs_string_ref_buffer::init() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::init"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!hs_da_init) - { - SPD_INIT_DYNAMIC_ARRAY2(&hs_conds, sizeof(SPIDER_HS_STRING_REF), - NULL, 16, 16, MYF(MY_WME)); - spider_alloc_calc_mem_init(hs_conds, 159); - spider_alloc_calc_mem(spider_current_trx, - hs_conds, hs_conds.max_element * hs_conds.size_of_element); - hs_da_init = TRUE; - } - DBUG_RETURN(0); -} - -void spider_db_hs_string_ref_buffer::clear() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::clear"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_conds.elements = 0; - DBUG_VOID_RETURN; -} - -int spider_db_hs_string_ref_buffer::push_back( - SPIDER_HS_STRING_REF &cond -) { - uint old_elements = hs_conds.max_element; - DBUG_ENTER("spider_db_hs_string_ref_buffer::push_back"); - DBUG_PRINT("info",("spider this=%p", this)); - if (insert_dynamic(&hs_conds, (uchar *) &cond)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (hs_conds.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - hs_conds, - (hs_conds.max_element - old_elements) * hs_conds.size_of_element); - } - DBUG_RETURN(0); -} - -SPIDER_HS_STRING_REF *spider_db_hs_string_ref_buffer::ptr() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::ptr"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN((SPIDER_HS_STRING_REF *) hs_conds.buffer); -} - -uint spider_db_hs_string_ref_buffer::size() -{ - DBUG_ENTER("spider_db_hs_string_ref_buffer::size"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(hs_conds.elements); -} -#endif - -spider_db_hs_str_buffer::spider_db_hs_str_buffer() : hs_da_init(FALSE) -{ - DBUG_ENTER("spider_db_hs_str_buffer::spider_db_hs_str_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -spider_db_hs_str_buffer::~spider_db_hs_str_buffer() -{ - DBUG_ENTER("spider_db_hs_str_buffer::~spider_db_hs_str_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - if (hs_da_init) - { - spider_free_mem_calc(spider_current_trx, - hs_conds_id, hs_conds.max_element * hs_conds.size_of_element); - delete_dynamic(&hs_conds); - } - DBUG_VOID_RETURN; -} - -int spider_db_hs_str_buffer::init() -{ - DBUG_ENTER("spider_db_hs_str_buffer::init"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!hs_da_init) - { - SPD_INIT_DYNAMIC_ARRAY2(&hs_conds, sizeof(spider_string *), - NULL, 16, 16, MYF(MY_WME)); - spider_alloc_calc_mem_init(hs_conds, 160); - spider_alloc_calc_mem(spider_current_trx, - hs_conds, hs_conds.max_element * hs_conds.size_of_element); - hs_da_init = TRUE; - } - DBUG_RETURN(0); -} - -void spider_db_hs_str_buffer::clear() -{ - uint i; - spider_string *element; - DBUG_ENTER("spider_db_hs_str_buffer::clear"); - DBUG_PRINT("info",("spider this=%p", this)); - for (i = 0; i < hs_conds.elements; i++) - { - get_dynamic(&hs_conds, (uchar *) &element, i); - element->free(); - spider_free(spider_current_trx, element, MYF(0)); - } - hs_conds.elements = 0; - DBUG_VOID_RETURN; -} - -spider_string *spider_db_hs_str_buffer::add( - uint *strs_pos, - const char *str, - uint str_len -) { - spider_string *element; - DBUG_ENTER("spider_db_hs_str_buffer::add"); - DBUG_PRINT("info",("spider this=%p", this)); - if (hs_conds.elements <= *strs_pos + 1) - { - if (!(element = (spider_string *) spider_malloc(spider_current_trx, 8, - sizeof(spider_string), MYF(MY_WME | MY_ZEROFILL)))) - DBUG_RETURN(NULL); - element->init_calc_mem(98); - element->set_charset(&my_charset_bin); - if ((element->reserve(str_len + 1))) - { - spider_free(spider_current_trx, element, MYF(0)); - DBUG_RETURN(NULL); - } - element->q_append(str, str_len); - uint old_elements = hs_conds.max_element; - if (insert_dynamic(&hs_conds, (uchar *) &element)) - { - element->free(); - spider_free(spider_current_trx, element, MYF(0)); - DBUG_RETURN(NULL); - } - if (hs_conds.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - hs_conds, - (hs_conds.max_element - old_elements) * - hs_conds.size_of_element); - } - } else { - element = ((spider_string **) hs_conds.buffer)[*strs_pos]; - element->length(0); - if ((element->reserve(str_len + 1))) - DBUG_RETURN(NULL); - element->q_append(str, str_len); - } - (*strs_pos)++; - DBUG_RETURN(element); -} - -spider_db_handlersocket_row::spider_db_handlersocket_row() : - spider_db_row(spider_dbton_handlersocket.dbton_id), - hs_row(NULL), field_count(0), row_size(0), cloned(FALSE) -{ - DBUG_ENTER("spider_db_handlersocket_row::spider_db_handlersocket_row"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -spider_db_handlersocket_row::~spider_db_handlersocket_row() -{ - DBUG_ENTER("spider_db_handlersocket_row::~spider_db_handlersocket_row"); - DBUG_PRINT("info",("spider this=%p", this)); - if (cloned) - { - spider_free(spider_current_trx, hs_row_first, MYF(0)); - } - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket_row::store_to_field( - Field *field, - CHARSET_INFO *access_charset -) { - DBUG_ENTER("spider_db_handlersocket_row::store_to_field"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!hs_row->begin()) - { - DBUG_PRINT("info", ("spider field is null")); - field->set_null(); - field->reset(); - } else { -#ifndef DBUG_OFF - char buf[MAX_FIELD_WIDTH]; - spider_string tmp_str(buf, MAX_FIELD_WIDTH, field->charset()); - tmp_str.init_calc_mem(119); - tmp_str.length(0); - tmp_str.append(hs_row->begin(), hs_row->size(), &my_charset_bin); - DBUG_PRINT("info", ("spider val=%s", tmp_str.c_ptr_safe())); -#endif - field->set_notnull(); - if (field->flags & BLOB_FLAG) - { - DBUG_PRINT("info", ("spider blob field")); - ((Field_blob *)field)->set_ptr( - hs_row->size(), (uchar *) hs_row->begin()); - } else - field->store(hs_row->begin(), hs_row->size(), &my_charset_bin); - } - DBUG_RETURN(0); -} - -int spider_db_handlersocket_row::append_to_str( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_row::append_to_str"); - DBUG_PRINT("info",("spider this=%p", this)); - if (str->reserve(hs_row->size())) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(hs_row->begin(), hs_row->size()); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_row::append_escaped_to_str( - spider_string *str, - uint dbton_id -) { - DBUG_ENTER("spider_db_handlersocket_row::append_escaped_to_str"); - DBUG_PRINT("info",("spider this=%p", this)); - spider_string tmp_str(hs_row->begin(), hs_row->size() + 1, &my_charset_bin); - tmp_str.init_calc_mem(172); - tmp_str.length(hs_row->size()); - if (str->reserve(hs_row->size() * 2 + 2)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - spider_dbton[dbton_id].db_util->append_escaped_util(str, tmp_str.get_str()); - str->mem_calc(); - DBUG_RETURN(0); -} - -void spider_db_handlersocket_row::first() -{ - DBUG_ENTER("spider_db_handlersocket_row::first"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_row = hs_row_first; - DBUG_VOID_RETURN; -} - -void spider_db_handlersocket_row::next() -{ - DBUG_ENTER("spider_db_handlersocket_row::next"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_row++; - DBUG_VOID_RETURN; -} - -bool spider_db_handlersocket_row::is_null() -{ - DBUG_ENTER("spider_db_handlersocket_row::is_null"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(!hs_row->begin()); -} - -int spider_db_handlersocket_row::val_int() -{ - DBUG_ENTER("spider_db_handlersocket_row::val_int"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(atoi(hs_row->begin())); -} - -double spider_db_handlersocket_row::val_real() -{ - DBUG_ENTER("spider_db_handlersocket_row::val_real"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(hs_row->begin() ? my_atof(hs_row->begin()) : 0.0); -} - -my_decimal *spider_db_handlersocket_row::val_decimal( - my_decimal *decimal_value, - CHARSET_INFO *access_charset -) { - DBUG_ENTER("spider_db_handlersocket_row::val_decimal"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!hs_row->begin()) - DBUG_RETURN(NULL); - -#ifdef SPIDER_HAS_DECIMAL_OPERATION_RESULTS_VALUE_TYPE - decimal_operation_results(str2my_decimal(0, hs_row->begin(), hs_row->size(), - access_charset, decimal_value), "", ""); -#else - decimal_operation_results(str2my_decimal(0, hs_row->begin(), hs_row->size(), - access_charset, decimal_value)); -#endif - - DBUG_RETURN(decimal_value); -} - -SPIDER_DB_ROW *spider_db_handlersocket_row::clone() -{ - spider_db_handlersocket_row *clone_row; - char *tmp_char; - uint i; - DBUG_ENTER("spider_db_handlersocket_row::clone"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(clone_row = new spider_db_handlersocket_row(dbton_id))) - { - DBUG_RETURN(NULL); - } - if (!spider_bulk_malloc(spider_current_trx, 169, MYF(MY_WME), - &clone_row->hs_row, (uint) (sizeof(SPIDER_HS_STRING_REF) * field_count), - &tmp_char, (uint) (row_size), - NullS) - ) { - delete clone_row; - DBUG_RETURN(NULL); - } - for (i = 0; i < field_count; i++) - { - memcpy(tmp_char, hs_row_first[i].begin(), hs_row_first[i].size()); - clone_row->hs_row[i].set(tmp_char, hs_row_first[i].size()); - tmp_char += hs_row_first[i].size(); - } - clone_row->hs_row_first = clone_row->hs_row; - clone_row->cloned = TRUE;; - clone_row->row_size = row_size;; - DBUG_RETURN(NULL); -} - -int spider_db_handlersocket_row::store_to_tmp_table( - TABLE *tmp_table, - spider_string *str -) { - uint i; - SPIDER_HS_STRING_REF *tmp_hs_row = hs_row; - DBUG_ENTER("spider_db_handlersocket_row::store_to_tmp_table"); - DBUG_PRINT("info",("spider this=%p", this)); - str->length(0); - for (i = 0; i < field_count; i++) - { - if (tmp_hs_row->begin()) - { - if (str->reserve(tmp_hs_row->size())) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(tmp_hs_row->begin(), tmp_hs_row->size()); - } - tmp_hs_row++; - } - tmp_table->field[0]->set_notnull(); - tmp_table->field[0]->store( - (const char *) hs_row, - sizeof(SPIDER_HS_STRING_REF) * field_count, &my_charset_bin); - tmp_table->field[1]->set_notnull(); - tmp_table->field[1]->store( - str->ptr(), str->length(), &my_charset_bin); - tmp_table->field[2]->set_null(); - DBUG_RETURN(tmp_table->file->ha_write_row(tmp_table->record[0])); -} - -uint spider_db_handlersocket_row::get_byte_size() -{ - DBUG_ENTER("spider_db_handlersocket_row::get_byte_size"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(row_size); -} - - -spider_db_handlersocket_result_buffer::spider_db_handlersocket_result_buffer( -) : spider_db_result_buffer() -{ - DBUG_ENTER("spider_db_handlersocket_result_buffer::spider_db_handlersocket_result_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -spider_db_handlersocket_result_buffer::~spider_db_handlersocket_result_buffer() -{ - DBUG_ENTER( - "spider_db_handlersocket_result_buffer::~spider_db_handlersocket_result_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -void spider_db_handlersocket_result_buffer::clear() -{ - DBUG_ENTER("spider_db_handlersocket_result_buffer::clear"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_result.readbuf.clear(); - DBUG_VOID_RETURN; -} - -bool spider_db_handlersocket_result_buffer::check_size( - longlong size -) { - DBUG_ENTER("spider_db_handlersocket_result_buffer::check_size"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((uint) hs_result.readbuf.real_size() > size) - { - hs_result.readbuf.real_free(); - DBUG_RETURN(TRUE); - } - DBUG_RETURN(FALSE); -} - -spider_db_handlersocket_result::spider_db_handlersocket_result( - SPIDER_DB_CONN *in_db_conn -) : spider_db_result(in_db_conn), row(in_db_conn->dbton_id) -{ - DBUG_ENTER("spider_db_handlersocket_result::spider_db_handlersocket_result"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -spider_db_handlersocket_result::~spider_db_handlersocket_result() -{ - DBUG_ENTER( - "spider_db_handlersocket_result::~spider_db_handlersocket_result"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -bool spider_db_handlersocket_result::has_result() -{ - DBUG_ENTER("spider_db_handlersocket_result::has_result"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(((*hs_conn_p)->get_response_end_offset() > 0)); -} - -void spider_db_handlersocket_result::free_result() -{ - DBUG_ENTER("spider_db_handlersocket_result::free_result"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if ((*hs_conn_p)->get_response_end_offset() > 0) - { - (*hs_conn_p)->response_buf_remove(); - if ((*hs_conn_p)->get_error_code()) - { - DBUG_PRINT("info",("spider hs %d %s", - (*hs_conn_p)->get_error_code(), - (*hs_conn_p)->get_error().ptr())); - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - } - DBUG_VOID_RETURN; -} - -SPIDER_DB_ROW *spider_db_handlersocket_result::current_row() -{ - DBUG_ENTER("spider_db_handlersocket_result::current_row"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN((SPIDER_DB_ROW *) row.clone()); -} - -SPIDER_DB_ROW *spider_db_handlersocket_result::fetch_row() -{ - DBUG_ENTER("spider_db_handlersocket_result::fetch_row"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(row.hs_row = (SPIDER_HS_STRING_REF *) - (*hs_conn_p)->get_next_row())) - { - store_error_num = HA_ERR_END_OF_FILE; - DBUG_RETURN(NULL); - } - row.field_count = field_count; - row.hs_row_first = row.hs_row; - row.row_size = (*hs_conn_p)->get_row_size(); - DBUG_RETURN((SPIDER_DB_ROW *) &row); -} - -SPIDER_DB_ROW *spider_db_handlersocket_result::fetch_row_from_result_buffer( - spider_db_result_buffer *spider_res_buf -) { - spider_db_handlersocket_result_buffer *hs_res_buf; - DBUG_ENTER("spider_db_handlersocket_result::fetch_row_from_result_buffer"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_res_buf = (spider_db_handlersocket_result_buffer *) spider_res_buf; - if (!(row.hs_row = (SPIDER_HS_STRING_REF *) - (*hs_conn_p)->get_next_row_from_result(hs_res_buf->hs_result))) - { - store_error_num = HA_ERR_END_OF_FILE; - DBUG_RETURN(NULL); - } - row.field_count = field_count; - row.hs_row_first = row.hs_row; - row.row_size = (*hs_conn_p)->get_row_size_from_result(hs_res_buf->hs_result); - DBUG_RETURN((SPIDER_DB_ROW *) &row); -} - -SPIDER_DB_ROW *spider_db_handlersocket_result::fetch_row_from_tmp_table( - TABLE *tmp_table -) { - uint i; - spider_string tmp_str1, tmp_str2; - const char *row_ptr; - SPIDER_HS_STRING_REF *tmp_hs_row; - uint field_count; - DBUG_ENTER("spider_db_handlersocket_result::fetch_row_from_tmp_table"); - DBUG_PRINT("info",("spider this=%p", this)); - tmp_str1.init_calc_mem(171); - tmp_str2.init_calc_mem(173); - tmp_table->field[0]->val_str(tmp_str1.get_str()); - tmp_table->field[1]->val_str(tmp_str2.get_str()); - tmp_str1.mem_calc(); - tmp_str2.mem_calc(); - row_ptr = tmp_str2.ptr(); - tmp_hs_row = (SPIDER_HS_STRING_REF *) tmp_str1.ptr(); - field_count = tmp_str1.length() / sizeof(SPIDER_HS_STRING_REF); - row.hs_row = tmp_hs_row; - row.field_count = field_count; - row.hs_row_first = row.hs_row; - for (i = 0; i < field_count; i++) - { - if (tmp_hs_row->begin()) - { - uint length = tmp_hs_row->size(); - tmp_hs_row->set(row_ptr, length); - row_ptr += length; - } - tmp_hs_row++; - } - row.row_size = row_ptr - tmp_str2.ptr(); - DBUG_RETURN((SPIDER_DB_ROW *) &row); -} - -int spider_db_handlersocket_result::fetch_table_status( - int mode, - ha_statistics &stat -) { - DBUG_ENTER("spider_db_handlersocket_result::fetch_table_status"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_result::fetch_table_records( - int mode, - ha_rows &records -) { - DBUG_ENTER("spider_db_handlersocket_result::fetch_table_records"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_result::fetch_table_cardinality( - int mode, - TABLE *table, - longlong *cardinality, - uchar *cardinality_upd, - int bitmap_size -) { - DBUG_ENTER("spider_db_handlersocket_result::fetch_table_cardinality"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_result::fetch_table_mon_status( - int &status -) { - DBUG_ENTER("spider_db_handlersocket_result::fetch_table_mon_status"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -longlong spider_db_handlersocket_result::num_rows() -{ - DBUG_ENTER("spider_db_handlersocket_result::num_rows"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN((longlong) 0); -} - -uint spider_db_handlersocket_result::num_fields() -{ - DBUG_ENTER("spider_db_handlersocket_result::num_fields"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(field_count); -} - -void spider_db_handlersocket_result::move_to_pos( - longlong pos -) { - DBUG_ENTER("spider_db_handlersocket_result::move_to_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket_result::get_errno() -{ - DBUG_ENTER("spider_db_handlersocket_result::get_errno"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider store_error_num=%d", store_error_num)); - DBUG_RETURN(store_error_num); -} - -#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE -int spider_db_handlersocket_result::fetch_columns_for_discover_table_structure( - spider_string *str, - CHARSET_INFO *access_charset -) { - DBUG_ENTER("spider_db_handlersocket_result::fetch_columns_for_discover_table_structure"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -} - -int spider_db_handlersocket_result::fetch_index_for_discover_table_structure( - spider_string *str, - CHARSET_INFO *access_charset -) { - DBUG_ENTER("spider_db_handlersocket_result::fetch_index_for_discover_table_structure"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -} - -int spider_db_handlersocket_result::fetch_table_for_discover_table_structure( - spider_string *str, - SPIDER_SHARE *spider_share, - CHARSET_INFO *access_charset -) { - DBUG_ENTER("spider_db_handlersocket_result::fetch_table_for_discover_table_structure"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -} -#endif - -spider_db_handlersocket::spider_db_handlersocket( - SPIDER_CONN *conn -) : spider_db_conn(conn), - handler_open_array_inited(FALSE), - request_key_req_first(NULL), - request_key_req_last(NULL), - request_key_snd_first(NULL), - request_key_snd_last(NULL), - request_key_reuse_first(NULL), - request_key_reuse_last(NULL) -{ - DBUG_ENTER("spider_db_handlersocket::spider_db_handlersocket"); - DBUG_PRINT("info",("spider this=%p", this)); -#ifndef HANDLERSOCKET_MYSQL_UTIL -#else - hs_conn = NULL; -#endif - DBUG_VOID_RETURN; -} - -spider_db_handlersocket::~spider_db_handlersocket() -{ - st_spider_db_request_key *tmp_request_key; - DBUG_ENTER("spider_db_handlersocket::~spider_db_handlersocket"); - DBUG_PRINT("info",("spider this=%p", this)); - if (handler_open_array_inited) - { - reset_opened_handler(); - spider_free_mem_calc(spider_current_trx, - handler_open_array_id, - handler_open_array.max_element * - handler_open_array.size_of_element); - delete_dynamic(&handler_open_array); - } - while (request_key_req_first) - { - tmp_request_key = request_key_req_first->next; - spider_free(spider_current_trx, request_key_req_first, MYF(0)); - request_key_req_first = tmp_request_key; - } - while (request_key_snd_first) - { - tmp_request_key = request_key_snd_first->next; - spider_free(spider_current_trx, request_key_snd_first, MYF(0)); - request_key_snd_first = tmp_request_key; - } - while (request_key_reuse_first) - { - tmp_request_key = request_key_reuse_first->next; - spider_free(spider_current_trx, request_key_reuse_first, MYF(0)); - request_key_reuse_first = tmp_request_key; - } - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket::init() -{ - DBUG_ENTER("spider_db_handlersocket::init"); - DBUG_PRINT("info",("spider this=%p", this)); - if ( - SPD_INIT_DYNAMIC_ARRAY2(&handler_open_array, - sizeof(SPIDER_LINK_FOR_HASH *), NULL, 16, 16, MYF(MY_WME)) - ) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - spider_alloc_calc_mem_init(handler_open_array, 79); - spider_alloc_calc_mem(spider_current_trx, - handler_open_array, - handler_open_array.max_element * - handler_open_array.size_of_element); - handler_open_array_inited = TRUE; - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::is_connected() -{ - DBUG_ENTER("spider_db_handlersocket::is_connected"); - DBUG_PRINT("info",("spider this=%p", this)); -#ifndef HANDLERSOCKET_MYSQL_UTIL - DBUG_RETURN(hs_conn.operator->()); -#else - DBUG_RETURN(hs_conn); -#endif -} - -void spider_db_handlersocket::bg_connect() -{ - DBUG_ENTER("spider_db_handlersocket::bg_connect"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket::connect( - char *tgt_host, - char *tgt_username, - char *tgt_password, - long tgt_port, - char *tgt_socket, - char *server_name, - int connect_retry_count, - longlong connect_retry_interval -) { - DBUG_ENTER("spider_db_handlersocket::connect"); - DBUG_PRINT("info",("spider this=%p", this)); - SPIDER_HS_SOCKARGS sockargs; - sockargs.timeout = conn->connect_timeout; - sockargs.recv_timeout = conn->net_read_timeout; - sockargs.send_timeout = conn->net_write_timeout; - if (conn->hs_sock) - { - sockargs.family = AF_UNIX; - sockargs.set_unix_domain(conn->hs_sock); - } else { - char port_str[6]; - my_sprintf(port_str, (port_str, "%05ld", conn->hs_port)); - if (sockargs.resolve(conn->tgt_host, port_str) != 0) - { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), - conn->tgt_host); - DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE); - } - } -#ifndef HANDLERSOCKET_MYSQL_UTIL - if (!(hs_conn.operator->())) -#else - if (!(hs_conn)) -#endif - { - hs_conn = SPIDER_HS_CONN_CREATE(sockargs); - } else { - hs_conn->reconnect(); - spider_db_hs_request_buf_reset(conn); - } -#ifndef HANDLERSOCKET_MYSQL_UTIL - if (!(hs_conn.operator->())) -#else - if (!(hs_conn)) -#endif - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - while (hs_conn->get_error_code()) - { - THD *thd = current_thd; - if ( - !connect_retry_count || - (thd && thd->killed) - ) { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), - conn->tgt_host); - DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE); - } - connect_retry_count--; - my_sleep((ulong) connect_retry_interval); - hs_conn->reconnect(); - } - reset_request_key_req(); - reset_request_key_snd(); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::ping() -{ - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::ping"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if ((*hs_conn_p)->reconnect()) - { - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - DBUG_RETURN(ER_SPIDER_HS_NUM); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - - reset_request_key_req(); - reset_request_key_snd(); - conn->opened_handlers = 0; - conn->db_conn->reset_opened_handler(); - ++conn->connection_id; - DBUG_RETURN(0); -} - -void spider_db_handlersocket::bg_disconnect() -{ - DBUG_ENTER("spider_db_handlersocket::bg_disconnect"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -void spider_db_handlersocket::disconnect() -{ - DBUG_ENTER("spider_db_handlersocket::disconnect"); - DBUG_PRINT("info",("spider this=%p", this)); -#ifndef HANDLERSOCKET_MYSQL_UTIL - if (hs_conn.operator->()) -#else - DBUG_PRINT("info",("spider hs_conn=%p", hs_conn)); - if (hs_conn) -#endif - { - hs_conn->close(); -#ifndef HANDLERSOCKET_MYSQL_UTIL - SPIDER_HS_CONN tmp_hs_conn; - tmp_hs_conn = hs_conn; -#else - delete hs_conn; - hs_conn = NULL; -#endif - } - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket::set_net_timeout() -{ - DBUG_ENTER("spider_db_handlersocket::set_net_timeout"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(hs_conn->set_timeout( - conn->net_write_timeout, - conn->net_read_timeout - )); -} - -int spider_db_handlersocket::exec_query( - const char *query, - uint length, - int quick_mode -) { - DBUG_ENTER("spider_db_handlersocket::query"); - DBUG_PRINT("info",("spider this=%p", this)); - SPIDER_HS_CONN *hs_conn_p = &hs_conn; -#ifndef HANDLERSOCKET_MYSQL_UTIL - DBUG_PRINT("info", ("spider hs_conn %p", hs_conn.operator->())); -#else - DBUG_PRINT("info", ("spider hs_conn %p", hs_conn)); -#endif - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if (spider_param_general_log()) - { - const char *tgt_str = conn->hs_sock ? conn->hs_sock : conn->tgt_host; - uint32 tgt_len = strlen(tgt_str); - spider_string tmp_query_str((*hs_conn_p)->get_writebuf_size() + - conn->tgt_wrapper_length + - tgt_len + (SPIDER_SQL_SPACE_LEN * 2)); - tmp_query_str.init_calc_mem(231); - tmp_query_str.length(0); - tmp_query_str.q_append(conn->tgt_wrapper, conn->tgt_wrapper_length); - tmp_query_str.q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); - tmp_query_str.q_append(tgt_str, tgt_len); - tmp_query_str.q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); - tmp_query_str.q_append((*hs_conn_p)->get_writebuf_begin(), - (*hs_conn_p)->get_writebuf_size()); - general_log_write(current_thd, COM_QUERY, tmp_query_str.ptr(), - tmp_query_str.length()); - } - if ((*hs_conn_p)->request_send() < 0) - { - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - DBUG_RETURN(ER_SPIDER_HS_NUM); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - move_request_key_to_snd(); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::get_errno() -{ - DBUG_ENTER("spider_db_handlersocket::get_errno"); - DBUG_PRINT("info",("spider this=%p", this)); - stored_error = hs_conn->get_error_code(); - DBUG_PRINT("info",("spider stored_error=%d", stored_error)); - DBUG_RETURN(stored_error); -} - -const char *spider_db_handlersocket::get_error() -{ - const char *error_ptr; - DBUG_ENTER("spider_db_handlersocket::get_error"); - DBUG_PRINT("info",("spider this=%p", this)); -#ifndef HANDLERSOCKET_MYSQL_UTIL - error_ptr = hs_conn->get_error().c_str(); -#else - error_ptr = hs_conn->get_error().c_ptr(); -#endif - DBUG_PRINT("info",("spider error=%s", error_ptr)); - DBUG_RETURN(error_ptr); -} - -bool spider_db_handlersocket::is_server_gone_error( - int error_num -) { - bool server_gone; - DBUG_ENTER("spider_db_handlersocket::is_server_gone_error"); - DBUG_PRINT("info",("spider this=%p", this)); - server_gone = (hs_conn->get_error_code() < 0); - DBUG_PRINT("info",("spider server_gone=%s", server_gone ? "TRUE" : "FALSE")); - DBUG_RETURN(server_gone); -} - -bool spider_db_handlersocket::is_dup_entry_error( - int error_num -) { - bool dup_entry; - DBUG_ENTER("spider_db_handlersocket::is_dup_entry_error"); - DBUG_PRINT("info",("spider this=%p", this)); -#ifndef HANDLERSOCKET_MYSQL_UTIL - const char *c_str = hs_conn->get_error().c_str(); -#else - const char *c_str = hs_conn->get_error().c_ptr_safe(); -#endif - dup_entry = - ( - c_str[0] == '1' && - c_str[1] == '2' && - c_str[2] == '1' && - c_str[3] == '\0' - ); - DBUG_PRINT("info",("spider dup_entry=%s", dup_entry ? "TRUE" : "FALSE")); - DBUG_RETURN(dup_entry); -} - -bool spider_db_handlersocket::is_xa_nota_error( - int error_num -) { - bool xa_nota; - DBUG_ENTER("spider_db_handlersocket::is_xa_nota_error"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - xa_nota = (stored_error == ER_XAER_NOTA); - DBUG_PRINT("info",("spider xa_nota=%s", xa_nota ? "TRUE" : "FALSE")); - DBUG_RETURN(xa_nota); -} - -spider_db_result *spider_db_handlersocket::store_result( - spider_db_result_buffer **spider_res_buf, - st_spider_db_request_key *request_key, - int *error_num -) { - int internal_error; - spider_db_handlersocket_result *result; - spider_db_handlersocket_result_buffer *hs_res_buf; - DBUG_ENTER("spider_db_handlersocket::store_result"); - DBUG_PRINT("info",("spider this=%p", this)); - if (*spider_res_buf) - { - hs_res_buf = (spider_db_handlersocket_result_buffer *) *spider_res_buf; - } else { - if (!(hs_res_buf = new spider_db_handlersocket_result_buffer())) - { - *error_num = HA_ERR_OUT_OF_MEM; - DBUG_RETURN(NULL); - } - *spider_res_buf = (spider_db_result_buffer *) hs_res_buf; - } - hs_res_buf->clear(); - if (!(result = new spider_db_handlersocket_result(this))) - { - *error_num = HA_ERR_OUT_OF_MEM; - DBUG_RETURN(NULL); - } - *error_num = 0; - result->hs_conn_p = &hs_conn; - size_t num_fields; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - if (request_key) - { - int tmp_res, tmp_err = (*hs_conn_p)->get_error_code(); - while ((tmp_res = check_request_key(request_key)) == 1) - { - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if ((internal_error = (*hs_conn_p)->response_recv(num_fields))) - { - if (!tmp_err && internal_error > 0) - { - (*hs_conn_p)->clear_error(); - } else { - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); -#ifndef DBUG_OFF - if ((*hs_conn_p)->get_response_end_offset() > 0 && - (*hs_conn_p)->get_readbuf_begin()) - { - char tmp_buf[MAX_FIELD_WIDTH]; - String tmp_str(tmp_buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.length(0); - tmp_str.append((*hs_conn_p)->get_readbuf_begin(), - (*hs_conn_p)->get_response_end_offset(), &my_charset_bin); - DBUG_PRINT("info",("spider hs readbuf01 size=%zu str=%s", - (*hs_conn_p)->get_response_end_offset(), tmp_str.c_ptr_safe())); - } -#endif - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if (internal_error > 0) - { - (*hs_conn_p)->response_buf_remove(); - if ((*hs_conn_p)->get_error_code()) - { - DBUG_PRINT("info",("spider hs %d %s", - (*hs_conn_p)->get_error_code(), - (*hs_conn_p)->get_error().ptr())); - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->clear_error(); - } - delete result; - DBUG_RETURN(NULL); - } - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->response_buf_remove(); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - } - if (tmp_res == -1) - { - DBUG_PRINT("info",("spider ER_SPIDER_REQUEST_KEY_NUM")); - *error_num = ER_SPIDER_REQUEST_KEY_NUM; - DBUG_RETURN(NULL); - } - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if ( - (internal_error = (*hs_conn_p)->response_recv(num_fields)) || - (*error_num = (*hs_conn_p)->get_result(hs_res_buf->hs_result)) - ) { - if (*error_num) - { - *error_num = HA_ERR_OUT_OF_MEM; - } - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); -#ifndef DBUG_OFF - if ((*hs_conn_p)->get_response_end_offset() > 0 && - (*hs_conn_p)->get_readbuf_begin()) - { - char tmp_buf[MAX_FIELD_WIDTH]; - String tmp_str(tmp_buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.length(0); - tmp_str.append((*hs_conn_p)->get_readbuf_begin(), - (*hs_conn_p)->get_response_end_offset(), &my_charset_bin); - DBUG_PRINT("info",("spider hs readbuf01 size=%zu str=%s", - (*hs_conn_p)->get_response_end_offset(), tmp_str.c_ptr_safe())); - } -#endif - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if (internal_error > 0) - { - (*hs_conn_p)->response_buf_remove(); - if ((*hs_conn_p)->get_error_code()) - { - DBUG_PRINT("info",("spider hs %d %s", - (*hs_conn_p)->get_error_code(), - (*hs_conn_p)->get_error().ptr())); - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - } - delete result; - DBUG_RETURN(NULL); - } -#ifndef DBUG_OFF - if ((*hs_conn_p)->get_response_end_offset() > 0 && - (*hs_conn_p)->get_readbuf_begin()) - { - char tmp_buf[MAX_FIELD_WIDTH]; - String tmp_str(tmp_buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.length(0); - tmp_str.append((*hs_conn_p)->get_readbuf_begin(), - (*hs_conn_p)->get_response_end_offset(), &my_charset_bin); - DBUG_PRINT("info",("spider hs readbuf02 size=%zu str=%s", - (*hs_conn_p)->get_response_end_offset(), tmp_str.c_ptr_safe())); - } -#endif - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->response_buf_remove(); - if ((*hs_conn_p)->get_error_code()) - { - DBUG_PRINT("info",("spider hs %d %s", - (*hs_conn_p)->get_error_code(), - (*hs_conn_p)->get_error().ptr())); - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - field_count = (uint) num_fields; - result->field_count = field_count; - DBUG_RETURN(result); -} - -spider_db_result *spider_db_handlersocket::use_result( - ha_spider *spider, - st_spider_db_request_key *request_key, - int *error_num -) { - int internal_error; - spider_db_handlersocket_result *result; - DBUG_ENTER("spider_db_handlersocket::use_result"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(result = new spider_db_handlersocket_result(this))) - { - *error_num = HA_ERR_OUT_OF_MEM; - DBUG_RETURN(NULL); - } - *error_num = 0; - result->hs_conn_p = &hs_conn; - size_t num_fields; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - if (request_key) - { - int tmp_res, tmp_err = (*hs_conn_p)->get_error_code(); - while ((tmp_res = check_request_key(request_key)) == 1) - { - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if ((internal_error = (*hs_conn_p)->response_recv(num_fields))) - { - if (!tmp_err && internal_error > 0) - { - (*hs_conn_p)->clear_error(); - } else { - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); -#ifndef DBUG_OFF - if ((*hs_conn_p)->get_response_end_offset() > 0 && - (*hs_conn_p)->get_readbuf_begin()) - { - char tmp_buf[MAX_FIELD_WIDTH]; - String tmp_str(tmp_buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.length(0); - tmp_str.append((*hs_conn_p)->get_readbuf_begin(), - (*hs_conn_p)->get_response_end_offset(), &my_charset_bin); - DBUG_PRINT("info",("spider hs readbuf01 size=%zu str=%s", - (*hs_conn_p)->get_response_end_offset(), tmp_str.c_ptr_safe())); - } -#endif - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if (internal_error > 0) - { - (*hs_conn_p)->response_buf_remove(); - if ((*hs_conn_p)->get_error_code()) - { - DBUG_PRINT("info",("spider hs %d %s", - (*hs_conn_p)->get_error_code(), - (*hs_conn_p)->get_error().ptr())); - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->clear_error(); - } - delete result; - DBUG_RETURN(NULL); - } - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->response_buf_remove(); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - } - if (tmp_res == -1) - { - DBUG_PRINT("info",("spider ER_SPIDER_REQUEST_KEY_NUM")); - *error_num = ER_SPIDER_REQUEST_KEY_NUM; - DBUG_RETURN(NULL); - } - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if ( - (internal_error = (*hs_conn_p)->response_recv(num_fields)) - ) { - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); -#ifndef DBUG_OFF - if ((*hs_conn_p)->get_response_end_offset() > 0 && - (*hs_conn_p)->get_readbuf_begin()) - { - char tmp_buf[MAX_FIELD_WIDTH]; - String tmp_str(tmp_buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.length(0); - tmp_str.append((*hs_conn_p)->get_readbuf_begin(), - (*hs_conn_p)->get_response_end_offset(), &my_charset_bin); - DBUG_PRINT("info",("spider hs readbuf01 size=%zu str=%s", - (*hs_conn_p)->get_response_end_offset(), tmp_str.c_ptr_safe())); - } -#endif - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if (internal_error > 0) - { - (*hs_conn_p)->response_buf_remove(); - if ((*hs_conn_p)->get_error_code()) - { - DBUG_PRINT("info",("spider hs %d %s", - (*hs_conn_p)->get_error_code(), - (*hs_conn_p)->get_error().ptr())); - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - } - delete result; - DBUG_RETURN(NULL); - } -#ifndef DBUG_OFF - if ((*hs_conn_p)->get_response_end_offset() > 0 && - (*hs_conn_p)->get_readbuf_begin()) - { - char tmp_buf[MAX_FIELD_WIDTH]; - String tmp_str(tmp_buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.length(0); - tmp_str.append((*hs_conn_p)->get_readbuf_begin(), - (*hs_conn_p)->get_response_end_offset(), &my_charset_bin); - DBUG_PRINT("info",("spider hs readbuf02 size=%zu str=%s", - (*hs_conn_p)->get_response_end_offset(), tmp_str.c_ptr_safe())); - } -#endif - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - field_count = (uint) num_fields; - result->field_count = field_count; - DBUG_RETURN(result); -} - -int spider_db_handlersocket::next_result() -{ - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::next_result"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - if ((*hs_conn_p)->stable_point()) - DBUG_RETURN(-1); - DBUG_RETURN(0); -} - -uint spider_db_handlersocket::affected_rows() -{ - int error_num; - const SPIDER_HS_STRING_REF *hs_row; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::affected_rows"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - if ( - field_count != 1 || - !(hs_row = (*hs_conn_p)->get_next_row()) || - !hs_row->begin() - ) { - DBUG_RETURN(0); - } - DBUG_RETURN((uint) my_strtoll10(hs_row->begin(), (char**) NULL, &error_num)); -} - -uint spider_db_handlersocket::matched_rows() -{ - DBUG_ENTER("spider_db_handlersocket::matched_rows"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::inserted_info( - spider_db_handler *handler, - ha_copy_info *copy_info -) { - DBUG_ENTER("spider_db_handlersocket::inserted_info"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -ulonglong spider_db_handlersocket::last_insert_id() -{ - DBUG_ENTER("spider_db_handlersocket::last_insert_id"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::set_character_set( - const char *csname -) { - DBUG_ENTER("spider_db_handlersocket::set_character_set"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::select_db( - const char *dbname -) { - DBUG_ENTER("spider_db_handlersocket::select_db"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::consistent_snapshot( - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::consistent_snapshot"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::trx_start_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::trx_start_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::start_transaction( - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::start_transaction"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::commit( - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::commit"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::rollback( - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::rollback"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::xa_start_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::xa_start_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::xa_start( - XID *xid, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::xa_start"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::xa_end( - XID *xid, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::xa_end"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::xa_prepare( - XID *xid, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::xa_prepare"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::xa_commit( - XID *xid, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::xa_commit"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::xa_rollback( - XID *xid, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::xa_rollback"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::set_trx_isolation_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::set_trx_isolation_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::set_trx_isolation( - int trx_isolation, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::set_trx_isolation"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::set_autocommit_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::set_autocommit_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::set_autocommit( - bool autocommit, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::set_autocommit"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::set_sql_log_off_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::set_sql_log_off_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::set_sql_log_off( - bool sql_log_off, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::set_sql_log_off"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::set_wait_timeout_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::set_wait_timeout_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::set_wait_timeout( - int wait_timeout, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::set_wait_timeout"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::set_sql_mode_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::set_sql_mode_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::set_sql_mode( - sql_mode_t sql_mode, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::set_sql_mode"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::set_time_zone_in_bulk_sql() -{ - DBUG_ENTER("spider_db_handlersocket::set_time_zone_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::set_time_zone( - Time_zone *time_zone, - int *need_mon -) { - DBUG_ENTER("spider_db_handlersocket::set_time_zone"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket::show_master_status( - SPIDER_TRX *trx, - SPIDER_SHARE *share, - int all_link_idx, - int *need_mon, - TABLE *table, - spider_string *str, - int mode, - SPIDER_DB_RESULT **res1, - SPIDER_DB_RESULT **res2 -) { - DBUG_ENTER("spider_db_handlersocket::show_master_status"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::append_sql( - char *sql, - ulong sql_length, - st_spider_db_request_key *request_key -) { - int error_num; - size_t req_num; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::append_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = append_request_key(request_key))) - DBUG_RETURN(error_num); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - if (!(req_num = (*hs_conn_p)->request_buf_append(sql, sql + sql_length))) - { - DBUG_PRINT("info",("spider hs %d %s", - (*hs_conn_p)->get_error_code(), - (*hs_conn_p)->get_error().ptr())); - (*hs_conn_p)->write_error_to_log(__func__, __FILE__, __LINE__); - DBUG_RETURN((*hs_conn_p)->get_error_code()); - } - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - while (req_num > 1) - { - if ((error_num = append_request_key(request_key))) - DBUG_RETURN(error_num); - --req_num; - } - DBUG_RETURN(0); -} - -int spider_db_handlersocket::append_open_handler( - uint handler_id, - const char *db_name, - const char *table_name, - const char *index_name, - const char *sql, - st_spider_db_request_key *request_key -) { - int error_num; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::append_open_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = append_request_key(request_key))) - DBUG_RETURN(error_num); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->request_buf_open_index( - handler_id, - db_name, - table_name, - index_name, - sql - ); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::append_select( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key -) { - int error_num; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::append_select"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = append_request_key(request_key))) - DBUG_RETURN(error_num); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->request_buf_exec_generic( - handler_id, - SPIDER_HS_STRING_REF(sql->ptr(), sql->length()), - keys->ptr(), (size_t) keys->size(), - limit, skip, - SPIDER_HS_STRING_REF(), - NULL, 0); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::append_insert( - uint handler_id, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - st_spider_db_request_key *request_key -) { - int error_num; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::append_insert"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = append_request_key(request_key))) - DBUG_RETURN(error_num); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->request_buf_exec_generic( - handler_id, - SPIDER_HS_STRING_REF(SPIDER_SQL_HS_INSERT_STR, SPIDER_SQL_HS_INSERT_LEN), - upds->ptr(), (size_t) upds->size(), - 0, 0, - SPIDER_HS_STRING_REF(), NULL, 0); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::append_update( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - int limit, - int skip, - bool increment, - bool decrement, - st_spider_db_request_key *request_key -) { - int error_num; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::append_update"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = append_request_key(request_key))) - DBUG_RETURN(error_num); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->request_buf_exec_generic( - handler_id, - SPIDER_HS_STRING_REF(sql->ptr(), sql->length()), - keys->ptr(), (size_t) keys->size(), - limit, skip, - increment ? - SPIDER_HS_STRING_REF(SPIDER_SQL_HS_INCREMENT_STR, - SPIDER_SQL_HS_INCREMENT_LEN) : - decrement ? - SPIDER_HS_STRING_REF(SPIDER_SQL_HS_DECREMENT_STR, - SPIDER_SQL_HS_DECREMENT_LEN) : - SPIDER_HS_STRING_REF(SPIDER_SQL_HS_UPDATE_STR, - SPIDER_SQL_HS_UPDATE_LEN), - upds->ptr(), (size_t) upds->size() - ); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::append_delete( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key -) { - int error_num; - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::append_delete"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = append_request_key(request_key))) - DBUG_RETURN(error_num); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->request_buf_exec_generic( - handler_id, - SPIDER_HS_STRING_REF(sql->ptr(), sql->length()), - keys->ptr(), (size_t) keys->size(), - limit, skip, - SPIDER_HS_STRING_REF(SPIDER_SQL_HS_DELETE_STR, SPIDER_SQL_HS_DELETE_LEN), - NULL, 0); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - DBUG_RETURN(0); -} - -void spider_db_handlersocket::reset_request_queue() -{ - SPIDER_HS_CONN *hs_conn_p = &hs_conn; - DBUG_ENTER("spider_db_handlersocket::reset_request_queue"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider hs hs_conn=%p", hs_conn_p)); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - (*hs_conn_p)->request_reset(); - DBUG_PRINT("info",("spider hs num_req_bufd=%zu", - (*hs_conn_p)->get_num_req_bufd())); - DBUG_PRINT("info",("spider hs num_req_sent=%zu", - (*hs_conn_p)->get_num_req_sent())); - DBUG_PRINT("info",("spider hs num_req_rcvd=%zu", - (*hs_conn_p)->get_num_req_rcvd())); - DBUG_PRINT("info",("spider hs response_end_offset=%zu", - (*hs_conn_p)->get_response_end_offset())); - reset_request_key_req(); - DBUG_VOID_RETURN; -} - -size_t spider_db_handlersocket::escape_string( - char *to, - const char *from, - size_t from_length -) { - DBUG_ENTER("spider_db_handlersocket::escape_string"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - memcpy(to, from, from_length); - DBUG_RETURN(from_length); -} - -bool spider_db_handlersocket::have_lock_table_list() -{ - DBUG_ENTER("spider_db_handlersocket::have_lock_table_list"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_handlersocket::append_lock_tables( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket::lock_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_db_handlersocket::append_unlock_tables( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket::append_unlock_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -uint spider_db_handlersocket::get_lock_table_hash_count() -{ - DBUG_ENTER("spider_db_handlersocket::get_lock_table_hash_count"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -void spider_db_handlersocket::reset_lock_table_hash() -{ - DBUG_ENTER("spider_db_handlersocket::reset_lock_table_hash"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -uint spider_db_handlersocket::get_opened_handler_count() -{ - DBUG_ENTER("spider_db_handlersocket::get_opened_handler_count"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(handler_open_array.elements); -} - -void spider_db_handlersocket::reset_opened_handler() -{ - ha_spider *tmp_spider; - int tmp_link_idx; - SPIDER_LINK_FOR_HASH **tmp_link_for_hash; - DBUG_ENTER("spider_db_handlersocket::reset_opened_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - while ((tmp_link_for_hash = - (SPIDER_LINK_FOR_HASH **) pop_dynamic(&handler_open_array))) - { - tmp_spider = (*tmp_link_for_hash)->spider; - tmp_link_idx = (*tmp_link_for_hash)->link_idx; - tmp_spider->clear_handler_opened(tmp_link_idx, conn->conn_kind); - } - DBUG_VOID_RETURN; -} - -void spider_db_handlersocket::set_dup_key_idx( - ha_spider *spider, - int link_idx -) { - DBUG_ENTER("spider_db_handlersocket::set_dup_key_idx"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket::append_request_key( - st_spider_db_request_key *request_key -) { - st_spider_db_request_key *tmp_request_key; - DBUG_ENTER("spider_db_handlersocket::append_request_key"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider request_key=%p", request_key)); - if (request_key) - { - DBUG_PRINT("info",("spider request_key->spider_thread_id=%llu", - request_key->spider_thread_id)); - DBUG_PRINT("info",("spider request_key->query_id=%llu", - request_key->query_id)); - DBUG_PRINT("info",("spider request_key->handler=%p", - request_key->handler)); - DBUG_PRINT("info",("spider request_key->request_id=%llu", - request_key->request_id)); - if (request_key_reuse_first) - { - tmp_request_key = request_key_reuse_first; - request_key_reuse_first = request_key_reuse_first->next; - if (!request_key_reuse_first) - request_key_reuse_last = NULL; - } else { - if (!(tmp_request_key = (st_spider_db_request_key *) - spider_malloc(spider_current_trx, 1, sizeof(st_spider_db_request_key), - MYF(MY_WME))) - ) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - *tmp_request_key = *request_key; - tmp_request_key->next = NULL; - if (request_key_req_last) - request_key_req_last->next = tmp_request_key; - else - request_key_req_first = tmp_request_key; - request_key_req_last = tmp_request_key; - } - DBUG_RETURN(0); -} - -void spider_db_handlersocket::reset_request_key_req() -{ - DBUG_ENTER("spider_db_handlersocket::reset_request_key_req"); - DBUG_PRINT("info",("spider this=%p", this)); - if (request_key_req_first) - { - if (request_key_reuse_last) - request_key_reuse_last->next = request_key_req_first; - else - request_key_reuse_first = request_key_req_first; - request_key_reuse_last = request_key_req_last; - request_key_req_first = NULL; - request_key_req_last = NULL; - } - DBUG_VOID_RETURN; -} - -void spider_db_handlersocket::reset_request_key_snd() -{ - DBUG_ENTER("spider_db_handlersocket::reset_request_key_snd"); - DBUG_PRINT("info",("spider this=%p", this)); - if (request_key_snd_first) - { - if (request_key_reuse_last) - request_key_reuse_last->next = request_key_snd_first; - else - request_key_reuse_first = request_key_snd_first; - request_key_reuse_last = request_key_snd_last; - request_key_snd_first = NULL; - request_key_snd_last = NULL; - } - DBUG_VOID_RETURN; -} - -void spider_db_handlersocket::move_request_key_to_snd() -{ - DBUG_ENTER("spider_db_handlersocket::move_request_key_to_snd"); - DBUG_PRINT("info",("spider this=%p", this)); - if (request_key_req_first) - { - if (request_key_snd_last) - request_key_snd_last->next = request_key_req_first; - else - request_key_snd_first = request_key_req_first; - request_key_snd_last = request_key_req_last; - request_key_req_first = NULL; - request_key_req_last = NULL; - } - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket::check_request_key( - st_spider_db_request_key *request_key -) { - st_spider_db_request_key *tmp_request_key; - DBUG_ENTER("spider_db_handlersocket::check_request_key"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider request_key=%p", request_key)); - DBUG_PRINT("info",("spider request_key_snd_first=%p", - request_key_snd_first)); - if (!request_key_snd_first) - { - DBUG_PRINT("info",("spider -1")); - DBUG_RETURN(-1); - } - tmp_request_key = request_key_snd_first; - request_key_snd_first = request_key_snd_first->next; - if (!request_key_snd_first) - request_key_snd_last = NULL; - tmp_request_key->next = NULL; - if (request_key_reuse_last) - request_key_reuse_last->next = tmp_request_key; - else - request_key_reuse_first = tmp_request_key; - request_key_reuse_last = tmp_request_key; - - DBUG_PRINT("info",("spider tmp_request_key->spider_thread_id=%llu", - tmp_request_key->spider_thread_id)); - DBUG_PRINT("info",("spider request_key->spider_thread_id=%llu", - request_key->spider_thread_id)); - DBUG_PRINT("info",("spider tmp_request_key->query_id=%llu", - tmp_request_key->query_id)); - DBUG_PRINT("info",("spider request_key->query_id=%llu", - request_key->query_id)); - DBUG_PRINT("info",("spider tmp_request_key->handler=%p", - tmp_request_key->handler)); - DBUG_PRINT("info",("spider request_key->handler=%p", - request_key->handler)); - DBUG_PRINT("info",("spider tmp_request_key->request_id=%llu", - tmp_request_key->request_id)); - DBUG_PRINT("info",("spider request_key->request_id=%llu", - request_key->request_id)); - if ( - tmp_request_key->spider_thread_id != request_key->spider_thread_id || - tmp_request_key->query_id != request_key->query_id || - tmp_request_key->handler != request_key->handler || - tmp_request_key->request_id != request_key->request_id - ) { - DBUG_PRINT("info",("spider 1")); - DBUG_RETURN(1); - } - DBUG_PRINT("info",("spider 0")); - DBUG_RETURN(0); -} - -bool spider_db_handlersocket::cmp_request_key_to_snd( - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_handlersocket::cmp_request_key_to_snd"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider request_key=%p", request_key)); - if ( - !request_key - ) { - DBUG_PRINT("info",("spider TRUE")); - DBUG_RETURN(TRUE); - } - DBUG_PRINT("info",("spider request_key_snd_first=%p", - request_key_snd_first)); - if ( - !request_key_snd_first - ) { - DBUG_PRINT("info",("spider FALSE")); - DBUG_RETURN(FALSE); - } - DBUG_PRINT("info",("spider request_key_snd_first->spider_thread_id=%llu", - request_key_snd_first->spider_thread_id)); - DBUG_PRINT("info",("spider request_key->spider_thread_id=%llu", - request_key->spider_thread_id)); - DBUG_PRINT("info",("spider request_key_snd_first->query_id=%llu", - request_key_snd_first->query_id)); - DBUG_PRINT("info",("spider request_key->query_id=%llu", - request_key->query_id)); - DBUG_PRINT("info",("spider request_key_snd_first->handler=%p", - request_key_snd_first->handler)); - DBUG_PRINT("info",("spider request_key->handler=%p", - request_key->handler)); - DBUG_PRINT("info",("spider request_key_snd_first->request_id=%llu", - request_key_snd_first->request_id)); - DBUG_PRINT("info",("spider request_key->request_id=%llu", - request_key->request_id)); - if ( - request_key_snd_first->spider_thread_id != request_key->spider_thread_id || - request_key_snd_first->query_id != request_key->query_id || - request_key_snd_first->handler != request_key->handler || - request_key_snd_first->request_id != request_key->request_id - ) { - DBUG_PRINT("info",("spider FALSE")); - DBUG_RETURN(FALSE); - } - DBUG_PRINT("info",("spider TRUE")); - DBUG_RETURN(TRUE); -} - -spider_db_handlersocket_util::spider_db_handlersocket_util() : spider_db_util() -{ - DBUG_ENTER("spider_db_handlersocket_util::spider_db_handlersocket_util"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -spider_db_handlersocket_util::~spider_db_handlersocket_util() -{ - DBUG_ENTER("spider_db_handlersocket_util::~spider_db_handlersocket_util"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_VOID_RETURN; -} - -int spider_db_handlersocket_util::append_name( - spider_string *str, - const char *name, - uint name_length -) { - DBUG_ENTER("spider_db_handlersocket_util::append_name"); - str->q_append(name, name_length); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_name_with_charset( - spider_string *str, - const char *name, - uint name_length, - CHARSET_INFO *name_charset -) { - DBUG_ENTER("spider_db_handlersocket_util::append_name_with_charset"); - if (str->reserve(SPIDER_SQL_NAME_QUOTE_LEN * 2 + name_length * 2)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - str->append(name, name_length, name_charset); - if (str->reserve(SPIDER_SQL_NAME_QUOTE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_escaped_name( - spider_string *str, - const char *name, - uint name_length -) { - int error_num; - DBUG_ENTER("spider_db_handlersocket_util::append_name"); - if (str->reserve(SPIDER_SQL_NAME_QUOTE_LEN * 2 + name_length * 2)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - if ((error_num = spider_db_append_name_with_quote_str_internal( - str, name, name_length, dbton_id))) - { - DBUG_RETURN(error_num); - } - if (str->reserve(SPIDER_SQL_NAME_QUOTE_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_escaped_name_with_charset( - spider_string *str, - const char *name, - uint name_length, - CHARSET_INFO *name_charset -) { - int error_num; - DBUG_ENTER("spider_db_handlersocket_util::append_name_with_charset"); - if (str->reserve(SPIDER_SQL_NAME_QUOTE_LEN * 2 + name_length * 2)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - if ((error_num = spider_db_append_name_with_quote_str_internal( - str, name, name_length, name_charset, dbton_id))) - { - DBUG_RETURN(error_num); - } - if (str->reserve(SPIDER_SQL_NAME_QUOTE_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - DBUG_RETURN(0); -} - -bool spider_db_handlersocket_util::is_name_quote( - const char head_code -) { - DBUG_ENTER("spider_db_handlersocket_util::is_name_quote"); - DBUG_RETURN(head_code == *name_quote_str); -} - -int spider_db_handlersocket_util::append_escaped_name_quote( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::append_escaped_name_quote"); - if (str->reserve(SPIDER_SQL_NAME_QUOTE_LEN * 2)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_column_value( - ha_spider *spider, - spider_string *str, - Field *field, - const uchar *new_ptr, - CHARSET_INFO *access_charset -) { - char buf[MAX_FIELD_WIDTH]; - spider_string tmp_str(buf, MAX_FIELD_WIDTH, &my_charset_bin); - String *ptr; - uint length; - DBUG_ENTER("spider_db_handlersocket_util::append_column_value"); - tmp_str.init_calc_mem(180); - - if (new_ptr) - { - if ( - field->type() == MYSQL_TYPE_BLOB || - field->real_type() == MYSQL_TYPE_VARCHAR - ) { - length = uint2korr(new_ptr); - tmp_str.set((char *) new_ptr + HA_KEY_BLOB_LENGTH, length, - &my_charset_bin); - ptr = tmp_str.get_str(); - } else if (field->type() == MYSQL_TYPE_GEOMETRY) - { -/* - uint mlength = SIZEOF_STORED_DOUBLE, lcnt; - uchar *dest = (uchar *) buf; - const uchar *source; - for (lcnt = 0; lcnt < 4; lcnt++) - { - mlength = SIZEOF_STORED_DOUBLE; - source = new_ptr + mlength + SIZEOF_STORED_DOUBLE * lcnt; - while (mlength--) - *dest++ = *--source; - } - tmp_str.length(SIZEOF_STORED_DOUBLE * lcnt); -*/ - double xmin, xmax, ymin, ymax; -/* - float8store(buf,xmin); - float8store(buf+8,xmax); - float8store(buf+16,ymin); - float8store(buf+24,ymax); - memcpy(&xmin,new_ptr,sizeof(xmin)); - memcpy(&xmax,new_ptr + 8,sizeof(xmax)); - memcpy(&ymin,new_ptr + 16,sizeof(ymin)); - memcpy(&ymax,new_ptr + 24,sizeof(ymax)); - float8get(xmin, buf); - float8get(xmax, buf + 8); - float8get(ymin, buf + 16); - float8get(ymax, buf + 24); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); - DBUG_PRINT("info", ("spider geo is %.14g %.14g %.14g %.14g", - xmin, xmax, ymin, ymax)); -*/ - float8get(xmin, new_ptr); - float8get(xmax, new_ptr + 8); - float8get(ymin, new_ptr + 16); - float8get(ymax, new_ptr + 24); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); -/* - float8get(xmin, new_ptr + SIZEOF_STORED_DOUBLE * 4); - float8get(xmax, new_ptr + SIZEOF_STORED_DOUBLE * 5); - float8get(ymin, new_ptr + SIZEOF_STORED_DOUBLE * 6); - float8get(ymax, new_ptr + SIZEOF_STORED_DOUBLE * 7); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); - float8get(xmin, new_ptr + SIZEOF_STORED_DOUBLE * 8); - float8get(xmax, new_ptr + SIZEOF_STORED_DOUBLE * 9); - float8get(ymin, new_ptr + SIZEOF_STORED_DOUBLE * 10); - float8get(ymax, new_ptr + SIZEOF_STORED_DOUBLE * 11); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); - float8get(xmin, new_ptr + SIZEOF_STORED_DOUBLE * 12); - float8get(xmax, new_ptr + SIZEOF_STORED_DOUBLE * 13); - float8get(ymin, new_ptr + SIZEOF_STORED_DOUBLE * 14); - float8get(ymax, new_ptr + SIZEOF_STORED_DOUBLE * 15); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); -*/ -/* - tmp_str.set((char *) new_ptr, SIZEOF_STORED_DOUBLE * 4, - &my_charset_bin); -*/ - tmp_str.length(0); - tmp_str.q_append((char *) SPIDER_SQL_LINESTRING_HEAD_STR, - SPIDER_SQL_LINESTRING_HEAD_LEN); - tmp_str.q_append((char *) new_ptr, SIZEOF_STORED_DOUBLE); - tmp_str.q_append((char *) new_ptr + SIZEOF_STORED_DOUBLE * 2, - SIZEOF_STORED_DOUBLE); - tmp_str.q_append((char *) new_ptr + SIZEOF_STORED_DOUBLE, - SIZEOF_STORED_DOUBLE); - tmp_str.q_append((char *) new_ptr + SIZEOF_STORED_DOUBLE * 3, - SIZEOF_STORED_DOUBLE); - ptr = tmp_str.get_str(); - } else { - ptr = field->val_str(tmp_str.get_str(), new_ptr); - tmp_str.mem_calc(); - } - } else { - ptr = field->val_str(tmp_str.get_str()); - tmp_str.mem_calc(); - } - DBUG_PRINT("info", ("spider field->type() is %d", field->type())); - DBUG_PRINT("info", ("spider ptr->length() is %d", ptr->length())); -/* - if ( - field->type() == MYSQL_TYPE_BIT || - (field->type() >= MYSQL_TYPE_TINY_BLOB && - field->type() <= MYSQL_TYPE_BLOB) - ) { - uchar *hex_ptr = (uchar *) ptr->ptr(), *end_ptr; - char *str_ptr; - DBUG_PRINT("info", ("spider HEX")); - if (str->reserve(SPIDER_SQL_HEX_LEN + ptr->length() * 2)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_HEX_STR, SPIDER_SQL_HEX_LEN); - str_ptr = (char *) str->ptr() + str->length(); - for (end_ptr = hex_ptr + ptr->length(); hex_ptr < end_ptr; hex_ptr++) - { - *str_ptr++ = spider_dig_upper[(*hex_ptr) >> 4]; - *str_ptr++ = spider_dig_upper[(*hex_ptr) & 0x0F]; - } - str->length(str->length() + ptr->length() * 2); - } else -*/ - spider_handlersocket_handler *hs_handler = (spider_handlersocket_handler *) - spider->dbton_handler[spider_dbton_handlersocket.dbton_id]; - spider_string *hs_str; - if (!(hs_str = hs_handler->hs_strs.add( - &hs_handler->hs_strs_pos, ptr->ptr(), ptr->length()))) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - SPIDER_HS_STRING_REF ref = - SPIDER_HS_STRING_REF(hs_str->ptr(), hs_str->length()); - if (hs_handler->hs_adding_keys) - { - DBUG_PRINT("info", ("spider add to key:%s", hs_str->c_ptr_safe())); - hs_handler->hs_keys.push_back(ref); - } else { - DBUG_PRINT("info", ("spider add to upd:%s", hs_str->c_ptr_safe())); - hs_handler->hs_upds.push_back(ref); - } - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_trx_isolation( - spider_string *str, - int trx_isolation -) { - DBUG_ENTER("spider_db_handlersocket_util::append_trx_isolation"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_autocommit( - spider_string *str, - bool autocommit -) { - DBUG_ENTER("spider_db_handlersocket_util::append_autocommit"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_sql_log_off( - spider_string *str, - bool sql_log_off -) { - DBUG_ENTER("spider_db_handlersocket_util::append_sql_log_off"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_wait_timeout( - spider_string *str, - int wait_timeout -) { - DBUG_ENTER("spider_db_handlersocket_util::append_wait_timeout"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_sql_mode( - spider_string *str, - sql_mode_t sql_mode -) { - DBUG_ENTER("spider_db_handlersocket_util::append_sql_mode"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_time_zone( - spider_string *str, - Time_zone *time_zone -) { - DBUG_ENTER("spider_db_handlersocket_util::append_time_zone"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_start_transaction( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::append_start_transaction"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_xa_start( - spider_string *str, - XID *xid -) { - DBUG_ENTER("spider_db_handlersocket_util::append_xa_start"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_lock_table_head( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::append_lock_table_head"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_lock_table_body( - spider_string *str, - const char *db_name, - uint db_name_length, - CHARSET_INFO *db_name_charset, - const char *table_name, - uint table_name_length, - CHARSET_INFO *table_name_charset, - int lock_type -) { - DBUG_ENTER("spider_db_handlersocket_util::append_lock_table_body"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_lock_table_tail( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::append_lock_table_tail"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_unlock_table( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::append_unlock_table"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::open_item_func( - Item_func *item_func, - ha_spider *spider, - spider_string *str, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields -) { - uint dbton_id = spider_dbton_handlersocket.dbton_id; - int error_num; - Item *item, **item_list = item_func->arguments(); - uint roop_count, item_count = item_func->argument_count(), start_item = 0; - LEX_CSTRING func_name_c; - const char *func_name = SPIDER_SQL_NULL_CHAR_STR, - *separator_str = SPIDER_SQL_NULL_CHAR_STR, - *last_str = SPIDER_SQL_NULL_CHAR_STR; - int func_name_length = SPIDER_SQL_NULL_CHAR_LEN, - separator_str_length = SPIDER_SQL_NULL_CHAR_LEN, - last_str_length = SPIDER_SQL_NULL_CHAR_LEN; - int use_pushdown_udf; - bool merge_func = FALSE; - DBUG_ENTER("spider_db_handlersocket_util::open_item_func"); - if (str) - { - if (str->reserve(SPIDER_SQL_OPEN_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - } - DBUG_PRINT("info",("spider functype = %d", item_func->functype())); - switch (item_func->functype()) - { - case Item_func::ISNULL_FUNC: - last_str = SPIDER_SQL_IS_NULL_STR; - last_str_length = SPIDER_SQL_IS_NULL_LEN; - break; - case Item_func::ISNOTNULL_FUNC: - last_str = SPIDER_SQL_IS_NOT_NULL_STR; - last_str_length = SPIDER_SQL_IS_NOT_NULL_LEN; - break; - case Item_func::UNKNOWN_FUNC: - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - DBUG_PRINT("info",("spider func_name = %s", func_name)); - DBUG_PRINT("info",("spider func_name_length = %d", func_name_length)); - if (func_name_length == 1 && - ( - !strncasecmp("+", func_name, func_name_length) || - !strncasecmp("-", func_name, func_name_length) || - !strncasecmp("*", func_name, func_name_length) || - !strncasecmp("/", func_name, func_name_length) || - !strncasecmp("%", func_name, func_name_length) || - !strncasecmp("&", func_name, func_name_length) || - !strncasecmp("|", func_name, func_name_length) || - !strncasecmp("^", func_name, func_name_length) - ) - ) { - /* no action */ - break; - } else if (func_name_length == 2 && - ( - !strncasecmp("<<", func_name, func_name_length) || - !strncasecmp(">>", func_name, func_name_length) - ) - ) { - /* no action */ - break; - } else if (func_name_length == 3 && - !strncasecmp("div", func_name, func_name_length) - ) { - /* no action */ - break; - } else if (func_name_length == 4) - { - if ( - !strncasecmp("rand", func_name, func_name_length) && -#ifdef SPIDER_Item_args_arg_count_IS_PROTECTED - !item_func->argument_count() -#else - !item_func->arg_count -#endif - ) { - if (str) - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - DBUG_RETURN(spider_db_open_item_int(item_func, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - } else if ( - !strncasecmp("case", func_name, func_name_length) - ) { -#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC - Item_func_case *item_func_case = (Item_func_case *) item_func; - if (str) - { - if (str->reserve(SPIDER_SQL_CASE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN); - } - if (item_func_case->first_expr_num != -1) - { - if ((error_num = spider_db_print_item_type( - item_list[item_func_case->first_expr_num], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - } - for (roop_count = 0; roop_count < item_func_case->ncases; - roop_count += 2) - { - if (str) - { - if (str->reserve(SPIDER_SQL_WHEN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN); - } - if ((error_num = spider_db_print_item_type( - item_list[roop_count], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (str->reserve(SPIDER_SQL_THEN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN); - } - if ((error_num = spider_db_print_item_type( - item_list[roop_count + 1], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - } - if (item_func_case->else_expr_num != -1) - { - if (str) - { - if (str->reserve(SPIDER_SQL_ELSE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN); - } - if ((error_num = spider_db_print_item_type( - item_list[item_func_case->else_expr_num], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - } - if (str) - { - if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN); - str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, - SPIDER_SQL_CLOSE_PAREN_LEN); - } - DBUG_RETURN(0); -#else - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); -#endif - } - } else if (func_name_length == 6 && - !strncasecmp("istrue", func_name, func_name_length) - ) { - last_str = SPIDER_SQL_IS_TRUE_STR; - last_str_length = SPIDER_SQL_IS_TRUE_LEN; - break; - } else if (func_name_length == 7) - { - if (!strncasecmp("isfalse", func_name, func_name_length)) - { - last_str = SPIDER_SQL_IS_FALSE_STR; - last_str_length = SPIDER_SQL_IS_FALSE_LEN; - break; - } else if ( - !strncasecmp("sysdate", func_name, func_name_length) || - !strncasecmp("curdate", func_name, func_name_length) || - !strncasecmp("curtime", func_name, func_name_length) - ) { - if (str) - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - DBUG_RETURN(spider_db_open_item_string(item_func, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - } else if ( - !strncasecmp("convert", func_name, func_name_length) - ) { - if (str) - { - if (str->reserve(func_name_length * 2 + SPIDER_SQL_OPEN_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, - SPIDER_SQL_OPEN_PAREN_LEN); - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - } - break; - } - } else if (func_name_length == 8 && - ( - !strncasecmp("utc_date", func_name, func_name_length) || - !strncasecmp("utc_time", func_name, func_name_length) - ) - ) { - if (str) - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - DBUG_RETURN(spider_db_open_item_string(item_func, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - } else if (func_name_length == 9 && - !strncasecmp("isnottrue", func_name, func_name_length) - ) { - last_str = SPIDER_SQL_IS_NOT_TRUE_STR; - last_str_length = SPIDER_SQL_IS_NOT_TRUE_LEN; - break; - } else if (func_name_length == 10) - { - if (!strncasecmp("isnotfalse", func_name, func_name_length)) - { - last_str = SPIDER_SQL_IS_NOT_FALSE_STR; - last_str_length = SPIDER_SQL_IS_NOT_FALSE_LEN; - break; - } else if (!strncasecmp("column_get", func_name, func_name_length)) - { - if (str) - { - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - } - func_name = SPIDER_SQL_COMMA_STR; - func_name_length = SPIDER_SQL_COMMA_LEN; - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - break; - } - } else if (func_name_length == 12) - { - if (!strncasecmp("cast_as_date", func_name, func_name_length)) - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } - } - last_str = SPIDER_SQL_AS_DATE_STR; - last_str_length = SPIDER_SQL_AS_DATE_LEN; - break; - } else if (!strncasecmp("cast_as_time", func_name, func_name_length)) - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } - } - last_str = SPIDER_SQL_AS_TIME_STR; - last_str_length = SPIDER_SQL_AS_TIME_LEN; - break; - } - } else if (func_name_length == 13) - { - if (!strncasecmp("utc_timestamp", func_name, func_name_length)) - { - if (str) - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - DBUG_RETURN(spider_db_open_item_string(item_func, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - } else if (!strncasecmp("timestampdiff", func_name, func_name_length)) - { -#ifdef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC - Item_func_timestamp_diff *item_func_timestamp_diff = - (Item_func_timestamp_diff *) item_func; - if (str) - { - const char *interval_str; - uint interval_len; - switch (item_func_timestamp_diff->int_type) - { - case INTERVAL_YEAR: - interval_str = SPIDER_SQL_YEAR_STR; - interval_len = SPIDER_SQL_YEAR_LEN; - break; - case INTERVAL_QUARTER: - interval_str = SPIDER_SQL_QUARTER_STR; - interval_len = SPIDER_SQL_QUARTER_LEN; - break; - case INTERVAL_MONTH: - interval_str = SPIDER_SQL_MONTH_STR; - interval_len = SPIDER_SQL_MONTH_LEN; - break; - case INTERVAL_WEEK: - interval_str = SPIDER_SQL_WEEK_STR; - interval_len = SPIDER_SQL_WEEK_LEN; - break; - case INTERVAL_DAY: - interval_str = SPIDER_SQL_DAY_STR; - interval_len = SPIDER_SQL_DAY_LEN; - break; - case INTERVAL_HOUR: - interval_str = SPIDER_SQL_HOUR_STR; - interval_len = SPIDER_SQL_HOUR_LEN; - break; - case INTERVAL_MINUTE: - interval_str = SPIDER_SQL_MINUTE_STR; - interval_len = SPIDER_SQL_MINUTE_LEN; - break; - case INTERVAL_SECOND: - interval_str = SPIDER_SQL_SECOND_STR; - interval_len = SPIDER_SQL_SECOND_LEN; - break; - case INTERVAL_MICROSECOND: - interval_str = SPIDER_SQL_MICROSECOND_STR; - interval_len = SPIDER_SQL_MICROSECOND_LEN; - break; - default: - interval_str = ""; - interval_len = 0; - break; - } - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN + - interval_len + SPIDER_SQL_COMMA_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - str->q_append(interval_str, interval_len); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - if ((error_num = spider_db_print_item_type(item_list[0], NULL, spider, - str, alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (str->reserve(SPIDER_SQL_COMMA_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - if ((error_num = spider_db_print_item_type(item_list[1], NULL, spider, - str, alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, - SPIDER_SQL_CLOSE_PAREN_LEN); - } - DBUG_RETURN(0); -#else - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); -#endif - } - } else if (func_name_length == 14) - { - if (!strncasecmp("cast_as_binary", func_name, func_name_length)) - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(123); - tmp_str.length(0); - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } -#if MYSQL_VERSION_ID < 50500 - item_func->print(tmp_str.get_str(), QT_IS); -#else - item_func->print(tmp_str.get_str(), QT_TO_SYSTEM_CHARSET); -#endif - tmp_str.mem_calc(); - if (tmp_str.reserve(1)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - tmp_ptr = tmp_str.c_ptr_quick(); - DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr)); - while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_BINARY_STR))) - tmp_ptr = tmp_ptr2 + 1; - last_str = tmp_ptr - 1; - last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN; - } - break; - } else if (!strncasecmp("cast_as_signed", func_name, func_name_length)) - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } - } - last_str = SPIDER_SQL_AS_SIGNED_STR; - last_str_length = SPIDER_SQL_AS_SIGNED_LEN; - break; - } - } else if (func_name_length == 16) - { - if (!strncasecmp("cast_as_unsigned", func_name, func_name_length)) - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } - } - last_str = SPIDER_SQL_AS_UNSIGNED_STR; - last_str_length = SPIDER_SQL_AS_UNSIGNED_LEN; - break; - } else if (!strncasecmp("decimal_typecast", func_name, - func_name_length)) - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(124); - tmp_str.length(0); - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } -#if MYSQL_VERSION_ID < 50500 - item_func->print(tmp_str.get_str(), QT_IS); -#else - item_func->print(tmp_str.get_str(), QT_TO_SYSTEM_CHARSET); -#endif - tmp_str.mem_calc(); - if (tmp_str.reserve(1)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - tmp_ptr = tmp_str.c_ptr_quick(); - DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr)); - while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_DECIMAL_STR))) - tmp_ptr = tmp_ptr2 + 1; - last_str = tmp_ptr - 1; - last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN; - } - break; - } else if (!strncasecmp("cast_as_datetime", func_name, - func_name_length)) - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } - } - last_str = SPIDER_SQL_AS_DATETIME_STR; - last_str_length = SPIDER_SQL_AS_DATETIME_LEN; - break; - } - } else if (func_name_length == 17) - { - if (!strncasecmp("date_add_interval", func_name, func_name_length)) - { - Item_date_add_interval *item_date_add_interval = - (Item_date_add_interval *) item_func; - func_name = spider_db_timefunc_interval_str[ - item_date_add_interval->int_type]; - func_name_length = strlen(func_name); - if ((error_num = spider_db_print_item_type(item_list[0], NULL, spider, - str, alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (item_date_add_interval->date_sub_interval) - { - if (str->reserve(SPIDER_SQL_NEGINTERVAL_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_NEGINTERVAL_STR, - SPIDER_SQL_NEGINTERVAL_LEN); - } else { - if (str->reserve(SPIDER_SQL_INTERVAL_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_INTERVAL_STR, SPIDER_SQL_INTERVAL_LEN); - } - } - if ((error_num = spider_db_print_item_type(item_list[1], NULL, spider, - str, alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (str->reserve(func_name_length + SPIDER_SQL_CLOSE_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, - SPIDER_SQL_CLOSE_PAREN_LEN); - } - DBUG_RETURN(0); - } - } - if (str) - { - if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - } - func_name = SPIDER_SQL_COMMA_STR; - func_name_length = SPIDER_SQL_COMMA_LEN; - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - break; - case Item_func::NOW_FUNC: - if (str) - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - DBUG_RETURN(spider_db_open_item_string(item_func, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - case Item_func::CHAR_TYPECAST_FUNC: - DBUG_PRINT("info",("spider CHAR_TYPECAST_FUNC")); - { - item = item_list[0]; - if (item->type() == Item::FUNC_ITEM) - { - DBUG_PRINT("info",("spider child is FUNC_ITEM")); - Item_func *ifunc = (Item_func *) item; - if (ifunc->functype() == Item_func::UNKNOWN_FUNC) - { - LEX_CSTRING child_func_name_c; - const char *child_func_name; - int child_func_name_length; - DBUG_PRINT("info",("spider child is UNKNOWN_FUNC")); - child_func_name_c = ifunc->func_name_cstring(); - child_func_name = child_func_name_c.str; - child_func_name_length = child_func_name_c.length; - DBUG_PRINT("info",("spider child func_name is %s", child_func_name)); - if ( - child_func_name_length == 10 && - !strncasecmp("column_get", child_func_name, child_func_name_length) - ) { - DBUG_PRINT("info",("spider this is merge func")); - merge_func = TRUE; - } - } - } - - if (str) - { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(125); - tmp_str.length(0); - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (!merge_func) - { - if (str->reserve(SPIDER_SQL_CAST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CAST_STR, SPIDER_SQL_CAST_LEN); - } -#if MYSQL_VERSION_ID < 50500 - item_func->print(tmp_str.get_str(), QT_IS); -#else - item_func->print(tmp_str.get_str(), QT_TO_SYSTEM_CHARSET); -#endif - tmp_str.mem_calc(); - if (tmp_str.reserve(1)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - tmp_ptr = tmp_str.c_ptr_quick(); - DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr)); - while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_CHAR_STR))) - tmp_ptr = tmp_ptr2 + 1; - last_str = tmp_ptr - 1; - last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN; - } - } - break; - case Item_func::NOT_FUNC: - DBUG_PRINT("info",("spider NOT_FUNC")); - if (item_list[0]->type() == Item::COND_ITEM) - { - DBUG_PRINT("info",("spider item_list[0] is COND_ITEM")); - Item_cond *item_cond = (Item_cond *) item_list[0]; - if (item_cond->functype() == Item_func::COND_AND_FUNC) - { - DBUG_PRINT("info",("spider item_cond is COND_AND_FUNC")); - List_iterator_fast<Item> lif(*(item_cond->argument_list())); - bool has_expr_cache_item = FALSE; - bool has_isnotnull_func = FALSE; - bool has_other_item = FALSE; - while((item = lif++)) - { -#ifdef SPIDER_HAS_EXPR_CACHE_ITEM - if ( - item->type() == Item::EXPR_CACHE_ITEM - ) { - DBUG_PRINT("info",("spider EXPR_CACHE_ITEM")); - has_expr_cache_item = TRUE; - } else -#endif - if ( - item->type() == Item::FUNC_ITEM && - ((Item_func *) item)->functype() == Item_func::ISNOTNULL_FUNC - ) { - DBUG_PRINT("info",("spider ISNOTNULL_FUNC")); - has_isnotnull_func = TRUE; - } else { - DBUG_PRINT("info",("spider has other item")); - DBUG_PRINT("info",("spider COND type=%d", item->type())); - has_other_item = TRUE; - } - } - if (has_expr_cache_item && has_isnotnull_func && !has_other_item) - { - DBUG_PRINT("info",("spider NOT EXISTS skip")); - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); - } - } - } - if (str) - { - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - if (str->reserve(func_name_length + SPIDER_SQL_SPACE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); - } - break; - case Item_func::NEG_FUNC: - if (str) - { - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - if (str->reserve(func_name_length + SPIDER_SQL_SPACE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); - } - break; - case Item_func::IN_FUNC: - if (((Item_func_opt_neg *) item_func)->negated) - { - func_name = SPIDER_SQL_NOT_IN_STR; - func_name_length = SPIDER_SQL_NOT_IN_LEN; - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - } else { - func_name = SPIDER_SQL_IN_STR; - func_name_length = SPIDER_SQL_IN_LEN; - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - } - break; - case Item_func::BETWEEN: - if (((Item_func_opt_neg *) item_func)->negated) - { - func_name = SPIDER_SQL_NOT_BETWEEN_STR; - func_name_length = SPIDER_SQL_NOT_BETWEEN_LEN; - separator_str = SPIDER_SQL_AND_STR; - separator_str_length = SPIDER_SQL_AND_LEN; - } else { - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - separator_str = SPIDER_SQL_AND_STR; - separator_str_length = SPIDER_SQL_AND_LEN; - } - break; - case Item_func::UDF_FUNC: - use_pushdown_udf = spider_param_use_pushdown_udf(spider->trx->thd, - spider->share->use_pushdown_udf); - if (!use_pushdown_udf) - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); - if (str) - { - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - DBUG_PRINT("info",("spider func_name = %s", func_name)); - DBUG_PRINT("info",("spider func_name_length = %d", func_name_length)); - if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - } - func_name = SPIDER_SQL_COMMA_STR; - func_name_length = SPIDER_SQL_COMMA_LEN; - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - break; -#ifdef MARIADB_BASE_VERSION - case Item_func::XOR_FUNC: -#else - case Item_func::COND_XOR_FUNC: -#endif - if (str) - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - DBUG_RETURN( - spider_db_open_item_cond((Item_cond *) item_func, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - case Item_func::TRIG_COND_FUNC: - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); - case Item_func::GUSERVAR_FUNC: - if (str) - str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); - if (item_func->result_type() == STRING_RESULT) - DBUG_RETURN(spider_db_open_item_string(item_func, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - else - DBUG_RETURN(spider_db_open_item_int(item_func, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields)); - case Item_func::FT_FUNC: - if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY) - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); - start_item = 1; - if (str) - { - if (str->reserve(SPIDER_SQL_MATCH_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_MATCH_STR, SPIDER_SQL_MATCH_LEN); - } - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - break; - case Item_func::SP_EQUALS_FUNC: - if (str) - { - func_name = SPIDER_SQL_MBR_EQUAL_STR; - func_name_length = SPIDER_SQL_MBR_EQUAL_LEN; - DBUG_PRINT("info",("spider func_name = %s", func_name)); - DBUG_PRINT("info",("spider func_name_length = %d", func_name_length)); - if (str->reserve(func_name_length)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - } - func_name = SPIDER_SQL_COMMA_STR; - func_name_length = SPIDER_SQL_COMMA_LEN; - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - break; - case Item_func::SP_DISJOINT_FUNC: - case Item_func::SP_INTERSECTS_FUNC: - case Item_func::SP_TOUCHES_FUNC: - case Item_func::SP_CROSSES_FUNC: - case Item_func::SP_WITHIN_FUNC: - case Item_func::SP_CONTAINS_FUNC: - case Item_func::SP_OVERLAPS_FUNC: - if (str) - { - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - DBUG_PRINT("info",("spider func_name = %s", func_name)); - DBUG_PRINT("info",("spider func_name_length = %d", func_name_length)); - if (str->reserve( -#ifndef SPIDER_ITEM_GEOFUNC_NAME_HAS_MBR - SPIDER_SQL_MBR_LEN + -#endif - func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); -#ifndef SPIDER_ITEM_GEOFUNC_NAME_HAS_MBR - str->q_append(SPIDER_SQL_MBR_STR, SPIDER_SQL_MBR_LEN); -#endif - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - } - func_name = SPIDER_SQL_COMMA_STR; - func_name_length = SPIDER_SQL_COMMA_LEN; - separator_str = SPIDER_SQL_COMMA_STR; - separator_str_length = SPIDER_SQL_COMMA_LEN; - last_str = SPIDER_SQL_CLOSE_PAREN_STR; - last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; - break; - case Item_func::EQ_FUNC: - case Item_func::EQUAL_FUNC: - case Item_func::NE_FUNC: - case Item_func::LT_FUNC: - case Item_func::LE_FUNC: - case Item_func::GE_FUNC: - case Item_func::GT_FUNC: - case Item_func::LIKE_FUNC: - if (str) - { - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - } - break; - default: - THD *thd = spider->trx->thd; - SPIDER_SHARE *share = spider->share; - if (spider_param_skip_default_condition(thd, - share->skip_default_condition)) - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); - if (str) - { - func_name_c = item_func->func_name_cstring(); - func_name = func_name_c.str; - func_name_length = func_name_c.length; - } - break; - } - DBUG_PRINT("info",("spider func_name = %s", func_name)); - DBUG_PRINT("info",("spider func_name_length = %d", func_name_length)); - DBUG_PRINT("info",("spider separator_str = %s", separator_str)); - DBUG_PRINT("info",("spider separator_str_length = %d", separator_str_length)); - DBUG_PRINT("info",("spider last_str = %s", last_str)); - DBUG_PRINT("info",("spider last_str_length = %d", last_str_length)); - if (item_count) - { - item_count--; - for (roop_count = start_item; roop_count < item_count; roop_count++) - { - item = item_list[roop_count]; - if ((error_num = spider_db_print_item_type(item, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (roop_count == 1) - { - func_name = separator_str; - func_name_length = separator_str_length; - } - if (str) - { - if (str->reserve(func_name_length + SPIDER_SQL_SPACE_LEN * 2)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); - str->q_append(func_name, func_name_length); - str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); - } - } - item = item_list[roop_count]; - if ((error_num = spider_db_print_item_type(item, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - } - if (item_func->functype() == Item_func::FT_FUNC) - { - Item_func_match *item_func_match = (Item_func_match *)item_func; - if (str) - { - if (str->reserve(SPIDER_SQL_AGAINST_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_AGAINST_STR, SPIDER_SQL_AGAINST_LEN); - } - item = item_list[0]; - if ((error_num = spider_db_print_item_type(item, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (str->reserve( - ((item_func_match->match_flags & FT_BOOL) ? - SPIDER_SQL_IN_BOOLEAN_MODE_LEN : 0) + - ((item_func_match->match_flags & FT_EXPAND) ? - SPIDER_SQL_WITH_QUERY_EXPANSION_LEN : 0) - )) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (item_func_match->match_flags & FT_BOOL) - str->q_append(SPIDER_SQL_IN_BOOLEAN_MODE_STR, - SPIDER_SQL_IN_BOOLEAN_MODE_LEN); - if (item_func_match->match_flags & FT_EXPAND) - str->q_append(SPIDER_SQL_WITH_QUERY_EXPANSION_STR, - SPIDER_SQL_WITH_QUERY_EXPANSION_LEN); - } - } else if (item_func->functype() == Item_func::UNKNOWN_FUNC) - { - if ( - func_name_length == 7 && - !strncasecmp("convert", func_name, func_name_length) - ) { - if (str) - { - Item_func_conv_charset *item_func_conv_charset = - (Item_func_conv_charset *)item_func; - CHARSET_INFO *conv_charset = - item_func_conv_charset->SPIDER_Item_func_conv_charset_conv_charset; - uint cset_length = strlen(conv_charset->csname); - if (str->reserve(SPIDER_SQL_USING_LEN + cset_length)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_USING_STR, SPIDER_SQL_USING_LEN); - str->q_append(conv_charset->csname, cset_length); - } - } - } - if (str) - { - if (merge_func) - str->length(str->length() - SPIDER_SQL_CLOSE_PAREN_LEN); - if (str->reserve(last_str_length + SPIDER_SQL_CLOSE_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(last_str, last_str_length); - str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN); - } - DBUG_RETURN(0); -} - -#ifdef HANDLER_HAS_DIRECT_AGGREGATE -int spider_db_handlersocket_util::open_item_sum_func( - Item_sum *item_sum, - ha_spider *spider, - spider_string *str, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields -) { - uint dbton_id = spider_dbton_handlersocket.dbton_id; - uint roop_count, item_count = item_sum->get_arg_count(); - int error_num; - DBUG_ENTER("spider_db_handlersocket_util::open_item_sum_func"); - DBUG_PRINT("info",("spider Sumfunctype = %d", item_sum->sum_func())); - switch (item_sum->sum_func()) - { - case Item_sum::COUNT_FUNC: - case Item_sum::SUM_FUNC: - case Item_sum::MIN_FUNC: - case Item_sum::MAX_FUNC: - { - LEX_CSTRING func_name_c = item_sum->func_name_cstring(); - const char *func_name = func_name_c.str; - uint func_name_length = func_name_c.length; - Item *item, **args = item_sum->get_args(); - if (str) - { - if (str->reserve(func_name_length)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(func_name, func_name_length); - } - if (item_count) - { - item_count--; - for (roop_count = 0; roop_count < item_count; roop_count++) - { - item = args[roop_count]; - if ((error_num = spider_db_print_item_type(item, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (str->reserve(SPIDER_SQL_COMMA_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - } - item = args[roop_count]; - if ((error_num = spider_db_print_item_type(item, NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - } - if (str) - { - if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, - SPIDER_SQL_CLOSE_PAREN_LEN); - } - } - break; - case Item_sum::COUNT_DISTINCT_FUNC: - case Item_sum::SUM_DISTINCT_FUNC: - case Item_sum::AVG_FUNC: - case Item_sum::AVG_DISTINCT_FUNC: - case Item_sum::STD_FUNC: - case Item_sum::VARIANCE_FUNC: - case Item_sum::SUM_BIT_FUNC: - case Item_sum::UDF_SUM_FUNC: - case Item_sum::GROUP_CONCAT_FUNC: - default: - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); - } - DBUG_RETURN(0); -} -#endif - -int spider_db_handlersocket_util::append_escaped_util( - spider_string *to, - String *from -) { - DBUG_ENTER("spider_db_handlersocket_util::append_escaped_util"); - DBUG_PRINT("info",("spider this=%p", this)); - to->append_escape_string(from->ptr(), from->length()); - DBUG_RETURN(0); -} - -#ifdef SPIDER_HAS_GROUP_BY_HANDLER -int spider_db_handlersocket_util::append_from_and_tables( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - uint table_count -) { - DBUG_ENTER("spider_db_handlersocket_util::append_from_and_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::reappend_tables( - spider_fields *fields, - SPIDER_LINK_IDX_CHAIN *link_idx_chain, - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::reappend_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_where( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::append_where"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_handlersocket_util::append_having( - spider_string *str -) { - DBUG_ENTER("spider_db_handlersocket_util::append_having"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} -#endif - -spider_handlersocket_share::spider_handlersocket_share( - st_spider_share *share -) : spider_db_share( - share, - spider_dbton_handlersocket.dbton_id -), - table_names_str(NULL), - db_names_str(NULL), - db_table_str(NULL), -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - db_table_str_hash_value(NULL), -#endif - table_nm_max_length(0), - db_nm_max_length(0), - column_name_str(NULL), - same_db_table_name(TRUE), - first_all_link_idx(-1) -{ - DBUG_ENTER("spider_handlersocket_share::spider_handlersocket_share"); - DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 186); - spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); - DBUG_VOID_RETURN; -} - -spider_handlersocket_share::~spider_handlersocket_share() -{ - DBUG_ENTER("spider_handlersocket_share::~spider_handlersocket_share"); - DBUG_PRINT("info",("spider this=%p", this)); - free_column_name_str(); - free_table_names_str(); -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - if (db_table_str_hash_value) - { - spider_free(spider_current_trx, db_table_str_hash_value, MYF(0)); - } -#endif - spider_free_mem_calc(spider_current_trx, mem_calc_id, sizeof(*this)); - DBUG_VOID_RETURN; -} - -int spider_handlersocket_share::init() -{ - int error_num; - DBUG_ENTER("spider_handlersocket_share::init"); - DBUG_PRINT("info",("spider this=%p", this)); -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - if (!(db_table_str_hash_value = (my_hash_value_type *) - spider_bulk_alloc_mem(spider_current_trx, 203, - __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), - &db_table_str_hash_value, - sizeof(my_hash_value_type) * spider_share->all_link_count, - NullS)) - ) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } -#endif - - if ( - (error_num = create_table_names_str()) || - ( - spider_share->table_share && - (error_num = create_column_name_str()) - ) - ) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_share::append_table_name( - spider_string *str, - int all_link_idx -) { - const char *db_nm = db_names_str[all_link_idx].ptr(); - uint db_nm_len = db_names_str[all_link_idx].length(); - const char *table_nm = table_names_str[all_link_idx].ptr(); - uint table_nm_len = table_names_str[all_link_idx].length(); - DBUG_ENTER("spider_handlersocket_share::append_table_name"); - DBUG_PRINT("info",("spider this=%p", this)); - if (str->reserve(db_nm_len + SPIDER_SQL_DOT_LEN + table_nm_len + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 4)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - spider_db_handlersocket_utility.append_name(str, db_nm, db_nm_len); - str->q_append(SPIDER_SQL_DOT_STR, SPIDER_SQL_DOT_LEN); - spider_db_handlersocket_utility.append_name(str, table_nm, table_nm_len); - DBUG_RETURN(0); -} - -int spider_handlersocket_share::create_table_names_str() -{ - int error_num, roop_count; - uint table_nm_len, db_nm_len; - spider_string *str, *first_tbl_nm_str, *first_db_nm_str, *first_db_tbl_str; - char *first_tbl_nm, *first_db_nm; - uint dbton_id = spider_dbton_handlersocket.dbton_id; - DBUG_ENTER("spider_handlersocket_share::create_table_names_str"); - table_names_str = NULL; - db_names_str = NULL; - db_table_str = NULL; - if ( - !(table_names_str = new spider_string[spider_share->all_link_count]) || - !(db_names_str = new spider_string[spider_share->all_link_count]) || - !(db_table_str = new spider_string[spider_share->all_link_count]) - ) { - error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - - same_db_table_name = TRUE; - first_tbl_nm = spider_share->tgt_table_names[0]; - first_db_nm = spider_share->tgt_dbs[0]; - table_nm_len = spider_share->tgt_table_names_lengths[0]; - db_nm_len = spider_share->tgt_dbs_lengths[0]; - first_tbl_nm_str = &table_names_str[0]; - first_db_nm_str = &db_names_str[0]; - first_db_tbl_str = &db_table_str[0]; - for (roop_count = 0; roop_count < (int) spider_share->all_link_count; - roop_count++) - { - table_names_str[roop_count].init_calc_mem(86); - db_names_str[roop_count].init_calc_mem(87); - db_table_str[roop_count].init_calc_mem(88); - if (spider_share->sql_dbton_ids[roop_count] != dbton_id) - continue; - if (first_all_link_idx == -1) - first_all_link_idx = roop_count; - - str = &table_names_str[roop_count]; - if ( - roop_count != 0 && - same_db_table_name && - spider_share->tgt_table_names_lengths[roop_count] == table_nm_len && - !memcmp(first_tbl_nm, spider_share->tgt_table_names[roop_count], - table_nm_len) - ) { - if (str->copy(*first_tbl_nm_str)) - { - error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - } else { - str->set_charset(spider_share->access_charset); - if ((error_num = spider_db_append_name_with_quote_str(str, - spider_share->tgt_table_names[roop_count], dbton_id))) - goto error; - if (roop_count) - { - same_db_table_name = FALSE; - DBUG_PRINT("info", ("spider found different table name %s", - spider_share->tgt_table_names[roop_count])); - if (str->length() > table_nm_max_length) - table_nm_max_length = str->length(); - } else - table_nm_max_length = str->length(); - } - - str = &db_names_str[roop_count]; - if ( - roop_count != 0 && - same_db_table_name && - spider_share->tgt_dbs_lengths[roop_count] == db_nm_len && - !memcmp(first_db_nm, spider_share->tgt_dbs[roop_count], - db_nm_len) - ) { - if (str->copy(*first_db_nm_str)) - { - error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - } else { - str->set_charset(spider_share->access_charset); - if ((error_num = spider_db_append_name_with_quote_str(str, - spider_share->tgt_dbs[roop_count], dbton_id))) - goto error; - if (roop_count) - { - same_db_table_name = FALSE; - DBUG_PRINT("info", ("spider found different db name %s", - spider_share->tgt_dbs[roop_count])); - if (str->length() > db_nm_max_length) - db_nm_max_length = str->length(); - } else - db_nm_max_length = str->length(); - } - - str = &db_table_str[roop_count]; - if ( - roop_count != 0 && - same_db_table_name - ) { - if (str->copy(*first_db_tbl_str)) - { - error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - } else { - str->set_charset(spider_share->access_charset); - if ((error_num = append_table_name(str, roop_count))) - goto error; - } -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - db_table_str_hash_value[roop_count] = my_calc_hash( - &spider_open_connections, (uchar*) str->ptr(), str->length()); -#endif - } - DBUG_RETURN(0); - -error: - if (db_table_str) - { - delete [] db_table_str; - db_table_str = NULL; - } - if (db_names_str) - { - delete [] db_names_str; - db_names_str = NULL; - } - if (table_names_str) - { - delete [] table_names_str; - table_names_str = NULL; - } - DBUG_RETURN(error_num); -} - -void spider_handlersocket_share::free_table_names_str() -{ - DBUG_ENTER("spider_handlersocket_share::free_table_names_str"); - if (db_table_str) - { - delete [] db_table_str; - db_table_str = NULL; - } - if (db_names_str) - { - delete [] db_names_str; - db_names_str = NULL; - } - if (table_names_str) - { - delete [] table_names_str; - table_names_str = NULL; - } - DBUG_VOID_RETURN; -} - -int spider_handlersocket_share::create_column_name_str() -{ - spider_string *str; - int error_num; - Field **field; - TABLE_SHARE *table_share = spider_share->table_share; - uint dbton_id = spider_dbton_handlersocket.dbton_id; - DBUG_ENTER("spider_handlersocket_share::create_column_name_str"); - if ( - table_share->fields && - !(column_name_str = new spider_string[table_share->fields]) - ) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - for (field = table_share->field, str = column_name_str; - *field; field++, str++) - { - str->init_calc_mem(202); - str->set_charset(spider_share->access_charset); - if ((error_num = spider_db_append_name_with_quote_str(str, - (*field)->field_name, dbton_id))) - goto error; - } - DBUG_RETURN(0); - -error: - if (column_name_str) - { - delete [] column_name_str; - column_name_str = NULL; - } - DBUG_RETURN(error_num); -} - -void spider_handlersocket_share::free_column_name_str() -{ - DBUG_ENTER("spider_handlersocket_share::free_column_name_str"); - if (column_name_str) - { - delete [] column_name_str; - column_name_str = NULL; - } - DBUG_VOID_RETURN; -} - -uint spider_handlersocket_share::get_column_name_length( - uint field_index -) { - DBUG_ENTER("spider_handlersocket_share::get_column_name_length"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(column_name_str[field_index].length()); -} - -int spider_handlersocket_share::append_column_name( - spider_string *str, - uint field_index -) { - int error_num; - DBUG_ENTER("spider_handlersocket_share::append_column_name"); - DBUG_PRINT("info",("spider this=%p", this)); - error_num = spider_db_handlersocket_utility.append_name(str, - column_name_str[field_index].ptr(), column_name_str[field_index].length()); - DBUG_RETURN(error_num); -} - -int spider_handlersocket_share::append_column_name_with_alias( - spider_string *str, - uint field_index, - const char *alias, - uint alias_length -) { - DBUG_ENTER("spider_handlersocket_share::append_column_name_with_alias"); - DBUG_PRINT("info",("spider this=%p", this)); - if (str->reserve( - alias_length + - column_name_str[field_index].length() + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(alias, alias_length); - append_column_name(str, field_index); - DBUG_RETURN(0); -} - -bool spider_handlersocket_share::need_change_db_table_name() -{ - DBUG_ENTER("spider_handlersocket_share::need_change_db_table_name"); - DBUG_RETURN(!same_db_table_name); -} - -#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE -int spider_handlersocket_share::discover_table_structure( - SPIDER_TRX *trx, - SPIDER_SHARE *spider_share, - spider_string *str -) { - DBUG_ENTER("spider_handlersocket_share::discover_table_structure"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -} -#endif - -spider_handlersocket_handler::spider_handlersocket_handler( - ha_spider *spider, - spider_handlersocket_share *db_share -) : spider_db_handler( - spider, - db_share -), - handlersocket_share(db_share), - link_for_hash(NULL) -{ - DBUG_ENTER("spider_handlersocket_handler::spider_handlersocket_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 187); - spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); - DBUG_VOID_RETURN; -} - -spider_handlersocket_handler::~spider_handlersocket_handler() -{ - DBUG_ENTER("spider_handlersocket_handler::~spider_handlersocket_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - if (link_for_hash) - { - spider_free(spider_current_trx, link_for_hash, MYF(0)); - } - spider_free_mem_calc(spider_current_trx, mem_calc_id, sizeof(*this)); - DBUG_VOID_RETURN; -} - -int spider_handlersocket_handler::init() -{ - st_spider_share *share = spider->share; - TABLE *table = spider->get_table(); - DBUG_ENTER("spider_handlersocket_handler::init"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(link_for_hash = (SPIDER_LINK_FOR_HASH *) - spider_bulk_alloc_mem(spider_current_trx, 204, - __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), - &link_for_hash, - sizeof(SPIDER_LINK_FOR_HASH) * share->link_count, - &minimum_select_bitmap, - table ? sizeof(uchar) * no_bytes_in_map(table->read_set) : 0, - NullS)) - ) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - uint roop_count; - for (roop_count = 0; roop_count < share->link_count; roop_count++) - { - link_for_hash[roop_count].spider = spider; - link_for_hash[roop_count].link_idx = roop_count; - link_for_hash[roop_count].db_table_str = - &handlersocket_share->db_table_str[roop_count]; -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - link_for_hash[roop_count].db_table_str_hash_value = - handlersocket_share->db_table_str_hash_value[roop_count]; -#endif - } - hs_sql.init_calc_mem(63); - hs_sql.set_charset(share->access_charset); - hs_keys.init(); - hs_upds.init(); - hs_strs.init(); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_index_hint( - spider_string *str, - int link_idx, - ulong sql_type - ) -{ - DBUG_ENTER("spider_handlersocket_handler::append_index_hint"); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_table_name_with_adjusting( - spider_string *str, - int link_idx, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_table_name_with_adjusting"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_tmp_table_and_sql_for_bka( - const key_range *start_key -) { - DBUG_ENTER("spider_handlersocket_handler::append_tmp_table_and_sql_for_bka"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reuse_tmp_table_and_sql_for_bka() -{ - DBUG_ENTER("spider_handlersocket_handler::reuse_tmp_table_and_sql_for_bka"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_union_table_and_sql_for_bka( - const key_range *start_key -) { - DBUG_ENTER("spider_handlersocket_handler::append_union_table_and_sql_for_bka"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reuse_union_table_and_sql_for_bka() -{ - DBUG_ENTER("spider_handlersocket_handler::reuse_union_table_and_sql_for_bka"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_insert_for_recovery( - ulong sql_type, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::append_insert_for_recovery"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_update( - const TABLE *table, - my_ptrdiff_t ptr_diff -) { - DBUG_ENTER("spider_handlersocket_handler::append_update"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_update( - const TABLE *table, - my_ptrdiff_t ptr_diff, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::append_update"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_delete( - const TABLE *table, - my_ptrdiff_t ptr_diff -) { - DBUG_ENTER("spider_handlersocket_handler::append_delete"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_delete( - const TABLE *table, - my_ptrdiff_t ptr_diff, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::append_delete"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_insert_part() -{ - DBUG_ENTER("spider_handlersocket_handler::append_insert_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_update_part() -{ - DBUG_ENTER("spider_handlersocket_handler::append_update_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_delete_part() -{ - DBUG_ENTER("spider_handlersocket_handler::append_delete_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -int spider_handlersocket_handler::append_increment_update_set_part() -{ - DBUG_ENTER("spider_handlersocket_handler::append_increment_update_set_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} -#endif - -int spider_handlersocket_handler::append_update_set_part() -{ - DBUG_ENTER("spider_handlersocket_handler::append_update_set_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -int spider_handlersocket_handler::append_direct_update_set_part() -{ - SPIDER_SHARE *share = spider->share; - DBUG_ENTER("spider_handlersocket_handler::append_direct_update_set_part"); - if ( - spider->do_direct_update && - (spider->direct_update_kinds & SPIDER_SQL_KIND_HS) - ) { - DBUG_PRINT("info",("spider add set for DU SPIDER_SQL_KIND_HS")); - size_t roop_count; - Field *field; - hs_adding_keys = FALSE; - for (roop_count = 0; roop_count < spider->hs_pushed_ret_fields_num; - roop_count++) - { - Field *top_table_field = - spider->get_top_table_field(spider->hs_pushed_ret_fields[roop_count]); - if (!(field = spider->field_exchange(top_table_field))) - continue; - if (top_table_field->is_null()) - { - hs_upds.push_back(spider_null_string_ref); - } else { - if (spider_db_handlersocket_utility. - append_column_value(spider, NULL, top_table_field, NULL, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - } - } - DBUG_RETURN(0); -} -#endif - -int spider_handlersocket_handler::append_minimum_select_without_quote( - spider_string *str -) { - TABLE *table = spider->get_table(); - Field **field; - int field_length; - bool appended = FALSE; - DBUG_ENTER("spider_handlersocket_handler::append_minimum_select_without_quote"); - minimum_select_bitmap_create(); - for (field = table->field; *field; field++) - { - if (minimum_select_bit_is_set((*field)->field_index)) - { -/* - spider_set_bit(minimum_select_bitmap, (*field)->field_index); -*/ - field_length = - handlersocket_share->column_name_str[(*field)->field_index].length(); - if (str->reserve(field_length + SPIDER_SQL_COMMA_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append( - handlersocket_share->column_name_str[(*field)->field_index].ptr(), - handlersocket_share->column_name_str[(*field)->field_index].length()); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - appended = TRUE; - } - } - if (appended) - str->length(str->length() - SPIDER_SQL_COMMA_LEN); - DBUG_RETURN(0); -} - -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -int spider_handlersocket_handler::append_minimum_select_by_field_idx_list( - spider_string *str, - uint32 *field_idxs, - size_t field_idxs_num -) { - Field *field; - int roop_count, field_length; - bool appended = FALSE; - DBUG_ENTER("spider_handlersocket_handler::append_minimum_select_by_field_idx_list"); - for (roop_count = 0; roop_count < (int) field_idxs_num; roop_count++) - { - field = spider->get_top_table_field(field_idxs[roop_count]); - if ((field = spider->field_exchange(field))) - { - field_length = - handlersocket_share->column_name_str[field->field_index].length(); - if (str->reserve(field_length + SPIDER_SQL_COMMA_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append( - handlersocket_share->column_name_str[field->field_index].ptr(), - handlersocket_share->column_name_str[field->field_index].length()); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - appended = TRUE; - } - } - if (appended) - str->length(str->length() - SPIDER_SQL_COMMA_LEN); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_dup_update_pushdown_part( - const char *alias, - uint alias_length -) { - DBUG_ENTER("spider_handlersocket_handler::append_dup_update_pushdown_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_update_columns_part( - const char *alias, - uint alias_length -) { - DBUG_ENTER("spider_handlersocket_handler::append_update_columns_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::check_update_columns_part() -{ - DBUG_ENTER("spider_handlersocket_handler::check_update_columns_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} -#endif - -int spider_handlersocket_handler::append_select_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_table_select_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_table_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_key_select_part( - ulong sql_type, - uint idx -) { - DBUG_ENTER("spider_handlersocket_handler::append_key_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_minimum_select_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_minimum_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_hint_after_table_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_hint_after_table_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -void spider_handlersocket_handler::set_where_pos( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::set_where_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -void spider_handlersocket_handler::set_where_to_pos( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::set_where_to_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -int spider_handlersocket_handler::check_item_type( - Item *item -) { - DBUG_ENTER("spider_handlersocket_handler::check_item_type"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_values_connector_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_values_connector_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_values_terminator_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_values_terminator_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_union_table_connector_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_union_table_connector_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_union_table_terminator_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_union_table_terminator_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_key_column_values_part( - const key_range *start_key, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_key_column_values_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_key_column_values_with_name_part( - const key_range *start_key, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_key_column_values_with_name_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_key_where_part( - const key_range *start_key, - const key_range *end_key, - ulong sql_type -) { - int error_num; - spider_string *str; - bool set_order; - DBUG_ENTER("spider_handlersocket_handler::append_key_where_part"); - switch (sql_type) - { - case SPIDER_SQL_TYPE_SELECT_HS: - case SPIDER_SQL_TYPE_INSERT_HS: - case SPIDER_SQL_TYPE_UPDATE_HS: - case SPIDER_SQL_TYPE_DELETE_HS: - str = &hs_sql; - str->length(0); - hs_adding_keys = TRUE; - set_order = FALSE; - break; - default: - DBUG_RETURN(0); - } - error_num = append_key_where(str, NULL, NULL, start_key, end_key, - sql_type, set_order); - DBUG_RETURN(error_num); -} - -int spider_handlersocket_handler::append_key_where( - spider_string *str, - spider_string *str_part, - spider_string *str_part2, - const key_range *start_key, - const key_range *end_key, - ulong sql_type, - bool set_order -) { - int error_num; - DBUG_ENTER("spider_handlersocket_handler::append_key_where"); - error_num = spider_db_append_key_where_internal(str, str_part, str_part2, - start_key, end_key, spider, set_order, sql_type, - spider_dbton_handlersocket.dbton_id); - DBUG_RETURN(error_num); -} - -int spider_handlersocket_handler::append_is_null_part( - ulong sql_type, - KEY_PART_INFO *key_part, - const key_range *key, - const uchar **ptr, - bool key_eq, - bool tgt_final -) { - int error_num; - spider_string *str; - DBUG_ENTER("spider_handlersocket_handler::append_is_null_part"); - DBUG_PRINT("info",("spider this=%p", this)); - switch (sql_type) - { - case SPIDER_SQL_TYPE_SELECT_HS: - case SPIDER_SQL_TYPE_INSERT_HS: - case SPIDER_SQL_TYPE_UPDATE_HS: - case SPIDER_SQL_TYPE_DELETE_HS: - str = &hs_sql; - break; - default: - DBUG_RETURN(0); - } - error_num = append_is_null(sql_type, str, NULL, NULL, key_part, key, ptr, - key_eq, tgt_final); - DBUG_RETURN(error_num); -} - -int spider_handlersocket_handler::append_is_null( - ulong sql_type, - spider_string *str, - spider_string *str_part, - spider_string *str_part2, - KEY_PART_INFO *key_part, - const key_range *key, - const uchar **ptr, - bool key_eq, - bool tgt_final -) { - DBUG_ENTER("spider_handlersocket_handler::append_is_null"); - DBUG_PRINT("info",("spider this=%p", this)); - if (key_part->null_bit) - { - if (*(*ptr)++) - { - hs_keys.push_back(spider_null_string_ref); - DBUG_RETURN(-1); - } - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_where_terminator_part( - ulong sql_type, - bool set_order, - int key_count -) { - DBUG_ENTER("spider_handlersocket_handler::append_where_terminator_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_match_where_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_match_where_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_condition_part( - const char *alias, - uint alias_length, - ulong sql_type, - bool test_flg -) { - DBUG_ENTER("spider_handlersocket_handler::append_condition_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_match_select_part( - ulong sql_type, - const char *alias, - uint alias_length -) { - DBUG_ENTER("spider_handlersocket_handler::append_match_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -#ifdef HANDLER_HAS_DIRECT_AGGREGATE -int spider_handlersocket_handler::append_sum_select_part( - ulong sql_type, - const char *alias, - uint alias_length -) { - DBUG_ENTER("spider_handlersocket_handler::append_sum_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} -#endif - -void spider_handlersocket_handler::set_order_pos( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::set_order_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -void spider_handlersocket_handler::set_order_to_pos( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::set_order_to_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -#ifdef HANDLER_HAS_DIRECT_AGGREGATE -int spider_handlersocket_handler::append_group_by_part( - const char *alias, - uint alias_length, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_group_by_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} -#endif - -int spider_handlersocket_handler::append_key_order_for_merge_with_alias_part( - const char *alias, - uint alias_length, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_key_order_for_merge_with_alias_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_key_order_for_direct_order_limit_with_alias_part( - const char *alias, - uint alias_length, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_key_order_for_direct_order_limit_with_alias_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_key_order_with_alias_part( - const char *alias, - uint alias_length, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_key_order_with_alias_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_limit_part( - longlong offset, - longlong limit, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_limit_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info", ("spider offset=%lld", offset)); - DBUG_PRINT("info", ("spider limit=%lld", limit)); - hs_skip = (int) offset; - hs_limit = (int) limit; - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reappend_limit_part( - longlong offset, - longlong limit, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reappend_limit_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_select_lock_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_select_lock_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_union_all_start_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_union_all_start_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_union_all_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_union_all_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_union_all_end_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_union_all_end_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_multi_range_cnt_part( - ulong sql_type, - uint multi_range_cnt, - bool with_comma -) { - DBUG_ENTER("spider_handlersocket_handler::append_multi_range_cnt_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_multi_range_cnt_with_name_part( - ulong sql_type, - uint multi_range_cnt -) { - DBUG_ENTER("spider_handlersocket_handler::append_multi_range_cnt_with_name_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_open_handler_part( - ulong sql_type, - uint handler_id, - SPIDER_CONN *conn, - int link_idx -) { - int error_num; - spider_string *str; - DBUG_ENTER("spider_handlersocket_handler::append_open_handler_part"); - DBUG_PRINT("info",("spider this=%p", this)); - switch (sql_type) - { - case SPIDER_SQL_TYPE_OTHER_HS: - str = &hs_sql; - break; - default: - DBUG_RETURN(0); - } - error_num = append_open_handler(str, handler_id, conn, link_idx); - DBUG_RETURN(error_num); -} - -int spider_handlersocket_handler::append_open_handler( - spider_string *str, - uint handler_id, - SPIDER_CONN *conn, - int link_idx -) { - int error_num; - DBUG_ENTER("spider_handlersocket_handler::append_open_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - if ( - str->length() == 0 && -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - ( - ( - ( - spider->sql_command == SQLCOM_HS_INSERT || - spider->hs_pushed_ret_fields_num == MAX_FIELDS - ) && -#endif - (error_num = append_minimum_select_without_quote(str)) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - ) || - ( - ( - spider->sql_command != SQLCOM_HS_INSERT && - spider->hs_pushed_ret_fields_num < MAX_FIELDS - ) && - (error_num = append_minimum_select_by_field_idx_list(str, - spider->hs_pushed_ret_fields, spider->hs_pushed_ret_fields_num)) - ) - ) -#endif - ) { - DBUG_RETURN(error_num); - } - - TABLE *table = spider->get_table(); - SPIDER_SHARE *share = spider->share; - DBUG_PRINT("info",("spider field list=%s", str->c_ptr_safe())); - if (!spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_set_bit(spider->db_request_phase, link_idx); - ++spider->db_request_id[link_idx]; - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->trx->spider_thread_id; - request_key.query_id = spider->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - conn->db_conn->append_open_handler( - handler_id, - share->tgt_dbs[spider->conn_link_idx[link_idx]], - share->tgt_table_names[spider->conn_link_idx[link_idx]], - spider->active_index < MAX_KEY ? - table->key_info[spider->active_index].name : - "0", - str->c_ptr_safe(), - &request_key - ); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_close_handler_part( - ulong sql_type, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::append_close_handler_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_insert_terminator_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_insert_terminator_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_insert_values_part( - ulong sql_type -) { - int error_num; - spider_string *str; - DBUG_ENTER("spider_mysql_handler::append_insert_values_part"); - DBUG_PRINT("info",("spider this=%p", this)); - switch (sql_type) - { - case SPIDER_SQL_TYPE_INSERT_HS: - str = &hs_sql; - break; - default: - DBUG_RETURN(0); - } - error_num = append_insert_values(str); - DBUG_RETURN(error_num); -} - -int spider_handlersocket_handler::append_insert_values( - spider_string *str -) { - SPIDER_SHARE *share = spider->share; - TABLE *table = spider->get_table(); - Field **field; - DBUG_ENTER("spider_mysql_handler::append_insert_values"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_adding_keys = FALSE; - for (field = table->field; *field; field++) - { - DBUG_PRINT("info",("spider field_index=%u", (*field)->field_index)); - if ( - bitmap_is_set(table->write_set, (*field)->field_index) || - bitmap_is_set(table->read_set, (*field)->field_index) - ) { -#ifndef DBUG_OFF - my_bitmap_map *tmp_map = - dbug_tmp_use_all_columns(table, table->read_set); -#endif - DBUG_PRINT("info",("spider is_null()=%s", - (*field)->is_null() ? "TRUE" : "FALSE")); - DBUG_PRINT("info",("spider table->next_number_field=%p", - table->next_number_field)); - DBUG_PRINT("info",("spider *field=%p", *field)); - DBUG_PRINT("info",("spider force_auto_increment=%s", - (table->next_number_field && spider->force_auto_increment) ? - "TRUE" : "FALSE")); - if ( - (*field)->is_null() || - ( - table->next_number_field == *field && - !table->auto_increment_field_not_null && - !spider->force_auto_increment - ) - ) { - hs_upds.push_back(spider_null_string_ref); - } else { - spider_db_handlersocket_utility. - append_column_value(spider, NULL, *field, NULL, - share->access_charset); - } -#ifndef DBUG_OFF - dbug_tmp_restore_column_map(table->read_set, tmp_map); -#endif - } - } - int error_num; - int roop_count2; - for ( - roop_count2 = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_count2 < (int) share->link_count; - roop_count2 = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count2, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - if (spider->sql_kind[roop_count2] == SPIDER_SQL_KIND_HS) - { - SPIDER_CONN *conn = spider->hs_w_conns[roop_count2]; - if (conn->dbton_id == spider_dbton_handlersocket.dbton_id) - { - if ((error_num = request_buf_insert(roop_count2))) - DBUG_RETURN(error_num); -#ifdef HA_CAN_BULK_ACCESS - if (spider->is_bulk_access_clone) - { - spider->connection_ids[roop_count2] = conn->connection_id; - spider_trx_add_bulk_access_conn(spider->trx, conn); - } -#endif - } - } - } - hs_upds.clear(); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_into_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_into_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -void spider_handlersocket_handler::set_insert_to_pos( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::set_insert_to_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -int spider_handlersocket_handler::append_from_part( - ulong sql_type, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::append_from_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_delete_all_rows_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_delete_all_rows_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_explain_select_part( - const key_range *start_key, - const key_range *end_key, - ulong sql_type, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::append_explain_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::is_sole_projection_field( - uint16 field_index -) { - DBUG_ENTER("spider_handlersocket_handler::is_sole_projection_field"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -bool spider_handlersocket_handler::is_bulk_insert_exec_period( - bool bulk_end -) { - DBUG_ENTER("spider_handlersocket_handler::is_bulk_insert_exec_period"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!spider->bulk_insert || bulk_end) - DBUG_RETURN(TRUE); - DBUG_RETURN(FALSE); -} - -bool spider_handlersocket_handler::sql_is_filled_up( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::sql_is_filled_up"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(FALSE); -} - -bool spider_handlersocket_handler::sql_is_empty( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::sql_is_empty"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(FALSE); -} - -bool spider_handlersocket_handler::support_multi_split_read() -{ - DBUG_ENTER("spider_handlersocket_handler::support_multi_split_read"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(FALSE); -} - -bool spider_handlersocket_handler::support_bulk_update() -{ - DBUG_ENTER("spider_handlersocket_handler::support_bulk_update"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(FALSE); -} - -int spider_handlersocket_handler::bulk_tmp_table_insert() -{ - DBUG_ENTER("spider_handlersocket_handler::bulk_tmp_table_insert"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::bulk_tmp_table_insert( - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::bulk_tmp_table_insert"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::bulk_tmp_table_end_bulk_insert() -{ - DBUG_ENTER("spider_handlersocket_handler::bulk_tmp_table_end_bulk_insert"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::bulk_tmp_table_rnd_init() -{ - DBUG_ENTER("spider_handlersocket_handler::bulk_tmp_table_rnd_init"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::bulk_tmp_table_rnd_next() -{ - DBUG_ENTER("spider_handlersocket_handler::bulk_tmp_table_rnd_next"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::bulk_tmp_table_rnd_end() -{ - DBUG_ENTER("spider_handlersocket_handler::bulk_tmp_table_rnd_end"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -bool spider_handlersocket_handler::need_copy_for_update( - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::need_copy_for_update"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(TRUE); -} - -bool spider_handlersocket_handler::bulk_tmp_table_created() -{ - DBUG_ENTER("spider_handlersocket_handler::bulk_tmp_table_created"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(FALSE); -} - -int spider_handlersocket_handler::mk_bulk_tmp_table_and_bulk_start() -{ - DBUG_ENTER("spider_handlersocket_handler::mk_bulk_tmp_table_and_bulk_start"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -void spider_handlersocket_handler::rm_bulk_tmp_table() -{ - DBUG_ENTER("spider_handlersocket_handler::rm_bulk_tmp_table"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} - -int spider_handlersocket_handler::insert_lock_tables_list( - SPIDER_CONN *conn, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::insert_lock_tables_list"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_lock_tables_list( - SPIDER_CONN *conn, - int link_idx, - int *appended -) { - DBUG_ENTER("spider_handlersocket_handler::append_lock_tables_list"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::realloc_sql( - ulong *realloced -) { - THD *thd = spider->trx->thd; - st_spider_share *share = spider->share; - int init_sql_alloc_size = - spider_param_init_sql_alloc_size(thd, share->init_sql_alloc_size); - DBUG_ENTER("spider_handlersocket_handler::realloc_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((int) hs_sql.alloced_length() > init_sql_alloc_size * 2) - { - hs_sql.free(); - if (hs_sql.real_alloc(init_sql_alloc_size)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - *realloced |= SPIDER_SQL_TYPE_FULL_HS; - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reset_sql( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reset_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - if (sql_type & SPIDER_SQL_TYPE_FULL_HS) - { - hs_sql.length(0); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reset_keys( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reset_keys"); - DBUG_PRINT("info",("spider this=%p", this)); - if (sql_type & SPIDER_SQL_TYPE_FULL_HS) - { - hs_keys.clear(); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reset_upds( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reset_upds"); - DBUG_PRINT("info",("spider this=%p", this)); - if (sql_type & SPIDER_SQL_TYPE_FULL_HS) - { - hs_upds.clear(); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reset_strs( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reset_strs"); - DBUG_PRINT("info",("spider this=%p", this)); - if (sql_type & SPIDER_SQL_TYPE_FULL_HS) - { - hs_strs.clear(); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reset_strs_pos( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reset_strs_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - if (sql_type & SPIDER_SQL_TYPE_FULL_HS) - { - hs_strs_pos = 0; - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::push_back_upds( - SPIDER_HS_STRING_REF &info -) { - int error_num; - DBUG_ENTER("spider_handlersocket_handler::push_back_upds"); - DBUG_PRINT("info",("spider this=%p", this)); - error_num = hs_upds.push_back(info); - DBUG_RETURN(error_num); -} - -int spider_handlersocket_handler::request_buf_find( - int link_idx -) { - int error_num; - spider_string *hs_str; - SPIDER_CONN *conn; - uint handler_id; - DBUG_ENTER("spider_handlersocket_handler::request_buf_find"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(hs_str = hs_strs.add(&hs_strs_pos, hs_sql.ptr(), hs_sql.length()))) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if (spider->conn_kind[link_idx] == SPIDER_CONN_KIND_HS_READ) - { - conn = spider->hs_r_conns[link_idx]; - handler_id = spider->r_handler_id[link_idx]; - } else { - conn = spider->hs_w_conns[link_idx]; - handler_id = spider->w_handler_id[link_idx]; - } - if ((error_num = spider_db_conn_queue_action(conn))) - DBUG_RETURN(error_num); - if (!spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_set_bit(spider->db_request_phase, link_idx); - ++spider->db_request_id[link_idx]; - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->trx->spider_thread_id; - request_key.query_id = spider->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - conn->db_conn->append_select( - handler_id, hs_str, &hs_keys, - hs_limit, hs_skip, &request_key); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::request_buf_insert( - int link_idx -) { - int error_num; - DBUG_ENTER("spider_handlersocket_handler::request_buf_insert"); - DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = spider_db_conn_queue_action(spider->hs_w_conns[link_idx]))) - DBUG_RETURN(error_num); - if (!spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_set_bit(spider->db_request_phase, link_idx); - ++spider->db_request_id[link_idx]; - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->trx->spider_thread_id; - request_key.query_id = spider->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - spider->hs_w_conns[link_idx]->db_conn->append_insert( - spider->w_handler_id[link_idx], &hs_upds, &request_key); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::request_buf_update( - int link_idx -) { - int error_num; - spider_string *hs_str; - DBUG_ENTER("spider_handlersocket_handler::request_buf_update"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(hs_str = hs_strs.add(&hs_strs_pos, hs_sql.ptr(), hs_sql.length()))) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if ((error_num = spider_db_conn_queue_action(spider->hs_w_conns[link_idx]))) - DBUG_RETURN(error_num); - if (!spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_set_bit(spider->db_request_phase, link_idx); - ++spider->db_request_id[link_idx]; - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->trx->spider_thread_id; - request_key.query_id = spider->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - spider->hs_w_conns[link_idx]->db_conn->append_update( - spider->w_handler_id[link_idx], hs_str, &hs_keys, &hs_upds, - hs_limit, hs_skip, - spider->hs_increment, spider->hs_decrement, &request_key - ); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::request_buf_delete( - int link_idx -) { - int error_num; - spider_string *hs_str; - DBUG_ENTER("spider_handlersocket_handler::request_buf_delete"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(hs_str = hs_strs.add(&hs_strs_pos, hs_sql.ptr(), hs_sql.length()))) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - if ((error_num = spider_db_conn_queue_action(spider->hs_w_conns[link_idx]))) - DBUG_RETURN(error_num); - if (!spider_bit_is_set(spider->db_request_phase, link_idx)) - { - spider_set_bit(spider->db_request_phase, link_idx); - ++spider->db_request_id[link_idx]; - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->trx->spider_thread_id; - request_key.query_id = spider->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = spider->db_request_id[link_idx]; - request_key.next = NULL; - spider->hs_w_conns[link_idx]->db_conn->append_delete( - spider->w_handler_id[link_idx], hs_str, &hs_keys, - hs_limit, hs_skip, &request_key); - DBUG_RETURN(0); -} - -bool spider_handlersocket_handler::need_lock_before_set_sql_for_exec( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::need_lock_before_set_sql_for_exec"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(TRUE); -} - -#ifdef SPIDER_HAS_GROUP_BY_HANDLER -int spider_handlersocket_handler::set_sql_for_exec( - ulong sql_type, - int link_idx, - SPIDER_LINK_IDX_CHAIN *link_idx_chain -) { - DBUG_ENTER("spider_handlersocket_handler::set_sql_for_exec"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} -#endif - -int spider_handlersocket_handler::set_sql_for_exec( - ulong sql_type, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::set_sql_for_exec"); - DBUG_PRINT("info",("spider this=%p", this)); - if (sql_type & SPIDER_SQL_TYPE_SELECT_HS) - { - DBUG_RETURN(request_buf_find(link_idx)); - } - if (sql_type & SPIDER_SQL_TYPE_INSERT_HS) - { - DBUG_RETURN(request_buf_insert(link_idx)); - } - if (sql_type & SPIDER_SQL_TYPE_UPDATE_HS) - { - DBUG_RETURN(request_buf_update(link_idx)); - } - if (sql_type & SPIDER_SQL_TYPE_DELETE_HS) - { - DBUG_RETURN(request_buf_delete(link_idx)); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::set_sql_for_exec( - spider_db_copy_table *tgt_ct, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::set_sql_for_exec"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::execute_sql( - ulong sql_type, - SPIDER_CONN *conn, - int quick_mode, - int *need_mon -) { - DBUG_ENTER("spider_handlersocket_handler::execute_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - if (!(sql_type & SPIDER_SQL_TYPE_FULL_HS)) - { - /* nothing to do */ - DBUG_RETURN(0); - } - DBUG_RETURN(spider_db_query( - conn, - NULL, - 0, - quick_mode, - need_mon - )); -} - -int spider_handlersocket_handler::reset() -{ - DBUG_ENTER("spider_handlersocket_handler::reset"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::sts_mode_exchange( - int sts_mode -) { - DBUG_ENTER("spider_handlersocket_handler::sts_mode_exchange"); - DBUG_PRINT("info",("spider sts_mode=%d", sts_mode)); - DBUG_RETURN(sts_mode); -} - -int spider_handlersocket_handler::show_table_status( - int link_idx, - int sts_mode, - uint flag -) { - spider_db_handlersocket_result res(NULL); - SPIDER_SHARE *share = spider->share; - ulonglong auto_increment_value = 0; - DBUG_ENTER("spider_handlersocket_show_table_status"); - res.fetch_table_status( - sts_mode, - share->stat - ); - if (auto_increment_value > share->lgtm_tblhnd_share->auto_increment_value) - { - share->lgtm_tblhnd_share->auto_increment_value = auto_increment_value; - DBUG_PRINT("info",("spider auto_increment_value=%llu", - share->lgtm_tblhnd_share->auto_increment_value)); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::crd_mode_exchange( - int crd_mode -) { - DBUG_ENTER("spider_handlersocket_handler::crd_mode_exchange"); - DBUG_PRINT("info",("spider crd_mode=%d", crd_mode)); - DBUG_RETURN(crd_mode); -} - -int spider_handlersocket_handler::show_index( - int link_idx, - int crd_mode -) { - DBUG_ENTER("spider_handlersocket_handler::show_index"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::show_records( - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::show_records"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::show_last_insert_id( - int link_idx, - ulonglong &last_insert_id -) { - DBUG_ENTER("spider_handlersocket_handler::show_last_insert_id"); - last_insert_id = 0; - DBUG_RETURN(0); -} - -ha_rows spider_handlersocket_handler::explain_select( - key_range *start_key, - key_range *end_key, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::explain_select"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::lock_tables( - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::lock_tables"); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::unlock_tables( - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::unlock_tables"); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::disable_keys( - SPIDER_CONN *conn, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::disable_keys"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::enable_keys( - SPIDER_CONN *conn, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::enable_keys"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::check_table( - SPIDER_CONN *conn, - int link_idx, - HA_CHECK_OPT* check_opt -) { - DBUG_ENTER("spider_handlersocket_handler::check_table"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::repair_table( - SPIDER_CONN *conn, - int link_idx, - HA_CHECK_OPT* check_opt -) { - DBUG_ENTER("spider_handlersocket_handler::repair_table"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::analyze_table( - SPIDER_CONN *conn, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::analyze_table"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::optimize_table( - SPIDER_CONN *conn, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::optimize_table"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::flush_tables( - SPIDER_CONN *conn, - int link_idx, - bool lock -) { - DBUG_ENTER("spider_handlersocket_handler::flush_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::flush_logs( - SPIDER_CONN *conn, - int link_idx -) { - DBUG_ENTER("spider_handlersocket_handler::flush_logs"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::insert_opened_handler( - SPIDER_CONN *conn, - int link_idx -) { - spider_db_handlersocket *db_conn = (spider_db_handlersocket *) conn->db_conn; - SPIDER_LINK_FOR_HASH *tmp_link_for_hash = &link_for_hash[link_idx]; - DBUG_ASSERT(tmp_link_for_hash->spider == spider); - DBUG_ASSERT(tmp_link_for_hash->link_idx == link_idx); - uint old_elements = db_conn->handler_open_array.max_element; - DBUG_ENTER("spider_handlersocket_handler::insert_opened_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - if (insert_dynamic(&db_conn->handler_open_array, - (uchar*) &tmp_link_for_hash)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - if (db_conn->handler_open_array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - db_conn->handler_open_array, - (db_conn->handler_open_array.max_element - old_elements) * - db_conn->handler_open_array.size_of_element); - } - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::delete_opened_handler( - SPIDER_CONN *conn, - int link_idx -) { - spider_db_handlersocket *db_conn = (spider_db_handlersocket *) conn->db_conn; - uint roop_count, elements = db_conn->handler_open_array.elements; - SPIDER_LINK_FOR_HASH *tmp_link_for_hash; - DBUG_ENTER("spider_handlersocket_handler::delete_opened_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - for (roop_count = 0; roop_count < elements; roop_count++) - { - get_dynamic(&db_conn->handler_open_array, (uchar *) &tmp_link_for_hash, - roop_count); - if (tmp_link_for_hash == &link_for_hash[link_idx]) - { - delete_dynamic_element(&db_conn->handler_open_array, roop_count); - break; - } - } - DBUG_ASSERT(roop_count < elements); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::sync_from_clone_source( - spider_db_handler *dbton_hdl -) { - spider_handlersocket_handler *hs_hdl = - (spider_handlersocket_handler *) dbton_hdl; - DBUG_ENTER("spider_handlersocket_handler::sync_from_clone_source"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_strs_pos = hs_hdl->hs_strs_pos; - DBUG_RETURN(0); -} - -bool spider_handlersocket_handler::support_use_handler( - int use_handler -) { - DBUG_ENTER("spider_handlersocket_handler::support_use_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(TRUE); -} - -void spider_handlersocket_handler::minimum_select_bitmap_create() -{ - TABLE *table = spider->get_table(); - Field **field_p; - DBUG_ENTER("spider_handlersocket_handler::minimum_select_bitmap_create"); - memset(minimum_select_bitmap, 0, no_bytes_in_map(table->read_set)); - if ( - spider->use_index_merge || -#ifdef HA_CAN_BULK_ACCESS - (spider->is_clone && !spider->is_bulk_access_clone) -#else - spider->is_clone -#endif - ) { - /* need preparing for cmp_ref */ - TABLE_SHARE *table_share = table->s; - if ( - table_share->primary_key == MAX_KEY - ) { - /* need all columns */ - memset(minimum_select_bitmap, 0xFF, no_bytes_in_map(table->read_set)); - DBUG_VOID_RETURN; - } else { - /* need primary key columns */ - uint roop_count; - KEY *key_info; - KEY_PART_INFO *key_part; - Field *field; - key_info = &table_share->key_info[table_share->primary_key]; - key_part = key_info->key_part; - for (roop_count = 0; - roop_count < spider_user_defined_key_parts(key_info); - roop_count++) - { - field = key_part[roop_count].field; - spider_set_bit(minimum_select_bitmap, field->field_index); - } - } - } - for (field_p = table->field; *field_p; field_p++) - { - uint field_index = (*field_p)->field_index; - if ( - spider_bit_is_set(spider->searched_bitmap, field_index) || - bitmap_is_set(table->read_set, field_index) || - bitmap_is_set(table->write_set, field_index) - ) { - spider_set_bit(minimum_select_bitmap, field_index); - } - } - DBUG_VOID_RETURN; -} - -bool spider_handlersocket_handler::minimum_select_bit_is_set( - uint field_index -) { - DBUG_ENTER("spider_handlersocket_handler::minimum_select_bit_is_set"); - DBUG_PRINT("info",("spider field_index=%u", field_index)); - DBUG_PRINT("info",("spider minimum_select_bitmap=%s", - spider_bit_is_set(minimum_select_bitmap, field_index) ? - "TRUE" : "FALSE")); - DBUG_RETURN(spider_bit_is_set(minimum_select_bitmap, field_index)); -} - -void spider_handlersocket_handler::copy_minimum_select_bitmap( - uchar *bitmap -) { - int roop_count; - TABLE *table = spider->get_table(); - DBUG_ENTER("spider_handlersocket_handler::copy_minimum_select_bitmap"); - for (roop_count = 0; - roop_count < (int) ((table->s->fields + 7) / 8); - roop_count++) - { - bitmap[roop_count] = - minimum_select_bitmap[roop_count]; - DBUG_PRINT("info",("spider roop_count=%d", roop_count)); - DBUG_PRINT("info",("spider bitmap=%d", - bitmap[roop_count])); - } - DBUG_VOID_RETURN; -} - -int spider_handlersocket_handler::init_union_table_name_pos() -{ - DBUG_ENTER("spider_handlersocket_handler::init_union_table_name_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::set_union_table_name_pos() -{ - DBUG_ENTER("spider_handlersocket_handler::set_union_table_name_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reset_union_table_name( - spider_string *str, - int link_idx, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reset_union_table_name"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -#ifdef SPIDER_HAS_GROUP_BY_HANDLER -int spider_handlersocket_handler::append_list_item_select_part( - List<Item> *select, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_list_item_select_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_from_and_tables_part( - spider_fields *fields, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_from_and_tables_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::reappend_tables_part( - spider_fields *fields, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::reappend_tables_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_where_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_where_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_having_part( - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_having_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_item_type_part( - Item *item, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_item_type_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_group_by_part( - ORDER *order, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_group_by_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_handlersocket_handler::append_order_by_part( - ORDER *order, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type -) { - DBUG_ENTER("spider_handlersocket_handler::append_order_by_part"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} -#endif -#endif diff --git a/storage/spider/spd_db_handlersocket.h b/storage/spider/spd_db_handlersocket.h deleted file mode 100644 index f7a454b66af..00000000000 --- a/storage/spider/spd_db_handlersocket.h +++ /dev/null @@ -1,1091 +0,0 @@ -/* Copyright (C) 2012-2018 Kentoku Shiba - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ - -#define SPIDER_HS_CONN dena::hstcpcli_ptr -#define SPIDER_HS_CONN_CREATE dena::hstcpcli_i::create -#define SPIDER_HS_RESULT dena::hstresult -#define SPIDER_HS_SOCKARGS dena::socket_args - -class spider_db_handlersocket_util: public spider_db_util -{ -public: - spider_db_handlersocket_util(); - ~spider_db_handlersocket_util(); - int append_name( - spider_string *str, - const char *name, - uint name_length - ); - int append_name_with_charset( - spider_string *str, - const char *name, - uint name_length, - CHARSET_INFO *name_charset - ); - int append_escaped_name( - spider_string *str, - const char *name, - uint name_length - ); - int append_escaped_name_with_charset( - spider_string *str, - const char *name, - uint name_length, - CHARSET_INFO *name_charset - ); - bool is_name_quote( - const char head_code - ); - int append_escaped_name_quote( - spider_string *str - ); - int append_column_value( - ha_spider *spider, - spider_string *str, - Field *field, - const uchar *new_ptr, - CHARSET_INFO *access_charset - ); - int append_trx_isolation( - spider_string *str, - int trx_isolation - ); - int append_autocommit( - spider_string *str, - bool autocommit - ); - int append_sql_log_off( - spider_string *str, - bool sql_log_off - ); - int append_wait_timeout( - spider_string *str, - int wait_timeout - ); - int append_sql_mode( - spider_string *str, - sql_mode_t sql_mode - ); - int append_time_zone( - spider_string *str, - Time_zone *time_zone - ); - int append_start_transaction( - spider_string *str - ); - int append_xa_start( - spider_string *str, - XID *xid - ); - int append_lock_table_head( - spider_string *str - ); - int append_lock_table_body( - spider_string *str, - const char *db_name, - uint db_name_length, - CHARSET_INFO *db_name_charset, - const char *table_name, - uint table_name_length, - CHARSET_INFO *table_name_charset, - int lock_type - ); - int append_lock_table_tail( - spider_string *str - ); - int append_unlock_table( - spider_string *str - ); - int open_item_func( - Item_func *item_func, - ha_spider *spider, - spider_string *str, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields - ); -#ifdef HANDLER_HAS_DIRECT_AGGREGATE - int open_item_sum_func( - Item_sum *item_sum, - ha_spider *spider, - spider_string *str, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields - ); -#endif - int append_escaped_util( - spider_string *to, - String *from - ); - int append_escaped_util( - spider_string *to, - String *from - ); -#ifdef SPIDER_HAS_GROUP_BY_HANDLER - int append_from_and_tables( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - uint table_count - ); - int reappend_tables( - spider_fields *fields, - SPIDER_LINK_IDX_CHAIN *link_idx_chain, - spider_string *str - ); - int append_where( - spider_string *str - ); - int append_having( - spider_string *str - ); -#endif -}; - -class spider_db_handlersocket_row: public spider_db_row -{ -public: - SPIDER_HS_STRING_REF *hs_row; - SPIDER_HS_STRING_REF *hs_row_first; - uint field_count; - uint row_size; - bool cloned; - spider_db_handlersocket_row(); - ~spider_db_handlersocket_row(); - int store_to_field( - Field *field, - CHARSET_INFO *access_charset - ); - int append_to_str( - spider_string *str - ); - int append_escaped_to_str( - spider_string *str, - uint dbton_id - ); - void first(); - void next(); - bool is_null(); - int val_int(); - double val_real(); - my_decimal *val_decimal( - my_decimal *decimal_value, - CHARSET_INFO *access_charset - ); - SPIDER_DB_ROW *clone(); - int store_to_tmp_table( - TABLE *tmp_table, - spider_string *str - ); - uint get_byte_size(); -}; - -class spider_db_handlersocket_result_buffer: public spider_db_result_buffer -{ -public: - SPIDER_HS_RESULT hs_result; - spider_db_handlersocket_result_buffer(); - ~spider_db_handlersocket_result_buffer(); - void clear(); - bool check_size( - longlong size - ); -}; - -class spider_db_handlersocket_result: public spider_db_result -{ -public: - SPIDER_HS_CONN *hs_conn_p; - spider_db_handlersocket_row row; - SPIDER_HS_STRING_REF hs_row; - uint field_count; - int store_error_num; - spider_db_handlersocket_result(SPIDER_DB_CONN *in_db_conn); - ~spider_db_handlersocket_result(); - bool has_result(); - void free_result(); - SPIDER_DB_ROW *current_row(); - SPIDER_DB_ROW *fetch_row(); - SPIDER_DB_ROW *fetch_row_from_result_buffer( - spider_db_result_buffer *spider_res_buf - ); - SPIDER_DB_ROW *fetch_row_from_tmp_table( - TABLE *tmp_table - ); - int fetch_table_status( - int mode, - ha_statistics &stat - ); - int fetch_table_records( - int mode, - ha_rows &records - ); - int fetch_table_cardinality( - int mode, - TABLE *table, - longlong *cardinality, - uchar *cardinality_upd, - int bitmap_size - ); - int fetch_table_mon_status( - int &status - ); - longlong num_rows(); - uint num_fields(); - void move_to_pos( - longlong pos - ); - int get_errno(); -#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE - int fetch_columns_for_discover_table_structure( - spider_string *str, - CHARSET_INFO *access_charset - ); - int fetch_index_for_discover_table_structure( - spider_string *str, - CHARSET_INFO *access_charset - ); - int fetch_table_for_discover_table_structure( - spider_string *str, - SPIDER_SHARE *spider_share, - CHARSET_INFO *access_charset - ); -#endif -}; - -class spider_db_handlersocket: public spider_db_conn -{ - SPIDER_HS_CONN hs_conn; - int stored_error; - uint field_count; -public: - DYNAMIC_ARRAY handler_open_array; - bool handler_open_array_inited; - uint handler_open_array_id; - const char *handler_open_array_func_name; - const char *handler_open_array_file_name; - ulong handler_open_array_line_no; - st_spider_db_request_key *request_key_req_first; - st_spider_db_request_key *request_key_req_last; - st_spider_db_request_key *request_key_snd_first; - st_spider_db_request_key *request_key_snd_last; - st_spider_db_request_key *request_key_reuse_first; - st_spider_db_request_key *request_key_reuse_last; - spider_db_handlersocket( - SPIDER_CONN *conn - ); - ~spider_db_handlersocket(); - int init(); - bool is_connected(); - void bg_connect(); - int connect( - char *tgt_host, - char *tgt_username, - char *tgt_password, - long tgt_port, - char *tgt_socket, - char *server_name, - int connect_retry_count, - longlong connect_retry_interval - ); - int ping(); - void bg_disconnect(); - void disconnect(); - int set_net_timeout(); - int exec_query( - const char *query, - uint length, - int quick_mode - ); - int get_errno(); - const char *get_error(); - bool is_server_gone_error( - int error_num - ); - bool is_dup_entry_error( - int error_num - ); - bool is_xa_nota_error( - int error_num - ); - spider_db_result *store_result( - spider_db_result_buffer **spider_res_buf, - st_spider_db_request_key *request_key, - int *error_num - ); - spider_db_result *use_result( - ha_spider *spider, - st_spider_db_request_key *request_key, - int *error_num - ); - int next_result(); - uint affected_rows(); - uint matched_rows(); - bool inserted_info( - spider_db_handler *handler, - spider_copy_info *copy_info - ); - ulonglong last_insert_id(); - int set_character_set( - const char *csname - ); - int select_db( - const char *dbname - ); - int consistent_snapshot( - int *need_mon - ); - bool trx_start_in_bulk_sql(); - int start_transaction( - int *need_mon - ); - int commit( - int *need_mon - ); - int rollback( - int *need_mon - ); - bool xa_start_in_bulk_sql(); - int xa_start( - XID *xid, - int *need_mon - ); - int xa_end( - XID *xid, - int *need_mon - ); - int xa_prepare( - XID *xid, - int *need_mon - ); - int xa_commit( - XID *xid, - int *need_mon - ); - int xa_rollback( - XID *xid, - int *need_mon - ); - bool set_trx_isolation_in_bulk_sql(); - int set_trx_isolation( - int trx_isolation, - int *need_mon - ); - bool set_autocommit_in_bulk_sql(); - int set_autocommit( - bool autocommit, - int *need_mon - ); - bool set_sql_log_off_in_bulk_sql(); - int set_sql_log_off( - bool sql_log_off, - int *need_mon - ); - bool set_wait_timeout_in_bulk_sql(); - int set_wait_timeout( - int wait_timeout, - int *need_mon - ); - bool set_sql_mode_in_bulk_sql(); - int set_sql_mode( - sql_mode_t sql_mode, - int *need_mon - ); - bool set_time_zone_in_bulk_sql(); - int set_time_zone( - Time_zone *time_zone, - int *need_mon - ); - int show_master_status( - SPIDER_TRX *trx, - SPIDER_SHARE *share, - int all_link_idx, - int *need_mon, - TABLE *table, - spider_string *str, - int mode, - SPIDER_DB_RESULT **res1, - SPIDER_DB_RESULT **res2 - ); - int append_sql( - char *sql, - ulong sql_length, - st_spider_db_request_key *request_key - ); - int append_open_handler( - uint handler_id, - const char *db_name, - const char *table_name, - const char *index_name, - const char *sql, - st_spider_db_request_key *request_key - ); - int append_select( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ); - int append_insert( - uint handler_id, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - st_spider_db_request_key *request_key - ); - int append_update( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - int limit, - int skip, - bool increment, - bool decrement, - st_spider_db_request_key *request_key - ); - int append_delete( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ); - void reset_request_queue(); - size_t escape_string( - char *to, - const char *from, - size_t from_length - ); - bool have_lock_table_list(); - int append_lock_tables( - spider_string *str - ); - int append_unlock_tables( - spider_string *str - ); - uint get_lock_table_hash_count(); - void reset_lock_table_hash(); - uint get_opened_handler_count(); - void reset_opened_handler(); - void set_dup_key_idx( - ha_spider *spider, - int link_idx - ); - int append_request_key( - st_spider_db_request_key *request_key - ); - void reset_request_key_req(); - void reset_request_key_snd(); - void move_request_key_to_snd(); - int check_request_key( - st_spider_db_request_key *request_key - ); - bool cmp_request_key_to_snd( - st_spider_db_request_key *request_key - ); -}; - -class spider_handlersocket_share: public spider_db_share -{ -public: - spider_string *table_names_str; - spider_string *db_names_str; - spider_string *db_table_str; -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - my_hash_value_type *db_table_str_hash_value; -#endif - uint table_nm_max_length; - uint db_nm_max_length; - spider_string *column_name_str; - bool same_db_table_name; - int first_all_link_idx; - spider_handlersocket_share( - st_spider_share *share - ); - ~spider_handlersocket_share(); - int init(); - int append_table_name( - spider_string *str, - int all_link_idx - ); - int create_table_names_str(); - void free_table_names_str(); - int create_column_name_str(); - void free_column_name_str(); - uint get_column_name_length( - uint field_index - ); - int append_column_name( - spider_string *str, - uint field_index - ); - int append_column_name_with_alias( - spider_string *str, - uint field_index, - const char *alias, - uint alias_length - ); - bool need_change_db_table_name(); -#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE - int discover_table_structure( - SPIDER_TRX *trx, - SPIDER_SHARE *spider_share, - spider_string *str - ); -#endif -}; - -class spider_handlersocket_handler: public spider_db_handler -{ - spider_string hs_sql; -public: - bool hs_adding_keys; - SPIDER_DB_HS_STRING_REF_BUFFER hs_keys; - SPIDER_DB_HS_STRING_REF_BUFFER hs_upds; - SPIDER_DB_HS_STR_BUFFER hs_strs; - uint hs_strs_pos; - int hs_limit; - int hs_skip; - spider_handlersocket_share *handlersocket_share; - SPIDER_LINK_FOR_HASH *link_for_hash; - uchar *minimum_select_bitmap; - spider_handlersocket_handler( - ha_spider *spider, - spider_handlersocket_share *db_share - ); - ~spider_handlersocket_handler(); - int init(); - int append_index_hint( - spider_string *str, - int link_idx, - ulong sql_type - ); - int append_table_name_with_adjusting( - spider_string *str, - int link_idx, - ulong sql_type - ); - int append_tmp_table_and_sql_for_bka( - const key_range *start_key - ); - int reuse_tmp_table_and_sql_for_bka(); - int append_union_table_and_sql_for_bka( - const key_range *start_key - ); - int reuse_union_table_and_sql_for_bka(); - int append_insert_for_recovery( - ulong sql_type, - int link_idx - ); - int append_update( - const TABLE *table, - my_ptrdiff_t ptr_diff - ); - int append_update( - const TABLE *table, - my_ptrdiff_t ptr_diff, - int link_idx - ); - int append_delete( - const TABLE *table, - my_ptrdiff_t ptr_diff - ); - int append_delete( - const TABLE *table, - my_ptrdiff_t ptr_diff, - int link_idx - ); - int append_insert_part(); - int append_update_part(); - int append_delete_part(); -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - int append_increment_update_set_part(); -#endif - int append_update_set_part(); -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - int append_direct_update_set_part(); -#endif - int append_minimum_select_without_quote( - spider_string *str - ); -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - int append_minimum_select_by_field_idx_list( - spider_string *str, - uint32 *field_idxs, - size_t field_idxs_num - ); - int append_dup_update_pushdown_part( - const char *alias, - uint alias_length - ); - int append_update_columns_part( - const char *alias, - uint alias_length - ); - int check_update_columns_part(); - int append_select_part( - ulong sql_type - ); -#endif - int append_table_select_part( - ulong sql_type - ); - int append_key_select_part( - ulong sql_type, - uint idx - ); - int append_minimum_select_part( - ulong sql_type - ); - int append_hint_after_table_part( - ulong sql_type - ); - void set_where_pos( - ulong sql_type - ); - void set_where_to_pos( - ulong sql_type - ); - int check_item_type( - Item *item - ); - int append_values_connector_part( - ulong sql_type - ); - int append_values_terminator_part( - ulong sql_type - ); - int append_union_table_connector_part( - ulong sql_type - ); - int append_union_table_terminator_part( - ulong sql_type - ); - int append_key_column_values_part( - const key_range *start_key, - ulong sql_type - ); - int append_key_column_values_with_name_part( - const key_range *start_key, - ulong sql_type - ); - int append_key_where_part( - const key_range *start_key, - const key_range *end_key, - ulong sql_type - ); - int append_key_where( - spider_string *str, - spider_string *str_part, - spider_string *str_part2, - const key_range *start_key, - const key_range *end_key, - ulong sql_type, - bool set_order - ); - int append_is_null_part( - ulong sql_type, - KEY_PART_INFO *key_part, - const key_range *key, - const uchar **ptr, - bool key_eq, - bool tgt_final - ); - int append_is_null( - ulong sql_type, - spider_string *str, - spider_string *str_part, - spider_string *str_part2, - KEY_PART_INFO *key_part, - const key_range *key, - const uchar **ptr, - bool key_eq, - bool tgt_final - ); - int append_where_terminator_part( - ulong sql_type, - bool set_order, - int key_count - ); - int append_match_where_part( - ulong sql_type - ); - int append_condition_part( - const char *alias, - uint alias_length, - ulong sql_type, - bool test_flg - ); - int append_match_select_part( - ulong sql_type, - const char *alias, - uint alias_length - ); -#ifdef HANDLER_HAS_DIRECT_AGGREGATE - int append_sum_select_part( - ulong sql_type, - const char *alias, - uint alias_length - ); -#endif - void set_order_pos( - ulong sql_type - ); - void set_order_to_pos( - ulong sql_type - ); -#ifdef HANDLER_HAS_DIRECT_AGGREGATE - int append_group_by_part( - const char *alias, - uint alias_length, - ulong sql_type - ); -#endif - int append_key_order_for_merge_with_alias_part( - const char *alias, - uint alias_length, - ulong sql_type - ); - int append_key_order_for_direct_order_limit_with_alias_part( - const char *alias, - uint alias_length, - ulong sql_type - ); - int append_key_order_with_alias_part( - const char *alias, - uint alias_length, - ulong sql_type - ); - int append_limit_part( - longlong offset, - longlong limit, - ulong sql_type - ); - int reappend_limit_part( - longlong offset, - longlong limit, - ulong sql_type - ); - int append_select_lock_part( - ulong sql_type - ); - int append_union_all_start_part( - ulong sql_type - ); - int append_union_all_part( - ulong sql_type - ); - int append_union_all_end_part( - ulong sql_type - ); - int append_multi_range_cnt_part( - ulong sql_type, - uint multi_range_cnt, - bool with_comma - ); - int append_multi_range_cnt_with_name_part( - ulong sql_type, - uint multi_range_cnt - ); - int append_open_handler_part( - ulong sql_type, - uint handler_id, - SPIDER_CONN *conn, - int link_idx - ); - int append_open_handler( - spider_string *str, - uint handler_id, - SPIDER_CONN *conn, - int link_idx - ); - int append_close_handler_part( - ulong sql_type, - int link_idx - ); - int append_insert_terminator_part( - ulong sql_type - ); - int append_insert_values_part( - ulong sql_type - ); - int append_insert_values( - spider_string *str - ); - int append_into_part( - ulong sql_type - ); - void set_insert_to_pos( - ulong sql_type - ); - int append_from_part( - ulong sql_type, - int link_idx - ); - int append_delete_all_rows_part( - ulong sql_type - ); - int append_explain_select_part( - const key_range *start_key, - const key_range *end_key, - ulong sql_type, - int link_idx - ); - bool is_sole_projection_field( - uint16 field_index - ); - bool is_bulk_insert_exec_period( - bool bulk_end - ); - bool sql_is_filled_up( - ulong sql_type - ); - bool sql_is_empty( - ulong sql_type - ); - bool support_multi_split_read(); - bool support_bulk_update(); - int bulk_tmp_table_insert(); - int bulk_tmp_table_insert( - int link_idx - ); - int bulk_tmp_table_end_bulk_insert(); - int bulk_tmp_table_rnd_init(); - int bulk_tmp_table_rnd_next(); - int bulk_tmp_table_rnd_end(); - bool need_copy_for_update( - int link_idx - ); - bool bulk_tmp_table_created(); - int mk_bulk_tmp_table_and_bulk_start(); - void rm_bulk_tmp_table(); - int insert_lock_tables_list( - SPIDER_CONN *conn, - int link_idx - ); - int append_lock_tables_list( - SPIDER_CONN *conn, - int link_idx, - int *appended - ); - int realloc_sql( - ulong *realloced - ); - int reset_sql( - ulong sql_type - ); - int reset_keys( - ulong sql_type - ); - int reset_upds( - ulong sql_type - ); - int reset_strs( - ulong sql_type - ); - int reset_strs_pos( - ulong sql_type - ); - int push_back_upds( - SPIDER_HS_STRING_REF &info - ); - int request_buf_find( - int link_idx - ); - int request_buf_insert( - int link_idx - ); - int request_buf_update( - int link_idx - ); - int request_buf_delete( - int link_idx - ); - bool need_lock_before_set_sql_for_exec( - ulong sql_type - ); -#ifdef SPIDER_HAS_GROUP_BY_HANDLER - int set_sql_for_exec( - ulong sql_type, - int link_idx, - SPIDER_LINK_IDX_CHAIN *link_idx_chain - ); -#endif - int set_sql_for_exec( - ulong sql_type, - int link_idx - ); - int set_sql_for_exec( - spider_db_copy_table *tgt_ct, - ulong sql_type - ); - int execute_sql( - ulong sql_type, - SPIDER_CONN *conn, - int quick_mode, - int *need_mon - ); - int reset(); - int sts_mode_exchange( - int sts_mode - ); - int show_table_status( - int link_idx, - int sts_mode, - uint flag - ); - int crd_mode_exchange( - int crd_mode - ); - int show_index( - int link_idx, - int crd_mode - ); - int show_records( - int link_idx - ); - int show_last_insert_id( - int link_idx, - ulonglong &last_insert_id - ); - ha_rows explain_select( - const key_range *start_key, - const key_range *end_key, - int link_idx - ); - int lock_tables( - int link_idx - ); - int unlock_tables( - int link_idx - ); - int disable_keys( - SPIDER_CONN *conn, - int link_idx - ); - int enable_keys( - SPIDER_CONN *conn, - int link_idx - ); - int check_table( - SPIDER_CONN *conn, - int link_idx, - HA_CHECK_OPT* check_opt - ); - int repair_table( - SPIDER_CONN *conn, - int link_idx, - HA_CHECK_OPT* check_opt - ); - int analyze_table( - SPIDER_CONN *conn, - int link_idx - ); - int optimize_table( - SPIDER_CONN *conn, - int link_idx - ); - int flush_tables( - SPIDER_CONN *conn, - int link_idx, - bool lock - ); - int flush_logs( - SPIDER_CONN *conn, - int link_idx - ); - int insert_opened_handler( - SPIDER_CONN *conn, - int link_idx - ); - int delete_opened_handler( - SPIDER_CONN *conn, - int link_idx - ); - int sync_from_clone_source( - spider_db_handler *dbton_hdl - ); - bool support_use_handler( - int use_handler - ); - void minimum_select_bitmap_create(); - bool minimum_select_bit_is_set( - uint field_index - ); - void copy_minimum_select_bitmap( - uchar *bitmap - ); - int init_union_table_name_pos(); - int set_union_table_name_pos(); - int reset_union_table_name( - spider_string *str, - int link_idx, - ulong sql_type - ); -#ifdef SPIDER_HAS_GROUP_BY_HANDLER - int append_from_and_tables_part( - spider_fields *fields, - ulong sql_type - ); - int reappend_tables_part( - spider_fields *fields, - ulong sql_type - ); - int append_where_part( - ulong sql_type - ); - int append_having_part( - ulong sql_type - ); - int append_item_type_part( - Item *item, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type - ); - int append_list_item_select_part( - List<Item> *select, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type - ); - int append_group_by_part( - ORDER *order, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type - ); - int append_order_by_part( - ORDER *order, - const char *alias, - uint alias_length, - bool use_fields, - spider_fields *fields, - ulong sql_type - ); -#endif -}; diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index e04f67897dc..3b8a7e133e7 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -14,10 +14,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ -#include "hs_compat.h" -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#include "hstcpcli.hpp" -#endif +#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \ + my_init_dynamic_array2(PSI_INSTRUMENT_ME, A, B, C, D, E, F) +#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ + init_alloc_root(PSI_INSTRUMENT_ME, A, B, C, D) #define SPIDER_DBTON_SIZE 15 @@ -116,26 +116,6 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_TABLE_NAME_STR "`table_name`" #define SPIDER_SQL_TABLE_NAME_LEN sizeof(SPIDER_SQL_TABLE_NAME_STR) - 1 -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#define SPIDER_SQL_HS_EQUAL_STR "=" -#define SPIDER_SQL_HS_EQUAL_LEN (sizeof(SPIDER_SQL_HS_EQUAL_STR) - 1) -#define SPIDER_SQL_HS_GT_STR ">" -#define SPIDER_SQL_HS_GT_LEN (sizeof(SPIDER_SQL_HS_GT_STR) - 1) -#define SPIDER_SQL_HS_GTEQUAL_STR ">=" -#define SPIDER_SQL_HS_GTEQUAL_LEN (sizeof(SPIDER_SQL_HS_GTEQUAL_STR) - 1) -#define SPIDER_SQL_HS_LT_STR "<" -#define SPIDER_SQL_HS_LT_LEN (sizeof(SPIDER_SQL_HS_LT_STR) - 1) -#define SPIDER_SQL_HS_INSERT_STR "+" -#define SPIDER_SQL_HS_INSERT_LEN (sizeof(SPIDER_SQL_HS_INSERT_STR) - 1) -#define SPIDER_SQL_HS_UPDATE_STR "U" -#define SPIDER_SQL_HS_UPDATE_LEN (sizeof(SPIDER_SQL_HS_UPDATE_STR) - 1) -#define SPIDER_SQL_HS_DELETE_STR "D" -#define SPIDER_SQL_HS_DELETE_LEN (sizeof(SPIDER_SQL_HS_DELETE_STR) - 1) -#define SPIDER_SQL_HS_INCREMENT_STR "+" -#define SPIDER_SQL_HS_INCREMENT_LEN (sizeof(SPIDER_SQL_HS_INCREMENT_STR) - 1) -#define SPIDER_SQL_HS_DECREMENT_STR "-" -#define SPIDER_SQL_HS_DECREMENT_LEN (sizeof(SPIDER_SQL_HS_DECREMENT_STR) - 1) -#endif #define SPIDER_SQL_HS_LTEQUAL_STR "<=" #define SPIDER_SQL_HS_LTEQUAL_LEN (sizeof(SPIDER_SQL_HS_LTEQUAL_STR) - 1) @@ -229,16 +209,9 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_LOP_CHK_PRM_PRF_LEN (sizeof(SPIDER_SQL_LOP_CHK_PRM_PRF_STR) - 1) #define SPIDER_CONN_KIND_MYSQL (1 << 0) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#define SPIDER_CONN_KIND_HS_READ (1 << 2) -#define SPIDER_CONN_KIND_HS_WRITE (1 << 3) -#endif #define SPIDER_SQL_KIND_SQL (1 << 0) #define SPIDER_SQL_KIND_HANDLER (1 << 1) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#define SPIDER_SQL_KIND_HS (1 << 2) -#endif #define SPIDER_SQL_TYPE_SELECT_SQL (1 << 0) #define SPIDER_SQL_TYPE_INSERT_SQL (1 << 1) @@ -744,71 +717,6 @@ public: ); }; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#define SPIDER_HS_UINT32_INFO dena::uint32_info -#define SPIDER_HS_STRING_REF dena::string_ref -#ifndef HANDLERSOCKET_MYSQL_UTIL -#define SPIDER_HS_VECTOR std::vector -class spider_db_hs_string_ref_buffer -{ - SPIDER_HS_VECTOR<SPIDER_HS_STRING_REF> hs_conds; -public: - spider_db_hs_string_ref_buffer(); - ~spider_db_hs_string_ref_buffer(); - int init(); - void clear(); - int push_back( - SPIDER_HS_STRING_REF &cond - ); - SPIDER_HS_STRING_REF *ptr(); - uint size(); -}; -#else -class spider_db_hs_string_ref_buffer -{ - bool hs_da_init; - DYNAMIC_ARRAY hs_conds; - uint hs_conds_id; - const char *hs_conds_func_name; - const char *hs_conds_file_name; - ulong hs_conds_line_no; -public: - spider_db_hs_string_ref_buffer(); - ~spider_db_hs_string_ref_buffer(); - int init(); - void clear(); - int push_back( - SPIDER_HS_STRING_REF &cond - ); - SPIDER_HS_STRING_REF *ptr(); - uint size(); -}; -#endif - -class spider_db_hs_str_buffer -{ - bool hs_da_init; - DYNAMIC_ARRAY hs_conds; - uint hs_conds_id; - const char *hs_conds_func_name; - const char *hs_conds_file_name; - ulong hs_conds_line_no; -public: - spider_db_hs_str_buffer(); - ~spider_db_hs_str_buffer(); - int init(); - void clear(); - spider_string *add( - uint *strs_pos, - const char *str, - uint str_len - ); -}; - -#define SPIDER_DB_HS_STRING_REF_BUFFER spider_db_hs_string_ref_buffer -#define SPIDER_DB_HS_STR_BUFFER spider_db_hs_str_buffer -#endif - struct st_spider_db_request_key { ulonglong spider_thread_id; @@ -1222,54 +1130,6 @@ public: SPIDER_DB_RESULT **res1, SPIDER_DB_RESULT **res2 ) = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - virtual int append_sql( - char *sql, - ulong sql_length, - st_spider_db_request_key *request_key - ) = 0; - virtual int append_open_handler( - uint handler_id, - const char *db_name, - const char *table_name, - const char *index_name, - const char *sql, - st_spider_db_request_key *request_key - ) = 0; - virtual int append_select( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ) = 0; - virtual int append_insert( - uint handler_id, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - st_spider_db_request_key *request_key - ) = 0; - virtual int append_update( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - int limit, - int skip, - bool increment, - bool decrement, - st_spider_db_request_key *request_key - ) = 0; - virtual int append_delete( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ) = 0; - virtual void reset_request_queue() = 0; -#endif virtual size_t escape_string( char *to, const char *from, @@ -1403,11 +1263,6 @@ public: virtual int append_insert_part() = 0; virtual int append_update_part() = 0; virtual int append_delete_part() = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - virtual int append_increment_update_set_part() = 0; -#endif -#endif virtual int append_update_set_part() = 0; #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS virtual int append_direct_update_set_part() = 0; @@ -1646,23 +1501,6 @@ public: virtual int reset_sql( ulong sql_type ) = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - virtual int reset_keys( - ulong sql_type - ) = 0; - virtual int reset_upds( - ulong sql_type - ) = 0; - virtual int reset_strs( - ulong sql_type - ) = 0; - virtual int reset_strs_pos( - ulong sql_type - ) = 0; - virtual int push_back_upds( - SPIDER_HS_STRING_REF &info - ) = 0; -#endif virtual bool need_lock_before_set_sql_for_exec( ulong sql_type ) = 0; @@ -2026,19 +1864,6 @@ typedef struct st_spider_result_list SPIDER_RESULT *current; KEY *key_info; int key_order; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ulonglong hs_upd_rows; - SPIDER_DB_RESULT *hs_result; - SPIDER_DB_RESULT_BUFFER *hs_result_buf; - bool hs_has_result; - SPIDER_DB_CONN *hs_conn; -#endif -#ifdef HA_CAN_BULK_ACCESS -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uchar *hs_r_bulk_open_index; - uchar *hs_w_bulk_open_index; -#endif -#endif spider_string *sqls; int ha_read_kind; bool have_sql_kind_backup; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 4033f8e79a6..14e71a33b31 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -3732,97 +3732,6 @@ int spider_db_mbase::select_binlog_gtid_pos( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int spider_db_mbase::append_sql( - char *sql, - ulong sql_length, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_mbase::append_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_mbase::append_open_handler( - uint handler_id, - const char *db_name, - const char *table_name, - const char *index_name, - const char *sql, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_mbase::append_open_handler"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_mbase::append_select( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_mbase::append_select"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_mbase::append_insert( - uint handler_id, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_mbase::append_insert"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_mbase::append_update( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - int limit, - int skip, - bool increment, - bool decrement, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_mbase::append_update"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_mbase::append_delete( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_mbase::append_delete"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -void spider_db_mbase::reset_request_queue() -{ - DBUG_ENTER("spider_db_mbase::reset_request_queue"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} -#endif - size_t spider_db_mbase::escape_string( char *to, const char *from, @@ -8943,9 +8852,6 @@ int spider_mbase_handler::init() mysql_share->db_table_str_hash_value[roop_count]; #endif } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - hs_upds.init(); -#endif DBUG_RETURN(0); } @@ -9856,67 +9762,6 @@ int spider_mbase_handler::append_delete( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -int spider_mbase_handler::append_increment_update_set_part() -{ - int error_num; - DBUG_ENTER("spider_mbase_handler::append_increment_update_set_part"); - DBUG_PRINT("info",("spider this=%p", this)); - error_num = append_increment_update_set(&update_sql); - DBUG_RETURN(error_num); -} - -int spider_mbase_handler::append_increment_update_set( - spider_string *str -) { - uint field_name_length; - uint roop_count; - Field *field; - DBUG_ENTER("spider_mbase_handler::append_increment_update_set"); - if (str->reserve(SPIDER_SQL_SET_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_SET_STR, SPIDER_SQL_SET_LEN); - const SPIDER_HS_STRING_REF *value = hs_upds.ptr(); - for (roop_count = 0; roop_count < hs_upds.size(); - roop_count++) - { - if ( - value[roop_count].size() == 1 && - *(value[roop_count].begin()) == '0' - ) - continue; - - Field *top_table_field = - spider->get_top_table_field(spider->hs_pushed_ret_fields[roop_count]); - if (!(field = spider->field_exchange(top_table_field))) - continue; - field_name_length = - mysql_share->column_name_str[field->field_index].length(); - - if (str->reserve(field_name_length * 2 + /* SPIDER_SQL_NAME_QUOTE_LEN */ - 4 + SPIDER_SQL_EQUAL_LEN + SPIDER_SQL_HS_INCREMENT_LEN + - SPIDER_SQL_COMMA_LEN + value[roop_count].size())) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - mysql_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - mysql_share->append_column_name(str, field->field_index); - if (spider->hs_increment) - str->q_append(SPIDER_SQL_HS_INCREMENT_STR, - SPIDER_SQL_HS_INCREMENT_LEN); - else - str->q_append(SPIDER_SQL_HS_DECREMENT_STR, - SPIDER_SQL_HS_DECREMENT_LEN); - str->q_append(value[roop_count].begin(), value[roop_count].size()); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); - DBUG_RETURN(0); -} -#endif -#endif - int spider_mbase_handler::append_update_set_part() { int error_num; @@ -9996,13 +9841,6 @@ int spider_mbase_handler::append_direct_update_set_part() int spider_mbase_handler::append_direct_update_set( spider_string *str ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint field_name_length; - SPIDER_SHARE *share = spider->share; -#ifndef DBUG_OFF - TABLE *table = spider->get_table(); -#endif -#endif DBUG_ENTER("spider_mbase_handler::append_direct_update_set"); if ( spider->direct_update_kinds == SPIDER_SQL_KIND_SQL && @@ -10018,61 +9856,7 @@ int spider_mbase_handler::append_direct_update_set( if ( (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - size_t roop_count; - Field *field; - if (str->reserve(SPIDER_SQL_SET_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_SET_STR, SPIDER_SQL_SET_LEN); - for (roop_count = 0; roop_count < spider->hs_pushed_ret_fields_num; - roop_count++) - { - Field *top_table_field = - spider->get_top_table_field(spider->hs_pushed_ret_fields[roop_count]); - if (!(field = spider->field_exchange(top_table_field))) - continue; - field_name_length = - mysql_share->column_name_str[field->field_index].length(); - if (top_table_field->is_null()) - { - if (str->reserve(field_name_length + /* SPIDER_SQL_NAME_QUOTE_LEN */ - 2 + SPIDER_SQL_EQUAL_LEN + SPIDER_SQL_NULL_LEN + - SPIDER_SQL_COMMA_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - mysql_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - str->q_append(SPIDER_SQL_NULL_STR, SPIDER_SQL_NULL_LEN); - } else { - if (str->reserve(field_name_length + /* SPIDER_SQL_NAME_QUOTE_LEN */ - 2 + SPIDER_SQL_EQUAL_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - mysql_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); -#ifndef DBUG_OFF - my_bitmap_map *tmp_map = dbug_tmp_use_all_columns(table, - table->read_set); -#endif - if ( - spider_db_mbase_utility-> - append_column_value(spider, str, top_table_field, NULL, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN) - ) { -#ifndef DBUG_OFF - dbug_tmp_restore_column_map(table->read_set, tmp_map); -#endif - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } -#ifndef DBUG_OFF - dbug_tmp_restore_column_map(table->read_set, tmp_map); -#endif - } - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); -#else DBUG_ASSERT(0); -#endif } DBUG_RETURN(0); } @@ -14059,54 +13843,6 @@ int spider_mbase_handler::reset_sql( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int spider_mbase_handler::reset_keys( - ulong sql_type -) { - DBUG_ENTER("spider_mbase_handler::reset_keys"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_mbase_handler::reset_upds( - ulong sql_type -) { - DBUG_ENTER("spider_mbase_handler::reset_upds"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_upds.clear(); - DBUG_RETURN(0); -} - -int spider_mbase_handler::reset_strs( - ulong sql_type -) { - DBUG_ENTER("spider_mbase_handler::reset_strs"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_mbase_handler::reset_strs_pos( - ulong sql_type -) { - DBUG_ENTER("spider_mbase_handler::reset_strs_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_mbase_handler::push_back_upds( - SPIDER_HS_STRING_REF &info -) { - int error_num; - DBUG_ENTER("spider_mbase_handler::push_back_upds"); - DBUG_PRINT("info",("spider this=%p", this)); - error_num = hs_upds.push_back(info); - DBUG_RETURN(error_num); -} -#endif - bool spider_mbase_handler::need_lock_before_set_sql_for_exec( ulong sql_type ) { diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index 8c7f52ef75b..09c51a7ab53 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -577,54 +577,6 @@ public: uint binlog_pos_length, SPIDER_DB_RESULT **res ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int append_sql( - char *sql, - ulong sql_length, - st_spider_db_request_key *request_key - ); - int append_open_handler( - uint handler_id, - const char *db_name, - const char *table_name, - const char *index_name, - const char *sql, - st_spider_db_request_key *request_key - ); - int append_select( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ); - int append_insert( - uint handler_id, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - st_spider_db_request_key *request_key - ); - int append_update( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - int limit, - int skip, - bool increment, - bool decrement, - st_spider_db_request_key *request_key - ); - int append_delete( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ); - void reset_request_queue(); -#endif size_t escape_string( char *to, const char *from, @@ -812,9 +764,6 @@ protected: spider_string *exec_ha_sql; bool reading_from_bulk_tmp_table; bool filled_up; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_DB_HS_STRING_REF_BUFFER hs_upds; -#endif SPIDER_INT_HLD *union_table_name_pos_first; SPIDER_INT_HLD *union_table_name_pos_current; public: @@ -921,14 +870,6 @@ public: int append_delete( spider_string *str ); - #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - int append_increment_update_set_part(); - int append_increment_update_set( - spider_string *str - ); - #endif - #endif int append_update_set_part(); int append_update_set( spider_string *str @@ -1459,23 +1400,6 @@ public: int reset_sql( ulong sql_type ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int reset_keys( - ulong sql_type - ); - int reset_upds( - ulong sql_type - ); - int reset_strs( - ulong sql_type - ); - int reset_strs_pos( - ulong sql_type - ); - int push_back_upds( - SPIDER_HS_STRING_REF &info - ); -#endif bool need_lock_before_set_sql_for_exec( ulong sql_type ); diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc index 77d3c808b70..3b0854e609d 100644 --- a/storage/spider/spd_db_oracle.cc +++ b/storage/spider/spd_db_oracle.cc @@ -2254,97 +2254,6 @@ int spider_db_oracle::show_master_status( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int spider_db_oracle::append_sql( - char *sql, - ulong sql_length, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_oracle::append_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_oracle::append_open_handler( - uint handler_id, - const char *db_name, - const char *table_name, - const char *index_name, - const char *sql, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_oracle::append_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_oracle::append_select( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_oracle::append_select"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_oracle::append_insert( - uint handler_id, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_oracle::append_insert"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_oracle::append_update( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - int limit, - int skip, - bool increment, - bool decrement, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_oracle::append_update"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_db_oracle::append_delete( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key -) { - DBUG_ENTER("spider_db_oracle::append_delete"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -void spider_db_oracle::reset_request_queue() -{ - DBUG_ENTER("spider_db_oracle::reset_request_queue"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_VOID_RETURN; -} -#endif - size_t spider_db_oracle::escape_string( char *to, const char *from, @@ -5646,9 +5555,6 @@ int spider_oracle_handler::init() oracle_share->db_table_str_hash_value[roop_count]; #endif } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - hs_upds.init(); -#endif DBUG_RETURN(0); } @@ -6417,78 +6323,6 @@ int spider_oracle_handler::append_delete( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -int spider_oracle_handler::append_increment_update_set_part() -{ - int error_num; - DBUG_ENTER("spider_oracle_handler::append_increment_update_set_part"); - DBUG_PRINT("info",("spider this=%p", this)); - error_num = append_increment_update_set(&update_sql); - DBUG_RETURN(error_num); -} - -int spider_oracle_handler::append_increment_update_set( - spider_string *str -) { - uint field_name_length; - uint roop_count; - Field *field; - DBUG_ENTER("spider_oracle_handler::append_increment_update_set"); - if (str->reserve(SPIDER_SQL_SET_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_SET_STR, SPIDER_SQL_SET_LEN); - const SPIDER_HS_STRING_REF *value = hs_upds.ptr(); - for (roop_count = 0; roop_count < hs_upds.size(); - roop_count++) - { - DBUG_PRINT("info",("spider value_size[%u]=%zu", roop_count, - value[roop_count].size())); -#ifndef DBUG_OFF - char print_buf[MAX_FIELD_WIDTH]; - if (value[roop_count].size() < MAX_FIELD_WIDTH) - { - memcpy(print_buf, value[roop_count].begin(), value[roop_count].size()); - print_buf[value[roop_count].size()] = '\0'; - DBUG_PRINT("info",("spider value[%u]=%s", roop_count, print_buf)); - } -#endif - if ( - value[roop_count].size() == 1 && - *(value[roop_count].begin()) == '0' - ) - continue; - - Field *top_table_field = - spider->get_top_table_field(spider->hs_pushed_ret_fields[roop_count]); - if (!(field = spider->field_exchange(top_table_field))) - continue; - field_name_length = - oracle_share->column_name_str[field->field_index].length(); - - if (str->reserve(field_name_length * 2 + /* SPIDER_SQL_NAME_QUOTE_LEN */ - 4 + SPIDER_SQL_EQUAL_LEN + SPIDER_SQL_HS_INCREMENT_LEN + - SPIDER_SQL_COMMA_LEN + value[roop_count].size())) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - oracle_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - oracle_share->append_column_name(str, field->field_index); - if (spider->hs_increment) - str->q_append(SPIDER_SQL_HS_INCREMENT_STR, - SPIDER_SQL_HS_INCREMENT_LEN); - else - str->q_append(SPIDER_SQL_HS_DECREMENT_STR, - SPIDER_SQL_HS_DECREMENT_LEN); - str->q_append(value[roop_count].begin(), value[roop_count].size()); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); - DBUG_RETURN(0); -} -#endif -#endif - int spider_oracle_handler::append_update_set_part() { int error_num; @@ -6573,13 +6407,6 @@ int spider_oracle_handler::append_direct_update_set_part() int spider_oracle_handler::append_direct_update_set( spider_string *str ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint field_name_length; - SPIDER_SHARE *share = spider->share; -#ifndef DBUG_OFF - TABLE *table = spider->get_table(); -#endif -#endif DBUG_ENTER("spider_oracle_handler::append_direct_update_set"); if ( spider->direct_update_kinds == SPIDER_SQL_KIND_SQL && @@ -6594,61 +6421,7 @@ int spider_oracle_handler::append_direct_update_set( if ( (spider->direct_update_kinds & SPIDER_SQL_KIND_SQL) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - size_t roop_count; - Field *field; - if (str->reserve(SPIDER_SQL_SET_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_SET_STR, SPIDER_SQL_SET_LEN); - for (roop_count = 0; roop_count < spider->hs_pushed_ret_fields_num; - roop_count++) - { - Field *top_table_field = - spider->get_top_table_field(spider->hs_pushed_ret_fields[roop_count]); - if (!(field = spider->field_exchange(top_table_field))) - continue; - field_name_length = - oracle_share->column_name_str[field->field_index].length(); - if (top_table_field->is_null()) - { - if (str->reserve(field_name_length + /* SPIDER_SQL_NAME_QUOTE_LEN */ - 2 + SPIDER_SQL_EQUAL_LEN + SPIDER_SQL_NULL_LEN + - SPIDER_SQL_COMMA_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - oracle_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - str->q_append(SPIDER_SQL_NULL_STR, SPIDER_SQL_NULL_LEN); - } else { - if (str->reserve(field_name_length + /* SPIDER_SQL_NAME_QUOTE_LEN */ - 2 + SPIDER_SQL_EQUAL_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - oracle_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); -#ifndef DBUG_OFF - my_bitmap_map *tmp_map = dbug_tmp_use_all_columns(table, - table->read_set); -#endif - if ( - spider_db_oracle_utility. - append_column_value(spider, str, top_table_field, NULL, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN) - ) { -#ifndef DBUG_OFF - dbug_tmp_restore_column_map(table->read_set, tmp_map); -#endif - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } -#ifndef DBUG_OFF - dbug_tmp_restore_column_map(table->read_set, tmp_map); -#endif - } - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); -#else DBUG_ASSERT(0); -#endif } DBUG_RETURN(0); } @@ -10784,54 +10557,6 @@ int spider_oracle_handler::reset_sql( DBUG_RETURN(0); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -int spider_oracle_handler::reset_keys( - ulong sql_type -) { - DBUG_ENTER("spider_oracle_handler::reset_keys"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_oracle_handler::reset_upds( - ulong sql_type -) { - DBUG_ENTER("spider_oracle_handler::reset_upds"); - DBUG_PRINT("info",("spider this=%p", this)); - hs_upds.clear(); - DBUG_RETURN(0); -} - -int spider_oracle_handler::reset_strs( - ulong sql_type -) { - DBUG_ENTER("spider_oracle_handler::reset_strs"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_oracle_handler::reset_strs_pos( - ulong sql_type -) { - DBUG_ENTER("spider_oracle_handler::reset_strs_pos"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(0); - DBUG_RETURN(0); -} - -int spider_oracle_handler::push_back_upds( - SPIDER_HS_STRING_REF &info -) { - int error_num; - DBUG_ENTER("spider_oracle_handler::push_back_upds"); - DBUG_PRINT("info",("spider this=%p", this)); - error_num = hs_upds.push_back(info); - DBUG_RETURN(error_num); -} -#endif - bool spider_oracle_handler::need_lock_before_set_sql_for_exec( ulong sql_type ) { diff --git a/storage/spider/spd_db_oracle.h b/storage/spider/spd_db_oracle.h index c8c1522599f..357fee35c67 100644 --- a/storage/spider/spd_db_oracle.h +++ b/storage/spider/spd_db_oracle.h @@ -473,54 +473,6 @@ public: SPIDER_DB_RESULT **res1, SPIDER_DB_RESULT **res2 ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int append_sql( - char *sql, - ulong sql_length, - st_spider_db_request_key *request_key - ); - int append_open_handler( - uint handler_id, - const char *db_name, - const char *table_name, - const char *index_name, - const char *sql, - st_spider_db_request_key *request_key - ); - int append_select( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ); - int append_insert( - uint handler_id, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - st_spider_db_request_key *request_key - ); - int append_update( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - SPIDER_DB_HS_STRING_REF_BUFFER *upds, - int limit, - int skip, - bool increment, - bool decrement, - st_spider_db_request_key *request_key - ); - int append_delete( - uint handler_id, - spider_string *sql, - SPIDER_DB_HS_STRING_REF_BUFFER *keys, - int limit, - int skip, - st_spider_db_request_key *request_key - ); - void reset_request_queue(); -#endif size_t escape_string( char *to, const char *from, @@ -685,9 +637,6 @@ private: bool filled_up; bool select_rownum_appended; bool update_rownum_appended; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_DB_HS_STRING_REF_BUFFER hs_upds; -#endif SPIDER_INT_HLD *union_table_name_pos_first; SPIDER_INT_HLD *union_table_name_pos_current; public: @@ -792,14 +741,6 @@ public: int append_delete( spider_string *str ); - #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - int append_increment_update_set_part(); - int append_increment_update_set( - spider_string *str - ); - #endif - #endif int append_update_set_part(); int append_update_set( spider_string *str @@ -1330,23 +1271,6 @@ public: int reset_sql( ulong sql_type ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int reset_keys( - ulong sql_type - ); - int reset_upds( - ulong sql_type - ); - int reset_strs( - ulong sql_type - ); - int reset_strs_pos( - ulong sql_type - ); - int push_back_upds( - SPIDER_HS_STRING_REF &info - ); -#endif bool need_lock_before_set_sql_for_exec( ulong sql_type ); diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 6db37de78ab..41f7bf6d6a4 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -220,54 +220,22 @@ int spider_udf_direct_sql_create_conn_key( spider_dbton[roop_count2].wrapper && !strcmp(direct_sql->tgt_wrapper, spider_dbton[roop_count2].wrapper) ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif if (spider_dbton[roop_count2].db_access_type == SPIDER_DB_ACCESS_TYPE_SQL) { direct_sql->dbton_id = roop_count2; break; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (spider_dbton[roop_count2].db_access_type == - SPIDER_DB_ACCESS_TYPE_NOSQL) - { - direct_sql->dbton_id = roop_count2; - break; - } - } -#endif } } if (direct_sql->dbton_id == SPIDER_DBTON_SIZE) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif my_printf_error( ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM, ER_SPIDER_SQL_WRAPPER_IS_INVALID_STR, MYF(0), direct_sql->tgt_wrapper); DBUG_RETURN(ER_SPIDER_SQL_WRAPPER_IS_INVALID_NUM); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - my_printf_error( - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM, - ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR, - MYF(0), direct_sql->tgt_wrapper); - DBUG_RETURN(ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM); - } -#endif } - -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif tables_on_different_db_are_joinable = spider_dbton[direct_sql->dbton_id].db_util-> tables_on_different_db_are_joinable(); @@ -292,16 +260,6 @@ int spider_udf_direct_sql_create_conn_key( + direct_sql->tgt_dsn_length + 1 + direct_sql->tgt_filedsn_length + 1 + direct_sql->tgt_driver_length; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - direct_sql->conn_key_length - = 1 - + direct_sql->tgt_wrapper_length + 1 - + direct_sql->tgt_host_length + 1 - + 5 + 1 - + direct_sql->tgt_socket_length; - } -#endif if (!(direct_sql->conn_key = (char *) spider_malloc(spider_current_trx, 9, direct_sql->conn_key_length + 1, MYF(MY_WME | MY_ZEROFILL))) @@ -328,12 +286,11 @@ int spider_udf_direct_sql_create_conn_key( { DBUG_PRINT("info",("spider tgt_socket=%s", direct_sql->tgt_socket)); tmp_name = strmov(tmp_name + 1, direct_sql->tgt_socket); - } else - tmp_name++; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) + } + else { -#endif + tmp_name++; + } if (!tables_on_different_db_are_joinable) { if (direct_sql->tgt_default_db_name) @@ -425,9 +382,6 @@ int spider_udf_direct_sql_create_conn_key( tmp_name = strmov(tmp_name + 1, direct_sql->tgt_driver); } else tmp_name++; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif #ifdef SPIDER_HAS_HASH_VALUE_TYPE direct_sql->conn_key_hash_value = my_calc_hash(&spider_open_connections, (uchar*) direct_sql->conn_key, direct_sql->conn_key_length); @@ -456,10 +410,6 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( UTC = my_tz_find(current_thd, &tz_00_name); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif tables_on_different_db_are_joinable = spider_dbton[direct_sql->dbton_id].db_util-> tables_on_different_db_are_joinable(); @@ -496,24 +446,6 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( goto error_alloc_conn; } conn->default_database.init_calc_mem(138); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 33, MYF(MY_WME | MY_ZEROFILL), - &conn, (uint) (sizeof(*conn)), - &tmp_name, (uint) (direct_sql->conn_key_length + 1), - &tmp_host, (uint) (direct_sql->tgt_host_length + 1), - &tmp_socket, (uint) (direct_sql->tgt_socket_length + 1), - &tmp_wrapper, (uint) (direct_sql->tgt_wrapper_length + 1), - &need_mon, (uint) (sizeof(int)), - NullS)) - ) { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_alloc_conn; - } - conn->default_database.init_calc_mem(103); - } -#endif conn->conn_key_length = direct_sql->conn_key_length; conn->conn_key = tmp_name; @@ -525,10 +457,6 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( conn->tgt_host_length = direct_sql->tgt_host_length; conn->tgt_host = tmp_host; memcpy(conn->tgt_host, direct_sql->tgt_host, direct_sql->tgt_host_length); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif conn->tgt_port = direct_sql->tgt_port; conn->tgt_socket_length = direct_sql->tgt_socket_length; conn->tgt_socket = tmp_socket; @@ -630,18 +558,6 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( } else conn->tgt_driver = NULL; conn->tgt_ssl_vsc = direct_sql->tgt_ssl_vsc; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - conn->hs_port = direct_sql->tgt_port; - if (direct_sql->tgt_socket) - { - conn->hs_sock_length = direct_sql->tgt_socket_length; - conn->hs_sock = tmp_socket; - memcpy(conn->hs_sock, direct_sql->tgt_socket, - direct_sql->tgt_socket_length); - } - } -#endif conn->dbton_id = direct_sql->dbton_id; conn->conn_need_mon = need_mon; conn->need_mon = need_mon; @@ -660,19 +576,7 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( conn->semi_trx_isolation = -2; conn->semi_trx_isolation_chk = FALSE; conn->semi_trx_chk = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif conn->conn_kind = SPIDER_CONN_KIND_MYSQL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (direct_sql->access_mode == 1) - { - conn->conn_kind = SPIDER_CONN_KIND_HS_READ; - } else { - conn->conn_kind = SPIDER_CONN_KIND_HS_WRITE; - } -#endif #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&conn->mta_conn_mutex, MY_MUTEX_INIT_FAST)) @@ -763,82 +667,26 @@ SPIDER_CONN *spider_udf_direct_sql_get_conn( ) { SPIDER_CONN *conn = NULL; DBUG_ENTER("spider_udf_direct_sql_get_conn"); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - DBUG_PRINT("info",("spider direct_sql->access_mode=%d", - direct_sql->access_mode)); -#endif #ifdef SPIDER_HAS_HASH_VALUE_TYPE if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (direct_sql->access_mode == 0 && -#endif !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( &trx->trx_conn_hash, direct_sql->conn_key_hash_value, (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) || - (direct_sql->access_mode == 1 && - !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( - &trx->trx_direct_hs_r_conn_hash, direct_sql->conn_key_hash_value, - (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)) - ) || - (direct_sql->access_mode == 2 && - !(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( - &trx->trx_direct_hs_w_conn_hash, direct_sql->conn_key_hash_value, - (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)) - ) -#endif ) #else if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (direct_sql->access_mode == 0 && -#endif !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_conn_hash, (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) || - (direct_sql->access_mode == 1 && - !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_direct_hs_r_conn_hash, - (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)) - ) || - (direct_sql->access_mode == 2 && - !(conn = (SPIDER_CONN*) my_hash_search(&trx->trx_direct_hs_w_conn_hash, - (uchar*) direct_sql->conn_key, direct_sql->conn_key_length)) - ) -#endif ) #endif { if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (direct_sql->access_mode == 0 && -#endif ( (spider_param_conn_recycle_mode(trx->thd) & 1) || spider_param_conn_recycle_strict(trx->thd) ) -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) || - (direct_sql->access_mode == 1 && - ( - (spider_param_hs_r_conn_recycle_mode(trx->thd) & 1) || - spider_param_hs_r_conn_recycle_strict(trx->thd) - ) - ) || - (direct_sql->access_mode == 2 && - ( - (spider_param_hs_w_conn_recycle_mode(trx->thd) & 1) || - spider_param_hs_w_conn_recycle_strict(trx->thd) - ) - ) -#endif ) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif pthread_mutex_lock(&spider_conn_mutex); #ifdef SPIDER_HAS_HASH_VALUE_TYPE if (!(conn = (SPIDER_CONN*) my_hash_search_using_hash_value( @@ -864,9 +712,6 @@ SPIDER_CONN *spider_udf_direct_sql_get_conn( pthread_mutex_unlock(&spider_conn_mutex); DBUG_PRINT("info",("spider get global conn")); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif } else { DBUG_PRINT("info",("spider create new conn")); /* conn_recycle_strict = 0 and conn_recycle_mode = 0 or 2 */ @@ -876,10 +721,6 @@ SPIDER_CONN *spider_udf_direct_sql_get_conn( conn->thd = trx->thd; conn->priority = direct_sql->priority; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 0) - { -#endif uint old_elements = trx->trx_conn_hash.array.max_element; #ifdef HASH_UPDATE_WITH_HASH_VALUE if (my_hash_insert_with_hash_value(&trx->trx_conn_hash, @@ -899,50 +740,6 @@ SPIDER_CONN *spider_udf_direct_sql_get_conn( (trx->trx_conn_hash.array.max_element - old_elements) * trx->trx_conn_hash.array.size_of_element); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (direct_sql->access_mode == 1) - { - uint old_elements = trx->trx_direct_hs_r_conn_hash.array.max_element; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - if (my_hash_insert_with_hash_value(&trx->trx_direct_hs_r_conn_hash, - direct_sql->conn_key_hash_value, (uchar*) conn)) -#else - if (my_hash_insert(&trx->trx_direct_hs_r_conn_hash, (uchar*) conn)) -#endif - { - spider_free_conn(conn); - *error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - if (trx->trx_direct_hs_r_conn_hash.array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - trx->trx_direct_hs_r_conn_hash, - (trx->trx_direct_hs_r_conn_hash.array.max_element - old_elements) * - trx->trx_direct_hs_r_conn_hash.array.size_of_element); - } - } else { - uint old_elements = trx->trx_direct_hs_w_conn_hash.array.max_element; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - if (my_hash_insert_with_hash_value(&trx->trx_direct_hs_w_conn_hash, - direct_sql->conn_key_hash_value, (uchar*) conn)) -#else - if (my_hash_insert(&trx->trx_direct_hs_w_conn_hash, (uchar*) conn)) -#endif - { - spider_free_conn(conn); - *error_num = HA_ERR_OUT_OF_MEM; - goto error; - } - if (trx->trx_direct_hs_w_conn_hash.array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - trx->trx_direct_hs_w_conn_hash, - (trx->trx_direct_hs_w_conn_hash.array.max_element - old_elements) * - trx->trx_direct_hs_w_conn_hash.array.size_of_element); - } - } -#endif } if (conn->queued_connect) @@ -1228,9 +1025,6 @@ int spider_udf_parse_direct_sql_param( direct_sql->net_write_timeout = -1; direct_sql->bulk_insert_rows = -1; direct_sql->connection_channel = -1; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - direct_sql->access_mode = -1; -#endif #if MYSQL_VERSION_ID < 50500 #else direct_sql->use_real_table = -1; @@ -1290,9 +1084,6 @@ int spider_udf_parse_direct_sql_param( goto error; continue; case 3: -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_INT_WITH_MAX("acm", access_mode, 0, 2); -#endif SPIDER_PARAM_LONGLONG("bir", bulk_insert_rows, 0); SPIDER_PARAM_INT_WITH_MAX("cch", connection_channel, 0, 63); SPIDER_PARAM_INT("cto", connect_timeout, 0); @@ -1352,9 +1143,6 @@ int spider_udf_parse_direct_sql_param( error_num = param_string_parse.print_param_error(); goto error; case 11: -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_INT_WITH_MAX("access_mode", access_mode, 0, 2); -#endif error_num = param_string_parse.print_param_error(); goto error; case 12: @@ -1451,9 +1239,6 @@ int spider_udf_set_direct_sql_param_default( } if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - direct_sql->access_mode == 0 && -#endif !direct_sql->tgt_socket && (!direct_sql->tgt_host || !strcmp(direct_sql->tgt_host, my_localhost)) ) { @@ -1620,20 +1405,8 @@ int spider_udf_set_direct_sql_param_default( } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == -1) - direct_sql->access_mode = 0; -#endif - if (port_has_default_value) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (direct_sql->access_mode == 1) - direct_sql->tgt_port = 9998; - else if (direct_sql->access_mode == 2) - direct_sql->tgt_port = 9999; - else -#endif direct_sql->tgt_port = MYSQL_PORT; } else if (direct_sql->tgt_port < 0) @@ -1897,15 +1670,8 @@ long long spider_direct_sql_body( goto error; } } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (trx->trx_start && direct_sql->access_mode != 1) - { -#endif trx->updated_in_this_trx = TRUE; DBUG_PRINT("info",("spider trx->updated_in_this_trx=TRUE")); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } -#endif #if MYSQL_VERSION_ID < 50500 #else use_real_table = spider_param_udf_ds_use_real_table(thd, diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 25eeb87d5ff..dde20098a4a 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -469,11 +469,6 @@ typedef struct st_spider_conn #endif int link_idx; spider_db_conn *db_conn; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - query_id_t hsc_query_id; - ulonglong hs_pre_age; - ulonglong hs_age; -#endif uint opened_handlers; ulonglong conn_id; ulonglong connection_id; @@ -538,10 +533,6 @@ typedef struct st_spider_conn char *tgt_driver; long tgt_port; long tgt_ssl_vsc; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char *hs_sock; - long hs_port; -#endif uint tgt_host_length; uint tgt_username_length; @@ -559,9 +550,6 @@ typedef struct st_spider_conn uint tgt_dsn_length; uint tgt_filedsn_length; uint tgt_driver_length; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint hs_sock_length; -#endif uint dbton_id; #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -748,11 +736,6 @@ typedef struct st_spider_wide_handler uchar *rnd_write_bitmap; SPIDER_CONDITION *condition; void *owner; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - uint32 *hs_pushed_ret_fields; -#endif -#endif #ifdef WITH_PARTITION_STORAGE_ENGINE SPIDER_PARTITION_HANDLER *partition_handler; #endif @@ -763,11 +746,6 @@ typedef struct st_spider_wide_handler TABLE_SHARE *top_share; enum thr_lock_type lock_type; uchar lock_table_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - uint32 hs_pushed_strref_num; -#endif -#endif int lock_mode; int external_lock_type; int cond_check_error; @@ -781,13 +759,6 @@ typedef struct st_spider_wide_handler #ifdef HA_CAN_BULK_ACCESS ulonglong external_lock_cnt; #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - size_t hs_pushed_ret_fields_num; - size_t hs_pushed_ret_fields_size; - size_t hs_pushed_lcl_fields_num; -#endif -#endif bool between_flg; bool idx_bitmap_is_set; bool rnd_bitmap_is_set; @@ -804,12 +775,6 @@ typedef struct st_spider_wide_handler bool write_can_replace; bool insert_with_update; bool cond_check; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - bool hs_increment; - bool hs_decrement; -#endif -#endif bool semi_table_lock; } SPIDER_WIDE_HANDLER; @@ -845,30 +810,6 @@ typedef struct st_spider_transaction const char *trx_another_conn_hash_func_name; const char *trx_another_conn_hash_file_name; ulong trx_another_conn_hash_line_no; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - HASH trx_hs_r_conn_hash; - uint trx_hs_r_conn_hash_id; - const char *trx_hs_r_conn_hash_func_name; - const char *trx_hs_r_conn_hash_file_name; - ulong trx_hs_r_conn_hash_line_no; - HASH trx_hs_w_conn_hash; - uint trx_hs_w_conn_hash_id; - const char *trx_hs_w_conn_hash_func_name; - const char *trx_hs_w_conn_hash_file_name; - ulong trx_hs_w_conn_hash_line_no; -#endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - HASH trx_direct_hs_r_conn_hash; - uint trx_direct_hs_r_conn_hash_id; - const char *trx_direct_hs_r_conn_hash_func_name; - const char *trx_direct_hs_r_conn_hash_file_name; - ulong trx_direct_hs_r_conn_hash_line_no; - HASH trx_direct_hs_w_conn_hash; - uint trx_direct_hs_w_conn_hash_id; - const char *trx_direct_hs_w_conn_hash_func_name; - const char *trx_direct_hs_w_conn_hash_file_name; - ulong trx_direct_hs_w_conn_hash_line_no; -#endif HASH trx_alter_table_hash; uint trx_alter_table_hash_id; const char *trx_alter_table_hash_func_name; @@ -884,10 +825,6 @@ typedef struct st_spider_transaction SPIDER_CONN *join_trx_top; ulonglong spider_thread_id; ulonglong trx_conn_adjustment; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ulonglong trx_hs_r_conn_adjustment; - ulonglong trx_hs_w_conn_adjustment; -#endif uint locked_connections; ulonglong direct_update_count; @@ -895,9 +832,6 @@ typedef struct st_spider_transaction ulonglong direct_order_limit_count; ulonglong direct_aggregate_count; ulonglong parallel_search_count; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ulonglong hs_result_free_count; -#endif #ifdef HA_CAN_BULK_ACCESS SPIDER_CONN *bulk_access_conn_first; @@ -1113,9 +1047,6 @@ typedef struct st_spider_share int error_read_mode; int error_write_mode; int active_link_count; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - longlong hs_result_free_size; -#endif #ifdef HA_CAN_BULK_ACCESS int bulk_access_free; #endif @@ -1134,10 +1065,6 @@ typedef struct st_spider_share #ifdef SPIDER_HAS_HASH_VALUE_TYPE my_hash_value_type *conn_keys_hash_value; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - my_hash_value_type *hs_read_conn_keys_hash_value; - my_hash_value_type *hs_write_conn_keys_hash_value; -#endif #endif char **server_names; char **tgt_table_names; @@ -1161,12 +1088,6 @@ typedef struct st_spider_share char **tgt_pk_names; char **tgt_sequence_names; char **conn_keys; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char **hs_read_socks; - char **hs_write_socks; - char **hs_read_conn_keys; - char **hs_write_conn_keys; -#endif long *tgt_ports; long *tgt_ssl_vscs; long *link_statuses; @@ -1182,13 +1103,6 @@ typedef struct st_spider_share #endif longlong *monitoring_limit; longlong *monitoring_sid; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - long *use_hs_reads; - long *use_hs_writes; - long *hs_read_ports; - long *hs_write_ports; - long *hs_write_to_reads; -#endif long *use_handlers; long *connect_timeouts; long *net_read_timeouts; @@ -1219,16 +1133,7 @@ typedef struct st_spider_share uint *tgt_pk_names_lengths; uint *tgt_sequence_names_lengths; uint *conn_keys_lengths; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint *hs_read_socks_lengths; - uint *hs_write_socks_lengths; - uint *hs_read_conn_keys_lengths; - uint *hs_write_conn_keys_lengths; -#endif uint *sql_dbton_ids; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint *hs_dbton_ids; -#endif uint server_names_charlen; uint tgt_table_names_charlen; @@ -1252,12 +1157,6 @@ typedef struct st_spider_share uint tgt_pk_names_charlen; uint tgt_sequence_names_charlen; uint conn_keys_charlen; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint hs_read_socks_charlen; - uint hs_write_socks_charlen; - uint hs_read_conn_keys_charlen; - uint hs_write_conn_keys_charlen; -#endif uint server_names_length; uint tgt_table_names_length; @@ -1281,12 +1180,6 @@ typedef struct st_spider_share uint tgt_pk_names_length; uint tgt_sequence_names_length; uint conn_keys_length; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint hs_read_socks_length; - uint hs_write_socks_length; - uint hs_read_conn_keys_length; - uint hs_write_conn_keys_length; -#endif uint tgt_ports_length; uint tgt_ssl_vscs_length; uint link_statuses_length; @@ -1302,13 +1195,6 @@ typedef struct st_spider_share #endif uint monitoring_limit_length; uint monitoring_sid_length; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint use_hs_reads_length; - uint use_hs_writes_length; - uint hs_read_ports_length; - uint hs_write_ports_length; - uint hs_write_to_reads_length; -#endif uint use_handlers_length; uint connect_timeouts_length; uint net_read_timeouts_length; @@ -1326,11 +1212,6 @@ typedef struct st_spider_share uint use_sql_dbton_count; uint use_sql_dbton_ids[SPIDER_DBTON_SIZE]; uint sql_dbton_id_to_seq[SPIDER_DBTON_SIZE]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint use_hs_dbton_count; - uint use_hs_dbton_ids[SPIDER_DBTON_SIZE]; - uint hs_dbton_id_to_seq[SPIDER_DBTON_SIZE]; -#endif SPIDER_ALTER_TABLE alter_table; SPIDER_WIDE_SHARE *wide_share; @@ -1389,9 +1270,6 @@ typedef struct st_spider_direct_sql int net_write_timeout; longlong bulk_insert_rows; int connection_channel; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - int access_mode; -#endif #if MYSQL_VERSION_ID < 50500 #else int use_real_table; diff --git a/storage/spider/spd_init_query.h b/storage/spider/spd_init_query.h index 0dcbcd50230..1cf987134f6 100644 --- a/storage/spider/spd_init_query.h +++ b/storage/spider/spd_init_query.h @@ -543,7 +543,7 @@ static LEX_STRING spider_init_queries[] = { " @server_major_version > 10 or" " (" " @server_major_version = 10 and" - " @server_minor_version >= 8" + " @server_minor_version >= 999" " )" " )" " then" @@ -803,7 +803,7 @@ static LEX_STRING spider_init_queries[] = { " @server_major_version > 10 or" " (" " @server_major_version = 10 and" - " @server_minor_version >= 8" + " @server_minor_version >= 999" " )" " )" " then" diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc index 1c9bc10d9c3..b14c19fc2c2 100644 --- a/storage/spider/spd_param.cc +++ b/storage/spider/spd_param.cc @@ -101,19 +101,6 @@ static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff) DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -static int spider_hs_result_free(THD *thd, SHOW_VAR *var, char *buff) -{ - int error_num = 0; - SPIDER_TRX *trx; - DBUG_ENTER("spider_hs_result_free"); - var->type = SHOW_LONGLONG; - if ((trx = spider_get_trx(thd, TRUE, &error_num))) - var->value = (char *) &trx->hs_result_free_count; - DBUG_RETURN(error_num); -} -#endif - struct st_mysql_show_var spider_status_variables[] = { {"Spider_mon_table_cache_version", @@ -144,13 +131,6 @@ struct st_mysql_show_var spider_status_variables[] = {"Spider_parallel_search", (char *) &spider_parallel_search, SHOW_FUNC}, #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef SPIDER_HAS_SHOW_SIMPLE_FUNC - {"Spider_hs_result_free", (char *) &spider_hs_result_free, SHOW_SIMPLE_FUNC}, -#else - {"Spider_hs_result_free", (char *) &spider_hs_result_free, SHOW_FUNC}, -#endif -#endif {NullS, NullS, SHOW_LONG} }; @@ -655,33 +635,6 @@ int spider_param_reset_sql_alloc( reset_sql_alloc : THDVAR(thd, reset_sql_alloc)); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -/* - -1 :use table parameter - 0-:result free size for handlersocket - */ -static MYSQL_THDVAR_LONGLONG( - hs_result_free_size, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Result free size for handlersocket", /* comment */ - NULL, /* check */ - NULL, /* update */ - -1, /* def */ - -1, /* min */ - 9223372036854775807LL, /* max */ - 0 /* blk */ -); - -longlong spider_param_hs_result_free_size( - THD *thd, - longlong hs_result_free_size -) { - DBUG_ENTER("spider_param_hs_result_free_size"); - DBUG_RETURN(THDVAR(thd, hs_result_free_size) < 0 ? - hs_result_free_size : THDVAR(thd, hs_result_free_size)); -} -#endif - /* -1 :use table parameter 0 :off @@ -1929,31 +1882,6 @@ double spider_param_ping_interval_at_trx_start( DBUG_RETURN(THDVAR(thd, ping_interval_at_trx_start)); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -/* - 0 :always ping - 1-:interval - */ -static MYSQL_THDVAR_INT( - hs_ping_interval, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Ping interval for handlersocket", /* comment */ - NULL, /* check */ - NULL, /* update */ - 30, /* def */ - 0, /* min */ - 2147483647, /* max */ - 0 /* blk */ -); - -double spider_param_hs_ping_interval( - THD *thd -) { - DBUG_ENTER("spider_param_hs_ping_interval"); - DBUG_RETURN(THDVAR(thd, hs_ping_interval)); -} -#endif - /* -1 :use table parameter 0 :normal mode @@ -2553,154 +2481,6 @@ longlong spider_param_udf_ct_bulk_insert_rows( udf_ct_bulk_insert_rows : spider_udf_ct_bulk_insert_rows); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -/* - 0: no recycle - 1: recycle in instance - 2: recycle in thread - */ -static MYSQL_THDVAR_UINT( - hs_r_conn_recycle_mode, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Handlersocket connection recycle mode", /* comment */ - NULL, /* check */ - NULL, /* update */ - 2, /* def */ - 0, /* min */ - 2, /* max */ - 0 /* blk */ -); - -uint spider_param_hs_r_conn_recycle_mode( - THD *thd -) { - DBUG_ENTER("spider_param_hs_r_conn_recycle_mode"); - DBUG_RETURN(THDVAR(thd, hs_r_conn_recycle_mode)); -} - -/* - 0: weak - 1: strict - */ -static MYSQL_THDVAR_UINT( - hs_r_conn_recycle_strict, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Strict handlersocket connection recycle", /* comment */ - NULL, /* check */ - NULL, /* update */ - 0, /* def */ - 0, /* min */ - 1, /* max */ - 0 /* blk */ -); - -uint spider_param_hs_r_conn_recycle_strict( - THD *thd -) { - DBUG_ENTER("spider_param_hs_r_conn_recycle_strict"); - DBUG_RETURN(THDVAR(thd, hs_r_conn_recycle_strict)); -} - -/* - 0: no recycle - 1: recycle in instance - 2: recycle in thread - */ -static MYSQL_THDVAR_UINT( - hs_w_conn_recycle_mode, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Handlersocket connection recycle mode", /* comment */ - NULL, /* check */ - NULL, /* update */ - 2, /* def */ - 0, /* min */ - 2, /* max */ - 0 /* blk */ -); - -uint spider_param_hs_w_conn_recycle_mode( - THD *thd -) { - DBUG_ENTER("spider_param_hs_w_conn_recycle_mode"); - DBUG_RETURN(THDVAR(thd, hs_w_conn_recycle_mode)); -} - -/* - 0: weak - 1: strict - */ -static MYSQL_THDVAR_UINT( - hs_w_conn_recycle_strict, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Strict handlersocket connection recycle", /* comment */ - NULL, /* check */ - NULL, /* update */ - 0, /* def */ - 0, /* min */ - 1, /* max */ - 0 /* blk */ -); - -uint spider_param_hs_w_conn_recycle_strict( - THD *thd -) { - DBUG_ENTER("spider_param_hs_w_conn_recycle_strict"); - DBUG_RETURN(THDVAR(thd, hs_w_conn_recycle_strict)); -} - -/* - -1 :use table parameter - 0 :not use - 1 :use handlersocket - */ -static MYSQL_THDVAR_INT( - use_hs_read, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Use handlersocket for reading", /* comment */ - NULL, /* check */ - NULL, /* update */ - -1, /* def */ - -1, /* min */ - 1, /* max */ - 0 /* blk */ -); - -int spider_param_use_hs_read( - THD *thd, - int use_hs_read -) { - DBUG_ENTER("spider_param_use_hs_read"); - DBUG_RETURN(THDVAR(thd, use_hs_read) == -1 ? - use_hs_read : THDVAR(thd, use_hs_read)); -} - -/* - -1 :use table parameter - 0 :not use - 1 :use handlersocket - */ -static MYSQL_THDVAR_INT( - use_hs_write, /* name */ - PLUGIN_VAR_RQCMDARG, /* opt */ - "Use handlersocket for writing", /* comment */ - NULL, /* check */ - NULL, /* update */ - -1, /* def */ - -1, /* min */ - 1, /* max */ - 0 /* blk */ -); - -int spider_param_use_hs_write( - THD *thd, - int use_hs_write -) { - DBUG_ENTER("spider_param_use_hs_write"); - DBUG_RETURN(THDVAR(thd, use_hs_write) == -1 ? - use_hs_write : THDVAR(thd, use_hs_write)); -} -#endif - /* -1 :use table parameter 0 :not use @@ -3528,9 +3308,6 @@ static struct st_mysql_sys_var* spider_system_variables[] = { MYSQL_SYSVAR(semi_split_read_limit), MYSQL_SYSVAR(init_sql_alloc_size), MYSQL_SYSVAR(reset_sql_alloc), -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - MYSQL_SYSVAR(hs_result_free_size), -#endif MYSQL_SYSVAR(multi_split_read), MYSQL_SYSVAR(max_order), MYSQL_SYSVAR(semi_trx_isolation), @@ -3591,9 +3368,6 @@ static struct st_mysql_sys_var* spider_system_variables[] = { MYSQL_SYSVAR(sts_bg_mode), #endif MYSQL_SYSVAR(ping_interval_at_trx_start), -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - MYSQL_SYSVAR(hs_ping_interval), -#endif MYSQL_SYSVAR(auto_increment_mode), MYSQL_SYSVAR(same_server_link), MYSQL_SYSVAR(local_lock_table), @@ -3616,14 +3390,6 @@ static struct st_mysql_sys_var* spider_system_variables[] = { MYSQL_SYSVAR(bka_mode), MYSQL_SYSVAR(udf_ct_bulk_insert_interval), MYSQL_SYSVAR(udf_ct_bulk_insert_rows), -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - MYSQL_SYSVAR(hs_r_conn_recycle_mode), - MYSQL_SYSVAR(hs_r_conn_recycle_strict), - MYSQL_SYSVAR(hs_w_conn_recycle_mode), - MYSQL_SYSVAR(hs_w_conn_recycle_strict), - MYSQL_SYSVAR(use_hs_read), - MYSQL_SYSVAR(use_hs_write), -#endif MYSQL_SYSVAR(use_handler), MYSQL_SYSVAR(error_read_mode), MYSQL_SYSVAR(error_write_mode), diff --git a/storage/spider/spd_param.h b/storage/spider/spd_param.h index c3a79cec065..a6a9dd80026 100644 --- a/storage/spider/spd_param.h +++ b/storage/spider/spd_param.h @@ -73,12 +73,6 @@ int spider_param_reset_sql_alloc( THD *thd, int reset_sql_alloc ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -longlong spider_param_hs_result_free_size( - THD *thd, - longlong hs_result_free_size -); -#endif int spider_param_multi_split_read( THD *thd, int multi_split_read @@ -261,11 +255,6 @@ int spider_param_sts_bg_mode( double spider_param_ping_interval_at_trx_start( THD *thd ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -double spider_param_hs_ping_interval( - THD *thd -); -#endif int spider_param_auto_increment_mode( THD *thd, int auto_increment_mode @@ -320,28 +309,6 @@ int spider_param_udf_ct_bulk_insert_interval( longlong spider_param_udf_ct_bulk_insert_rows( longlong udf_ct_bulk_insert_rows ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -uint spider_param_hs_r_conn_recycle_mode( - THD *thd -); -uint spider_param_hs_r_conn_recycle_strict( - THD *thd -); -uint spider_param_hs_w_conn_recycle_mode( - THD *thd -); -uint spider_param_hs_w_conn_recycle_strict( - THD *thd -); -int spider_param_use_hs_read( - THD *thd, - int use_hs_read -); -int spider_param_use_hs_write( - THD *thd, - int use_hs_write -); -#endif int spider_param_use_handler( THD *thd, int use_handler diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index f2fc6c089b0..e3f8ba22b7f 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -31,6 +31,7 @@ #include "sql_select.h" #include "tztime.h" #include "sql_parse.h" +#include "create_options.h" #endif #include "spd_err.h" #include "spd_param.h" @@ -137,9 +138,6 @@ handlerton *spider_hton_ptr; SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; extern SPIDER_DBTON spider_dbton_mysql; extern SPIDER_DBTON spider_dbton_mariadb; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -extern SPIDER_DBTON spider_dbton_handlersocket; -#endif #ifdef HAVE_ORACLE_OCI extern SPIDER_DBTON spider_dbton_oracle; #endif @@ -156,10 +154,6 @@ PSI_mutex_key spd_key_mutex_wide_share; #endif PSI_mutex_key spd_key_mutex_lgtm_tblhnd_share; PSI_mutex_key spd_key_mutex_conn; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -PSI_mutex_key spd_key_mutex_hs_r_conn; -PSI_mutex_key spd_key_mutex_hs_w_conn; -#endif PSI_mutex_key spd_key_mutex_open_conn; PSI_mutex_key spd_key_mutex_allocated_thds; PSI_mutex_key spd_key_mutex_mon_table_cache; @@ -206,10 +200,6 @@ static PSI_mutex_info all_spider_mutexes[]= #endif { &spd_key_mutex_lgtm_tblhnd_share, "lgtm_tblhnd_share", PSI_FLAG_GLOBAL}, { &spd_key_mutex_conn, "conn", PSI_FLAG_GLOBAL}, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - { &spd_key_mutex_hs_r_conn, "hs_r_conn", PSI_FLAG_GLOBAL}, - { &spd_key_mutex_hs_w_conn, "hs_w_conn", PSI_FLAG_GLOBAL}, -#endif { &spd_key_mutex_open_conn, "open_conn", PSI_FLAG_GLOBAL}, { &spd_key_mutex_allocated_thds, "allocated_thds", PSI_FLAG_GLOBAL}, { &spd_key_mutex_mon_table_cache, "mon_table_cache", PSI_FLAG_GLOBAL}, @@ -311,6 +301,18 @@ static PSI_thread_info all_spider_threads[] = { }; #endif +struct ha_table_option_struct +{ + char *remote_server; + char *remote_database; + char *remote_table; +}; + +ha_create_table_option spider_table_option_list[]= { + HA_TOPTION_STRING("REMOTE_SERVER", remote_server), + HA_TOPTION_STRING("REMOTE_DATABASE", remote_database), + HA_TOPTION_STRING("REMOTE_TABLE", remote_table), HA_TOPTION_END}; + extern HASH spider_open_connections; extern HASH spider_ipport_conns; extern uint spider_open_connections_id; @@ -318,20 +320,6 @@ extern const char *spider_open_connections_func_name; extern const char *spider_open_connections_file_name; extern ulong spider_open_connections_line_no; extern pthread_mutex_t spider_conn_mutex; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -extern HASH spider_hs_r_conn_hash; -extern uint spider_hs_r_conn_hash_id; -extern const char *spider_hs_r_conn_hash_func_name; -extern const char *spider_hs_r_conn_hash_file_name; -extern ulong spider_hs_r_conn_hash_line_no; -extern pthread_mutex_t spider_hs_r_conn_mutex; -extern HASH spider_hs_w_conn_hash; -extern uint spider_hs_w_conn_hash_id; -extern const char *spider_hs_w_conn_hash_func_name; -extern const char *spider_hs_w_conn_hash_file_name; -extern ulong spider_hs_w_conn_hash_line_no; -extern pthread_mutex_t spider_hs_w_conn_mutex; -#endif extern HASH *spider_udf_table_mon_list_hash; extern uint spider_udf_table_mon_list_hash_id; extern const char *spider_udf_table_mon_list_hash_func_name; @@ -851,30 +839,6 @@ int spider_free_share_alloc( } spider_free(spider_current_trx, share->static_link_ids, MYF(0)); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (share->hs_read_socks) - { - for (roop_count = 0; roop_count < (int) share->hs_read_socks_length; - roop_count++) - { - if (share->hs_read_socks[roop_count]) - spider_free(spider_current_trx, share->hs_read_socks[roop_count], - MYF(0)); - } - spider_free(spider_current_trx, share->hs_read_socks, MYF(0)); - } - if (share->hs_write_socks) - { - for (roop_count = 0; roop_count < (int) share->hs_write_socks_length; - roop_count++) - { - if (share->hs_write_socks[roop_count]) - spider_free(spider_current_trx, share->hs_write_socks[roop_count], - MYF(0)); - } - spider_free(spider_current_trx, share->hs_write_socks, MYF(0)); - } -#endif if (share->bka_engine) spider_free(spider_current_trx, share->bka_engine, MYF(0)); if (share->conn_keys) @@ -897,18 +861,6 @@ int spider_free_share_alloc( spider_free(spider_current_trx, share->monitoring_flag, MYF(0)); if (share->monitoring_kind) spider_free(spider_current_trx, share->monitoring_kind, MYF(0)); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (share->use_hs_reads) - spider_free(spider_current_trx, share->use_hs_reads, MYF(0)); - if (share->use_hs_writes) - spider_free(spider_current_trx, share->use_hs_writes, MYF(0)); - if (share->hs_read_ports) - spider_free(spider_current_trx, share->hs_read_ports, MYF(0)); - if (share->hs_write_ports) - spider_free(spider_current_trx, share->hs_write_ports, MYF(0)); - if (share->hs_write_to_reads) - spider_free(spider_current_trx, share->hs_write_to_reads, MYF(0)); -#endif if (share->use_handlers) spider_free(spider_current_trx, share->use_handlers, MYF(0)); if (share->connect_timeouts) @@ -1053,18 +1005,6 @@ void spider_free_tmp_share_alloc( spider_free(spider_current_trx, share->static_link_ids[0], MYF(0)); share->static_link_ids[0] = NULL; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (share->hs_read_socks && share->hs_read_socks[0]) - { - spider_free(spider_current_trx, share->hs_read_socks[0], MYF(0)); - share->hs_read_socks[0] = NULL; - } - if (share->hs_write_socks && share->hs_write_socks[0]) - { - spider_free(spider_current_trx, share->hs_write_socks[0], MYF(0)); - share->hs_write_socks[0] = NULL; - } -#endif if (share->bka_engine) { spider_free(spider_current_trx, share->bka_engine, MYF(0)); @@ -1175,7 +1115,8 @@ int spider_create_string_list( DBUG_ENTER("spider_create_string_list"); *list_length = 0; - param_string_parse->init_param_value(); + if (param_string_parse) + param_string_parse->init_param_value(); if (!str) { *string_list = NULL; @@ -1375,8 +1316,9 @@ int spider_create_string_list( } } - param_string_parse->set_param_value(tmp_ptr3, - tmp_ptr3 + strlen(tmp_ptr3) + 1); + if (param_string_parse) + param_string_parse->set_param_value(tmp_ptr3, + tmp_ptr3 + strlen(tmp_ptr3) + 1); DBUG_PRINT("info",("spider string_list[%d]=%s", roop_count, (*string_list)[roop_count])); @@ -1833,10 +1775,17 @@ int st_spider_param_string_parse::print_param_error() } #define SPIDER_PARAM_STR_LENS(name) name ## _lengths #define SPIDER_PARAM_STR_CHARLEN(name) name ## _charlen -#define SPIDER_PARAM_STR_LIST(title_name, param_name) \ +#define SPIDER_PARAM_STR_LIST(title_name, param_name) \ + SPIDER_PARAM_STR_LIST_CHECK(title_name, param_name, FALSE) +#define SPIDER_PARAM_STR_LIST_CHECK(title_name, param_name, already_set) \ if (!strncasecmp(tmp_ptr, title_name, title_length)) \ { \ DBUG_PRINT("info", ("spider " title_name " start")); \ + if (already_set) \ + { \ + error_num= ER_SPIDER_INVALID_CONNECT_INFO_NUM; \ + goto error; \ + } \ if (!share->param_name) \ { \ if ((tmp_ptr2= spider_get_string_between_quote(start_ptr, FALSE))) \ @@ -2082,6 +2031,31 @@ int st_spider_param_string_parse::print_param_error() title_name); \ } +/* + Set a given engine-defined option, which holds a string list, to the + corresponding attribute of SPIDER_SHARE. +*/ +#define SPIDER_OPTION_STR_LIST(title_name, option_name, param_name) \ + if (option_struct && option_struct->option_name) \ + { \ + DBUG_PRINT("info", ("spider " title_name " start overwrite")); \ + share->SPIDER_PARAM_STR_CHARLEN(param_name)= \ + strlen(option_struct->option_name); \ + if ((error_num= spider_create_string_list( \ + &share->param_name, &share->SPIDER_PARAM_STR_LENS(param_name), \ + &share->SPIDER_PARAM_STR_LEN(param_name), \ + option_struct->option_name, \ + share->SPIDER_PARAM_STR_CHARLEN(param_name), NULL))) \ + goto error; \ + } + +/* + Parse connection information specified by COMMENT, CONNECT, or engine-defined + options. + + TODO: Deprecate the connection specification by COMMENT and CONNECT, + and then solely utilize engine-defined options. +*/ int spider_parse_connect_info( SPIDER_SHARE *share, TABLE_SHARE *table_share, @@ -2098,6 +2072,7 @@ int spider_parse_connect_info( int title_length; SPIDER_PARAM_STRING_PARSE connect_string_parse; SPIDER_ALTER_TABLE *share_alter; + ha_table_option_struct *option_struct; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_element *part_elem; partition_element *sub_elem; @@ -2120,7 +2095,14 @@ int spider_parse_connect_info( #ifdef WITH_PARTITION_STORAGE_ENGINE spider_get_partition_info(share->table_name, share->table_name_length, table_share, part_info, &part_elem, &sub_elem); + if (part_info) + if (part_info->is_sub_partitioned()) + option_struct= sub_elem->option_struct; + else + option_struct= part_elem->option_struct; + else #endif + option_struct= table_share->option_struct; #ifndef WITHOUT_SPIDER_BG_SEARCH share->sts_bg_mode = -1; #endif @@ -2191,9 +2173,6 @@ int spider_parse_connect_info( share->error_read_mode = -1; share->error_write_mode = -1; share->active_link_count = -1; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - share->hs_result_free_size = -1; -#endif #ifdef HA_CAN_BULK_ACCESS share->bulk_access_free = -1; #endif @@ -2377,17 +2356,6 @@ int spider_parse_connect_info( #endif SPIDER_PARAM_STR_LIST("fds", tgt_filedsns); SPIDER_PARAM_LONGLONG("frd", first_read, 0); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_LONGLONG("hrf", hs_result_free_size, 0); - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "hrp", hs_read_ports, 0, 65535); - SPIDER_PARAM_STR_LIST("hrs", hs_read_socks); - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "hwp", hs_write_ports, 0, 65535); - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "hwr", hs_write_to_reads, 0, 1); - SPIDER_PARAM_STR_LIST("hws", hs_write_socks); -#endif SPIDER_PARAM_DEPRECATED_WARNING("isa"); SPIDER_PARAM_INT("isa", init_sql_alloc_size, 0); SPIDER_PARAM_DEPRECATED_WARNING("ilm"); @@ -2453,7 +2421,9 @@ int spider_parse_connect_info( SPIDER_PARAM_STR_LIST("sqn", tgt_sequence_names); SPIDER_PARAM_LONGLONG("srd", second_read, 0); SPIDER_PARAM_DOUBLE("srt", scan_rate, 0); - SPIDER_PARAM_STR_LIST("srv", server_names); + SPIDER_PARAM_STR_LIST_CHECK("srv", server_names, + option_struct && + option_struct->remote_server); SPIDER_PARAM_DOUBLE("ssr", semi_split_read, 0); SPIDER_PARAM_LONGLONG("ssl", semi_split_read_limit, 0); #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -2465,16 +2435,12 @@ int spider_parse_connect_info( SPIDER_PARAM_INT_WITH_MAX("stl", semi_table_lock, 0, 1); SPIDER_PARAM_LONGLONG("srs", static_records_for_status, 0); SPIDER_PARAM_LONG_LIST_WITH_MAX("svc", tgt_ssl_vscs, 0, 1); - SPIDER_PARAM_STR_LIST("tbl", tgt_table_names); + SPIDER_PARAM_STR_LIST_CHECK("tbl", tgt_table_names, + option_struct && + option_struct->remote_table); SPIDER_PARAM_INT_WITH_MAX("tcm", table_count_mode, 0, 3); SPIDER_PARAM_DEPRECATED_WARNING("uhd"); SPIDER_PARAM_LONG_LIST_WITH_MAX("uhd", use_handlers, 0, 3); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "uhr", use_hs_reads, 0, 1); - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "uhw", use_hs_writes, 0, 1); -#endif SPIDER_PARAM_INT_WITH_MAX("upu", use_pushdown_udf, 0, 1); SPIDER_PARAM_INT_WITH_MAX("utc", use_table_charset, 0, 1); error_num = connect_string_parse.print_param_error(); @@ -2486,12 +2452,16 @@ int spider_parse_connect_info( error_num = connect_string_parse.print_param_error(); goto error; case 5: - SPIDER_PARAM_STR_LIST("table", tgt_table_names); + SPIDER_PARAM_STR_LIST_CHECK("table", tgt_table_names, + option_struct && + option_struct->remote_table); error_num = connect_string_parse.print_param_error(); goto error; case 6: SPIDER_PARAM_STR_LIST("driver", tgt_drivers); - SPIDER_PARAM_STR_LIST("server", server_names); + SPIDER_PARAM_STR_LIST_CHECK("server", server_names, + option_struct && + option_struct->remote_server); SPIDER_PARAM_STR_LIST("socket", tgt_sockets); SPIDER_PARAM_HINT("idx", key_hint, 3, (int) table_share->keys, spider_db_append_key_hint); @@ -2508,7 +2478,9 @@ int spider_parse_connect_info( error_num = connect_string_parse.print_param_error(); goto error; case 8: - SPIDER_PARAM_STR_LIST("database", tgt_dbs); + SPIDER_PARAM_STR_LIST_CHECK("database", tgt_dbs, + option_struct && + option_struct->remote_database); SPIDER_PARAM_STR_LIST("password", tgt_passwords); SPIDER_PARAM_DEPRECATED_WARNING("sts_mode"); SPIDER_PARAM_INT_WITH_MAX("sts_mode", sts_mode, 1, 2); @@ -2557,9 +2529,6 @@ int spider_parse_connect_info( SPIDER_PARAM_LONG_LIST_WITH_MAX("link_status", link_statuses, 0, 3); SPIDER_PARAM_DEPRECATED_WARNING("use_handler"); SPIDER_PARAM_LONG_LIST_WITH_MAX("use_handler", use_handlers, 0, 3); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_LONG_LIST_WITH_MAX("use_hs_read", use_hs_reads, 0, 1); -#endif SPIDER_PARAM_INT_WITH_MAX("casual_read", casual_read, 0, 63); SPIDER_PARAM_DEPRECATED_WARNING("buffer_size"); SPIDER_PARAM_INT("buffer_size", buffer_size, 0); @@ -2570,20 +2539,10 @@ int spider_parse_connect_info( SPIDER_PARAM_DOUBLE("crd_interval", crd_interval, 0); SPIDER_PARAM_INT_WITH_MAX("low_mem_read", low_mem_read, 0, 1); SPIDER_PARAM_STR_LIST("default_file", tgt_default_files); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "use_hs_write", use_hs_writes, 0, 1); - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "hs_read_port", hs_read_ports, 0, 65535); -#endif error_num = connect_string_parse.print_param_error(); goto error; case 13: SPIDER_PARAM_STR_LIST("default_group", tgt_default_groups); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "hs_write_port", hs_write_ports, 0, 65535); -#endif SPIDER_PARAM_STR_LIST("sequence_name", tgt_sequence_names); error_num = connect_string_parse.print_param_error(); goto error; @@ -2593,10 +2552,6 @@ int spider_parse_connect_info( #ifndef WITHOUT_SPIDER_BG_SEARCH SPIDER_PARAM_LONGLONG("bgs_first_read", bgs_first_read, 0); #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_STR_LIST( - "hs_read_socket", hs_read_socks); -#endif SPIDER_PARAM_INT_WITH_MAX("read_only_mode", read_only_mode, 0, 1); SPIDER_PARAM_LONG_LIST_WITH_MAX("access_balance", access_balances, 0, 2147483647); @@ -2619,10 +2574,6 @@ int spider_parse_connect_info( SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_flag", monitoring_flag, 0, 1); SPIDER_PARAM_LONG_LIST_WITH_MAX("monitoring_kind", monitoring_kind, 0, 3); SPIDER_PARAM_DOUBLE("semi_split_read", semi_split_read, 0); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_STR_LIST( - "hs_write_socket", hs_write_socks); -#endif SPIDER_PARAM_LONG_LIST_WITH_MAX("connect_timeout", connect_timeouts, 0, 2147483647); SPIDER_PARAM_LONG_LIST_WITH_MAX("strict_group_by", @@ -2646,10 +2597,6 @@ int spider_parse_connect_info( SPIDER_PARAM_INT("bulk_update_size", bulk_update_size, 0); SPIDER_PARAM_LONG_LIST_WITH_MAX("net_read_timeout", net_read_timeouts, 0, 2147483647); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_LONG_LIST_WITH_MAX( - "hs_write_to_read", hs_write_to_reads, 0, 1); -#endif SPIDER_PARAM_INT_WITH_MAX( "error_write_mode", error_write_mode, 0, 1); #ifdef HA_CAN_BULK_ACCESS @@ -2698,9 +2645,6 @@ int spider_parse_connect_info( SPIDER_PARAM_INT("init_sql_alloc_size", init_sql_alloc_size, 0); SPIDER_PARAM_INT_WITH_MAX( "auto_increment_mode", auto_increment_mode, 0, 3); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - SPIDER_PARAM_LONGLONG("hs_result_free_size", hs_result_free_size, 0); -#endif SPIDER_PARAM_DEPRECATED_WARNING("bka_table_name_type"); SPIDER_PARAM_LONG_LIST_WITH_MAX("bka_table_name_type", bka_table_name_types, 0, 1); @@ -2771,6 +2715,10 @@ int spider_parse_connect_info( } } + SPIDER_OPTION_STR_LIST("server", remote_server, server_names); + SPIDER_OPTION_STR_LIST("database", remote_database, tgt_dbs); + SPIDER_OPTION_STR_LIST("table", remote_table, tgt_table_names); + /* check all_link_count */ share->all_link_count = 1; if (share->all_link_count < share->server_names_length) @@ -2839,22 +2787,6 @@ int spider_parse_connect_info( if (share->all_link_count < share->monitoring_bg_interval_length) share->all_link_count = share->monitoring_bg_interval_length; #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (share->all_link_count < share->use_hs_reads_length) - share->all_link_count = share->use_hs_reads_length; - if (share->all_link_count < share->use_hs_writes_length) - share->all_link_count = share->use_hs_writes_length; - if (share->all_link_count < share->hs_read_ports_length) - share->all_link_count = share->hs_read_ports_length; - if (share->all_link_count < share->hs_write_ports_length) - share->all_link_count = share->hs_write_ports_length; - if (share->all_link_count < share->hs_read_socks_length) - share->all_link_count = share->hs_read_socks_length; - if (share->all_link_count < share->hs_write_socks_length) - share->all_link_count = share->hs_write_socks_length; - if (share->all_link_count < share->hs_write_to_reads_length) - share->all_link_count = share->hs_write_to_reads_length; -#endif if (share->all_link_count < share->use_handlers_length) share->all_link_count = share->use_handlers_length; if (share->all_link_count < share->connect_timeouts_length) @@ -3075,47 +3007,6 @@ int spider_parse_connect_info( &share->monitoring_sid_length, share->all_link_count))) goto error; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((error_num = spider_increase_long_list( - &share->use_hs_reads, - &share->use_hs_reads_length, - share->all_link_count))) - goto error; - if ((error_num = spider_increase_long_list( - &share->use_hs_writes, - &share->use_hs_writes_length, - share->all_link_count))) - goto error; - if ((error_num = spider_increase_long_list( - &share->hs_read_ports, - &share->hs_read_ports_length, - share->all_link_count))) - goto error; - if ((error_num = spider_increase_long_list( - &share->hs_write_ports, - &share->hs_write_ports_length, - share->all_link_count))) - goto error; - if ((error_num = spider_increase_string_list( - &share->hs_read_socks, - &share->hs_read_socks_lengths, - &share->hs_read_socks_length, - &share->hs_read_socks_charlen, - share->all_link_count))) - goto error; - if ((error_num = spider_increase_string_list( - &share->hs_write_socks, - &share->hs_write_socks_lengths, - &share->hs_write_socks_length, - &share->hs_write_socks_charlen, - share->all_link_count))) - goto error; - if ((error_num = spider_increase_long_list( - &share->hs_write_to_reads, - &share->hs_write_to_reads_length, - share->all_link_count))) - goto error; -#endif if ((error_num = spider_increase_long_list( &share->use_handlers, &share->use_handlers_length, @@ -4063,42 +3954,6 @@ int spider_set_connect_info_default( share->monitoring_sid[roop_count] = current_thd->server_id; #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (share->use_hs_reads[roop_count] == -1) - share->use_hs_reads[roop_count] = 0; - if (share->use_hs_writes[roop_count] == -1) - share->use_hs_writes[roop_count] = 0; - if (share->hs_read_ports[roop_count] == -1) - { - share->hs_read_ports[roop_count] = 9998; - } else if (share->hs_read_ports[roop_count] < 0) - { - share->hs_read_ports[roop_count] = 0; - } else if (share->hs_read_ports[roop_count] > 65535) - { - share->hs_read_ports[roop_count] = 65535; - } - if (share->hs_write_ports[roop_count] == -1) - { - share->hs_write_ports[roop_count] = 9999; - } else if (share->hs_write_ports[roop_count] < 0) - { - share->hs_write_ports[roop_count] = 0; - } else if (share->hs_write_ports[roop_count] > 65535) - { - share->hs_write_ports[roop_count] = 65535; - } - if (share->hs_write_to_reads[roop_count] == -1) - { - share->hs_write_to_reads[roop_count] = 1; - } else if (share->hs_write_to_reads[roop_count] < 0) - { - share->hs_write_to_reads[roop_count] = 0; - } else if (share->hs_write_to_reads[roop_count] > 1) - { - share->hs_write_to_reads[roop_count] = 1; - } -#endif if (share->use_handlers[roop_count] == -1) share->use_handlers[roop_count] = 0; if (share->connect_timeouts[roop_count] == -1) @@ -4243,10 +4098,6 @@ int spider_set_connect_info_default( share->error_write_mode = 0; if (share->active_link_count == -1) share->active_link_count = share->all_link_count; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (share->hs_result_free_size == -1) - share->hs_result_free_size = 1048576; -#endif #ifdef HA_CAN_BULK_ACCESS if (share->bulk_access_free == -1) share->bulk_access_free = 0; @@ -4421,23 +4272,12 @@ int spider_create_conn_keys( ) { int roop_count, roop_count2; char *tmp_name, port_str[6]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char *tmp_hs_r_name, *tmp_hs_w_name; -#endif uint length_base = sizeof(uint) * share->all_link_count; uint *conn_keys_lengths; uint *sql_dbton_ids; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - uint *hs_dbton_ids; - uint *hs_r_conn_keys_lengths; - uint *hs_w_conn_keys_lengths; -#endif DBUG_ENTER("spider_create_conn_keys"); char *ptr; uint length = length_base * 2; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - length += length_base * 3; -#endif ptr = (char *) my_alloca(length); if (!ptr) { @@ -4446,26 +4286,11 @@ int spider_create_conn_keys( conn_keys_lengths = (uint *) ptr; ptr += length_base; sql_dbton_ids = (uint *) ptr; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ptr += length_base; - hs_dbton_ids = (uint *) ptr; - ptr += length_base; - hs_r_conn_keys_lengths = (uint *) ptr; - ptr += length_base; - hs_w_conn_keys_lengths = (uint *) ptr; -#endif share->conn_keys_charlen = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - share->hs_read_conn_keys_charlen = 0; - share->hs_write_conn_keys_charlen = 0; -#endif for (roop_count = 0; roop_count < (int) share->all_link_count; roop_count++) { bool get_sql_id = FALSE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - bool get_nosql_id = FALSE; -#endif for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++) { DBUG_PRINT("info",("spider share->tgt_wrappers[%d]=%s", roop_count, @@ -4485,35 +4310,12 @@ int spider_create_conn_keys( ) { sql_dbton_ids[roop_count] = roop_count2; get_sql_id = TRUE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (get_nosql_id) -#endif - break; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - else - continue; -#endif - } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - !get_nosql_id && - spider_dbton[roop_count2].db_access_type == - SPIDER_DB_ACCESS_TYPE_NOSQL - ) { - hs_dbton_ids[roop_count] = roop_count2; - get_nosql_id = TRUE; - if (get_sql_id) break; } -#endif } } if (!get_sql_id) sql_dbton_ids[roop_count] = SPIDER_DBTON_SIZE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!get_nosql_id) - hs_dbton_ids[roop_count] = SPIDER_DBTON_SIZE; -#endif bool tables_on_different_db_are_joinable; if (get_sql_id) @@ -4546,24 +4348,6 @@ int spider_create_conn_keys( + share->tgt_filedsns_lengths[roop_count] + 1 + share->tgt_drivers_lengths[roop_count]; share->conn_keys_charlen += conn_keys_lengths[roop_count] + 2; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - hs_r_conn_keys_lengths[roop_count] - = 1 - + share->tgt_wrappers_lengths[roop_count] + 1 - + share->tgt_hosts_lengths[roop_count] + 1 - + 5 + 1 - + share->hs_read_socks_lengths[roop_count]; - share->hs_read_conn_keys_charlen += - hs_r_conn_keys_lengths[roop_count] + 2; - hs_w_conn_keys_lengths[roop_count] - = 1 - + share->tgt_wrappers_lengths[roop_count] + 1 - + share->tgt_hosts_lengths[roop_count] + 1 - + 5 + 1 - + share->hs_write_socks_lengths[roop_count]; - share->hs_write_conn_keys_charlen += - hs_w_conn_keys_lengths[roop_count] + 2; -#endif } if (!(share->conn_keys = (char **) spider_bulk_alloc_mem(spider_current_trx, 45, @@ -4575,26 +4359,7 @@ int spider_create_conn_keys( sizeof(my_hash_value_type) * share->all_link_count, #endif &tmp_name, sizeof(char) * share->conn_keys_charlen, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &share->hs_read_conn_keys, sizeof(char *) * share->all_link_count, - &share->hs_read_conn_keys_lengths, length_base, -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - &share->hs_read_conn_keys_hash_value, - sizeof(my_hash_value_type) * share->all_link_count, -#endif - &tmp_hs_r_name, sizeof(char) * share->hs_read_conn_keys_charlen, - &share->hs_write_conn_keys, sizeof(char *) * share->all_link_count, - &share->hs_write_conn_keys_lengths, length_base, -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - &share->hs_write_conn_keys_hash_value, - sizeof(my_hash_value_type) * share->all_link_count, -#endif - &tmp_hs_w_name, sizeof(char) * share->hs_write_conn_keys_charlen, -#endif &share->sql_dbton_ids, length_base, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &share->hs_dbton_ids, length_base, -#endif NullS)) ) { my_afree(conn_keys_lengths); @@ -4604,15 +4369,6 @@ int spider_create_conn_keys( memcpy(share->conn_keys_lengths, conn_keys_lengths, length_base); memcpy(share->sql_dbton_ids, sql_dbton_ids, length_base); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - share->hs_read_conn_keys_length = share->all_link_count; - share->hs_write_conn_keys_length = share->all_link_count; - memcpy(share->hs_read_conn_keys_lengths, hs_r_conn_keys_lengths, - length_base); - memcpy(share->hs_write_conn_keys_lengths, hs_w_conn_keys_lengths, - length_base); - memcpy(share->hs_dbton_ids, hs_dbton_ids, length_base); -#endif my_afree(conn_keys_lengths); @@ -4754,82 +4510,14 @@ int spider_create_conn_keys( &spider_open_connections, (uchar*) share->conn_keys[roop_count], share->conn_keys_lengths[roop_count]); #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - share->hs_read_conn_keys[roop_count] = tmp_hs_r_name; - *tmp_hs_r_name = '0'; - DBUG_PRINT("info",("spider tgt_wrappers[%d]=%s", roop_count, - share->tgt_wrappers[roop_count])); - tmp_hs_r_name = strmov(tmp_hs_r_name + 1, share->tgt_wrappers[roop_count]); - DBUG_PRINT("info",("spider tgt_hosts[%d]=%s", roop_count, - share->tgt_hosts[roop_count])); - tmp_hs_r_name = strmov(tmp_hs_r_name + 1, share->tgt_hosts[roop_count]); - my_sprintf(port_str, (port_str, "%05ld", - share->hs_read_ports[roop_count])); - DBUG_PRINT("info",("spider port_str=%s", port_str)); - tmp_hs_r_name = strmov(tmp_hs_r_name + 1, port_str); - if (share->hs_read_socks[roop_count]) - { - DBUG_PRINT("info",("spider hs_read_socks[%d]=%s", roop_count, - share->hs_read_socks[roop_count])); - tmp_hs_r_name = strmov(tmp_hs_r_name + 1, - share->hs_read_socks[roop_count]); - } else - tmp_hs_r_name++; - tmp_hs_r_name++; - tmp_hs_r_name++; -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - share->hs_read_conn_keys_hash_value[roop_count] = my_calc_hash( - &spider_open_connections, (uchar*) share->hs_read_conn_keys[roop_count], - share->hs_read_conn_keys_lengths[roop_count]); -#endif - share->hs_write_conn_keys[roop_count] = tmp_hs_w_name; - *tmp_hs_w_name = '0'; - DBUG_PRINT("info",("spider tgt_wrappers[%d]=%s", roop_count, - share->tgt_wrappers[roop_count])); - tmp_hs_w_name = strmov(tmp_hs_w_name + 1, share->tgt_wrappers[roop_count]); - DBUG_PRINT("info",("spider tgt_hosts[%d]=%s", roop_count, - share->tgt_hosts[roop_count])); - tmp_hs_w_name = strmov(tmp_hs_w_name + 1, share->tgt_hosts[roop_count]); - my_sprintf(port_str, (port_str, "%05ld", - share->hs_write_ports[roop_count])); - DBUG_PRINT("info",("spider port_str=%s", port_str)); - tmp_hs_w_name = strmov(tmp_hs_w_name + 1, port_str); - if (share->hs_write_socks[roop_count]) - { - DBUG_PRINT("info",("spider hs_write_socks[%d]=%s", roop_count, - share->hs_write_socks[roop_count])); - tmp_hs_w_name = strmov(tmp_hs_w_name + 1, - share->hs_write_socks[roop_count]); - } else - tmp_hs_w_name++; - tmp_hs_w_name++; - tmp_hs_w_name++; -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - share->hs_write_conn_keys_hash_value[roop_count] = my_calc_hash( - &spider_open_connections, (uchar*) share->hs_write_conn_keys[roop_count], - share->hs_write_conn_keys_lengths[roop_count]); -#endif -#endif } for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++) { if (spider_bit_is_set(share->dbton_bitmap, roop_count2)) { -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (spider_dbton[roop_count2].db_access_type == - SPIDER_DB_ACCESS_TYPE_SQL) - { -#endif share->use_sql_dbton_ids[share->use_dbton_count] = roop_count2; share->sql_dbton_id_to_seq[roop_count2] = share->use_dbton_count; share->use_sql_dbton_count++; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - share->use_hs_dbton_ids[share->use_hs_dbton_count] = roop_count2; - share->hs_dbton_id_to_seq[roop_count2] = share->use_hs_dbton_count; - share->use_hs_dbton_count++; - } -#endif share->use_dbton_ids[share->use_dbton_count] = roop_count2; share->dbton_id_to_seq[roop_count2] = share->use_dbton_count; share->use_dbton_count++; @@ -4886,9 +4574,6 @@ SPIDER_SHARE *spider_create_share( SPD_INIT_ALLOC_ROOT(&share->mem_root, 4096, 0, MYF(MY_WME)); share->use_count = 0; share->use_dbton_count = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - share->use_hs_dbton_count = 0; -#endif share->table_name_length = length; share->table_name = tmp_name; strmov(share->table_name, table_name); @@ -5081,12 +4766,6 @@ SPIDER_SHARE *spider_get_share( SPIDER_RESULT_LIST *result_list = &spider->result_list; uint length, tmp_conn_link_idx = 0, buf_sz; char *tmp_name, *tmp_cid; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char *tmp_hs_r_name, *tmp_hs_w_name; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - uint32 *tmp_hs_r_ret_fields, *tmp_hs_w_ret_fields; -#endif -#endif int roop_count; double sts_interval; int sts_mode; @@ -5411,16 +5090,6 @@ SPIDER_SHARE *spider_get_share( &spider->conns, sizeof(SPIDER_CONN *) * share->link_count, &spider->conn_link_idx, sizeof(uint) * share->link_count, &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &spider->hs_r_conn_keys, sizeof(char *) * share->link_count, - &tmp_hs_r_name, sizeof(char) * share->hs_read_conn_keys_charlen, - &spider->hs_r_conns, sizeof(SPIDER_CONN *) * share->link_count, - &spider->hs_r_conn_ages, sizeof(ulonglong) * share->link_count, - &spider->hs_w_conn_keys, sizeof(char *) * share->link_count, - &tmp_hs_w_name, sizeof(char) * share->hs_write_conn_keys_charlen, - &spider->hs_w_conns, sizeof(SPIDER_CONN *) * share->link_count, - &spider->hs_w_conn_ages, sizeof(ulonglong) * share->link_count, -#endif &spider->sql_kind, sizeof(uint) * share->link_count, &spider->connection_ids, sizeof(ulonglong) * share->link_count, &spider->conn_kind, sizeof(uint) * share->link_count, @@ -5429,26 +5098,6 @@ SPIDER_SHARE *spider_get_share( &spider->m_handler_opened, sizeof(uchar) * share->link_bitmap_size, &spider->m_handler_id, sizeof(uint) * share->link_count, &spider->m_handler_cid, sizeof(char *) * share->link_count, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &spider->r_handler_opened, sizeof(uchar) * share->link_bitmap_size, - &spider->r_handler_id, sizeof(uint) * share->link_count, - &spider->r_handler_index, sizeof(uint) * share->link_count, - &spider->w_handler_opened, sizeof(uchar) * share->link_bitmap_size, - &spider->w_handler_id, sizeof(uint) * share->link_count, - &spider->w_handler_index, sizeof(uint) * share->link_count, -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - &spider->do_hs_direct_update, sizeof(uchar) * share->link_bitmap_size, - &spider->hs_r_ret_fields, sizeof(uint32 *) * share->link_count, - &spider->hs_w_ret_fields, sizeof(uint32 *) * share->link_count, - &spider->hs_r_ret_fields_num, sizeof(size_t) * share->link_count, - &spider->hs_w_ret_fields_num, sizeof(size_t) * share->link_count, - &tmp_hs_r_ret_fields, - sizeof(uint32) * share->link_count * table_share->fields, - &tmp_hs_w_ret_fields, - sizeof(uint32) * share->link_count * table_share->fields, - &spider->tmp_column_bitmap, sizeof(uchar) * share->bitmap_size, -#endif -#endif &tmp_cid, sizeof(char) * (SPIDER_SQL_HANDLER_CID_LEN + 1) * share->link_count, &spider->need_mons, sizeof(int) * share->link_count, @@ -5460,14 +5109,6 @@ SPIDER_SHARE *spider_get_share( sizeof(uchar) * share->link_bitmap_size, &result_list->tmp_table_created, sizeof(uchar) * share->link_bitmap_size, -#ifdef HA_CAN_BULK_ACCESS -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &result_list->hs_r_bulk_open_index, - sizeof(uchar) * share->link_bitmap_size, - &result_list->hs_w_bulk_open_index, - sizeof(uchar) * share->link_bitmap_size, -#endif -#endif &result_list->sql_kind_backup, sizeof(uint) * share->link_count, &result_list->casual_read, sizeof(int) * share->link_count, &spider->dbton_handler, @@ -5481,12 +5122,6 @@ SPIDER_SHARE *spider_get_share( goto error_but_no_delete; } memcpy(tmp_name, share->conn_keys[0], share->conn_keys_charlen); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - memcpy(tmp_hs_r_name, share->hs_read_conn_keys[0], - share->hs_read_conn_keys_charlen); - memcpy(tmp_hs_w_name, share->hs_write_conn_keys[0], - share->hs_write_conn_keys_charlen); -#endif spider->conn_keys_first_ptr = tmp_name; for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) @@ -5494,18 +5129,6 @@ SPIDER_SHARE *spider_get_share( spider->conn_keys[roop_count] = tmp_name; *tmp_name = first_byte; tmp_name += share->conn_keys_lengths[roop_count] + 1; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider->hs_r_conn_keys[roop_count] = tmp_hs_r_name; - tmp_hs_r_name += share->hs_read_conn_keys_lengths[roop_count] + 1; - spider->hs_w_conn_keys[roop_count] = tmp_hs_w_name; - tmp_hs_w_name += share->hs_write_conn_keys_lengths[roop_count] + 1; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - spider->hs_r_ret_fields[roop_count] = tmp_hs_r_ret_fields; - tmp_hs_r_ret_fields += table_share->fields; - spider->hs_w_ret_fields[roop_count] = tmp_hs_w_ret_fields; - tmp_hs_w_ret_fields += table_share->fields; -#endif -#endif spider->m_handler_cid[roop_count] = tmp_cid; tmp_cid += SPIDER_SQL_HANDLER_CID_LEN + 1; result_list->upd_tmp_tbl_prms[roop_count].init(); @@ -5953,16 +5576,6 @@ SPIDER_SHARE *spider_get_share( &spider->conns, sizeof(SPIDER_CONN *) * share->link_count, &spider->conn_link_idx, sizeof(uint) * share->link_count, &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &spider->hs_r_conn_keys, sizeof(char *) * share->link_count, - &tmp_hs_r_name, sizeof(char) * share->hs_read_conn_keys_charlen, - &spider->hs_r_conns, sizeof(SPIDER_CONN *) * share->link_count, - &spider->hs_r_conn_ages, sizeof(ulonglong) * share->link_count, - &spider->hs_w_conn_keys, sizeof(char *) * share->link_count, - &tmp_hs_w_name, sizeof(char) * share->hs_write_conn_keys_charlen, - &spider->hs_w_conns, sizeof(SPIDER_CONN *) * share->link_count, - &spider->hs_w_conn_ages, sizeof(ulonglong) * share->link_count, -#endif &spider->sql_kind, sizeof(uint) * share->link_count, &spider->connection_ids, sizeof(ulonglong) * share->link_count, &spider->conn_kind, sizeof(uint) * share->link_count, @@ -5971,26 +5584,6 @@ SPIDER_SHARE *spider_get_share( &spider->m_handler_opened, sizeof(uchar) * share->link_bitmap_size, &spider->m_handler_id, sizeof(uint) * share->link_count, &spider->m_handler_cid, sizeof(char *) * share->link_count, -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &spider->r_handler_opened, sizeof(uchar) * share->link_bitmap_size, - &spider->r_handler_id, sizeof(uint) * share->link_count, - &spider->r_handler_index, sizeof(uint) * share->link_count, - &spider->w_handler_opened, sizeof(uchar) * share->link_bitmap_size, - &spider->w_handler_id, sizeof(uint) * share->link_count, - &spider->w_handler_index, sizeof(uint) * share->link_count, -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - &spider->do_hs_direct_update, sizeof(uchar) * share->link_bitmap_size, - &spider->hs_r_ret_fields, sizeof(uint32 *) * share->link_count, - &spider->hs_w_ret_fields, sizeof(uint32 *) * share->link_count, - &spider->hs_r_ret_fields_num, sizeof(size_t) * share->link_count, - &spider->hs_w_ret_fields_num, sizeof(size_t) * share->link_count, - &tmp_hs_r_ret_fields, - sizeof(uint32) * share->link_count * table_share->fields, - &tmp_hs_w_ret_fields, - sizeof(uint32) * share->link_count * table_share->fields, - &spider->tmp_column_bitmap, sizeof(uchar) * share->bitmap_size, -#endif -#endif &tmp_cid, sizeof(char) * (SPIDER_SQL_HANDLER_CID_LEN + 1) * share->link_count, &spider->need_mons, sizeof(int) * share->link_count, @@ -6002,14 +5595,6 @@ SPIDER_SHARE *spider_get_share( sizeof(uchar) * share->link_bitmap_size, &result_list->tmp_table_created, sizeof(uchar) * share->link_bitmap_size, -#ifdef HA_CAN_BULK_ACCESS -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - &result_list->hs_r_bulk_open_index, - sizeof(uchar) * share->link_bitmap_size, - &result_list->hs_w_bulk_open_index, - sizeof(uchar) * share->link_bitmap_size, -#endif -#endif &result_list->sql_kind_backup, sizeof(uint) * share->link_count, &result_list->casual_read, sizeof(int) * share->link_count, &spider->dbton_handler, @@ -6020,12 +5605,6 @@ SPIDER_SHARE *spider_get_share( goto error_but_no_delete; } memcpy(tmp_name, share->conn_keys[0], share->conn_keys_charlen); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - memcpy(tmp_hs_r_name, share->hs_read_conn_keys[0], - share->hs_read_conn_keys_charlen); - memcpy(tmp_hs_w_name, share->hs_write_conn_keys[0], - share->hs_write_conn_keys_charlen); -#endif spider->conn_keys_first_ptr = tmp_name; for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) @@ -6033,18 +5612,6 @@ SPIDER_SHARE *spider_get_share( spider->conn_keys[roop_count] = tmp_name; *tmp_name = first_byte; tmp_name += share->conn_keys_lengths[roop_count] + 1; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider->hs_r_conn_keys[roop_count] = tmp_hs_r_name; - tmp_hs_r_name += share->hs_read_conn_keys_lengths[roop_count] + 1; - spider->hs_w_conn_keys[roop_count] = tmp_hs_w_name; - tmp_hs_w_name += share->hs_write_conn_keys_lengths[roop_count] + 1; -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - spider->hs_r_ret_fields[roop_count] = tmp_hs_r_ret_fields; - tmp_hs_r_ret_fields += table_share->fields; - spider->hs_w_ret_fields[roop_count] = tmp_hs_w_ret_fields; - tmp_hs_w_ret_fields += table_share->fields; -#endif -#endif spider->m_handler_cid[roop_count] = tmp_cid; tmp_cid += SPIDER_SQL_HANDLER_CID_LEN + 1; result_list->upd_tmp_tbl_prms[roop_count].init(); @@ -7231,32 +6798,6 @@ int spider_db_done( } pthread_mutex_unlock(&spider_allocated_thds_mutex); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - pthread_mutex_lock(&spider_hs_w_conn_mutex); - while ((conn = (SPIDER_CONN*) my_hash_element(&spider_hs_w_conn_hash, 0))) - { -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&spider_hs_w_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&spider_hs_w_conn_hash, (uchar*) conn); -#endif - spider_free_conn(conn); - } - pthread_mutex_unlock(&spider_hs_w_conn_mutex); - pthread_mutex_lock(&spider_hs_r_conn_mutex); - while ((conn = (SPIDER_CONN*) my_hash_element(&spider_hs_r_conn_hash, 0))) - { -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&spider_hs_r_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&spider_hs_r_conn_hash, (uchar*) conn); -#endif - spider_free_conn(conn); - } - pthread_mutex_unlock(&spider_hs_r_conn_mutex); -#endif pthread_mutex_lock(&spider_conn_mutex); while ((conn = (SPIDER_CONN*) my_hash_element(&spider_open_connections, 0))) { @@ -7286,18 +6827,6 @@ int spider_db_done( spider_allocated_thds.array.max_element * spider_allocated_thds.array.size_of_element); my_hash_free(&spider_allocated_thds); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider_free_mem_calc(spider_current_trx, - spider_hs_w_conn_hash_id, - spider_hs_w_conn_hash.array.max_element * - spider_hs_w_conn_hash.array.size_of_element); - my_hash_free(&spider_hs_w_conn_hash); - spider_free_mem_calc(spider_current_trx, - spider_hs_r_conn_hash_id, - spider_hs_r_conn_hash.array.max_element * - spider_hs_r_conn_hash.array.size_of_element); - my_hash_free(&spider_hs_r_conn_hash); -#endif spider_free_mem_calc(spider_current_trx, spider_open_connections_id, spider_open_connections.array.max_element * @@ -7345,10 +6874,6 @@ int spider_db_done( pthread_mutex_destroy(&spider_mon_table_cache_mutex); pthread_mutex_destroy(&spider_allocated_thds_mutex); pthread_mutex_destroy(&spider_open_conn_mutex); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - pthread_mutex_destroy(&spider_hs_w_conn_mutex); - pthread_mutex_destroy(&spider_hs_r_conn_mutex); -#endif pthread_mutex_destroy(&spider_conn_mutex); pthread_mutex_destroy(&spider_lgtm_tblhnd_share_mutex); #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -7443,6 +6968,7 @@ int spider_db_init( #ifdef SPIDER_HAS_GROUP_BY_HANDLER spider_hton->create_group_by = spider_create_group_by_handler; #endif + spider_hton->table_options= spider_table_option_list; if (my_gethwaddr((uchar *) addr)) { @@ -7572,24 +7098,6 @@ int spider_db_init( #endif goto error_open_conn_mutex_init; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#if MYSQL_VERSION_ID < 50500 - if (pthread_mutex_init(&spider_hs_r_conn_mutex, MY_MUTEX_INIT_FAST)) -#else - if (mysql_mutex_init(spd_key_mutex_hs_r_conn, - &spider_hs_r_conn_mutex, MY_MUTEX_INIT_FAST)) -#endif - goto error_hs_r_conn_mutex_init; - -#if MYSQL_VERSION_ID < 50500 - if (pthread_mutex_init(&spider_hs_w_conn_mutex, MY_MUTEX_INIT_FAST)) -#else - if (mysql_mutex_init(spd_key_mutex_hs_w_conn, - &spider_hs_w_conn_mutex, MY_MUTEX_INIT_FAST)) -#endif - goto error_hs_w_conn_mutex_init; - -#endif #if MYSQL_VERSION_ID < 50500 if (pthread_mutex_init(&spider_allocated_thds_mutex, MY_MUTEX_INIT_FAST)) #else @@ -7669,26 +7177,6 @@ int spider_db_init( spider_open_connections, spider_open_connections.array.max_element * spider_open_connections.array.size_of_element); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (my_hash_init(PSI_INSTRUMENT_ME, &spider_hs_r_conn_hash, spd_charset_utf8mb3_bin, 32, 0, 0, - (my_hash_get_key) spider_conn_get_key, 0, 0)) - goto error_hs_r_conn_hash_init; - - spider_alloc_calc_mem_init(spider_hs_r_conn_hash, 147); - spider_alloc_calc_mem(NULL, - spider_hs_r_conn_hash, - spider_hs_r_conn_hash.array.max_element * - spider_hs_r_conn_hash.array.size_of_element); - if (my_hash_init(PSI_INSTRUMENT_ME, &spider_hs_w_conn_hash, spd_charset_utf8mb3_bin, 32, 0, 0, - (my_hash_get_key) spider_conn_get_key, 0, 0)) - goto error_hs_w_conn_hash_init; - - spider_alloc_calc_mem_init(spider_hs_w_conn_hash, 148); - spider_alloc_calc_mem(NULL, - spider_hs_w_conn_hash, - spider_hs_w_conn_hash.array.max_element * - spider_hs_w_conn_hash.array.size_of_element); -#endif if (my_hash_init(PSI_INSTRUMENT_ME, &spider_allocated_thds, spd_charset_utf8mb3_bin, 32, 0, 0, (my_hash_get_key) spider_allocated_thds_get_key, 0, 0)) goto error_allocated_thds_hash_init; @@ -7802,12 +7290,6 @@ int spider_db_init( spider_dbton_mariadb.db_util->dbton_id = dbton_id; spider_dbton[dbton_id] = spider_dbton_mariadb; ++dbton_id; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider_dbton_handlersocket.dbton_id = dbton_id; - spider_dbton_handlersocket.db_util->dbton_id = dbton_id; - spider_dbton[dbton_id] = spider_dbton_handlersocket; - ++dbton_id; -#endif #ifdef HAVE_ORACLE_OCI spider_dbton_oracle.dbton_id = dbton_id; spider_dbton_oracle.db_util->dbton_id = dbton_id; @@ -7883,20 +7365,6 @@ error_mon_table_cache_array_init: error_allocated_thds_hash_init: my_hash_free(&spider_ipport_conns); error_ipport_conn__hash_init: -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider_free_mem_calc(NULL, - spider_hs_w_conn_hash_id, - spider_hs_w_conn_hash.array.max_element * - spider_hs_w_conn_hash.array.size_of_element); - my_hash_free(&spider_hs_w_conn_hash); -error_hs_w_conn_hash_init: - spider_free_mem_calc(NULL, - spider_hs_r_conn_hash_id, - spider_hs_r_conn_hash.array.max_element * - spider_hs_r_conn_hash.array.size_of_element); - my_hash_free(&spider_hs_r_conn_hash); -error_hs_r_conn_hash_init: -#endif spider_free_mem_calc(NULL, spider_open_connections_id, spider_open_connections.array.max_element * @@ -7935,12 +7403,6 @@ error_mem_calc_mutex_init: error_mon_table_cache_mutex_init: pthread_mutex_destroy(&spider_allocated_thds_mutex); error_allocated_thds_mutex_init: -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - pthread_mutex_destroy(&spider_hs_w_conn_mutex); -error_hs_w_conn_mutex_init: - pthread_mutex_destroy(&spider_hs_r_conn_mutex); -error_hs_r_conn_mutex_init: -#endif pthread_mutex_destroy(&spider_open_conn_mutex); error_open_conn_mutex_init: pthread_mutex_destroy(&spider_conn_mutex); @@ -8017,6 +7479,12 @@ char *spider_create_table_name_string( } #ifdef WITH_PARTITION_STORAGE_ENGINE +/* + Get the target partition_elements. + + The target partition and subpartition are detected by the table name, + which is in the form like "t1#P#pt1". +*/ void spider_get_partition_info( const char *table_name, uint table_name_length, @@ -8566,113 +8034,6 @@ bool spider_check_pk_update( DBUG_RETURN(FALSE); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -bool spider_check_hs_pk_update( - ha_spider *spider, - key_range *key -) { - uint roop_count, field_index, set_count = 0; - TABLE *table = spider->get_table(); - TABLE_SHARE *table_share = table->s; - SPIDER_SHARE *share = spider->share; - KEY *key_info; - KEY_PART_INFO *key_part; - char buf[MAX_FIELD_WIDTH], buf2[MAX_FIELD_WIDTH]; - spider_string tmp_str(buf, MAX_FIELD_WIDTH, &my_charset_bin), - tmp_str2(buf2, MAX_FIELD_WIDTH, &my_charset_bin); - String *str, *str2; - DBUG_ENTER("spider_check_hs_pk_update"); - tmp_str.init_calc_mem(137); - - if (table_share->primary_key == MAX_KEY) - DBUG_RETURN(FALSE); - memset(spider->tmp_column_bitmap, 0, sizeof(uchar) * share->bitmap_size); - key_info = &table->key_info[table_share->primary_key]; - key_part = key_info->key_part; - for (roop_count = 0; roop_count < spider_user_defined_key_parts(key_info); - roop_count++) - { - field_index = key_part[roop_count].field->field_index; - if (bitmap_is_set(table->write_set, field_index)) - { - DBUG_PRINT("info", ("spider set key_part=%u field_index=%u", - roop_count, field_index)); - spider_set_bit(spider->tmp_column_bitmap, field_index); - set_count++; - } - } - DBUG_PRINT("info", ("spider set_count=%u", set_count)); - - Field *field; - uint store_length, length, var_len; - const uchar *ptr; - bool key_eq; - key_part_map tgt_key_part_map = key->keypart_map; - key_info = &table->key_info[spider->active_index]; - for ( - key_part = key_info->key_part, - length = 0; - tgt_key_part_map; - length += store_length, - tgt_key_part_map >>= 1, - key_part++ - ) { - store_length = key_part->store_length; - field = key_part->field; - field_index = field->field_index; - if (spider_bit_is_set(spider->tmp_column_bitmap, field_index)) - { - ptr = key->key + length; - key_eq = (tgt_key_part_map > 1); - if (key_part->null_bit && *ptr++) - { - if (key->flag != HA_READ_KEY_EXACT || !field->is_null()) - { - DBUG_PRINT("info", ("spider flag=%u is_null=%s", - key->flag, field->is_null() ? "TRUE" : "FALSE")); - DBUG_RETURN(TRUE); - } - } else { - if ( - field->type() == MYSQL_TYPE_BLOB || - field->real_type() == MYSQL_TYPE_VARCHAR || - field->type() == MYSQL_TYPE_GEOMETRY - ) { - var_len = uint2korr(ptr); - tmp_str.set((char *) ptr + HA_KEY_BLOB_LENGTH, var_len, - &my_charset_bin); - str = tmp_str.get_str(); - } else { - str = field->val_str(tmp_str.get_str(), ptr); - tmp_str.mem_calc(); - } - str2 = field->val_str(tmp_str2.get_str()); - tmp_str2.mem_calc(); - if ( - str->length() != str2->length() || - memcmp(str->ptr(), str2->ptr(), str->length()) - ) { - DBUG_PRINT("info", ("spider length=%u %u", - str->length(), str2->length())); - DBUG_PRINT("info", ("spider length=%s %s", - str->c_ptr_safe(), str2->c_ptr_safe())); - DBUG_RETURN(TRUE); - } - } - set_count--; - } - } - DBUG_PRINT("info", ("spider set_count=%u", set_count)); - if (set_count) - { - DBUG_RETURN(TRUE); - } - DBUG_RETURN(FALSE); -} -#endif -#endif - void spider_set_tmp_share_pointer( SPIDER_SHARE *tmp_share, char **tmp_connect_info, @@ -8704,10 +8065,6 @@ void spider_set_tmp_share_pointer( tmp_share->tgt_pk_names = &tmp_connect_info[18]; tmp_share->tgt_sequence_names = &tmp_connect_info[19]; tmp_share->static_link_ids = &tmp_connect_info[20]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->hs_read_socks = &tmp_connect_info[21]; - tmp_share->hs_write_socks = &tmp_connect_info[22]; -#endif tmp_share->tgt_ports = &tmp_long[0]; tmp_share->tgt_ssl_vscs = &tmp_long[1]; tmp_share->link_statuses = &tmp_long[2]; @@ -8718,13 +8075,6 @@ void spider_set_tmp_share_pointer( tmp_share->monitoring_bg_flag = &tmp_long[6]; tmp_share->monitoring_bg_kind = &tmp_long[7]; #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->use_hs_reads = &tmp_long[8]; - tmp_share->use_hs_writes = &tmp_long[9]; - tmp_share->hs_read_ports = &tmp_long[10]; - tmp_share->hs_write_ports = &tmp_long[11]; - tmp_share->hs_write_to_reads = &tmp_long[12]; -#endif tmp_share->use_handlers = &tmp_long[13]; tmp_share->connect_timeouts = &tmp_long[14]; tmp_long[13] = -1; @@ -8761,10 +8111,6 @@ void spider_set_tmp_share_pointer( tmp_share->tgt_pk_names_lengths = &tmp_connect_info_length[18]; tmp_share->tgt_sequence_names_lengths = &tmp_connect_info_length[19]; tmp_share->static_link_ids_lengths = &tmp_connect_info_length[20]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->hs_read_socks_lengths = &tmp_connect_info_length[21]; - tmp_share->hs_write_socks_lengths = &tmp_connect_info_length[22]; -#endif tmp_share->server_names_length = 1; tmp_share->tgt_table_names_length = 1; tmp_share->tgt_dbs_length = 1; @@ -8801,15 +8147,6 @@ void spider_set_tmp_share_pointer( #ifndef WITHOUT_SPIDER_BG_SEARCH tmp_share->monitoring_bg_interval_length = 1; #endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->hs_read_socks_length = 1; - tmp_share->hs_write_socks_length = 1; - tmp_share->use_hs_reads_length = 1; - tmp_share->use_hs_writes_length = 1; - tmp_share->hs_read_ports_length = 1; - tmp_share->hs_write_ports_length = 1; - tmp_share->hs_write_to_reads_length = 1; -#endif tmp_share->use_handlers_length = 1; tmp_share->connect_timeouts_length = 1; tmp_share->net_read_timeouts_length = 1; @@ -8832,9 +8169,6 @@ void spider_set_tmp_share_pointer( tmp_share->monitoring_sid[0] = -1; tmp_share->bka_engine = NULL; tmp_share->use_dbton_count = 0; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - tmp_share->use_hs_dbton_count = 0; -#endif DBUG_VOID_RETURN; } @@ -9017,26 +8351,17 @@ longlong spider_split_read_param( #ifdef SPIDER_HAS_GROUP_BY_HANDLER bool inserting = ( -#ifdef HS_HAS_SQLCOM - spider->wide_handler->sql_command == SQLCOM_HS_INSERT || -#endif spider->wide_handler->sql_command == SQLCOM_INSERT || spider->wide_handler->sql_command == SQLCOM_INSERT_SELECT ); #endif bool updating = ( -#ifdef HS_HAS_SQLCOM - spider->wide_handler->sql_command == SQLCOM_HS_UPDATE || -#endif spider->wide_handler->sql_command == SQLCOM_UPDATE || spider->wide_handler->sql_command == SQLCOM_UPDATE_MULTI ); bool deleting = ( -#ifdef HS_HAS_SQLCOM - spider->wide_handler->sql_command == SQLCOM_HS_DELETE || -#endif spider->wide_handler->sql_command == SQLCOM_DELETE || spider->wide_handler->sql_command == SQLCOM_DELETE_MULTI ); @@ -10125,10 +9450,6 @@ int spider_create_spider_object_for_share( uint *conn_link_idx; uchar *conn_can_fo; char **conn_keys; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - char **hs_r_conn_keys; - char **hs_w_conn_keys; -#endif spider_db_handler **dbton_hdl; SPIDER_WIDE_HANDLER *wide_handler; DBUG_ENTER("spider_create_spider_object_for_share"); @@ -10149,21 +9470,6 @@ int spider_create_spider_object_for_share( goto error_spider_alloc; } DBUG_PRINT("info",("spider spider=%p", (*spider))); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!(need_mons = (int *) - spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL), - &need_mons, (uint) (sizeof(int) * share->link_count), - &conns, (uint) (sizeof(SPIDER_CONN *) * share->link_count), - &conn_link_idx, (uint) (sizeof(uint) * share->link_count), - &conn_can_fo, (uint) (sizeof(uchar) * share->link_bitmap_size), - &conn_keys, (uint) (sizeof(char *) * share->link_count), - &hs_r_conn_keys, (uint) (sizeof(char *) * share->link_count), - &hs_w_conn_keys, (uint) (sizeof(char *) * share->link_count), - &dbton_hdl, (uint) (sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE), - &wide_handler, (uint) sizeof(SPIDER_WIDE_HANDLER), - NullS)) - ) -#else if (!(need_mons = (int *) spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL), &need_mons, (uint) (sizeof(int) * share->link_count), @@ -10175,7 +9481,6 @@ int spider_create_spider_object_for_share( &wide_handler, (uint) sizeof(SPIDER_WIDE_HANDLER), NullS)) ) -#endif { error_num = HA_ERR_OUT_OF_MEM; goto error_need_mons_alloc; @@ -10191,10 +9496,6 @@ int spider_create_spider_object_for_share( (*spider)->need_mons = need_mons; (*spider)->conn_keys_first_ptr = share->conn_keys[0]; (*spider)->conn_keys = conn_keys; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (*spider)->hs_r_conn_keys = hs_r_conn_keys; - (*spider)->hs_w_conn_keys = hs_w_conn_keys; -#endif (*spider)->dbton_handler = dbton_hdl; (*spider)->search_link_idx = -1; for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++) diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h index dc351e73c61..39d1e0fdbe7 100644 --- a/storage/spider/spd_table.h +++ b/storage/spider/spd_table.h @@ -641,15 +641,6 @@ bool spider_check_pk_update( TABLE *table ); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -bool spider_check_hs_pk_update( - ha_spider *spider, - key_range *key -); -#endif -#endif - void spider_set_tmp_share_pointer( SPIDER_SHARE *tmp_share, char **tmp_connect_info, diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index 0023a5d4bbc..3cdb1f844be 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -1168,30 +1168,6 @@ int spider_free_trx_alloc( trx->trx_another_conn_hash.array.max_element * trx->trx_another_conn_hash.array.size_of_element); my_hash_free(&trx->trx_another_conn_hash); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider_free_mem_calc(spider_current_trx, - trx->trx_direct_hs_r_conn_hash_id, - trx->trx_direct_hs_r_conn_hash.array.max_element * - trx->trx_direct_hs_r_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_direct_hs_r_conn_hash); - spider_free_mem_calc(spider_current_trx, - trx->trx_direct_hs_w_conn_hash_id, - trx->trx_direct_hs_w_conn_hash.array.max_element * - trx->trx_direct_hs_w_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_direct_hs_w_conn_hash); -#endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider_free_mem_calc(spider_current_trx, - trx->trx_hs_r_conn_hash_id, - trx->trx_hs_r_conn_hash.array.max_element * - trx->trx_hs_r_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_hs_r_conn_hash); - spider_free_mem_calc(spider_current_trx, - trx->trx_hs_w_conn_hash_id, - trx->trx_hs_w_conn_hash.array.max_element * - trx->trx_hs_w_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_hs_w_conn_hash); -#endif spider_free_mem_calc(spider_current_trx, trx->trx_ha_hash_id, trx->trx_ha_hash.array.max_element * @@ -1278,58 +1254,6 @@ SPIDER_TRX *spider_get_trx( trx->trx_another_conn_hash.array.max_element * trx->trx_another_conn_hash.array.size_of_element); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - my_hash_init(&trx->trx_hs_r_conn_hash, spd_charset_utf8mb3_bin, 32, 0, 0, - (my_hash_get_key) spider_conn_get_key, 0, 0) - ) - goto error_hs_r_init_hash; - spider_alloc_calc_mem_init(trx->trx_hs_r_conn_hash, 153); - spider_alloc_calc_mem( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_hs_r_conn_hash, - trx->trx_hs_r_conn_hash.array.max_element * - trx->trx_hs_r_conn_hash.array.size_of_element); - - if ( - my_hash_init(&trx->trx_hs_w_conn_hash, spd_charset_utf8mb3_bin, 32, 0, 0, - (my_hash_get_key) spider_conn_get_key, 0, 0) - ) - goto error_hs_w_init_hash; - spider_alloc_calc_mem_init(trx->trx_hs_w_conn_hash, 154); - spider_alloc_calc_mem( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_hs_w_conn_hash, - trx->trx_hs_w_conn_hash.array.max_element * - trx->trx_hs_w_conn_hash.array.size_of_element); -#endif - -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - my_hash_init(&trx->trx_direct_hs_r_conn_hash, spd_charset_utf8mb3_bin, 32, - 0, 0, (my_hash_get_key) spider_conn_get_key, 0, 0) - ) - goto error_direct_hs_r_init_hash; - spider_alloc_calc_mem_init(trx->trx_direct_hs_r_conn_hash, 155); - spider_alloc_calc_mem( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_direct_hs_r_conn_hash, - trx->trx_direct_hs_r_conn_hash.array.max_element * - trx->trx_direct_hs_r_conn_hash.array.size_of_element); - - if ( - my_hash_init(&trx->trx_direct_hs_w_conn_hash, spd_charset_utf8mb3_bin, 32, - 0, 0, (my_hash_get_key) spider_conn_get_key, 0, 0) - ) - goto error_direct_hs_w_init_hash; - spider_alloc_calc_mem_init(trx->trx_direct_hs_w_conn_hash, 156); - spider_alloc_calc_mem( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_direct_hs_w_conn_hash, - trx->trx_direct_hs_w_conn_hash.array.max_element * - trx->trx_direct_hs_w_conn_hash.array.size_of_element); -#endif - if ( my_hash_init(PSI_INSTRUMENT_ME, &trx->trx_alter_table_hash, spd_charset_utf8mb3_bin, 32, 0, 0, (my_hash_get_key) @@ -1369,10 +1293,6 @@ SPIDER_TRX *spider_get_trx( ++spider_thread_id; pthread_mutex_unlock(&spider_thread_id_mutex); trx->trx_conn_adjustment = 1; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - trx->trx_hs_r_conn_adjustment = 1; - trx->trx_hs_w_conn_adjustment = 1; -#endif if (thd) { @@ -1526,38 +1446,6 @@ error_init_trx_ha_hash: trx->trx_alter_table_hash.array.size_of_element); my_hash_free(&trx->trx_alter_table_hash); error_init_alter_hash: -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider_free_mem_calc( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_direct_hs_w_conn_hash_id, - trx->trx_direct_hs_w_conn_hash.array.max_element * - trx->trx_direct_hs_w_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_direct_hs_w_conn_hash); -error_direct_hs_w_init_hash: - spider_free_mem_calc( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_direct_hs_r_conn_hash_id, - trx->trx_direct_hs_r_conn_hash.array.max_element * - trx->trx_direct_hs_r_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_direct_hs_r_conn_hash); -error_direct_hs_r_init_hash: -#endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider_free_mem_calc( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_hs_w_conn_hash_id, - trx->trx_hs_w_conn_hash.array.max_element * - trx->trx_hs_w_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_hs_w_conn_hash); -error_hs_w_init_hash: - spider_free_mem_calc( - thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, - trx->trx_hs_r_conn_hash_id, - trx->trx_hs_r_conn_hash.array.max_element * - trx->trx_hs_r_conn_hash.array.size_of_element); - my_hash_free(&trx->trx_hs_r_conn_hash); -error_hs_r_init_hash: -#endif spider_free_mem_calc( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_another_conn_hash_id, @@ -3741,28 +3629,6 @@ int spider_check_trx_and_get_conn( if (!trx_ha || trx_ha->wait_for_reusing) spider_trx_set_link_idx_for_all(spider); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if (use_conn_kind) - { - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) - { - if ( -/* - spider->conn_kind[roop_count] != SPIDER_CONN_KIND_MYSQL && -*/ - share->hs_dbton_ids[spider->conn_link_idx[roop_count]] == - SPIDER_DBTON_SIZE - ) { - /* can't use hs interface */ - spider->conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; - spider_clear_bit(spider->do_hs_direct_update, roop_count); - } - } - } -#endif -#endif - if (semi_table_lock_conn) first_byte = '0' + spider_param_semi_table_lock(thd, share->semi_table_lock); @@ -3778,14 +3644,6 @@ int spider_check_trx_and_get_conn( trx_ha->wait_for_reusing || trx->spider_thread_id != spider->spider_thread_id || trx->trx_conn_adjustment != spider->trx_conn_adjustment || -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - (use_conn_kind && - ( - trx->trx_hs_r_conn_adjustment != spider->trx_hs_r_conn_adjustment || - trx->trx_hs_w_conn_adjustment != spider->trx_hs_w_conn_adjustment - ) - ) || -#endif first_byte != *spider->conn_keys[0] || share->link_statuses[spider->conn_link_idx[spider->search_link_idx]] == SPIDER_LINK_STATUS_NG @@ -3795,13 +3653,6 @@ int spider_check_trx_and_get_conn( "spider change thd" : "spider next trx")); spider->wide_handler->trx = trx; spider->trx_conn_adjustment = trx->trx_conn_adjustment; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (use_conn_kind) - { - spider->trx_hs_r_conn_adjustment = trx->trx_hs_r_conn_adjustment; - spider->trx_hs_w_conn_adjustment = trx->trx_hs_w_conn_adjustment; - } -#endif if ( spider->spider_thread_id != trx->spider_thread_id || spider->search_link_query_id != thd->query_id @@ -3846,12 +3697,6 @@ int spider_check_trx_and_get_conn( { if (!spider->handler_opened(roop_count, SPIDER_CONN_KIND_MYSQL)) spider->conns[roop_count] = NULL; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (!spider->handler_opened(roop_count, SPIDER_CONN_KIND_HS_READ)) - spider->hs_r_conns[roop_count] = NULL; - if (!spider->handler_opened(roop_count, SPIDER_CONN_KIND_HS_WRITE)) - spider->hs_w_conns[roop_count] = NULL; -#endif } bool search_link_idx_is_checked = FALSE; for ( @@ -3868,18 +3713,8 @@ int spider_check_trx_and_get_conn( if (roop_count == spider->search_link_idx) search_link_idx_is_checked = TRUE; if ( -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ( -#endif tgt_conn_kind == SPIDER_CONN_KIND_MYSQL && !spider->conns[roop_count] -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - ) || - (tgt_conn_kind == SPIDER_CONN_KIND_HS_READ && - !spider->hs_r_conns[roop_count]) || - (tgt_conn_kind == SPIDER_CONN_KIND_HS_WRITE && - !spider->hs_w_conns[roop_count]) -#endif ) { *spider->conn_keys[roop_count] = first_byte; if ( @@ -3919,51 +3754,6 @@ int spider_check_trx_and_get_conn( } conn->error_mode &= spider->error_mode; } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if ( - spider->do_direct_update && - spider_bit_is_set(spider->do_hs_direct_update, roop_count) && - !spider->hs_w_conns[roop_count] - ) { - if ( - !(conn = - spider_get_conn(share, roop_count, - spider->conn_keys[roop_count], trx, - spider, FALSE, TRUE, - SPIDER_CONN_KIND_HS_WRITE, - &error_num)) - ) { - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - error_num = spider_ping_table_mon_from_table( - trx, - trx->thd, - share, - roop_count, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - TRUE - ); - } - DBUG_PRINT("info",("spider get conn error")); - *spider->conn_keys[0] = first_byte_bak; - spider->spider_thread_id = 0; - DBUG_RETURN(error_num); - } - conn->error_mode &= spider->error_mode; - } -#endif -#endif } if (!search_link_idx_is_checked) { @@ -4002,21 +3792,8 @@ int spider_check_trx_and_get_conn( ) { if (roop_count == spider->search_link_idx) search_link_idx_is_checked = TRUE; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ( - !use_conn_kind || - spider->conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL - ) { -#endif - conn = spider->conns[roop_count]; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else if (spider->conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ) - { - conn = spider->hs_r_conns[roop_count]; - } else { - conn = spider->hs_w_conns[roop_count]; - } -#endif + + conn= spider->conns[roop_count]; if (!conn) { @@ -4056,53 +3833,6 @@ int spider_check_trx_and_get_conn( } } conn->error_mode &= spider->error_mode; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS - if ( - spider->do_direct_update && - spider_bit_is_set(spider->do_hs_direct_update, roop_count) - ) { - conn = spider->hs_w_conns[roop_count]; - if (!conn) - { - DBUG_PRINT("info",("spider get hs_w_conn %d", roop_count)); - if ( - !(conn = - spider_get_conn(share, roop_count, - spider->conn_keys[roop_count], trx, - spider, FALSE, TRUE, - SPIDER_CONN_KIND_HS_WRITE, - &error_num)) - ) { - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - error_num = spider_ping_table_mon_from_table( - trx, - trx->thd, - share, - roop_count, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - TRUE - ); - } - DBUG_PRINT("info",("spider get conn error")); - DBUG_RETURN(error_num); - } - } - } - conn->error_mode &= spider->error_mode; -#endif -#endif } if (!search_link_idx_is_checked) { @@ -4358,20 +4088,6 @@ void spider_trx_set_link_idx_for_all( share->conn_keys[0]), char*); DBUG_PRINT("info",("spider conn_keys[%d]=%s", roop_count, spider->conn_keys[roop_count])); -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - spider->hs_r_conn_keys[roop_count] = - ADD_TO_PTR(spider->conn_keys_first_ptr, - PTR_BYTE_DIFF(share->hs_read_conn_keys[conn_link_idx[roop_count]], - share->conn_keys[0]), char*); - DBUG_PRINT("info",("spider hs_r_conn_keys[%d]=%s", - roop_count, spider->hs_r_conn_keys[roop_count])); - spider->hs_w_conn_keys[roop_count] = - ADD_TO_PTR(spider->conn_keys_first_ptr, - PTR_BYTE_DIFF(share->hs_write_conn_keys[conn_link_idx[roop_count]], - share->conn_keys[0]), char*); - DBUG_PRINT("info",("spider hs_w_conn_keys[%d]=%s", - roop_count, spider->hs_w_conn_keys[roop_count])); -#endif } DBUG_VOID_RETURN; } |