, , 5 requêtes pour contrôler vos PTFS

On ne dira jamais assez comment à quel point SQL nous simplifie la vie .
C’est d’autant plus vrai pour la gestion des correctifs

Voici 5 requêtes à garder pour vos controles de PTFs

1) Contrôle de La TR et de la version avec QSYS2.GROUP_PTF_INF


SELECT CURRENT SERVER CONCAT ‘ est en version ‘ CONCAT PTF_GROUP_TARGET_RELEASE
CONCAT ‘ et le niveau de TR est : ‘ CONCAT PTF_GROUP_LEVEL AS NIVEAU_DE_TECHNOLOGY_REFRESH
FROM QSYS2.GROUP_PTF_INFO WHERE PTF_GROUP_DESCRIPTION = ‘TECHNOLOGY REFRESH’
AND PTF_GROUP_STATUS = ‘INSTALLED’ ORDER BY PTF_GROUP_TARGET_RELEASE DESC
FETCH FIRST 1 ROWS ONLY

2) Contrôle des cumulatives sur le microcode et L’OS avec QSYS2.PTF_INFO

with result_ptf
as(
SELECT PTF_PRODUCT_ID , Max(PTF_IDENTIFIER) as last_ptf
FROM QSYS2.PTF_INFO
WHERE (PTF_PRODUCT_ID = ‘5770999’ and substr(PTF_IDENTIFIER , 1 , 2) = ‘TL’ ) or
(PTF_PRODUCT_ID = ‘5770SS1’ and substr(PTF_IDENTIFIER , 1 , 2) = ‘TC’ ) GROUP BY PTF_PRODUCT_ID
)
select PTF_PRODUCT_ID, date(’20’ concat substr(LAST_ptf, 3, 2) concat ‘-01-01’) +
(dec(substr(Last_PTF , 4, 3)) – 1 ) days as last_date_ptf
from result_ptf
where date(’20’ concat substr(LAST_ptf, 3, 2) concat ‘-01-01’) +
(dec(substr(Last_PTF , 4, 3)) – 1 ) days < (current_date – 6 months)

3) Contrôle si groupes à télécharger, nécessite une connexion avec SYSTOOLS.GROUP_PTF_CURRENCY


select
cast(substr(PTF_GROUP_TITLE, 1, 50) as char(50)) as Nom_groupe,
PTF_GROUP_LEVEL_AVAILABLE as niveau
from systools.group_ptf_currency
where ptf_group_level_installed <> ptf_group_level_available

4) Contrôle si groupes à appliquer , nécessite un IPL avec QSYS2.GROUP_PTF_INFO

SELECT * FROM GROUP_PTF_INFO WHERE PTF_GROUP_STATUS not in
(‘INSTALLED’, ‘RELATED GROUP’, ‘NOT APPLICABLE’))

5) Contrôle du firmware , nécessite une connexion avec SYSTOOLS.FIRMWARE_CURRENCY

SELECT * FROM SYSTOOLS.FIRMWARE_CURRENCY
WHERE FW_CURRENTFIXPACK <> FW_RECOMMENDED_UPGRADE and +
FW_RECOMMENDED_UPGRADE is not null ) with data

Remarque

il en existe sans doute d’autres, la limite c’est votre imagination …

, , , , Mise à jour Produits Open source sur vitre IBMi

Vous connaissez l’outil ACS de gestion des packages OPEN SOURCE

Si vous décidez d’utiliser l’open source vous vous rendrez compte qu’il faudra sans doute automatiser la mise à jour des Packages RPM par YUM.

Voici donc quelques éléments pour réaliser cette opération !

D’abord vous devrez vérifier que vous avez bien Yum installé sur votre machine, normalement il es la ACS l’utilise.

Les logiciels open source sont installés dans le répertoire

/QOpenSys/pkgs/bin

sous QSH

faire un cd /QOpenSys/pkgs/bin

puis ls yum*
yum yum-builddep yum-debug-dump yum-groups-manager
yumdownloader yum-config-manager yum-debug-restore

$ Vous devez avoir le fichier yum

