http://mysql.taobao.org/monthly/2015/08/07/

/*****************************************************************//**
Creates and opens a handle to a table which already exists in an InnoDB
database.
@return 1 if error, 0 if success */
UNIV_INTERN
int
ha_innobase::open(
/*==============*/
const char* name, /*!< in: table name */
int mode, /*!< in: not used */
uint test_if_locked) /*!< in: not used */
{
dict_table_t* ib_table;
char norm_name[];
THD* thd;
char* is_part = NULL;
ibool par_case_name_set = FALSE;
char par_case_name[MAX_FULL_NAME_LEN + ];
dict_err_ignore_t ignore_err = DICT_ERR_IGNORE_NONE; DBUG_ENTER("ha_innobase::open"); thd = ha_thd(); normalize_table_name(norm_name, name); user_thd = NULL; if (!(share=get_share(name))) { DBUG_RETURN();
} /* Will be allocated if it is needed in ::update_row() */
upd_buf = NULL;
upd_buf_size = ; /* Get pointer to a table object in InnoDB dictionary cache */
ib_table = dict_table_get(norm_name, TRUE, ignore_err); table_opened: prebuilt = row_create_prebuilt(ib_table, table->s->reclength); prebuilt->default_rec = table->s->default_values;
ut_ad(prebuilt->default_rec); /* Looks like MySQL-3.23 sometimes has primary key number != 0 */ primary_key = table->s->primary_key;
key_used_on_scan = primary_key; /* Allocate a buffer for a 'row reference'. A row reference is
a string of bytes of length ref_length which uniquely specifies
a row in our table. Note that MySQL may also compare two row
references for equality by doing a simple memcmp on the strings
of length ref_length! */ if (!row_table_got_default_clust_index(ib_table)) { prebuilt->clust_index_was_generated = FALSE; if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
sql_print_error("Table %s has a primary key in "
"InnoDB data dictionary, but not "
"in MySQL!", name); /* This mismatch could cause further problems
if not attended, bring this to the user's attention
by printing a warning in addition to log a message
in the errorlog */
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_NO_SUCH_INDEX,
"InnoDB: Table %s has a "
"primary key in InnoDB data "
"dictionary, but not in "
"MySQL!", name); /* If primary_key >= MAX_KEY, its (primary_key)
value could be out of bound if continue to index
into key_info[] array. Find InnoDB primary index,
and assign its key_length to ref_length.
In addition, since MySQL indexes are sorted starting
with primary index, unique index etc., initialize
ref_length to the first index key length in
case we fail to find InnoDB cluster index. Please note, this will not resolve the primary
index mismatch problem, other side effects are
possible if users continue to use the table.
However, we allow this table to be opened so
that user can adopt necessary measures for the
mismatch while still being accessible to the table
date. */
ref_length = table->key_info[].key_length; /* Find correspoinding cluster index
key length in MySQL's key_info[] array */
for (ulint i = ; i < table->s->keys; i++) {
dict_index_t* index;
index = innobase_get_index(i);
if (dict_index_is_clust(index)) {
ref_length =
table->key_info[i].key_length;
}
}
} else {
/* MySQL allocates the buffer for ref.
key_info->key_length includes space for all key
columns + one byte for each column that may be
NULL. ref_length must be as exact as possible to
save space, because all row reference buffers are
allocated based on ref_length. */ ref_length = table->key_info[primary_key].key_length;
}
} else {
if (primary_key != MAX_KEY) {
sql_print_error(
"Table %s has no primary key in InnoDB data "
"dictionary, but has one in MySQL! If you "
"created the table with a MySQL version < "
"3.23.54 and did not define a primary key, "
"but defined a unique key with all non-NULL "
"columns, then MySQL internally treats that "
"key as the primary key. You can fix this "
"error by dump + DROP + CREATE + reimport "
"of the table.", name); /* This mismatch could cause further problems
if not attended, bring this to the user attention
by printing a warning in addition to log a message
in the errorlog */
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_NO_SUCH_INDEX,
"InnoDB: Table %s has no "
"primary key in InnoDB data "
"dictionary, but has one in "
"MySQL!", name);
} prebuilt->clust_index_was_generated = TRUE; ref_length = DATA_ROW_ID_LEN; /* If we automatically created the clustered index, then
MySQL does not know about it, and MySQL must NOT be aware
of the index used on scan, to make it avoid checking if we
update the column of the index. That is why we assert below
that key_used_on_scan is the undefined value MAX_KEY.
The column is the row id in the automatical generation case,
and it will never be updated anyway. */ if (key_used_on_scan != MAX_KEY) {
sql_print_warning(
"Table %s key_used_on_scan is %lu even "
"though there is no primary key inside "
"InnoDB.", name, (ulong) key_used_on_scan);
}
} /* Index block size in InnoDB: used by MySQL in query optimization */
stats.block_size = * ; /* Init table lock structure */
thr_lock_data_init(&share->lock,&lock,(void*) ); if (prebuilt->table) {
/* We update the highest file format in the system table
space, if this table has higher file format setting. */ trx_sys_file_format_max_upgrade(
(const char**) &innobase_file_format_max,
dict_table_get_format(prebuilt->table));
} /* Only if the table has an AUTOINC column. */
if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
dict_table_autoinc_lock(prebuilt->table); /* Since a table can already be "open" in InnoDB's internal
data dictionary, we only init the autoinc counter once, the
first time the table is loaded. We can safely reuse the
autoinc value from a previous MySQL open. */
if (dict_table_autoinc_read(prebuilt->table) == ) { innobase_initialize_autoinc();
} dict_table_autoinc_unlock(prebuilt->table);
} info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); DBUG_RETURN();
}
/************************************************************************//**
Handling the shared INNOBASE_SHARE structure that is needed to provide table
locking.
****************************************************************************/ static INNOBASE_SHARE* get_share(const char* table_name)
{
INNOBASE_SHARE *share;
mysql_mutex_lock(&innobase_share_mutex); ulint fold = ut_fold_string(table_name); HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
INNOBASE_SHARE*, share,
ut_ad(share->use_count > ),
!strcmp(share->table_name, table_name)); if (!share) { uint length = (uint) strlen(table_name); /* TODO: invoke HASH_MIGRATE if innobase_open_tables
grows too big */ share = (INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+,
MYF(MY_FAE | MY_ZEROFILL)); share->table_name = (char*) memcpy(share + ,
table_name, length + ); HASH_INSERT(INNOBASE_SHARE, table_name_hash,
innobase_open_tables, fold, share); thr_lock_init(&share->lock); /* Index translation table initialization */
share->idx_trans_tbl.index_mapping = NULL;
share->idx_trans_tbl.index_count = ;
share->idx_trans_tbl.array_size = ;
} share->use_count++;
mysql_mutex_unlock(&innobase_share_mutex); return(share);
}

