电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

测量磁盘I/O


发布日期:2021/1/6
 
我怎样分离Oracle I/O 来使得性能最高?

我是否应该分离数据文件和索引文件?

我是否应该分离redo日志?

这些问题(并且还有更多的)看起来似乎是对于数据库管理员来说的它们在一般程度上很容易解答但是在实际操作中可能是非常难以解决的除非我们检查一下我们的磁盘子系统到底是怎样执行的

我们中的许多人可能立即就不读这篇文章了对自己说这些问题和详细程度只是对于我们的系统管理员或那些控制磁盘管理的人来说的我经常看到两种不同的方式来配置Oracle存储第一种是当架构师要在一个存储数组中分离Oracle对象类型(数据索引重做档案文件等等)时使用Oracle灵活架构(OFAOracles Flexible Architecture)方法第二种方法是建立一个JBOD(Just a Bunch Of Disks简单磁盘捆绑)配置并将所有东西都放到上面这两种方法都缺乏能够最终形成协调的数据库系统的计划和配置它们只是碰运气罢了希望因为遵循了一个预先确定的方法从而一切进行顺利但是这些方法可能在你的环境里不起作用不要依靠于你的系统管理员因为他们自己可能都不知道怎么获取信息而当他们这么做的时候通常是在更高的级别因为他们也不能将这些信息与Oracle堆栈关联起来

所以数据库管理员必须开始从一个纯粹的I/O透视图来了解应用程序将这个信息传递给存储管理员然后一起开发一个配置或改变存储子系统的计划这将用于应用程序混合对于存储OLTP环境的一个重要性能指示器是基于每秒I/O操作次数(IOPS)和延迟(I/O来回的时间)OLAP数据库是你的数据仓库或报表系统并由移动大量的主要做只读的数据来分类对于存储数组一个OLAP环境的性能是基于兆比特位每秒(MBPS)的一个数据库工作负载经常描述为它的应用程序混合了解和将一个应用程序混合转化为一个数据库工作负载对于优化存储系统来说是非常重要的一个OLTP数据库的工作负载是由小的随机I/O来分类的而OLAP是由大型的连续或随机I/O来分类的

对于数据库管理员来说现在该看看你的数据库的内部了你必须想办法获取某种形式的统计信息使你可以在数据库级别分类SQL类型和I/O请求例如Oracle只有很少的表允许提取这个信息举例来说我们可以查询gv$sysstat视图(物理读取总的IO请求——物理读取总的多块请求)来获得系统中小量读取的次数在一段时间内做这个操作用结束时的值减去开始时的值你就很快地获得了那段时间的小量读取的IOPS必须对每一个可用的统计进行这个操作以了解你的数据库所请求的总的IOPS和MBPS这些是你需要获得的相关统计信息基本上大量读写是用来计算MBPS的而小量读写是用来进行IOPS计算的

gv$sysstat(namevalue)

TotalReads:physicalreadtotalIOrequests

TotalWrites:physicalwritetotalIOrequests

LargeReads:physicalreadtotalmultiblockrequests

LargeWrites:physicalwritetotalmultiblockrequests

TotalBytesRead:physicalreadtotalbytes

TotalBytesWritten:physicalwritetotalbytes

Tocalculatesmallreads:

SmallReads=TotalReadsLargeReads

SmallWrites=TotalWritesLargeWrites

使用这些数据使我们可以考虑到我们目前的数据库性能和存储请求从而作出明智的决策数据库可能正在被讨论而实际的I/O请求可能比最优情形下的要低所以可能需要进行调整但是将这些IOPS和MBPS转给存储管理员去评估存储解决方案是否是正确的和是否需要重新配置是数据库管理员的责任这些重新配置可能需要移动数据文件来使用更多的磁盘添加更多的磁盘用于更高的吞吐量或者降低应用程序的IOPS和MBPS是的我们再次回到了应用程序我知道你了解要做什么

下面两个脚本使你可以开始了我花费了很多时间来使它们变得容易使用并提供给你信息使你能够快速了解你的磁盘子系统在过去的时间里执行的怎么样

setechooff

setfeedbackoff

setheadingoff

setlinesize

setpagesize

setverifyoff

settermoutoff

columnrptnew_valuerpt

selectinstance_name||_||to_char(sysdateYYYYMMDDHHMISS)||_vsysstat_ioworkloadLSTrptfromv$instance;

settermouton

prompt

prompt

prompt^^^^^^^^^^^^^

promptReportName:/LST/&&rpt

prompt^^^^^^^^^^^^^

