MySQL · 参数故事 · innodb_additional_mem_pool_size

参数简介

innodb_additional_mem_pool_size 是 InnoDB 用来保存数据字典信息和其他内部数据结构的内存池的大小,单位是 byte,参数默认值为8M。数据库中的表数量越多,参数值应该越大,如果 InnoDB 用完了内存池中的内存,就会从操作系统中分配内存,同时在 error log 中打入报警信息。

innodb_use_sys_malloc 配置为 ON 时,innodb_additional_mem_pool_size 失效(直接从操作系统分配内存)。

innodb_additional_mem_pool_size 和 innodb_use_sys_malloc 在 MySQL 5.7.4 中移除。

参数合理值预估

./storage/innobase/handler/ha_innodb.cc:
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;

./storage/innobase/srv/srv0srv.cc:        mem_init(srv_mem_pool_size);

storage/innobase/mem/mem0dbg.cc: mem_comm_pool = mem_pool_create(size);

从源码中可以看出,innodb_additional_mem_pool_size 的参数值用于指定内存池 mem_comm_pool 的大小;

storage/innobase/mem/mem0mem.cc:
        block = static_cast<mem_block_t*>(
                mem_area_alloc(&len, mem_comm_pool));

函数 mem_area_alloc 从 mem_comm_pool 内存池中分配内存;

storage/innobase/mem/mem0pool.cc:

/* If we are using os allocator just make a simple call
to malloc */
        if (UNIV_LIKELY(srv_use_sys_malloc)) {
        return(malloc(*psize));
}

........

area = UT_LIST_GET_FIRST(pool->free_list[n]);

if (area == NULL) {
        ret = mem_pool_fill_free_list(n, pool);

        if (ret == FALSE) {
                /* Out of memory in memory pool: we try to allocate
                from the operating system with the regular malloc: */

                mem_n_threads_inside--;
                mutex_exit(&(pool->mutex));

                return(ut_malloc(size));
        }

        area = UT_LIST_GET_FIRST(pool->free_list[n]);
}

如果 innodb_use_sys_malloc (上述代码中的srv_use_sys_malloc) 设置为 ON,或者内存池中没有足够的内存可供分配,则直接从操作系统中分配内存。

mem_area_alloc 调用栈如下(use database 触发断点)

#0  mem_area_alloc
#1  0x000000000118048d in mem_heap_create_block_func
#2  0x000000000149a390 in mem_heap_create_func
#3  0x00000000014aa6d5 in dict_load_table
#4  0x0000000001481082 in dict_table_open_on_name
#5  0x000000000109d769 in ha_innobase::open
#6  0x00000000006d5245 in handler::ha_open
#7  0x0000000000b830ae in open_table_from_share
#8  0x000000000091deee in open_table
#9  0x0000000000922eea in open_and_process_table
#10 0x000000000092492f in open_tables
#11 0x0000000000926c21 in open_normal_and_derived_tables
#12 0x0000000000a83834 in mysqld_list_fields
#13 0x00000000009f28e1 in dispatch_command
#14 0x00000000009eeb51 in do_command
#15 0x0000000000982cb6 in do_handle_one_connection
#16 0x000000000098238b in handle_one_connection
#17 0x0000000001877f91 in pfs_spawn_thread
#18 0x0000003d8c007851 in start_thread ()
#19 0x0000003d8bce767d in clone ()

函数 dict_load_table 中会为每张表分配32k的空间 ( mem_heap_create(32000) 实际分配32744字节空间 ),数据字典中每张表所占空间的上限是32k,具体占用空间根据列数和索引数量分配,分配完成后回收32k中未使用的空间

storage/innobase/dict/dict0load.cc: heap = mem_heap_create(32000);

show engine innodb status BUFFER POOL AND MEMORY Dictionary cache

实际使用的数据字典缓存,不会超过每张表32k,实测过程中,每张表不包括索引占4K,每个索引占2k,列数对空间占用影响不大。

测试用表如下,未建索引时,1000张表占用空间4M,增加列占用空间增长不明显,每增加一个索引,占用空间增加2M,可以估测每张表占用空间4k(不含索引),每个索引占用空间2k。

