martes, 21 de diciembre de 2010

Liberado el CU5 de SQL Server 2008 R2 RTM

Ha sido liberado el pack acumulativo 5 de actualizaciones para SQL Server 2008 R2 RTM.

Aqui podeis encontrar información sobre los fixes que se realizan: http://support.microsoft.com/kb/2438347/en-us 

Para más información ir a la fuente:

http://blogs.msdn.com/b/sqlreleaseservices/archive/2010/12/20/cumulative-update-5-for-sql-server-2008-r2-rtm.aspx?utm_source=twitterfeed&utm_medium=twitter&utm_content=%23release

Automatiza el análisis de contadores de rendimiento

Como bien sabe cualquier DBA, siempre conviene ser proactivo y parte de esa proactividad es la capacidad de analizar la información que proviene de nuestros sistemas de la forma mas útil posible.

En este caso me he decidido a escribir brevemente sobre un apartado que mucha gente no conoce del colector de contadores de rendimiento, su capacidad de almacenar la información en base de datos.

Si bien no quiero llevaros a pensar que es la práctica a seguir siempre (cada escenario es diferente), si quiero daros a conocer las posibilidades que tenemos de utilizar este enfoque, dado que es muy versatil.

Lo único que necesitamos es crearnos un DSN de sistema, que apuntaremos a la instancia y BBBDD donde queramos almacenar la información.

Para ello lo voy a enseñar con una serie de screenshots, que se ve claro:

1. Abrimos el administrador de origenes de datos ODBC y nos vamos a la pestaña “System DSN

image

Figura 1

2. Seleccionamos el driver “SQL Server”

image

Figura 2

3. Configuramos su conexión como vemos en las figuras de la 3 a la 7. Nótese que debemos especificar una BBDD donde almacenar la información.

     La BBDD que pongamos, si no tiene las tablas donde almacenarse la información, en el proceso de configuración del colector de datos se creará. Si ya existian por el contrario, no se borrarán, se insertarán los datos sin más.

image

Figura 3

imageimage

Figura 4-5

imageimage

Figuras 6-7

4. Una vez hemos acabado de configurar nuestro DSN de sistema, procedemos ahora a configurar el colector de datos. Para ello abrimos el monitor de rendimiento (ver figura 8)

image

Figura 8

5. Nos vamos a definirnos un colector de usuario como se puede apreciar en las figuras 9 a la 12

imageimage

Figuras 9-10

NOTA: En la figura 12 nos pide una ruta de disco local donde almacenar la información. Puesto que por defecto se crea así, le especificaremos una ruta, pero no será utilizada por lo que podemos dejarla como está

imageimage

Figuras 11-12

6. Ahora es cuando realmente hacemos la parte “diferente” del proceso, puesto que configuraremos el colector para que en lugar de almacenar la información en formato binario en la ruta especificada anteriormente, le diremos que lo almacenaremos en base de datos, utilizando el DSN de sistema creado con anterioridad

 

image

Figura 13

Al pulsar sobre propiedades tal como se aprecia en la figura 13, pasamos a configurar el “log format”  indicando que lo deseamos en formato SQL (figura 14) y posteriormente indicamos el DSN de sistema que utilizará para almacenar la información (figura 15).

imageimage

Figuras 14-15

7. Una vez pulsado en el botón de inicio de coleccionar datos, se procederá a la creación de objetos necesarios para ello en la BBDD destino

image

Figura 16

image

Figura 17

NOTA: Fíjese como ahora el Output es SQL:loquesea. Esto en otras configuraciones es una ruta a un fichero .blg

8. La última parte ya corre de vuestro lado. Quedaria por tanto explotar esa información (como podeis ver por ejemplo en el Code Snippet que os he dejado), reciclar la información, crear reportes, consolidar,…

Code Snippet
  1. SELECT
  2.   dtid.DISPLAYSTRING
  3.             , cd.MACHINENAME
  4.   , cd.OBJECTNAME
  5. , cd.COUNTERNAME
  6. , cd.INSTANCENAME
  7. , cdta.COUNTERDATETIME
  8. , cdta.COUNTERVALUE
  9. FROM dbo.CounterData AS cdta
  10.          INNER JOIN dbo.CounterDetails AS cd ON cdta.COUNTERID = cd.COUNTERID
  11.          INNER JOIN dbo.DisplayToID AS dtid  ON cdta.GUID = dtid.GUID