spool/LST/&&rpt

columnsrnew_valuesr

columnswnew_valuesw

columnlrnew_valuelr

columnlwnew_valuelw

columntbrnew_valuetbr

columntbwnew_valuetbw

settermoutoff

SELECT

sum(decode(namephysicalreadtotalIOrequestsvalue)decode(namephysicalreadtotalmultiblockrequestsvalue))sr

sum(decode(namephysicalwritetotalIOrequestsvalue)decode(namephysicalwritetotalmultiblockrequestsvalue))sw

sum(decode(namephysicalreadtotalmultiblockrequestsvalue))lr

sum(decode(namephysicalwritetotalmultiblockrequestsvalue))lw

sum(decode(namephysicalreadtotalbytesvalue))tbr

sum(decode(namephysicalwritetotalbytesvalue))tbw

FROMv$sysstat;

settermouton

prompt

prompt

prompt^^^^^^^^^^^^

promptFirstSample

prompt^^^^^^^^^^^^

promptNumberofSmallReads:&&sr

promptNumberofSmallWrites:&&sw

promptNumberofLargeReads:&&lr

promptNumberofLargeWrites:&&lw

promptTotalBytesRead:&&tbr

promptTotalBytesWritten:&&tbw

prompt

prompt

promptEntertheamountoftime(inseconds)youwouldlikethisprocesstosleepforsamplingdata

prompt^^^^^^^^^^^^^^^^^^

promptSleepTime(secs):&&sleeptime

prompt^^^^^^^^^^^^^^^^^^

execDBMS_LOCKSLEEP(&&sleeptime);

columnsrnew_valuesr

columnswnew_valuesw

columnlrnew_valuelr

columnlwnew_valuelw

columntbrnew_valuetbr

columntbwnew_valuetbw

settermoutoff

SELECT

sum(decode(namephysicalreadtotalIOrequestsvalue)decode(namephysicalreadtotalmultiblockrequestsvalue))sr

sum(decode(namephysicalwritetotalIOrequestsvalue)decode(namephysicalwritetotalmultiblockrequestsvalue))sw

sum(decode(namephysicalreadtotalmultiblockrequestsvalue))lr

sum(decode(namephysicalwritetotalmultiblockrequestsvalue))lw

sum(decode(namephysicalreadtotalbytesvalue))tbr

sum(decode(namephysicalwritetotalbytesvalue))tbw

FROMv$sysstat;

settermouton

prompt

prompt

prompt^^^^^^^^^^^^^

promptSecondSample

prompt^^^^^^^^^^^^^

promptNumberofSmallReads:&&sr

promptNumberofSmallWrites:&&sw

promptNumberofLargeReads:&&lr

promptNumberofLargeWrites:&&lw

promptTotalBytesRead:&&tbr

promptTotalBytesWritten:&&tbw

prompt

prompt

prompt^^^^^^^^^

promptResults:

prompt^^^^^^^^^

columnsrinew_valuesri

columnswinew_valueswi

columntsinew_valuetsi

columnsrpnew_valuesrp

columnswpnew_valueswp

columnlrinew_valuelri

columnlwinew_valuelwi

columntlinew_valuetli

columnlrpnew_valuelrp

columnlwpnew_valuelwp

columntrnew_valuetr

columntwnew_valuetw

columntmnew_valuetm

SELECT

ROUND((&&sr&&sr)/&&sleeptime)sri

ROUND((&&sw&&sw)/&&sleeptime)swi

ROUND(((&&sr&&sr)+(&&sw&&sw))/&&sleeptime)tsi

ROUND((&&sr&&sr)/DECODE(((&&sr&&sr)+(&&sw&&sw))((&&sr&&sr)+(&&sw&&sw)))*)srp

ROUND((&&sw&&sw)/DECODE(((&&sr&&sr)+(&&sw&&sw))((&&sr&&sr)+(&&sw&&sw)))*)swp

ROUND((&&lr&&lr)/&&sleeptime)lri

ROUND((&&lw&&lw)/&&sleeptime)lwi

ROUND(((&&lr&&lr)+(&&lw&&lw))/&&sleeptime)tli

ROUND((&&lr&&lr)/DECODE(((&&lr&&lr)+(&&lw&&lw))((&&lr&&lr)+(&&lw&&lw)))*)lrp

ROUND((&&lw&&lw)/DECODE(((&&lr&&lr)+(&&lw&&lw))((&&lr&&lr)+(&&lw&&lw)))*)lwp

ROUND(((&&tbr&&tbr)/&&sleeptime)/)tr

