首页 > 数据库 >科普文:软件架构数据库系列之【MySQL状态参数:open table浅析和[ERROR] Error in accept: Two many open files】

科普文:软件架构数据库系列之【MySQL状态参数:open table浅析和[ERROR] Error in accept: Two many open files】

时间:2024-11-14 17:17:17浏览次数:3  
标签:files tables cache share 状态参数 table open 浅析

概叙

科普文:软件架构数据库系列之【MySQL状态参数:table cache源码浅析】-CSDN博客

MySQL经常会遇到Too many open files,MySQL上的open_files_limit和OS层面上设置的open file limit有什么关系?
源码中也会看到不同的数据结构,TABLE, TABLE_SHARE,跟表是什么关系?
MySQL flush tables又做了些什么,接下来梳理一下。

[ERROR] Error in accept: Two many open files

"Too many open files" 错误通常指操作系统层面的文件描述符限制已经达到。在 MySQL 的情况下,这意味着 MySQL 试图打开更多的文件(如数据文件、索引文件、二进制日志文件等),但是已达到操作系统允许同时打开的最大文件数量。

事故现场信息

错误日志

prometheus监控

服务器参数

服务器ulimit -a查看文件系统打开文件限制:100001

数据库参数

数据库参数限制都为:65535 

show global variables like '%file%';

| innodb_open_files | 65535 |

| open_files_limit | 65535 |

事故分析

1)还原事故前后业务操作,只有DTS数据迁移是新增业务

2)数据库表的个数为75000多张

3)根据报错与表的个数,并且DTS在数据迁移前需要对整个DB下表的校验,猜测是DTS在一个事务中打开了DB下面所有的表的frm,用于校验,

由于表的个数为72000张,超过了mysql系统参数innodb_open_files、open_files_limit 的限制。

但是还未超过Linux 系统参数 open files的限制。

事故解决方案

1、调整服务器参数

open files 调整为 655350

/etc/security/limits.conf

2、调整mysql参数

innodb_open_files、open_files_limit 的限制也调整为655350

注意:在修改系统文件描述符限制时,应当根据系统资源和应用需求谨慎操作,并确保有足够的权限。如果不熟悉相关配置,建议咨询系统管理员或专业人士。

调整参数据后验证

通过监控可以看到,Innodb OPen Files 已经超过了原来的65535的限制,达到了75240,error 日志中也不在报错

open table浅析

 

 数据结构

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++;

要点:

  1. MySQL server层维护了一个全局的table definition cache即table_def_cache,所以一个table_share只会创建一次,后续进行共享。
  2. 初始化table_share的过程中,调用文件系统打开frm文件,初始化完成后,关闭frm文件。
  3. 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

 

标签:files,tables,cache,share,状态参数,table,open,浅析
From: https://blog.csdn.net/Rookie_CEO/article/details/143770968

相关文章

  • [USACO07OPEN] Dining G
    和过去的自己不期而遇需要进行点边转化以限制1头牛至多只产生1的贡献点击查看代码#include<bits/stdc++.h>usingnamespacestd;vector<int>a[1005],c[1005],h[1005];intcur[1005],d[1005];ints=0,t=1000;queue<int>q;intread1(){ charcc=getchar(); while(!(......
  • 手把手教你搭建OpenDRIVE道路模型(下)
        《手把手教你搭建OpenDRIVE道路模型(上)》中,我们已经学习了ModelBase基本操作说明,本文将介绍如何搭建丰富的OpenDRIVE道路模型。信号和物体添加     为进一步实现对静态场景的丰富,软件还支持在道路上配置通用的交通标志和物体,包含交通标识与设施、植物、城镇建......
  • [OpenWRT] /dev/sda: Unknown USB bridge [0x0bda:0x9201 (0xf200)] Please specify d
     >>smartctl--testshort/dev/sdasmartctl7.22020-12-30r5155[aarch64-linux-5.10.176](localbuild)Copyright(C)2002-20,BruceAllen,ChristianFranke,www.smartmontools.org/dev/sda:UnknownUSBbridge[0x0bda:0x9201(0xf200)]Pleasespecifyde......
  • 使用 Python 和 OpenCV 实现摄像头人脸检测并截图
    概述在现代应用中,人脸检测是一项非常重要的技术,广泛应用于安全监控、身份验证等领域。本文将详细介绍如何使用Python和OpenCV库实现摄像头人脸检测并截图,并通过具体的代码示例来展示整个过程。环境准备在开始编写代码之前,确保已经安装了OpenCV库。可以使用以下命令......
  • 基于 OpenCV 的图像融合
    概述图像融合是一种常见的图像处理技术,通过将两张或多张图像按一定比例混合,生成一张新的图像。本文将介绍如何使用OpenCV实现图像融合,具体包括读取图像、调整图像大小、图像融合以及保存和显示结果图像。我们将通过一个具体的示例来展示这一过程。准备工作在开始之前,确......
  • OpenAI官方发布:利用ChatGPT提升写作的12条指南
    近日,OpenAI官方发布了学生如何利用ChatGPT提升写作的12条指南,值得深入研究学习。在如今AIGC应用爆发增长的时间点,如何充分利用生成式AI工具,如ChatGPT,有效切快速的提升写作和学习能力,成为每个学生、学者、甚至职场人必须掌握的技能之一。以下十二个操作技巧,将为您提供全新的......
  • openSUSE 环境下通过 zypper 安装软件
    操作场景为了提升您在云服务器上的软件安装效率,减少下载和安装软件的成本,腾讯云提供了zypper下载源。openSUSE操作系统和部分SLES的云服务器用户可通过zypper快速安装软件。本文档以openSUSE操作系统为例,指导您通过zypper快速安装软件。操作步骤查看软件源1.使......
  • OpenCV补充
    图像的基本表示方法1.二值图像二值图像是指仅包含黑色和白色两种颜色的图像 2.1灰色图像灰度图像有256个灰度级,用数值区间[0,255]来表示,其中255表示为纯白色,0表示为纯黑色256个灰度级的数值恰好可以用一个字节(8位二进制值)来表示   由于OpenCV没有二值图像这种......
  • 项目实战:Qt+OpenCV透视变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出
    需求  1.打开图片;  2.矫正识别角点;  3.四点对应偏移距离;  4.支持设置棋盘格的行列角点数;  5.导出结果图片; 背景  深入研究图像拼接细分支算法,产出的效果查看工具,验证算法单步思路。 相关博客  《项目实战:Qt+OpenCV透视变换工具v1.1.0(支持打开图......
  • 百度发布 AI 眼镜:全球首搭中文大模型,支持边走边问;OpenAI 联合创始人宣布回归,主抓重大
       开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(Real-TimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编......