04 - System Administration04g - Varie sistemistica

Gestione del sistema IBM i: FAQ e Howto (Parte 2 – IT)

Questo post è la continuazione del post “Gestione del sistema IBM i: FAQ e Howto (Parte 1 – IT)“.

iAdmin-FAQ-011: Controllare meglio i lavori JDBC/ODBC (QZDASOINIT JOBs)

Sempre più spesso ci troviamo a dover gestire e controllare le performance e le attività dei lavori che accedono al DB2 for i via JDBC/ODBC: collegamenti da applicazioni esterne o da linguaggi open source come PHP-Java-Node.js-Python, SQL interattivi gestiti da RunSQL Script di ACS/Rdi ecc.

Sappiamo che tutti questi lavori, per default, vengono gestiti nel sottosistema QUSRWRK tramite job che vanno sotto il nome di QZDASOINIT o QRWTSRVR e non abbiamo grandi possibilità di controllo granulare.

In questo ottimo articolo del 2015 su ITJungle “Tuning SQL Environments On i“, Paul Tuohy ci spiega come portare alcuni JOB (a seconda dell’utente di esecuzione!) in un sottosistema indipendente con delle impostazioni di priority e timeslice dedicate.

Anche in questo TechTip di Kent Milligan su McPressOnline “TechTip: Routing Away Your QZDASOINIT Troubles” viene spiegato il processo.

Se hai un sistema operativo vecchio probabilmente ti tocca guardare qui : QZDASOINIT on the Wiki Midrange, se invece sei al passo con i tempi ci sono degli ottimi IBM i Service per vedere e controllare i Prestart-job, come spiegato in questo post su IBMSystemsMag: “Active_Job_Info() for Prestart Server Jobs”

Ma già nel 2011 Yiyu Jia aveva fatto un post nel suo blog “IBM i5/OS V5R4 prestart job and database connection tuning.” dove spiegava i concetti di Prestart Job per un miglior controllo dei JOB QZDASOINIT.

iAdmin-FAQ-012: Convertire il charset di un file nell’IFS

Per convertire l’encoding del character set di un file nell’IFS possiamo usare iconv:

Esempio convertire da plain ASCII a EBCDIC CCSID 037 USA:

 /QOpenSys/pkgs/bin/iconv -f ISO8859-1-t IBM-037 myfile.ascii  > myfile.ebcdic 

e viceversa

 /QOpenSys/pkgs/bin/iconv -f IBM-037 -t ISO8859-1 /home/me/myfile.ebcdic >/home/me/myfile.txt 

Per ottenere la lista dei charset supportati:

   /QOpenSys/pkgs/bin/iconv   -l 

iAdmin-FAQ-013: Leggere e scrivere files nell’IFS

Ci sono diversi modi per leggere e scrive file nell’IFS, qui di seguito qualche link a post di altri siti/blog dove se ne parla:

iAdmin-FAQ-014: Quali sono le porte TCP di IBM ACS Access Client Solution?

Le porte di ACS sono le stesse del “vecchio” Iseries Access / Client Access

PC FunctionServer NamePort Non-SSLPort SSL
Server Mapperas-svrmap449
License Managementas-central84709470
Database Accessas-database84719471
Data Queuesas-dtaq84729472
IFS Access using
System i Navigator
as-file84739473
Network Printersas-netprt84749474
Remote Commandas-rmtcmd84759475
Signon Verificationas-signon84769476
Telnet (5250 Emulation)telnet23992
Navigator for i (web)as-nav20042005
HTTP Administrationas-admin20012010
POP3 (MAPI)pop35010
Management Centralas-mgtc >5555 and 55445566 and 5577
Ultimedia Servicesas-usf84809480
DDM/DRDADDM/DRDA446448
NetServernetbios >137
NetServerCIFS445
NetServernetbios >139
Service Tools Serveras-sts3000
DHCP Monitor942
RUNRMTCMDREXEC512

Come si può vedere dal sito IBM Support “TCP/IP Ports Required for IBM i Access and Related Functions” oppure dal manuale ACS: ” https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajr/rzajrpdf.pdf

iAdmin-FAQ-015: Controllare lo stato delle connessioni di rete IPv4 e IPv6

Se voglio controllare in modo veloce le connessioni di rete al mio IBM i, posso farlo con un semplice statement SQL utilizzando i DB2 for i Services:

select local_port, remote_address, count(*) as nbrconnections
 from QSYS2.NETSTAT_INFO
 group by local_port, remote_address
 order by remote_address;