il est conseillé de mettre ce répertoire dans votre Path.
Vous avez un fichier .profile éditer le pour ajouter ces 2 lignes par exemple à la fin de votre fichier .profile :
PATH=/QOpenSys/pkgs/bin:$PATH
export PATH

Il est également conseillé pour des questions d’homogénisation de votre systéme d’utiliser un répertoire /home/votreprofile qui est la valaur par défaut de votre profil utilisateur (paramètre HOMEDIR de votre USER IBMi) et votre .profile devrait s’y trouver

Attention si vous voulez que ca fonctionne dans tous les environnements votre fichier .profile doit être en CCSID 819

Maintenant voyons comment procéder pour automatiser ces opérations de mise à jour
vous devrez planifier une tache qui lancera un QSH

la commande à passer pour voir si des mises à jour sont disponibles
c’est > yum check-update
Pour ce faciliter la vie on mettra cette information dans un fichier txt
yum check-update > majpackage.txt
Ce fichier comporte l’intégralité des mises à jours et même les obsolescences
pour ce limiter au logiciel qu’on veut mettre à jour on peut faire un cat avec un grep, par exemple nous on veut les mises à jour pour le logiciel NODEJS

cat majpackage.txt | grep « node »

nodejs14.ppc64 14.17.5-1 ibm
$

On voit qu’on a une mise à jour à faire, vous pouvez alors envoyer un mail par la commande sndsmtpemm pour indiquer la mise à jour à faire.

ou faire la mise à jour directement

yum update nodejs14.ppc64 -y –enablerepo=ibm
-y pour indiquer que vous allez installer en batch !

Il est conseillé de mettre un fichier de log exemple

Vous pourrez analyser ensuite la log en cas de problème en principe le nettoyage étant fait à la fin et votre version continu à fonctionner !

Il suffit de faire un ou 2 programmes CLP ou scriptes Unix et d’y intégrer ce qu’on vient de voir !

Une des problématiques quand on fait du SQL c’est d’identifier rapidement une requête qui serait trop gourmande .

Dans un poste précédent j’indiquais comment avoir ces éléments en utilisant le cache SQL, mais ca peut être long pour une première analyse !

La TR5 version 7/4, TR11 version 7/3 apporte une nouvelle fonction table (QSYS2.ACTIVE_QUERY_INFO( )) qui va nous permettre de répondre à cette problématique !

page de référence IBM

https://www.ibm.com/docs/en/i/7.4?topic=services-active-query-info-table-function

Pour l’utiliser, vous devez avoir *JOBCTL dans votre profil ou être ajouté dans la fonction USAGE QIBM_DB_SQLADM .

Exemple :


Une demande qui donne à un instant donné, les 10 requêtes les plus consommatrices de votre IBMi

SELECT QUALIFIED_JOB_NAME as travail , query_type as type_requete, File_Name as fichier , Library_name as bibliotheque,
current_runtime as temps_execution , CURRENT_TEMPORARY_STORAGE as memoire_utilisee
FROM
TABLE(QSYS2.ACTIVE_QUERY_INFO())
where current_runtime is not null
ORDER BY current_runtime desc
fetch first 10 row only

Vous pourrez alors agir en ayant le nom du travail , et utiliser la vue ACS prévue à cet effet par exemple !

On indique le premier fichier spécifié dans la requête (vue ou table), attention QSQPTABL indique que c’est une fonction table .

, , Liste de jobqs utilisées sur votre ibmi

Vous avez sans doute un grand nombre de jobqs sur votre système, mais savez vous réellement celles qui servent ?

Pour connaitre les liste des jobq utilisées, on va consulter les messages CPF11224 qui indiquent le début d’un travail et qui contiennent dans les données la jobq par lequel ils sont arrivés

j’ai utilisé dans mon exemple de table dans qtemp, vous pouvez un un with si vous préférez

Liste des jobqs utilisées

create table qtemp/lstjobqus as(
select distinct
cast(substr(message_tokens, 59, 10) as char(10)) as jobq,
cast(substr(message_tokens, 69, 10) as char(10)) as jobq_lib
FROM TABLE(qsys2.history_log_info(START_TIME => CURRENT TIMESTAMP –
30 days , END_TIME => CURRENT TIMESTAMP)) x
where message_id = ‘CPF1124’ ) with data

