博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ha_innobase::open
阅读量:4508 次
发布时间:2019-06-08

本文共 8804 字,大约阅读时间需要 29 分钟。

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

/*****************************************************************//**Creates and opens a handle to a table which already exists in an InnoDBdatabase.@return    1 if error, 0 if success */UNIV_INTERNintha_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);}

 

转载于:https://www.cnblogs.com/taek/p/5071191.html

你可能感兴趣的文章
Visual Studio中的快捷键
查看>>
Mac下显示和隐藏“隐藏文件”
查看>>
Chessboard POJ - 2446(最大流 || 匹配)
查看>>
Warning: Cannot modify header information原因及解决方案
查看>>
Python ConfigParser模块
查看>>
程序员的学习和积累
查看>>
.net实现支付宝在线支付
查看>>
centos7 swoole 三步搞定全部
查看>>
noip2014day1题解
查看>>
Excel:一些方法的理解
查看>>
【转】在RHEL上升级Python
查看>>
java:环境变量设置
查看>>
Servlet的学习之Response响应对象(3)
查看>>
基础知识回顾——上下文管理器
查看>>
ARM(RISC)和x86(CISC)的技术差异
查看>>
第3章 对象基础
查看>>
文件压缩与解压缩
查看>>
android 搜索自动匹配关键字并且标红
查看>>
Android ViewPager使用详解
查看>>
python爬虫之scrapy的pipeline的使用
查看>>