Linux会对用户所占用的系统资源进行限制,MySQL运行在Linux系统下也会受此限制。
查看当前系统的所有限制值
shell>ulimit -a
设置可以同时打开的最大文件数,默认为1024,如不修改打开文件数过多会出现too many open files错误。
shell>ulimit -n
设置最大可用进程数
shell>ulimit -u
一般可通过修改/etc/security/limits.conf文件进行配置。
shell>more /etc/security/limits.conf
* soft nproc 20480
* hard nproc 20480
* soft nofile 65535
* hard nofile 65535
MySQL打开文件限制
mysql>show variables like '%open\_%'
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| innodb_open_files | 4096 |
| open_files_limit | 65535 |
| table_open_cache | 2048 |
| table_open_cache_instances | 1 |
+----------------------------+-------+
4 rows in set (0.00 sec)
open_files_limit : *** 作系统允许mysqld打开的文件数量,服务器运行时该变量为系统实际允许打开的值,和启动服务器指定的参数可能不一致。如果该值为0,表示不允许MySQL修改打开的文件数量。
有效的open_files_limit值是基于系统启动指定的open_files_limit,max_connections和table_open_cache计算得到,服务器将会获取三个指标中最大的值,如果三者指标都没有指定,服务器将获得os允许的最大值。
1) 10 + max_connections + (table_open_cache * 2)
2) max_connections * 5
3) 启动时设定的open_files_limit,如果没有指定默认为5000
innodb_open_files:指定MySQL可同时打开.ibd文件的最大个数,最小为10,默认300。此选项只针对InnoDB表打开的.ibd文件描述符,独立于open_files_limit。
table_open_cache:所有线程打开表的数目。它的作用就是缓存表文件描述符,降低打开关闭表的频率, 如果这个参数设置得过小,就不得不关闭一些已打开的表以便为缓存新表,从而出现频繁的打开关闭MyISAM表文件的情况,而INNODB表的打开不受这个参数控制,而是放到其数据字典当中,即在ibd文件中。当Opened_tables状态值较大,且不经常使用FLUSH TABLES 关闭并重新打开表,就需要增加该值。
table_open_cache_instances:表缓存实例数,为通过减小会话间争用提高扩展性,表缓存会分区为table_open_cache/table_open_cache_instances大小的较小的缓存实例。DML语句会话只需要锁定所在缓存实例,这样多个会话访问表缓存时就可提升性能(DDL语句仍会锁定整个缓存)。默认该值为1,当16核以上可设置为8或16。
table_definition_cache:缓存表定义(.frm)文件的数量。如果表较多,可以增大该值加快打开表。与一般表缓存不同,表定义缓存不占用文件描述符,占用空间也小。最小为400,上线为2000,默认为:
400 + (table_open_cache / 2)。如果打开表数量高于table_definition_cache,则会通过LRU机制搜索表空间LRU文件列表并刷新列表。对于InnoDB,打开文件的限制为max(table_definition_cache, innodb_open_files)。
MySQL文件打开状态
mysql>show global status like '%open%'
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Com_ha_open | 0 |
| Com_show_open_tables | 1 |
| Innodb_num_open_files | 19 |
| Open_files | 3 |
| Open_streams | 0 |
| Open_table_definitions | 8 |
| Open_tables | 8 |
| Opened_files | 509 |
| Opened_table_definitions | 116 |
| Opened_tables | 90 |
| Slave_open_temp_tables | 0 |
| Table_open_cache_hits | 3254 |
| Table_open_cache_misses | 90 |
| Table_open_cache_overflows | 0 |
+----------------------------+-------+
14 rows in set (0.00 sec)
Open_table_definitions:代表当前缓存了多少.frm文件。
Opened_table_definitions:代表自MySQL启动后,缓存了.frm文件的数量。 需要注意的是.frm文件是MySQL用于存放表结构的文件,
对应myisam和innodb存储引擎都必须有的,可以通过show open tables 查看 这2个变量的值。
Open_tables:代表当前打开的表个数
Opened_tables:代表自MySQL启动后,打开过的表个数,如该值过大,可能是table_open_cache设置太小。
Open_files:打开文件的个数。服务器层打开的一般文件,不包含sockets 或 pipes类型文件,也不包含内部函数打开的文件。
Opened_files:通过使用my_open()系统函数打开的文件数。
Table_open_cache_hits:打开表缓存查找的命中数。
Table_open_cache_misses:打开表缓存查找的未命中数。
Table_open_cache_overflows:打开表缓存溢出数。
MySQL如何打开关闭表
由于MySQL是多线程的,因此可能存在多个会话同时根据指定表进行查询。为解决同一个表在不同会话状态不一致,该表会由每个会话独立的打开,这样MySQL会消耗内存但会提高性能。
table_open_cache同时会跟max_connections相关。如200个并发连接线程,指定的表缓存至少为200*N,N为每个连接关联的最大表数量。
以下几种情况MySQL会关闭未使用的表并将其从表缓存中删除:
表缓存已满,线程将要打开不在缓存中的表。
缓存中的表多于table_open_cache且缓存中的表不被任何线程使用。
当发生表刷新 *** 作(flush tables)
当表缓存满后,服务器将执行以下 *** 作:
当前不使用的表将被释放,先释放最近最少使用的表
当新表需要被打开,但是缓存已满且无表可以被释放,服务器将会根据需要临时扩展缓存,当临时扩展缓存中的表从使用变为未使用状态,表将被关闭,扩充的临时缓存将被释放。
文件打开常见问题
数据库报错:
[ERROR] /opt/mysql/bin/mysqld: Can't open file: './tpcc/sbtest98.frm' (errno: 24 - Too many open files)
查看os最大允许打开数
shell>ulimit -n
65535
查看数据库打开设定最大打开文件数
mysql>show global variables like 'open_files_limit'
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| open_files_limit | 500 |
+------------------+-------+
1 row in set (0.00 sec)
查看当前数据库已经打开的文件描述符
shell>ll /proc/24012/fd | wc
501 5507 41673
调整open_files_limit设定并重启生效。
1、找回表结构,如果表结构没有丢失直接到下一步\x0d\x0a\x0d\x0aa、先创建一个数据库,这个数据库必须是没有表和任何 *** 作的。\x0d\x0a\x0d\x0ab、创建一个表结构,和要恢复的表名是一样的。表里的字段无所谓。一定要是innodb引擎的。CREATE TABLE `weibo_qq0`( `weiboid` bigint(20)) ENGINE=InnoDB DEFAULT CHARSET=utf8\x0d\x0a\x0d\x0ac、关闭mysql, service mysqld stop\x0d\x0a\x0d\x0ad、用需要恢复的frm文件覆盖刚新建的frm文件\x0d\x0a\x0d\x0ae、修改my.ini 里 innodb_force_recovery=1 , 如果不成修改为 2,3,4,5,6。\x0d\x0a\x0d\x0af、 启动mysql,service mysqld startshow create table weibo_qq0 就能li到表结构信息了。\x0d\x0a\x0d\x0a2、找回数据。记得上面把 innodb_force_recovery改掉了,需要注释掉,不然恢复模式不好 *** 作。 这里有个关键的问题,就是innodb里的任何数据 *** 作都是一个日志的记录点。也就是如果我们需要数据恢复,必须把之前的表的数据的日志记录点添加到一致。\x0d\x0a\x0d\x0aa、建立一个数据库,根据上面导出的创建表的sql执行创建表。\x0d\x0a\x0d\x0ab、找到记录点。先要把当前数据库的表空间废弃掉,使当前ibd的数据文件和frm分离。 ALTER TABLE weibo_qq0 DISCARD TABLESPACE\x0d\x0a\x0d\x0ac、把之前要恢复的 .ibd文件复制到新的表结构文件夹下。 使当前的ibd 和frm发生关系。ALTER TABLE weibo_qq0 IMPORT TABLESPACE结果不出意外肯定会报错。就和我们开展数据开始说的那样,数据记录点不一致。我们看看之前ibd记录的点在什么位置。开始执行 import tablespace,报错 ERROR 1030 (HY000): Got error -1 from storage engine。找到mysql的错误日志,InnoDB: Error: tablespace id in file ‘.testweibo_qq0.ibd’ is 112, but in the InnoDB InnoDB: data dictionary it is 1. 因为 weibo_qq0 之前的记录点在112,当前的表只创建一次,所以记录点是1.\x0d\x0a\x0d\x0ad、那怎么从1记录到112。for ($1=1$i 回答于 2022-11-16有两种方法,一种方法使用mysql的check table和repair table 的sql语句,另一种方法是使用MySQL提供的多个myisamchk, isamchk数据检测恢复工具。前者使用起来比较简便。推荐使用。1. check table 和 repair table
登陆mysql 终端:
mysql -uxxxxx -p dbname
check table tabTest
如果出现的结果说Status是OK,则不用修复,如果有Error,可以用:
repair table tabTest
进行修复,修复之后可以在用check table命令来进行检查。在新版本的phpMyAdmin里面也可以使用check/repair的功能。
2. myisamchk, isamchk
其中myisamchk适用于MYISAM类型的数据表,而isamchk适用于ISAM类型的数据表。这两条命令的主要参数相同,一般新的系统都使用MYISAM作为缺省的数据表类型,这里以myisamchk为例子进行说明。当发现某个数据表出现问题时可以使用:
myisamchk tablename.MYI
进行检测,如果需要修复的话,可以使用:
myisamchk -of tablename.MYI
关于myisamchk的详细参数说明,可以参见它的使用帮助。需要注意的时在进行修改时必须确保MySQL服务器没有访问这个数据表,保险的情况下是最好在进行检测时把MySQL服务器Shutdown掉。
-----------------------------
另外可以把下面的命令放在你的rc.local里面启动MySQL服务器前:
[ -x /tmp/mysql.sock ] &&/pathtochk/myisamchk -of /DATA_DIR/*/*.MYI
其中的/tmp/mysql.sock是MySQL监听的Sock文件位置,对于使用RPM安装的用户应该是/var/lib/mysql/mysql.sock,对于使用源码安装则是/tmp/mysql.sock可以根据自己的实际情况进行变更,而pathtochk则是myisamchk所在的位置,DATA_DIR是你的MySQL数据库存放的位置。
需要注意的时,如果你打算把这条命令放在你的rc.local里面,必须确认在执行这条指令时MySQL服务器必须没有启动!检测修复所有数据库(表)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)