Liste des jobqs présentes sur le système

create table qtemp/lstjobq as (
SELECT OBJNAME as jobq, OBJLIB as jobq_lib
FROM TABLE(QSYS2.OBJECT_STATISTICS(‘ALL’, ‘JOBQ’)) ) with data

Liste des jobqs non utilisées

select a.jobq, a.jobq_lib from lstjobq as a exception join
lstjobqus as b on
a.jobq= b.jobq and a.jobq_lib = b.jobq_lib

remarque :

Avec cette liste vous pouvez faire du ménage et ne plus démarrer les sous systèmes inutiles par exemple.

, , Comment suivre son plan de production quotidien ?

Supposons que vous utilisiez le job scheduler de l’IBMi, (WRKJOBSCDE), si vous utilisez AJS seul le fichier de départ change mais la démarche reste la même.

Notre méthode ne marche que pour le jour courrant
on va utiliser la date de prochaine soumission égale à la date du jour dans notre fichier CHEDULED_JOB qui contient les jobs planifiés .

Vous devez planifier un job tous les matins à 0h et 2 minutes dans la file d’attente QCTL pour être sur de le faire passer

ce job aura une requête de ce type qui créera une table plandujour

create table plandujour as (
Select SCHEDULED_JOB_NAME, SCHEDULED_TIME,
ifnull(DESCRIPTION,  »  ») as description
from QSYS2.SCHEDULED_JOB_INFO
where NEXT_SUBMISSION_DATE = current date and
substr(SCHEDULED_JOB_NAME, 1, 1) <>  »Q »
and status <>  »HELD »
order by SCHEDULED_TIME ) with data +

Vous avez ainsi tous les jobs prévus pour la journée par heure de planification

maintenant nous allons voir comment suivre le déroulement des ces travaux

Pour suivre vos travaux on va utiliser la fonction table suivante HISTORY_LOG_INFO

exemple pour avoir les jobs du jour

SELECT * FROM TABLE(QSYS2.HISTORY_LOG_INFO(CURRENT DATE)) X

Chaque job qui tourne sur le système va générer au moins 2 messages

un CPF1124 Travail …/…/… démarré le
un CPF1164 Travail …/…/… arrêté le

donc
si votre travail n’a pas tourné vous n’avez aucun message
si votre travail tourne vous avez un CPF1124
si votre travail est terminé vous avez un CPF1164

Vous pouvez déjà suivre l’avancement grace à la zone MESSAGE_TIMESTAMP et avoir une durée entre les 2 messages

Remarque :

pour savoir si votre travail c’est terminé normalement c’est un peu plus compliqué, vous devrez analyser le code fin par exemple dans la zone MESSAGE_TEXT.

code fin 0 indiquant une fin normale du traitement

Un exemple de requête (à améliorer)

pour les codes fin , pour les jobs qui débordent de la journée etc…

WITH logdujour (mgr_id, mgr_name, mgr_dept) AS(
SELECT * FROM TABLE(QSYS2.HISTORY_LOG_INFO(CURRENT DATE)) X)
select
a.SCHEDULED_JOB_NAME as nom_travail,
a.SCHEDULED_TIME as
HEURE_prev ,
ifnull(b.MESSAGE_TIMESTAMP,  »1911-11-11-00.00.00.00000 ») as Heure_debut ,
ifnull(c.MESSAGE_TIMESTAMP,  »1911-11-11-00.00.00.00000 ») as heure_fin,
ifnull(c.SEVERITY, »99 ») as code_sev ,
ifnull(b.FROM_JOB,  »  ») as name_JOB
from plandujour a
Left outer join logdujour b
on B.MESSAGE_ID = »CPF1124 » and B.FROM_JOB like( »% » concat
A.SCHEDULED_JOB_NAME concat  »% »)
Left outer join logdujour c
on C.MESSAGE_ID = »CPF1164 » and C.FROM_JOB like( »% » concat
A.SCHEDULED_JOB_NAME concat  »% »)

Vous pouvez planifier un job chaque soir qui vous envoie un récapitulatif de la journée ,

ou que les jobs en erreur par exemple

Vous pouvez historiser ces données si vous avez besoin de consolider un suivi, etc …

