Join Now

Juletip #12b - Kill Bill eller er det stabil drift!

by SAS Employee TorbenJuulJohansson on ‎12-12-2014 04:41 AM (320 Views)

Kender du filmene Kill Bill: Volume 1 og Kill Bill: Volume 2? I denne serie skal Bill dræbes, da den tidligere kæreste og boss til Black Mamba har nogle ret irriterende hensigter. Nogle gange kan det dog også være nyttigt at lege Kill SAS, som jeg vil fortælle om lige om lidt.

Ofte er jeg nemlig med til at udvikle løsninger for vores kunder, hvor det er vigtigt at sikre, at den natlige batch er så stabil som muligt. Mange ting kan gå galt, og i nogle tilfælde ser man, at batchjobs fejler, fordi en tabel er låst af den ene eller anden årsag.

En typisk grund til, at tabeller er låst, er, at nogle brugere har arbejdet i SAS® Enterprise Guide® mod SAS-tabeller og 'glemmer' at lukke SAS Enterprise Guide, når de går hjem fra arbejde. Måske har de efterladt SAS Enterprise Guide, mens de er inde i en SAS-tabel, og så er det, problemerne opstår. Nu er det jo nok ikke så optimalt at gå til samme yderligheder som Black Mamba i Kill Bill. I stedet kan vi opbygge en selvforsvarsmekanisme og lege Kill SAS. 

Løsningen går i al sin enkelhed ud på at dræbe de processer, som kan forstyrre opdateringen om natten. Den første løsning er meget simpel og går ud på at dræbe alle SAS-processer, før vi går i gang med vores flow. Den simpleste måde, jeg har set, at dette kunne gøres på, er at lave et lille VBS-script med følgende stup kode:


     # PowerShell 'Stops' Windows Process
     Clear-Host
     Stop-Process -force -name sas

Dette VBS-script dræber alle sas.exe-processer. Denne løsning kan være god eller dårlig, alt afhængig af jeres SAS it-arkitektur. Hvis I har en metadata-server kørende på samme maskine, vil den også blive dræbt, og det er jo ikke meningen.

I stedet for at skyde med spredehagl og udrydde alle potentielle fjender på sin vej (som man vel med rette kan sige, at Black Mamba gør) kunne det måske være bedre at sigte mere præcist med en kikkertsigte, lidt lige som en rigtig snigskytte gør det. 

Den anden løsning, jeg vil foreslå, er derfor en makro, som undersøger, hvilke processer der låser en given tabel og dræber dem. Herved forstyrrer vi vores driftsmiljø mindst muligt. Fordelen ved denne metode er også, at alle andre processer end blot sas.exe-processer bliver dræbt, hvis de lægger hindringer i vejen.

Som et eksempel på denne løsning er følgende makroer:

%macro kill(pid=);
     %let pskillcmd=%str(F:\SysinternalsSuite\pskill.exe);
     filename cmd pipe "&pskillcmd -t &pid";

     data _null_;
          infile cmd;
          input;
          put _infile_;
     run;

%mend;

%macro findpidandkill(Table=);
     %let handlecmd=%str(F:\SysinternalsSuite\handle.exe);

     /* Looking up physical file for table using output from proc contents */
     ods _all_ close;
     ods output enginehost=host;

     proc contents data=&Table;
     run;

     data _null_;
          set host(where=(label1="Filename"));
          call symput("filename",cvalue1);
     run;


     /* Find PID (process id) that uses our table and kill using %kill */
     %put NOTE: Detecting locks for file &filename;
     filename cmd pipe "&handlecmd ""&filename""";

     data _null_;
           length line $500 executable $100 pid $8;
           infile cmd truncover length=len;
           input line $varying.len;

           if index(upcase(line),upcase(strip("&filename"))) then do;
                 executable = scan(_infile_,1,' ');
                 pid = scan(_infile_,2,':');

                 if pid ne "" then do;
                       call execute('%kill(pid='||pid||');');
                       put 'NOTE: Process ' pid +(-1) ', executable "' executable +(-1) '", will be terminated.';
                 end;
           end;
     run;

%mend;

%findpidandkill(Table=sashelp.class);

Denne makro anvender 2 værktøjer fra Sysinternals Suite fra Microsoft, som kan downloades her: http://technet.microsoft.com/en-us/sysinternals/bb545027.aspx.

Den første makro %findpidandkill undersøger, hvilke processer der har åbnet den SAS-tabel, du har angivet i argumentet 'table'. For hver af de processer, makroen finder, kaldes en anden makro (kill), som dræber den pågældende process. Det bedste sted at kalde makroen %findpidandkill er lige før, du går i gang med at opdatere din tabel.

Håber, du bliver glad for at lege Kill SAS.

PS. Tak til et par gode kollegaer (Johannes Jørgensen og Henrik Dorf), som vistnok har skrevet/delt noget af koden, som jeg har gjort mere anvendelig.

PSS. Hvis du synes, det er godt at lege SAS-snigskytte (som jeg gør), så læg gerne en kommentar med, hvordan du personligt leger Kill SAS.

Comments
by Occasional Learner JacobZimling
on ‎12-12-2014 06:50 AM

Super tip og overraskende simpelt at implementere.

Er der nogen derude der ved, om der findes noget svarende til "Sysinternals Suite fra Microsoft" til UNIX så os med SAS-installationer på UNIX kan lege med?