PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/bin/
Upload File :
Current File : //bin/mariadb-report
#!/usr/bin/perl

# mariadb-report v4.0 Oct 23 2015
# renamed to from mysqlreport in 2020
# http://hackmysql.com/mysqlreport

# mariadb-report makes an easy-to-read report of important MySQL/MariaDB status values.
# Copyright 2006-2008 Daniel Nichter
# Copyright 2012-2015 Jean Weisbuch
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# The GNU General Public License is available at:
# http://www.gnu.org/copyleft/gpl.html

use strict;
use File::Temp qw(tempfile);
use DBI;
use Getopt::Long;
eval { require Term::ReadKey; };
my $RK = ($@ ? 0 : 1);

sub have_op;

my $WIN = ($^O eq 'MSWin32' ? 1 : 0);
my %op;
my %mycnf; # ~/.my.cnf
my ($tmpfile_fh, $tmpfile);
my ($stat_name, $stat_val, $stat_label);
my $MySQL_version;
my (%stats, %vars); # SHOW STATUS, SHOW VARIABLES
my (%DMS_vals, %Com_vals, %ib_vals);
my $dbh;
my ($questions, $key_read_ratio, $key_write_ratio, $dms, $slow_query_t);
my ($key_cache_block_size, $key_buffer_used, $key_buffer_usage);
my ($qc_mem_used, $qc_hi_r, $qc_ip_r); # Query Cache
my ($ib_bp_used, $ib_bp_total, $ib_bp_read_ratio);
my ($relative_live, $relative_infiles);
my $real_uptime;
my (%stats_present, %stats_past); # For relative reports
my ($pagecache_read_ratio, $pagecache_write_ratio, $pagecache_block_size, $pagecache_buffer_used, $pagecache_buffer_usage); # AriaDB pagecache stats
my ($binlog_cache_ratio, $binlog_stmt_cache_ratio); # binary log cache
my $dbms;
my ($rows, $rows_using_indexes);

GetOptions (
   \%op,
   "user=s",
   "password:s",
   "host=s",
   "port=s",
   "socket=s",
   "no-mycnf",
   "infile|in=s",
   "outfile=s",
   "flush-status",
   "email=s",
   "r|relative:i",
   "c|report-count=i",
   "detach",
   "help|?",
   "debug"
);

show_help_and_exit() if $op{'help'};

get_user_mycnf() unless $op{'no-mycnf'};

# Command line options override ~/.my.cnf
$mycnf{'host'}   = $op{'host'}   if have_op 'host';
$mycnf{'port'}   = $op{'port'}   if have_op 'port';
$mycnf{'socket'} = $op{'socket'} if have_op 'socket';
$mycnf{'user'}   = $op{'user'}   if have_op 'user';

$mycnf{'user'} ||= $ENV{'USER'};

if(exists $op{'password'})
{
   if($op{'password'} eq '') # Prompt for password
   {
      Term::ReadKey::ReadMode(2) if $RK;
      print "Password for database user $mycnf{'user'}: ";
      chomp($mycnf{'pass'} = <STDIN>);
      Term::ReadKey::ReadMode(0), print "\n" if $RK;
   }
   else { $mycnf{'pass'} = $op{'password'}; } # Use password given on command line
}

$op{'com'} ||= 3;
$op{'c'}   ||= 1; # Used in collect_reports() if --r given integer value

$relative_live    = 0;
$relative_infiles = 0;

if(defined $op{'r'})
{
   if($op{r}) { $relative_live    = 1; }  # if -r was given an integer value
   else       { $relative_infiles = 1; }
}

# The report is written to a tmp file first.
# Later it will be moved to $op{'outfile'} or emailed $op{'email'} if needed.
($tmpfile_fh, $tmpfile) = tempfile() or die "Cannot open temporary file for writing: $!\n";

if($op{'detach'})
{
   $SIG{'TERM'} = 'sig_handler';

   if(fork())
   {
      print "mariadb-report has forked and detached.\n";
      print "While running detached, mariadb-report writes reports to '$tmpfile'.\n";

      exit;
   }

   open(STDIN, "</dev/null");
   open(STDOUT, "> $tmpfile") or die "Cannot dup STDOUT: $!\n";
   open(STDERR, "> $tmpfile") or die "Cannot dup STDERR: $!\n";
}

select $tmpfile_fh;
$| = 1 if ($op{'detach'} || $relative_live);

print "tmp file: $tmpfile\n" if $op{debug};

# Connect to MySQL/MariaDB
if(!$op{'infile'} && !$relative_infiles)
{
   connect_to_MySQL();
}

my $have_innodb_vals = 1; # This might be set to 0 later in get_MySQL_version()
my $have_aria_vals = 0;
my $have_subquerycache_vals = 0;
my $have_binlog_vals = 0;
my $have_tokudb_engine = 0;
my $use_thread_pool = 0;

if(defined $op{'r'})
{
   if($relative_live)
   {
      print STDERR "mariadb-report is writing relative reports to '$tmpfile'.\n" unless $op{'detach'};
      get_MySQL_version();
      collect_reports();
   }

   if($relative_infiles) { read_relative_infiles(); }
}
else
{
   if(!$op{'infile'})
   {
      get_MySQL_version();
      get_vals();
      get_vars();
   }
   else
   {
      read_infile($op{'infile'});
   }

   get_Com_values();

   set_myisam_vals();
   set_ib_vals() if $have_innodb_vals;
   set_aria_vals() if $have_aria_vals;
   set_subquerycache_vals() if $have_subquerycache_vals;
   set_binlog_vals() if $have_binlog_vals;

   write_report();
}

exit_tasks_and_cleanup();

exit;