ROUND(((&&tbw&&tbw)/&&sleeptime)/)tw

ROUND((((&&tbr&&tbr)+(&&tbw&&tbw))/&&sleeptime)/)tm

FROMdual;

SELECT

SmallReadIOPS=||ROUND((&&sr&&sr)/&&sleeptime)||IOPS

SmallWriteIOPS=||ROUND((&&sw&&sw)/&&sleeptime)||IOPS

TotalSmallIOPS=||ROUND(((&&sr&&sr)+(&&sw&&sw))/&&sleeptime)||IOPS

SmallReadI/O%=||ROUND((&&sr&&sr)/DECODE(((&&sr&&sr)+(&&sw&&sw))((&&sr&&sr)+(&&sw&&sw)))*)||%

SmallWriteI/O%=||ROUND((&&sw&&sw)/DECODE(((&&sr&&sr)+(&&sw&&sw))((&&sr&&sr)+(&&sw&&sw)))*)||%

LargeReadIOPS=||ROUND((&&lr&&lr)/&&sleeptime)||IOPS

LargeWriteIOPS=||ROUND((&&lw&&lw)/&&sleeptime)||IOPS

TotalLargeIOPS=||ROUND(((&&lr&&lr)+(&&lw&&lw))/&&sleeptime)||IOPS

LargeReadI/O%=||ROUND((&&lr&&lr)/DECODE(((&&lr&&lr)+(&&lw&&lw))((&&lr&&lr)+(&&lw&&lw)))*)||%

LargeWriteI/O%=||ROUND((&&lw&&lw)/DECODE(((&&lr&&lr)+(&&lw&&lw))((&&lr&&lr)+(&&lw&&lw)))*)||%

TotalRead=||ROUND(((&&tbr&&tbr)/&&sleeptime)/)||MBPS

TotalWritten=||ROUND(((&&tbw&&tbw)/&&sleeptime)/)||MBPS

TotalMBPS=||ROUND((((&&tbr&&tbr)+(&&tbw&&tbw))/&&sleeptime)/)||MBPS

FROMdual

;

promptSmallReadIOPS=&&sriIOPS

promptSmallWriteIOPS=&&swiIOPS

promptTotalSmallIOPS=&&tsiIOPS

promptSmallReadI/O%=&&srp%

promptSmallWriteI/O%=&&swp%

promptLargeReadIOPS=&&lriIOPS

promptLargeWriteIOPS=&&lwiIOPS

promptTotalLargeIOPS=&&tliIOPS

promptLargeReadI/O%=&&lrp%

promptLargeWriteI/O%=&&lwp%

promptTotalRead=&&trMBPS

promptTotalWritten=&&twMBPS

promptTotalMBPS=&&tmMBPS

spooloff

undefinesleeptime

从工作负载库历史记录里获得一个完整的IOPS和MBPS的历史记录并将它绘制出来用于管理这使得你可以看到总的数据库磁盘活动将它与你的磁盘容量相比较记住这些数据是所有磁盘的你通过除以服务数据库请求中的总的磁盘数可以获得平均IOPS/MBPS这是很有用的信息一旦你将结果绘制成图表你就可以看到你的I/O和应用程序的执行在这一天里是怎么样的或者至少确定了峰值时间段在哪

setechooff

setfeedbackoff

setlinesize

setpagesize

setverifyoff

settermoutoff

columnrptnew_valuerpt

selectinstance_name||_wrh_sysstat_ioworkload_||LSTrptfromv$instance;

settermouton

prompt

prompt

prompt^^^^^^^^^^^^^

promptReportName:/LST/&&rpt

prompt^^^^^^^^^^^^^

spool/LST/&&rpt

columnsriheadSmall|Read|IOPS

columnswiheadSmall|Write|IOPS

columntsiheadTotal|Small|IOPS

columnsrpheadSmall|Read|I/O%

columnswpheadSmall|Write|I/O%

columnlriheadLarge|Read|IOPS

columnlwiheadLarge|Write|IOPS

columntliheadTotal|Large|IOPS

columnlrpheadLarge|Read|I/O%

columnlwpheadLarge|Write|I/O%

columntrheadTotal|Read|MBPS

columntwheadTotal|Written|MBPS

columntmheadTotal|MBPS

columnbegin_timefora

columnend_timefora

SELECTend_time

ROUND(sr/inttime)sri

ROUND(sw/inttime)swi

ROUND((sr+sw)/inttime)tsi

ROUND(sr/DECODE((sr+sw)(sr+sw))*)srp

