暂无图片
暂无图片
10
暂无图片
暂无图片
暂无图片

Log file sync导致的数据库异常缓慢

1109

0、判断流程(事后判断的,但是我觉得写在前边大家能更好的理解)

第一阶段解决思路和步骤

1、查看AWR报告等待事件及其百分比(确定优先级,先是Log file sync才是gc buffer busy acquire)。

2、根据ASH报告确定等待事件对应的SQL语句类型(增、删、改、查)。

3、根据SQL确定数据库对象,我这里是插入慢,所以确定表的大小、索引、统计信息等信息。

4、确定的表都是日志表,了解是有垃圾数据可以清理的,那么操作步骤是清理垃圾数据、整理表碎片、重建索引、收集统计信息。(确定这些操作是因为数据越大、索引越大,插入就越慢,所以缩减表和索引的规模),观察1个小时后,awr报告没有任何变化,业务反馈还是慢,解决失败。



第二阶段解决思路和步骤

5、定位服务器CPU(TOP)、存储(sar或者iostat)、网络(traceroute)之间的问题,初步判断问题概率磁盘 》 网络 》 CPU。

6、通过iostat命令检查,发现 %iowait、await、svctm、%util等待百分比太高。有的同学问怎么算高,我个人认为,%iowait、await、svctm的值超过10就算高(这里不是指三个都高算高,而且其中任意两个超过10),%util超过80就算高。

7、再次查询数据库redo日志切换和归档生成量,发现数据库的切换次数和归档生成量次数不算多,判断标准是redo日志是否都处于active或者current状态,或者和过去一周对比切换次数是否有差异。

8、询问云平台的同事,两节点服务器是否在近期有变更?尤其是磁盘和网络方面的调整或者异常信息,回答是没有,目前为止优化再次失败。



第三阶段解决思路和步骤

9、摇人,找大哥能解决。

10、以半个小时为判断间隔时间,定期收集awr和业务反馈时间。

11、关闭节点2,只保留节点1来对外提供服务,来判断是否是节点之间的网络导致此问题的发生,定位等待事件gc buffer busy acquire的根本原因。

12、半个小时后业务反馈还是缓慢,数据库节点1负载只提高了5%,awr报告几乎没有改变,结论就是负载的确提高,但是没有到忍受不了的地步,也不是节点之间的网络有问题。

13、矛头还是定向了磁盘的问题,分为磁盘性能和服务器到磁盘的网络波动(极有可能是服务器和存储之间的光纤、交换口、网络等方面有问题)。

14、数据库进程方面,主要是定位 ckpt、lgwr、dbwn三个进程。

15、调整ckpt进程,提高检查点触发频率,缩短数据库宕机异常恢复时间,缩短dbwn触发间隔时间。参数分别fast_start_mttr_target是和_db_fast_obj_ckpt。

16、调整dbwn参数,分别是 db_writer_processes 和commit_logging、commit_wait。前者代表dbwn的进程数量,cpu / 8 = db_writer_processes。 后二者commit_logging='batch'和commit_wait='nowait' 前者代表的意思是批量提交,后者代表的是写完即返回,都是提升速度减少安全性的操作。业务反馈速度飙升,除极少数制单卡顿,其他均正常。

17、问题已解决,还是侧面验证了磁盘的性能问题,需要云平台的再次答复。


第四阶段解决思路和步骤

18、敌我双方就dd的写入进行了针锋相对的验证对答。


DBWn负责写检查点队列上的脏数据块,而CKPT负责记录当前检查点队列的第一个数据块所对应的的重做条目在日志文件中的地址。


1、问题简介

  某生产数据库从七月中旬开始工作日上午9:30到11:30,下午2:30到5:30比较繁忙,异常缓慢,需要检查数据库存在的异常问题。


2、问题定位

2.1、第一阶段(从数据库角度出发,处理log file sync 和gc buffer acquire等待事件)

log file sync 占比最大

gc buffer busy acquire 占比第二

这两个等待事件占比最大?谁是因谁是果?


