diff --git a/storage/tianchi/ha_tse.cc b/storage/tianchi/ha_tse.cc index 11c9dcbb909506dde77716c4f4b901cee1f2177a..a6f13bdc7ad836796e1b065db3f3dc9c68c3c1eb 100644 --- a/storage/tianchi/ha_tse.cc +++ b/storage/tianchi/ha_tse.cc @@ -2277,6 +2277,11 @@ int ha_tse::initialize() { m_tch.cursor_ref = 0; m_tch.cursor_valid = false; m_tch.part_id = (uint32_t)0xFFFFFFFF; + + m_tse_buf = tse_alloc_buf(&m_tch, BIG_RECORD_SIZE); + if (m_tse_buf == nullptr) { + tse_log_warning("alloc shm mem failed, m_tse_buf size(%u)", BIG_RECORD_SIZE); + } return CT_SUCCESS; } @@ -2561,24 +2566,26 @@ int ha_tse::convert_mysql_record_and_write_to_cantian(uchar *buf, int *cantian_r int error_result; ct_errno_t ret; uint64_t cur_last_insert_id = 0; - if (m_tse_buf == nullptr) { - m_tse_buf = tse_alloc_buf(&m_tch, BIG_RECORD_SIZE); - } - if (m_tse_buf == nullptr) { + uchar *tse_buf = m_tse_buf ? m_tse_buf : tse_alloc_buf(&m_tch, BIG_RECORD_SIZE_DYNAMIC); + if (tse_buf == nullptr) { return convert_tse_error_code_to_mysql(ERR_ALLOC_MEMORY); } - memset(m_tse_buf, 0, sizeof(row_head_t)); - record_buf_info_t record_buf = {m_tse_buf, buf, cantian_record_buf_size}; + memset(tse_buf, 0, sizeof(row_head_t)); + record_buf_info_t record_buf = {tse_buf, buf, cantian_record_buf_size}; update_member_tch(m_tch, tse_hton, ha_thd()); error_result = mysql_record_to_cantian_record(*table, &record_buf, m_tch, serial_column_offset); update_sess_ctx_by_tch(m_tch, tse_hton, ha_thd()); // update for tse_knl_write_lob in mysql_record_to_cantian_record if (error_result != 0) { + // 如果m_tse_buf为空,说明tse_buf是动态申请的,在函数退出之前要释放掉 + if (m_tse_buf == nullptr) { + tse_free_buf(&m_tch, tse_buf); + } return error_result; } update_member_tch(m_tch, tse_hton, ha_thd()); - record_info_t record_info = { m_tse_buf, (uint16_t)*cantian_record_buf_size }; + record_info_t record_info = { tse_buf, (uint16_t)*cantian_record_buf_size }; ret = (ct_errno_t)tse_write_row(&m_tch, &record_info, *serial_column_offset, &cur_last_insert_id, flag); update_sess_ctx_by_tch(m_tch, tse_hton, ha_thd()); check_error_code_to_mysql(ha_thd(), &ret); @@ -2588,6 +2595,10 @@ int ha_tse::convert_mysql_record_and_write_to_cantian(uchar *buf, int *cantian_r insert_id_for_cur_row = cur_last_insert_id; } + if (m_tse_buf == nullptr) { + tse_free_buf(&m_tch, tse_buf); + } + return convert_tse_error_code_to_mysql(ret); } @@ -2751,15 +2762,13 @@ EXTER_ATTACK int ha_tse::update_row(const uchar *old_data, uchar *new_data) { return HA_ERR_RECORD_IS_THE_SAME; } - if (m_tse_buf == nullptr) { - m_tse_buf = tse_alloc_buf(&m_tch, BIG_RECORD_SIZE); - } - if (m_tse_buf == nullptr) { + uchar *tse_buf = m_tse_buf ? m_tse_buf : tse_alloc_buf(&m_tch, BIG_RECORD_SIZE_DYNAMIC); + if (tse_buf == nullptr) { return convert_tse_error_code_to_mysql(ERR_ALLOC_MEMORY); } - memset(m_tse_buf, 0, sizeof(row_head_t)); + memset(tse_buf, 0, sizeof(row_head_t)); - record_buf_info_t record_buf = {m_tse_buf, new_data, &cantian_new_record_buf_size}; + record_buf_info_t record_buf = {tse_buf, new_data, &cantian_new_record_buf_size}; ct_errno_t ret = (ct_errno_t)mysql_record_to_cantian_record(*table, &record_buf, m_tch, &serial_column_offset, &upd_fields); if (ret != CT_SUCCESS) { @@ -2775,9 +2784,13 @@ EXTER_ATTACK int ha_tse::update_row(const uchar *old_data, uchar *new_data) { if (!flag.no_foreign_key_check) { flag.no_cascade_check = flag.dd_update ? true : pre_check_for_cascade(true); } - ret = (ct_errno_t)tse_update_row(&m_tch, cantian_new_record_buf_size, m_tse_buf, + ret = (ct_errno_t)tse_update_row(&m_tch, cantian_new_record_buf_size, tse_buf, &upd_fields[0], upd_fields.size(), flag); check_error_code_to_mysql(thd, &ret); + // 如果m_tse_buf为空,说明tse_buf是动态申请的,在函数退出之前要释放掉 + if (m_tse_buf == nullptr) { + tse_free_buf(&m_tch, tse_buf); + } return convert_tse_error_code_to_mysql(ret); } @@ -3074,16 +3087,19 @@ int ha_tse::rnd_next(uchar *buf) { if (!m_rec_buf || m_rec_buf->max_records() == 0) { int ret = CT_SUCCESS; ct_errno_t ct_ret = CT_SUCCESS; - if (m_tse_buf == nullptr) { - m_tse_buf = tse_alloc_buf(&m_tch, BIG_RECORD_SIZE); - } - if (m_tse_buf == nullptr) { + uchar *tse_buf = m_tse_buf ? m_tse_buf : tse_alloc_buf(&m_tch, BIG_RECORD_SIZE_DYNAMIC); + if (tse_buf == nullptr) { return convert_tse_error_code_to_mysql(ERR_ALLOC_MEMORY); } - record_info_t record_info = {m_tse_buf, 0}; + record_info_t record_info = {tse_buf, 0}; ct_ret = (ct_errno_t)tse_rnd_next(&m_tch, &record_info); ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_END_OF_FILE); + + // 如果m_tse_buf为空,说明tse_buf是动态申请的,在函数退出之前要释放掉 + if (m_tse_buf == nullptr) { + tse_free_buf(&m_tch, tse_buf); + } return ret; } @@ -3166,21 +3182,23 @@ EXTER_ATTACK int ha_tse::rnd_pos(uchar *buf, uchar *pos) { ha_statistic_increment(&System_status_var::ha_read_rnd_count); int ret = CT_SUCCESS; ct_errno_t ct_ret = CT_SUCCESS; - - if (m_tse_buf == nullptr) { - m_tse_buf = tse_alloc_buf(&m_tch, BIG_RECORD_SIZE); - } - if (m_tse_buf == nullptr) { + uchar *tse_buf = m_tse_buf ? m_tse_buf : tse_alloc_buf(&m_tch, BIG_RECORD_SIZE_DYNAMIC); + if (tse_buf == nullptr) { return convert_tse_error_code_to_mysql(ERR_ALLOC_MEMORY); } - record_info_t record_info = {m_tse_buf, 0}; + record_info_t record_info = {tse_buf, 0}; uint key_len = ref_length; if (IS_TSE_PART(m_tch.part_id)) { key_len -= PARTITION_BYTES_IN_POS; } ct_ret = (ct_errno_t)tse_rnd_pos(&m_tch, key_len, pos, &record_info); ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_KEY_NOT_FOUND); + + // 如果m_tse_buf为空,说明tse_buf是动态申请的,在函数退出之前要释放掉 + if (m_tse_buf == nullptr) { + tse_free_buf(&m_tch, tse_buf); + } return ret; } @@ -3516,15 +3534,13 @@ EXTER_ATTACK int ha_tse::index_read(uchar *buf, const uchar *key, uint key_len, return ret; } - if (m_tse_buf == nullptr) { - m_tse_buf = tse_alloc_buf(&m_tch, BIG_RECORD_SIZE); - } - if (m_tse_buf == nullptr) { + uchar *tse_buf = m_tse_buf ? m_tse_buf : tse_alloc_buf(&m_tch, BIG_RECORD_SIZE_DYNAMIC); + if (tse_buf == nullptr) { return convert_tse_error_code_to_mysql(ERR_ALLOC_MEMORY); } update_member_tch(m_tch, tse_hton, ha_thd()); - record_info_t record_info = {m_tse_buf, 0}; + record_info_t record_info = {tse_buf, 0}; attachable_trx_update_pre_addr(tse_hton, ha_thd(), &m_tch, true); @@ -3540,6 +3556,11 @@ EXTER_ATTACK int ha_tse::index_read(uchar *buf, const uchar *key, uint key_len, } ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_KEY_NOT_FOUND); + + // 如果m_tse_buf为空,说明tse_buf是动态申请的,在函数退出之前要释放掉 + if (m_tse_buf == nullptr) { + tse_free_buf(&m_tch, tse_buf); + } return ret; } @@ -3554,18 +3575,20 @@ int ha_tse::index_fetch(uchar *buf) { if (!m_rec_buf || m_rec_buf->max_records() == 0) { int ret = CT_SUCCESS; ct_errno_t ct_ret = CT_SUCCESS; - if (m_tse_buf == nullptr) { - m_tse_buf = tse_alloc_buf(&m_tch, BIG_RECORD_SIZE); - } - if (m_tse_buf == nullptr) { + uchar *tse_buf = m_tse_buf ? m_tse_buf : tse_alloc_buf(&m_tch, BIG_RECORD_SIZE_DYNAMIC); + if (tse_buf == nullptr) { return convert_tse_error_code_to_mysql(ERR_ALLOC_MEMORY); } - record_info_t record_info = {m_tse_buf, 0}; + record_info_t record_info = {tse_buf, 0}; attachable_trx_update_pre_addr(tse_hton, ha_thd(), &m_tch, true); ct_ret = (ct_errno_t)tse_general_fetch(&m_tch, &record_info); attachable_trx_update_pre_addr(tse_hton, ha_thd(), &m_tch, false); ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_END_OF_FILE); + // 如果m_tse_buf为空,说明tse_buf是动态申请的,在函数退出之前要释放掉 + if (m_tse_buf == nullptr) { + tse_free_buf(&m_tch, tse_buf); + } return ret; } diff --git a/storage/tianchi/ha_tse.h b/storage/tianchi/ha_tse.h index e156f5885a660d235814077bcea42b451725e7f7..6cbdcb09f5d8806d6da14f0b1ad22980bae6357a 100644 --- a/storage/tianchi/ha_tse.h +++ b/storage/tianchi/ha_tse.h @@ -64,6 +64,7 @@ using namespace std; #define DEFAULT_RANGE_DENSITY 0.5 #define PREFER_RANGE_DENSITY 0.8 #define CT_MAX_RECORD_LENGTH 64000 +#define BIG_RECORD_SIZE_DYNAMIC (BIG_RECORD_SIZE + 8) // ha_tse构造函数中若没有申请到读写buf共享内存,就在使用时从40968内存池子中动态申请和释放 /* update if restraints changed in Cantian */ #define TSE_MAX_KEY_PART_LENGTH 4095 // CT_MAX_KEY_SIZE @@ -871,7 +872,7 @@ public: tianchi_handler_t m_tch; /* cantian record buffer */ - uchar *m_tse_buf = nullptr; + uchar *m_tse_buf; /* select lock mode */ lock_mode m_select_lock = lock_mode::NO_LOCK;