Create Table: CREATE TABLE `1000` (
  `id` int(11) DEFAULT NULL,
  `a` varchar(255) DEFAULT NULL,
 `b` varchar(255) DEFAULT NULL,
  `c` varchar(255) DEFAULT NULL,
  `d` varchar(255) DEFAULT NULL,
  KEY `a` (`a`),
  KEY `b` (`b`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

引入和移除该参数的原因

早期操作系统的内存分配器性能和可伸缩性较差,并且当时没有适合多核心CPU的内存分配器。所以,InnoDB 实现了一套自己的内存分配系统,做为内存系统的参数之一,引入了innodb_additional_mem_pool_size

随着多核心CPU的广泛应用和操作系统的成熟,操作系统能够提供性能更高、可伸缩性更好的内存分配器,包括 Hoard、libumem、mtmalloc、ptmalloc、tbbmalloc 和 TCMalloc 等。InnoDB 实现的内存分配器相比操作系统的内存分配器并没有明显优势,所以在之后的版本,会移除 innodb_additional_mem_pool_size 和 innodb_use_sys_malloc 两个参数,统一使用操作系统的内存分配器。

时间: 2024-08-05 04:11:30

MySQL · 参数故事 · innodb_additional_mem_pool_size的相关文章

MySQL内核月报 2014.08-MySQL· 参数故事·timed_mutexes

提要 MySQL 5.5.39 Release版本正式从源码里删除了全局参数timed_mutexes.timed_mutexes原本用来控制是否对Innodb引擎的mutex wait进行计时统计,以方便进行性能诊断.为什么要删除这个参数呢? 下面介绍下相关背景: Innodb的同步锁机制 Innodb封装了mutex和rw_lock结构来保护内存的变量和结构,进行多线程同步,考虑可移植性, mutex使用lock_word或者OS mutex来保证原子操作,并使用event条件变量进行阻塞和

mysql参数调优

为何要调整参数 不同服务器之间的配置.性能不一样 不同业务场景对数据的需求不一样 Mysql的默认参数只是个参考值,并不适合所有的应用场景 优化之前我们需要知道什么 服务器相关的配置 服务器型号 操作系统版本 内核版本 磁盘存储介质(sas sata ssd) 业务相关的情况 读多写少,读少写多 业务数据增长量 mysql相关的配置 服务器上需要关注那些 硬件情况 cpu(几核.超线程) 内存 磁盘(容量.性能) 操作系统版本(是否为稳定版) CPU.网卡节电模式(建议数据库应用的服务器,关闭节

深入理解mysql参数

前言:mysql参数的修改在mysql的课程里面应该属于相对基础的知识,但是作为一个mysql的初学者还是很有必要弄懂这个知识点,以后的学习过程中将会经常用到的.技术很多时候都是相通的,如果有学过oracle的朋友应该会知道,oracle的参数里面有几个标签:动态参数.静态参数.session级别修改.全局修改.立即生效和延迟生效.作为数据库mysql也同样有这些特性,但是整体学起来后会发现mysql某些方面还是没有oracle做的到位,在该文档的最后咱们再做个总结. 一.参数文件 1.查看参数

MySQL内核月报 2014.09-TokuDB· 参数故事·数据安全和性能

TokuDB里可调优的参数不多,今天把"最重要"的几个拉出来晒晒. 与性能相关的参数及说明: 针对不同的使用场景: 1) 对数据要求较高(不允许丢失数据,事务ACID完整性),只需根据内存调整tokudb_cache_size大小即可,建议开启tokudb_directio. 2) 对数据要求不太高(允许部分数据丢失,不要求事务ACID完整性),可配置: 在此配置下,每1秒对log buffer做下fsync,可充分利用log的group commit功能,如果TokuDB挂掉,则可能会丢失最多

MySQL · 参数优化 ·RDS MySQL参数调优最佳实践

前言 很多时候,RDS用户经常会问如何调优RDS MySQL的参数,为了回答这个问题,写一篇blog来进行解释: 哪一些参数不能修改,那一些参数可以修改: 这些提供修改的参数是不是已经是最佳设置,如何才能利用好这些参数: 哪些参数可以改 细心的用户在购买RDS的时候都会看到,不同规格能够提供的最大连接数以及内存是不同的,所以这一些产品规格的限制参数:连接数.内存用户是不能够修改的,如果内存或者连接数出现了瓶颈: 内存瓶颈:实例会出现OOM,然后导致主备发生切换 连接数瓶颈:应用不能新建立连接到数

RDS MySQL参数调优最佳实践

前言 很多时候,RDS用户经常会问如何调优RDS MySQL的参数,为了回答这个问题,写一篇blog来进行解释: 哪一些参数不能修改,那一些参数可以修改: 这些提供修改的参数是不是已经是最佳设置,如何才能利用好这些参数: 哪些参数可以改 细心的用户在购买RDS的时候都会看到,不同规格能够提供的最大连接数以及内存是不同的,所以这一些产品规格的限制参数:连接数.内存用户是不能够修改的,如果内存或者连接数出现了瓶颈: 内存瓶颈:实例会出现OOM,然后导致主备发生切换 连接数瓶颈:应用不能新建立连接到数

MySQL参数log_bin_trust_function_creators介绍

  MySQL的有个参数log_bin_trust_function_creators,官方文档对这个参数的介绍.解释如下所示:     log_bin_trust_function_creators Command-Line Format --log-bin-trust-function-creators System Variable Name log_bin_trust_function_creators Variable Scope Global Dynamic Variable Yes

mysql -参数thread_cache_size优化方法 小结_Mysql

说明: 根据调查发现以上服务器线程缓存thread_cache_size没有进行设置,或者设置过小,这个值表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,增加这个值可以改善系统性能.通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用.(-->表示要调整的值) 根据物理

mysql参数之autocommit的详解

autocommit是一个改变事务提交方式参数,设置为1时,所有改变变的立即生效,也就是说为1时,语句执行完后,事务自动提交.如果设置为0时,需要通过commit或者rollback进行提交或者回滚事务. 纠正一种说法就是,set autocommit = 0时,会自动开启一个事务,准确来说是set autocommit = 0时下一个语句会自动开启一个事务. set autocommit = 0与start transaction的区别: 前者下改变事务提交方式,是自动提交还是非自动提交,设置