• MySQL InnoDB Engine--自适应哈希索引代码瞎猜01


    1、自适应哈希索引初始化

    在storageinnobaseufuf0buf.cc的函数buf_pool_init负责初始化Buffer pool, 会调用btr_search_sys_create来初始化AHI,并分配当前Buffer pool内存的1/64给AHI。

    /** Creates the buffer pool.
    @param[in]  total_size    Size of the total pool in bytes.
    @param[in]  n_instances   Number of buffer pool instances to create.
    @return DB_SUCCESS if success, DB_ERROR if not enough memory or error */
    dberr_t buf_pool_init(ulint total_size, ulint n_instances) {
        
        /** 初始化AHI并分片buffer pool的1/64内存给AHI **/
        btr_search_sys_create(buf_pool_get_curr_size() / sizeof(void *) / 64);
    }

    在btr_search_sys_create中,会按照参数innodb_adaptive_hash_index_parts来设置hash_tabsles数量,并将内存平均分配给每个hash_table。

    在创建每个hash_table时,会按照(hash_size / btr_ahi_parts)来设置hash_table的cells数量。

    /** Creates and initializes the adaptive search system at a database start.
    @param[in]    hash_size    hash table size. */
    void btr_search_sys_create(ulint hash_size) {
      /* Search System is divided into n parts.
      Each part controls access to distinct set of hash buckets from
      hash table through its own latch. */
    
      /* Step-1: Allocate latches (1 per part). */
      btr_search_latches = reinterpret_cast<rw_lock_t **>(
          ut_malloc(sizeof(rw_lock_t *) * btr_ahi_parts, mem_key_ahi));
    
      for (ulint i = 0; i < btr_ahi_parts; ++i) {
        btr_search_latches[i] = reinterpret_cast<rw_lock_t *>(
            ut_malloc(sizeof(rw_lock_t), mem_key_ahi));
    
        rw_lock_create(btr_search_latch_key, btr_search_latches[i],
                       SYNC_SEARCH_SYS);
      }
    
      /* Step-2: Allocate hash tablees. */
      btr_search_sys = reinterpret_cast<btr_search_sys_t *>(
          ut_malloc(sizeof(btr_search_sys_t), mem_key_ahi));
    
      btr_search_sys->hash_tables = reinterpret_cast<hash_table_t **>(
          ut_malloc(sizeof(hash_table_t *) * btr_ahi_parts, mem_key_ahi));
    
      for (ulint i = 0; i < btr_ahi_parts; ++i) {
        btr_search_sys->hash_tables[i] =
            ib_create((hash_size / btr_ahi_parts), LATCH_ID_HASH_TABLE_MUTEX, 0,
                      MEM_HEAP_FOR_BTR_SEARCH);
    
    #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
        btr_search_sys->hash_tables[i]->adaptive = TRUE;
    #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
      }
    }

    通过调用通用的ib_create函数来创建hast_table:

    /** Creates a hash table with at least n array cells.  The actual number
     of cells is chosen to be a prime number slightly bigger than n.
     @return own: created table */
    hash_table_t *ib_create(ulint n,       /*!< in: number of array cells */
                            latch_id_t id, /*!< in: latch ID */
                            ulint n_sync_obj,
                            /*!< in: number of mutexes to protect the
                            hash table: must be a power of 2, or 0 */
                            ulint type) /*!< in: type of datastructure for which
                                        MEM_HEAP_FOR_PAGE_HASH */
    {
      hash_table_t *table;
    
      ut_a(type == MEM_HEAP_FOR_BTR_SEARCH || type == MEM_HEAP_FOR_PAGE_HASH);
    
      ut_ad(ut_is_2pow(n_sync_obj));
      table = hash_create(n);
    
      /* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
      but in practise it never should in this case, hence the asserts. */
    
      if (n_sync_obj == 0) {
        table->heap = mem_heap_create_typed(
            ut_min(static_cast<ulint>(4096), MEM_MAX_ALLOC_IN_BUF / 2 -
                                                 MEM_BLOCK_HEADER_SIZE -
                                                 MEM_SPACE_NEEDED(0)),
            type);
        ut_a(table->heap);
    
        return (table);
      }
    
      if (type == MEM_HEAP_FOR_PAGE_HASH) {
        /* We create a hash table protected by rw_locks for
        buf_pool->page_hash. */
        hash_create_sync_obj(table, HASH_TABLE_SYNC_RW_LOCK, id, n_sync_obj);
      } else {
        hash_create_sync_obj(table, HASH_TABLE_SYNC_MUTEX, id, n_sync_obj);
      }
    
      table->heaps =
          static_cast<mem_heap_t **>(ut_malloc_nokey(n_sync_obj * sizeof(void *)));
    
      for (ulint i = 0; i < n_sync_obj; i++) {
        table->heaps[i] = mem_heap_create_typed(
            ut_min(static_cast<ulint>(4096), MEM_MAX_ALLOC_IN_BUF / 2 -
                                                 MEM_BLOCK_HEADER_SIZE -
                                                 MEM_SPACE_NEEDED(0)),
            type);
        ut_a(table->heaps[i]);
      }
    
      return (table);
    }
    
    /** Creates a hash table with >= n array cells. The actual number
     of cells is chosen to be a prime number slightly bigger than n.
     @return own: created table */
    hash_table_t *hash_create(ulint n); /*!< in: number of array cells */
    
    /* Fix Bug #13859: symbol collision between imap/mysql */
    #define hash_create hash0_create

    在hash_create函数中会跟进传入的cell数量重新计算,取一个大于"传入cell数量"的最小素数。

    /** Creates a hash table with >= n array cells. The actual number of cells is
     chosen to be a prime number slightly bigger than n.
     @return own: created table */
    hash_table_t *hash_create(ulint n) /*!< in: number of array cells */
    {
      hash_cell_t *array;
      ulint prime;
      hash_table_t *table;
    
      prime = ut_find_prime(n);
    
      table = static_cast<hash_table_t *>(ut_malloc_nokey(sizeof(hash_table_t)));
    
      array =
          static_cast<hash_cell_t *>(ut_malloc_nokey(sizeof(hash_cell_t) * prime));
    
      /* The default type of hash_table is HASH_TABLE_SYNC_NONE i.e.:
      the caller is responsible for access control to the table. */
      table->type = HASH_TABLE_SYNC_NONE;
      table->cells = array;
      table->n_cells = prime;
    #ifndef UNIV_HOTBACKUP
    #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
      table->adaptive = FALSE;
    #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
      table->n_sync_obj = 0;
      table->sync_obj.mutexes = nullptr;
      table->heaps = nullptr;
    #endif /* !UNIV_HOTBACKUP */
      table->heap = nullptr;
      ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
    
      /* Initialize the cell array */
      hash_table_clear(table);
    
      return (table);
    }
  • 相关阅读:
    Windows 8(64位)如何搭建 Android 开发环境与真机测试(转)
    C# winform写入和读取TXT文件
    winform利用ImageList控件和ListView控件组合制作图片文件浏览器
    Linux 桌面玩家指南:01. 玩转 Linux 系统的方法论
    这些年一直记不住的 Java I/O
    深入理解 JavaScript,以及 Linux 下的开发调试工具
    在 Ubuntu 中使用 Visual Studio Code
    像黑客一样使用 Linux 命令行
    JAAS 是个什么梗
    Java 开发主流 IDE 环境体验
  • 原文地址:https://www.cnblogs.com/gaogao67/p/14991542.html
Copyright © 2020-2023  润新知