2.1.1、问题SQL整改

gc buffer busy acquire是当session#1尝试请求访问远程实例(remote instance)buffer,但是在session#1之前已经有相同实例上另外一个session#2请求访问了相同的buffer,并且没有完成,那么session#1等待gc buffer busy acquire。


通过检查AWR报告和ASH报告,分别观察TOP SQL语句和Segment Statistics里Segments by Physical Writes、Segments by Physical Write Requests、Segments by Direct Physical Writes、Segments by Row Lock Waits分别出现的数据库对象。

######查询插入慢的表大小select owner, segment_name, segment_type, bytes / 1024 / 1024 / 1024
  from dba_segments
 where owner in ('用户1', '用户2')
   and segment_name in ('表1', '表2');


########查询表的统计信息select OWNER, TABLE_NAME, LAST_ANALYZED
  from dba_tables
 where owner in ('用户1', '用户2')
   and TABLE_NAME in ('表1', '表2');


##查看表的索引,索引越多,DML操作越慢select OWNER, INDEX_NAME, INDEX_TYPE, TABLE_NAME
  from dba_indexes
 where owner in ('用户1', '用户2')
   and TABLE_NAME in ('表1', '表2');


发现慢的都是日志表,表1和 表2清理垃圾数据,整理碎片,收集统计信息,重建索引。不起效果,接着下一步。


2.2、第二阶段(针对服务器)

2.2.1、定位CPU

####注意第二行第五列的wa数值Tasks: 595 total,   3 running, 592 sleeping,   0 stopped,   0 zombie
%Cpu(s):  8.5 us,  2.8 sy,  0.0 ni, 87.1 id,  1.4 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem : 65967600 total, 17362260 free,  7846728 used, 40758612 buff/cache
KiB Swap: 12582908 total, 12582908 free,        0 used. 23437396 avail Mem 

wa (IO-wait): CPU等待I/O操作的时间百分比。

这个wa数值一直会变化,其中最大会达到14%左右。


2.2.2、定位网络

AWR报告里的 Interconnect Ping Latency Stats (不知道为啥插入图片老是失败)

第一行和第二行分为节点1和节点2

第二列、第三列、第四列是一组,表示500byte的平均等待时间,节点1和节点2分别是0.31和0.41。

第五列、第六列、第七列是一组,表示8Kb的平均等待时间,节点1和节点2分别是0.28和0.51。

有个博客说Avg Latency 500b(8kb) msg超过了5,就代表有大概率网络有问题。定位方式可以通过owswatch检查。


2.2.3、定位IO

##显示磁盘使用情况,主要看 %iowait
iostat -x 2

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           8.57    0.00    5.27   13.48    0.00   72.67

await 等待I/O平均的时间(milliseconds)
svctm I/O需求完成的平均时间
%util 被I/O需求消耗的CPU百分比

观察%iowait很大,怀疑磁盘有问题。


2.2.4、控制文件争用

问题原因可能是控制文件太大或者是删除归档等操作太频繁。

####查询控制文件位置SQL> show parameter control_files

NAME	        TYPE	       VALUE
------------- ----------- ------------------------------
control_files  string     +DATA/ojndev4/controlfile/current.256.1150558725


##查询控制文件大小ASMCMD> du +DATA/ojndev4/controlfile/
Used_MB      Mirror_used_MB
     24                  24


查看归档生成量

