等待事件含义

当数据库创建临时文件时,会发生IO:BufFileRead和IO:BufFileWrite等待事件。当操作需要的内存比当前定义的work_mem内存参数更多时,会将临时数据写入磁盘永久存储。这种操作有时被称为“溢出到磁盘”。

IO:BufFileRead和IO:BufFile Write涉及work_mem内存区和maintenance_work_mem内存区。

work_mem的默认值为4 MB。如果一个会话并行执行操作,则每个处理并行性的工作进程将使用4MB的内存。因此,需要谨慎设置work_mem。如果将该值增加得太多,则运行多个会话可能会消耗太多内存。如果设置的值太低,数据库会在本地存储中创建临时文件。这些临时文件的磁盘I/O消耗可能会降低性能。

如果观察到以下事件,则数据库可能正在生成临时文件:

1、数据库存储性能突然急剧下降,然后快速恢复。

2、执行计划中可以看到sort disk字样,表示work_mem不够用了,排序已经溢出到磁盘排序。

可能导致等待增加的原因

IO:BufFileRead和IO:BufFileWrite等待事件的常见原因包括:

需要使用更多work_mem内存的查询

具有以下特征的查询使用work_mem区域:

  • Hash joins
  • ORDER BY clause
  • GROUP BY clause
  • DISTINCT
  • Window functions
  • CREATE TABLE AS SELECT
  • Materialized view refresh

需要使用更多maintenance_work_mem内存的语句

以下语句使用到维护工作区域:

CREATE INDEX,VACUUM, ALTER TABLE ADD FOREIGN KEY,CLUSTER

解决方法

定位问题

当我们在kwr报告中发现这类IO等待事件,说明很可能有sql已经内存溢出,需要用到磁盘排序。这时需要查看有无可疑的top sql

或者设置参数log_temp_files。此参数记录生成超过阈值KB的临时文件的所有查询。如果值为0,数据库记录所有临时文件。如果值为1024,数据库会记录所有生成大于1MB的临时文件的查询。

避免使用DISTINCT

如果可能,请避免使用DISTINCT操作来删除重复的行。查询返回的不必要和重复的行越多,DISTINCT操作的成本就越高。如果可能,请在WHERE子句中添加过滤条件,这可以提高性能并减少资源使用。

如果需要对同一表的多行使用DISTINCT,请考虑创建一个复合索引。将索引中的多列分组可以缩短计算不同行的时间。

检查ORDER BY和GROUP BY查询

ORDER BY子句可能会导致临时文件过多。考虑以下指导原则:

仅当需要对ORDER BY子句中的列进行排序时才将其包括在内。对于在ORDER BY子句中返回数千行并指定许多列的查询,此准则尤其重要。

当ORDER BY子句与具有相同升序或降序的列匹配时,考虑创建索引以加速ORDER BY语句。较小的索引读取和遍历速度更快。

如果可能,通过筛选结果集来减少需要排序的行数。如果使用WITH子句语句或子查询,请记住内部查询会生成一个结果集并将其传递给外部查询。查询可以筛选出的行越多,查询需要执行的排序就越少。

如果您不需要获得完整的结果集,请使用LIMIT子句。例如,如果您只想要前五行,那么使用LIMIT子句的查询不会一直生成结果。通过这种方式,查询所需的内存和临时文件更少。

GROUP BY自己也可以产生临时文件,使用GROUP BY查询的函数汇总:

  • COUNT
  • AVG
  • MIN
  • MAX
  • SUM
  • STDDEV

考虑使用窗口函数代替GROUP BY

使用GROUP BY可以更改结果集,然后检索聚合结果。使用窗口函数,可以在不更改结果集的情况下聚合数据。窗口函数使用OVER子句在查询定义的集合之间执行计算,将一行与另一行关联起来。

可以使用窗口函数中的所有GROUP BY函数,也可以使用以下函数:

  • RANK
  • ARRAY_AGG
  • ROW_NUMBER
  • LAG
  • LEAD

