[转帖]ha_innobase::open_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 1421 | 回复: 0   主题: [转帖]ha_innobase::open        下一篇 
ad222888
注册用户
等级:新兵
经验:66
发帖:134
精华:0
注册:2016-9-25
状态:离线
发送短消息息给ad222888 加好友    发送短消息息给ad222888 发消息
发表于: IP:您无权察看 2018-8-15 15:03:39 | [全部帖] [楼主帖] 楼主

/*****************************************************************//**

Creates and opens a handle to a table which already exists in an InnoDB

database.

@return 1 if error, 0 if success */

UNIV_INTERN

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[1000];

THD* thd;

char* is_part = NULL;

ibool par_case_name_set = FALSE;

char par_case_name[MAX_FULL_NAME_LEN + 1];

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(1);

    /* Will be allocated if it is needed in ::update_row() */

    upd_buf = NULL;

    upd_buf_size = 0;

    /* 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[0].key_length;

    /* Find correspoinding cluster index

    key length in MySQL‘s key_info[] array */

    for (ulint i = 0; 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 = 16 * 1024;

    /* Init table lock structure */

    thr_lock_data_init(&share->lock,&lock,(void*) 0);

    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) == 0) {

    innobase_initialize_autoinc();

    dict_table_autoinc_unlock(prebuilt->table);

    info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);

    DBUG_RETURN(0);

    /************************************************************************//**

    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 > 0),

    !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+1,

    MYF(MY_FAE | MY_ZEROFILL));

    share->table_name = (char*) memcpy(share + 1,

    table_name, length + 1);

    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 = 0;

    share->idx_trans_tbl.array_size = 0;

    share->use_count++;

    mysql_mutex_unlock(&innobase_share_mutex);

    return(share);




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论