Esecuele Sin Fronteras

SQL Server, Reporting Services y Biztalk Server
  • Esecuele Sin Fronteras

    Reporting Error in CRM - The report cannot be displayed. (rsProcessingAborted)

    • 0 Comments

     

    Los síntomas de recibir el siguiente error al intentar ejecutar informes creados en CRM con el asistente ó utilizando MSCRM_FetchDataSource:

    En el servidor de SSRS:
    Your browser does not support scripts or has been configured not to allow scripts.

    En las máquinas clientes:

    An error occurred during client rendering.
    An error has occurred during report processing.
    Cannot create a connection to data source ‘CRM’.
    For more information about this error navigate to the report server on the local
    server machine, or enable remote errors.

    En CRM:


    Reporting Error
    The report cannot be displayed. (rsProcessingAborted
    )

     

    Pueden tener las siguientes causas:

    1. SPN's no configurados
    2. Falta de permisos de la cuenta de servicio de SSRS Service en el AD y en SQL
    3. Site de CRM ApplicationHost.config no configurado para utilizar las credenciales de Windows Authentication del AppPoolCredentials

     

    Prueba las alguna de las siguientes alternativas para solucionarlo:

     

    1.       Configurar los SPNs en el servidor especificado:

     

    Servidor CRM
    SETSPN -a HTTP/CrmServerName Domain\CRMAppPool
    SETSPN -a HTTP/CrmServerName.Domain.com Domain\CRMAppPool

    Servidor SSRS/SQL Server:

    SETSPN -a HTTP/SsrsServerName Domain\SRSAppPool
    SETSPN -a HTTP/SsrsServerName.Domain.com Domain\SRSAppPool

    Para SQL:
    SETSPN -a MSSQLSvc/SqlServerName:1433 Domain\SQLServerSvcAcct
    SETSPN -a MSSQLSvc/SqlServerName.Domain.com:1433 Domain\SQLServerSvcAcct

     

    2.       Configurar los permisos de la cuenta de servicio de SSRS Service en el AD y modificar los permisos del grupo SQLAccessGroup en SQL como dice el artículo:


    Error message when you run a report in Microsoft Dynamics CRM 4.0: "Reporting Error.
    The report cannot be displayed"

    http://support.microsoft.com/kb/946585 

    Sección: Complete the following steps if SQL Reporting Services is running as a domain user account

     

    3.       Añadir/cambiar la siguiente sección el fichero ApplicationHost.config del site de CRM Site en un editor de texto . (%windir%\system32\inetsrv\config\. Para todos los ficheros bajo la ruta del Default Web Site)

    Poner el elemento WindowsAuthentication del atributo useAppPoolCredentials a true.

     

    Por ejemplo:

     

    <system.webServer>

       <security>

          <authentication>

            <windowsAuthentication enabled="true" useAppPoolCredentials="true" />

          </authentication>

       </security>

    </system.webServer>   

     

    Si el servidor de CRM 2012 esta configurado en SQL Cluster habrá que añadir un par de SPNs más como explica el siguiente artículo:

    Microsoft Dynamics CRM 2011: Reports created by report wizard may fail when executing

    http://support.microsoft.com/kb/2590774 

     

    Maria Esteban

    Ingeniero de Soporte de Reporting Services

  • Esecuele Sin Fronteras

    Usuario huérfanos en LogShipping

    • 0 Comments

    Supongamos que nos encontramos en la siguiente situación:

    En nuestro entorno tenemos montado Log shipping. Estamos utilizando logins de SQL Server, por lo que podemos tener usuarios huérfanos.

    Queremos corregir este problema, pero no queremos romper el log shipping. ¿Qué podemos hacer?

    Primero, vamos a entender que es un usuario de base de datos, que es un login, como se genera un usuario huérfano, y cuál es la relación entre un usuario de BD y un login:

    ¿Qué es un login?

    Un login es una entidad que accede a la instancia de SQL Server. Esto puede ser un usuario de dominio, un usuario local del sistema, o un usuario de SQL Server. Con esto, podremos entrar a nivel de instancia, aunque no necesariamente a ninguna BD que este dentro de esta instancia.

    Para acceder a una BD, tendremos que ser parte de alguno de los roles que otorgan acceso a las BD, o bien tener un usuario de BD mapeado a nuestro login.

    ¿Qué es un usuario de BD?

    Un usuario de BD es la entidad que trabajara a nivel de BD, que puede tener ciertos privilegios a ciertos objetos dentro de esta misma BD.

    ¿Cuál es la posible relación entre un usuario de BD y un login?

    Cuando se relacionan login y usuario, lo hacen a través de un identificador único, el SID. Este SID puede ser generado a nivel de dominio, a nivel de máquina, o bien a nivel de instancia.

    Podréis encontrar más información en la siguiente URL:

    http://msdn.microsoft.com/es-es/library/ms181127.aspx

    Una vez visto esto, vamos a comprobar si tenemos usuarios huérfanos entre las instancias que trabajan en el logshipping:

    Primero, comprobamos que en la instancia principal, nuestro Login “Orphaned”, tiene mapeado el usuario de BD:

    clip_image002

    Y comprobamos que el SID que une al usuario de BD “test”, y al login “Orphaned” es el mismo:

    clip_image004

    Por lo que, debido a cómo funciona “Log Shipping”, en la BD secundaria, tendremos este mismo SID asociado a nuestro usuario de BD, pero, nuestro login tendrá un diferente SID:

    clip_image006

    Es decir, que si rompemos el logshipping, veremos que nuestro login “Orphaned” no tendrá acceso a la BD “LogShipping_test”.

    clip_image008

    Si intento entrar con el login “Orphaned” dentro de la BD recién recuperada, recibiré el siguiente error:

    clip_image010

    Posibles soluciones para no romper el LogShipping:

    Crear el login en la instancia secundaria con el mismo SID que la primaria, añadiendo la cláusula “SID”, y poniendo el mismo SID que el login de la instancia primaria:

    clip_image012

    En esta pantalla podemos observar que el login “Orphaned” ya tiene acceso a nuestra BD.

    Esto es muy útil si, por cualquier razón, no podemos modificar el usuario de BD. Aunque, al borrar el login, cuando lo creemos, tendremos que darle todos los permisos que tuviese antes a nivel de instancia, y corregir cualquier otro mapeo de usuario que tenga.

    Si pudiéramos modificar la BD, podremos lanzar el siguiente comando:

    USE <database_name>;

    GO

    sp_change_users_login @Action='update_one', @UserNamePattern='<database_user>',

    @LoginName='<login_name>';

    GO

    Un poco mas de información:

    http://msdn.microsoft.com/es-es/library/ms175475(v=sql.105).aspx

     

    Moisés Romero Senosiain – Microsoft Customer Support Services

  • Esecuele Sin Fronteras

    Versionando Procedimientos Almacenados en SQL SERVER

    • 0 Comments

    INTRODUCCION.- 

    Muchas veces nos hemos encontrado cuando desarrollamos procedimientos almacenados la necesidad de poder crear una versión de uno previamente creado.

    A la hora de versionar un procedimiento almacenado nos encontramos con diferentes problemas, como por ejemplo:

    • Cómo normalizar y/o escribir el nombre de estas versiones V1, V2, fecha y un largo etcetera, por ejemplo, spCargaCliente, spCargaClienteV1.
    •  
    • También existen otros problemas añadidos a la hora de hacer los scripts de creación de la base de datos donde tenemos, para mantener un seguimiento de los mismos, que seleccionar uno a uno todos los procedimientos almacenados con sus diferentes versiones.

     

    PEQUEÑO TRUCO.-

    Vamos a establecer un ejemplo, de cómo, SQL SERVER puede ayudarnos a organizarlos y cómo puede a la hora de crear el script sólo ver un procedimiento almacenado con sus diferentes versiones.

    Lo primero vamos a crear un procedimiento almacenado simple:

    CREATE PROCEDURE [dbo].[spVersion]
    AS
    BEGIN

        SELECT 'v1'
    END

    Si ejecutamos el procedimiento almacenado, por ejemplo, EXEC spVersion obtenemos el valor v1.

    Ahora crearemos otro procedimiento con el mismo nombre pero esta vez vamos a añadir al nombre el signo ; y un número de versión, por ejemplo, el  (Inicialmente la versión 1 ya está reservada para la primera definición del procedimiento ).

     

    CREATE PROCEDURE [dbo].[spVersion];2
    AS
    BEGIN
        SET NOCOUNT ON;

       SELECT 'v2'
    END

    Si ejecutamos el procedimiento EXEC spVersion volvemos a obtener el valor ‘v1’ y si ejecutamos el procedimiento EXEC spVersion;2 obtenemos el valor ‘v2’.

    Si abrimos el SQL SERVER Management Studio y expandimos los procedimientos almacenados, vemos que sólo existe un procedimiento almacenado.

     

    clip_image001

    Y si accedemos a su definición veremos el siguiente resultado.

    clip_image002

    Lo cual nos permite ir realizando los diferentes versionados del procedimiento almacenado.

     

    José Manuel Jurado Diaz.

    Ingeniero de Soporte de SQL SERVER

  • Esecuele Sin Fronteras

    De Oracle a SQL Server, introducción

    • 1 Comments

    Voy a ser sincero. Las primeras bases de datos con las que trabaje fueron de Oracle. Desde la versión 8i en adelante.

    Comencé a trabajar con SQL Server hace ya unos años, y lo primero que eche en falta eran las vistas dinámicas, no porque no existieran, sino porque no encontré una referencia rápida que me dijera, por ejemplo, que equivalente tenemos de la v$session.

    Intentare, durante las próximas entregas, mostrar las diferencias entre estos dos grandes motores, y poder aportar toda la información necesaria para tener una “piedra rosetta”, y que el cambio de tecnología de un DBA desde Oracle a SQL Server sea lo menos traumático posible, que cosas podemos mantener, y que no podemos. Que existe, y que no.

    En este caso, me basare en Oracle 10g R2 y SQL Server 2008 R2.

    Sin más, comenzamos:

    En esta ocasión, vamos a hablar de algunas de las vistas dinámicas que suelen usarse más de Oracle, y la opción mas parecida en SQL Server

     

    Oracle Views

    SQL Server equivalent

    v$session

    sys.sysprocesses

       

    v$process

    sys.dm_exec_connections

     

    sys.dm_exec_sessions

     

    sys.dm_exec_requests

       

    v$session_wait

    sys.dm_os_waiting_tasks

       

    v$sql

    Para estas vistas, tendremos que realizar alguna de las siguientes consultas:

    v$sqltext

    select * from sys.dm_exec_query_stats cross apply sys.dm_exec_sql_text(plan_handle)

    v$sqlarea

    Select * from sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_query_plan(plan_handle);

     

    select * from sys.dm_exec_query_stats CROSS APPLY sys.dm_exec_query_plan(plan_handle) cross apply sys.dm_exec_sql_text(plan_handle)

       

    v$lock

    sys.dm_os_waiting_tasks

    Algunos enlaces útiles:

    Oracle Views

    Link de Oracle

    v$session

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2088.htm#sthref2731

    v$process

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2022.htm#sthref2643

    v$session_wait

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2094.htm#sthref2738

    v$sql

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2113.htm#sthref2757

    v$sqltext

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2132.htm#sthref2776

    v$sqlarea

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2129.htm#sthref2773

    v$lock

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_1147.htm#sthref2582

       

    SQL Server view

    Link de Microsoft

    sys.sysprocesses

    http://msdn.microsoft.com/es-es/library/ms179881.aspx

    sys.dm_exec_connections

    http://msdn.microsoft.com/es-es/library/ms181509.aspx

    sys.dm_exec_sessions

    http://msdn.microsoft.com/es-es/library/ms176013.aspx

    sys.dm_exec_requests

    http://msdn.microsoft.com/es-es/library/ms177648.aspx

    sys.dm_os_waiting_tasks

    http://msdn.microsoft.com/es-es/library/ms188743.aspx

    sys.dm_exec_query_stats

    http://msdn.microsoft.com/en-us/library/ms189741.aspx

    sys.dm_exec_sql_text

    http://msdn.microsoft.com/en-us/library/ms181929.aspx

    sys.dm_exec_query_plan

    http://msdn.microsoft.com/en-us/library/ms189747.aspx

    sys.dm_exec_cached_plans

    http://msdn.microsoft.com/en-us/library/ms187404.aspx

    Moisés Romero Senosiain – Microsoft Customer Support Services

  • Esecuele Sin Fronteras

    Sobre la instalación de Reporting Services en clúster…

    • 0 Comments

     

    1. ¿Esta soportada la instalación de Reporting Services en clúster?

    Del siguiente artículo puedes ver que la instalación en clúster está soportada sólo para las bases de datos de SQL server (ReportServer y ReportServerTempDB) pero no para el servicio Web.

    Hosting a Report Server Database in a SQL Server Failover Cluster

    http://msdn.microsoft.com/en-us/library/bb630402.aspx

    (en Español)

    Hospedar una base de datos del servidor de informes en un clúster de conmutación por error de SQL Server

    http://msdn.microsoft.com/es-es/library/bb630402.aspx

    SQL Server provides failover clustering support so that you can use multiple disks for one or more SQL Server instances. Failover clustering is supported only for the report server database; you cannot run the Report Server service as part of a failover cluster.

    To host a report server database on a SQL Server failover cluster, the cluster must already be installed and configured. You can then select the failover cluster as the server name when you create the report server database in the Database Setup page of the Reporting Services Configuration tool.

    Although the Report Server service cannot participate in a failover cluster, you can install Reporting Services on a computer that has a SQL Server failover cluster installed. The report server runs independently of the failover cluster. If you install a report server on a computer that is part of a SQL Server failover instance, you are not required to use the failover cluster for the report server database; you can use a different SQL Server instance to host the database.

     

    2. Pasos a seguir para instalar Reporting Services con las bases de datos en clúster:

     

    1. Primero instalamos Reporting Services en una máquina (diferente al clúster, o en un nodo del clúster si se prefiere) eligiendo la opción “Install but do not configure the server” durante las opciones de instalación del asistente.

    2. Una vez terminada la instalación, habrá que configurar Reporting Services utilizando el “Reporting Services Configuration Manager”

    Los siguientes artículos muestran los pasos a seguir para configurar las urls y la base de datos

    How to: Configure a URL (Reporting Services Configuration)

    http://msdn.microsoft.com/en-us/library/bb630447.aspx

    How to: Create a Report Server Database (Reporting Services Configuration)

    http://msdn.microsoft.com/en-us/library/ms157300.aspx

    los enlaces en español son:

    Cómo configurar una dirección URL (Configuración de Reporting Services)

    http://msdn.microsoft.com/es-es/library/bb630447.aspx

    Cómo crear una base de datos de servidor de informes (configuración de Reporting Services)

    http://msdn.microsoft.com/es-es/library/ms157300.aspx

     

     

    Maria Esteban

    Ingeniero de Soporte de Reporting Services

  • Esecuele Sin Fronteras

    SQLOS–Introducción scheduling

    • 0 Comments

    En este post vamos a introducir el manejo a bajo nivel que hace SQL de las tareas que le piden los usuarios, como algunos sabréis SQL tiene su proprio “sistema operativo” que se encarga del scheduling, memoria etcetera, este componente recibe el original nombre de SQLOS. En este post nos centraremos en la parte de scheduling, para apoyar las explicaciones vamos a usar las vistas dinámicas que proporciona SQL Server a partir de su versión 2005 (http://msdn.microsoft.com/en-us/library/ms188754.aspx).

    Nodes

    Los nodos pertenecen más a la parte de memoria, pero juegan un papel muy importante a la hora de crear otros los schedulers, SQLOS crea un nodo por cada nodo NUMA (http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access) que tenga la máquina más un nodo adicional para la conexión dedicada de administración (DAC), si nuestra máquina es UMA (http://en.wikipedia.org/wiki/Uniform_Memory_Access) se crearan dos nodos uno para uso normal y otro para el DAC.

    Para ver los nodos que ha creado nuestro SQLOS podemos recurrir a la vista: sys.dm_os_nodes (http://msdn.microsoft.com/en-us/library/bb510628(v=sql.100).aspx), en mi máquina podemos ver que solo crea dos nodos, uno para uso normal y otro para uso del DAC.

    image

    El id de los nodos es consecutivo excepto el DAC que para 32bits es 32 y para 64bits es 64. En el estado podemos ver como todos están ONLINE (normalmente deben estar así), luego su dirección de memoria del nodo que para tareas de depuración de SQLOS viene muy bien y la máscara de afinidad del nodo, en sistemas con un solo socket veremos que la afinidad es 255, en sistemas con varios sockets veremos que la afinidad se ajusta al numero de cores de cada socket.

    Para procesadores X64 indicar que todos los procesadores con controladora interna de memoria son procesadores NUMA esto incluye todos los procesadores AMD (Opteron, Athlon X64 y posteriores) y los procesadores de intel basados en Nehalem (http://en.wikipedia.org/wiki/Nehalem_(microarchitecture)) y posteriores (Sandy Bridge, Ivy Bridge…)

    La tecnología IA64 (Itanium) es NUMA.

    Schedulers

    Para estudiar los diferentes componentes vamos a ir de abajo a arriba, en la parte más baja entran los schedulers, este componente es el encargado de realizar el scheduling entre las diferentes tareas tanto de usuario como de sistema. SQL Server crea un scheduler de usuario por cada CPU lógica que tenga el sistema, y algunos más para tareas internas.

    Para ver los schedulers del sistema tenemos la vista dinámica sys.dm_os_schedulers (http://msdn.microsoft.com/en-us/library/ms177526.aspx). La salida de esta vista en mi máquina:

    image

    Como con los nodos tenemos la dirección de memoria del Scheduler así como a que nodo pertenece, mi máquina es un i7 (Nehalem) de un solo socket y cuatro cores, como tengo Hyper-Threading (HT) activado el número de cores lógicos es ocho, por tanto SQLOS crea ocho schedulers, uno por core lógico, para tareas de usuario (status = VISIBLE), adicionalmente crea 4 schedulers para tareas administrativas y  uno para el DAC. La columna is_idle nos indica si el scheduler está ejecutando algo [0] o está sin hacer nada [1], Failed_to_create_worker es una columna interesante ya que nos indica si el scheduler a fallado en crear un worker [1] en algun momento, si es así podemos encontrarnos ante problemas de presión de memoria, o un valor de worker threads (http://msdn.microsoft.com/en-us/library/ms187024.aspx) muy alto si hemos establecido esta opción a mano, no recomendable.

    Indicar que en máquinas dedicadas exclusivamente a SQL puede ser buena opción desactivar Hyper-Threading a nivel de BIOS esto provocará que el número de cores lógicos corresponda con el número de cores físico haciendo que SQL cree un scheduler por core físico, reduciendo posibles esperas causadas por Hyper-Threading. Para determinar el impacto en el rendimiento se recomienda probar una carga de uso normal en un entorno de preproducción tanto con HT activado como con HT desactivado.

    Workers

    Cada scheduler tiene un número n de workers, el número global de workers en toda la instancia no puede sobrepasar el valor ‘max worker threads’. Cuando llega un nuevo trabajo el scheduler busca un worker libre si no existe ninguno intenta crear uno nuevo y asignarle la tarea. Para poder ver los workers del sistema podemos usar la vista: sys.dm_os_workers (http://msdn.microsoft.com/en-us/library/ms178626.aspx)

    image

    Como siempre la primera columna (worker_address) es la dirección de memoria del objeto, is_preemtive lo veremos más adelante, exception_num es el último numero de error que se ha producido en ese worker, en la captura podemos ver un 1222 que significa lock timeout. en state podemos ver si el worker está corriendo o suspendido, en last_wait_type podemos ver por que estaba esperando en la última espera que hizo el thread, posteriormente tenemos las direcciones de memoria de: task que está ejecutando el worker, el thread de windows usado para ejecutar la tarea y el scheduler al cual pertenece este thread.

    Task

    Esto representa una tarea, o subtarea de un usuario, cuando el engine decide paralelizar una query creará subtasks que se asignaran a workers libres para completar la query original. La vista que nos proporciona esta información es: sys.dm_os_tasks (http://msdn.microsoft.com/en-us/library/ms174963.aspx). En mi máquina

    image

    Aquí podemos ver la dirección de la tarea, el estado en el que está la tarea, el scheduler en el que está ejecutando la tarea, el número de sesión de usuario que ha lanzado la tarea y la dirección del worker que está ejecutando la tarea.

    Mezclandolo todo

    Para empezar vamos a recordar las relaciones entre elementos.

    SQLOS tiene tantos nodos como nodos NUMA tenga la máquina,

    SQLOS tiene tantos schedulers como cores lógicos reporte windows.

    Cada scheduler tiene n workers y un worker solo puede pertenecer a un scheduler.

    Cada worker tiene uno y solo un thread.

    Cada worker tiene una y solo una tarea. Una vez completada la tarea el worker puede tener una tarea nueva.

    Una tarea solo puede pertenecer a un worker.

    Llega una nueva tarea, ¿ahora que hago?

    Cuando llega una nueva tarea se le asigna un scheduler, este scheduler busca entre sus workers si hay algun que no esté haciendo nada, si es así se asigna la tarea al worker y se coloca en la lista de workers que pueden ser ejecutado. Si no hay ningun worker libre se intenta crear uno nuevo. Cuando al worker le toque ejecutar se le dara el procesador y es el worker el que debe decidir cuanto tiempo permanece en el. ¡Multitarea colaborativa!

    Multitarea colaborativa en SQLOS

    Como hemos visto es decisión del worker cuando devuelve el control al scheduler para que pueda ejecutar otro worker. Todos las tareas internas de SQL Server se controlan para no estar mucho tiempo ocupando el scheduler y que la ejecución sea fluida, esto se hace por rendimiento ya que simplifica enormemente el scheduler.

    Bien, pero y si una tarea tarda mucho

    Para estos casos existe una monitorización de los schedulers, si un scheduler no ha hecho un cambio de contexto en cierto tiempo se genera un volcado de memoria del scheduler afectado, elimina la task y marca el worker como libre.

    Seguramente muchos de vosotros os habréis encontrado con un volcado cuya descripción es “Non-Yielding Scheduler”, este tipo de volcados significa que un worker no ha retornado el control al scheduler en un tiempo adecuado, por tanto la tarea es terminada para no afectar a las restantes.

    Que pasa cuando es necesario hacer una llamada a Windows.

    Como muchos sabréis la multitarea de Windows es preemtiva, esto quiere decir que es el sistema operativo el que quita la ejecución a los procesos y se los asigna a otros procesos sin que el proceso afectado se entere de nada. Que pasa si tengo que hacer una llamada a Windows, ODBC, … cuya multitarea es preemtiva. En ese caso se marca el flag is_preemtive en el worker para evitar que el monitor de schedulers genere un volcado y mate el proceso en caso de que este tarde mucho en responder, como puede ser un acceso a disco, registro....

    Pablo Gavela López – Microsoft Customer Support Services

  • Esecuele Sin Fronteras

    Uso de campos XML en SQL SERVER

    • 0 Comments

    INTRODUCCION.-

    Hemos observado en algunos casos en determinados proyectos que usan SQL SERVER se implementan campos de tipo TEXT para almacenar datos de XML.

    Desde la versión de SQL SERVER 2005 existe la posibilidad o bien de leer archivos de XML y poder manipularlos o almacenarlos como un campo de XML dentro de una tabla de SQL SERVER.

    Nuestro pequeño post girará en entorno al nuevo tipo de dato XML que nos permite realizar operaciones desde la lectura, indexación por path, valores y tags así como poder actualizar sólo la parte del XML sin tener que sustituir todo el contenido del campo, ahorrando muchas de las operativas de manipulación por parte de desarrollador.

    Con el fin de crear una pequeña guía de trabajo del uso de este nuevo tipo de datos, os mostraremos varios detalles del mismo.

    TABLA DE EJEMPLO.-

    Lo primero que vamos a realizar será crear una tabla que llamaremos EjemploXML que contendrá dos campos:

    • XML_ID de tipo integer y autoincremental que nos permitirá crear una clave única para el ejemplo.
    •  
    • XML_Data de tipo XML que nos permitirá almacenar los datos en XML.

    clip_image001[22]

     

    OPERACIONES.-

    Una vez ya tenemos la tabla vamos a realizar operaciones básicas como:

    Insertar varios registros pudiendo utilizar dos formas:

    • SQL Directa: Insert Into EjemploXML(XML_Data) Values('<cliente>Juan Perez</cliente>')

     

    • O más avanzada usando una variable de tipo XML:

    DECLARE @xml AS XML

    SET @xml = '<Clientes> <Cliente> <ClienteID>2005</ClienteID> <Nombre>25</Nombre> </Cliente> </Clientes>’

    INSERT INTO EjemploXML(XML_Data) Values (@xml)

    Una vez hemos insertado estos datos, podemos ya realizar nuestras propias sentencias de SQL. Por un lado:

     

    • SELECT * FROM EjemploXML , que nos mostraría línea a línea los registros y su contenido XML.

     

     

    • Si queremos filtrar por algún contenido del XML, basta con añadir una serie de operadores que nos permitirán filtrar cualquier de los datos disponibles:

    SELECT * FROM EjemplosXML where xml_data.exist('/Clientes/Cliente/ClienteID[text()=10]')=1

     

    Comentar dos casos en relación a las búsquedas:

     

    • Cuando existen muchos XML por procesar, podemos como cualquier base de datos crear índices, pero estos índices al ser campos del tipo XML, son “algo especiales en su construcción”, por ejemplo:

     

    • Lo primero crearemos un índice primario como cualquier otro que podamos crear: CREATE Primary XML INDEX xml_idx_1 ON EjemploXML(XML_Data) Con este índice indicaremos a SQL SERVER que este campo XML tiene un índice.

     

     

    CREATE XML INDEX xml_idx_1_a ON EjemploXML(XML_Data) USING XML INDEX xml_idx_1 FOR PATH

    CREATE XML INDEX xml_idx_1_v ON EjemploXML(XML_Data) USING XML INDEX xml_idx_1 FOR value

    CREATE XML INDEX xml_idx_1_p ON EjemploXML(XML_Data) USING XML INDEX xml_idx_1 FOR property

     

    Finalmente, nos queda la posibilidad de bien, borrar o actualizar los datos de un XML. Para ello tenemos los siguientes métodos explicados en la siguiente URL: http://msdn.microsoft.com/es-es/library/ms177454.aspx

    NOTAS GENERALES.-

     

    Comentar por último que los nuevos tipos de datos de XML no sólo pueden usarse como campos de tablas, sino, que tienen otras funcionalidades como:

     

    • Devoluciones de valores de funciones UDF
    • Parámetros de procedimientos almacenados y funciones
    • Tipos de variables
    •  

    A parte, otras de las ventajas de que disponemos, es que podemos aplicar un constraint para evitar que un XML no esté bien formado, es decir, validar esquemas de XML o bien podemos añadir el contenido directamente del XML a través del comando BULK INSERT

  • Esecuele Sin Fronteras

    He borrado mi grupo de cluster con el recurso de SQL. ¿Y ahora?

    • 0 Comments

    Hoy vamos a hablar de cómo recrear un grupo de cluster de SQL Server bajo Windows Server 2008 cuando sea eliminado por error.

    Si lo que quieres es montarlo por primera vez, es necesario seguir este link, http://msdn.microsoft.com/en-us/library/ms179530.aspx , el cual nos ira guiando desde la planificación, hasta la consecución de nuestro objetivo. Siguiendo este link, además de crear el grupo de cluster, se deja configurado automáticamente el grupo de cluster y el servicio de SQL.

    Supongamos esta situación, Mike, nuestro DBA senior, le pide a Paul, un recién contratado DBA, que modifique la configuración del cluster. Paul borra, accidentalmente, el grupo del cluster.

    ¿Como puede Mike recuperar nuestro grupo perdido de cluster?

    Primero, Mike se conectara a la consola de cluster del nodo activo.

    clip_image002

    Dentro de “Services and Applications”, tendremos que generar nuestro contenedor. Botón derecho sobre “Services and applications” > “More Actions” > “Create Empty Service or application”

    Vamos a ponerle un nombre que nos diga algo, por ejemplo “test_moises”

    clip_image004

    Como vemos, esta vacío, así que vamos a añadir todos nuestros resources…

    Primero, para SQL Server, debemos añadir un “Client Access Point”, donde pondremos nuestro “Virtual name”, y nuestro “Virtual Address”, y la subred a la que va a escuchar, en caso de que haya varias...

    clip_image006

    Bien, pues ya está montado, ahora añadiremos los discos que utilizaremos para SQL Server, para ello pulsaremos sobre “Add storage”, y seleccionaremos los discos que necesitemos.

    clip_image008

    Perfecto, y ahora a por nuestro objetivo real, el resource de SQL Server.

    Pulsamos sobre “Add a resource” > “More resources” > “Add Sql Server”

    clip_image010

    Ojo, porque todavía no está configurado. Botón derecho sobre el recién estrenado SQL Server resource, y propiedades. En la pestaña “General”, podremos cambiar el nombre del recurso. Esto es solo para que nosotros nos acordemos, el cluster trabaja por debajo con los GUID.

    En la pestaña “Dependencies”, añadiremos las dependencias necesarias, en este caso, SQL Server, VirtualName y discos:

    clip_image012

    En la pestaña “Properties”, añadiremos el value del “VirtualServerName” y del “InstanceName”. (ejemplo grafico de que es el VirtualServerName y el InstanceName)

    clip_image014

    Por último, el SQL Server Agent. Pulsamos sobre “Add a resource” > “More resources” > “Add Sql Server Agent”.

    clip_image016

    La dependencia que pondremos es el resource de “SQL Server”, y en la pestaña “Properties”, configuramos, al igual que en el caso del resource de “SQL Server”, los values del “VirtualServerName” y del “InstanceName”.

    Si tuviésemos algún problema con las propiedades, podemos guiarnos por este kb: http://support.microsoft.com/kb/810056

    *Cuidado con este link, porque la traducción automática en castellano también modifica los valores del registro a editar, que realmente no se deben cambiar...

    clip_image017

    Pero en registro veremos:

    clip_image019

    Mike volverá a tener su cluster funcionando, y los usuarios no han tenido perdida de servicio.

     

    Moisés Romero Senosiain

    Ingeniero de soporte de SQL Server

  • Esecuele Sin Fronteras

    ¿Dónde está mi memoria?–Lock Pages in Memory (x64)

    • 0 Comments

    Acabamos de comprar un flamante nuevo servidor, 24 cores, 128GB de RAM, discos SSD en RAID 0… Instalamos SQL Server, 64 bits por supuesto, activamos Lock Pages in Memory (http://msdn.microsoft.com/en-us/library/ms190730.aspx) para que SQL no sea paginado fuera de RAM. Y para deleitarnos con nuestra obra cogemos contadores de carga de CPU, bloqueos, memoria…. Y ahí empieza el problema, ¡dónde está mi memoria!

    La memoria puede estar “perdida”, entre comillas ya que la memoria está siendo realmente usada, por diversos motivos, para los ejemplos usaré mi modesto Xeon de 4 cores y 12GB de RAM. Para capturar el uso de RAM física se usara la herramienta RAMMap de Mark Russinovich y Bryce Cogswell que podemos bajar de sysinternals: http://technet.microsoft.com/en-us/sysinternals/ff700229

    1 – Task Manager y lock pages in memory.

    Para realizar las pruebas se hace una SELECT de 10.000.000 de registros.

    Si usamos task manager para comprobar el uso de RAM de SQL podemos llevarnos una sorpresa.

    image

    Esta memoria es el Working Set (la memoria física usada actualmente por SQL Server). Apenas 116MB de uso, esto no cuadra con una base de datos que mueve cientos, miles o millones de datos por segundo por tanto algo debe estar mal.

    Si vamos a Management Studio y ejecutamos

    DBCC MEMORYSTATUS

    SQL nos proporcionará un resumen del uso de RAM que para nada coincidirá con lo que nos indica el task manager.

    Memory Manager                           KB        
    ---------------------------------------- -----------
    VM Reserved                                 19015912
    VM Committed                                  119148
    Locked Pages Allocated                        747776
    Reserved Memory                                 1024
    Reserved Memory In Use                             0

    Vamos a fijarnos únicamente en los valores VM Committed y Locked Pages Allocated (AWE Allocated en SQL Server 2005).

    VM Commited: Éste valor es el tamaño de memoria virtual (del proceso) que actualmente está siendo manejado por SQL Server, esta memoria puede ser paginada, el working set es un sub conjunto de esta memoria, por tanto los valores obtenidos tienen lógica.

    Locked Pages Allocated (AWE allocated en SQL Server 2005): Este valor indica la cantidad de RAM física bloqueada en memoria por SQL Server y que no se puede ser paginada. Por tanto esta valor más el working set nos darán una idea aproximada del tamaño de la RAM física consumida por SQL Server (En este caso 118972KB + 747776KB, unos 846MB)

    La explicación de este comportamiento es que al activar  Lock Pages in Memory en x64 se está haciendo uso de algo muy conocido por la gente que ya ha trabajado con SQL en x86, me refiero a: Address Windowing Extensions (AWE) http://msdn.microsoft.com/en-us/library/aa366527(v=vs.85).aspx. Esta API sigue estando presente en las ediciones de 64 bits de Windows debido a su utilidad ya que es la única forma que tiene un programa de usuario de bloquear RAM física para su uso. Para los programadores que tenga curiosidad les recomiendo que vean la entrada de msdn VirtualAlloc(http://msdn.microsoft.com/en-us/library/aa366887(v=vs.85).aspx) con el flag MEM_PHYSICAL. Esta memoria está fuera de la memoria virtual del proceso y por tanto no aparece en el Working Set del Task Manager.

    A continuación lanzamos RAMMap para ver en que se está usando la RAM física.

    image

    Como podemos ver el valor consumido por AWE coincide exactamente con el de Lock Pages Allocated, 744776KB.

    Hemos encontrado nuestra memoria.

    2 – Lock Pages Allocated no coincide con el valor de AWE. Presentamos “Large Page Extensions”

    Ahora realizamos la misma prueba con una máquina i7 de 4 cores y 16GB de RAM. Arrancamos SQL Server, lanzamos Management Studio, hacemos una SELECT de 10.000.000 de registros y…

    image

    Un working set de 131468KB. Mas o menos como antes. Ahora veamos la salida de DBCC MEMORYSTATUS

    Memory Manager                           KB        
    ---------------------------------------- -----------
    VM Reserved                                 23200928
    VM Committed                                  174292
    Locked Pages Allocated                        682048
    Reserved Memory                                 1024
    Reserved Memory In Use                             0

    Parece que todo está mas o menos como en el ejemplo anterior, 174292KB para VM Commited y 682048KB para Lock Pages Allocated. Pero cuando vamos a RAMmap vemos esto:

    image

    Y… oops. AWE está consumiendo 731200de RAM, lo que nos deja con la siguiente pregunta ¿Donde están mis 48MB?

    La respuesta está en “Large Page Extension” (http://msdn.microsoft.com/en-us/library/aa366720.aspx). Basicamente SQL Server 64bits si se encuentra más de 8GB libres al arrancar usará parte de la memoria para "Large Pages” este tipo de páginas de memoria proporcionan un aumento de rendimiento para grandes cargas de datos y se reserva usando el API de AWE, por tanto RAMMap la muestra como memoria AWE, mas información (http://blogs.msdn.com/b/psssql/archive/2009/06/05/sql-server-and-large-pages-explained.aspx). Si en vez de utilizar DBCC MEMORYSTATUS usamos DMV’s podremos ver este tipo de reservas de memoria. Usaremos la siguinte query (Esta query solo funciona en SQL Server 2008 y superiores):

    SELECT large_page_allocations_kb, locked_page_allocations_kb FROM sys.dm_os_process_memory

    En mi caso el resultado es el siguiente:

    image

    Lo que nos dice que 682048KB están en Locked Pages y 49152KB están en Large Pages, lo que nos suma los 731200KB. En caso de SQL Server 2005 no hay ninguna query con la que podamos consultar este tipo de memoria, con lo que tendremos que hacer un acto de fe.

    Notas sobre Large Pages:

    - Solo está disponible en Developer y Enterprise

    - Cuanto más RAM tenga el sistema más RAM se reserva para Large Pages.

    - Las Large Pages solo se activan si tenemos más de 8GB libres cuando arranca SQL Server.

    - Large Pages no está limitado por Max Server Memory.

    - Con mirar nuestro ERROLOG sabremos si están activas las Large Pages, se registrara lo siguiente:

    2011-09-02 13:13:47.41 Server      Large Page Extensions enabled.
    2011-09-02 13:13:47.41 Server      Large Page Granularity: 2097152
    2011-09-02 13:13:47.41 Server      Large Page Allocated: 32MB
    2011-09-02 13:13:47.43 Server      Using locked pages for buffer pool.

    Pablo Gavela López – Microsoft Customer Support Services

  • Esecuele Sin Fronteras

    Mejores prácticas para el diseño de índices

    • 0 Comments

    Continuamente llegan a nosotros casos de rendimiento  en las que de una manera u otra están relacionadas con la gestión de los índices.

    En muchos casos TSQL, Jobs,  que tardan mucho  o TSQL que antes no tardaban nada con pocos registros cada vez la base de datos invierte más tiempo en realizarlos.

    En todos ellos, se observa un patrón común con un alto uso de CPU o los contadores de rendimiento de disco inusualmente elevados o bien muchos operativas de table scan.

    En este post trataremos de identificar los aspectos relacionados con los índices en el que lo dividiremos en tres partes:

    ·         Fragmentación de los índices, es decir, cada vez que se inserta/actualiza o se borran registros el impacto de cómo está alineado las páginas de datos de índices con los datos.

     

    ·         Índices que SQL SERVER identifica que podrían ser necesarios crear y que creándolos provocarían un aumento considerable en la mejora del rendimiento del servidor.

     

    ·         Cómo, cuándo y en qué porcentaje la base de datos están usando estos índices.

     

    Para ello nos apoyaremos en unas vistas dinámicas muy interesantes que nos van a permitir conocer estos datos que tenemos habilitadas en SQL SERVER 2005 y 2008.

     

    Fragmentación de los índices:

    Para conocer qué es la fragmentación para ello visitemos la URL:  http://technet.microsoft.com/es-es/library/ms189858.aspx

     

    Para conocer cómo se detecta la fragmentación disponemos de dos opciones uno DBCC SHOWCONTIG que aportaba esta información en versiones anteriores o bien la nueva DMV que nos informa con muchos más detalles, el nivel de fragmentación de los índices. Para ello visitaremos la URL: http://technet.microsoft.com/es-es/library/ms188917.aspx

     

    Dentro de la DMV ejecutaremos la siguiente query para observar la fragmentación de los índices:

     

    select OBJECT_NAME([object_id]) as NombreTabla, *

    from master.sys.dm_db_index_physical_stats(DB_ID('bbddusuario'),NULL,NULL,NULL,'DETAILED')

    order by avg_fragmentation_in_percent desc

     

    clip_image002[4]

     

    En este ejemplo, crearemos una tabla con 3 campos:

    ·         IdElemento que será el campo Identidad y Primary key por defecto.

    ·         Campo1 y Campo2 ambos de nvarchar(10)

     

    Una vez creada la tabla creamos un nuevo índice seleccionado el campo Campo1 dejando la definición del índice de relleno ( fillfactor) por defecto.

    Haremos inserciones y borrados masivos durante un tiempo y volveremos a ejecutar la query, obteniendo el siguiente resultado:

    clip_image004[4]

    En la que podemos identificar la columna avg_fragmentation_in_percent que nos indica por cada tipo de índice el porcentaje de fragmentación. En algunos casos observamos que el porcentaje es muy alto.

    Por ello, basta con realizar alguna actividad de reindexación ( reconstrucción ( rebuild ) o reorganización ( reorganize ) ) de los datos para obtener el siguiente resultado y mejorar sensiblemente el resultado de las operaciones de búsqueda. URL: http://msdn.microsoft.com/es-es/library/ms188917.aspx

    clip_image006[4]

     

     

    Otro de las cosas que podemos observar en esta estadística son:

    o   El nivel de ocupación de cada una de las páginas ( columna avg_page_space_used_in_percent ) con lo cual podemos definir un fill factor o índice de relleno acorde y bajar la fragmentación. URL: http://msdn.microsoft.com/es-es/library/ms191005(v=sql.90).aspx

     

    o   La cantidad de registros usados en cada índice ( columna record_count ). En caso de que este índice tenga una cantidad de registros muy cercano a la cantidad de registros de la tabla ( select count(*) from , este índice podría no ser necesario por su nivel de cardianalidad ( número de registros diferentes único que forman el índice ).  El motor de optimización de la base de datos podría no utilizar este índice ya que podría considerar que es mejor leer la tabla que usar el índice.

     

    Índices que SQL SERVER identifica que mejorarían el rendimiento ( MISSING INDEXES )

    Por otro lado, tenemos los índices que provocarían un aumento considerable en la mejora del rendimiento del servidor.

    Para conocer los índices que sería necesarios crear, si ejecutamos la siguiente query podremos encontrar los índices que podría ser necesarios crear para mejorar el rendimiento. En la columna avg_user_impact se podría ver el % de performance. Debemos recordar que crear índices mejora el rendimiento pero obliga a que las escrituras puedan llevar más tiempo al actualizar los datos y que la información que obtenemos se inicializa después de cada reinicio de la instancia de SQL SERVER. URL: http://technet.microsoft.com/es-es/library/ms345434.aspx

     

    SELECT

    statement AS [database.scheme.table],

    column_id , column_name, column_usage,

    migs.user_seeks, migs.user_scans,

    migs.last_user_seek, migs.avg_total_user_cost,

    migs.avg_user_impact

    FROM sys.dm_db_missing_index_details AS mid

    CROSS APPLY sys.dm_db_missing_index_columns (mid.index_handle)

    INNER JOIN sys.dm_db_missing_index_groups AS mig

    ON mig.index_handle = mid.index_handle

    INNER JOIN sys.dm_db_missing_index_group_stats  AS migs

    ON mig.index_group_handle=migs.group_handle

    ORDER BY mig.index_group_handle, mig.index_handle, column_id

    Siguiendo con nuestro ejemplo, vamos a realizar un par de consultas en nuestra tabla. Como recordamos nuestra tabla ( Table_1 ) contiene 3 campos, IdElemento como índice primario, Campo1 que está indexado y Campo2 que no está indexado.

    Vamos a realizar un par de consultas sobre el campo2 al cercar de los 7 millones de registros que tenemos en la tabla table_1.

    Select * from table_1 where campo2 = ‘juan’

    Select * from table_1 where campo2 like ‘juan%’

    Seguidamente, ejecutaremos la query de obtener los índices que SQL SERVER aconseja crear y obtenemos los siguientes datos.

    clip_image008[4]

    Como podemos observar las primeras tres filas corresponde a la mejora del filtrado inicial de campo2 = ‘juan’ en las que SQL SERVER nos indica que podríamos mejorar nuestro rendimiento en un 99.91% si creamos un índice en el que Campo2 esté definido en el mismo e incluyamos como campos include del mismo a IdElemento y Campo1.

    clip_image010[4]

    clip_image012[4]

    SQL SERVER recomienda el incluir los campos debido a la query SELECT * en la que se recogen todos los campos. Lógicamente, este índice es para este caso y posiblemente acotar los campos ( sustituir el * por los campos que necesitamos hará que quizás no sea necesario incluir estos campos.

    Finalmente, podemos observar que las tres siguientes filas con un porcentaje de cerca del 69% para la query con la clausula LIKE.

     

    INDICES QUE SQL SERVER NO USA EN NUESTRA BASE DE DATOS

    Por último, para conocer los índices no usados, si ejecutamos la siguiente query

     

    select i.name, * from sys.dm_db_index_usage_stats s

    inner join sys.indexes i on i.object_id = s.object_id and i.index_id = s.index_id

    where database_id = DB_ID()  

    podremos encontrar los índices que podría ser necesarios crear para mejorar la performance desde el último reinicio de la instancia de SQL SERVER. En la URL http://technet.microsoft.com/es-es/library/ms188755.aspx  encontramos información sobre todas sus columnas.

    Para ello creamos un índice llamado IX_Table_2 que lo formarán los campos campo1 y campo2 y estarán incluidos el campo de IdElemento.

    clip_image014[4]

    clip_image016[4]

    Realizamos un par de consultas a la tabla incluyendo algunos de estos campos  y volveremos a realizar la query para obtener la estadística de los índices.

    clip_image018[4]

    Podemos observar la columna user_updates o las columnas last_user_seek o las columnas last_user_scan para observar si el índice se está usando.

    Como ocurre con los índices que podrían ser necesarios crear, estas estadísticas se inicializan cada vez que se reinicia la instancia.

    Jose Manuel Jurado Díaz

    Ingeniero de soporte de SQL Server

Page 3 of 9 (81 items) 12345»