PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/bin
Viewing File: /usr/bin/mariadbd-multi
#!/usr/bin/perl # Copyright (c) 2000, 2017, Oracle and/or its affiliates. # Copyright (c) 2010, 2017, MariaDB Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; version 2 # of the License. # # 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, # MA 02110-1335 USA use Getopt::Long; use POSIX qw(strftime getcwd); use File::Path qw(mkpath); $|=1; $VER="3.0"; my @defaults_options; # Leading --no-defaults, --defaults-file, etc. $opt_example = 0; $opt_help = 0; $opt_log = undef(); $opt_mysqladmin = "/usr/bin/mariadb-admin"; $opt_mysqld = "/usr/sbin/mariadbd"; $opt_no_log = 0; $opt_password = undef(); $opt_tcp_ip = 0; $opt_user = "root"; $opt_version = 0; $opt_silent = 0; $opt_verbose = 0; $opt_wsrep_new_cluster = 0; my $my_print_defaults_exists= 1; my $logdir= undef(); my ($mysqld, $mysqladmin, $groupids, $homedir, $my_progname); $homedir = $ENV{HOME}; $my_progname = $0; $my_progname =~ s/.*[\/]//; if (defined($ENV{UMASK})) { my $UMASK = $ENV{UMASK}; my $m; my $fmode = "0640"; if(($UMASK =~ m/[^0246]/) || ($UMASK =~ m/^[^0]/) || (length($UMASK) != 4)) { printf("UMASK must be a 3-digit mode with an additional leading 0 to indicate octal.\n"); printf("The first digit will be corrected to 6, the others may be 0, 2, 4, or 6.\n"); } else { $fmode= substr $UMASK, 2, 2; $fmode= "06${fmode}"; } if($fmode != $UMASK) { printf("UMASK corrected from $UMASK to $fmode ...\n"); } $fmode= oct($fmode); umask($fmode); } main(); #### #### main sub routine #### sub main { my $flag_exit= 0; if (!defined(my_which(my_print_defaults))) { # We can't throw out yet, since --version, --help, or --example may # have been given print "WARNING: my_print_defaults command not found.\n"; print "Please make sure you have this command available and\n"; print "in your path. The command is available from the latest\n"; print "MariaDB distribution.\n"; $my_print_defaults_exists= 0; } # Remove leading defaults options from @ARGV while (@ARGV > 0) { last unless $ARGV[0] =~ /^--(?:no-defaults$|(?:defaults-file|defaults-extra-file)=)/; push @defaults_options, (shift @ARGV); } foreach (@defaults_options) { $_ = quote_shell_word($_); } # Add [mysqld_multi] options to front of @ARGV, ready for GetOptions() unshift @ARGV, defaults_for_group('mysqld_multi'); # We've already handled --no-defaults, --defaults-file, etc. if (!GetOptions("help", "example", "version", "mysqld=s", "mysqladmin=s", "user=s", "password=s", "log=s", "no-log", "tcp-ip", "silent", "verbose", "wsrep-new-cluster")) { $flag_exit= 1; } usage() if ($opt_help); if ($opt_verbose && $opt_silent) { print "Both --verbose and --silent have been given. Some of the warnings "; print "will be disabled\nand some will be enabled.\n\n"; } init_log() if (!defined($opt_log)); $groupids = $ARGV[1]; if ($opt_version) { print "$my_progname version $VER by Jani Tolonen\n"; exit(0); } example() if ($opt_example); if ($flag_exit) { print "Error with an option, see $my_progname --help for more info.\n"; exit(1); } if (!defined(my_which(my_print_defaults))) { print "ABORT: Can't find command 'my_print_defaults'.\n"; print "This command is available from the latest MariaDB\n"; print "distribution. Please make sure you have the command\n"; print "in your PATH.\n"; exit(1); } usage() if (!defined($ARGV[0]) || (!($ARGV[0] =~ m/^start$/i) && !($ARGV[0] =~ m/^stop$/i) && !($ARGV[0] =~ m/^reload$/i) && !($ARGV[0] =~ m/^report$/i))); if (!$opt_no_log) { w2log("$my_progname log file version $VER; run: ", "$opt_log", 1, 0); } else { print "$my_progname log file version $VER; run: "; print strftime "%a %b %e %H:%M:%S %Y", localtime; print "\n"; } if (($ARGV[0] =~ m/^start$/i) || ($ARGV[0] =~ m/^reload$/i)) { if (!defined(($mysqld= my_which($opt_mysqld))) && $opt_verbose) { print "WARNING: Couldn't find the default mysqld binary.\n"; print "Tried: $opt_mysqld\n"; print "This is OK, if you are using option \"mysqld=...\" in "; print "groups [mysqldN] separately for each.\n\n"; } if ($ARGV[0] =~ m/^start$/i) { start_mysqlds(); } elsif ($ARGV[0] =~ m/^reload$/i) { reload_mysqlds(); } } else { if (!defined(($mysqladmin= my_which($opt_mysqladmin))) && $opt_verbose) { print "WARNING: Couldn't find the default mysqladmin binary.\n"; print "Tried: $opt_mysqladmin\n"; print "This is OK, if you are using option \"mysqladmin=...\" in "; print "groups [mysqldN] separately for each.\n\n"; } if ($ARGV[0] =~ m/^report$/i) { report_mysqlds(); } else { stop_mysqlds(); } } } # # Quote word for shell # sub quote_shell_word { my ($option)= @_; $option =~ s!([^\w=./-])!\\$1!g; return $option; } #### #### get options for a group #### sub defaults_for_group { my ($group) = @_; return () unless $my_print_defaults_exists; my $com= join ' ', 'my_print_defaults', @defaults_options, $group; my @defaults = `$com`; chomp @defaults; return @defaults; } #### #### Init log file. Check for appropriate place for log file, in the following #### order: my_print_defaults mysqld datadir, /usr/share/mysql #### sub init_log { foreach my $opt (defaults_for_group('--mysqld')) { if ($opt =~ m/^--datadir=(.*)/ && -d "$1" && -w "$1") { $logdir= $1; } } if (!defined($logdir)) { $logdir= "/usr/share/mysql" if (-d "/usr/share/mysql" && -w "/usr/share/mysql"); } if (!defined($logdir)) { # Log file was not specified and we could not log to a standard place, # so log file be disabled for now. if (!$opt_silent) { print "WARNING: Log file disabled. Maybe directory or file isn't writable?\n"; } $opt_no_log= 1; } else { $opt_log= "$logdir/mysqld_multi.log"; } } #### #### Report living and not running MariaDB servers #### sub report_mysqlds { my (@groups, $com, $i, @options, $pec); print "Reporting MariaDB servers\n"; if (!$opt_no_log) { w2log("\nReporting MariaDB servers","$opt_log",0,0); } @groups = &find_groups($groupids); for ($i = 0; defined($groups[$i]); $i++) { $com= get_mysqladmin_options($i, @groups); $com.= " ping >> /dev/null 2>&1"; system($com); $pec = $? >> 8; if ($pec) { print "MariaDB server from group: $groups[$i] is not running\n"; if (!$opt_no_log) { w2log("MariaDB server from group: $groups[$i] is not running", "$opt_log", 0, 0); } } else { print "MariaDB server from group: $groups[$i] is running\n"; if (!$opt_no_log) { w2log("MariaDB server from group: $groups[$i] is running", "$opt_log", 0, 0); } } } if (!$i) { print "No groups to be reported (check your GNRs)\n"; if (!$opt_no_log) { w2log("No groups to be reported (check your GNRs)", "$opt_log", 0, 0); } } } #### #### start multiple servers #### sub start_mysqlds() { my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $suffix_found, $info_sent); $suffix_found= 0; if (!$opt_no_log) { w2log("\nStarting MariaDB servers\n","$opt_log",0,0); } else { print "\nStarting MariaDB servers\n"; } @groups = &find_groups($groupids); for ($i = 0; defined($groups[$i]); $i++) { @options = defaults_for_group($groups[$i]); $basedir_found= 0; # The default $mysqld_found= 1; # The default $mysqld_found= 0 if (!length($mysqld)); $com= "$mysqld"; for ($j = 0, $tmp= ""; defined($options[$j]); $j++) { if ("--datadir=" eq substr($options[$j], 0, 10)) { $datadir = $options[$j]; $datadir =~ s/\-\-datadir\=//; eval { mkpath($datadir) }; if ($@) { print "FATAL ERROR: Cannot create data directory $datadir: $!\n"; exit(1); } if (! -d $datadir."/mysql") { if (-w $datadir) { print "\n\nInstalling new database in $datadir\n\n"; $install_cmd="/usr/bin/mysql_install_db "; $install_cmd.="--user=mysql "; $install_cmd.="--datadir=$datadir"; system($install_cmd); } else { print "\n"; print "FATAL ERROR: Tried to create mysqld under group [$groups[$i]],\n"; print "but the data directory is not writable.\n"; print "data directory used: $datadir\n"; exit(1); } } if (! -d $datadir."/mysql") { print "\n"; print "FATAL ERROR: Tried to start mysqld under group [$groups[$i]],\n"; print "but no data directory was found or could be created.\n"; print "data directory used: $datadir\n"; exit(1); } } if ("--mysqladmin=" eq substr($options[$j], 0, 13)) { # catch this and ignore } elsif ("--mysqld=" eq substr($options[$j], 0, 9)) { $options[$j]=~ s/\-\-mysqld\=//; $com= $options[$j]; $mysqld_found= 1; } elsif ("--basedir=" eq substr($options[$j], 0, 10)) { $basedir= $options[$j]; $basedir =~ s/^--basedir=//; $basedir_found= 1; $options[$j]= quote_shell_word($options[$j]); $tmp.= " $options[$j]"; } elsif ("--defaults-group-suffix=" eq substr($options[$j], 0, 24)) { $suffix_found= 1; } else { $options[$j]= quote_shell_word($options[$j]); $tmp.= " $options[$j]"; } } if ($opt_verbose && $com =~ m/\/(mariadbd-safe)$/ && !$info_sent) { print "WARNING: $1 is being used to start mariadbd. In this case you "; print "may need to pass\n\"ledir=...\" under groups [mysqldN] to "; print "$1 in order to find the actual mysqld binary.\n"; print "ledir (library executable directory) should be the path to the "; print "wanted mysqld binary.\n\n"; $info_sent= 1; } if (!$suffix_found) { $com.= " --defaults-group-suffix="; $com.= substr($groups[$i],6); } $com.= $tmp; if ($opt_wsrep_new_cluster) { $com.= " --wsrep-new-cluster"; } $com.= " >> $opt_log 2>&1" if (!$opt_no_log); $com.= " &"; if (!$mysqld_found) { print "\n"; print "FATAL ERROR: Tried to start mysqld under group [$groups[$i]], "; print "but no mysqld binary was found.\n"; print "Please add \"mysqld=...\" in group [mysqld_multi], or add it to "; print "group [$groups[$i]] separately.\n"; exit(1); } if ($basedir_found) { $curdir=getcwd(); chdir($basedir) or die "Can't change to datadir $basedir"; } system($com); if ($basedir_found) { chdir($curdir) or die "Can't change back to original dir $curdir"; } } if (!$i && !$opt_no_log) { w2log("No MariaDB servers to be started (check your GNRs)", "$opt_log", 0, 0); } } #### #### reload multiple servers #### sub reload_mysqlds() { my (@groups, $com, $tmp, $i, @options, $j); if (!$opt_no_log) { w2log("\nReloading MySQL servers\n","$opt_log",0,0); } else { print "\nReloading MySQL servers\n"; } @groups = &find_groups($groupids); for ($i = 0; defined($groups[$i]); $i++) { $mysqld_server = $mysqld; @options = defaults_for_group($groups[$i]); for ($j = 0, $tmp= ""; defined($options[$j]); $j++) { if ("--mysqladmin=" eq substr($options[$j], 0, 13)) { # catch this and ignore } elsif ("--mysqld=" eq substr($options[$j], 0, 9)) { $options[$j] =~ s/\-\-mysqld\=//; $mysqld_server = $options[$j]; } elsif ("--pid-file=" eq substr($options[$j], 0, 11)) { $options[$j] =~ s/\-\-pid-file\=//; $pid_file = $options[$j]; } } $com = "killproc -p $pid_file -HUP $mysqld_server"; system($com); $com = "touch $pid_file"; system($com); } if (!$i && !$opt_no_log) { w2log("No MySQL servers to be reloaded (check your GNRs)", "$opt_log", 0, 0); } } ### #### stop multiple servers #### sub stop_mysqlds() { my (@groups, $com, $i, @options); if (!$opt_no_log) { w2log("\nStopping MariaDB servers\n","$opt_log",0,0); } else { print "\nStopping MariaDB servers\n"; } @groups = &find_groups($groupids); for ($i = 0; defined($groups[$i]); $i++) { $com= get_mysqladmin_options($i, @groups); $com.= " shutdown"; $com.= " >> $opt_log 2>&1" if (!$opt_no_log); $com.= " &"; system($com); } if (!$i && !$opt_no_log) { w2log("No MariaDB servers to be stopped (check your GNRs)", "$opt_log", 0, 0); } } #### #### Sub function for mysqladmin option parsing #### sub get_mysqladmin_options { my ($i, @groups)= @_; my ($mysqladmin_found, $com, $tmp, $j); @options = defaults_for_group($groups[$i]); $mysqladmin_found= 1; # The default $mysqladmin_found= 0 if (!length($mysqladmin)); $com = "$mysqladmin"; $tmp = " -u $opt_user"; if (defined($opt_password)) { my $pw= $opt_password; # Protect single quotes in password $pw =~ s/'/'"'"'/g; $tmp.= " -p'$pw'"; } $tmp.= $opt_tcp_ip ? " -h 127.0.0.1" : ""; for ($j = 0; defined($options[$j]); $j++) { if ("--mysqladmin=" eq substr($options[$j], 0, 13)) { $options[$j]=~ s/\-\-mysqladmin\=//; $com= $options[$j]; $mysqladmin_found= 1; } elsif ((($options[$j] =~ m/^(\-\-socket\=)(.*)$/) && !$opt_tcp_ip) || ($options[$j] =~ m/^(\-\-port\=)(.*)$/)) { $tmp.= " $options[$j]"; } } if (!$mysqladmin_found) { print "\n"; print "FATAL ERROR: Tried to use mysqladmin in group [$groups[$i]], "; print "but no mysqladmin binary was found.\n"; print "Please add \"mysqladmin=...\" in group [mysqld_multi], or "; print "in group [$groups[$i]].\n"; exit(1); } $com.= $tmp; return $com; } # Return a list of option files which can be opened. Similar, but not # identical, to behavior of my_search_option_files() # TODO implement and use my_print_defaults --list-groups instead sub list_defaults_files { my %opt; foreach (@defaults_options) { return () if /^--no-defaults$/; $opt{$1} = $2 if /^--defaults-(extra-file|file)=(.*)$/; } return ($opt{file}) if exists $opt{file}; my @dirs; # same rule as in mysys/my_default.c if ('/etc') { push @dirs, '/etc/my.cnf'; } else { push @dirs, '/etc/my.cnf', '/etc/mysql/my.cnf'; } push @dirs, "$ENV{MYSQL_HOME}/my.cnf" if $ENV{MYSQL_HOME}; push @dirs, $opt{'extra-file'} if $opt{'extra-file'}; push @dirs, "$ENV{HOME}/.my.cnf" if $ENV{HOME}; return @dirs; } # Takes a specification of GNRs (see --help), and returns a list of matching # groups which actually are mentioned in a relevant config file sub find_groups { my ($raw_gids) = @_; my %gids; my @groups; if (defined($raw_gids)) { # Make a hash of the wanted group ids foreach my $raw_gid (split ',', $raw_gids) { # Match 123 or 123-456 my ($start, $end) = ($raw_gid =~ /^\s*(\d+)(?:\s*-\s*(\d+))?\s*$/); $end = $start if not defined $end; if (not defined $start or $end < $start or $start < 0) { print "ABORT: Bad GNR: $raw_gid; see $my_progname --help\n"; exit(1); } foreach my $i ($start .. $end) { # Use $i + 0 to normalize numbers (002 + 0 -> 2) $gids{$i + 0}= 1; } } } my %seen; my @defaults_files = list_defaults_files(); while (@defaults_files) { my $file = shift @defaults_files; next unless defined $file and not $seen{$file}++ and open CONF, '<', $file; while (<CONF>) { if (/^\s*\[\s*(mysqld)(\d+)\s*\]\s*$/) { #warn "Found a group: $1$2\n"; # Use $2 + 0 to normalize numbers (002 + 0 -> 2) if (not defined($raw_gids) or $gids{$2 + 0}) { push @groups, "$1$2"; } } elsif (/^\s*!include\s+(\S.*?)\s*$/) { push @defaults_files, $1; } elsif (/^\s*!includedir\s+(\S.*?)\s*$/) { push @defaults_files, <$1/*.cnf>; } } close CONF; } return @groups; } #### #### w2log: Write to a logfile. #### 1.arg: append to the log file (given string, or from a file. if a file, #### file will be read from $opt_logdir) #### 2.arg: logfile -name (w2log assumes that the logfile is in $opt_logdir). #### 3.arg. 0 | 1, if true, print current date to the logfile. 3. arg will #### be ignored, if 1. arg is a file. #### 4.arg. 0 | 1, if true, first argument is a file, else a string #### sub w2log { my ($msg, $file, $date_flag, $is_file)= @_; my (@data); open (LOGFILE, ">>$opt_log") or die "FATAL: w2log: Couldn't open log file: $opt_log\n"; if ($is_file) { open (FROMFILE, "<$msg") && (@data=<FROMFILE>) && close(FROMFILE) or die "FATAL: w2log: Couldn't open file: $msg\n"; foreach my $line (@data) { print LOGFILE "$line"; } } else { print LOGFILE "$msg"; print LOGFILE strftime "%a %b %e %H:%M:%S %Y", localtime if ($date_flag); print LOGFILE "\n"; } close (LOGFILE); return; } #### #### my_which is used, because we can't assume that every system has the #### which -command. my_which can take only one argument at a time. #### Return values: requested system command with the first found path, #### or undefined, if not found. #### sub my_which { my ($command) = @_; my (@paths, $path); # If the argument is not 'my_print_defaults' then it would be of the format # <absolute_path>/<program> return $command if ($command ne 'my_print_defaults' && -f $command && -x $command); @paths = split(':', $ENV{'PATH'}); foreach $path (@paths) { $path .= "/$command"; return $path if (-f $path && -x $path); } return undef(); } #### #### example #### sub example { print <<EOF; # This is an example of a my.cnf file for $my_progname. # Usually this file is located in home dir ~/.my.cnf or /etc/my.cnf # # SOME IMPORTANT NOTES FOLLOW: # # 1.COMMON USER # # Make sure that the MariaDB user, who is stopping the mysqld services, has # the same password to all MariaDB servers being accessed by $my_progname. # This user needs to have the 'Shutdown_priv' -privilege, but for security # reasons should have no other privileges. It is advised that you create a # common 'multi_admin' user for all MariaDB servers being controlled by # $my_progname. Here is an example how to do it: # # GRANT SHUTDOWN ON *.* TO multi_admin\@localhost IDENTIFIED BY 'password' # # You will need to apply the above to all MariaDB servers that are being # controlled by $my_progname. 'multi_admin' will shutdown the servers # using 'mysqladmin' -binary, when '$my_progname stop' is being called. # # 2.PID-FILE # # If you are using mariadbd-safe to start mariadbd, make sure that every # MariaDB server has a separate pid-file. In order to use mariadbd-safe # via $my_progname, you need to use two options: # # mysqld=/path/to/mariadbd-safe # ledir=/path/to/mariadbd-binary/ # # ledir (library executable directory), is an option that only mariadbd-safe # accepts, so you will get an error if you try to pass it to mysqld directly. # For this reason you might want to use the above options within [mysqld#] # group directly. # # 3.DATA DIRECTORY # # It is NOT advised to run many MariaDB servers within the same data directory. # You can do so, but please make sure to understand and deal with the # underlying caveats. In short they are: # - Speed penalty # - Risk of table/data corruption # - Data synchronising problems between the running servers # - Heavily media (disk) bound # - Relies on the system (external) file locking # - Is not applicable with all table types. (Such as InnoDB) # Trying so will end up with undesirable results. # # 4.TCP/IP Port # # Every server requires one and it must be unique. # # 5.[mysqld#] Groups # # In the example below the first and the fifth mysqld group was # intentionally left out. You may have 'gaps' in the config file. This # gives you more flexibility. # # 6.MariaDB Server User # # You can pass the user=... option inside [mysqld#] groups. This # can be very handy in some cases, but then you need to run $my_progname # as UNIX root. # # 7.A Start-up Manage Script for $my_progname # # In the recent MariaDB distributions you can find a file called # mysqld_multi.server.sh. It is a wrapper for $my_progname. This can # be used to start and stop multiple servers during boot and shutdown. # # You can place the file in /etc/init.d/mysqld_multi.server.sh and # make the needed symbolic links to it from various run levels # (as per Linux/Unix standard). You may even replace the # /etc/init.d/mysql.server script with it. # # Before using, you must create a my.cnf file either in /usr/my.cnf # or /root/.my.cnf and add the [mysqld_multi] and [mysqld#] groups. # # The script can be found from support-files/mysqld_multi.server.sh # in MariaDB distribution. (Verify the script before using) # [mysqld_multi] mysqld = /usr/bin/mariadbd-safe mysqladmin = /usr/bin/mariadb-admin user = multi_admin password = my_password [mysqld2] socket = /tmp/mysql.sock2 port = 3307 pid-file = /var/lib/mysql2/hostname.pid2 datadir = /var/lib/mysql2 language = /usr/share/mysql/mysql/english user = unix_user1 [mysqld3] mysqld = /path/to/mariadbd-safe ledir = /path/to/mariadbd-binary/ mysqladmin = /path/to/mariadb-admin socket = /tmp/mysql.sock3 port = 3308 pid-file = /var/lib/mysql3/hostname.pid3 datadir = /var/lib/mysql3 language = /usr/share/mysql/mysql/swedish user = unix_user2 [mysqld4] socket = /tmp/mysql.sock4 port = 3309 pid-file = /var/lib/mysql4/hostname.pid4 datadir = /var/lib/mysql4 language = /usr/share/mysql/mysql/estonia user = unix_user3 [mysqld6] socket = /tmp/mysql.sock6 port = 3311 pid-file = /var/lib/mysql6/hostname.pid6 datadir = /var/lib/mysql6 language = /usr/share/mysql/mysql/japanese user = unix_user4 EOF exit(0); } #### #### usage #### sub usage { print <<EOF; $my_progname version $VER by Jani Tolonen Description: $my_progname can be used to start, reload, or stop any number of separate mysqld processes running in different TCP/IP ports and UNIX sockets. $my_progname can read group [mysqld_multi] from my.cnf file. You may want to put options mysqld=... and mysqladmin=... there. Since version 2.10 these options can also be given under groups [mysqld#], which gives more control over different versions. One can have the default mysqld and mysqladmin under group [mysqld_multi], but this is not mandatory. Please note that if mysqld or mysqladmin is missing from both [mysqld_multi] and [mysqld#], a group that is tried to be used, $my_progname will abort with an error. $my_progname will search for groups named [mysqld#] from my.cnf (or the given --defaults-extra-file=...), where '#' can be any positive integer starting from 1. These groups should be the same as the regular [mysqld] group, but with those port, socket and any other options that are to be used with each separate mysqld process. The number in the group name has another function; it can be used for starting, reloading, stopping, or reporting any specific mysqld server. Usage: $my_progname [OPTIONS] {start|reload|stop|report} [GNR,GNR,GNR...] or $my_progname [OPTIONS] {start|reload|stop|report} [GNR-GNR,GNR,GNR-GNR,...] The GNR means the group number. You can start, reload, stop or report any GNR, or several of them at the same time. (See --example) The GNRs list can be comma separated or a dash combined. The latter means that all the GNRs between GNR1-GNR2 will be affected. Without GNR argument all the groups found will either be started, reloaded, stopped, or reported. Note that syntax for specifying GNRs must appear without spaces. Options: These options must be given before any others: --no-defaults Do not read any defaults file --defaults-file=... Read only this configuration file, do not read the standard system-wide and user-specific files --defaults-extra-file=... Read this configuration file in addition to the standard system-wide and user-specific files Using: @{[join ' ', @defaults_options]} --example Give an example of a config file with extra information. --help Print this help and exit. --log=... Log file. Full path to and the name for the log file. NOTE: If the file exists, everything will be appended. Using: $opt_log --mysqladmin=... mysqladmin binary to be used for a server shutdown. Since version 2.10 this can be given within groups [mysqld#] Using: $mysqladmin --mysqld=... mariadbd binary to be used. Note that you can give mariadbd-safe to this option also. The options are passed to mysqld. Just make sure you have mariadbd in your PATH or fix mariadbd-safe. Using: $mysqld Please note: Since mysqld_multi version 2.3 you can also give this option inside groups [mysqld#] in ~/.my.cnf, where '#' stands for an integer (number) of the group in question. This will be recognised as a special option and will not be passed to the mysqld. This will allow one to start different mysqld versions with mysqld_multi. --no-log Print to stdout instead of the log file. By default the log file is turned on. --password=... Password for mysqladmin user. --silent Disable warnings. --tcp-ip Connect to the MariaDB server(s) via the TCP/IP port instead of the UNIX socket. This affects stopping and reporting. If a socket file is missing, the server may still be running, but can be accessed only via the TCP/IP port. By default connecting is done via the UNIX socket. --user=... mysqladmin user. Using: $opt_user --verbose Be more verbose. --version Print the version number and exit. --wsrep-new-cluster Bootstrap a cluster. EOF exit(0); }