Se volessi solo controllare gli accessi 5250 sulla porta 23:

select local_port, remote_address, count(*) as nbrconnections
 from QSYS2.NETSTAT_INFO
 where local_port = 23
 group by local_port, remote_address
 order by remote_address;

iAdmin-FAQ-016: Quali file hanno impostato il flag “Reuse deleted records”?

Questa domanda è stata posta sulla mailing list Midrange.com, visto che nel system-catalog non è presente questa informazione?

La risposta arriva da Bruce Vinings, con un piccolo programma RPG che utilizza la API QDBRTVFD per recuperare l’informazione … poi crea una UDF che chiama il programma RPG:

 ctl-opt dftactgrp(*no);

  dcl-pr RtvFD2;
    fileIn          char(10)          const;
    libIn           char(10)          const;
    reuseSts        char(10);
    fileInd         int(5)            const;
    libInd          int(5)            const;
    reuseStsInd     int(5);
    sqlState        char(5);
    sqlName         varchar(517)      const;
    sqlSpecific     varchar(128)      const;
    sqlDiag         varchar(1000);
  end-pr;
  dcl-pi RtvFD2;
    fileIn          char(10)          const;
    libIn           char(10)          const;
    reuseSts        char(10);
    fileInd         int(5)            const;
    libInd          int(5)            const;
    reuseStsInd     int(5);
    sqlState        char(5);
    sqlName         varchar(517)      const;
    sqlSpecific     varchar(128)      const;
    sqlDiag         varchar(1000);
  end-pi;


  dcl-pr RtvReuse                     extpgm('QDBRTVFD');
    rcvVar          char(65535)       options(*varsize);
    lenRcvVar       int(10)           const;
    qualRtnFN       char(20);
    formatAPI       char(8)            const;
    qualFileName    char(20)           const;
    rcdFmtName      char(10)           const;
    ovrPcs          char(1)            const;
    system          char(10)           const;
    formatType      char(10)           const;
    errCde                             likeds(qusec);
  end-pr;

/copy qsysinc/qrpglesrc,qusec
/copy qsysinc/qrpglesrc,qdbrtvfd

 dcl-ds baseFD                        likeds(QDBQ25) based(ptrRcvVar);
 dcl-ds pFAtrs                        likeds(QDBQ26) based(ptrPFAtrs);
 dcl-ds errCde                        qualified;
   hdr                                likeds(qusec);
   errDta          char(256);
 end-ds;

 dcl-s ptrPFAtrs   pointer;
 dcl-s ptrRcvVar   pointer            inz(%addr(rcvVar));
 dcl-s qualRtnFN   char(20);
 dcl-s rcvVar      char(4096);
 dcl-s theFile     char(10)           inz('MYFILE');

  errCde.hdr.QUSBPrv = 0;
  monitor;
    RtvReuse( rcvVar      :%size(rcvVar)       :qualRtnFN
             :'FILD0100'  :(fileIn + libIn)    :' *FIRST'
             :'0'         :'*LCL'              :'*INT'
             :errCde);
    if %bitand(%subst(baseFD.QDBBits27 :1 :1) :x'20') = x'00';
      ptrPFAtrs = ptrRcvVar + baseFD.QDBPFOf;
      if %bitand(pFAtrs.QDBBits33 :x'80') = x'80';
        reuseSts = 'YES';
      else;
        reuseSts = 'NO';
      endif;
    else;
      reuseSts = 'N/A';
    endif;
  on-error;
    reuseStsInd = -1;
  endmon;
  *inlr = *on;
  return; 

Ed ecco invece la Function SQL

 create or replace function Reuse_Deleted_Records
                          ( tableName  char(10)
                           ,schemaName char(10)
                          )
                  returns char(10)
                  external name 'MYLIB/RTVFD2'
                  program type main
                  language rpgle
                  parameter style sql
                  returns null on null input
                  no external action
                  not fenced 

Per poi utilizzare la UDF prendendo l’elenco di file dal System Catalog

 Select system_table_name, system_table_schema,
       Reuse_Deleted_Records(system_table_name,system_Table_schema)
From systables
where table_type in ('P', 'T')
 and  system_table_schema = 'MYLIB';
 

iAdmin-FAQ-017: WRKOBJLCK con SQL (QSYS2.OBJECT_LOCK_INFO)