with redo_data as (
SELECT instance_number,
       to_date(to_char(redo_date,'DD-MON-YY-HH24:MI'), 'DD-MON-YY-HH24:MI') redo_dt,
       trunc(redo_size/(1024 * 1024 * 1024),2) redo_size_gb
FROM  (
  SELECT dbid, instance_number, redo_date, redo_size , startup_time  FROM  (
    SELECT  sysst.dbid,sysst.instance_number, begin_interval_time redo_date, startup_time,
  VALUE -
    lag (VALUE) OVER
    ( PARTITION BY  sysst.dbid, sysst.instance_number, startup_time
      ORDER BY begin_interval_time ,sysst.instance_number
     ) redo_size
  FROM sys.wrh$_sysstat sysst , DBA_HIST_SNAPSHOT snaps
WHERE sysst.stat_id =
       ( SELECT stat_id FROM sys.wrh$_stat_name WHERE  stat_name='redo size' )
  AND snaps.snap_id = sysst.snap_id
  AND snaps.dbid =sysst.dbid
  AND sysst.instance_number  = snaps.instance_number
  AND snaps.begin_interval_time> sysdate-30
   ORDER BY snaps.snap_id )
  )
)
select  instance_number,  redo_dt, redo_size_gb,
    sum (redo_size_gb) over (partition by  trunc(redo_dt)) total_daily,
    trunc(sum (redo_size_gb) over (partition by  trunc(redo_dt))/24,2) hourly_rate
   from redo_Data
order by redo_dt, instance_number;

用来判断是否真的有那么多归档需要删除?


2.3、第三阶段(数据库参数及硬件的整改)


这个数值是设置数据库恢复启动后花费的时间。换句话说也就是检查点检查的频率,fast_start_mttr_target的单位是秒,数值越小,检查点触发的频率越快,对数据库的负载越高,刷新脏块的效率越高,数据库异常恢复的速度越快,但是这个只是预期值,不是你设置了这个数值,他真的就能在120秒内恢复。

alter system set fast_start_mttr_target=120 scope=both sid='*';


接着核对了数据库的dbwn进程,这个进程的数值是 CPU格数 / 8 = 16C / 8 = 2个

SQL> show parameter db_writer_processes

NAME				              TYPE	           VALUE
-------------------- ----------- ------------------------------
db_writer_processes		  integer	             2

log file sync等待时间居然还有等待几秒的情况,我做过服务器里插数的实验,都是毫秒级别,这里表现了插入、提交的性能差。尤其是32s的情况。


快速提交参数的修改

alter system set "_db_fast_obj_ckpt"=false scope=both sid='*';alter system set "_db_fast_obj_ckpt"=True scope=both sid='*';


修改数据库的提交方式和是否等待,在这里,把参数commit_logging修改成batch批量提交,参数commit_wait修改为不等待,提升了数据库的写入效率,降低了数据库的安全性,极有可能丢失数据。

alter system set commit_logging='batch'  scope=both sid='*';
alter system set commit_wait='nowait'  scope=both sid='*';

目前就是dbw写慢,反过来阻塞了lgwr,影响你的commit,所以你batch,nowait 就好了。 —— 大佬原话。

从以上来判断,数据库的负载不高,和以往没有区别,他的根本原因就是磁盘出现了问题(不仅是存储本身问题。你机器到存储的光纤有问题,或者交换机口子有问题,都是类似的现象)。


2.4、第四阶段(与云平台的斗智斗勇)

云平台不承认磁盘有问题

##写入效果很好,达到了338MB/sdd if=/dev/zero of=/bigfile bs=4096 count=1000


##加入参数oflag=direct,写直接降低到 8.1M/sdd if=/dev/zero of=/bigfile bs=4096 count=1000 oflag=direct

direct(直接I/O):使用该选项可以绕过文件系统缓存,直接进行输入输出操作。这样可以提高数据传输速度,特别是在处理大文件时。


##加一块新的裸盘进行操作,写直接降低到 2.4M/s
dd if=/dev/zero of=/dev/sdp bs=4096 count=100000 oflag=direct


##查看是否有卡顿 —— 的确是有少许卡顿
strace -T -e trace=write dd if=/dev/zero of=/dev/sdp bs=4096 count=1 oflag=direct

结论:SAN交换机的级联线缆有一根有问题,一根线缆拖累了整个级联。


3、问题解决

治标解决:修改数据库参数

治本解决:检查磁盘网络波动、光缆情况等


4、问题梳理

怀疑数据库业务有新增导致有问题,怀疑数据库有问题,怀疑磁盘有问题,怀疑光缆有问题,最后确认。


5、涉及额外知识















「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论