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);
}

ha_innobase::open的更多相关文章

  1. ha_innobase::general_fetch

    /***********************************************************************//** Reads the next or previ ...

  2. ha_innobase::rnd_next

    /*****************************************************************//** Reads the next row in a table ...

  3. class ha_innobase: public handler

    /** The class defining a handle to an Innodb table */ class ha_innobase: public handler { row_prebui ...

  4. innodb 自增列重复值问题

    1 innodb 自增列出现重复值的问题 先从问题入手,重现下这个bug use test; drop table t1; create table t1(id int auto_increment, ...

  5. 悲剧啊!Mysql的上古BUG!!!

    导读 这是MySQL8.0修复的上古bug之一,在2003年由Percona的CEO(当时应该还没Percona吧)提出的bug#199,光看这bug号就扑面而来一股上古时代的沧桑气息. 问题的本质在 ...

  6. mysql5.7 代价模型浅析

    代价模型 mysql 5.7.10代价计算相对之前的版本有5.7 代价模型浅析较大的改进.例如 代价模型参数可以动态配置,可以适应不同的硬件 区分考虑数据在内存和在磁盘中的代价 代价精度提升为浮点型 ...

  7. innobackupex使用实践

    先介绍一下环境: MySQL:5.6.19 安装路径:/u01/mysql 数据文件:/u01/mysql/data 备份源:/u02/backup 我是异机恢复,和本机操作一样. 一. 全量备份 步 ...

  8. MySQL 外键异常分析

    外键约束异常现象 如下测例中,没有违反引用约束的插入失败. create database `a-b`; use `a-b`; SET FOREIGN_KEY_CHECKS=0; create tab ...

  9. [转载] 淘宝内部分享:怎么跳出MySQL的10个大坑(上)

    原文: http://mp.weixin.qq.com/s?__biz=MzAxNjAzMTQyMA==&mid=209773318&idx=1&sn=e9600d3db80b ...

随机推荐

  1. 【转】android 内存泄漏相关收藏博客。

    关于android内存泄漏的研究   博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基 ...

  2. QT windows msvc下使用boost库(备忘)

    win32-msvc2015: { contains(QMAKE_HOST.arch, x86):{ INCLUDEPATH += D:\3SDK\boost_1_61_0 LIBS += -LD:\ ...

  3. Emmet快速编写CSS样式

    基本的CSS样式编写时,很多样式只需输入首字母即可得到不带属性值的CSS样式,像上面说到的margin. 1.而对于一些带有特定的属性值的CSS样式,只需输入CSS标签与属性值的首字母就可以,比如: ...

  4. POJ 3579

    Median Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3528   Accepted: 1001 Descriptio ...

  5. SPOJ CNTPRIME 13015 Counting Primes (水题,区间更新,求区间的素数个数)

    题目连接:http://www.spoj.com/problems/CNTPRIME/ #include <iostream> #include <stdio.h> #incl ...

  6. 递归算法实现10进制到N进制的转换

    #include<iostream> using namespace std; int BaseTrans(int data,int B){ int s; ) ; //结束递归算法 s=d ...

  7. sql中时间的比较方法

    --------------------------------------------------------------------1. 当前系统日期.时间select getdate() 2. ...

  8. vector、string实现大数加法乘法

    理解 vector 是一个容器,是一个数据集,里边装了很多个元素.与数组最大的不同是 vector 可以动态增长. 用 vector 实现大数运算的关键是,以 string 的方式读入一个大数,然后将 ...

  9. Enum枚举 简单的使用

    在枚举中使用抽象方法 /** * 为枚举类定义一个抽象方法,<br/> * 这个抽象方法由不同的枚举值提供不同的实现 * * @author wangzhu * @date 2014-9- ...

  10. oracle触发器详解(转)

    触发器是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 8.1 触发器类型 触发器在数据库里以独立的对象存储,它与存储过 ...