Exemple d’un outil packagé utilisé dans notre centre de service pour suivre le planning quotidien:

https://github.com/Plberthoin/PLB/tree/master/DSPPLNPRD

, , SQL nom court / nom long

Rappel :

Pour les noms des objets collection, table, index, view, etc .. le système maintient en double un nom SQL et un nom IBM i
Exemple :
SQL / bd_des_articles et IBMi / BD_DE00001
la règle est la suivante pour les noms supérieurs à 10 caractères le système prends les 5 premières positions et incrémente un compteur sur 5 positions, ce qui n’est pas forcément très lisible.

pour éviter ca il est conseillé d’indiquer les 2 au moment de la création de votre objet SQL

Bien sur vous ne pourrez pas avoir des doublons ni sur le nom long ni sur le nom court

Voici quelques conseils

Création d’une base de données

Par un create schema par exemple

vous indiquez le nom sql et vous pouvez forcer un nom court par la clause FOR SCHEMA nomcourt

exemple

CREATE SCHEMA BASE_DE_DONNEES_ARTICLES FOR SCHEMA DBARTICLE

Création d’une table

create table

vous indiquez le nom sql et vous pouvez forcer un nom court par la clause SYSTEM NAME nomcourt
il est conseillé pour les mêmes raisons de mettre un nom cours un nom long par la clause FOR nomcourt

EXEMPLE

CREATE TABLE DBARTICLE.Fichier_ARTICLES FOR SYSTEM NAME ARTICLES (
NUMERO_ARTICLE FOR COLUMN NUMART DEC ( 6) NOT NULL WITH DEFAULT,
NOMCLI_ARTICLE FOR COLUMN NOMART CHAR ( 30) NOT NULL WITH DEFAULT)

vous pouvez utiliser indifféremment les 2 syntaxes

select
NUMART ,
NOMART
from DBARTICLE.Fichier_ARTICLES
ou

select
NUMERO_ARTICLE ,
NOMART
from DBARTICLE.ARTICLES

pour la plus part des autres objets vous pouvez indiquer la clause FOR SYSTEM NAME nomcourt

Création d’un index

CREATE INDEX nomlong FOR SYSTEM NAME nomcourt
ON bd (long ou court)/ table (nom court ou long)
(nom de zone court ou long)

Exemple

CREATE index DBARTICLE.key_articles_numcli FOR SYSTEM NAME key_numli
on DBARTICLE.ARTICLES
(NUMERO_ARTICLE)

Création d’une vue

CREATE VIEW … FOR SYSTEM NAME nomcourt ()

exemple

CREATE VIEW DBARTICLE.articles_nom_b FOR SYSTEM NAME articleb (
NUMERO_ARTICLE , NOMART )
as
(select
NUMERO_ARTICLE , NOMART
from DBARTICLE.ARTICLES
where NUMART like(‘B%’))

Remarques :

Vous pouvez créer une table en faisant un create table as

exemple

CREATE table DBARTICLE.articles_nom_c FOR SYSTEM NAME articlec as
(select
NUMERO_ARTICLE , NOMART
from DBARTICLE.ARTICLES
where NUMART like(‘B%’))
With data

Ce qui permet de récupérer les attributs des zones de la table

Vous pouvez renommer une zone

exemple

CREATE table DBARTICLE.articles_nom_cbis FOR SYSTEM NAME article1 as
(select
NUMERO_ARTICLE , NOMART as nom_article_bis
from DBARTICLE.ARTICLES
where NUMART like(‘B%’))
With data

Mais c’est une nouvelle zone et le nom court est conservé, bien sur sauf si c’est une zone de travail substr par exemple ….

Si vous souhaitez utiliser vos tables en RPG, vous pouvez préciser un nom de format, ce qui vous evitera un renommage dans le programme RPGLE
c’est en utilisant la clause RCDDFMT
CREATE TABLE nomdb.nomtable ( ) RCDFMT nomfmt

Exemple

CREATE TABLE DBARTICLE.Fichier_ARTICLES FOR SYSTEM NAME ARTICLES (
NUMERO_ARTICLE FOR COLUMN NUMART DEC ( 6) NOT NULL WITH DEFAULT,
NOMCLI_ARTICLE FOR COLUMN NOMART CHAR ( 30) NOT NULL WITH DEFAULT)
RCDFMT ARTICLEF