Il risultato del comando “WRKOBJLCK OBJ(MYLIB/TESTFILE) OBJTYPE(*FILE)” può essere ottenuto con SQL interrogando la vista QSYS2.IBJECT_LOCK_INFO, uno dei tanti “DB2 for i Services” messo a disposizione dal laboratorio IBM.

In questo post di Simon Hutchinson su RPGPGM.COM “Using SQL to look for record locks” vediamo un esempio concreto di utilizzo si questa view con una piccola utility che termina tutti i lavori che tengono in lock un oggetto

iAdmin-FAQ-018: WRKACTJOB con SQL (QSYS2.ACTIVE_JOB_INFO)

I DB2 for i Service sono un ottimo modo per interrogare il sistema da SQL senza lanciare comandi o System API: prendiamo ad esempio un WRKACTJOB … possiamo farlo con una semplice istruzione SQL come quella qui sotto:

select * from table(qsys2.active_job_info(
RESET_STATISTICS => 'NO',
SUBSYSTEM_LIST_FILTER => '' ,
JOB_NAME_FILTER => '*ALL',
CURRENT_USER_LIST_FILTER => '',
DETAILED_INFO => 'NONE'
)) A ; 

Se invece volessimo interrogare tutti i JOB, anche quelli chiusi in OUTQ possiamo usare questa altra vista sui JOB:

SELECT * FROM TABLE(QSYS2.JOB_INFO(JOB_USER_FILTER    => '*ALL'));

iAdmin-FAQ-019 WRKSYVAL con SQL (QSYS2.SYSTEM_VALUE_INFO)

Facendo il cambio da un POWER7 con la 7.2 ad un POWER9 con la 7.4 ho voluto accertarmi di aver settato tutte le impostazioni dei valori di sistema in modo corretto … per vederne la differenza tra le impostazioni del POWER7 e quelle del POWER9, ho creato una tabella con i valori del power7, spostata con FTP sul POWER9 e fatto un SQL di confronto:

-- Create a table with system values on the POWER7 system

create table MYLIB.SYSVALP7 as (
 SELECT * FROM QSYS2.SYSTEM_VALUE_INFO
 order by system_value_name) with data;

-- Save the table in a SAVF and move it on the POWER9 system ... and then, on my new POWER9 System

SELECT a.system_value_name, a.current_numeric_value as NumP9, 
 b.current_numeric_value as Num_P7, 
 a.current_character_value as Alf_p9,
 b.current_character_value as Alf_p7
 FROM SYSTEM_VALUE_INFO a
 left join MYLIB.SYSVALP7 b on b.system_value_name=a.system_value_name
 where a.current_numeric_value<>b.current_numeric_value or
 a.current_character_value<>b.current_character_value
 order by system_value_name;

iAdmin-FAQ-020 In che “memory pool” stanno girando i miei sottosistemi (WRKACTJOB join WRKSYSSTS)?

In ottica di ottimizzazione dei sottosistemi e dei lotti di memoria può essere utile sapere in che lotti di memoria (memory pool), visibili normalmente con WKRSYSSTS, stanno girando attualmente i sottosistemi, visibile normalmente con WRKACTJOB: i DB2 for i service ci vengono in aiuto con questo semplice JOIN tra due servizi:

SELECT DISTINCT CAST(A.Objlongschema AS CHAR(10)) AS "Library",
                 A.Objname AS "Subsystem",
                 b.memory_pool,
                 CASE
                     WHEN B.Subsystem IS Null THEN 'Inactive'
                     ELSE 'Active'
                 END AS "Status"
     FROM TABLE (
              Qsys2.Object_Statistics('*ALL', 'SBSD')
          ) A
          LEFT OUTER JOIN TABLE (
                  Qsys2.Active_Job_Info()
              ) B
              ON A.Objname = B.Subsystem
                  AND A.Objlongschema = B.Subsystem_Library_Name
     ORDER BY 4,
              2,
              1 ; 

--- Roberto De Pedrini Faq400.com
About author

Founder di Faq400 Srl, IBM Champion, ideatore del sito Faq400.com e del Blog blog.faq400.com. Sviluppatore RPG da quando avevo i pantaloni corti, forte sostenitore della piattaforma IBM i (ex AS400), ho sempre cercato di convididere le mie conoscenze con gli altri tramite forum, eventi e corsi. Oggi, tramite Faq400 Srl, cerchiamo di aiutare le aziende a sfruttare al meglio questa fantastica piattaforma IBM i.

Rispondi

%d blogger hanno fatto clic su Mi Piace per questo: