作者简介:高鹏,笔名八怪。《深入理解MySQL主从原理》图书作者,同时运营个人公众号“MySQL学习”,持续分享遇到的有趣case以及代码解析!
一、关于参数innodb_open_files
- 如果innodb_open_files小于10(或者没有设置为0), innodb_file_per_table 没有启用的情况下默认值就是300
- 如果innodb_open_files小于10(或者没有设置为0),如果在 innodb_file_per_table开启的且table_cache_size 大于300,则innobase_open_files 为table_cache_size(table_open_cache)
- 如果innobase_open_files设置大于了open_files_limit,则爆出警告,同时如果大于table_cache_size则设置为table_cache_size(table_open_cache)
代码如下:
if (innobase_open_files < 10) {
innobase_open_files = 300;
if (srv_file_per_table && table_cache_size > 300) {
innobase_open_files = table_cache_size;
}
}
if (innobase_open_files > (long) open_files_limit) {
ib::warn() < (long) table_cache_size) {
innobase_open_files = table_cache_size;
}
}
这个参数控制的是实际的Iinnodb层同时打开的文件数量(open),当然大于了也不会报错,通过LRU链表淘汰即可。这个一点和open_files_limit是不一样的。
二、关于fil_system简述
这是一个innodb中的一个全局变量,初始化的情况下就会设置,我们可以理解为这是一个关于Innodb所有物理文件信息的一个内存空间。
<code class="language-js_darkmode__15">fil_init(srv_file_per_table ? 50000 : 5000, srv_max_n_open_files);
->fil_system->max_n_open = max_n_open;
这里的srv_max_n_open_files实际上就是我们的参数innodb_open_files,初始化完成后,会将通过数据字典打开fil_space_t和fil_node_t加入到fil_system中,同时还会中物理文件是否存在的校验,检验会先实际的open物理文件,然后进行close。检验完成后实际上fil_system就包含了所有当前文件的一个内存结构,叫做InnoDB tablespace memory cache。fil_system中包含(不限于):
- UT_LIST_BASE_NODE_T(fil_node_t) LRU 当前打开文件的LRU链表(open)状态,注意这里是fil_node_t是实际对应的文件了,但是不一定处于open状态,当需要做IO操作的时候肯定是需要进行open操作的。对于redo,ibdata和undo来讲是常驻打开的,而对于我们普通用户的表来讲则是受这个LRU链表管理的。后面我们在讨论。
- UT_LIST_BASE_NODE_T(fil_space_t) space_list 这个就是所有根据字典建立的所有fil_space_t和file_node_t的内存结构,但是需要注意的是,这里面的信息并不代表已经打开了文件(open)。
- spaces 按照space id进行hash
- name_hash 按照space的名字进行hash
- max_n_open 参数innodb_open_files设置的值
- n_open 当前打开的文件数量
fil_space_create中可以看到:
<code class="language-js_darkmode__26"> HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space);
HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(name), space);
UT_LIST_ADD_LAST(fil_system->space_list, space); //加入space_list
fil_node_create中可以看到:
<code class="language-js_darkmode__29"> UT_LIST_ADD_LAST(space->chain, node);
mutex_exit(&fil_system->mutex);
他们都是在进行fil_system的维护操作。
其中:
- fil_space_t:为一个space结构代表一个表空间其中space_id包含在其中,下面是fil_node_t来表示各个物理文件,比如我们redo文件就包含多个,对于 innodb_file_per_table的表和undo文件来讲,每个fil_space_t都代表一个space,但是file_node_t自然就只有1个了。建立函数fil_space_create。当然这里的元素还很多,比如和hash结构相对应的元素,IO相关的元素等等。
- fil_node_t:为一个具体文件的表示,其中name就是文件所在的位置,is_open则代表是否已经打开了(open),还包含一些和IO相关的属性,chain和LRU则分别代表自己在space和fil_system LRU链表中所在的位置。建立函数为fil_node_create。
下面我们通过fil_system这个结构,来访问所有建立的cache对象。
<code class="language-js_darkmode__37">(gdb) p fil_system->space_list->start->name
$11 = 0x3378858 "innodb_system"
(gdb) p fil_system->space_list->start->chain
$17 = {count = 1, start = 0x3378888, end = 0x3378888, node = &fil_node_t::chain, init = 51966}
(gdb) p fil_system->space_list->start->space_list->next->name
$12 = 0x3378e38 "innodb_redo_log"
(gdb) p fil_system->space_list->start->space_list->next->chain->start->name
$21 = 0x3378f48 "./ib_logfile0"
gdb) p fil_system->space_list->start->space_list->next->chain
$19 = {count = 3, start = 0x3378e68, end = 0x33791a8, node = &fil_node_t::chain, init = 51966}
(gdb) p fil_system->space_list->start->space_list->next->space_list->next->name
$13 = 0x337dd98 "innodb_undo001"
(gdb) p fil_system->space_list->start->space_list->next->space_list->next->space_list->next->name
$14 = 0x337e8d8 "innodb_undo002"
(gdb) p fil_system->space_list->start->space_list->next->space_list->next->space_list->next->space_list->next->name
$15 = 0x337edc8 "innodb_undo003"
总的说来,当正常启动的时候,所有文件都会进行打开测试,但是随后关闭,同时加入到fil_system中,形成一个内存信息叫做InnoDB tablespace memory cache,后面我们要打开的文件时候就依赖于它。但是我们ibdata,undo,redo是常驻打开的。但是有一点当我们设置了innodb_force_recovery>3参数后不会做这样的检测和加入操作,随后会出现一个报错这个后面再说。这里只是简单的将fil_system的space_list和LRU画一下,如下图。不涉及hash结构,实际上查找的时候一般通过space id和name通过hash结构进行快速查找。
三、初始化关于文件测试打开和关闭
(gdb) bt
#0 0x00007ffff7bcded0 in open64 () from /lib64/libpthread.so.0
#1 0x0000000001a4938e in os_file_create_simple_no_error_handling_func (name=0x338ba88 "./woaini/im10.ibd", create_mode=51, access_type=333, read_only=true, success=0x7fffffff336f)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/os/os0file.cc:3931
#2 0x0000000001ccb07c in pfs_os_file_create_simple_no_error_handling_func (key=..., name=0x338ba88 "./woaini/im10.ibd", create_mode=51, access_type=333, read_only=true,
success=0x7fffffff336f, src_file=0x2353750 "/opt/percona-server-locks-detail-5.7.22/storage/innobase/fsp/fsp0file.cc", src_line=122)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/include/os0file.ic:120
#3 0x0000000001ccbc3f in Datafile::open_read_only (this=0x7fffffff3520, strict=true) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fsp/fsp0file.cc:122
#4 0x0000000001cb1084 in fil_ibd_open (validate=true, fix_dict=true, purpose=FIL_TYPE_TABLESPACE, id=40, flags=33, space_name=0x332b438 "woaini/im10",
path_in=0x332b4c8 "./woaini/im10.ibd") at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:3939
#5 0x0000000001c85ccc in dict_check_sys_tables (validate=true) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:1622
#6 0x0000000001c85fe1 in dict_check_tablespaces_and_store_max_id (validate=true) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:1682
#7 0x0000000001b606a2 in innobase_start_or_create_for_mysql () at /opt/percona-server-locks-detail-5.7.22/storage/innobase/srv/srv0start.cc:2433
#8 0x0000000001972854 in innobase_init (p=0x2e64a20) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/handler/ha_innodb.cc:4409
#9 0x0000000000f531e1 in ha_initialize_handlerton (plugin=0x2fef538) at /opt/percona-server-locks-detail-5.7.22/sql/handler.cc:871
#10 0x000000000159801a in plugin_initialize (plugin=0x2fef538) at /opt/percona-server-locks-detail-5.7.22/sql/sql_plugin.cc:1252
#11 0x0000000001598c80 in plugin_register_builtin_and_init_core_se (argc=0x2d7c530 , argv=0x2e62f58) at /opt/percona-server-locks-detail-5.7.22/sql/sql_plugin.cc:1615
#12 0x0000000000eb892b in init_server_components () at /opt/percona-server-locks-detail-5.7.22/sql/mysqld.cc:4333
#13 0x0000000000eba1ca in mysqld_main (argc=30, argv=0x2e62f58) at /opt/percona-server-locks-detail-5.7.22/sql/mysqld.cc:5110
#14 0x0000000000eb13bd in main (argc=4, argv=0x7fffffffe5f8) at /opt/percona-server-locks-detail-5.7.22/sql/main.cc:25
(gdb) c
Continuing.
Breakpoint 2, fil_space_create (name=0x332b438 "woaini/im10", id=40, flags=33, purpose=FIL_TYPE_TABLESPACE) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:1329
1329 ut_ad(fil_system);
(gdb) bt
#0 fil_space_create (name=0x332b438 "woaini/im10", id=40, flags=33, purpose=FIL_TYPE_TABLESPACE) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:1329
#1 0x0000000001cb1e11 in fil_ibd_open (validate=true, fix_dict=true, purpose=FIL_TYPE_TABLESPACE, id=40, flags=33, space_name=0x332b438 "woaini/im10",
path_in=0x332b4c8 "./woaini/im10.ibd") at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:4169
#2 0x0000000001c85ccc in dict_check_sys_tables (validate=true) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:1622
#3 0x0000000001c85fe1 in dict_check_tablespaces_and_store_max_id (validate=true) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:1682
#4 0x0000000001b606a2 in innobase_start_or_create_for_mysql () at /opt/percona-server-locks-detail-5.7.22/storage/innobase/srv/srv0start.cc:2433
#5 0x0000000001972854 in innobase_init (p=0x2e64a20) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/handler/ha_innodb.cc:4409
#6 0x0000000000f531e1 in ha_initialize_handlerton (plugin=0x2fef538) at /opt/percona-server-locks-detail-5.7.22/sql/handler.cc:871
#7 0x000000000159801a in plugin_initialize (plugin=0x2fef538) at /opt/percona-server-locks-detail-5.7.22/sql/sql_plugin.cc:1252
#8 0x0000000001598c80 in plugin_register_builtin_and_init_core_se (argc=0x2d7c530 , argv=0x2e62f58) at /opt/percona-server-locks-detail-5.7.22/sql/sql_plugin.cc:1615
#9 0x0000000000eb892b in init_server_components () at /opt/percona-server-locks-detail-5.7.22/sql/mysqld.cc:4333
#10 0x0000000000eba1ca in mysqld_main (argc=30, argv=0x2e62f58) at /opt/percona-server-locks-detail-5.7.22/sql/mysqld.cc:5110
#11 0x0000000000eb13bd in main (argc=4, argv=0x7fffffffe5f8) at /opt/percona-server-locks-detail-5.7.22/sql/main.cc:25
(gdb) c
Continuing.
Breakpoint 5, 0x00007ffff7bcd790 in close () from /lib64/libpthread.so.0
(gdb) bt
#0 0x00007ffff7bcd790 in close () from /lib64/libpthread.so.0
#1 0x0000000001a4965b in os_file_close_func (file=18) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/os/os0file.cc:4043
#2 0x0000000001ccb2d1 in pfs_os_file_close_func (file=..., src_file=0x2353750 "/opt/percona-server-locks-detail-5.7.22/storage/innobase/fsp/fsp0file.cc", src_line=192)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/include/os0file.ic:204
#3 0x0000000001ccbf91 in Datafile::close (this=0x7fffffff3520) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fsp/fsp0file.cc:192
#4 0x0000000001ccb8b5 in Datafile::shutdown (this=0x7fffffff3520) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fsp/fsp0file.cc:60
#5 0x0000000001cbaf98 in Datafile::~Datafile (this=0x7fffffff3520, __in_chrg=) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/include/fsp0file.h:137
#6 0x0000000001cb1fdd in fil_ibd_open (validate=true, fix_dict=true, purpose=FIL_TYPE_TABLESPACE, id=40, flags=33, space_name=0x332b438 "woaini/im10",
path_in=0x332b4c8 "./woaini/im10.ibd") at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:4200
#7 0x0000000001c85ccc in dict_check_sys_tables (validate=true) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:1622
#8 0x0000000001c85fe1 in dict_check_tablespaces_and_store_max_id (validate=true) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:1682
#9 0x0000000001b606a2 in innobase_start_or_create_for_mysql () at /opt/percona-server-locks-detail-5.7.22/storage/innobase/srv/srv0start.cc:2433
#10 0x0000000001972854 in innobase_init (p=0x2e64a20) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/handler/ha_innodb.cc:4409
#11 0x0000000000f531e1 in ha_initialize_handlerton (plugin=0x2fef538) at /opt/percona-server-locks-detail-5.7.22/sql/handler.cc:871
#12 0x000000000159801a in plugin_initialize (plugin=0x2fef538) at /opt/percona-server-locks-detail-5.7.22/sql/sql_plugin.cc:1252
#13 0x0000000001598c80 in plugin_register_builtin_and_init_core_se (argc=0x2d7c530 , argv=0x2e62f58) at /opt/percona-server-locks-detail-5.7.22/sql/sql_plugin.cc:1615
#14 0x0000000000eb892b in init_server_components () at /opt/percona-server-locks-detail-5.7.22/sql/mysqld.cc:4333
#15 0x0000000000eba1ca in mysqld_main (argc=30, argv=0x2e62f58) at /opt/percona-server-locks-detail-5.7.22/sql/mysqld.cc:5110
#16 0x0000000000eb13bd in main (argc=4, argv=0x7fffffffe5f8) at /opt/percona-server-locks-detail-5.7.22/sql/main.cc:25
可以看到在析构的时候进行了文件的关闭,这是在初始化的情况,会进行测试。如果们稍微浏览一下dict_check_sys_tables函数,则可以看到这里访问了3个数据字典SYS_TABLESPACES/SYS_DATAFILES/SYS_TABLESPACES,具体的文件位置所在地就在SYS_DATAFILES中。
四、Innodb文件的打开和关闭。
我们前面说的只是初始化测试的情况下打开和关闭,那么在正常情况下是如何打开和关闭文件的呢?简单的说需要进行物理IO操作的时候就会打开文件,当然一个表的数据文件只会打开一次。(比如进行统计数据收集)
正常脏数据刷盘,物理IO的情况下,重新打开,在fil_node_open_file的末尾加入到UT_LIST_ADD_FIRST(fil_system->LRU, node)链表中代表文件处于打开状态
Breakpoint 4, 0x00007ffff7bcded0 in open64 () from /lib64/libpthread.so.0
(gdb) bt
#0 0x00007ffff7bcded0 in open64 () from /lib64/libpthread.so.0
#1 0x0000000001a48e03 in os_file_create_func (name=0x33963e8 "./woaini/im119.ibd", create_mode=51, purpose=61, type=100, read_only=false, success=0x7fffdc0ba737)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/os/os0file.cc:3792
#2 0x0000000001ca5374 in pfs_os_file_create_func (key=..., name=0x33963e8 "./woaini/im119.ibd", create_mode=51, purpose=61, type=100, read_only=false, success=0x7fffdc0ba737,
src_file=0x234bf90 "/opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc", src_line=903)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/include/os0file.ic:174
#3 0x0000000001ca8ae4 in fil_node_open_file (node=0x3396308) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:903
#4 0x0000000001cb4ee5 in fil_node_prepare_for_io (node=0x3396308, system=0x3307f58, space=0x3395ff8) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:5363
#5 0x0000000001cb5c60 in _fil_io (type=..., sync=false, page_id=..., page_size=..., byte_offset=0, len=16384, buf=0x7fffe4504000, message=0x7fffe3645910, trx=0x0, should_buffer=false)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:5691
#6 0x0000000001c350af in buf_dblwr_write_block_to_datafile (bpage=0x7fffe3645910, sync=false) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0dblwr.cc:1165
#7 0x0000000001c354d1 in buf_dblwr_flush_buffered_writes (dblwr_partition=1) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0dblwr.cc:1277
#8 0x0000000001c40635 in buf_flush_end (buf_pool=0x33082b8, flush_type=BUF_FLUSH_LIST, flushed_page_count=3)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:2007
#9 0x0000000001c407f0 in buf_flush_do_batch (buf_pool=0x33082b8, type=BUF_FLUSH_LIST, min_n=200, lsn_limit=18446744073709551615, n_processed=0x7fffdc0bb978)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:2077
#10 0x0000000001c40c12 in buf_flush_lists (min_n=200, lsn_limit=18446744073709551615, n_processed=0x7fffdc0bba08)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:2216
#11 0x0000000001c4426f in buf_flush_page_cleaner_coordinator (arg=0x0) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:3366
#12 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#13 0x00007ffff66748dd in clone () from /lib64/libc.so.6
那么说明时候关闭我们打开的文件呢。其实就是根据我们打开的文件数是否大于了fil_system的max_n_open,如果超过了,则通过LRU 淘汰一部分打开的文件,供新打开的文件使用。比如这里就是刷盘操作遇到了这种情况,进行文件关闭:
(gdb) bt
#0 0x00007ffff7bcd790 in close () from /lib64/libpthread.so.0
#1 0x0000000001a4965b in os_file_close_func (file=33) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/os/os0file.cc:4043
#2 0x0000000001ca546e in pfs_os_file_close_func (file=..., src_file=0x234bf90 "/opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc", src_line=942)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/include/os0file.ic:204
#3 0x0000000001ca8db0 in fil_node_close_file (node=0x33de948) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:942
#4 0x0000000001ca8fc0 in fil_try_to_close_file_in_LRU (print_info=false) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:993
#5 0x0000000001ca9428 in fil_mutex_enter_and_prepare_for_io (space_id=143) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:1114
#6 0x0000000001cb58ba in _fil_io (type=..., sync=false, page_id=..., page_size=..., byte_offset=0, len=16384, buf=0x7fffe4504000, message=0x7fffe3645910, trx=0x0, should_buffer=false)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/fil/fil0fil.cc:5613
#7 0x0000000001c350af in buf_dblwr_write_block_to_datafile (bpage=0x7fffe3645910, sync=false) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0dblwr.cc:1165
#8 0x0000000001c354d1 in buf_dblwr_flush_buffered_writes (dblwr_partition=1) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0dblwr.cc:1277
#9 0x0000000001c40635 in buf_flush_end (buf_pool=0x33082b8, flush_type=BUF_FLUSH_LIST, flushed_page_count=3)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:2007
#10 0x0000000001c407f0 in buf_flush_do_batch (buf_pool=0x33082b8, type=BUF_FLUSH_LIST, min_n=200, lsn_limit=18446744073709551615, n_processed=0x7fffdc0bb978)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:2077
#11 0x0000000001c40c12 in buf_flush_lists (min_n=200, lsn_limit=18446744073709551615, n_processed=0x7fffdc0bba08)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:2216
#12 0x0000000001c4426f in buf_flush_page_cleaner_coordinator (arg=0x0) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/buf/buf0flu.cc:3366
#13 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0#14 0x00007ffff66748dd in clone () from /lib64/libc.so.6
这里我们稍微看一下fil_mutex_enter_and_prepare_for_io 中的这一段:
<code class="language-js_darkmode__126"> if (fil_system->n_open < fil_system->max_n_open) {
return;
}
/* If the file is already open, no need to do anything; if the
space does not exist, we handle the situation in the function
which called this function. */
if (space == NULL || UT_LIST_GET_FIRST(space->chain)->is_open) {
return;
} if (count > 1) {
print_info = true;
}
/* Too many files are open, try to close some */
do {
success = fil_try_to_close_file_in_LRU(print_info);
} while (success
&& fil_system->n_open >= fil_system->max_n_open);
这里不需要太多解释也就是根据fil_system->n_open < fil_system->max_n_open进行判断,其中fil_system->max_n_open就是我们的参数innodb_open_files参数,如果超过了则根据LRU链表进行打开文件的关闭。
当然如果想要操作表的物理文件的时候,那么首先要去确认是否这个表的物理信息已经存在于fil_system内存空间。我们前面说过,实际上innodb初始化的情况下就会将所有的物理文件信息加载到fil_system中,当open table的时候会也会去检查是否fil_system中包含了所要打开表的物理文件信息,也就是dict_load_tablespace 下的fil_space_for_table_exists_in_mem函数。如下:
#0 dict_load_tablespace (table=0x7fff94021ce0, heap=0x7fff94c5c188, ignore_err=DICT_ERR_IGNORE_NONE) at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:3054
#1 0x0000000001c8a0fc in dict_load_table_one (name=..., cached=true, ignore_err=DICT_ERR_IGNORE_NONE, fk_tables=std::deque with 0 elements)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:3265
#2 0x0000000001c8954c in dict_load_table (name=0x7fffdae50710 "woaini/im", cached=true, ignore_err=DICT_ERR_IGNORE_NONE)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0load.cc:3022
#3 0x0000000001c6bcdd in dict_table_open_on_name (table_name=0x7fffdae50710 "woaini/im", dict_locked=0, try_drop=1, ignore_err=DICT_ERR_IGNORE_NONE)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/dict/dict0dict.cc:1261
#4 0x0000000001977eac in ha_innobase::open_dict_table (table_name=0x7fff94979328 "./woaini/im", norm_name=0x7fffdae50710 "woaini/im", is_partition=false, ignore_err=DICT_ERR_IGNORE_NONE)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/handler/ha_innodb.cc:6993
#5 0x0000000001976f5c in ha_innobase::open (this=0x7fff949437f0, name=0x7fff94979328 "./woaini/im", mode=2, test_if_locked=2)
at /opt/percona-server-locks-detail-5.7.22/storage/innobase/handler/ha_innodb.cc:6624
#6 0x0000000000f56ff4 in handler::ha_open (this=0x7fff949437f0, table_arg=0x7fff94942e30, name=0x7fff94979328 "./woaini/im", mode=2, test_if_locked=2)
at /opt/percona-server-locks-detail-5.7.22/sql/handler.cc:2946
#7 0x0000000001663ca1 in open_table_from_share (thd=0x7fff94000b70, share=0x7fff94978f50, alias=0x7fff94005bf8 "im", db_stat=39, prgflag=8, ha_open_flags=0, outparam=0x7fff94942e30,
is_create_table=false) at /opt/percona-server-locks-detail-5.7.22/sql/table.cc:3459
#8 0x00000000014e0421 in open_table (thd=0x7fff94000b70, table_list=0x7fffdae515b0, ot_ctx=0x7fffdae51280) at /opt/percona-server-locks-detail-5.7.22/sql/sql_base.cc:3602
#9 0x00000000014e2f54 in open_and_process_table (thd=0x7fff94000b70, lex=0x7fff940031a0, tables=0x7fffdae515b0, counter=0x7fff94003260, flags=1024, prelocking_strategy=0x7fffdae51380,
has_prelocking_list=false, ot_ctx=0x7fffdae51280) at /opt/percona-server-locks-detail-5.7.22/sql/sql_base.cc:5213
#10 0x00000000014e4067 in open_tables (thd=0x7fff94000b70, start=0x7fffdae51340, counter=0x7fff94003260, flags=1024, prelocking_strategy=0x7fffdae51380)
at /opt/percona-server-locks-detail-5.7.22/sql/sql_base.cc:5831
#11 0x00000000014e5395 in open_tables_for_query (thd=0x7fff94000b70, tables=0x7fffdae515b0, flags=1024) at /opt/percona-server-locks-detail-5.7.22/sql/sql_base.cc:6606
#12 0x00000000015d0197 in mysqld_list_fields (thd=0x7fff94000b70, table_list=0x7fffdae515b0, wild=0x7fff94006530 "") at /opt/percona-server-locks-detail-5.7.22/sql/sql_show.cc:1134
#13 0x000000000156701b in dispatch_command (thd=0x7fff94000b70, com_data=0x7fffdae51d90, command=COM_FIELD_LIST) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1666
#14 0x00000000015655c5 in do_command (thd=0x7fff94000b70) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1021
#15 0x00000000016a635c in handle_connection (arg=0x3501e60) at /opt/percona-server-locks-detail-5.7.22/sql/conn_handler/connection_handler_per_thread.cc:312
#16 0x00000000018ce0b2 in pfs_spawn_thread (arg=0x34be470) at /opt/percona-server-locks-detail-5.7.22/storage/perfschema/pfs.cc:2190
#17 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0#18 0x00007ffff66748dd in clone () from /lib64/libc.so.6
但是我们一旦将innodb_force_recovery>3打开则不会加载物理信息到fil_system,那么这么带来的后果就是,在open table的时候会出现一个报错,然后重新加载fil_space_t和fil_node_t,如下:
<code class="language-js_darkmode__152">fil_space_for_table_exists_in_mem
->fil_space_get_by_id
->HASH_SEARCH
报错如下:
这个问题不用太关注,重新加载物理信息到fil_system即可。
五、关于统计值
- Innodb_num_open_files:和fil_system->n_open有同样的值,显然这个就是Innodb当前打开的文件数量。因为我们知道会通过它来进行比较,如果打开的fil_system->n_open 大于 fil_system->max_n_ope就会进行通过LRU链表进行的文件关闭。增加:
<code class="language-js_darkmode__160">fil_node_open_file
fil_system->n_open++;
fil_n_file_opened++;
减少:
<code class="language-js_darkmode__163">fil_node_close_file
fil_system->n_open--;
fil_n_file_opened--;
- Open_files:MySQL层当前打开的文件数,来自my_file_opened,close的时候会减去1
- Opened_files:MySQL总共打开文件的总数,来自my_file_total_opened,累计值,只增不减。
这样的话我们统计文件总数的时候,应该考虑Innodb_num_open_files+Open_files。而这个总数如果接近进程能够打开的最大文件数的话则可能出现报错。关于MySQLD进程能够打开的最大文件数量,参考文章:https://www.jianshu.com/p/98a43397ea23