ROUND(sw/DECODE((sr+sw)(sr+sw))*)swp

ROUND(lr/inttime)lri

ROUND(lw/inttime)lwi

ROUND((lr+lw)/inttime)tli

ROUND(lr/DECODE((lr+lw)(lr+lw))*)lrp

ROUND(lw/DECODE((lr+lw)(lr+lw))*)lwp

ROUND((tbr/inttime)/)tr

ROUND((tbw/inttime)/)tw

ROUND(((tbr+tbw)/inttime)/)tm

FROM(

SELECTbegsnap_idbeg_idendsnap_idend_id

begbegin_interval_timebegend_interval_time

endbegin_interval_timebegin_timeendend_interval_timeend_time

(extract(dayfrom(endend_interval_timeendbegin_interval_time))*)+

(extract(hourfrom(endend_interval_timeendbegin_interval_time))*)+

(extract(minutefrom(endend_interval_timeendbegin_interval_time))*)+

(extract(secondfrom(endend_interval_timeendbegin_interval_time))*)inttime

decode(endstartup_timeendbegin_interval_timeendsr(endsrbegsr))sr

decode(endstartup_timeendbegin_interval_timeendsw(endswbegsw))sw

decode(endstartup_timeendbegin_interval_timeendlr(endlrbeglr))lr

decode(endstartup_timeendbegin_interval_timeendlw(endlwbeglw))lw

decode(endstartup_timeendbegin_interval_timeendtbr(endtbrbegtbr))tbr

decode(endstartup_timeendbegin_interval_timeendtbw(endtbwbegtbw))tbw

FROM

(SELECTdba_hist_snapshotsnap_idstartup_timebegin_interval_timeend_interval_time

sum(decode(stat_namephysicalreadtotalIOrequestsvalue)

decode(stat_namephysicalreadtotalmultiblockrequestsvalue))sr

sum(decode(stat_namephysicalwritetotalIOrequestsvalue)

decode(stat_namephysicalwritetotalmultiblockrequestsvalue))sw

sum(decode(stat_namephysicalreadtotalmultiblockrequestsvalue))lr

sum(decode(stat_namephysicalwritetotalmultiblockrequestsvalue))lw

sum(decode(stat_namephysicalreadtotalbytesvalue))tbr

sum(decode(stat_namephysicalwritetotalbytesvalue))tbw

FROMwrh$_sysstatwrh$_stat_namedba_hist_snapshot

WHEREwrh$_sysstatstat_id=wrh$_stat_namestat_id

ANDwrh$_sysstatsnap_id=dba_hist_snapshotsnap_id

groupbydba_hist_snapshotsnap_idstartup_timebegin_interval_timeend_interval_time)beg

(SELECTdba_hist_snapshotsnap_idstartup_timebegin_interval_timeend_interval_time

sum(decode(stat_namephysicalreadtotalIOrequestsvalue)

decode(stat_namephysicalreadtotalmultiblockrequestsvalue))sr

sum(decode(stat_namephysicalwritetotalIOrequestsvalue)

decode(stat_namephysicalwritetotalmultiblockrequestsvalue))sw

sum(decode(stat_namephysicalreadtotalmultiblockrequestsvalue))lr

sum(decode(stat_namephysicalwritetotalmultiblockrequestsvalue))lw

sum(decode(stat_namephysicalreadtotalbytesvalue))tbr

sum(decode(stat_namephysicalwritetotalbytesvalue))tbw

FROMwrh$_sysstatwrh$_stat_namedba_hist_snapshot

WHEREwrh$_sysstatstat_id=wrh$_stat_namestat_id

ANDwrh$_sysstatsnap_id=dba_hist_snapshotsnap_id

groupbydba_hist_snapshotsnap_idstartup_timebegin_interval_timeend_interval_time)end

WHEREbegsnap_id+=endsnap_id

)

orderby

/

spooloff

从一个纯粹的I/O透视图了解一个应用程序是配置存储的一个关键方面Oracle 具有许多I/O类型需要进行匹配取样和关联到存储在Oracle 中有服务器进程产生的I/O这些服务器进程是由用户多数据库写入检查点活动日志记录工具(它不只是记录更新完成了还要从在线日志读取并通过存档文件过程写到存档文件日志中)产生的还有一些内部的决定规模和I/O频率的I/OOracle是一个非常复杂的包含很多进程的系统不了解你的磁盘I/O形式就几乎不可能做到恰当的配置

上一篇:在RedHat 7.x 上实现reiserfs & quota

下一篇:测试安装好的Statspack以及使statspack自动收集