Microsoft Premier Support (PFE) Latin America

Este Blog está dedicado a todo aquel interesado en tecnología Microsoft, y con deseos de aprender de la experiencia y vivencias de los PFES de Latinoamerica y del grupo de Incubation Support & Services (ISS)

July, 2011

  • Advantages and Disadvantages on Change Tracking

    Some weeks ago a customer asked me for options to Audit a specific situation. I decided to evaluate Change Tracking, a new feature in SQL 2008. The conclusion is that Change Tracking is not auditing feature and we shouldn't try to use it as one, so I want to share some of my findings. SQL Server 2008 has other features that track changes in some way that you can evaluate depending on your needs:

    -        SQL Auditing

    -        C2 Audit Mode

    -        SQL Traces (Profiler)

    -        Change Tracking

    -        Change Data Capture

    -        Custom code (triggers, additional columns in tables, additional code in sp’s, etc.)

    -        Third Party tools

    In this case we decided to try Change Tracking. Change tracking allows you to track every time a row or column is modified. To learn how to implement it, you can refer to http://msdn.microsoft.com/en-us/library/cc280462.aspx, here I want to mention the advantages and limitations I have found using this feature.

    Advantages

    -        Very easy to implement

    • Doesn’t require application changes (unless you want to add a change context)
    • Only requires configure database and objects.

    -        High performance implementation because is embedded in SQL Server and it isn’t something separated.

    -        You are able to identify the history of changes, not only, the last change.

    -        You can add context information to every DML if required (requires code change)

    -        You can identify which columns changes (if configured) not only which row.

    -        It doesn’t block the transaction log because the operation is synchronous, this means, that there is no risk that sometimes the log cannot be truncated because change tracking is blocking the transaction log.

    -        It is useful to identify the rows and/or columns that have changed and need to be moved to the Data Warehouse.

    -        You have auto cleanup. You don’t need to worry about deleting the information collected; it is deleted automatically based on the retention period.

    Disadvantages

    -        It doesn’t track time of the change.

    -        It doesn’t track security context that executed the change.

    -        It doesn’t save how the data changed, only tracks that a change was made.

    -        Depending on the amount of changes it will add some overhead to the server, although, this doesn’t seem to be significant.

    -        Because the operation is synchronous it will add some time to the transaction time. How much, depends on the amount of changes you are doing in your transaction.

     

    “The opinions and views expressed in this blog are those of the author and do not necessarily state or reflect those of Microsoft”

  • TIP: SharePoint PowerShell Mount-SPContentDatabase "creates" databases on SQLServer

    Hey there SharePoint Community,

    Recently I was deliverying the SharePoint 2010 Migration Workshop which I strongly recommend, during a Lab I realized some behaviour that freacked me out. One of the labs requires to attach a pre-existen content database, the content database is already created in SQL Server as part of the Virtual Machines deployment used in this workshop. Lab instructed students to use cmdlet Mount-SPContentDatabase with the correct sintax, a student rised his hand to ask for help, as per student he executed the command with no errors, to be sincere I did not believe him so I decided to double check what he did, after a deep reading I noticed that he made a mistake with the database name and the content database with the wrong name was created in SQL Server. I checked the execution of the cmdlet and effectively Mount-SPContentDatabase was succeed, no errors or warnings.

    WSS_Content_2007 - Content Database name provided in LAB

    WSS_Conten_2007 - Content Database name wrote by student

    From my point of view if Mount-SPContentDatabase attaches an EXISTANT database a PowerShell error should be thrown, so I checked using powershell help the cmdlet description as shown in pic below...

    Descirption says that the cmdlet Attaches an EXISTANT database but it did not do that, it created a new one on SQL Server, this can be an issue for the DBA's cause they could complain about the creation of the blank databases or databases that will not be used, so be careful.

    Additionally I will share to you a cmdlet that DO CREATE new content databases New-SPContentDatabase.

    References:

    Add a content database (SharePoint Server 2010) - http://technet.microsoft.com/en-us/library/cc825314.aspx

    New-SPContentDatabase (SharePoint Server 2010) - http://technet.microsoft.com/en-us/library/ff607581(office.14).aspx

    Take care, until de next POST

  • Como detectar a versão de Rollup Update instalada no Exchange Server 2007 ou 2010

    Uma coisa que nós sempre nos questionamos quando fazemos uma visita, ou estamos em um caso de suporte é: “qual é a versão do Exchange Server e o Rollup que está instalado em seus servidores?”. Muitas vezes a resposta é: “claro, a versão do Exchange é 20xx, Service Pack X, mas o último Rollup eu não sei!”. Para muitos de nós, assim também como vamos ver em outros artigos, este valor do Rollup Update é muito importante. Para conhecê-lo, existem varias maneiras de se obter este valor, claro que cada uma delas tem suas vantagens e desvantagens.

    Primero, utilizando a interface gráfica (GUI) é muito útil e você pode fazer através do Painel de Controle, Programas e Características. Como se pode observar na figura a continuação:

    Selecionamos a opção “view installed updates” (Ver as atualizações instaladas):

    Na próxima janela, podemos observar qual é o Rollup instalado, neste exemplo a figura mostra que nós temos o Rollup número 2 instalado neste servidor Exchange.

    Existe alguma desvantagem neste processo? Sim existe, automação! Se você tem que fazer este mesmo processo em 5, 10 ou 50 servidores Exchange, você vai levar muito tempo para coletar a informação necessária. Para automatizá-lo existe a opção de realizar um script powershell.

    A opção mais comum seria o comando Get-ExchangeServer, mas ele oferece unicamente a informação da versão do Exchange Server e não do Rollup instalado, para obter está informação, temos que conectar no registro do servidore e obter as chaves de registro de atualização do produto.

    Para resumir a história, as chaves de registro são:

    para Exchange 2007:

    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\461C2B4266EDEF444B864AD6D9E5B613\Patches\

    e para Exchange 2010:

    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\AE1D439464EB1B8488741FFA028E291C\Patches\

    O script que consulta estas chaves de registro para os servidores está detalhado a continuação. O importante é que este script está adaptado para coletar a informação do Exchange Server 2007 e do Exchange Server 2010.

    #Get-ExchangeServerPlus.ps1 
    #v1.3, 07/11/2011
    #Written By Paul Flaherty, blogs.flaphead.com
    #Modified by Jeff Guillet, www.expta.com
    #modified by Gregorio Parra, blogs.technet.com


    #Get a list of Exchange servers in the Org excluding Edge servers
    $MsxServers = Get-ExchangeServer | where {$_.ServerRole -ne "Edge" } | where {$_.ServerRole -ne "ProvisionedServer" } | sort Name

    #Loop through each Exchange server that is found
    ForEach ($MsxServer in $MsxServers)
    {

    #Get Exchange server version
    $MsxVersion = $MsxServer.ExchangeVersion

    #Create "header" string for output
    # Servername [Role] [Edition] Version Number
    $majorver = $MsxServer.AdminDisplayVersion.Major
    $txt1 = $MsxServer.Name + " [" + $MsxServer.ServerRole + "] [" + $MsxServer.Edition + "] [" + $MsxServer.AdminDisplayVersion + "] [Version:" + $majorver + "]"
    write-host $txt1

    #Connect to the Server's remote registry and enumerate all subkeys listed under "Patches"
    $Srv = $MsxServer.Name
    $key = ""

    #define the registry key, depending on Exchange Version 2007 or 2010
    if ($majorver -eq "8") # Exchange 2007
    {
    $key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\461C2B4266EDEF444B864AD6D9E5B613\Patches\"
    }
    if ($majorver -eq "14") # Exchange 2010
    {
    $key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\AE1D439464EB1B8488741FFA028E291C\Patches\"
    }
    $type = [Microsoft.Win32.RegistryHive]::LocalMachine
    $regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
    $regKey = $regKey.OpenSubKey($key)

    #Loop each of the subkeys (Patches) and gather the Installed date and Displayname of the Exchange 2007 patch
    $ErrorActionPreference = "SilentlyContinue"
    ForEach($sub in $regKey.GetSubKeyNames())
    {
    Write-Host "- " -nonewline
    $SUBkey = $key + $Sub
    $SUBregKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
    $SUBregKey = $SUBregKey.OpenSubKey($SUBkey)
    ForEach($SubX in $SUBRegkey.GetValueNames())
    {
    # Display Installed date and Displayname of the Exchange 2007 patch
    IF ($Subx -eq "Installed") {
    $d = $SUBRegkey.GetValue($SubX)
    $d = $d.substring(4,2) + "/" + $d.substring(6,2) + "/" + $d.substring(0,4)
    write-Host $d -NoNewLine
    }
    IF ($Subx -eq "DisplayName") {write-Host ": "$SUBRegkey.GetValue($SubX)}
    }
    }
    write-host ""
    }

    Se precisarem utilizar o script, ele está anexado a este post no blog.

     

    Façam um bom uso dele!

    Atenciosamente,

    Raphael Barini

    - Post original by GP traduzido pelo PFE de Exchange Server, Raphael Barini.

  • Como detectar la version de Rollup instalada en Exchange 2007 o 2010

    Una de las cosas que siempre se preguntamos cuando hacemos una visita, o estamos en un caso de soporte es: “que version de Exchange y Rollup esta instalado en sus servidores?”  a lo cual muchas veces la respuesta es: “ah si, el Exchange es 20XX, Service Pack X…. pero el rollup no se….. Surprised smile” y para varios de nosotros asi como veremos en posteriores articulos, el valor del rollup update es necesario conocerlo.   Para conocer este, hay varias formas que permiten conocer este valor, pero como suele suceder, cada una tiene sus ventajas y desventajas Smile

    primero que todo, la forma grafica es muy util esto se hace, por medio del complemento de programas y caracteristicas  que se localiza en el panel de control,

      image

    ahi, seleccionamos la opcion “view installed updates”

    image

    con eso, podemos ver el rollup instalado, que en este caso es el 2.

    image

    y con eso sabemos la version de rollup update. Pero que tiene de desventaja este proceso? pues que si lo haces en 5 o 10 servidores tomara algo de tiempo, asi que para hacerlo masivo, esta la siempre util opcion del script.

    pero la opcion  usual que es usar el comando get-exchangeServer ofece unicamente informacion de version, pero no de rollup, para obtener esta, nos debemos conectar al registro de la maquina y obtener las llaves de registro de las actualizaciones del producto.

    para hacer la historia corta, estas llaves son:

    para Exchange 2007:

    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\461C2B4266EDEF444B864AD6D9E5B613\Patches\

    y para Exchange 2010:

    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\AE1D439464EB1B8488741FFA028E291C\Patches\

    y el script que consulta estas llaves de registro para sus servidores es el que encontramos a continuacion, lo interesante es que este script esta adaptado tanto para Exchange 2007 como Exchange 2010.

    #Get-ExchangeServerPlus.ps1
    #v1.3, 07/11/2011
    #Written By Paul Flaherty, blogs.flaphead.com
    #Modified by Jeff Guillet, www.expta.com
    #modified by Gregorio Parra, blogs.technet.com
     
     
    #Get a list of Exchange servers in the Org excluding Edge servers
    $MsxServers = Get-ExchangeServer | where {$_.ServerRole -ne "Edge" } | where {$_.ServerRole -ne "ProvisionedServer" } | sort Name
     
    #Loop through each Exchange server that is found
    ForEach ($MsxServer in $MsxServers)
    {
     
        #Get Exchange server version
        $MsxVersion = $MsxServer.ExchangeVersion
     
        #Create "header" string for output
        # Servername [Role] [Edition] Version Number
        $majorver = $MsxServer.AdminDisplayVersion.Major
        $txt1 = $MsxServer.Name + " [" + $MsxServer.ServerRole + "] [" + $MsxServer.Edition + "] [" + $MsxServer.AdminDisplayVersion + "] [Version:" + $majorver + "]"
        write-host $txt1
     
        #Connect to the Server's remote registry and enumerate all subkeys listed under "Patches"
        $Srv = $MsxServer.Name
        $key = ""
     
        #define the registry key, depending on Exchange Version 2007 or 2010
        if ($majorver -eq "8") # Exchange 2007
        {
           $key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\461C2B4266EDEF444B864AD6D9E5B613\Patches\"
        }
        if ($majorver -eq "14") # Exchange 2010
        {
           $key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\AE1D439464EB1B8488741FFA028E291C\Patches\"
        }
        $type = [Microsoft.Win32.RegistryHive]::LocalMachine
        $regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
        $regKey = $regKey.OpenSubKey($key)
     
        #Loop each of the subkeys (Patches) and gather the Installed date and Displayname of the Exchange 2007 patch
        $ErrorActionPreference = "SilentlyContinue"
        ForEach($sub in $regKey.GetSubKeyNames())
        {
            Write-Host "- " -nonewline
            $SUBkey = $key + $Sub
            $SUBregKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
            $SUBregKey = $SUBregKey.OpenSubKey($SUBkey)
            ForEach($SubX in $SUBRegkey.GetValueNames())
            {
                # Display Installed date and Displayname of the Exchange 2007 patch
                IF ($Subx -eq "Installed")   {
                    $d = $SUBRegkey.GetValue($SubX)
                    $d = $d.substring(4,2) + "/" + $d.substring(6,2) + "/" + $d.substring(0,4)
                    write-Host $d -NoNewLine
                }
                IF ($Subx -eq "DisplayName") {write-Host ": "$SUBRegkey.GetValue($SubX)}
            }
        }
        write-host ""
    }

    adjunto, envio el archivo del Script

    disfrutenlo !

    -GP

  • Tablas Particionadas

    Durante una plática con todos los PFE’s de SQL Server, empezamos a platicar de los objetos que tienen millones y millones de registros, el acceso a este es muy lento y por consiguiente su administración. Con est preludio empezamos a tocar el tema de Tablas Particionadas, que en simples palabras es partir en múltiples pedacitos la tabla de millones de registros.

    Esta característica se encuentra en SQL Server 2005, SQL Server 2008 y SQL Server 2008 R2. Para poder generar tablas particionadas es necesario identificar la columna mediante la cual va a ser realizar dicha partición. Para la creación de la tabla particionada es necesario realizar los siguientes pasos:

    • Crear una función de partición (PARTITION FUNCTION), en esta se definirá el rango que cada partición va a almacenar. Para este caso existen dos métodos de Rangos, Izquierda (left) o Derecha (right), la diferencia del uso de este método, es la manera de realizar el análisis de rangos. Un ejemplo de la sentencia para cada método serían los siguiente

    CREATE PARTITION FUNCTION pfAnualR(int) AS RANGE RIGHT FOR VALUES(2008,2009,2010,2011)

    CREATE PARTITION FUNCTION pfAnualL(int) AS RANGE LEFT FOR VALUES(2008,2009,2010,2011)

    Primera Partición < 2008

    Primera Partición <= 2008

    Segunda Partición >= 2008

    Segunda Partición > 2008

    Tercera Partición >= 2009

    Tercera Particion > 2009

    Cuarta Partición >= 2010

    Cuarta Particion > 2010

    Quinta Partición >= 2011

    Quinta Particion > 2011

    • Crear un esquema para la partición (PARTITION SCHEME) , en esta se definirán los FileGroupsdonde se almacenara cada partición, un ejemplo es el siguiente (para la ejecución correcta de este script, es necesario que se creen o existan 5 FileGroups llamados FG01, FG02, FG03, FG04, FG05):

    CREATE PARTITION SCHEME psAnualR AS PARTITION pfAnualR TO ([FG01], [FG02], [FG03], [FG04], [FG05])

    CREATE PARTITION SCHEME psAnualL AS PARTITION pfAnualL TO ([FG01], [FG02], [FG03], [FG04], [FG05])

    • En la creación de la Tabla, la diferencia es que en lugar de definir un FileGroup donde se guardara el objeto, se define la Función de partición y la columna eje. Ejemplo

    CREATE TABLE tblEstadosR (Ano int, Mes int, Dia int, Tipo varchar(30), Importe float) ON psAnualR(Ano)

    CREATE TABLE tblEstadosL (Ano int, Mes int, Dia int, Tipo varchar(30), Importe float) ON psanualL(Ano)

    • Una vez realizados estos pasos, se procede a realizar el llenado de las tablas particionadas

    INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2007,08,22,'Cargo',13.00) INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2008,08,22,'Cargo',34.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2009,08,22,'Cargo',23.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2010,08,22,'Cargo',78.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2011,08,22,'Cargo',98.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2012,08,22,'Cargo',14.00) GO

    INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2007,08,22,'Cargo',13.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2008,08,22,'Cargo',34.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2009,08,22,'Cargo',23.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2010,08,22,'Cargo',78.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2011,08,22,'Cargo',98.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2012,08,22,'Cargo',14.00) GO

    Para saber en qué partición se encuentra la data se utilizara el siguiente comando Transac-SQL $PARTITION, este regresa el número de partición en el cual se encuentra la data. Para el ejemplo que estamos realizando, el nombre de la Base de Datos utilizada es BDPrueba

    SELECT Ano, BDPrueba.$Partition.pfAnualR(Ano) FROM tblEstadosR 

    SELECT Ano, BDPrueba.$Partition.pfAnualL(Ano) FROM tblEstadosL

    El resultado de estos querys, explicaran el tipo de Rango RIGHT o LEFT de una manera más clara.

    Primera Partición < 2008 Segunda Partición >= 2008 Tercera Partición >= 2009 Cuarta Partición >= 2010 Quinta Partición >= 2011 Quita Particion >= 2011

    Primera Partición <= 2008 Primera Partición > 2008 Segunda Partición > 2009 Tercera Partición > 2010 Cuarta Partición > 2011 Quinta Particion > 2011

    Con lo anterior, se ha aprendido los conceptos básicos de particionamiento de tablas, las ventajas principales al manejar esta característica son:

    - Sliding Windows escenarios

    - Mejora de actividades administrativas, como:

    • Mantenimiento de Índices
    • Compresión de particiones
    • Manejo de Storage

    Debido al manejo de paralelismo algunos queries se pueden comportar más lentos con tabla particionadas que sin tabla particionadas.

    Posteriormente en el siguiente blog discutiremos temas como:

    - Cuáles son las ventajas y desventajas de particionar una tabla

    - Consideraciones cuando se implementa Sliding Windows.

     

    “Las opiniones e ideas expresadas en este blog son las de los Autores y no necesariamente declaran o reflejan la opinión de Microsoft”

    Este material tambien lo podras acceder en http://blogs.technet.com/b/sql_pfe_latam/

  • Configurar Autenticacion Kerberos utilizando nombre virtual CAS

    En la mayoría de las ocasiones los administradores de Exchange 2010 deciden implementar configuraciones redundantes en particular en los roles de Client Access Severs (CAS). Aunque la protección se logra desde el punto de vista de eliminar el punto de falla de un solo nodo, quizás desde el punto de vista de seguridad o autenticación existan requerimientos más fuertes. Por defecto la autenticación es NTLM cuando se configura un arreglo de CAS ya sea utilizando Windows Network Load Balancing (WNLB) o alguna otra solución, NTLM es un mecanismo de autenticación que trabaja pero al final no es tan escalable como Kerberos. En fin este artículo se trata de los pasos a seguir para implementar autenticación de Kerberos. 

    Ambiente

    El ambiente se compone de 3 servidores con múltiples roles cada uno según se describe abajo:

    AD1HC1 (CAS\HUB)

    AD1HC2 (CAS\HUB)

    AD1DCMCLNT (AD, MBX, Outlook)

     

     

    Pre-Requisitos

    1. Debe existir un arreglo de servidores CAS en el ambiente configurado y trabajando
    2. Se deben tener privilegios en la Organización de Exchange para ejecutar los cmdlets
    3. Se deben tener privilegios en el Directorio Activo para crear cuentas
    4. Las funciones del directorio activo deben estar trabajando de manera apropiada

     Pasos

    1 - Ir a "Active Directory Users and Computers", se puede utilizar el comando dsa.msc

    2 - Crear una cuenta de computadora, en este caso se crea CASARRAYASA

    3 - Luego se abre el "Shell" de manejo de Exchange y nos movemos a el directorio de instalación de exchange en específico el directorio de "scripts" en este caso (C:\Program Files\Microsoft\Exchange Server\V14\Scripts)

    4 - Bajar script (CoverOABVDirtoWebApplication.ps1) y ejecutarlo en cada Client Access Server para convertir el directorio virtual de OAB (Offline Address Book) a aplicacion.

    5 - Luego ejecutamos el script (.\RollAlternateServiceAccountPassword.ps1 -ToArayMembers casarray.contoso.com -GenerateNewPasswordFor CONTOSO.COM\CASARRAYASA$) .

     

    6 - En la corrida el script te pregunta si quieres cambiarle la contraseña  a la cuenta de computadora a lo que se le dice que sí.

      7 -  Luego se asocian los servicios de exchange al nombre del arreglo y a la cuenta de computadora creada. Cambiamos en este paso el exchangeMDB para que el servicio de RPC Client Access (setspn -S exchangeMDB/casarray.contoso.com CONTOSO\CASARRAYASA$)

    8- Luego hacemos lo mismo para el exchangeAB para el servicio de Address Book (setspn -S exchangeAB/casarray.contoso.com CONTOSO\CASARRAYASA$)

     

    9- Hacemos otra registración para el servicio de Address Book (setspn -S exchangeRFR/casarray.contoso.com CONTOSO\CASARRAYASA$)

    10- Finalmente hacemos la registración para servicios Web  (setspn -S http/casarray.contoso.com CONTOSO\CASARRAYASA$)

    11- Luego se puede verificar las registraciones hechas a la cuenta de computadora utilizando el comando (setspn -L CONTOSO\CASARAYASA)

    12- En los CAS envueltos reinicia los servicios de RPC CLient Access y Address Book

    13- Aunque se debe tener cuidado adicional con este paso  se puede forzar el cliente de Outlook a utilizar kerberos para autenticarse a Exchange. (Si los pasos no se ejecutaron de manera apropiada este paso puede causar desconexión)

    14- Para verificar que Kerberos esté trabajando se puede utilizar KLIST para ver los tickets de Kerberos.

    Referencias

    Utilizando el RollAlternateServiceAccount Script

    http://technet.microsoft.com/es-es/library/ff808311.aspx

     

     

  • Partitioned Tables

    On one of my chats with my fellow SQL Server PFE’s, we started talking about objects that have millions and millions of records, how accessing them can be really slow, and of course its administration can be a real pain. With these in mind we starts talking about Partitioned Tables, that in simple words is broke a millions records table on many parts.

    This feature is enabled on SQL Server 2005, SQL Server 2008, SQL Server 2008 R2. To generate the partitioned tables you will need to identify the key (column) that you are going to use to partition the table. To create the partitioned table you need to execute these steps:

    • Create a partition function (PARTITION FUNCTION); this will define the range for every partition. You can use two methods on the ranges, Left or Right; this will define how the ranges are analyzed. Review the following example:  

    CREATE PARTITION FUNCTION pfAnualR(int) AS RANGE RIGHT FOR VALUES(2008,2009,2010,2011)

    CREATE PARTITION FUNCTION pfAnualL(int) AS RANGE LEFT FOR VALUES(2008,2009,2010,2011)

    Primera Partición < 2008

    Primera Partición <= 2008

    Segunda Partición >= 2008

    Segunda Partición > 2008

    Tercera Partición >= 2009

    Tercera Particion > 2009

    Cuarta Partición >= 2010

    Cuarta Particion > 2010

    Quinta Partición >= 2011

    Quinta Particion > 2011

    • Create a partition scheme (PARTITION SCHEME), this will define the filegroups where the partitions will be placed, you will need to create the filegroups prior to create the partition scheme, review the following example (for the successful execution of this script, you’ll need to create 5 filegroups named FG01, FG02, FG03, FG04, FG05):

    CREATE PARTITION SCHEME psAnualR AS PARTITION pfAnualR TO ([FG01], [FG02], [FG03], [FG04], [FG05])

    CREATE PARTITION SCHEME psAnualL AS PARTITION pfAnualL TO ([FG01], [FG02], [FG03], [FG04], [FG05])

    • When creating the table, the only difference is than instead of defining a filegroup where the object will be placed, you’ll define a partition function and the key column, Example:

    CREATE TABLE tblEstadosR (Ano int, Mes int, Dia int, Tipo varchar(30), Importe float) ON psAnualR(Ano)

    CREATE TABLE tblEstadosL (Ano int, Mes int, Dia int, Tipo varchar(30), Importe float) ON psanualL(Ano)

    • Now that you have your table, put the data on it:

    INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2007,08,22,'Cargo',13.00) INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2008,08,22,'Cargo',34.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2009,08,22,'Cargo',23.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2010,08,22,'Cargo',78.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2011,08,22,'Cargo',98.00)INSERT INTO tblEstadosR (Ano, Mes, Dia, Tipo, Importe) VALUES (2012,08,22,'Cargo',14.00) GO

    INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2007,08,22,'Cargo',13.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2008,08,22,'Cargo',34.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2009,08,22,'Cargo',23.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2010,08,22,'Cargo',78.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2011,08,22,'Cargo',98.00)INSERT INTO tblEstadosL (Ano, Mes, Dia, Tipo, Importe) VALUES (2012,08,22,'Cargo',14.00) GO

    If you want to know on which partition a piece of data reside, use the following TSQL Command $PARTITION, this command returns the partition number on which the data is placed. Review the following example:

    SELECT Ano, BDPrueba.$Partition.pfAnualR(Ano) FROM tblEstadosR

    SELECT Ano, BDPrueba.$Partition.pfAnualL(Ano) FROM tblEstadosL

    This Query results enhanced the RIGHT and LEFT range explanation.

    Primera Partición < 2008 Segunda Partición >= 2008 Tercera Partición >= 2009 Cuarta Partición >= 2010 Quinta Partición >= 2011 Quita Particion >= 2011

    Primera Partición <= 2008 Primera Partición > 2008 Segunda Partición > 2009 Tercera Partición > 2010 Cuarta Partición > 2011 Quinta Particion > 2011

    On this post you have learned the basic concept son table partitioning, some of its advantages are:

    -        Sliding Windows scenario

    -        Enhance Administrative activities, like:

    • Index Maintenance
    • Partition Compression
    • Storage Management

    Because of the parallelism some queries can perform slower using partitioned tables than using regular tables

    On another posts we will discuss topics like:

    -        Advantage and disadvantage on partitioned tables.

    -        Considerations on implementing Sliding Windows.

     

    “The opinions and views expressed in this blog are those of the author and do not necessarily state or reflect those of Microsoft”

  • Ventajas y Desventajas de Change Tracking

    Hace algunas semanas un cliente me preguntó por opciones para auditar una situación específica. Decidí probar  si Change Tracking, una de las nuevas funcionalidades de SQL Server 2008, podía cumplir con sus necesidades. La conclusión es que Change Tracking no es una solución de Auditoría y por lo tanto hay que evitar usarla con ese propósito. En SQL Server 2008 existen otras opciones que pueden permitir tener un registro de los cambios a la información de las tablas, dependiendo de tus necesidades puedes evaluar alguna de las siguientes opciones:

    -        Auditorías de SQL (Nueva en SQL 2008)

    -        C2 Audit Mode (disponible desde SQL 2000)

    -        SQL Traces (Disponibles desde SQL 2000)

    -        Change Tracking (Nueva en SQL 2008)

    -        Change Data Capture (Nueva en SQL 2008)

    -        Código personalizado (triggers, columnas adicionales en las tablas, código adicional en los sp’s, etc.)

    -        Herramientas de terceros

    En éste caso decidimos probar Change Tracking. Change Tracking permite generar un registro cada vez que ocurre un cambio en un registro o columna. Para aprender cómo implementarlo referirse a http://msdn.microsoft.com/en-us/library/cc280462.aspx. Aquí me voy a enfocar en explicar las ventajas y limitantes que he encontrado hasta el momento en esta funcionalidad.

    Ventajas

    -        Fácil y rápida de implementar.

    • No requiere cambios en la aplicación (a menos que se quiera agregar un contexto al cambio)
    • Solo requiere configurar la BD, tablas y periodo de retención.

    -        La implementación tiene mejor performance que la mayoría de las otras opciones porque es más granular y ligera.

    -        Permite identificar cuantos cambios ha tenido el registro y no solo el último cambio.

    -        Puedes agregar contexto a cada DML de modo que éste contexto se almacene como parte del registro de cambio (requiere cambio en el código para agregar el contexto)

    -        Puedes identificar las columnas que cambiaron si lo configuraste para llevar el registro a nivel de columna.

    -        No bloquea el log de transacciones por lo que la depuración automática en el Recovery Model Simple no se ve afectado como con otras opciones.

    -        Es útil para identificar que registros y/o columnas han cambiado y necesitan moverse o actualizarse en el Data Warehouse.

    -        Automáticamente se depura la información anterior a cierto tiempo configurado. No necesitas preocuparte por ésta depuración.

     

    Desventajas

    -        No registra la fecha y hora del cambio

    -        No registra el usuario o login que hizo el cambio.

    -        No guarda los datos modificados, solo registra el hecho de que hubo un cambio.

    -        Dependiendo de la cantidad de cambios va a agregar algo de overhead, pero la gran mayoría de las veces no será significativo.

    -        Debido a que la operación es síncrona agregará un poco de tiempo a cada transacción, la cantidad de tiempo dependerá de la cantidad de cambios sobre objetos con Change Tracking habilitado que se hagan dentro de la transacción.

     

    “Las opiniones e ideas expresadas en este blog son las de los Autores y no necesariamente declaran o reflejan la opinión de Microsoft”

    Este material tambien lo podras acceder en http://blogs.technet.com/b/sql_pfe_latam/ 

  • TIP: El CMDLet Mount-SPContentDatabase de PowerShell "crea" bases de datos

    Saludos Comunidad de SharePoint,

    Recientemente estuve entregando el Workshop de Migración a SharePoint 2010 que recomiendo ampliamente y durante un laboratorio me percaté de algo que me dejó boquiabierto. Resulta que durante el proceso de un laboratorio se requiere utilizar el cmdlet de SharePoint Powershell llamado Mount-SPContentDatabase para montar una base de datos que existe en el servidor de base de datos provisionado en las máquinas virtuales del taller. De pronto un estudiante levanta la mano para solicitar ayuda porque a pesar de que la ejecución del cmdlet no arrojó ningún error el no puede visualisar el contenido de la base de datos. Me acerco a revisar el desarrollo del laboratorio y me doy cuenta que el estudiante cometió un error al escribir la base de datos, omitió una letra, y le pregunto una vez más ¿Seguro que no te mando error? a lo que respondió que no, así que decidí revisar el código escrito en PowerShell y efectivamente el estudiante no cometió errores en la sintaxis del cmdlet pero si en el nombre de la base de datos.

    WSS_Content_2007 - Nombre de la base de datos del laboratorio previamente creada en SQL Server

    WSS_Conten_2007 - Nombre que el estudiante le dió al momento de seguir los pasos del lab

    Yo hubiera esperado que debido a la descripción del cmdlet como se ve en la imagen abajo, hubiera aparecido un mensaje diciendo que dicha base de datos no existe...

    Tal cual la ayuda del cmdlet dice claramente que adjunta una base de datos EXISTENTE pero en cambio creó una nueva base de datos y por consiguiente el estudiante no podía continuar con el laboratorio.

    Adicionalmente quiero compartirles que existe un CMDLet que permite crear bases de datos de contenido New-SPContentDatabase, así que tengan cuidado cuando utilicen los CMDLets de SharePoint PowerShell.

    Referencias:

    Agregar bases de datos de contenido en SP2010 - http://technet.microsoft.com/en-us/library/cc825314.aspx

    Adjuntar bases de datos de contenido en SP2010 - http://technet.microsoft.com/en-us/library/ff607581(office.14).aspx

    Saludos y hasta el próximo POST