数据库内核月报 - 2019 / 01

MySQL · 最佳实践 · MySQL中的IO共享操作

云现在这么火热,云数据库也是数据库界的一件大事,从技术的客户角度来讲,云最大的本质是资源和服务的共享模式,让同一个优质资源(包括软硬件和专家经验)可以同时服务更多的客户,减少资源的空置浪费,提升服务的时间效率,让客户得到按需的成本实惠。在这里先抛开服务不说,来讲一下资源部份,一个云数据库运行所需要的资源分为如下几层:

  • CPU资源,虽然有些地方不能共享,比如中断调用等,但用户的CPU是可以良好地进行隔离的,中断调用也基本上和用户的行为成正比,因此可以理解成CPU是具备良好隔离性的,可以理解成不共享的资源,是可以较好解决的,除非是出于成本目的极度共享。
  • 内存资源,内存一般无法共享,因为内存共享会影响物理机的稳定性,会影响服务质量,可以理解成不共享的资源。当然中间也有准确控制内存使用的难点。
  • 网络资源,可以分为两类资源,一类是硬件层面的流量,可以通过多块网卡来保持足够的流量带宽,或者进行高效的流量控制;另一类是TCP通信方面的软资源,比如TCP的缓存、连接数等等。因为还需要CPU及操作系统内核的协助,也受制于软资源的限制,更受制于上联的交换机,因此网络资源本质是一个充分共享,难以隔离的资源,在云上是需要极度关注的。
  • IO资源,从Linux/Unix的本质来讲,网络资源也是IO资源,在这里我们先分开,这里讲的IO资源特指数据存储相关的IO行为。有物理层面的资源,比如多块磁盘,或不同响应速度的磁盘;也有操作系统层面的软资源,比如VFS路径、卷管理方式、软硬件Raid模式等。在现有的云体系中,IO也是一个充分共享,难以隔离的资源,也是云上需要极度关注的点。

一个MySQL实例上的网络行为有哪几类呢?可以分为以下10类:

  • 正常业务流入量,指的是发送SQL语句或传入参数所需数据引起的流入量,应当在Receive Bytes统计中。
  • 正常业务流出量,指的是发送SQL语句执行结果引起的流出量,应当在Send Bytes统计中。
  • Binlog发送量,当实例作为Master时,可以允许多个备实例或其他第三方Binlog阅读工具(例如mysqlbinlog等)来读取增量日志,这块在源生的版本中没有流量控制,因此这部份流量也不可忽视。
  • Binlog接收量,当作为Slave时,可以从一个或多个备库接受增量Binlog,这块在源生的版本中没有流量控制,因此这部份流量也不可忽视。
  • Redo Log发送量,POLARDB基于物理日志进行复制,Primry需要向Replica来发送增量的物理日志,以进行内存数据回放同步。
  • Redo Log接收量,POLARDB基于物理日志进行复制,Replica需要从Primary来接收增量的物理日志,以进行内存数据回放同步。
  • Slow Log收集,部份用户会将Slow Query的阀值设置得比较低,并且会实时功批量收集Slow Log中的信息,极端情况下会引起不少的流量。
  • Audit SQL收集,如果要实时或批量收集审计日志,视审计级别及数据库的压力,也可能会产生不少的网络流量。
  • 秒级监控数据,为了分析问题都会收集较高频度的性能数据,视频率和收集数据的全面程度,也会产生不少的网络流量。
  • 备份恢复任务,由备份或恢复任务所引起的流量,也会给网络带来一定的压力。

一个MySQL实例上的存储IO行为有哪几类呢?可以分为以下18类:

  • 数据读操作,指将数据页从磁盘读取到数据缓存的操作。
  • 数据写操作,指将数据缓存脏页从缓存中刷到磁盘持久化(Checkpoint)或释放缓存引起的写操作。
  • 文件同步操作,MySQL支持非Direct IO操作,因此需要定期或准实时地将操作系统的文件缓存刷到磁盘上,以进行数据的持久化。
  • Redo Log写操作,数据库事务日志的写操作。
  • Redo Log同步操作,MySQL支持非Direct IO操作,因此需要定期或准实时地将操作系统的文件缓存刷到磁盘上,以进行数据的持久化。
  • Binlog写操作,在开启Binlog的情况下,会生成逻辑日志,当遇到大事务时,还会引发瞬间的IO高峰。
  • Binlog同步操作,MySQL Binlog不支持Direct IO操作,因些需要定期或准实时地将操作系统的文件缓存刷到磁盘上,以进行数据的持久化。
  • Binlog清理操作,清理大文件也会引发一定的IO,或影响可用内存。
  • Relay Log写操作,备库从主库接受Binlog增量数据,以Relay Log的方式保存进行续续同步。
  • Relay Log同步操作,MySQL Relay Log不支持Direct IO操作,因些需要定期或准实时地将操作系统的文件缓存刷到磁盘上,以进行数据的持久化。
  • Relay Log清理操作,清理大文件也会引发一定的IO,或影响可用内存。
  • 磁盘排序操作,当有大的结果集需要排序时,因为内存不是无限的,可能会用到额外的磁盘空间。
  • SQL中间结果,当有复杂SQL需要生成中间表时,因为内存不是无限的,可能会用到额外的磁盘空间。
  • Slow Log,部份用户会将Slow Query的阀值设置得比较低,可能引发较大的IO写出量。
  • Audit SQL,开启审计日志后,视数据库的压力和审计的粒度,可能会引发较大的IO写出量。
  • 监控数据,取决于监控数据是否选用落地的方案(一般都会选择落地的方案,以防性能数据丢失)。
  • 备份恢复,备份和恢复操作引起的IO量不可忽视。
  • Swap读写,当内存不够用,需要用到Swap区域时,也会产生大量的读写操作。

由于网络和IO是云上难隔离的点,在排查和分析问题时,需要充分考虑到所有的这些点引起的干扰,以便找到各类类问题的根源,特别是多实例相互干扰的场景。