#
# Subroutines
#
sub show_help_and_exit
{
   print <<"HELP";
mariadb-report v4.0 Oct 23 2015
mariadb-report makes an easy-to-read report of important MySQL/MariaDB status values.

Command line options (abbreviations work):
   --user USER       Connect to MySQL as USER
   --password PASS   Use PASS or prompt for MySQL user's password
   --host ADDRESS    Connect to MySQL at ADDRESS
   --port PORT       Connect to MySQL at PORT
   --socket SOCKET   Connect to MySQL at SOCKET
   --no-mycnf        Don't read ~/.my.cnf
   --infile FILE     Read status values from FILE instead of MySQL
   --outfile FILE    Write report to FILE
   --email ADDRESS   Email report to ADDRESS (doesn't work on Windows)
   --flush-status    Issue FLUSH STATUS; after getting current values
   --relative X      Generate relative reports. If X is an integer,
                     reports are live from the MySQL server X seconds apart.
                     If X is a list of infiles (file1 file2 etc.),
                     reports are generated from the infiles in the order
                     that they are given.
   --report-count N  Collect N number of live relative reports (default 1)
   --detach          Fork and detach from terminal (run in background)
   --help            Prints this
   --debug           Print debugging information

Visit http://hackmysql.com/mysqlreport for more information.
HELP

   exit;
}

sub get_user_mycnf
{
   print "get_user_mycnf\n" if $op{debug};

   return if $WIN;
   open MYCNF, "$ENV{HOME}/.my.cnf" or return;
   while(<MYCNF>)
   {
      if(/^(.+?)\s*=\s*"?(.+?)"?\s*$/)
      {
         $mycnf{$1} = $2;
         print "get_user_mycnf: read '$1 = $2'\n" if $op{debug};
      }
   }
   $mycnf{'pass'} ||= $mycnf{'password'} if exists $mycnf{'password'};
   close MYCNF;
}

sub connect_to_MySQL
{
   print "connect_to_MySQL\n" if $op{debug};

   my $dsn;

   if($mycnf{'socket'} && -S $mycnf{'socket'})
   {
      $dsn = "DBI:MariaDB:mariadb_socket=$mycnf{socket}";
   }
   elsif($mycnf{'host'})
   {
      $dsn = "DBI:MariaDB:host=$mycnf{host}" . ($mycnf{port} ? ";port=$mycnf{port}" : "");
   }
   else
   {
      $dsn = "DBI:MariaDB:host=localhost";
   }

   print "connect_to_MySQL: DBI DSN: $dsn\n" if $op{debug};

   $dbh = DBI->connect($dsn, $mycnf{'user'}, $mycnf{'pass'}) or die;
}

sub collect_reports
{
   print "collect_reports\n" if $op{debug};

   my $i;

   get_vals();
   get_vars();

   get_Com_values();

   %stats_past = %stats;

   set_myisam_vals();
   set_ib_vals() if $have_innodb_vals;
   set_aria_vals() if $have_aria_vals;
   set_subquerycache_vals() if $have_subquerycache_vals;
   set_binlog_vals() if $have_binlog_vals;

   print "#\n# Beginning report, 0 0:0:0\n#\n";

   write_report();

   for($i = 0; $i < $op{'c'}; $i++)
   {
      $dbh->disconnect();

      sleep($op{'r'});

      connect_to_MySQL();

      print "\n#\n# Interval report " , $i + 1 , ", +", sec_to_dhms(($i + 1) * $op{'r'}), "\n#\n";

      get_vals();

      write_relative_report();
   }
}

sub read_relative_infiles
{
   print "read_relative_infiles\n" if $op{debug};

   my $slurp;    # Used to check infiles for multiple sets of status values
   my $n_stats;  # Number of multiple sets of status values in an infile
   my $infile;
   my $report_n; # Report number

   $report_n = 1;

   foreach $infile (@ARGV)
   {
      # Read all of infile into $slurp
      open INFILE, "< $infile" or warn and next;
      $slurp = do { local $/;  <INFILE> };
      close INFILE;

      $n_stats = 0;

      # Count number of status value sets
      $n_stats++ while $slurp =~ /Aborted_clients/g;

      print "read_relative_infiles: found $n_stats sets of status values in file '$infile'\n"
         if $op{debug};

      if($n_stats == 1)
      {
         read_infile($infile);
         relative_infile_report($report_n++);
      }

      if($n_stats > 1)
      {
         my @tmpfile_fh;
         my @tmpfile_name;
         my $i;
         my $stat_n;  # Status value set number

         # Create a tmp file for each set of status values
         for($i = 0; $i < $n_stats; $i++)
         {
            my ($fh, $name) = tempfile()
               or die "read_relative_infiles: cannot open temporary file for writing: $!\n";

            push(@tmpfile_fh, $fh);
            push(@tmpfile_name, $name);

            print "read_relative_infiles: created tmp file '$name' for set $i\n" if $op{debug};
         }

         $i = 0;
         $stat_n = 0;

         select $tmpfile_fh[$i];

         # Read infile again and copy each set of status values to separate tmp files
         open INFILE, "< $infile" or warn and next;
         while(<INFILE>)
         {
            next if /^\+/;
            next if /^$/;

            # The infile must begin with the system variable values.
            # Therefore, the first occurrence of Aborted_clients indicates the beginning
            # of the first set of status values if no sets have occurred yet ($stat_n == 0).
            # In this case, the following status values are printed to the current fh,
            # along with the system variable values read thus far, until Aborted_clients
            # occurs again. Then begins the second and subsequent sets of status values.

            if(/Aborted_clients/)
            {
               print and next if $stat_n++ == 0;
               select $tmpfile_fh[++$i];
            }

            print;
         }
         close INFILE;

         # Re-select the main tmp file into which the reports are being written.
         select $tmpfile_fh;

         for($i = 0; $i < $n_stats; $i++)
         {
            close $tmpfile_fh[$i];

            print "read_relative_infiles: reading set $i tmp file '$tmpfile_name[$i]'\n"
               if $op{debug};

            read_infile($tmpfile_name[$i]);
            relative_infile_report($report_n++);

            if($WIN) { `del $tmpfile_name[$i]`;   }
            else     { `rm -f $tmpfile_name[$i]`; }

            print "read_relative_infiles: deleted set $i tmp file '$tmpfile_name[$i]'\n"
               if $op{debug};
         }

      } # if($n_stats > 1)
   } # foreach $infile (@files)
}

sub relative_infile_report
{
   print "relative_infile_report\n" if $op{debug};

   my $report_n = shift;

   if($report_n == 1)
   {
      get_Com_values();

      %stats_past = %stats;

      set_myisam_vals();
      set_ib_vals() if $have_innodb_vals;
      set_aria_vals() if $have_aria_vals;
      set_subquerycache_vals() if $have_subquerycache_vals;
      set_binlog_vals() if $have_binlog_vals;

      print "#\n# Beginning report, 0 0:0:0\n#\n";

      write_report();
   }
   else
   {
      print "\n#\n# Interval report ", $report_n - 1, ", +",
         sec_to_dhms($stats{Uptime} - $stats_past{Uptime}),
         "\n#\n";

      write_relative_report();
   }
}

sub get_vals
{
   print "get_vals\n" if $op{debug};

   my (@row, $query);

   # Get status values
   if($MySQL_version >= 50002)
   {
      $query = $dbh->prepare("SHOW GLOBAL STATUS;");
   }
   else
   {
      $query = $dbh->prepare("SHOW STATUS;");
   }
   $query->execute();
   # To avoid problems if the variable capitalization would change (eg. TokuDB on MariaDB 5.5 => 10.0), the $stats index is forced to have its first char uppercase and the rest lowercase
   while(@row = $query->fetchrow_array()) { $stats{ucfirst(lc($row[0]))} = $row[1]; }
   $query->finish();

   $real_uptime = $stats{'Uptime'};
}

sub get_vars
{
   print "get_vars\n" if $op{debug};

   my (@row, $query);

   # Get server system variables
   $query = $dbh->prepare("SHOW VARIABLES;");
   $query->execute();
   while(@row = $query->fetchrow_array()) { $vars{$row[0]} = $row[1]; }
   $query->finish();
   # table_cache was renamed to table_open_cache in MySQL 5.1.3
   if($MySQL_version >= 50103)
   {
      $vars{'table_cache'} = $vars{'table_open_cache'};
   }
   # log_slow_queries was renamed to slow_query_log in MySQL 5.1.29
   if($MySQL_version >= 50129)
   {
      $vars{'log_slow_queries'} = $vars{'slow_query_log'};
   }
}

sub read_infile
{
   print "read_infile\n" if $op{debug};

   my $infile = shift;

   # Default required system variable values if not set in INFILE.
   # As of mysqlreport v3.5 the direct output from SHOW VARIABLES;
   # can be put into INFILE instead. See http://hackmysql.com/mysqlreportdoc
   # for details.
   $vars{'version'} = "0.0.0"         if !exists $vars{'version'};
   $vars{'table_cache'} = 64          if !exists $vars{'table_cache'};
   $vars{'max_connections'} = 100     if !exists $vars{'max_connections'};
   $vars{'key_buffer_size'} = 8388600 if !exists $vars{'key_buffer_size'}; # 8M
   $vars{'thread_cache_size'} = 0     if !exists $vars{'thread_cache_size'};
   $vars{'tmp_table_size'} = 0        if !exists $vars{'tmp_table_size'};
   $vars{'long_query_time'} = '?'     if !exists $vars{'long_query_time'};
   $vars{'log_slow_queries'} = '?'    if !exists $vars{'log_slow_queries'};

   # One should also add:
   #    key_cache_block_size
   #    query_cache_size
   # to INFILE if needed.

   open INFILE, "< $infile" or die "Cannot open INFILE '$infile': $!\n";

   while(<INFILE>)
   {
      last if !defined $_;

      next if /^\+/;  # skip divider lines
      next if /^$/;   # skip blank lines

      next until /(Aborted_clients|back_log|=)/;

      if($1 eq 'Aborted_clients')  # status values
      {
         print "read_infile: start stats\n" if $op{debug};

         while($_)
         {
            chomp;
            if(/([A-Za-z_]+)[\s\t|]+(\d+)/)
            {
               $stats{$1} = $2;
               print "read_infile: save $1 = $2\n" if $op{debug};
            }
            else { print "read_infile: ignore '$_'\n" if $op{debug}; }

            last if $1 eq 'Uptime';  # exit while() if end of status values
            $_ = <INFILE>;  # otherwise, read next line of status values
         }
      }
      elsif($1 eq 'back_log')  # system variable values
      {
         print "read_infile: start vars\n" if $op{debug};

         while($_)
         {
            chomp;
            if(/([A-Za-z_]+)[\s\t|]+([\w\.\-]+)/)  # This will exclude some vars
            {                                      # like pid_file which we don't need
               $vars{$1} = $2;
               print "read_infile: save $1 = $2\n" if $op{debug};
            }
            else { print "read_infile: ignore '$_'\n" if $op{debug}; }

            last if $1 eq 'wait_timeout';  # exit while() if end of vars
            $_ = <INFILE>;  # otherwise, read next line of vars
         }
      }
      elsif($1 eq '=')  # old style, manually added system variable values
      {
         print "read_infile: start old vars\n" if $op{debug};

         while($_ && $_ =~ /=/)
         {
            chomp;
            if(/^\s*(\w+)\s*=\s*([0-9.]+)(M*)\s*$/)  # e.g.: key_buffer_size = 128M
            {
               $vars{$1} = ($3 ? $2 * 1024 * 1024 : $2);
               print "read_infile: read '$_' as $1 = $vars{$1}\n" if $op{debug};
            }
            else { print "read_infile: ignore '$_'\n" if $op{debug}; }

            $_ = <INFILE>;  # otherwise, read next line of old vars
         }

         redo;
      }
      else
      {
         print "read_infile: unrecognized line: '$_'\n" if $op{debug};
      }
   }

   close INFILE;

   $real_uptime = $stats{'Uptime'};

   $vars{'table_cache'} = $vars{'table_open_cache'} if exists $vars{'table_open_cache'};

   get_MySQL_version();
}

sub get_MySQL_version
{
   print "get_MySQL_version\n" if $op{debug};

   return if $MySQL_version;

   my ($major, $minor, $patch);

   if($op{'infile'} || $relative_infiles)
   {
      ($major, $minor, $patch) = ($vars{'version'} =~ /^(\d{1,2})\.(\d{1,2})\.(\d{1,2})/);
      if($vars{'version'} =~ /^\d{1,2}\.\d{1,2}\.\d{1,2}-MariaDB/) {
        print "MariaDB detected\n" if $op{debug};
        $dbms = "MariaDB";
      } else {
        $dbms = "MySQL";
      }
   }
   else
   {
      my (@row, $query);

      $query = $dbh->prepare("SHOW VARIABLES LIKE 'version';");
      $query->execute();
      @row = $query->fetchrow_array();
      $query->finish();
      ($major, $minor, $patch) = ($row[1] =~ /^(\d{1,2})\.(\d{1,2})\.(\d{1,2})/);
      if($row[1] =~ /^\d{1,2}\.\d{1,2}\.\d{1,2}-MariaDB/)
      {
         print "MariaDB detected\n" if $op{debug};
         $dbms = "MariaDB";
      }
      else
      {
         $dbms = "MySQL";
      }
   }

   # The major version number is kept as is while the minor version and the revision number are forced to 2 digits
   # e.g.: 5.5.9 will be 50509, 10.0.5 will be 100005 and 10.1.23 will be 100123
   $MySQL_version = sprintf("%d%02d%02d", $major, $minor, $patch);
   print "Version $MySQL_version\n" if $op{debug};

   # Innodb_ status values were added in 5.0.2
   if($MySQL_version < 50002)
   {
      $have_innodb_vals = 0;
      print "get_MySQL_version: no InnoDB reports because MySQL version is older than 5.0.2\n" if $op{debug};
   } else {
      $have_innodb_vals = $dbh->selectall_arrayref("SELECT SUPPORT FROM information_schema.engines WHERE ENGINE = 'InnoDB';", undef)->[0][0];
      if(defined($have_innodb_vals) && ($have_innodb_vals eq "YES" || $have_innodb_vals eq "DEFAULT"))
      {
         print "InnoDB detected\n" if $op{debug};
         $have_innodb_vals = 1;
      } else {
         print "InnoDB is not activated\n" if $op{debug};
         $have_innodb_vals = 0;
      }
   }

   if($dbms eq "MariaDB") {
      $have_aria_vals = $dbh->selectall_arrayref("SELECT SUPPORT FROM information_schema.engines WHERE ENGINE = 'Aria';", undef)->[0][0];
      if(defined($have_aria_vals) && $have_aria_vals eq "YES")
      {
         print "Aria engine detected\n" if $op{debug};
         $have_aria_vals = 1;
      } else {
         $have_aria_vals = 0;
      }

      # MariaDB 5.3+, activated by default since 5.3.2
      $have_subquerycache_vals = $dbh->selectall_arrayref("SELECT VARIABLE_VALUE REGEXP ',subquery_cache=on,|^subquery_cache=on,|,subquery_cache=on\$' AS SUBQUERY_CACHE FROM information_schema.global_variables WHERE VARIABLE_NAME = 'optimizer_switch';", undef)->[0][0];
      if(defined($have_subquerycache_vals) && $have_subquerycache_vals eq "1")
      {
         print "Subquery cache is activated\n" if $op{debug};
         $have_subquerycache_vals = 1;
      } else {
         $have_subquerycache_vals = 0;
      }
   }

   if($MySQL_version >= 50000)
   {
      # These checks use the 'information_schema' virtual database that has been added on MySQL 5.0

      # MariaDB 5.5.21+ and Percona Server 5.5.30+ use the same thread pool implementation
      $use_thread_pool = $dbh->selectall_arrayref("SELECT VARIABLE_VALUE FROM information_schema.global_variables WHERE VARIABLE_NAME = 'thread_handling';", undef)->[0][0];
      if(defined($use_thread_pool) && $use_thread_pool eq "pool-of-threads") {
         print "Thread pool is used\n" if $op{debug};
         $use_thread_pool = 1;
      } else {
         $use_thread_pool = 0;
      }

      $have_binlog_vals = $dbh->selectall_arrayref("SELECT VARIABLE_VALUE FROM information_schema.global_variables WHERE VARIABLE_NAME = 'log_bin';", undef)->[0][0];
      if(defined($have_binlog_vals) && $have_binlog_vals eq "ON")
      {
         print "Binary log is activated\n" if $op{debug};
         $have_binlog_vals = 1;
      } else {
         $have_binlog_vals = 0;
      }

      $have_tokudb_engine = $dbh->selectall_arrayref("SELECT SUPPORT FROM information_schema.engines WHERE ENGINE = 'TokuDB';", undef)->[0][0];
      if(defined($have_tokudb_engine) && ($have_tokudb_engine eq "YES" || $have_tokudb_engine eq "DEFAULT"))
      {
         print "TokuDB detected\n" if $op{debug};
         $have_tokudb_engine = 1;
      } else {
         $have_tokudb_engine = 0;
      }
   }
}

sub set_myisam_vals
{
   print "set_myisam_vals\n" if $op{debug};

# should be moved elsewere
   $questions = $stats{'Questions'};

   $key_read_ratio = sprintf "%.2f",
                     ($stats{'Key_read_requests'} ?
                      100 - ($stats{'Key_reads'} / $stats{'Key_read_requests'}) * 100 :
                      0);

   $key_write_ratio = sprintf "%.2f",
                      ($stats{'Key_write_requests'} ?
                       100 - ($stats{'Key_writes'} / $stats{'Key_write_requests'}) * 100 :
                       0);

   $key_cache_block_size = (defined $vars{'key_cache_block_size'} ?
                            $vars{'key_cache_block_size'} :
                            1024);

   $key_buffer_used = $stats{'Key_blocks_used'} * $key_cache_block_size;

   if(defined $stats{'Key_blocks_unused'}) # MySQL 4.1.2+
   {
      $key_buffer_usage =  $vars{'key_buffer_size'} -
                           ($stats{'Key_blocks_unused'} * $key_cache_block_size);
   }
   else { $key_buffer_usage = -1; }

   # Data Manipulation Statements: http://dev.mysql.com/doc/refman/5.0/en/data-manipulation.html
   %DMS_vals =
   (
      SELECT  => $stats{'Com_select'},
      INSERT  => $stats{'Com_insert'}  + $stats{'Com_insert_select'},
      REPLACE => $stats{'Com_replace'} + $stats{'Com_replace_select'},
      UPDATE  => $stats{'Com_update'}  +
                 (exists $stats{'Com_update_multi'} ? $stats{'Com_update_multi'} : 0),
      DELETE  => $stats{'Com_delete'}  +
                 (exists $stats{'Com_delete_multi'} ? $stats{'Com_delete_multi'} : 0)
   );

   $dms = $DMS_vals{SELECT} + $DMS_vals{INSERT} + $DMS_vals{REPLACE} + $DMS_vals{UPDATE} + $DMS_vals{DELETE};

   $slow_query_t = format_u_time($vars{long_query_time});
}

sub set_ib_vals
{
   print "set_ib_vals\n" if $op{debug};

   $ib_bp_used  = ($stats{'Innodb_buffer_pool_pages_total'} -
                   $stats{'Innodb_buffer_pool_pages_free'}) *
                   $stats{'Innodb_page_size'};

   $ib_bp_total = $stats{'Innodb_buffer_pool_pages_total'} * $stats{'Innodb_page_size'};

   $ib_bp_read_ratio = sprintf "%.2f",
                       ($stats{'Innodb_buffer_pool_read_requests'} ?
                        100 - ($stats{'Innodb_buffer_pool_reads'} /
                           $stats{'Innodb_buffer_pool_read_requests'}) * 100 :
                        0);
}

sub set_aria_vals
{
   print "set_aria_vals\n" if $op{debug};

   $pagecache_read_ratio = sprintf "%.2f",
                     ($stats{'Aria_pagecache_read_requests'} ?
                      100 - ($stats{'Aria_pagecache_reads'} / $stats{'Aria_pagecache_read_requests'}) * 100 :
                      0);

   $pagecache_write_ratio = sprintf "%.2f",
                      ($stats{'Aria_pagecache_write_requests'} ?
                       100 - ($stats{'Aria_pagecache_writes'} / $stats{'Aria_pagecache_write_requests'}) * 100 :
                       0);

   $pagecache_block_size = (defined $vars{'aria_block_size'} ?
                            $vars{'aria_block_size'} :
                            1024);

   $pagecache_buffer_used = $stats{'Aria_pagecache_blocks_used'} * $pagecache_block_size;

   $pagecache_buffer_usage =  $vars{'aria_pagecache_buffer_size'} -
                      ($stats{'Aria_pagecache_blocks_unused'} * $pagecache_block_size);
}

sub set_subquerycache_vals
{
   print "set_subquerycache_vals\n" if $op{debug};
}

sub set_binlog_vals
{
   print "set_binlog_vals\n" if $op{debug};

   if($stats{'Binlog_cache_use'} gt 0) { $binlog_cache_ratio = $stats{'Binlog_cache_disk_use'} / $stats{'Binlog_cache_use'}; }
   else { $binlog_cache_ratio = 0; }

   if(defined($stats{'Binlog_stmt_cache_use'}) && $stats{'Binlog_stmt_cache_use'} gt 0) { $binlog_stmt_cache_ratio = $stats{'Binlog_stmt_cache_disk_use'} / $stats{'Binlog_stmt_cache_use'}; }
   else { $binlog_stmt_cache_ratio = 0; }
}

sub write_relative_report
{
   print "write_relative_report\n" if $op{debug};

   %stats_present = %stats;

   for(keys %stats)
   {
      if($stats_past{$_} =~ /\d+/)
      {
         if($stats_present{$_} >= $stats_past{$_}) # Avoid negative values
         {
            $stats{$_} = $stats_present{$_} - $stats_past{$_};
         }
      }
   }

   # These values are either "at present" or "high water marks".
   # Therefore, it is more logical to not relativize these values.
   # Doing otherwise causes strange and misleading values.
   $stats{'Key_blocks_used'}      = $stats_present{'Key_blocks_used'};
   $stats{'Open_tables'}          = $stats_present{'Open_tables'};
   $stats{'Max_used_connections'} = $stats_present{'Max_used_connections'};
   $stats{'Threads_running'}      = $stats_present{'Threads_running'};
   $stats{'Threads_connected'}    = $stats_present{'Threads_connected'};
   $stats{'Threads_cached'}       = $stats_present{'Threads_cached'};
   $stats{'Qcache_free_blocks'}   = $stats_present{'Qcache_free_blocks'};
   $stats{'Qcache_total_blocks'}  = $stats_present{'Qcache_total_blocks'};
   $stats{'Qcache_free_memory'}   = $stats_present{'Qcache_free_memory'};
   if($have_innodb_vals)
   {
      $stats{'Innodb_page_size'}                 = $stats_present{'Innodb_page_size'};
      $stats{'Innodb_buffer_pool_pages_data'}    = $stats_present{'Innodb_buffer_pool_pages_data'};
      $stats{'Innodb_buffer_pool_pages_dirty'}   = $stats_present{'Innodb_buffer_pool_pages_dirty'};
      $stats{'Innodb_buffer_pool_pages_free'}    = $stats_present{'Innodb_buffer_pool_pages_free'};
      $stats{'Innodb_buffer_pool_pages_latched'} = $stats_present{'Innodb_buffer_pool_pages_latched'};
      $stats{'Innodb_buffer_pool_pages_misc'}    = $stats_present{'Innodb_buffer_pool_pages_misc'};
      $stats{'Innodb_buffer_pool_pages_total'}   = $stats_present{'Innodb_buffer_pool_pages_total'};
      $stats{'Innodb_data_pending_fsyncs'}       = $stats_present{'Innodb_data_pending_fsyncs'};
      $stats{'Innodb_data_pending_reads'}        = $stats_present{'Innodb_data_pending_reads'};
      $stats{'Innodb_data_pending_writes'}       = $stats_present{'Innodb_data_pending_writes'};

      # Innodb_row_lock_ values were added in MySQL 5.0.3
      if($MySQL_version >= 50003)
      {
         $stats{'Innodb_row_lock_current_waits'} = $stats_present{'Innodb_row_lock_current_waits'};
         $stats{'Innodb_row_lock_time_avg'}      = $stats_present{'Innodb_row_lock_time_avg'};
         $stats{'Innodb_row_lock_time_max'}      = $stats_present{'Innodb_row_lock_time_max'};
      }
   }
  if($have_aria_vals)
  {
     $stats{'Aria_pagecache_blocks_used'} = $stats_present{'Aria_pagecache_blocks_used'};
  }

   get_Com_values();

   %stats_past = %stats_present;

   set_myisam_vals();
   set_ib_vals() if $have_innodb_vals;
   set_aria_vals() if $have_aria_vals;
   set_subquerycache_vals() if $have_subquerycache_vals;
   set_binlog_vals() if $have_binlog_vals;

   write_report();
}

sub write_report
{
   print "write_report\n" if $op{debug};

   $~ = 'MYSQL_TIME', write;
   $~ = 'KEY_BUFF_MAX', write;
   if($key_buffer_usage != -1) { $~ = 'KEY_BUFF_USAGE', write }
   $~ = 'KEY_RATIOS', write;
   write_DTQ();
   $~ = 'SLOW_DMS', write;
   write_DMS();
   write_Com();
   write_Rows();
   $~ = 'SAS', write;
   write_qcache();
   $~ = 'REPORT_END', write;
   $~ = 'THREADS', write;
   if($use_thread_pool)
   {
      $~ = 'THREADPOOL', write;
   } else {
      $~ = 'THREADPERCONNECTION', write;
   }
   $~ = 'TAB', write;

   write_InnoDB() if $have_innodb_vals;
   write_Aria() if $have_aria_vals;
   write_Subquerycache() if $have_subquerycache_vals;
   write_Binlog() if $have_binlog_vals;
   write_TokuDB() if $have_tokudb_engine;
}

sub sec_to_dhms # Seconds to days+hours:minutes:seconds
{
   my $s = shift;
   my ($d, $h, $m) = (0, 0, 0);

   return '0 0:0:0' if $s <= 0;

   if($s >= 86400)
   {
      $d = int $s / 86400;
      $s -= $d * 86400;
   }

   if($s >= 3600)
   {
     $h = int $s / 3600;
     $s -= $h * 3600;
   }

   $m = int $s / 60;
   $s -= $m * 60;

   return "$d+$h:$m:$s";
}

sub make_short
{
   my ($number, $kb, $d) = @_;
   my $n = 0;
   my $short;

   $d ||= 2;

   if($kb) { while ($number > 1023) { $number /= 1024; $n++; }; }
   else { while ($number > 999) { $number /= 1000; $n++; }; }

   $short = sprintf "%.${d}f%s", $number, ('','k','M','G','T')[$n];
   if($short =~ /^(.+)\.(00)$/) { return $1; } # 12.00 -> 12 but not 12.00k -> 12k

   return $short;
}

# What began as a simple but great idea has become the new standard:
# long_query_time in microseconds. For MySQL 5.1.21+ this is now
# standard. For 4.1 and 5.0 patches, the architects of this idea
# provide: http://www.mysqlperformanceblog.com/mysql-patches/
# Relevant notes in MySQL manual:
# http://dev.mysql.com/doc/refman/5.1/en/slow-query-log.html
#
# The format_u_time sub simply beautifies long_query_time.

sub format_u_time  # format microsecond (µ) time value
{
   # 0.000000 - 0.000999 = 0 - 999 µ
   # 0.001000 - 0.999999 = 1 ms - 999.999 ms
   # 1.000000 - n.nnnnnn = 1 s - n.nnnnn s

   my $t = shift;
   my $f;  # formatted µ time
   my $u = chr(($WIN ? 230 : 181));

   $t = 0 if $t < 0;

   if($t > 0 && $t <= 0.000999)
   {
      $f = ($t * 1000000) . " $u";
   }
   elsif($t >= 0.001000 && $t <= 0.999999)
   {
      $f = ($t * 1000) . ' ms';
   }
   elsif($t >= 1)
   {
      $f = ($t * 1) . ' s';  # * 1 to remove insignificant zeros
   }
   else
   {
      $f = 0;  # $t should = 0 at this point
   }

   return $f;
}

sub perc # Percentage
{
   my($is, $of) = @_;
   $is = 0 if (not defined $is);
   return sprintf "%.2f", ($is * 100) / ($of ||= 1);
}

sub t # Time average per second
{
   my $val = shift;
   return 0 if !$val;
   return(make_short($val / $stats{'Uptime'}, 0, 1));
}

sub email_report # Email given report to $op{'email'}
{
   print "email_report\n" if $op{debug};

   return if $WIN;

   my $report = shift;

   open SENDMAIL, "|/usr/sbin/sendmail -t";
   print SENDMAIL "From: mariadb-report\n";
   print SENDMAIL "To: $op{email}\n";
   print SENDMAIL "Subject: $dbms status report on " . ($mycnf{'host'} || 'localhost') . "\n\n";
   print SENDMAIL `cat $report`;
   close SENDMAIL;
}

sub cat_report # Print given report to screen
{
   print "cat_report\n" if $op{debug};

   my $report = shift;
   my @report;

   open REPORT, "< $report";
   @report = <REPORT>;
   close REPORT;
   print @report;
}

sub get_Com_values
{
   print "get_Com_values\n" if $op{debug};

   %Com_vals = ();

   # Make copy of just the Com_ values
   for(keys %stats)
   {
      if(grep /^Com_/, $_ and $stats{$_} > 0)
      {
         /^Com_(.*)/;
         $Com_vals{$1} = $stats{$_};
      }
   }

   # Remove DMS values
   delete $Com_vals{'select'};
   delete $Com_vals{'insert'};
   delete $Com_vals{'insert_select'};
   delete $Com_vals{'replace'};
   delete $Com_vals{'replace_select'};
   delete $Com_vals{'update'};
   delete $Com_vals{'update_multi'} if exists $Com_vals{'update_multi'};
   delete $Com_vals{'delete'};
   delete $Com_vals{'delete_multi'} if exists $Com_vals{'delete_multi'};
}

sub write_DTQ # Write DTQ report in descending order by values
{
   print "write_DTQ\n" if $op{debug};

   $~ = 'DTQ';

   my %DTQ;
   my $first = 1;

   # Total Com values
   $stat_val = 0;
   for(values %Com_vals) { $stat_val += $_; }
   $DTQ{'Com_'} = $stat_val;

   $DTQ{'DMS'}      = $dms;
   $DTQ{'QC Hits'}  = $stats{'Qcache_hits'} if $stats{'Qcache_hits'} != 0;
   $DTQ{'COM_QUIT'} = int (($stats{'Connections'} - 2) - ($stats{'Aborted_clients'} / 2));

   $stat_val = 0;
   for(values %DTQ) { $stat_val += $_; }
   if($questions != $stat_val)
   {
      $DTQ{($questions > $stat_val ? '+Unknown' : '-Unknown')} = abs $questions - $stat_val;
   }

   for(sort { $DTQ{$b} <=> $DTQ{$a} } keys(%DTQ))
   {
      if($first) { $stat_label = '%Total:'; $first = 0; }
      else       { $stat_label = ''; }

      $stat_name = $_;
      $stat_val  = $DTQ{$_};
      write;
   }
}

sub write_DMS # Write DMS report in descending order by values
{
   print "write_DMS\n" if $op{debug};

   $~ = 'DMS';

   for(sort { $DMS_vals{$b} <=> $DMS_vals{$a} } keys(%DMS_vals))
   {
      $stat_name = $_;
      $stat_val  = $DMS_vals{$_};
      write;
   }
}

sub write_Com # Write COM report in descending order by values
{
   print "write_Com\n" if $op{debug};

   my $i = $op{'com'};

   $~ = 'COM_1';

   # Total Com values and write first line of COM report
   $stat_label = '%Total:' unless $op{'dtq'};
   $stat_val   = 0;
   for(values %Com_vals) { $stat_val += $_; }
   write;

   $~ = 'COM_2';

   # Sort remaining Com values, print only the top $op{'com'} number of values
   for(sort { $Com_vals{$b} <=> $Com_vals{$a} } keys(%Com_vals))
   {
      $stat_name = $_;
      $stat_val  = $Com_vals{$_};
      write;

      last if !(--$i);
   }
}

sub write_qcache
{
   print "write_qcache\n" if $op{debug};

   # Query cache was added in 4.0.1, but have_query_cache was added in 4.0.2,
   # ergo this method is slightly more reliable
   return if not exists $vars{'query_cache_size'};
   return if $vars{'query_cache_size'} == 0;
   return if defined($vars{'query_cache_type'}) and $vars{'query_cache_type'} eq 'OFF';

   $qc_mem_used = $vars{'query_cache_size'} - $stats{'Qcache_free_memory'};
   $qc_hi_r = sprintf "%.2f", $stats{'Qcache_hits'} / ($stats{'Qcache_inserts'} ||= 1);
   $qc_ip_r = sprintf "%.2f", $stats{'Qcache_inserts'} / ($stats{'Qcache_lowmem_prunes'} ||= 1);

   $~ = 'QCACHE';
   write;
}

sub write_Subquerycache
{
   print "write_Subquerycache\n" if $op{debug};

   return if not defined $stats{'Subquery_cache_hit'};
   return if $stats{'Subquery_cache_hit'} == 0 && $stats{'Subquery_cache_miss'} == 0;

   $~ = 'SUBQUERYCACHE';
   write;
}

sub write_Binlog
{
   print "write_Binlog\n" if $op{debug};

   return if $binlog_cache_ratio == 0 && $binlog_stmt_cache_ratio == 0;
   $~ = 'BINLOG';
   write;
}

sub write_TokuDB
{
   print "write_TokuDB\n" if $op{debug};

   return if $stats{'Tokudb_cachetable_size_current'} == 0;

   $~ = 'TOKUDB';
   write;
}

sub write_InnoDB
{
   print "write_InnoDB\n" if $op{debug};

   return if not defined $stats{'Innodb_page_size'};

   $stats{'Innodb_buffer_pool_pages_latched'} = 0 if not defined $stats{'Innodb_buffer_pool_pages_latched'};

   $~ = 'IB';
   write;

   # Innodb_row_lock_ values were added in MySQL 5.0.3
   if($MySQL_version >= 50003)
   {
      $~ = 'IB_LOCK';
      write;
   }

   # Data, Pages, Rows
   $~ = 'IB_DPR';
   write;
}


sub write_Aria
{
   print "write_Aria\n" if $op{debug};

   return if not defined $stats{'Aria_pagecache_blocks_used'};

   $~ = 'PAGECACHE_BUFF_MAX';
   write;

   if($pagecache_buffer_usage != -1) { $~ = 'PAGECACHE_BUFF_USAGE', write }

   $~ = 'PAGECACHE_RATIOS';
   write;
}

sub write_Rows
{
   print "write_Rows\n" if $op{debug};

   $rows_using_indexes = $stats{'Handler_read_first'} + $stats{'Handler_read_key'} + $stats{'Handler_read_next'} + $stats{'Handler_read_prev'};
   $rows = $rows_using_indexes + $stats{'Handler_read_rnd'} + $stats{'Handler_read_rnd_next'} + $stats{'Sort_rows'};

   $~ = 'ROWS';
   write;
}

sub have_op
{
   my $key = shift;
   return 1 if (exists $op{$key} && $op{$key} ne '');
   return 0;
}

sub sig_handler
{
   print "\nReceived signal at " , scalar localtime , "\n";
   exit_tasks_and_cleanup();
   exit;
}

sub exit_tasks_and_cleanup
{
   print "exit_tasks_and_cleanup\n" if $op{debug};

   close $tmpfile_fh;
   select STDOUT unless $op{'detach'};

   email_report($tmpfile) if $op{'email'};

   cat_report($tmpfile) unless $op{'detach'};

   if($op{'outfile'})
   {
      if($WIN) { `move $tmpfile $op{outfile}`; }
      else     { `mv $tmpfile $op{outfile}`;   }
   }
   else
   {
      unlink $tmpfile;
   }

   if(!$op{'infile'} && !$relative_infiles)
   {
      if($op{'flush-status'})
      {
         my $query = $dbh->prepare("FLUSH STATUS;");
         $query->execute();
         $query->finish();
      }
      $dbh->disconnect();
   }
}

#
# Formats
#

format MYSQL_TIME =
@<<<<<< @<<<<<<<<<<<<<<<<<< uptime @<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<
$dbms, $vars{'version'}, sec_to_dhms($real_uptime), (($op{infile} || $relative_infiles) ? '' : scalar localtime)
.

format KEY_BUFF_MAX =

__ Key _________________________________________________________________
Buffer used   @>>>>>> of  @>>>>>>   %Used: @>>>>>
make_short($key_buffer_used, 1), make_short($vars{'key_buffer_size'}, 1), perc($key_buffer_used, $vars{'key_buffer_size'})
.

format KEY_BUFF_USAGE =
  Current     @>>>>>>              %Usage: @>>>>>
make_short($key_buffer_usage, 1), perc($key_buffer_usage, $vars{'key_buffer_size'})
.

format KEY_RATIOS =
Write hit     @>>>>>%
$key_write_ratio
Read hit      @>>>>>%
$key_read_ratio

__ Questions ___________________________________________________________
Total       @>>>>>>>>    @>>>>>/s
make_short($questions), t($questions)
.

format DTQ =
  @<<<<<<<  @>>>>>>>>    @>>>>>/s  @>>>>>> @>>>>>
$stat_name, make_short($stat_val), t($stat_val), $stat_label, perc($stat_val, $questions)
.

format SLOW_DMS =
Slow @<<<<<<< @>>>>>>    @>>>>>/s          @>>>>>  %DMS: @>>>>> Log: @>>
$slow_query_t, make_short($stats{'Slow_queries'}), t($stats{'Slow_queries'}), perc($stats{'Slow_queries'}, $questions), perc($stats{'Slow_queries'}, $dms), $vars{'log_slow_queries'}
DMS         @>>>>>>>>    @>>>>>/s          @>>>>>
make_short($dms), t($dms), perc($dms, $questions)
.

format DMS =
  @<<<<<<<  @>>>>>>>>    @>>>>>/s          @>>>>>        @>>>>>
$stat_name, make_short($stat_val), t($stat_val), perc($stat_val, $questions), perc($stat_val, $dms)
.

format COM_1 =
Com_        @>>>>>>>>    @>>>>>/s          @>>>>>
make_short($stat_val), t($stat_val), perc($stat_val, $questions)
.

format COM_2 =
  @<<<<<<<<<< @>>>>>>    @>>>>>/s          @>>>>>
$stat_name, make_short($stat_val), t($stat_val), perc($stat_val, $questions)
.

format SAS =

__ SELECT and Sort _____________________________________________________
Scan          @>>>>>>    @>>>>>/s %SELECT: @>>>>>
make_short($stats{'Select_scan'}), t($stats{'Select_scan'}), perc($stats{'Select_scan'}, $stats{'Com_select'})
Range         @>>>>>>    @>>>>>/s          @>>>>>
make_short($stats{'Select_range'}), t($stats{'Select_range'}), perc($stats{'Select_range'}, $stats{'Com_select'})
Full join     @>>>>>>    @>>>>>/s          @>>>>>
make_short($stats{'Select_full_join'}), t($stats{'Select_full_join'}), perc($stats{'Select_full_join'}, $stats{'Com_select'})
Range check   @>>>>>>    @>>>>>/s          @>>>>>
make_short($stats{'Select_range_check'}), t($stats{'Select_range_check'}), perc($stats{'Select_range_check'}, $stats{'Com_select'})
Full rng join @>>>>>>    @>>>>>/s          @>>>>>
make_short($stats{'Select_full_range_join'}), t($stats{'Select_full_range_join'}), perc($stats{'Select_full_range_join'}, $stats{'Com_select'})
Sort scan     @>>>>>>    @>>>>>/s
make_short($stats{'Sort_scan'}), t($stats{'Sort_scan'})
Sort range    @>>>>>>    @>>>>>/s
make_short($stats{'Sort_range'}), t($stats{'Sort_range'})
Sort mrg pass @>>>>>>    @>>>>>/s
make_short($stats{'Sort_merge_passes'}), t($stats{'Sort_merge_passes'})
.

format QCACHE =

__ Query Cache _________________________________________________________
Memory usage  @>>>>>> of  @>>>>>>  %Usage: @>>>>>
make_short($qc_mem_used, 1), make_short($vars{'query_cache_size'}, 1), perc($qc_mem_used, $vars{'query_cache_size'})
Block Fragmnt @>>>>>%
perc($stats{'Qcache_free_blocks'}, $stats{'Qcache_total_blocks'})
Hits          @>>>>>>    @>>>>>/s
make_short($stats{'Qcache_hits'}), t($stats{'Qcache_hits'})
Inserts       @>>>>>>    @>>>>>/s
make_short($stats{'Qcache_inserts'}), t($stats{'Qcache_inserts'})
Insrt:Prune @>>>>>>:1    @>>>>>/s
make_short($qc_ip_r), t($stats{'Qcache_inserts'} - $stats{'Qcache_lowmem_prunes'})
Hit:Insert  @>>>>>>:1
$qc_hi_r, t($qc_hi_r)
.

format SUBQUERYCACHE =

__ Subquery Cache ______________________________________________________
Hit ratio     @>>>>>%
perc($stats{'Subquery_cache_hit'} / ($stats{'Subquery_cache_hit'} + $stats{'Subquery_cache_miss'}))
Hits          @>>>>>>   @>>>>>/s
make_short($stats{'Subquery_cache_hit'}), t($stats{'Subquery_cache_hit'})
Miss          @>>>>>>   @>>>>>/s
make_short($stats{'Subquery_cache_miss'}), t($stats{'Subquery_cache_miss'})
.

# Not really the end...
format REPORT_END =

__ Table Locks _________________________________________________________
Waited      @>>>>>>>>    @>>>>>/s  %Total: @>>>>>
make_short($stats{'Table_locks_waited'}), t($stats{'Table_locks_waited'}), perc($stats{'Table_locks_waited'}, $stats{'Table_locks_waited'} + $stats{'Table_locks_immediate'});
Immediate   @>>>>>>>>    @>>>>>/s
make_short($stats{'Table_locks_immediate'}), t($stats{'Table_locks_immediate'})

__ Tables ______________________________________________________________
Open        @>>>>>>>> of @>>>>>    %Cache: @>>>>>
$stats{'Open_tables'}, $vars{'table_cache'}, perc($stats{'Open_tables'}, $vars{'table_cache'})
Opened      @>>>>>>>>    @>>>>>/s
make_short($stats{'Opened_tables'}), t($stats{'Opened_tables'})

__ Connections _________________________________________________________
Max used    @>>>>>>>> of @>>>>>      %Max: @>>>>>
$stats{'Max_used_connections'}, $vars{'max_connections'}, perc($stats{'Max_used_connections'}, $vars{'max_connections'})
Total       @>>>>>>>>    @>>>>>/s
make_short($stats{'Connections'}), t($stats{'Connections'})

__ Created Temp ________________________________________________________
Disk table  @>>>>>>>>    @>>>>>/s   %Disk: @>>>>>
make_short($stats{'Created_tmp_disk_tables'}), t($stats{'Created_tmp_disk_tables'}), perc($stats{'Created_tmp_disk_tables'}, $stats{'Created_tmp_tables'})
Table       @>>>>>>>>    @>>>>>/s    Size: @>>>>>
make_short($stats{'Created_tmp_tables'}), t($stats{'Created_tmp_tables'}), make_short($vars{'tmp_table_size'}, 1, 1)
File        @>>>>>>>>    @>>>>>/s
make_short($stats{'Created_tmp_files'}), t($stats{'Created_tmp_files'})
.

format THREADS =

__ Threads _____________________________________________________________
Running     @>>>>>>>> of @>>>>>
$stats{'Threads_running'}, $stats{'Threads_connected'}
Created     @>>>>>>>>    @>>>>>/s
make_short($stats{'Threads_created'}), t($stats{'Threads_created'})
Slow        @>>>>>>>>    @>>>>>/s
$stats{'Slow_launch_threads'}, t($stats{'Slow_launch_threads'})
.

format THREADPERCONNECTION =
Cached      @>>>>>>>> of @>>>>>      %Hit: @>>>>>
$stats{'Threads_cached'}, $vars{'thread_cache_size'}, make_short(100 - perc($stats{'Threads_created'}, $stats{'Connections'}))
.

format THREADPOOL =
Threadpool  @>>>>>>>> of @>>>>>     %Used: @>>>>>
$stats{'Threadpool_threads'} + $stats{'Threadpool_idle_threads'}, $vars{'thread_pool_max_threads'}, make_short(perc($stats{'Threadpool_threads'} + $stats{'Threadpool_idle_threads'}, $vars{'thread_pool_max_threads'}))
  Running   @>>>>>>>> of @>>>>>  %Running: @>>>>>
$stats{'Threadpool_threads'}, $vars{'thread_pool_max_threads'}, make_short(perc($stats{'Threadpool_threads'}, $vars{'thread_pool_max_threads'}))
  Idle      @>>>>>>>> of @>>>>>     %Idle: @>>>>>
$stats{'Threadpool_idle_threads'}, $vars{'thread_pool_max_threads'}, make_short(perc($stats{'Threadpool_idle_threads'}, $vars{'thread_pool_max_threads'}))
.

format TAB =

__ Aborted _____________________________________________________________
Clients     @>>>>>>>>    @>>>>>/s
make_short($stats{'Aborted_clients'}), t($stats{'Aborted_clients'})
Connects    @>>>>>>>>    @>>>>>/s
make_short($stats{'Aborted_connects'}), t($stats{'Aborted_connects'})

__ Bytes _______________________________________________________________
Sent        @>>>>>>>>    @>>>>>/s
make_short($stats{'Bytes_sent'}), t($stats{'Bytes_sent'})
Received    @>>>>>>>>    @>>>>>/s
make_short($stats{'Bytes_received'}), t($stats{'Bytes_received'})
.

format IB =

__ InnoDB Buffer Pool __________________________________________________
Usage         @>>>>>> of  @>>>>>>  %Usage: @>>>>>
make_short($ib_bp_used, 1), make_short($ib_bp_total, 1), perc($ib_bp_used, $ib_bp_total)
Read hit      @>>>>>%
$ib_bp_read_ratio;
Pages
  Free      @>>>>>>>>              %Total: @>>>>>
make_short($stats{'Innodb_buffer_pool_pages_free'}), perc($stats{'Innodb_buffer_pool_pages_free'}, $stats{'Innodb_buffer_pool_pages_total'})
  Data      @>>>>>>>>                      @>>>>>  %Drty: @>>>>>
make_short($stats{'Innodb_buffer_pool_pages_data'}), perc($stats{'Innodb_buffer_pool_pages_data'}, $stats{'Innodb_buffer_pool_pages_total'}), perc($stats{'Innodb_buffer_pool_pages_dirty'}, $stats{'Innodb_buffer_pool_pages_data'})
  Misc      @>>>>>>>>                      @>>>>>
  $stats{'Innodb_buffer_pool_pages_misc'}, perc($stats{'Innodb_buffer_pool_pages_misc'}, $stats{'Innodb_buffer_pool_pages_total'})
  Latched   @>>>>>>>>                      @>>>>>
$stats{'Innodb_buffer_pool_pages_latched'}, perc($stats{'Innodb_buffer_pool_pages_latched'}, $stats{'Innodb_buffer_pool_pages_total'})
Reads       @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_buffer_pool_read_requests'}), t($stats{'Innodb_buffer_pool_read_requests'})
  From disk @>>>>>>>>    @>>>>>/s   %Disk: @>>>>>
make_short($stats{'Innodb_buffer_pool_reads'}), t($stats{'Innodb_buffer_pool_reads'}), perc($stats{'Innodb_buffer_pool_reads'}, $stats{'Innodb_buffer_pool_read_requests'})
  Ahead Rnd @>>>>>>>>    @>>>>>/s
$stats{'Innodb_buffer_pool_read_ahead_rnd'}, t($stats{'Innodb_buffer_pool_read_ahead_rnd'})
#  Ahead Sql @>>>>>>>>    @>>>>>/s
#$stats{'Innodb_buffer_pool_read_ahead_seq'}, t($stats{'Innodb_buffer_pool_read_ahead_seq'})
Writes      @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_buffer_pool_write_requests'}), t($stats{'Innodb_buffer_pool_write_requests'})
Wait Free   @>>>>>>>>    @>>>>>/s   %Wait: @>>>>>
$stats{'Innodb_buffer_pool_wait_free'}, t($stats{'Innodb_buffer_pool_wait_free'}), perc($stats{'Innodb_buffer_pool_wait_free'}, $stats{'Innodb_buffer_pool_write_requests'})
Flushes     @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_buffer_pool_pages_flushed'}), t($stats{'Innodb_buffer_pool_pages_flushed'})
.

format IB_LOCK =

__ InnoDB Lock _________________________________________________________
Waits       @>>>>>>>>    @>>>>>/s
$stats{'Innodb_row_lock_waits'}, t($stats{'Innodb_row_lock_waits'})
Current     @>>>>>>>>
$stats{'Innodb_row_lock_current_waits'}
Time acquiring
  Total     @>>>>>>>> ms
$stats{'Innodb_row_lock_time'}
  Average   @>>>>>>>> ms
$stats{'Innodb_row_lock_time_avg'}
  Max       @>>>>>>>> ms
$stats{'Innodb_row_lock_time_max'}
.

format IB_DPR =

__ InnoDB Data, Pages, Rows ____________________________________________
Data
  Reads     @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_data_reads'}), t($stats{'Innodb_data_reads'})
  Writes    @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_data_writes'}), t($stats{'Innodb_data_writes'})
  fsync     @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_data_fsyncs'}), t($stats{'Innodb_data_fsyncs'})
  Pending
    Reads   @>>>>>>>>
$stats{'Innodb_data_pending_reads'}, t($stats{'Innodb_data_pending_reads'})
    Writes  @>>>>>>>>
$stats{'Innodb_data_pending_writes'}, t($stats{'Innodb_data_pending_writes'})
    fsync   @>>>>>>>>
$stats{'Innodb_data_pending_fsyncs'}, t($stats{'Innodb_data_pending_fsyncs'})

Pages
  Created   @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_pages_created'}), t($stats{'Innodb_pages_created'})
  Read      @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_pages_read'}), t($stats{'Innodb_pages_read'})
  Written   @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_pages_written'}), t($stats{'Innodb_pages_written'})

Rows
  Deleted   @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_rows_deleted'}), t($stats{'Innodb_rows_deleted'})
  Inserted  @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_rows_inserted'}), t($stats{'Innodb_rows_inserted'})
  Read      @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_rows_read'}), t($stats{'Innodb_rows_read'})
  Updated   @>>>>>>>>    @>>>>>/s
make_short($stats{'Innodb_rows_updated'}), t($stats{'Innodb_rows_updated'})
.

format PAGECACHE_BUFF_MAX =

__ Aria Pagecache ______________________________________________________
Buffer used   @>>>>>> of  @>>>>>>   %Used: @>>>>>
make_short($pagecache_buffer_used, 1), make_short($vars{'aria_pagecache_buffer_size'}, 1), perc($pagecache_buffer_used, $vars{'aria_pagecache_buffer_size'})
.

format PAGECACHE_BUFF_USAGE =
  Current     @>>>>>>              %Usage: @>>>>>
make_short($pagecache_buffer_usage, 1), perc($pagecache_buffer_usage, $vars{'aria_pagecache_buffer_size'})
.

format PAGECACHE_RATIOS =
Write hit     @>>>>>%
$pagecache_write_ratio
Read hit      @>>>>>%
$pagecache_read_ratio
.

format BINLOG =

__ Binary Log Cache _____________________________________________________
Disk use
  Transactional		@>>>>>%
perc($binlog_cache_ratio)
  Non transactional	@>>>>>%
perc($binlog_stmt_cache_ratio)
.

format TOKUDB =

__ TokuDB ______________________________________________________________
Cachetable    @>>>>>> of  @>>>>>>  %Usage: @>>>>>
make_short($stats{Tokudb_cachetable_size_current}, 1), make_short($vars{tokudb_cache_size}, 1), perc($stats{Tokudb_cachetable_size_current}, $vars{tokudb_cache_size})
  Miss        @>>>>>>    @>>>>>/s
make_short($stats{'Tokudb_cachetable_miss'}), t($stats{'Tokudb_cachetable_miss'})
  Evictions   @>>>>>>    @>>>>>/s
make_short($stats{'Tokudb_cachetable_evictions'}), t($stats{'Tokudb_cachetable_evictions'})
.

format ROWS =

__ Rows ________________________________________________________________
Rows        @>>>>>>>>    @>>>>>/s
make_short($rows), t($rows)
  Using idx @>>>>>>>>    @>>>>>/s  %Index: @>>>>>
make_short($rows_using_indexes), t($rows_using_indexes), perc($rows_using_indexes,$rows)
Rows/question @>>>>>>
make_short($rows/$questions)
.