linux 这套系统去管理我们机器上的机械硬盘、SSD固态银盘等,在里面读取数据,或者写入数据。

MySQL 中数据页是随机读写的,而redo log 是顺序读写的。

image.png

image.png
上MySQL数据库就是个软件,其实就是用编程语言写的一套数据库管理软件而已,底层就是磁盘 来存储数据,基于内存来提升数据读写性能,然后设计了复杂的数据模型,帮助我们高校的存储和管理数据

MySQL 都是安装在Linux 上的,启动MySQL 的进程,就是启动了一个MySQL的数据库,在运行过程中,需要通过操作系统提供的接口,来调动CPU、内存、磁盘 和网卡这些硬件,由操作系统负责操作底层的硬件系统

image.png
数据库部署在机器上的时候,存储都是搭建的RAID存储架构 , RAID就是一个磁盘冗余阵列 , 引入RAID这个技术,大致理解为用来管理机器 里的多块磁盘的一种磁盘阵列技术! 因为一块磁盘的容量是有限的。

image.png

我们往磁盘里写数据的时候,通过RAID技术可以帮助我们选择一块磁盘写入,在读取数据的时候,我们也知道从哪 块磁盘去读取, 还可以实现数据冗余机制 -就是写磁盘的时候,会写在两块磁盘上,冗余备份,保障数据不丢失,image.png
以RAID技术实际上就是管理多块磁盘的一种磁盘阵列技术,他有软件层面的东西,也有硬件层买的东西,比如有 RAID卡这种硬件设备 ,带缓存的一个硬件, 是一种跟内存类似的SDRAM ,并不是直接使用服务器主内存的那种模式。 可以把RAID的缓存模式设置为write back,这样的话,所有写入到磁盘阵列的数据,先会缓存在RAID卡的缓 存里,后续慢慢再写入到磁盘阵列里去,这种写缓冲机制,可以大幅度提升我们的数据库磁盘写的性能
image.png
可能存在SDRAM 的数据还未写入到磁盘中,突然断电,导致数据丢失。 解决这个问题,RAID卡一般都配置有自己独立的锂电池或者是电容,如果服务器突然掉电 了,无法接通电源了,RAID卡自己是基于锂电池来供电运行的,然后他会赶紧把缓存里的数据写入到阵列中的磁盘上 去。 牛逼,还自带电源。image.png

锂电池,存在衰退的问题,为了解决这个问题,会进行定期的充放电来延长寿命和校准电池容量。在这个过程中,RAID的缓存级别 会从 write back变成write through,我们通过RAID写数据的时候, IO就直接写磁盘了 ; 写内存的话,性能也就是0.1ms这个级别,但是直接写磁盘,就性能退化10倍到毫秒级了!

这个时候一旦RAID锂电池自动充放电,往往会导致你的数据库服务器的RAID存储定期的性能出现几十倍的抖动, 间接导致你的数据库每隔一段时间就会出现性能几十倍的抖动! —为什么线上数据库隔一段时间就会出现抖动?

image.png

数据库无法连接问题- Too many connections

异常信息往往是“ERROR 1040(HY000): Too many connections”,这个时候就是说数据库的连接池 里已经有太多的连接了,不能再跟你建立新的连接了!

数据库 和 业务系统实例都是有一个连接池的,业务系统每个连接Socket 都会对应着数据库连接池里的一个连接Socket,这就是TCP网络连接。
image.png

当数据库告诉你Too many connections的时候,就是说他的连接池的连接已经满了,你业务系统不能跟他建立更 多的连接了!
数据库部署在64GB的大内存物理机上,机器配置各方面都很高,然后连接这台物理机 的Java系统部署在2台机器上,Java系统设置的连接池的最大大小是200,也就是说每台机器上部署的Java系统,最多 跟MySQL数据库建立200个连接,一共最多建立400个连接。image.png

但是这个时候如果MySQL报异常说Too many Connections,就说明目前MySQL甚至都无法建立400个网络连接?这 也太少了吧!毕竟是高配置的数据库机器!

检查了一下MySQL的配置文件,my.cnf,里面有一个关键的参数是max_connections,就是MySQL能建立 的最大连接数,设置的是800。

用命令行或者一些管理工具登录到MySQL去,可以执行下面的命令看一下 :
show variables like ‘max_connections’

此时你可以看到,当前MySQL仅仅只是建立了214个连接而已!
此时就可以想到,是不是MySQL根本不管我们设置的那个mac_connections,就是直接强行把最大连接数设 置为214了?于是我们可以去检查一下MySQL的启动日志

  1. Could not increase number of max_open_files to more than mysqld (request: 65535)
  2. Changed limits: max_connections: 214 (requested 2000)
  3. Changed limits: table_open_cache: 400 (requested 4096)

看看日志就很清楚了,MySQL发现自己无法设置max_connections为我们期望的800,只能强行限制为214 了!

简单来说,就是因为底层的linux操作系统把进程可以打开的文件句柄数限制为了1024了,导致 MySQL最大连接数是214! 为什么linux的文件句柄数量被限制了,MySQL最大连接数就被限制了呢?

image.png
linux 的文件句柄限制,导致了MySQL的最大连接数被限制,
ulimit -HSn 65535
然后就可以用如下命令检查最大文件句柄数是否被修改
cat /etc/security/limits.conf
cat /etc/rc.local

如果都修改好之后,可以在MySQL的my.cnf里确保max_connections参数也调整好了,然后可以重启服务器,然后重 启MySQL,这样的话,linux的最大文件句柄就会生效了,MySQL的最大连接数也会生效了

linux的话是默认会限制你每个进程对机器资 源的使用的,包括可以打开的文件句柄的限制,可以打开的子进程数的限制,网络缓存的限制,最大可以锁定的内存 大小。

因为linux操作系统设计的初衷,就是要尽量避免你某个进程一下子耗尽机器上的所有资源,所以他默认都是会做限制 的。

如果linux限制你一个进程的文件句柄太少的话,那么就会导致我们没办法创建大量的网络连接,此时我们的系统 进程就没法正常工作了

举个例子,比如MySQL运行的时候,其实就是linux上的一个进程,那么他其实是需要跟很多业务系统建立大量的连接 的,结果你限制了他的最大文件句柄数量,那么他就不能建立太多连接了!

在生产环境部署了一个系统,比如数据库系统、消息中间件系统、存储系统、缓存系统之后,都需要 调整一下linux的一些内核参数,这个文件句柄的数量是一定要调整的,通常都得设置为65535

可以用ulimit命令来设置每个进程被限制使用的资源量,用ulimit -a就可以看到进程被限制使用的各种资源的量。

image.png