image

Figura 18

Espero haberos dejado un buen punto de partida para “juguetear” Smile

Salu2!

miércoles, 15 de diciembre de 2010

Analizar automáticamente los resultados de SSUA

Uno de los principales procesos a seguir cuando se planea la migración de SQL Server hacia una versión superior del motor es la de analizar los potenciales problemas de incompatibilidad entre versiones.

Actualmente, se viene percibiendo en el mercado una gran cantidad de proyectos de migración desde versiones de SQL Server 2000 hacia SQL Server 2008 y 2008 R2. Dichos proyectos, principalmente vienen motivados tanto por la gran cantidad de mejoras y características que vienen de serie con las últimas versiones del motor, como de la necesidad de actualización debida a la pérdida de soporte de SQL Server 2000 por parte de Microsoft (http://support.microsoft.com/lifecycle/?p1=2852)

Debido a esta circunstancia, no solo el número de proyectos de migración se incrementa, sino que el número de instancias y bases de datos a migrar se multiplica (por experiencia encuentro que típicamente se tienen más de 3 instancias de SQL Server, con 10 BBDD cada una de media). Debido a esta circunstancia, al realizar assesments de migración hacia SQL Server 2008 y 2008 R2, debemos manejar mucha información.

En Solid Quality Mentors, hemos desarrollado una herramienta que hemos denominado HealthCheck y sobre la que hablaremos desde esta revista asiduamente, con la que entre otras cosas, facilitamos el trabajo con los ficheros de resultados de SSUA.

¿Qué es SSUA (Sql Server Upgrade Advisor)?

Es una herramienta gratuita proporcionada por Microsoft, para realizar labores de detección de patrones T-SQL y configuraciones depreciadas de SQL Server. Con ella, podremos saber si en cualquier objeto de nuestra base de datos existe una construcción sintáctica T-SQL depreciada que no funcionará en la versión del motor a la que deseamos migrar.

¿Por qué deseamos una automatización de los resultados de SSUA?

Como he avanzado al principio del artículo, una migración típica involucra más de una instancia de SQL Server, es por ello que en ocasiones analizar los resultados puede resultar una tarea tediosa.

¿Qué pretendemos automatizar?

La idea, es generar un fichero que contenga una línea por objeto a modificar, con información extra que con nuestra propia experiencia en la materia nos ayude a identificar lo que es costoso de lo que no, para que de un vistazo rápido, podamos realizar una valoración objetiva lo más acercada a la realidad, de lo que el coste del proyecto final nos puede suponer.

En la imagen siguiente, se puede apreciar como la forma de presentar los resultados por parte de SSUA aunque acertada, no es todo lo útil que desearíamos cuando tenemos que lidiar con múltiples objetos y/o ficheros de resultado.

clip_image002

No obstante, SSUA nos ofrece la posibilidad de exportar la información a un fichero .csv

clip_image004

Cuyo resultado es como el siguiente (después de procesarlo introduciendo sus valores en celdas):

clip_image006

La parte buena es que como se puede apreciar, aparece información de forma tabular. La parte no tan buena es que sigue sin ser completamente controlada por nosotros (“Database name: master”, por ejemplo no es óptimo porque sobraría “Database name:”).

La idea por tanto es que de una manera fácil y sencilla, haciendo uso de las características inherentes de Visual Studio y .net 4.0, podamos operar con los XML resultado de una forma exitosa y fácil.

Procesamiento del documento XML

La idea que me gustaría ilustrar, es que podemos procesar los resultados de SSUA de una forma cómoda y rápida usando Visual Studio 2010. Para ello, una vez obtenida la información con SSUA (resultados típicamente obtenidos bajo la ruta “\Documents\SQL Server 2008 Upgrade Advisor Reports”), procedemos a crearnos un esquema .xsd del documento XML con los resultados deseados ( DE.xml por ejemplo, es el que contendrá los resultados del motor relacional).

Abrimos el documento desde Visual Studio 2010 y seguidamente nos vamos a las opciones de menú XML->Create Schema

clip_image007

Una vez pulsado ahí, obtendremos su esquema .xsd

clip_image009

Como vemos, nada nuevo. La gracia viene ahora.

Podemos crearnos un proyecto de Visual Studio, al que añadir el siguiente código:

Code Snippet
  1.         public static DataTable Analyze(string pathToXml)
  2.         {
  3.             FillIssueTimming();
  4.             DataSet ds = new DataSet();
  5.             ds.ReadXmlSchema("SSUA\\XMLSchemas\\DE.xsd");
  6.             ds.EnforceConstraints = false;
  7.             XmlDataDocument xml = new XmlDataDocument(ds);
  8.             xml.Load(pathToXml);
  9.             var query = from ia in ds.Tables["ItemAttribute"].AsEnumerable()
  10.                         join ias in ds.Tables["ItemAttributes"].AsEnumerable()
  11.                             on ia.Field<int>("ItemAttributes_id") equals ias.Field<int>("ItemAttributes_id")
  12.                         join item in ds.Tables["Item"].AsEnumerable()
  13.                              on ias.Field<int>("Item_id") equals item.Field<int>("Item_id")
  14.                         join r in ds.Tables["Report"].AsEnumerable()
  15.                             on item.Field<Nullable<byte>>("ItemId") equals r.Field<Nullable<byte>>("ItemId")
  16.                         join iss in ds.Tables["Issue"].AsEnumerable()
  17.                             on r.Field<Nullable<byte>>("IssueId") equals iss.Field<Nullable<byte>>("IssueId")
  18.                         select new
  19.                         {
  20.                             ItemAttributesId = ia.Field<int>("ItemAttributes_id"),
  21.                             Name = ia.Field<string>("Name"),
  22.                             Value = ia.Field<string>("Value"),
  23.                             Issue = iss.Field<string>("IssueDescription"),
  24.                             IssueText = iss.Field<string>("IssueText"),
  25.                             IssueType = iss.Field<string>("IssueType")
  26.                         };
  27.  
  28.           // Get all the info you want in the export file
  29.           //
  30. DataTable resultado = new DataTable("results");
  31.             resultado.Columns.Add("IssueId", typeof(int));
  32.             resultado.Columns.Add("IssueType", typeof(string));
  33.             resultado.Columns.Add("Source Type", typeof(string));
  34.             resultado.Columns.Add("Database Name", typeof(String));
  35.             resultado.Columns.Add("Object Name", typeof(String));
  36.             resultado.Columns.Add("Object Type", typeof(String));            
  37.             resultado.Columns.Add("Keyword", typeof(String));
  38.             resultado.Columns.Add("Issue", typeof(String));
  39.             resultado.Columns.Add("SQL Batch", typeof(string));
  40.             resultado.Columns.Add("Trace File", typeof(string));
  41.             resultado.Columns.Add("IssueText", typeof(String));
  42.             resultado.Columns.Add("Estimated time of adaptation", typeof(String));
  43.             resultado.Columns.Add("Comments", typeof(String));
  44.  
  45.    foreach(var row in query)
  46.             {
  47.                 if (issueid_old != row.ItemAttributesId)
  48.                 {
  49.                     DataRow dr = resultado.NewRow();
  50.                     dr["IssueId"] = row.ItemAttributesId;
  51.                     dr["IssueType"] = row.issuetype;
  52.                     dr["Database Name"] = row.Value;
  53.                     dr["Issue"] = row.issue;
  54.                     dr["IssueText"] = row.issuetext;
  55.                                                  …
  56.                  }
  57.              }
  58.              …
  59.             return(resultado);
  60. }

Con esa sencilla consulta (a la que por supuesto podemos añadir todas las columnas que queramos), podemos obtener un DataTable que facilmente podemos exportar al formato que queramos (separado por comas o directamente a Excel usando la API OpenXML o Excel Interop).

Ahora tenemos la información procesada por nosotros, y en tan solo 5-10 minutos podremos tener nuestro exportador de datos de SSUA, al que por ejemplo le añadamos información extra relativa a tiempos estimados de análisis o migración basándonos en nuestra experiencia (como por ejemplo ocurre en nuestro HealthCheck).