若要最大限度地减少窗口函数生成的临时文件的数量,请在需要两个不同的聚合时删除同一结果集的重复数据。请考虑以下查询。

SELECT sum(salary) OVER (PARTITION BY dept ORDER BY salary DESC) as sum_salary
, avg(salary) OVER (PARTITION BY dept ORDER BY salary ASC) as avg_salary
FROM a;

可以改写为窗window子句,如下。

SELECT sum(salary) OVER w as sum_salary
, avg(salary) OVER w as_avg_salary
FROM a
WINDOW w AS (PARTITION BY dept ORDER BY salary DESC);

物化视图和CTAS语句

当刷新物化视图时,它会运行一个查询,此查询可能包含GROUP BY、ORDER BY或DISTINCT等操作。在刷新过程中,可能会看到大量的临时文件以及等待事件IO:BufFileWrite和IO:BufFileRead。类似地,当基于SELECT语句创建表时,create table语句会运行查询。要减少所需的临时文件,请优化查询。

当cluster tables时,增加maintenance_work_mem

CLUSTER命令根据index_name指定的现有索引对table_name指定的表进行重新聚类。此方法以物理方式重新创建表,以匹配给定索引的顺序。

如果运行CLUSTER命令并观察到等待事件IO:BufFileWrite和IO:BufFileRead,请调优maintenance_work_mem参数。将内存大小增加到一定的数量。

增加work_mem

在某些情况下,您唯一的选择是增加会话使用的内存。如果您的查询语句书写正确,并且使用了正确的联接键,请考虑增加work_mem值。

若要了解查询生成的临时文件数,请将log_temp_files设置为0。如果将work_mem值增加到日志中标识的最大值,则不会在查询生成临时文件。但是,需要注意,如果数据库有5000个连接,并且每个连接使用256MB内存,则数据库实例需要1.2TiB的RAM。因此,可能会出现oom的情况。

为共享缓冲池保留足够的内存

数据库还使用共享缓冲池之类的内存区域,而不仅仅是工作内存区域。在增加work_mem之前,还需考虑这些额外内存区域的需求。

例如,假设你的数据库实例有64GB的内存。默认情况下,75%的内存保留给共享缓冲池。减去分配给共享内存区域的后,剩余16GB左右。不要将剩余内存全部分配给工作内存区域,因为操作系统也需要内存。

管理连接数

假设数据库实例有5000个连接同时并发。每个连接至少使用4MB的work_mem。连接的高内存消耗可能会降低性能。可以选择以下措施:

1、升级到更大的硬件内存。

2、通过使用连接代理或连接池程序来减少同时连接数据库的数量。

3、当数据库连接较少时,可以通过计算数据库内存总消耗以便增加work_mem的值。通过这种方式,可以减少IO:BufFileRead和IO:BufFileWrite等待事件的发生。

