Documentos y utilidades para AS/400 que he ido creando y recopilando a lo largo de los años trabajando con este gratificante sistema operativo. www.as400howto.com
lunes, 22 de diciembre de 2008
martes, 16 de diciembre de 2008
Memoria para trabajos batch
Por omisión el subsistema QBATCH corre en el pool de memoria *BASE, esta configuración mezcla trabajos de sistema con nuestros trabajos por lotes, que posiblemente tienen unas necesidades de ejecución muy diferentes.
¿Como podemos asignar una memoria especial para nuestros trabajos por lotes en el subsistema QBATCH?, pues es sencillo:
- Debemos asignar memoria a un pool de memoria compartido, habitualmente para los trabajos del QBATCH se utiliza el *SHRPOOL1, calcular un tamaño mínimo para el pool (400 p.e. después se ajustara) y un nivel de actividad (numero trabajos activos al mismo tiempo en el pool, 10 p.e.) y ejecutar:
- CHGSHRPOOL POOL(*SHRPOOL1) SIZE(400) ACTLVL(10) PAGING(*CALC) TEXT('Batch jobs pool')
- Después añadir, al subsistema QBATCH, como segundo pool de memoria el *SHRPOOL1:
- CHGSBSD SBSD(QBATCH) POOLS((2 *SHRPOOL1))
- Una vez hecho, debemos cambiar el direccionamiento para que los trabajos que se sometan en este subsistema utilicen el segundo pool de memoria:
- CHGRTGE SBSD(QSYS/QBATCH) SEQNBR(9999) POOLID(2)
- A partir de este instante los trabajos que se sometan en el subsistema QBATCH utilizaran el pool de memoria *SHRPOOL1.
- El ajuste automático de rendimiento cambiará el tamaño de ese pool y su nivel de actividad según las necesidades de los trabajos, de la disponibilidad de recursos y de los parámetros que le indiquemos en la gestión de pools (WRKSHRPOOL).
Memoria para subsistema
Asignar prioridad automáticamente
lunes, 15 de diciembre de 2008
Subsistema de Control
Esta configuración se controla con el valor de sistema QCTLSBSD, podemos visualizarlo con DSPSYSVAL SYSVAL(QCTLSBSD).
En los nuevos sistemas viene por defecto como QBASE, en este caso solo arranca unos pocos subsistemas (QSYSWRK, QUSRWRK, QSERVER, QSPL) y la gestión de rendimiento es más difícil, ya que casi todos los trabajos corren en el mismo pool de memoria.
La otra configuración estándar (que viene de los tiempos del S/38) es utilizar el subsistema QCTL, para activarlo solo hemos de cambiar el valor del sistema QCTLSBSD con:
CHGSYSVAL SYSVAL(QCTLSBSD) VALUE('QCTL QSYS ')
Para que el cambio se active deberemos realizar IPL del sistema, por lo tanto deberemos planificar este cambio para cuando sea posible hacerlo.
Ahora cuando arranquemos el sistema tendremos el subsistema de control QCTL en lugar del QBASE. Ademas deberemos incluir en nuestro programa de inicio (valor de sistema QSTRUPGM) el arranque de los subsistemas QBATCH (para trabajos por lotes) y QINTER (para trabajos interactivos) si es que lo hemos modificado.
Ya de paso podemos activar el ajuste automático de rendimiento del sistema con:
CHGSYSVAL SYSVAL(QPFRADJ) VALUE('2')
Este cambio indica al sistema que haga el ajuste de rendimiento en IPL y dinámicamente y entra en vigor inmediatamente.
Este ajuste incluye entre otros:
- Tamaño memoria
- Niveles de actividad
- Paginación
Para una información más detallada podemos consultar el documento Experience Report
martes, 2 de diciembre de 2008
Cambiar inicio de sesión
Primero hemos de tener en cuenta que:
- El inicio de sesión se asocia a un subsistema, por tanto podemos tener, para algunos subsistemas, diferentes pantallas de inicio de sesión.
- No es buena idea cambiar la pantalla del subsistema QCTL.
- También deberíamos crear la nueva pantalla en una biblioteca del sistema, como la QGPL, para evitar problemas en caso de restaurar el sistema.
- Crearemos la nueva pantalla tomando como base la del fuente ubicado en QGPL/QDDSSRC.QDSIGNON, la podemos copiar como MYSIGNON.
- CPYSRCF FROMFILE(QGPL/QDDSSRC) TOFILE(QGPL/QDDSSRC) FROMMBR(QDSIGNON) TOMBR(MYSIGNON)
- Editar el nuevo archivo de pantalla (tipo DSPF) con el PDM, o el SDA.
- Si lo que queremos es añadir un texto tipo ASCII Art, puede que nos sea más fácil añadirla con el SDA.
- Hemos de respetar todos los campos, si no queremos mostrarlos, los podemos configurar como ocultos, con la columna Use = H o con las palabras clave DSPATR(PR) y DSPATR(ND).
- Lo más habitual es solo dejar los campos de entrada Usuario (USERID) y Contraseña (PASSWRD) y de salida con el nombre del Sistema, Subsistema y dispositivo (SYSNAME, SBSNAME, DEVNAME).
- Una vez creada la nueva pantalla de inicio de sesión, podemos probarla creando un subsistema especial, ¿como hacerlo? ver la entrada publicada "Asignar prioridad automáticamente" para crear un subsistema SPECIAL.
- CHGSBSD SBSD(QGPL/SPECIAL) SGNDSPF(QGPL/MYSIGNON)
- Una vez comprobado el nuevo inicio de sesión funciona correctamente, ya podemos cambiar la configuración del subsistema QINTER:
- CHGSBSD SBSD(QINTER) SGNDSPF(QGPL/MYSIGNON)
- Una vez hecho esto debemos reiniciar el subsistema QINTER, si tenemos usuarios conectados deberemos buscar el momento adecuado para hacerlo.
- Esto deberíamos hacerlo desde la consola del sistema:
- ENDSBS SBS(QINTER) OPTION(*IMMED)
- y a continuación:
- STRSBS SBSD(QINTER)
- Y ya tenemos nuestra nueva pantalla de signon.
viernes, 28 de noviembre de 2008
Obtener listas objetos en IFS
WRKLNK OBJ('/') DETAIL(*EXTENDED) DSPOPT(*ALL) pero si desde un programa queremos obtener una lista de archivos del directorio '/home/temp' (por ejemplo) no tenemos un mandato para hacerlo directamente y hemos de volcarlo a spool y leer ese spool o utilizar una API del sistema.
Una solución sencilla, si esta instalado el entorno QSHELL (opción 30 del 5722SS1) , es ejecutar mandatos tipo UNIX, pongo algunos ejemplos de los que se puede conseguir:
Obtener contenido del directorio /home/temp (en el archivo MYLIB/LISTDIR):
- QSH CMD('ls /home/temp/* >/qsys.lib/mylib.lib/listdir.file/listdir.mbr')
- QSH CMD('find / -type d |grep -v "QSYS.LIB" |grep -v "QNTC">/qsys.lib/mylib.lib/listdir.file/listdir.mbr')
- QSH CMD('ls -alR / |grep "/" |grep -v "l" |grep -v "QSYS.LIB">/qsys.lib/mylib.lib/listdir.file/listdir.mbr')
martes, 18 de noviembre de 2008
Prompt selectivo de mandato
El prompt selectivo se utiliza insertando caracteres especiales delante de los parámetros de los mandatos, los valores permitidos son:
- ?? Muestra el prompt del parámetro y permite cambiarlo.
- ?* Muestra el prompt del parámetro pero no permite cambiarlo
- ?- Oculta el parámetro.
- ?< Muestra el prompt del parámetro y permite cambiarlo, pero el valor por omisión es el que le enviamos desde el programa.
- ?& Solo se muestra el prompt del parámetro si se pulsa F10 y permite cambiarlo.
- ?% Solo se muestra el prompt del parámetro si se pulsa F10, pero no permite cambiarlo.
- blanco Muestra solo los parámetros con prompt selectivo, no permite F9.
- ? Muestra prompt del mandato y permite cambiar parámetros y pulsar F9.
RSTOBJ ??OBJ(*ALL) SAVLIB(LIBSAV) ?-DEV(*SAVF) OBJTYPE(*ALL) ?*SAVF(LIBSAVF/SAVF) ??RSTLIB(LIBSAV2)
Al ejecutar el programa obtendremos la siguiente pantalla:
Veamos que ocurre si añadimos el carácter ? delante del mandato RSTOBJ, también añadimos ?- en el parámetro DEV :
? RSTOBJ ??OBJ(*ALL) SAVLIB(LIBSAV) ?-DEV(*SAVF) OBJTYPE(*ALL) ?*SAVF(LIBSAVF/SAVF) ??RSTLIB(LIBSAV2)
Para controlar el prompt de los parámetros opcionales se utiliza ?% y ?&, aunque puede complicarnos el programa ya que hay parámetros que pueden depender de si usamos otros.
Nota: Si usamos el prompt selectivo también debemos de incluir la siguiente instrucción por si nos pulsan F3=Salir o F12=Cancelar:
MONMSG MSGID(CPF6801) /* F3 o F12 */
Más información en iSeries Information Center
domingo, 2 de noviembre de 2008
Asignar prioridad automáticamente
Supongamos que tenemos unos trabajos que queremos que tengan cierto tipo de prioridad (alta o baja) en la ejecución, habitualmente se utilizan los parámetros RUNPTY y TIMESLICE, para ello habremos de crear una clase especial para nuestros trabajos y es recomendable también crear un subsistema especial para dichos trabajos.
El procedimiento a seguir para crear este entorno especial:
- Crear la cola de trabajos asociada al subsistema:
- CRTJOBQ JOBQ(QGPL/SPECIAL) TEXT('Job queue for specials jobs Subsystem')
- Crear el subsistema:
- CRTSBSD SBSD(QGPL/SPECIAL) POOLS((1 *BASE) (2 *SHRPOOL1)) MAXJOBS(*NOMAX) TEXT('Subsystem for specials jobs')
- Con esto conseguimos que el trabajo, de tipo subsistema, se ejecute en el pool de memoria base y el resto de trabajos del subsistema se ejecutaran en el pool de memoria *SHRPOOL1.
- Añadir la cola de trabajos al subsistema:
- ADDJOBQE SBSD(QGPL/SPECIAL) JOBQ(QGPL/SPECIAL) MAXACT(*NOMAX) SEQNBR(10)
- Poner *NOMAX, o el numero máximo de trabajos, que queremos que se ejecuten por esa cola, el numero de secuencia es importante por si tenemos más de una cola de trabajos.
- Crear la nueva clase:
- CRTCLS CLS(QGPL/SPECIAL) RUNPTY(25) TIMESLICE(10000) PURGE(*NO) TEXT('Class for subsystem of special jobs')
- Asignar las entradas de direccionamiento para solo los trabajos batch que queramos usen la nueva clase:
- ADDRTGE SBSD(QGPL/SPECIAL) SEQNBR(10) CMPVAL('SPECIAL') PGM(QCMD) CLS(QGPL/SPECIAL) POOLID(2)
- Añadir entradas de direccionamiento para el resto de trabajos:
- ADDRTGE SBSD(QGPL/SPECIAL) SEQNBR(9999) CMPVAL(*ANY) PGM(QCMD) CLS(*LIBL/QBATCH) POOLID(2)
- Con estas dos entradas de direccionamiento conseguimos que:
- Los trabajos que, en la descripción de trabajo, envían como direccionamiento el valor RTGDTA('SPECIAL') usaran la clase QGPL/SPECIAL que les asignará un RUNPTY de 25 y un TIMESLICE de 10.000.
- El resto de trabajos usará la clase QGPL/QBATCH, que les asigna un RUNPTY de 50 y un TIMESLICE de 5.000.
- En ambos casos los trabajos se ejecutaran por el POOLID 2, o sea en este caso en el *SHRPOOL1 (ver paso 5).
- A continuación creamos una nueva descripción de trabajo, o modificar la que queramos usar, para que los trabajos se sometan por el nuevo subsistema:
- CRTJOBD JOBD(QGPL/SPECIAL) JOBQ(QGPL/SPECIAL) TEXT('Job description for special jobs') RTGDTA('SPECIAL')
- También podemos someterlos con SBMJOB, pero entonces habrá que acordarse de comprobar y modificar manualmente el parámetro RTGDTA en el mandato SBMJOB, en caso contrario usaran la clase por omisión asignada a *ANY.
- Si además queremos usar el mismo subsistema para que se conecte alguna pantalla tendremos de:
- Añadir el pool de memoria interactivo al subsistema:
- CHGSBSD SBSD(QGPL/SPECIAL) POOLS((1 *BASE) (2 *SHRPOOL1) (3 *INTERACT))
- Añadir una entrada de direccionamiento para los trabajos interactivos:
- ADDRTGE SBSD(QGPL/SPECIAL) SEQNBR(20) CMPVAL('QCMDI') PGM(QCMD) CLS(*LIBL/QINTER) POOLID(3)
- Añadir el nombre de dispositivo de pantalla que tendrá acceso al subsistema:
- ADDWSE SBSD(QGPL/SPECIAL) WRKSTN(Device_name)
- Con esto conseguimos que los trabajos interactivos se les asigne los valores de la clase QINTER y que son de RUNPTY 20 y un TIMESLICE de 2.000.
- Además se ejecutaran en el pool de memoria para trabajos interactivos (*INTERACT), optimizando de esta forma el funcionamiento del ajuste automático de rendimiento del sistema:
- Ahora solo nos queda:
- Asignar memoria al pool compartido *SHRPOOL1, si no lo estamos usando (podemos comprobarlo con WRKSHRPOOL):
- CHGSHRPOOL POOL(*SHRPOOL1) SIZE(256) ACTLVL(1)
- Finalmente arrancar el nuevo subsistema:
- STRSBS SBSD(QGPL/SPECIAL)
- El tamaño del pool y el nivel de actividad se irán ajustando automáticamente si tenemos el ajuste de rendimiento del sistema activado:
- DSPSYSVAL SYSVAL(QPFRADJ)
Nota: Si queremos deshacer la asignación de memoria en *SHRPOOL1 ejecutar el mandato CHGSHRPOOL POOL(*SHRPOOL1) SIZE(*NOSTG)
viernes, 10 de octubre de 2008
Sincronizar la hora del AS400
En nuestro AS400 tenemos disponible este servicio desde la V5R2, y es funcional (o sea que cambia la hora del reloj automáticamente) a partir de la V5R4. Para configurar el servicio SNTP en el AS400 ejecutar el mandato CHGNTPA con los parámetros:
CHGNTPA RMTSYS('direccion_servidor_hora') AUTOSTART(*YES) POLLITV(60) MINADJ(100) MAXADJ(20) ACTLOG(*CHANGE)
Además debemos activar la opción de ajuste automático de la hora:
CHGSYSVAL SYSVAL(QTIMADJ) VALUE(QIBM_OS400_SNTP)
También debemos configurar nuestra zona horaria para ello ejecutar:
WRKSYSVAL SYSVAL(QTIMZON), el valor para Europa es QP0100CET4
Offset . . . . . : +02:00
Full name . . . : Central European Daylight Saving Time
Abbreviated name : CEST
Podemos pulsar F4 para vez las zonas disponibles.
Para detener el servicio ejecutar: ENDTCPSVR SERVER(*NTP)
Nota: Revisar esta carpeta periódicamente, ya que se van acumulando los logs y no se vacían automáticamente.
martes, 7 de octubre de 2008
Modificar menu PetSis
El valor por omisión del mensaje se puede ver con el mandato:
Para ello seguiremos el siguiente procedimiento:
- Crearemos el programa CL DSPJOB2CL
- Crearemos el mandato DSPJOB2 que llama al programa DSPJOB2CL
- Este programa comprueba el tipo de usuario, si es *SECOFR o *PGMR o *SYSOPR ejecuta el mandato WRKJOB, en caso contrario ejecuta el mandato DSPJOB (como hasta ahora).
- Finalmente cambiamos el texto de mensaje CPX2313 para que ejecute DSPJOB2 en lugar de DSPJOB: CHGMSGD MSGID(CPX2313) MSGF(QSYS/QCPFMSG) MSG('ENDRQS DSPJOB2 DSPMSG SNDMSG SIGNOFF DSPMSG DSCJOB DSPWSUSR ENDRDBRQS ')
- ¡¡ Respetar espacios en blanco en el cuerpo del mensaje!!
Notas:
- El código de DSPJOB2 lo podemos bajar de aquí.
- Si tenemos lenguajes secundarios instalados, deberemos realizar el mismo cambio para todas las bibliotecas QSYSnnnn.
- Deberemos revisar este mensaje cada vez que actualicemos el sistema operativo, o que alguna ptf modifique el archivo de mensajes QCPFMSG.
Calculadora en ventana
La ayuda la tenemos pulsando la tecla F1.
El código de esta utilidad lo podemos bajar de aquí.
jueves, 2 de octubre de 2008
Memoria para subsistema
Como reservar memoria y asignar una prioridad automáticamente para ciertos trabajos o aplicaciones en uno o más subsistemas utilizando la memoria compartida.
En esta entrada explicare como reservar cierta cantidad de memoria para un subsistema.
- Crear un subsistema para ese tipo de trabajo es buena idea, así separamos el consumo de memoria y el ajuste automático del sistema trabaja mejor (QPFRADJ).
- Doy por supuesto que tienes el ajuste automático del sistema activado (QPFRADJ 2 o 3)
- Puedes asignarle a ese pool una cantidad de memoria, que puede ser variable o fija. Si la quieres siempre fija lo indicaras cuando creas el subsistema (CRTSBSD)
- Para crear un pool de memoria haz WRKSHRPOOL y asigna memoria, por ejemplo, al *SHRPOOL2, habitualmente el *SHRPOOL1 se utiliza para trabajos en el subsistema QBATCH, aunque no viene definido por omisión en el sistema.
- Después debes cambiar la descripción del nuevo subsistema para que utilice ese nuevo pool de memoria, normalmente yo recomiendo poner 2 pools el *BASE en primer lugar y *SHRPOOL2 en segundo lugar.
- Después deberás crear nuevas clases (CRTCLS) para el nuevo subsistema, que utilicen el segundo pool de memoria del subsistema y asignarlas a las entradas de direccionamiento del mismo (CHGRGTE), esto lo explicare en otro howto.
- Con esto conseguimos que el trabajo subsistema, corra en el pool *BASE y el resto de trabajos, dentro del subsistema, en el *SHRPOOL2.
- Para el ajuste de memoria del *SHRPOOL2, haz WRKSHRPOOL y pulsa F11 (otra vista), en las columnas que ves, puedes definir que porcentaje de memoria mínimo y máximo quieres que se lleven los trabajos de ese pool, si ponemos el mismo porcentaje en min y max lo que conseguimos es dejar fijo el tamaño de la memoria utilizada por ese pool.
- Esto creo que es mejor que asignar memoria fija al subsistema (paso 3) ya que en caso de equivocarnos solo hemos de cambiar el porcentaje y el ajuste auto del sistema hará el resto. De la otra forma hay que parar el subsistema.
- ¿Como calcular el tamaño de memoria que vas a necesitar?, pues es difícil, seguramente los trabajos están más tiempo esperando o leyendo disco, que utilizando memoria y CPU, pero si tiene que ver con la cantidad de trabajos que tenemos activos y en RUN en el subsistema. Mi recomendación es partir de un valor de tamaño de pool conocido, tirando a alto, y observar la paginación de ese pool de memoria (DSPSYSSTS) , si aparecen trabajos en estado INEL, indica que falta memoria en ese pool, ir añadiendo memoria al pool hasta que veamos que ya no aparecen trabajos en INEL u estado intermedios.
- Una recomendacion, para hacer estos ajustes, es mejor que no lo hagas en tu hora punta (mas que nada para que no te lleguen llamadas de usuarios) y tambien es mejor desactivar, mientras haces la prueba, el ajuste automático del sistema (QPFRADJ = 0) ya que en caso contrario te puede distorsionar el resultado.
- También debes saber que si tu proceso utiliza SQL el optimizador de SQL puede que decida crear un nuevo plan de acceso si ve que ha cambiado el tamaño del pool, eso no debería suponer un problema, pero en algunas instalaciones se traduce en un peor tiempo de respuesta de la aplicación, ya que reconstruye el plan de acceso demasiado a menudo.
jueves, 25 de septiembre de 2008
Duración de un RCLSTG
DSPDTAARA DTAARA(QUSRSYS/QRCLSTG)
Tal como se ve en la imagen el ultimo RCLSTG se ejecuto desde las 05:45:15h hasta las 09:51:46 del 01/06/2008, por tanto el proceso duro 4h 6min. 31seg.
En el histórico del sistema se graba el mensaje CPC8208 "Proceso de RCLSTG terminado" que nos informa de la cantidad de objetos procesados y suprimidos.
Para imprimir el histórico del sistema con los mensajes de como ha ido:
DSPLOG PERIOD((hora_inicio fecha_inicio) (hora_fin fecha_fin)) OUTPUT(*PRTSECLVL) MSGID(CPC8208 CPF3120 CPC3308 CPF8240 CPF8262 CPF8260 CPFA914 CPI8202 CPI8A10 CPC8A21 CPC8A22)Para ver el contenido de la biblioteca QRCL , donde van a parar los objetos recuperados por el RCLSTG, ejecuta el mandato:
DSPLIB LIB(QRCL)Esto es conveniente porque se puede haber recuperado algún objeto de tamaño considerable y que seguramente se debería eliminar.
De paso recordar que se debería pasar un RCLSTG periódicamente o, cuando ha habido una caída del sistema, y es casi obligatorio pasarlo antes de la instalación de una nueva release del sistema operativo.
También tener en cuenta que a partir de la V5R4 (algunos antes) tenemos algunos mandatos para reclamar cosas sin tener el sistema restringido:
- RCLDBXREF Reclaim DB Cross-Reference
- RCLDLO Reclaim Document Lib Object
- RCLLIB Reclaim Library
- RCLLNK Reclaim Object Links
- RCLOBJOWN Reclaim Objects by Owner
- RCLSPLSTG Reclaim Spool Storage
- RCLSTG Reclaim Storage
miércoles, 10 de septiembre de 2008
Cuenta iSeries gratuita
Pues bien existe la web de Innovative Systems que nos da esa posibilidad
Solo hemos de registrarnos y esperar que nos envíen el usuario y la contraseña para acceder a un sistema AS400 remoto a través de Internet.
Espero que os sirva de ayuda :o)
miércoles, 3 de septiembre de 2008
Nefarious Masqueraders
En él, se nos introduce en las técnicas para introducirse en un AS/400 y que nos puede servir, como administradores de sistemas, para ser conscientes de las vulnerabilidades del sistema y, de esta forma, poder tomar medidas para proteger mejor nuestros sistemas.
martes, 24 de junio de 2008
Lógicos en diferente biblioteca
SELECT DbFLib, DbFFil, DbFLDp, DbFFDp
FROM Qsys/QADbFDep
WHERE DbFLib <> DbFLDp
ORDER BY DbFLib, DbFFil, DbFLDp, DbFFDp
Esto también se aplica a archivos con restricciones, aunque en este caso es recomendable no tener archivos dependientes en diferentes bibliotecas y evitemos, siempre que podamos, estas situaciones.
Por ejemplo, si restauramos desde las copias de seguridad, realizadas con *ALLUSR, las bibliotecas están salvadas en la cinta en orden alfabético, pero el archivo LIB1/INDEX1 no se restaurara, porque no encuentra el archivo físico FILE1, del que depende, ya que esta en la biblioteca LIB2 que aun no se ha restaurado.
Library File Type
LIB1 INDEX1 LF
LIB2 FILE1 PF
jueves, 19 de junio de 2008
Gestionar receptores de diario
Dejo aparte la gestión de los receptores del propio sistema, que habitualmente se autogestionan en tiempo de IPL, si no vamos a realizar IPL en muchos tiempo puede que tengamos también que incluirlos en nuestra estrategia, no sin antes verificar y consultar con IBM, si fuese necesario, que impacto puede tener en el sistema.
- Caso1: En los sistemas de producción los receptores de diario están gestionados por MIMIX (u otra herramienta de replicación) y se mantienen en linea unos días y después se eliminan automáticamente por el software de replicación y si se han salvado previamente a cinta.
- Caso2: En los sistemas de producción que no tienen MIMIX, los receptores se van salvando a cinta y eliminando periódicamente (según el sistema).
- Caso3: En los sistemas de desarrollo (que nunca tienen MIMIX) los receptores los elimina automáticamente el sistema, cuando ya no hay ningún ciclo de compromiso pendiente y aunque no estén salvados a cinta, excepto los de auditoria del sistema (QAUDJRN) que se eliminan una vez salvados a cinta.
- Caso4: Poner la vuestra...
- Caso1: MIMIX detecta en que ciclo de commit estamos "encallados" y que nos retrasa la hora de aplicación de MIMIX, con la utilidad DSPJOBSEC averiguamos rápidamente que trabajo tiene el ciclo de commit abierto y podemos actuar en consecuencia.
- Caso2: Podemos deducir que con el movimiento normal podemos generar, en una semana (p.e.) 10 receptores de diario, si detectamos que hay más receptores de lo habitual es posible que hayan ciclos de commit abiertos.
- Caso3: Este es el más fácil, como mucho solo puede haber un receptor conectado al diario, ya que el resto el sistema y los va eliminando automáticamente, por tanto si vemos que hay más, es (casi) seguro que algún trabajo tiene un ciclo de commit abierto.
- Programas que no hacen commit (mala programación), o se meten en un bucle.
- Sentencias SQL. o QMQuery, sin ciclos de compromiso de larga ejecución; deberían evitarse o analizar si es posible lanzarlos con WITH NC (sin commit) aunque eso a veces no es posible si queremos tener consistencia en la base de datos.
- A veces detectamos algún CPYF que tiene ciclos de commit (no recuerdo bien como fue).
- Programadores que están debugando, abren un ciclo de commit, les casca el programa y van a por otra cosa, o hacen petición de sistema, o se van a comer, y el ciclo de commit se queda abierto hasta que no hacen signoff.
- Otras ?? (que cada uno añada las suyas)
- Estuve investigando usar el mandato WRKCMTDFN (a partir V5R4) pero de momento no puedo diferenciar los ciclos de commit abiertos con registros pendientes de los que no, aunque si se ve por pantalla con F11, a lo mejor dándole al "coco" mas tiempo....
- De momento se nos ocurrió: Contar el numero de receptores de diario de cada diario.
- DSPOBJD OBJ(*ALL/*ALL) OBJTYPE(*JRNRCV) OUTPUT(*OUTFILE) OUTFILE(QTEMP/JRNRCV) OUTMBR(*FIRST *REPLACE)
- Doy por supuesto que en una biblioteca no hay mas de un diario, que podría ser.
- Deberemos omitir el diario de auditoria y los de sistema, habitualmente empiezan por Q* y en bibliotecas que también empiezan por Q*.
- Otra estrategia seria hacer:
- DSPOBJD OBJ(Mylib/Myjrn1) OBJTYPE(*JRNRCV) OUTPUT(*OUTFILE) OUTFILE(QTEMP/JRNRCV) OUTMBR(*FIRST *REPLACE)
- DSPOBJD OBJ(Mylib/Myjrn2) OBJTYPE(*JRNRCV) OUTPUT(*OUTFILE) OUTFILE(QTEMP/JRNRCV) OUTMBR(*FIRST *ADD)
- DSPOBJD OBJ(MylibX/MyjrnX) OBJTYPE(*JRNRCV) OUTPUT(*OUTFILE) OUTFILE(QTEMP/JRNRCV) OUTMBR(*FIRST *ADD)
- Después contamos los receptores de cada diario, o lo hacemos por cada biblioteca cada vez, en fin múltiples posibilidades según se adapte a nuestra estrategia.
- Una vez sabemos que diario tiene un numero "anormal" de receptores, dejo para cada uno lo que es anormal, seguimos con:
- Volcamos el contenido del diario, de las entradas relacionadas con los ciclos de commit, a fichero (esto puede tardar):
- DSPJRN JRN(Mylib/MyJrn) RCVRNG(*CURCHAIN) JRNCDE((C)) OUTPUT(*OUTFILE) OUTFILE(QTEMP/DSPJRN)
- Después ejecutamos la sentencia SQL siguiente (esto es la "madre del cordero" ¡¡ gracias Inma!!):
(SELECT * FROM dspjrn WHERE joentt <> 'SC') SELECT aa.joseqn,
aa.jodate, aa.jotime, aa.jonbr, aa.jouser, aa.jojob, aa.joccid from
aa LEFT EXCEPTION JOIN bb ON aa.joccid = bb.joccid
- Esta SELECT nos devolverá la lista de trabajos con un ciclo de commit abierto, y la hora de del ciclo de commit, ya solo nos queda ir al trabajo a ver que pasa.
Por poner un ejemplo: Un programador un viernes y en un sistema de desarrollo (que estan 24x7) hace un call a un programa que se mete en un bucle, con un ciclo de commit abierto, haciendo updates del mismo registro como un "poseso", se cae su sesión y como no puede volver a entrar, se marcha de fin de semana. El lunes se descubre que hay una sesión en RUN todo el tiempo, se hace un ENDJOB *IMMED, con millones de cambios comprometidos en el mismo ciclo de commit. El trabajo tarda como 2 horas en empezar a hacer el rollback y 2 días en terminarlo. A todo esto la ocupación en disco ha ido subiendo, porque el sistema no elimina los receptores de diario desconectados, y salvados, ya que hay un ciclo de commit con transacciones pendientes. En fin que tenemos maquinas potentes, que si no andamos con cuidado podemos cargarnos el sistema.
domingo, 25 de mayo de 2008
Porcentaje rollback realizado
- Ejecutar mandato DSPJOB JOB(num_job/user_job/name_job)
- Seleccionar opcion "16. Display commitment control status, if active"
- Opcion "5=Display"
- Pulsar "F6=Display resource status"
- Pulsar AvPag.
- Seleccionar opcion "1=Select" en el recurso "Journal"
- Finalmente pulsar "F11=Display rollback status"
lunes, 5 de mayo de 2008
Restaurar archivos QHST
- Cargar la cinta donde realizamos el SavSys
- DSPTAP DEV(TAP01) DATA(*SAVRST)
- Ir pulsando Intro hasta encontrar la secuencia donde están los archivos QHST.
- Anotar numero secuencia y ID etiqueta archivo (p.e. Q5722SS1510310090)
- Ejecutar RSTOBJ OBJ(QHST*) SAVLIB(QSYS) DEV(TAP01) OBJTYPE(*FILE) VOL(Q5722SS1510310090) SEQNBR(33)
domingo, 6 de abril de 2008
Mejorar teclado emulacion 5250
La configuración por omisión no incluye ciertas funciones que los usuarios de los sistemas operativos de ventanas encontramos a faltar, como son las teclas Inicio para ir al Inicio del Campo, Fin para ir al Fin del Campo, Ctrl+C para Copiar un texto seleccionado o Ctrl+V para Pegar un texto; Ctrl+X no tiene sentido en una emulación 5250.
Como hacer esta personalización de teclado de la emulación, pues seguir los siguientes pasos:
- Bajaros el archivo as400_mejorado.kmp y lo guardais en la carpeta C:\Program Files\ibm\Client Access\Emulator\Private o donde os parezca mejor.
- Desde la emulación de pantalla del Personal Communications, pulsais el icono o Edit, Preferences, Keyboard, Customize.
- Despues File, Open y seleccionar el archivo de configuración de teclado que os habeis bajado.
- A continuación salvar la nueva configuración.
Esta configuración de teclado también convierte la tecla grande de Intro, como un Intro y no como Salida de Campo, esta la muevo a la tecla Ctrl de la derecha.
miércoles, 2 de abril de 2008
La clave de las claves
- Una contraseña ha de ser sencilla. Desde luego, la clave TMXKQGSW resulta bastante segura frente a hackers que lo intentan al azar, pero es muy difícil de recordar.
- Una contraseña no debe tener significado. Las palabras con significado son las más fáciles de reventar. Esto no excluye que sean sencillas de memorizar. Ejemplos: ZAZAMELI, PERPOLAS, RATOGARU.
- Una contraseña hay que memorizarla, no apuntarla. Quien no se fíe demasiado de su memoria a largo plazo, puede apuntar su palabra clave, pero nunca de manera que un extraño pueda reconocerla como tal. Así, nunca se la ha de escribir en el listín telefónico bajo CLAVE, SECRETO u ORDENADOR. Es mejor garabatearla en la agenda junto al recordatorio del cumpleaños de la abuela. En ningún caso se debe dejar la nota escrita cerca del ordenador, bajo el teléfono o pinchada en el panel de corcho.
- De vez en cuando conviene cambiar la contraseña. Por si acaso alguien no autorizado ya lo conoce pero todavía no se ha decidido a usarlo. Tampoco es preciso cambiarlo muy a menudo, podría causarnos molestas equivocaciones.
- Una contraseña se teclea en privado. Al introducir la clave antes de comenzar una sesión de trabajo, hay que asegurarse de que nadie mire por encima del hombro. Las personas de confianza hacen honor a su nombre respetando la intimidad del propietario de la clave.
- Ciertas palabras nunca han de servir de contraseña:
- Nombres propios y apellidos.
- Apodos. El propio, jamás, pero tampoco el del perro o el gato.
- Palabras informáticas, como TEST, SYSTEM, CHECK, BYTE...
- Fechas de cumpleaños.
- Cadenas con método: ABCDEFGH, A1B2C3, QWERTY...
- Palabras de moda: CHUNGO, GUAI, SUPER, TOTAL...
- Nombres de la mitología, la literatura o ciencia-ficción: Zeus, Quijote, Spock, Frodo...
- La palabra clave por antonomasia: (ábrete) SESAMO.
jueves, 27 de marzo de 2008
De mayúsculas a minúsculas
Para ello añadimos el siguiente código en nuestro programa, para convertir una variable de 5 caracteres de longitud, y utilizaremos la API QLGCNVCS.
DCL VAR(&VAR1) TYPE(*CHAR) LEN(5)
DCL VAR(&VAR2) TYPE(*CHAR) LEN(5)
DCL VAR(&VARLEN) TYPE(*CHAR) LEN(4) VALUE(X'00000005')
DCL VAR(&CASEU) TYPE(*CHAR) LEN(22) + VALUE(X'00000001000000000000000000000000000000000000')
DCL VAR(&CASEL) TYPE(*CHAR) LEN(22) + VALUE(X'00000001000000000000000100000000000000000000')
DCL VAR(&ERR) TYPE(*CHAR) LEN(4) VALUE(X'00000000')
De mayúsculas a minúsculas llamar a la API con el parámetro &CASEL:
CALL PGM(QLGCNVCS) PARM(&CASEL &VAR1 &VAR2 &VARLEN &ERR)
De minúsculas a mayúsculas llamar a la API con el parámetro &CASEU:
CALL PGM(QLGCNVCS) PARM(&CASEU &VAR1 &VAR2 &VARLEN &ERR)
lunes, 10 de marzo de 2008
Plantilla teclado IBM 3197
lunes, 25 de febrero de 2008
Imprimir fuente en DIN A-4
- Entrar al PDM con el mandato STRPDM
- Seleccionar opción "9. Work with user-defined options"
- Seleccionar archivo opciones, por omision QGPL/QAUOOPT(QAUOOPT) , pulsar Intro.
- Pulsar F6=Create
- Opción A4 (por ejemplo)
- Introducir en la linea de mandatos:
- OVRPRTF FILE(QPSUPRTF) PAGESIZE(102) LPI(9) OVRFLW(102) ALIGN(*YES) FONT(220) PRTQLTY(*DRAFT) PAGRTT(0) DUPLEX(*YES)
- Pulsar Intro para guardar la nueva opción del PDM.
A partir de pulsar la opción A4 todos los listados que pidamos en esa sesión, se imprimirán en ese formato. Con la opción DUPLEX(*YES) conseguimos imprimir por ambas caras si la impresora lo soporta.
Es posible se tenga que ajustar algún valor para que cuadre con la hoja de nuestra impresora.
Pero de todas formas el medio ambiente nos agradecera que ahorremos algunas hojas.
domingo, 24 de febrero de 2008
Cargar imagenes cd a AS400
Seguir el siguiente procedimiento (solo funciona en AS400 a partir V5R2).
- Colocar cd en un pc
- Arrancar pgm para generar imágenes (UltraISO, Nero, etc...) y crear imagen ISO del cd (cd's) que queremos cargar en el AS400.
- Copiar archivo iso generado al un directorio del AS400 (p.e. /images)
- Crear catalogo de imágenes en el AS400: CRTIMGCLG IMGCLG(MY_SOFTWARE) DIR('/images/MY_SOFTWARE') CRTDIR(*YES) TEXT('My software V.xx for AS400')
- Esto creara el directorio /images/MY_SOFTWARE y el objeto QUSRSYS/MY_SOFTWARE de tipo *IMGCLG
- Cargar imagen del cd al catalogo de imagenes: ADDIMGCLGE IMGCLG(MY_SOFTWARE) FROMFILE('/images/My_image.iso') TEXT('My software V.xx for AS400')
- Esto crea el archivo del ifs /images/MY_SOFTWARE/My_image.iso
- Para comprobar si se ha cargado:WRKIMGCLGE IMGCLG(MY_SOFTWARE)
- Crear dispositivo óptico virtual (por única vez): CRTDEVOPT DEVD(OPT90) RSRCNAME(*VRT) ONLINE(*NO) TEXT('cd-rom virtual')
- Activar el dispositivo óptico virtual:VRYCFG CFGOBJ(OPT90) CFGTYPE(*DEV) STATUS(*ON)
- Cargar el catalogo de imagenes (MY_SOFTWARE) al cd virtual (OPT90): LODIMGCLG IMGCLG(MY_SOFTWARE) DEV(OPT90) OPTION(*LOAD)
- Operar como un cd cargado en dispositivo optico OPT90 y realizar las operaciones como habitualmente.
- Al terminar descargar el catalogo de imagenes (MY_SOFTWARE) al cd virtual (OPT90): LODIMGCLG IMGCLG(MY_SOFTWARE) DEV(OPT90) OPTION(*UNLOAD)
domingo, 17 de febrero de 2008
Copiar archivos spool
Si utilizamos la opción *SPL nos copiara los archivos de spool a nuestro spool, nos permite indicar un numero máximo de paginas a copiar.
Si usamos la opción *TEXT, nos convierte todos los archivos de spool a ficheros ASCII dentro de una carpeta del IFS que le indiquemos.
jueves, 31 de enero de 2008
Configurar SNA sobre TCP/IP
Prerequisitos:
• TCPIP configurado correctamente.
• Subsistema QSNADS arrancado.
• Añadir usuarios al directorio (WRKDIRE).
Procedimiento, ejecutar en cada uno de los sistemas a conectar:
1. Activar el atributo de red "Permitir soporte AnyNet" con CHGNETA ALWANYNET(*YES), requiere IPL.
2. Añadir nombre al nombre de sistema principal el de 'nombre_sistema.appn.sna.ibm.com', utilizar el mandato CHGTCPHTE o CFGTCP, opción 10 y opción 2 en el sistema a modificar su entrada, de la tabla de sistema principales (HOSTS).
3. Crear el controlador APPC utilizando el mandato CRTCTLAPPC donde xxxxxxx es el nombre de sistema al que conectamos, en cada sistema origen utilizar el nombre del sistema destino.
CRTCTLAPPC CTLD(xxxxxxxx) LINKTYPE(*ANYNW) ONLINE(*YES) APPN(*YES) RMTNETID(*NETATR) RMTCPNAME(xxxxxxxxx) NODETYPE(*LENNODE) BEXROLE(*NETNODE) HPR(*YES) HPRPTHSWT(*NO) TMSGRPNBR(1) AUTOCRTDEV(*ALL) AUTODLTDEV(1440) USRDFN1(*LIND) USRDFN2(*LIND) USRDFN3(*LIND) TEXT('APPN sobre TCPIP para xxxxxxx') CMNRCYLMT(2 5) MSGQ(*SYSVAL)
4. Para crear el dispositivo APPC, y de paso probar la conexión, ejecutar STRPASTHR nombre_sistema, nos debería aparecer el inicio de sesión del sistema destino.
6. Ejecutar el mandato CFGDSTSRV "Configurar Servicios de Distribución".
7. Seleccionar la opción "1=Colas de distribución" y después pulsar "F6=Añadir cola de distribución"
8. Teclear en los campos Cola y Nombre ubicación remota el nombre del sistema destino:
9. Volver a paso 6 y seleccionar a continuación la opción "2=Tabla de direccionamiento", después pulsar "F6=Añadir entrada tabla de direccionamiento".
10. Teclear en los campos indicados el nombre de sistema de destino:
11. Si además queremos utilizar los mandatos SAVRST* entre sistemas debemos tener instalado el producto "OS/400 - ObjectConnect ", para V5R2 es 5722SS1- opción 22.
martes, 1 de enero de 2008
Blog d'utilitats per AS400
Link a mi antigua pagina web de Utilidades para AS/400