MySQL open table
背景:
MySQL经常会遇到Too many open files,MySQL上的open_files_limit和OS层面上设置的open file limit有什么关系?
源码中也会看到不同的数据结构,TABLE, TABLE_SHARE,跟表是什么关系?
MySQL flush tables又做了些什么,这几个东西放在一起,就会比较迷惑,下面进行梳理一下:
1 数据结构
table: MySQL为每一个查询sql中的表建一个TABLE对象
table_share: MySQL为每一张表建立一个table_share对象,与frm文件对应
handler: 对应于每个TABLE对象,innodb引擎创建一个handler
dict_table_t: innodb为每一个ibd表load一个数据字典对象
简略图如下:
1. open table的过程
测试sql:select * from xpchild.pp
函数调用栈:
open_and_lock_tables
open_tables
open_and_process_table
open_table:打开一个table,并赋值给table_list->table
下面进入核心的逻辑:
开始锁lock_open:
1.1 table_share:
首先根据db&&table_name创建一个table_share.
函数调用栈:
get_table_share_with_discover: 创建或者查找table_share对象。
get_table_share:如果全局cache:table_def_cache中存在,就直接使用,如果不存在,就创建一个table_share
alloc_table_share: 如果不存在,先分配一个share的对象。
open_table_def: 打开frm文件。
mysql_file_open: my_open打开
inline_mysql_file_close: my_close关闭
share->ref_count++;
要点:
- MySQL server层维护了一个全局的table definition cache即table_def_cache,所以一个table_share只会创建一次,后续进行共享。
- 初始化table_share的过程中,调用文件系统打开frm文件,初始化完成后,关闭frm文件。
- share结构中ref_count来表示有多少个table关联
1.2 打开table:
open_table_from_share
step1: 初始化table中的变量,包括file handler (get_new_handler(share->db_type()))
step2: 添加各种索引,字段结构
step3: file->ha_open:ha_innobase::open 为innodb的table创建一个handler。
要点:
1. 在open table的过程中,innodb会创建一个handler,并打开ibd文件,初始化dict_table结构。
释放锁lock_open
1.3 close table:
sql执行结束之前,会调用close table
close_open_tables(thd)
table_def_unuse_table:
要点:
1.table_share维护了两个双向链表used_tables,free_tables,当close table的时候,
1.1 table->in_use=NULL,
1.2 把table从used_tables移除
1.3 加入到free_tables
2.全局参数table_cache_size,已经当前table_cache_count计数控制cache的置换策略
2. 再次执行sql
因为第一步已经完成了table_share的创建,并且cache了table,再次执行sql时,open table的过程就比较简单:
2.1: get_table_share:从cache中直接获取table_share对象
2.2:open_table_from_share:从s->free_tables中获取缓存的可以使用的table,然后增加ref计数。
if (!share->free_tables.is_empty())
table= share->free_tables.front();
++share->ref_count;
3 系统计数:
opened_tables:系统在open_table_from_share中,对新建的table,进行thd->status_var.opened_tables++计数。
opened_shares: 系统在 open_table_def的函数中,对于首次进行open的table_share进行thd->status_var.opened_shares++计数
注: 所以当系统的status:open_tables增长比较多的时候,可以适当的增加table_cache_size,用于缓存更多的table,毕竟open table的开销还是不小的。
4 status统计
使用show status命令,跟open有关的几个:
{"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH}
注释:【全局变量】MySQL和innodb通过文件系统打开的文件的计数,这里包括了所有的文件,binlog,relay,alert,slow log等。
{"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC},
注释:【全局变量】server当前打开的table_share数量,等于table_def_cache.records的数量
{"Open_tables", (char*) &show_open_tables, SHOW_FUNC}
注释:【全局变量】 server当前打开的table数量,server维护了一个全局变量table_cache_count
{"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH}
注释:【全局变量】 启动以来打开过的文件的总数
{"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}
注释: 【线程变量】 在真正open_table_from_share的过程中,累计计数
{"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}
注释: 【线程变量】 在真正打开share的时候,累计计数
注: use test的过程:
在use test的过程中,会轮询把test db下的所有表的table_share都创建一遍,即open所有的frm文件,并创建table_share对象,最后close 所有的frm文件。
为了方便调试,写了一个进程监控的程序:pidmon.py
在gdb的时候,可以看到mysqld进程打开的所有文件:
Too many open files:
这里包括了server层的open frm,和innodb层open ibd的时候,当打开的文件超过limit限制,就会报这个错误。
但这个限制牵涉到两个参数:
一个是MySQL配置的open_files_limit
一个是OS层配置的进程的open file limit
下一篇:
flush tables究竟做了什么:close了server层创建的所有的table_share和table。
MySQL open table的更多相关文章
- MySQL Create Table创建表
表的创建命令需要: 表的名称 字段名称 定义每个字段(类型.长度等) 语法 下面是通用的SQL语法用来创建MySQL表: CREATE TABLE table_name (column_name co ...
- 【转】MySQL Temporary Table相关问题的探究
本文转载自:http://itindex.net/detail/10901-mysql-temporary-table 问题的引入 让我们先来观察几条非常简单的MySQL语句: mysql> c ...
- mysql create table - data_type length -- clwu
mysql create table 时,有时需要指定 data_type length http://dev.mysql.com/doc/refman/5.5/en/create-table.ht ...
- MySQL create table 语法
MySQL中create table语句的基本语法是: CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definitio ...
- MySQL ALTER TABLE: ALTER vs CHANGE vs MODIFY COLUMN
ALTER COLUMN 语法: ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} 作用: 设置或删除列的默认值.该操作会直接修 ...
- MySQL DROP TABLE操作以及 DROP 大表时的注意事项【转】
删表 DROP TABLE Syntax DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCAD ...
- linux下apt安装mysql导致mysql.user table is damaged
笔者在ubuntu下用 apt install mysql-server类似的命令安装mysql, 安装了最新版的mysql5.7,覆盖了操作系统内置的数据库mysql系统库. 最初启动mysql出错 ...
- mysql中Table is read only错误解决方法
今天再我把数据库data 拷贝到linux 下运行程序 ”mysql中Table is read only的解决“ 出现这样的问题,查询资料. linux下执行如下命令即可 #mysqladmin - ...
- MySQL check table/optimize table/analyze table/REPAIR TABLE
MySQL check table/optimize table/analyze table/REPAIR TABLE 转自:https://www.cnblogs.com/datastack/p/3 ...
- MySQL: OPTIMIZE TABLE: Table does not support optimize, doing recreate + analyze instead
show create table history;-------------------------- CREATE TABLE `foo` ( `itemid` bigint(20) unsig ...
随机推荐
- HTML 中的字符集、ASCII、 ISO-8859-1、符号之间的关系和 HTML URL 编码注意的事项
一.HTML 实体 1.什么是HTML 实体? 在 HTMl 中,某些字符是保留的.小于号 (<) 和 大于号 (>), 浏览器会误认为是标签 如果希望正确地显示预留字符,必须在 HTML ...
- Node.js之【正则表达式函数之match、test、exec、search、split、replace使用详解】
1. Match函数 使用指定的正则表达式函数对字符串惊醒查找,并以数组形式返回符合要求的字符串 原型:stringObj.match(regExp) 参数: stringObj 必选项,需要去进行匹 ...
- [译]Java Thread wait, notify和notifyAll示例
Java Thread wait, notify和notifyAll示例 Java上的Object类定义了三个final方法用于不同线程间关于某资源上的锁状态交互,这三个方法是:wait(), not ...
- 用CSS3写的小案例-图片缩放隐藏内容显示
思路分析 (1).搭建界面 (2).鼠标移到图片的时候,放大显示 (3).鼠标移入到当前的li标签里面找到后面的div让其显示出来 <!DOCTYPE html> <html lan ...
- php 字母大小写转换的函数
分享下,在php编程中,将字母大小写进行转换的常用函数. 1.将字符串转换成小写strtolower(): 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式放回这个字符串 2.将字符转成大 ...
- java 中的this关键字的几种用法
转自:http://blog.csdn.net/anmei2010/article/details/4091227 1. 当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在 ...
- zhuan: ubuntu 安装 apache2
安装 用 sudo apt-get install apache2 sudo /etc/init.d/apache2 restart 如果发现错误: 以下from:http://cache.baid ...
- Beaglebone Back学习三(开发环境搭建)
开发环境搭建 1 Ubuntu环境搭建 2 Window环境搭建 3 开发板环境搭建 1 Ubuntu环境搭建 (1)安装必要的网络工具 samba nfs tftp vmware-tools sam ...
- asp.net 运行时, 报控件不存在
Asp.net 运行时,报控件不存在,但系统中确实加入了控件z, 但是生成网站的时候,报控件不存在,输入代码的时候,this.edtxx.Text 确实可以输入 原因: 系统修改的时候,作了一个备份, ...
- LINQ to XML学习笔记
一.XML基础知识 1.XML:可扩展标记语言 Extensible Markup Language ,提供了一种保存数据的格式,数据可以通过这种格式很容易地在不同的应用程序之间实现共享. 2.使用X ...