KingbaseES V8R6 等待事件之IO类BufFileRead BufFileWrite的更多相关文章

  1. KingbaseESV8R6等待事件之lwlock buffer_content

    前言 等待事件是排查数据库性能的指标之一.简单理解,cpu在处理业务时由于业务逻辑,和不可避免的数据库其他原因造成的前台进程等待,这里的等待事件包含buffer类,io类,以及网络类等等,当我们遇到等 ...

  2. 【等待事件】等待事件系列(5.1)--Enqueue(队列等待)

    [等待事件]等待事件系列(5.1)--Enqueue(队列等待)   1  BLOG文档结构图   2  前言部分   2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可 ...

  3. 【等待事件】等待事件系列(3+4)--System IO(控制文件)+日志类等待

     [等待事件]等待事件系列(3+4)--System IO(控制文件)+日志类等待   1  BLOG文档结构图     2  前言部分   2.1  导读和注意事项 各位技术爱好者,看完本文后,你可 ...

  4. 与IO相关的等待事件troubleshooting-系列9

    Buffer Cache与IO相关的等待事件: 这种等待事件的产生原因是包含DBWR进程和IO Slaves的Buffer Cache操作. 'db file parallel write' , 'd ...

  5. 与IO相关的等待事件troubleshooting-系列5

    'db file scattered read'         这是另一种常见的等待事件.他产生于Oracle从磁盘读取多个块到Buffer Cache中非连续(" scattered&q ...

  6. 【等待事件】序列等待事件总结(enq: SQ - contention、row cache lock、DFS lock handle和enq: SV - contention)

    [等待事件]序列等待事件总结(enq: SQ - contention.row cache lock.DFS lock handle和enq: SV -  contention) 1  BLOG文档结 ...

  7. oracle等待事件以及解决方案

    我们可以通过视图v$session_wait来查看系统当前的等待事件,以及与等待事件相对应的资源的相关信息,从而可确定出产生瓶颈的类型及其对象. v$session_wait的p1.p2.p3告诉我们 ...

  8. oracle等待事件-direct path read/write

    转://http://blog.chinaunix.net/uid-23177306-id-2531235.html 一.direct path read1.与直接读取相关联的等待事件.当ORACLE ...

  9. Oracle 等待事件 db file sequential read

    db file sequential read-数据文件顺序读取 等待事件: "db file sequential read" Reference Note (文档 ID 345 ...

  10. 全面解析Oracle等待事件的分类、发现及优化

    一.等待事件由来 大家可能有些奇怪,为什么说等待事件,先谈到了指标体系.其实,正是因为指标体系的发展,才导致等待事件的引入.总结一下,Oracle的指标体系,大致经历了下面三个阶段: · 以命中率为主 ...

随机推荐

  1. k8s-dashboard、helm

    目录 dashboard 安装dashboard 1. 创建SA 2. 集群角色绑定 3. 创建secret 4. 查看token helm 安装helm 1. 下载tar包 2. 解压 3. 配置环 ...

  2. CentOS8-pacemaker+corosync高可用部署

    部署pacemaker yum install pacemaker pcs corosync fence-agents resource-agents 启动pcs服务 systemctl enable ...

  3. Linux Ubuntu 遇到的一些问题

    Ubuntu 国内下载地址:https://mirrors.tuna.tsinghua.edu.cn/# 1. 安装一些常用的软件时,需要下载 amd.deb 类型的包,并使用下面命令安装 sudo ...

  4. __set_name__魔法方法

    介绍 __set_name__ 方法是 Python 3.6 中引入的一种特殊方法,它可以在类属性被赋值时自动调用.这个方法可以用来处理类属性的名称绑定问题,例如将类属性与其所在的类进行绑定. 具体来 ...

  5. flask操作mongodb

    一个简单的注册登录 from pymongo import MongoClient MC = MongoClient('127.0.0.1', 27017) MongoDB = MC['s2'] #创 ...

  6. React 受控和非受控组件

    无论你做什么,都要相信自己可以做到,因为你的潜力是无限的. 把父组件的状态变成属性传递给子组件,子组件接受这个属性,听命于父组件.这个子组件就是叫做受控组件.在受控与非受控组件有两种理解方案,第一:狭 ...

  7. 【系统选型】企业即时通讯(IM)软件调研及供应商对比评估

    企业即时通讯(IM)软件调研及供应商对比评估 1.概览 1.1 即时通讯 即时通讯(Instant messaging,简称IM)是一个终端服务,允许两人或多人使用网路即时的传递文字讯息.档案.语音与 ...

  8. 安装SQL Server 具有不支持的属性(Compressed)集。

    安装sqlserver 2014报错信息 D:\Program Files\Microsoft SQL Server 具有不支持的属性(Compressed)集.请通过使用文件夹属性对话框从该文件夹中 ...

  9. 【LeetCode剑指offer#05】回文链表的两种解法+删除链表中间节点(链表的基本操作)

    回文链表 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表.如果是,返回 true :否则,返回 false . 示例 1: 输入:head = [1,2,2,1] 输出:true 示 ...

  10. 【LeetCode贪心#10】划分字母区间(有涉及hash数组的使用)

    划分字母区间 力扣题目链接(opens new window) 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中.返回一个表示每个字符串片段的长度的列表 ...