miércoles, 23 de julio de 2014

Consumo de memoria en SQL Server usando GeneXus.

Migrando a GeneXus Ev2 Upgrade 5, necesite hacer REBUILD ALL de algunas KB grandes. (10.000 objetos generables).
Esto me hizo recordar cuan lento se pone la maquina de desarrollo mientras ejecuta dicho REBUILD ALL.

Analizando un poco el problema, lo que veo que lo que mas enlentece mi notebook es el consumo de memoria de SQL Server, pues el CPU está sobradisimo. (menos de 20% de uso)

Mi notebook tiene 8GB de memoria y SQLServer está usando mas de 3Gb.

Me puse a investigar superficialmente como saber en que se usa la memoria dentro de SQL Server y encontre este script para hacerlo (no recuerdo la fuente :(  )

Los dejo aca, para que me sea mas facil encontrarlos la proxima vez que los necesite.

--find out how big buffer pool is and determine percentage used by each database

DECLARE @total_buffer INT;
SELECT @total_buffer = cntr_value   FROM sys.dm_os_performance_counters
WHERE RTRIM([object_name]) LIKE '%Buffer Manager'   AND counter_name = 'Total Pages';
;WITH src AS(   SELECT        database_id, db_buffer_pages = COUNT_BIG(*)
FROM sys.dm_os_buffer_descriptors       --WHERE database_id BETWEEN 5 AND 32766      
GROUP BY database_id)SELECT   [db_name] = CASE [database_id] WHEN 32767        THEN 'Resource DB'        ELSE DB_NAME([database_id]) END,   db_buffer_pages,   db_buffer_MB = db_buffer_pages / 128,   db_buffer_percent = CONVERT(DECIMAL(6,3),db_buffer_pages * 100.0 / @total_buffer)
FROM src
ORDER BY db_buffer_MB DESC;
Una vez que veo cuales son las bases que estan consumiendo mas memoria puedo analizar dentro de ellas cuales son las tablas/indices que ocupan mas lugar en memoria.
USE DB_que_usa_mucha_memoria --(se saca de la consulta anterior);

WITH src AS(   SELECT       [Object] = o.name,       [Type] = o.type_desc,       [Index] = COALESCE(i.name, ''),       [Index_Type] = i.type_desc,       p.[object_id],       p.index_id,       au.allocation_unit_id   
FROM       sys.partitions AS p   INNER JOIN       sys.allocation_units AS au       ON p.hobt_id = au.container_id   INNER JOIN       sys.objects AS o       ON p.[object_id] = o.[object_id]   INNER JOIN       sys.indexes AS i       ON o.[object_id] = i.[object_id]       AND p.index_id = i.index_id   WHERE       au.[type] IN (1,2,3)       AND o.is_ms_shipped = 0)
SELECT   src.[Object],   src.[Type],   src.[Index],   src.Index_Type,   buffer_pages = COUNT_BIG(b.page_id),   buffer_mb = COUNT_BIG(b.page_id) / 128
FROM   src
INNER JOIN   sys.dm_os_buffer_descriptors AS b  
 ON src.allocation_unit_id = b.allocation_unit_id
WHERE   b.database_id = DB_ID()
GROUP BY   src.[Object],   src.[Type],   src.[Index],   src.Index_Type
ORDER BY   buffer_pages DESC;


En mi caso, el ModelCrossReference que tiene unos 2 millones de registros el que consume mas memoria.


Por otro lado, alguna recomendaciones para el uso de memoria y disco de las KB de equipos de desarrollo.
Es comun que cuando estamos desarrollando, tengamos muchas KB y por lo tanto muchisimas bases SQLServer. Dichas bases en mi caso, las uso un rato y luego las dejo de usar por periodos prolongados.

Para bajar el uso de memoria, es recomendable que las bases se cierren automaticamente cuando se dejan de usar y tambien que se achiquen cuando tienen espacio libre (por ejemplo al borrar una version).

Para esto, uso el siguiente script


 
sp_MSforeachdb '
BEGIN
USE [?]
DECLARE @dbid INT
SET @dbid = DB_ID()
IF(@dbid > 4)
BEGIN
    PRINT ''[?]'' + CONVERT(VARCHAR, @dbid)
    ALTER DATABASE [?] SET AUTO_SHRINK ON
 ALTER DATABASE [?] SET AUTO_CLOSE ON
END
END;
'
Esto NO DEBERIA HACERSE EN SERVIDORES DE PRODUCCION, sino solamente en ambientes de desarrollo, pues no esta recomendado ni el cierre automático , ni el auto_shrink en bases de datos de producción.

miércoles, 25 de junio de 2014

Usabilizando GeneXus: Organizar archivos en carpetas dentro de la KB

En las KB GeneXus se pueden subir archivos para que los mismos sean utilizados por la aplicación.
Tienen la ventaja de poder extraerse en diferentes directorios y son muy practicos para DLL o JAR desarrollados por terceros, para scripts que necesiten ejecutarse, ejecutables externos, etc.

Tambien pueden ser usados para archivos de configuración, o de validación como XML Schemas , XSLT para procesar XML,  plantillas Excel, Word y demás.

En la KB grandes, es bastante común acumular muchos de estos archivos.

Los objetos de tipo File, por alguna razón que no entiendo bien, en GeneXus  no pueden almacenarse en Folders como la mayoría de los otros objetos de la KB, lo cual dificulta bastante la tarea de ordenarlos, distribuirlos, etc.

En Evolution 2, los archivos se ven asi:

Mi sugerencia, seria que los objetos del tipo FILE se pudieran ver de la siguiente forma


También me gustaría, pero se que es un poco mas difícil tener una herramienta para chequear si alguno de los archivos del FileSystem cambio, para que me avise si tengo que subirlo a la KB.

Pongo un ejemplo para que quede mas claro.

Tengo un XMLSchema llamado DocumentoFirmado.XSD, que mi aplicación utiliza y lo subo a la KB como archivo y el mismo se extrae automáticamente. En un momento determinado se modifica dicho archivo poniéndose una nueva versión y hago la prueba en mi KB y todo funciona de maravilla. Es un error comun, que nos olvidemos de subir dicho archivo a la KB, quedando diferente lo que tengo en la KB con lo que tengo en el File System. Estaria bueno poder seleccionar varios objetos del tipo File, y chequear si hay nuevas versiones de los archivos en el File System y que me permita actualizarlos.

Otro pedido, seria el de poder seleccionar varios archivos del tipo file y subirlos todos en un solo paso, no como ahora, que hay que hacerlo archivo por archivo.

Resumiendo mis sugerencias

  • Poder organizar los archivos en carpetas como los demás objetos
  • Ayuda para mantener sincronizados los archivos de la KB con el File System
  • Facilitar la creación en lote de objetos archivo pudiendo subir a la KB varios a la vez. 


martes, 17 de junio de 2014

Usabilizando GeneXus Server. Mejorar dialogo de Update.

Cuando GeneXus se utiliza con GeneXus Server,  una de las tareas rutinarias es traer los cambios que otros compañeros han realizado en la KB que se almacena en el repositorio central.

El dialogo que aparece, es similar a este:


La otra operacion que generalmente realizamos, es hacer un build all, para asegurarnos que todo lo que bajamos del servidor no rompe nada de lo existente. 

Mis sugerencias

1) Dialogo de Team Development/Update/Preview
Hoy se muestran aquellos objetos que se van a actualizar. 
Para mi forma de trabajar, es mas practico que muestre los COMMITS que se han realizado en el servidor, desde el ultimo FULL UPDATE. 
Esto es mas facil de interpretar que los objetos para los desarrolladores GeneXus. 
Permitiria traer solo una funcionalidad (completa) sin tener que seleccionar objeto a objeto. 
Opcionalmente podria ver los objetos que tengo que traer. 