Pour connaitre les correspondances sur les objets existants
vous pouvez utiliser les vues SQL

pour les tables
SELECT TABLE_NAME, SYSTEM_TABLE_NAME FROM systables
where …

pour les indexs

SELECT INDEX_NAME, SYSTEM_INDEX_NAME FROM SYSINDEXES
where

pour les vues

SELECT TABLE_NAME, SYSTEM_VIEW_NAME FROM sysviews
where

oui la vue s’appelle TABLE_NAME ?????????? ca sent le copier coller …

on peut renommer des noms systèmes sur des objets SQL

Exemples

RENAME TABLE GDATA.LONG_NOM_TABLE TO SYSTEM NAME LONG_NOM

RENAME index GDATA.LONG_INDEX_ZONE1 TO SYSTEM NAME I_ZONE1

RENAME index GDATA.LONG_VIEW_ALL TO SYSTEM NAME LONG_VIEW

, , 5 astuces pour optimiser vos connexions ODBC.

On a souvent du mal a régler ODBC voici quelques points qui peuvent vous aider dans cette tache.
L’apport de la procédure SET_SERVER_SBS_ROUTING qui permet de router des jobs ODBC, par adresses IP ou utilisateurs à considérablement changer la donne.

Rappel sur la procédure SET_SERVER_SBS_ROUTING

Gestion par utilisateur

call qsys2.SET_SERVER_SBS_ROUTING(‘PLB’, ‘QZDASOINIT’ , ‘ODBC’)

pour activer la redirection

call qsys2.SET_SERVER_SBS_ROUTING(‘PLB’, ‘QZDASOINIT’ , NULL);

pour supprimer cette redirection

SELECT * FROM QSYS2.SERVER_SBS_ROUTING

Pour les redirections existantes par nom user

Gestion par adresse IP

Pour activer

CALL QSYS2.SET_SERVER_SBS_ROUTING(AUTHORIZATION_NAME => ‘*ALL’,
SERVER_NAME => ‘QZDASOINIT’,
IP_ADDRESS_START => ‘192.168.1.10’,
IP_ADDRESS_END => ‘192.168.1.30’,
SUBSYSTEM_NAME => ‘ODBC’)

Pour supprimer cette redirection

CALL QSYS2.SET_SERVER_SBS_ROUTING(AUTHORIZATION_NAME => ‘*ALL’,
SERVER_NAME => ‘QZDASOINIT’,
IP_ADDRESS_START => ‘192.168.1.10’,
IP_ADDRESS_END => ‘192.168.1.30’,
SUBSYSTEM_NAME => NULL);

pour voir les redirections existantes par adresses IP

SELECT * FROM QSYS2.SERVER_SBS_CONFIGURATION;

Voici quelques axes qui peuvent vous donner des idées

1) Séparer vos connexions en créant un sous système spécifique

Ce qui permet une meilleur administration.
Vous pourrez rooter vos jobs par utilisateurs ou par adresse ip grâce à la procédure sql SET_SERVER_SBS_ROUTING

CRTSBSD SBSD(VOTRESBS)
POOLS((1 *BASE))
TEXT(‘Sous systéme pour job ODBC’)
vous pouvez indiquer le pool de base

un travail à démarrage automatique

ADDPJE SBSD(GODBC) PGM(QSYS/QZDASOINIT) INLJOBS(QZDASOINIT) JOBD(Qgpl/votrejobd) CLS(QSYS/votreclasse) user(votreuser)

et un poste de routage

ADDRTGE SBSD(VOTRESBS)
SEQNBR(9999)
CMPVAL(*ANY)
PGM(VOTREPGM)
CLS(VOTRECLASS)

2) Mettre un pool spécifique sur votre sous système

Ce qui permettra de réinitialiser votre cache entre 2 benchmarks.

POOLS((1 *SHRPOOL7))

3) Mettre une classe spécifique