最新文章

  1. canvas画圆(一)
  2. HTML基础(3)
  3. Spring JDBC实现查询
  4. 01从c到c++
  5. 三表联查,这是我目前写过的最长的sql语句,嗯嗯,果然遇到问题才能让我更快成长,更复杂的语句也有了一些心得了
  6. SQL 替换指定列中的指定字符串
  7. changepassword.c 0.9:一个通过WEB界面更改LINUX用户密码的程序
  8. css 关于两栏布局,左边固定,右边自适应
  9. [Guava官方文档翻译] 3. 前置条件检查(Preconditions Explained)
  10. MediaCodec文档翻译
  11. Visual Studio Code开发TypeScript
  12. Django连接mysql数据库
  13. GHSpro文件上传
  14. MySQL:System.Data.Entity ,MySqlCommand, MySqlParameter and &quot;LIKE&quot; %
  15. react-native基础教程(1)
  16. 苹果审核被拒,Guideline 1.1.6 - Safety - Objectionable Content;Guideline 3.1.1 - Business - Payments - In-App Purchase
  17. License 校验
  18. java集合框架体系
  19. XML解析的二种方法之Sax解析
  20. C++ Primer Plus学习:第八章

热门文章

  1. NSStringDrawingOptions-b
  2. 2140: 稳定婚姻 - BZOJ
  3. c++ 获取本地ip地址
  4. 【转】使用JIRA搭建企业问题跟踪系统【个人推荐】
  5. javaZIP压缩文件
  6. Oracle 10G 安装后 不能卸载, 不能打开Web管理....
  7. PAT-乙级-1053. 住房空置率 (20)
  8. 基于 Eclipse 平台的代码生成技术
  9. cf 363A B C
  10. Google 网站打不开