<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>André Rodrigues (SQL MAGU)</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/andrecr/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/andrecr/feed.xml</link>
    <description>Um blog para falar sobre SQL Server</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:37:27 GMT</lastBuildDate>
    <language>pt_BR</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Migrando dados On-Premises para o Azure com o novo Azure Database Migration Service</title>
      <link>https://docs.microsoft.com/archive/blogs/andrecr/migrando-dados-on-premises-para-o-azure-com-o-novo-azure-database-migration-service</link>
      <pubDate>Fri, 16 Feb 2018 16:51:34 GMT</pubDate>
      <dc:creator><![CDATA[André César Rodrigues]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/andrecr/?p=35</guid>
      <description><![CDATA[Olá Pessoal tudo bem? Espero que sim!

 

Recentemente a Microsoft anunciou o Public Preview do...]]></description>
      <content:encoded><![CDATA[Olá Pessoal tudo bem? Espero que sim!

<strong> </strong>

Recentemente a Microsoft anunciou o <strong>Public</strong> <strong>Preview do Azure Database Migration Service (Azure DMS)</strong>, uma nova forma de levar seus dados em bases SQL Server <u>ou de outras fontes de dados</u> para o Azure:

<a href="https://blogs.msdn.microsoft.com/datamigration/2017/11/15/announcing-the-azure-database-migration-service-public-preview/">https://blogs.msdn.microsoft.com/datamigration/2017/11/15/announcing-the-azure-database-migration-service-public-preview/</a>

Pensando nisso, resolvi montar este tutorial mostrando como migrar uma base de dados SQL Server localizada em um ambiente On-Premises para o Azure SQL Database usando o Azure DMS.

O tutorial explica desde de como criar uma conexão entre o Azure e um servidor em Hyper-V (On-Premises) usando VPN Site-to-Site até a migração dos dados com o Azure Database Migration Service.

<strong> </strong>

<strong>Pré-Requisitos</strong>

&nbsp;
<ul>
 	<li>Azure subscription (Obs.: Uma conta gratuita pode ser criada através do site: <a href="https://azure.microsoft.com/en-us/free/?v=18.03">https://azure.microsoft.com/en-us/free/?v=18.03</a>);</li>
 	<li>Hyper-V host com conexão a Internet;</li>
 	<li>ISO Windows Server 2016 (Obs.: Pode ser uma edição de avaliação a qual pode ser encontrada no seguinte site: <a href="https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2016">https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2016</a>);</li>
 	<li>ISO SQL Server 2016 ou 2017 (Obs.: Pode ser uma edição de avaliação a qual pode ser encontrada no seguinte site: <a href="https://www.microsoft.com/en-us/sql-server/sql-server-downloads">https://www.microsoft.com/en-us/sql-server/sql-server-downloads</a>);</li>
 	<li>Management Studio 17.x (Download: <a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms">https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms</a>);</li>
 	<li>Data Migration Assistant 3.x (Download: <a href="https://www.microsoft.com/en-us/download/details.aspx?id=53595">https://www.microsoft.com/en-us/download/details.aspx?id=53595</a>);</li>
 	<li>Um banco de amostragem, no caso irei usar um backup da base AdventureWorks2016 (Download: <a href="https://github.com/Microsoft/sql-server-samples/releases/tag/adventureworks">https://github.com/Microsoft/sql-server-samples/releases/tag/adventureworks</a>).</li>
</ul>
&nbsp;

<strong>HYPER-V</strong>

&nbsp;

Abra o Virtual Switch Manager do Hyper-V e crie dois novos switches virtuais conforme abaixo:

Nome: External – Tipo: External (Associe a interface que provê sua conexão com a Internet)

<img width="879" height="837" class="alignnone wp-image-45 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/124-1024x975.png" />

Nome: Private – Tipo: Private

<img width="879" height="837" class="alignnone wp-image-55 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/29-1024x975.png" />

Crie uma máquina virtual nova com um disco dinâmico de 128 GB e 2 adaptadores de rede onde um deles deverá ser associado ao virtual switch <strong>External</strong> e o outro ao <strong>Private </strong>que criamos nos passos anteriores:

<img width="879" height="837" class="alignnone wp-image-65 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/39-1024x975.png" />

<img width="879" height="837" class="alignnone wp-image-75 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/49-1024x975.png" />

Instale o Windows Server 2016 + SQL Server 2016 ou superior e restaure o backup da base AdventureWorks2016 no SQL Server que você acabou de instalar.

Agora, você irá notar na VM que um dos adaptadores de rede vai estar com conexão na Internet, nomeie ele na VM como External para evitar confusão. O outro adaptador nomeie como Private:

<img width="879" height="290" class="alignnone wp-image-76 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/56-1024x338.png" />

No adaptador External, clique com o direito, e mantenha apenas as opções de TCP/IP marcadas conforme abaixo:

<img width="623" height="811" class="alignnone wp-image-85 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/66.png" />

Deixe as configurações de IP e DNS em automático:

<img width="879" height="1001" class="alignnone wp-image-95 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/74-899x1024.png" />

Clique em “Advanced...” e na aba WINS marque a opção <strong>Disable NetBIOS over TCP/IP:</strong>

<img width="838" height="1024" class="alignnone wp-image-105 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/82-838x1024.png" />

No adaptador Private configure um IPv4 com máscara e DNS, não precisa de Gateway, no caso usarei:

Subnet Mask = 255.255.255.0

DNS = 192.168.0.1

IPv4 = 192.168.0.2

<img width="879" height="1001" class="alignnone wp-image-106 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/91-899x1024.png" />

Por enquanto, está é nossa configuração para o Hyper-V, agora vamos partir para o Azure.

&nbsp;

<strong>AZURE</strong>

&nbsp;

<strong>Resource Group</strong>

&nbsp;

Abra o Azure Portal, a primeira coisa que devemos fazer é criar um novo grupo de recursos, vou chama-lo de SAMPLE-DMS-S2S-RG:

<img width="463" height="1024" class="alignnone wp-image-115 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/102-463x1024.png" />

<strong>Virtual Network</strong>

&nbsp;

Dentro do grupo de recursos que foi criado, adicione uma Virtual Network, vou chama-la de SAMPLE-DMS-S2S-Vnet:

<img width="879" height="943" class="alignnone wp-image-125 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/1110-954x1024.png" />

Em address space adicione 10.2.0.0/16.

Em subnet name vou dar o nome de SAMPLE-DMS-S2S-Vnet-Subnet.

Em subnet address range adicione 10.2.0.0/24.

Em resource group, selecione nosso grupo de recursos, no meu caso SAMPLE-DMS-S2S-RG:

<img width="479" height="1024" class="alignnone wp-image-126 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/125-479x1024.png" />

<strong>Virtual Network Gateway</strong>

&nbsp;

Agora, vamos criar um novo Virtual Network Gateway dentro do nosso Resource Group, ele irá conter nossa segunda subnet.

Vá em Virtual Networks&gt; SAMPLE-DMS-S2S-Vnet &gt; Subnets:

<img width="404" height="1024" class="alignnone wp-image-135 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/131-404x1024.png" />

Clique em <strong>+ Gateway Subnet</strong> e em address range use 10.2.1.0/24:

<img width="870" height="1024" class="alignnone wp-image-145 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/141-870x1024.png" />

Você deve ver agora as duas Subnets conforme a imagem abaixo:

<img width="879" height="252" class="alignnone wp-image-146 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/151-1024x293.png" />

Agora dentro do nosso RG, adicione o Virtual Network Gateway e clique em <strong>Create</strong>:

<img width="879" height="456" class="alignnone wp-image-155 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/161-1024x531.png" />

Vou chamar o Virtual Network Gateway de SAMPLE-DMS-S2S-VnetGW.

Deixe o gateway type como VPN e seu vpn type como Route-based.

O SKU deixe em Basic.

Para a Virtual Network selecione a que criamos, no meu caso SAMPLE-DMS-S2S-Vnet.

Em Public IP, como não temos um, teremos que criar, vou chama-lo de SAMPLE-DMS-S2S-VnetGW-PublicIP. Lembrando que pode demorar um pouco até que um IP seja provisionado. Clique em <strong>Create</strong> ao final:

<img width="491" height="1024" class="alignnone wp-image-165 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/171-491x1024.png" />

<strong>Obs.: Esta etapa pode levar vários minutos.</strong>

&nbsp;

<strong>Local Network Gateway</strong>

<strong> </strong>

Agora que criamos o Virtual Network Gateway, vamos criar um Local Network Gateway.

Em nosso grupo de recursos, adicione o Local Network Gateway e clique em <strong>Create</strong>:

<img width="879" height="494" class="alignnone wp-image-175 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/181-1024x575.png" />

Vou chamá-lo de SAMPLE-DMS-S2S-LocalNetGW.

Em IP address, precisamos voltar lá na nossa VM no Hyper-V e descobrir qual seu IP público, para isso, dentro da VM abra o prompt de comando e rode o seguinte:

<em>nslookup myip.opendns.com resolver1.opendns.com</em>

No meu caso meu IP público é 177.113.183.174:

<img width="879" height="404" class="alignnone wp-image-185 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/191-1024x471.png" />

<em></em>

Em Address space, adicione a sub-rede do network adapter Private da nossa VM no Hyper V, no caso 192.168.0.2/32, ao término clique em <strong>Create</strong>:

<img width="490" height="1024" class="alignnone wp-image-195 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/20-490x1024.png" />

<strong>New connection - Local Network Gateway</strong>

<strong> </strong>

Agora, precisamos criar uma conexão no nosso Local Network Gateway. Para isso, vá em suas settings&gt;connections e clique em <strong>+Add</strong>:

<img width="742" height="1024" class="alignnone wp-image-205 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/211-742x1024.png" />

Vou chama-la de SAMPLE-DMS-S2S-LocalNetGW-Conn.

Defina seu Virtual Network Gateway com o que criamos anteriormente, no meu caso, SAMPLE-DMS-S2S-VnetGW.

Defina uma Shared Key (PSK) <u>e lembre-se de anota-la pois iremos precisar dela depois em nossa VM no Hyper-V,</u> ao final clique em <strong>OK</strong>:

<img width="472" height="1024" class="alignnone wp-image-215 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/221-472x1024.png" />

Se todas etapas foram devidamente feitas até aqui podemos partir para a configuração do RRAS em nossa VM no Hyper-V.

&nbsp;

<strong>Configuração do RRAS na VM do Hyper-V.</strong>

&nbsp;

Em nossa VM no Hyper abra o Server Manager.

Vá em <strong>Manage&gt;Add Roles and Features</strong>.

Em Before You Begin clique em <strong>Next</strong>.

Em Selection installation type selecione Role-Based or Feature-based installation e clique em <strong>Next</strong>.

Em Select server destination clique em <strong>Next</strong>.

Em Select server roles selecione Remote Access e clique em <strong>Next</strong>.

Em Select features clique em <strong>Next</strong>.

Em Remote Access clique em <strong>Next</strong>.

Em Role Services marque <strong>Direct Access and VPN (RAS):</strong>

<img width="879" height="627" class="alignnone wp-image-225 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/231-1024x731.png" />

Clique em <strong>Add Features</strong>:

<img width="879" height="923" class="alignnone wp-image-235 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/241-975x1024.png" />

Depois marque Routing também e clique em <strong>Next</strong>:

<img width="879" height="627" class="alignnone wp-image-245 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/251-1024x730.png" />

Em Web Server Role (IIS) clique em <strong>Next</strong>.

Em Select role services deixe o default e clique em <strong>Next</strong>.

Em Confirmation clique em <strong>Install</strong>.

Após o término da instalação, no Server Manager, em Tools, clique em <strong>Routing and Remote Access</strong>:

<img width="736" height="1024" class="alignnone wp-image-255 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/261-736x1024.png" />

Clique com o direito no nome do computador e selecione<strong> Configure and Enable Routing and Remote Access:</strong>

<img width="879" height="130" class="alignnone wp-image-265 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/271-1024x152.png" />

Na primeira tela clique em <strong>Next</strong>.

Em Configuration, marque Secure connection between two private networks e clique em <strong>Next:</strong>

<img width="879" height="744" class="alignnone wp-image-275 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/281-1024x867.png" />

Em Demand-Dial Connections marque <strong>Yes</strong> e clique em <strong>Next:</strong>

<img width="879" height="744" class="alignnone wp-image-276 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/291-1024x867.png" />

Em IP Address Assignment selecione <strong>Automatically</strong> e clique em <strong>Next:</strong>

<img width="879" height="744" class="alignnone wp-image-285 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/30-1024x867.png" />

Clique em <strong>Finish</strong> e aguarde:

<img width="300" height="124" class="alignnone size-medium wp-image-295" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/311-300x124.png" />

Após isso, uma nova janela já vai abrir para configurarmos a Demand-Dial Interface, clique em <strong>Next:</strong>

<img width="879" height="694" class="alignnone wp-image-305 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/321-1024x809.png" />

De um nome e clique em <strong>Next</strong>, no caso vou chama-la de <strong>SAMPLE-S2S-RRAS-Azure</strong>:

<img width="879" height="694" class="alignnone wp-image-315 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/331-1024x809.png" />

Em Connection Type selecione <strong>Connecting using virtual private network (VPN)</strong> e clique em <strong>Next:</strong>

<img width="879" height="694" class="alignnone wp-image-325 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/341-1024x809.png" />

Em VPN type selecione <strong>IKEv2</strong> e clique em <strong>Next:</strong>

<img width="879" height="694" class="alignnone wp-image-335 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/351-1024x809.png" />

Em IP Address, vá em nosso Virtual Network Gateway no Azure e copie seu <strong>Public IP</strong> (Lembra que o criamos?), cole o endereço copiado e clique em <strong>Next</strong>:

<img width="879" height="270" class="alignnone wp-image-336 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/361-1024x315.png" />

<img width="879" height="694" class="alignnone wp-image-346 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/371-1024x809.png" />

Em Protocols and Security selecione <strong>Route IP Packets on this interface</strong> e clique em <strong>Next</strong>:

<img width="879" height="694" class="alignnone wp-image-355 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/381-1024x809.png" />

Em Static Routes, vamos adicionar a rota da nossa subnet no Azure, no caso 10.2.0.0, 255.255.255.0, Metric: 24, depois clique em <strong>Next</strong>:

<img width="879" height="755" class="alignnone wp-image-365 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/391-1024x880.png" />

<img width="879" height="694" class="alignnone wp-image-375 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/40-1024x809.png" />

Depois cheque a rota adicionada em <strong>Static Routes</strong>:

<img width="879" height="250" class="alignnone wp-image-385 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/411-1024x291.png" />

Em Dial-Out Credentials de um nome qualquer e clique em <strong>Next</strong> e na última tela em <strong>Finish</strong>:

<img width="879" height="694" class="alignnone wp-image-395 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/421-1024x809.png" />

Agora em <strong>Routing and Remote Access &gt; Network Interfaces</strong>, clique com o direito na interface que criamos, no meu caso, SAMPLE-S2S-RRAS-Azure, depois clique em <strong>Propriedades</strong>:

<img width="879" height="439" class="alignnone wp-image-396 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/431-1024x511.png" />

Na aba Security, marque a opção <strong>Use preshared key for authentication</strong> e informe a mesma PSK que usamos no Azure:

<img width="824" height="1024" class="alignnone wp-image-406 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/441-824x1024.png" />

Na aba options, marque a opção <strong>Persistent Connection:</strong>

<img width="824" height="1024" class="alignnone wp-image-416 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/451-824x1024.png" />

<strong>Testando a conexão entre o ambiente On-Premisses e o Azure</strong>

<strong> </strong>

Agora, clique com o direito na interface, no meu caso SAMPLE-S2S-RRAS-Azure e clique em <strong>Connect</strong>.

Se deu tudo certo, a conexão será estabelecida e você poderá comprovar isso olhando a coluna Connection State e lá no Azure, a coluna STATUS dentro da Connection do Local Network Gateway:

<img width="879" height="468" class="alignnone wp-image-425 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/461-1024x545.png" />

<img width="879" height="304" class="alignnone wp-image-426 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/471-1024x354.png" />

Se por acaso a conexão não puder ser estabelecida, verifique se as portas do Azure estão liberadas no Firewall e também não se esqueça dos dispositivos de rede, os links a seguir podem ajudar:

<a href="https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/hybrid-networking/vpn">https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/hybrid-networking/vpn</a>

<a href="https://blogs.technet.microsoft.com/rrasblog/2006/06/14/which-ports-to-unblock-for-vpn-traffic-to-pass-through/">https://blogs.technet.microsoft.com/rrasblog/2006/06/14/which-ports-to-unblock-for-vpn-traffic-to-pass-through/</a>

Faça um ping da VM do Hyper-V no IP 10.2.0.0, o mesmo deve responder com sucesso:

<img width="879" height="482" class="alignnone wp-image-435 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/481-1024x561.png" />

<strong>Data Migration Assistant – Migração do schema do banco On-Premisses para o Azure</strong>

<strong> </strong>

Agora vamos realizar a migração do Schema do banco através do Data Migration Assistant (DMA).

Se voce ainda não baixou o DMA, baixe e o instale em nossa VM no Hyper-V, (Download: <a href="https://www.microsoft.com/en-us/download/details.aspx?id=53595">https://www.microsoft.com/en-us/download/details.aspx?id=53595</a>)

Abra o DMA, na esquerda, clique no sinal de <strong>“+”</strong>, selecione <strong>Migration</strong>, de um nome ao projeto, no meu caso <strong>SAMPLE-AzureDMS-Demo</strong>, em Source deixe como SQL Server e target como Azure SQL Database, em migration scope deixe selecionado <strong>Schema Only</strong> e clique em <strong>Create:</strong>

<img width="879" height="458" class="alignnone wp-image-445 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/491-1024x533.png" />

Em connect to source informe o nome da instância On-Premises, defina o método de autenticação que preferir, no meu caso irei usar Windows Authentication, marque as opções de <strong>Encrypt Connection</strong> e <strong>Trust Server Certificate</strong> e clique em <strong>Connect:</strong>

<img width="879" height="458" class="alignnone wp-image-455 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/50-1024x533.png" />

Selecione a base <strong>AdventureWorks2016</strong> que havíamos restaurado inicialmente e clique em <strong>Next:</strong>

<img width="879" height="458" class="alignnone wp-image-465 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/511-1024x533.png" />

Em Connect to target server, clique em <strong>Create New Azure SQL Database:</strong>

<img width="300" height="85" class="alignnone size-medium wp-image-475" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/521-300x85.png" />

Abra o portal do Azure e crie em nosso Resource Group uma nova Azure SQL Database em branco chamada <strong>AdventureWorks2016</strong>:

<img width="479" height="1024" class="alignnone wp-image-485 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/531-479x1024.png" />

Em Server, crie um novo, no meu caso vou chama-lo de <strong>azuredmstestserver</strong>:

<img width="879" height="567" class="alignnone wp-image-486 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/541-1024x660.png" />

<img width="684" height="618" class="alignnone wp-image-495 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/551.png" />

Na SQL database que acabamos de criar clique em<strong> Set server firewall:</strong>

<img width="879" height="398" class="alignnone wp-image-505 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/561-1024x464.png" />

Crie uma regra contendo o IP público da nossa VM no Hyper-V, no meu caso 177.113.183.174, clique em <strong>Save:</strong>

<img width="879" height="255" class="alignnone wp-image-795 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/147-1024x297.png" />

Volte ao DMA e informe o server name da SQL database criada, método de autenticação, marque as opções de <strong>Encrypt connection</strong> e <strong>Trust Server Certificate</strong> e clique em <strong>Connect:</strong>

<img width="879" height="458" class="alignnone wp-image-525 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/58-1024x533.png" />

Selecione a Azure SQL Database que criamos e clique em <strong>Next:</strong>

<img width="879" height="458" class="alignnone wp-image-535 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/59-1024x533.png" />

Em Select objects, deixe todos objetos marcados e clique em <strong>Generate SQL Script</strong>:

<img width="879" height="458" class="alignnone wp-image-545 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/60-1024x533.png" />

Após o script ter sido gerado clique em <strong>Deploy schema</strong>:

<img width="879" height="458" class="alignnone wp-image-765 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/821-1024x533.png" />

Aguarde a execução do deploy:

<img width="879" height="458" class="alignnone wp-image-565 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/621-1024x533.png" />

Após o deploy do schema feche o DMA.

&nbsp;

<strong>Azure Database Migration Service – Data migration</strong>

<strong> </strong>

Agora que nosso schema já foi migrado para o Azure, vamos levar os dados usando o novo serviço Azure Database Migration Service.

No menu do Portal clique em <strong>Subscriptions:</strong>

<img width="879" height="638" class="alignnone wp-image-575 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/631-1024x743.png" />

Após selecionar a assinatura, vá em <strong>Resource Providers</strong>:

<img width="417" height="1024" class="alignnone wp-image-585 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/641-417x1024.png" />

Procure por <strong>Microsoft.DataMigration</strong> e clique em <strong>Register</strong>.

Agora clique em <strong>Create a resource</strong>, localize o Azure Database Migration Service e clique em <strong>Create</strong>:

<img width="879" height="459" class="alignnone wp-image-595 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/651-1024x535.png" />

Nas configurações do Azure DMS, de um nome ao recurso (chamei o meu de SAMPLE-AzureDMS-Demo), selecione a Vnet que criamos, no meu caso SAMPLE-DMS-S2S-Vnet e clique em <strong>Create:</strong>

<img width="482" height="1024" class="alignnone wp-image-605 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/661-482x1024.png" />

Depois que o deploy finalizar, abra o recurso e clique em <strong>+ New Migration Project</strong>:

<img width="879" height="315" class="alignnone wp-image-615 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/67-1024x367.png" />

De um nome ao projeto, no meu caso <strong>AzureDMSDataMigration</strong> e clique em <strong>Create:</strong>

<img width="498" height="1024" class="alignnone wp-image-625 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/68-498x1024.png" />

Agora, em Select source, coloque o IP do adaptador Private da nossa VM no Hyper-V (que é também o IP que responde nosso SQL Server), informe o usuário (no meu caso o sysadmin) e clique em<strong> Save:</strong>

<img width="879" height="938" class="alignnone wp-image-635 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/69-960x1024.png" />

Na próxima etapa vamos selecionar a base <strong>AdventureWorks2016</strong> e clicar em <strong>Save</strong>:

<img width="879" height="659" class="alignnone wp-image-645 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/70-1024x768.png" />

Agora vamos informar os dados do nosso SQL database de destino e clicar em <strong>Save</strong>:

<img width="879" height="917" class="alignnone wp-image-655 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/711-982x1024.png" />

A próxima tela é um sumário do que está envolvido no nosso projeto dentro do DMS, confira as informações e clique em <strong>Save:</strong>

<img width="879" height="667" class="alignnone wp-image-665 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/721-1024x777.png" />

Agora, estaremos de volta a tela do nosso DMS, clique em cima do projeto que acabamos de criar e em cima clique em <strong>+ New Activity</strong> e depois em <strong>Run Database Migration:</strong>

<img width="300" height="116" class="alignnone size-medium wp-image-675" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/731-300x116.png" />

Será necessário redigitar a senha do source server e target server, faça isso e clique em <strong>Save.</strong>

Na etapa Map to target database note que a SQL database que já havíamos criado anteriormente será selecionada automaticamente, aqui também devemos marcar a opção <strong>SET SOURCE DATABASE READ-ONLY</strong>, feito isso clique em <strong>Save:</strong>

<img width="879" height="668" class="alignnone wp-image-685 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/741-1024x778.png" />

Na etapa Select tables, como já levamos o schema das tabelas da base On-Premisses anteriormente, ele automaticamente já fez o <em>link</em> delas com as tabelas vazias da Azure SQL database, clique em <strong>Save:</strong>

<img width="879" height="657" class="alignnone wp-image-695 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/75-1024x765.png" />

Agora, temos uma tela sumarizando o que foi selecionado, de um nome para a atividade (no meu caso AzureDMSActivity), em Validation Option deixe como Do Not Validade afinal é somente um teste, confirme as demais informações e estando tudo certo clique em <strong>Run migration:</strong>

<img width="879" height="943" class="alignnone wp-image-705 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/76-955x1024.png" />

Agora nossa atividade no DMS estará com status de <strong>Running:</strong>

<img width="879" height="294" class="alignnone wp-image-715 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/77-1024x343.png" />

Clicando na atividade é possível acompanhar a migração ou mesmo para-la:

<img width="879" height="533" class="alignnone wp-image-775 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/83-1024x621.png" />

Aguarde o DMS terminar a migração dos dados entre as tabelas, no meu caso levou ~4 minutos:

<img width="879" height="536" class="alignnone wp-image-725 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/78-1024x625.png" />

Voce também pode fazer download de um PDF contendo detalhes da migração, basta clicar em <strong>Download report:</strong>

<img width="879" height="537" class="alignnone wp-image-735 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/79-1024x626.png" />

<em>Exemplo de relatório:</em>

<img width="879" height="541" class="alignnone wp-image-745 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/80-1024x630.png" />

Clicando na linha indicativa da base de dados você também consegue ver o status por tabela pelo próprio portal:

<img width="879" height="507" class="alignnone wp-image-755 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/811-1024x591.png" />

Bom pessoal era isso, espero que o tutorial tenha sido útil a vocês!

&nbsp;

Abraço e até a próxima!

<strong> </strong>

<strong>Referências:</strong>

<strong> </strong>

<strong><em>Migrate SQL Server to Azure SQL Database</em></strong>

<a href="https://docs.microsoft.com/en-us/azure/dms/tutorial-sql-server-to-azure-sql"><em>https://docs.microsoft.com/en-us/azure/dms/tutorial-sql-server-to-azure-sql</em></a>

<strong><em>Differentiating Microsoft’s Database Migration Tools and Services</em></strong>

<em><a href="https://blogs.msdn.microsoft.com/datamigration/2017/10/13/differentiating-microsofts-database-migration-tools-and-services/">https://blogs.msdn.microsoft.com/datamigration/2017/10/13/differentiating-microsofts-database-migration-tools-and-services/</a></em>

<strong><em>Let’s Configure Azure Site-to-Site VPN with RRAS in Azure Resource Manager!</em></strong>

<a href="https://blogs.technet.microsoft.com/jletsch/2016/03/15/lets-configure-azure-site-to-site-vpn-with-rras-in-azure-resource-manager/"><em>https://blogs.technet.microsoft.com/jletsch/2016/03/15/lets-configure-azure-site-to-site-vpn-with-rras-in-azure-resource-manager/</em></a>]]></content:encoded>
    </item>
    <item>
      <title>Entendendo os PAGE SPLITs e o que seria o FILL FACTOR.</title>
      <link>https://docs.microsoft.com/archive/blogs/andrecr/entendendo-os-page-splits-e-o-que-seria-o-fill-factor</link>
      <pubDate>Tue, 21 Nov 2017 22:21:40 GMT</pubDate>
      <dc:creator><![CDATA[André César Rodrigues]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/andrecr/?p=26</guid>
      <description><![CDATA[Olá pessoal tudo bem com vocês? Espero que sim!

Estava bem sumido do meu blog...]]></description>
      <content:encoded><![CDATA[Olá pessoal tudo bem com vocês? Espero que sim!

Estava bem sumido do meu blog (<a href="https://sqlmagu.blogspot.com.br/">https://sqlmagu.blogspot.com.br/</a>) mas vou tentar voltar as poucos (devagar rsrs) e agora vou postar as coisas novas por aqui.

Como DBA SQL Server você provavelmente já sabe que o SQL Server aloca páginas de dados e índices de 8 KB e talvez, indo mais fundo no assunto, provavelmente já tenha ouvido falar sobre a operação <em>PAGE SPLIT</em> e o termo <em>FILL FACTOR</em> certo? Bom, no artigo de hoje vou explicar cada um deles e sugerir algumas coisas que podem ser úteis na administração da sua instância com SQL Server.

<strong>O que seria um PAGE SPLIT?</strong>

Quando o SQL Server vai fazer uma alocação em uma página de dados proveniente de um <em>INSERT</em> ou de um <em>UPDATE</em> em um índice <em>CLUSTERED ou NON-CLUSTERED (nível folha e intermediário)</em> e não existe mais espaço na página para manipular a linha afetada, ele realiza o que chamamos de<em> PAGE</em> <em>SPLIT</em>, ou seja, cria uma nova página de dados e movimenta mais ou menos a metade das linhas para ela. Em uma tabela sem índices <em>(HEAP)</em> não existem <em>PAGE SPLITS</em>, pois não existe uma ordenação logica dos dados, as alocações são baseadas nos <em>FORWARDED RECORDS</em>.

<strong>Certo, mas onde entra o FILL FACTOR nesta história toda?</strong>

Nas páginas de um índice <em>CLUSTERED ou NON CLUSTERED</em>, o <em>FILL FACTOR</em> de um índice define o quanto da página de dados será preenchido, onde ele é considerado nas seguintes situações:
<ul>
 	<li>Na criação do índice ou em seu <em>REBUILD</em>.</li>
 	<li>No nível folha e nos níveis intermediários quando o PAD_INDEX é especificado para o índice. Onde o PAD_INDEX é sempre igual ao FILL FACTOR.</li>
</ul>
Se você tem em determinado índice um <em>FILL FACTOR</em> em 70% por exemplo, significa que 30% do tamanho total da página será deixado sem preenchimento, este espaço vazio fica entre as linhas do índice e não no final dele.

<strong>O bom PAGE SPLIT e o PAGE SPLIT ruim</strong>

Bom, agora que você já tem uma noção do que é <em>PAGE SPLIT</em> e do que é <em>FILL FACTOR</em>, podemos falar sobre a diferença entre um bom <em>PAGE SPLIT</em> e um <em>PAGE SPLIT</em> ruim.

O bom <em>PAGE SPLIT</em> é aquele que ocorre sempre ao final do índice, imagine uma inserção em um campo <em>IDENTITY</em>, onde os dados são sempre inseridos em ordem ao final do índice, quando não existe mais espaço na última página, uma nova página vazia será alocada e os dados continuarão sendo inseridos. Agora pense por exemplo em uma inserção no meio do índice, ou mesmo em um <em>UPDATE</em> que cresce a linha de modo que ela deixe de caber na página, o SQL Server precisa, portanto, alocar uma nova página e movimentar parte dos dados da página original para ela, isso acaba gerando mais IO, fragmentação e aumento do <em>transaction log</em>, este seria o <em>PAGE SPLIT</em> ruim.

Certo...o que eu consigo fazer para nunca mais ter <em>PAGE SPLITS</em> ruins? A reposta é: <em>nada, </em>massss você pode tentar algumas coisas para pelo menos diminuir a ocorrência deles! Como? Lembra do <em>FILL FACTOR</em>?

<strong>Ajustando o FILL FACTOR</strong>

Não existe uma formula mágica de calcular qual é o <em>FILL FACTOR</em> ideal para cada índice que você possui, o melhor a fazer é acompanhar a carga de trabalho, identificar os índices com maior ocorrência de <em>PAGE SPLITS</em> e ir ajustando aos poucos o seu valor. De que forma você pode fazer isso? Se você está em um SQL Server anterior ao 2012, você pode começar olhando as colunas <strong><em>leaf_allocation_count</em></strong> e <strong><em>nonleaf_allocation_count</em></strong> da DMV <strong>sys.dm_db_index_operational_stats</strong>, dê uma olhada na query mencionada no site abaixo:

<a href="https://social.technet.microsoft.com/wiki/contents/articles/25473.sql-server-dmv-to-track-page-split.aspx"><em>https://social.technet.microsoft.com/wiki/contents/articles/25473.sql-server-dmv-to-track-page-split.aspx</em></a>

Com ela você pode ter uma ideia dos <em>PAGE SPLITS</em> considerando que ela captura a informação somente se o metadados dos objetos estiverem em cache, caso o serviço do SQL Server seja reiniciado ou a base alvo passe por um detach/attach por exemplo, a DMV não irá retornar à informação esperada, outro ponto aqui é entender que todas operações de <em>PAGE SPLITS</em> serão consideradas, sejam eles bons ou ruins.

Existe uma outra forma de saber como estão os <em>PAGE SPLITS</em> dos índices ao longo do tempo usando <strong><em>EXTENDED EVENTS</em></strong> e a vantagem se comparado a DMV anterior é que podemos filtrar a informação somente nos <em>PAGE SPLITS</em> ruins, basicamente precisamos criar uma sessão de xevents com o evento <strong>sql_server.transaction_log</strong> e filtrar o campo <strong>operation</strong> com o <strong>valor = 11</strong>, que significa <strong>LOP_DELETE_SPLIT</strong>. Esta operação indica que o SQL Server está movendo dados de uma página a outra, ou seja, <em>PAGE SPLITS</em> ruins.

Existe um artigo excelente do Kehayias que te ajuda a montar esta sessão de eventos estendidos:

<a href="https://www.sqlskills.com/blogs/jonathan/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time/"><em>https://www.sqlskills.com/blogs/jonathan/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time/</em></a>

A query abaixo é uma adaptação do código do <strong>Kehayias</strong> para que a informação possa ser lida do arquivo ao invés do histograma:

<code style="font-size: 12px"><span style="color: black"></span><span style="color: blue">SELECT  </span><span style="color: black">o.name </span><span style="color: blue">AS </span><span style="color: black">table_name</span><span style="color: gray">,
</span><span style="color: black">i.name </span><span style="color: blue">AS </span><span style="color: black">index_name</span><span style="color: gray">,
</span><span style="color: black">SplitCount</span><span style="color: gray">,
</span><span style="color: black">i.fill_factor
</span><span style="color: blue">FROM </span><span style="color: gray">(
</span><span style="color: blue">SELECT
</span><span style="color: magenta">DB_NAME</span><span style="color: gray">(</span><span style="color: black">TAB.database_id</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">DatabaseName</span><span style="color: gray">,
</span><span style="color: magenta">COUNT</span><span style="color: gray">(</span><span style="color: black">TAB.[alloc_unit_id]</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">SplitCount</span><span style="color: gray">,
</span><span style="color: black">alloc_unit_id
</span><span style="color: blue">FROM</span><span style="color: gray">(
</span><span style="color: blue">SELECT
</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: black">mi</span><span style="color: gray">, </span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: black">mi</span><span style="color: gray">, </span><span style="color: magenta">GETUTCDATE</span><span style="color: gray">(), </span><span style="color: magenta">CURRENT_TIMESTAMP</span><span style="color: gray">),
</span><span style="color: black">xevents.event_data.value</span><span style="color: gray">(</span><span style="color: red">'(event/@timestamp)[1]'</span><span style="color: gray">,
</span><span style="color: red">'datetime2'</span><span style="color: gray">)) </span><span style="color: blue">AS </span><span style="color: black">[event time] </span><span style="color: gray">,
</span><span style="color: black">xevents.event_data.value</span><span style="color: gray">(</span><span style="color: red">'(event/data[@name="database_id"]/value)[1]'</span><span style="color: gray">, </span><span style="color: red">'int'</span><span style="color: gray">)
</span><span style="color: blue">AS </span><span style="color: black">[database_id]</span><span style="color: gray">,
</span><span style="color: black">xevents.event_data.value</span><span style="color: gray">(</span><span style="color: red">'(event/data[@name="database_name"]/value)[1]'</span><span style="color: gray">, </span><span style="color: red">'varchar(max)'</span><span style="color: gray">)
</span><span style="color: blue">AS </span><span style="color: black">[database name]</span><span style="color: gray">,
</span><span style="color: black">xevents.event_data.value</span><span style="color: gray">(</span><span style="color: red">'(event/data[@name="alloc_unit_id"]/value)[1]'</span><span style="color: gray">, </span><span style="color: red">'BIGINT'</span><span style="color: gray">)
</span><span style="color: blue">AS </span><span style="color: black">[alloc_unit_id]
</span><span style="color: blue">FROM </span><span style="color: black">sys.</span><span style="color: darkred">fn_xe_file_target_read_file
</span><span style="color: gray">(</span><span style="color: red">'C:\temp\PageSplitTracking*.xel'</span><span style="color: gray">, </span><span style="color: green">-- ALTERE AQUI COM AS INFORMAÇÕES DO SEU ARQUIVO
</span><span style="color: red">'C:\temp\PageSplitTracking*.xem'</span><span style="color: gray">, </span><span style="color: green">-- ALTERE AQUI COM AS INFORMAÇÕES DO SEU ARQUIVO
</span><span style="color: gray">NULL, NULL)
CROSS </span><span style="color: black">APPLY </span><span style="color: gray">(</span><span style="color: blue">SELECT </span><span style="color: magenta">CAST</span><span style="color: gray">(</span><span style="color: black">event_data </span><span style="color: blue">AS XML</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">event_data</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">xevents
</span><span style="color: gray">) </span><span style="color: black">TAB
</span><span style="color: blue">GROUP BY </span><span style="color: black">TAB.alloc_unit_id</span><span style="color: gray">, </span><span style="color: black">TAB.database_id
</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">tab
</span><span style="color: blue">JOIN </span><span style="color: black">sys.allocation_units </span><span style="color: blue">AS </span><span style="color: black">au
</span><span style="color: blue">ON </span><span style="color: black">TAB.alloc_unit_id </span><span style="color: blue">= </span><span style="color: black">au.allocation_unit_id
</span><span style="color: blue">JOIN </span><span style="color: black">sys.partitions </span><span style="color: blue">AS </span><span style="color: black">p
</span><span style="color: blue">ON </span><span style="color: black">au.container_id </span><span style="color: blue">= </span><span style="color: black">p.partition_id
</span><span style="color: blue">JOIN </span><span style="color: black">sys.indexes </span><span style="color: blue">AS </span><span style="color: black">i
</span><span style="color: blue">ON </span><span style="color: black">p.</span><span style="color: magenta">OBJECT_ID </span><span style="color: blue">= </span><span style="color: black">i.</span><span style="color: magenta">OBJECT_ID
</span><span style="color: gray">AND </span><span style="color: black">p.index_id </span><span style="color: blue">= </span><span style="color: black">i.index_id
</span><span style="color: blue">JOIN </span><span style="color: black">sys.objects </span><span style="color: blue">AS </span><span style="color: black">o
</span><span style="color: blue">ON </span><span style="color: black">p.</span><span style="color: magenta">OBJECT_ID </span><span style="color: blue">= </span><span style="color: black">o.</span><span style="color: magenta">OBJECT_ID</span></code>

Pessoal, espero que este artigo seja útil para vocês no dia a dia quando o assunto for diminuir a ocorrência de <em>PAGE SPLITS</em> ruins, qualquer dúvida estou à disposição!

Um abraço!

André Rodrigues

&nbsp;

<strong>Referências: </strong>

<a href="https://sqlblog.com/blogs/kalen_delaney/archive/2009/11/11/fragmentation-and-forwarded-records-in-a-heap.aspx"><em>https://sqlblog.com/blogs/kalen_delaney/archive/2009/11/11/fragmentation-and-forwarded-records-in-a-heap.aspx</em></a><em>  </em>

<a href="https://blogs.msdn.microsoft.com/craigfr/2009/07/29/correction-to-my-prior-post-on-sys-dm_db_index_operational_stats/"><em>https://blogs.msdn.microsoft.com/craigfr/2009/07/29/correction-to-my-prior-post-on-sys-dm_db_index_operational_stats/</em></a>

<a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-db-index-operational-stats-transact-sql"><em>https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-db-index-operational-stats-transact-sql</em></a>

<a href="https://technet.microsoft.com/en-us/library/bb630339(v=sql.110).aspx"><em>https://technet.microsoft.com/en-us/library/bb630339(v=sql.110).aspx</em></a>

<a href="https://www.sqlskills.com/blogs/paul/how-expensive-are-page-splits-in-terms-of-transaction-log/"><em>https://www.sqlskills.com/blogs/paul/how-expensive-are-page-splits-in-terms-of-transaction-log/</em></a>]]></content:encoded>
    </item>
  </channel>
</rss>