Ce qui permettra de régler les priorités d’exécution sur la commande rtge.
la classe par défaut est la QPWFSERVER , dupliquez la et ajustez les paramètres que vous désirez par CHGCLS.
Par exemple , les priorités
4) mettre un jobd specifique pour fixer le niveau de log par exemple sur la commande ajout des travaux auto.
la jobd par défaut est la QDFTSVR , dupliquez la et ajustez les paramètres que vous désirez par CHGJOBD.
Par exemple le niveu de log

5) Mettre un programme initial spécifique

Pour par exemple choisir le fichier qaqqini pour les réglages sql
Le programme par défaut est QCMD , voici un exemple.
Par exemple , changer le fichier QAQQINI
PGM
CHGQRYA QRYOPTLIB(&LIB)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(‘Vous +
utilisez désormais QAQQINI de la +
bibliothèque, ‘ BCAT &LIB) MSGTYPE(STATUS)
ENDPM

Rappel :

Ici on traite pas de la traçabilité, il est important de voir qui peut faire de l’odbc sur votre système.

Nous avons un logiciel GODBC qui peut vous aider dans cette tache ici : https://www.gaia.fr/produits/

, , Moderniser vos menus IBMi

Vous pouvez désormais accèder aux fichiers des messages par SQL grace à la vue SQL QSYS2.MESSAGE_FILE_DATA.

Vos menus personnalisés utilisent des commandes qui sont stockés dans des fichiers messages

Voici une idée pour améliorer vos menus

l’idée c’est prendre la commande à éxecuter et l’afficher, vous pouver customizer l’affichage du texte

J’ai publié le code sur github l’adresse suivante : https://github.com/Plberthoin/PLB/tree/master/GTOOLS

Vous devez récupérer, un dds , un sqlrpgle et une cmd

Voila qui peut vous donner des idées pour la gestion de vos fichiers messages

, Télécharger PTF par FTPS

Téléchargement de PTF par FTP

Depuis mi-juillet , ce n’est plus un choix le mode FTP simple en anonymous ne fonctionne plus , vous le voyez quand vous allez sur fix central le mode ftps ou sftp est par défaut .

Quand vous faites votre demande sous recevez désormais 3 mails au lieu de 2
-Le premier, pour vous dire que votre demande a été prise en compte.
-Le deuxième, pour vous indiquer les instructions à passer pour votre téléchargement
-Le Troisième (nouveau) qui contiendra le mot de passe que vous devrez utiliser

Comment faire désormais pour télécharger ces PTFs, on va voir 2 méthodes ?

1) A partir de Filezilla


Le logiciel connait le certificat racine Digicert
donc si vous vous connectez en ssl sur le site delivery01-bld.dhe.ibm.com ,il vous propose la première fois de télécharger le certificat.

Et vous pouvez faire votre téléchargement .

2) A partir de votre partition IBMi

Il va vous falloir installer le certicicat racine Digicert et le certificat du site dans DCM qui gére les certificats coté IBMi.

il est conseiller pour faire ses installations d’utiliser le logiciel QMGTOOLS.

nous vous conseillons également de le mettre à jour pour éviter les problémes.

ADDLIBLE LIB(QMGTOOLS)
GO MENU(MG)

  1. Check IBM for updated QMGTOOLS

Vous pouvez donc maintenant faire vos installations

Le certificat racine est disponible ici

https://www.ibm.com/support/pages/node/1077897

Vous devez dezipper vos fichiers et les copier dans l’IFS de votre IBM i par exemple /temp

Vous allez utilisez la première commande suivante
GETSSL pour le certifcicat racine
détail ici
https://www.ibm.com/support/pages/node/683901
et pour installer le certificat vous allez à nouveau utiliser la commande GETSSL avec le paramétrage suivant
QMGTOOLS/GETSSL IP(WWW.ECUREP.IBM.COM)
PORT(443)
AUTOIMP(Y)
STOREPWD(‘votre mot de passe’)

Si vous allez dans DCM vous avez un nouveau certificat installé QMG0001

Vous pouvez désormais vous connecter au site avec la commande suivante

FTP RMTSYS(‘delivery01-bld.dhe.ibm.com’) SECCNN(*SSL)

Attention cependant vous devrez forcer le mode par la commande FTP SENDEPRT

Voila, une fois que vous avez paramétrer vous pouvez utiliser télécharger vos PTFs comme avant.