2) Tareas MSBuild para listar todos los Commits desde el ultimo Full Update (esto sive para implementar 1)

3) Update y Build All en un solo paso. 
Seria bueno tener un boton que haga el UPDATE y si no hay errores o warnings, realice el build all de la aplicacion. 
El log estaria unificado (Update + Build All) 

4) Tarea Msbuild para hacer el Update + Build All 
Hoy  se puede hacer, pero si ya estuviese programado el control de warnings y errores en el paso del Update, seria mucho mejor. 

El dialogo nuevo, quedaría asi:

Debería haber usado los diálogos de la Ev3 para hacer este post, pero se me venció la licencia y por eso use los de Ev2 del Wiki. Estaba con poco tiempo y aproveche el tiempo de una conversión de una KB para postear esto. 

miércoles, 4 de junio de 2014

Seguridad en aplicaciones: GeneXus y OWASP Top 10 - GeneXus Consulting

Me llegó la siguiente noticia de GeneXus Consulting y es importante que todos en la comunidad Genexus le demos importancia a este tema. 



Ya está disponible el documento para descargar. El objetivo: identificar los aspectos de seguridad a tener en cuenta al desarrollar con GeneXus para cumplir con el OWASP Top 10, 2013.

jueves, 22 de mayo de 2014

GeneXus Warning Manager

Cuando estoy haciendo migraciones de GeneXus, es habitual que tenga que cambiar muchas veces la forma que manejo los warnings y errores que envía GeneXus.

En las primeras etapas de la migración me concentro en los errores mas graves.
Luego de solucionados estos, pasamos a los errores propios de la migración, por ejemplo sentencias que tengamos en lenguaje nativo dentro de nuestros objetos y por ultimo ya paso a errores los warning que de controles de tipos y cantidades de parámetros.

Esto implica que tengo que camibar las propiedades de la KB:

Disabled warnings
Warning treated as error

poniendo y cambiando los valores de los códigos de errores, los cuales no son fáciles de recordar.

Para facilitar esta tarea, decidi hacer una recolección de todos los errores y warnings que encontré y los puse en una planilla electrónica en la nube.

En dicha planilla, permite hacerle click a dos columnas que arma un string con los códigos de los warnings para deshabilitarlos o para pasarlos a errores. Luego hago Copy/Paste sobre las propiedades (aun no es automatico el cambio de la propiedad)

Como es una planilla web, la misma puede ser ejecutada desde dentro de GeneXus, haciendo el trabajo mas fácil.

Estoy en proceso de migrar 7 KB de 7.5 a Ev2, para un cliente, y esta sencilla planilla me permitio ahorrar bastante tiempo.


Para usar una versión publica de la planilla, pueden poner el link

https://docs.google.com/a/concepto.com.uy/spreadsheet/ccc?key=0AmiF9WWJN0VvdFpOenZvTW1kYUpRSHZ4N2U4STRKeGc#gid=0

en el campo Address de la Start Page de GeneXus y van a poder utilizarla.

Como es publica, cualquier va a poder modificarla, por lo que no me hago responsable de los resultados.