SSMS 17.3 est disponible

Comme vous le savez probablement, depuis l’été 2016, et SQL Server 2016, SSMS possède dorénavant son propre cycle de vie, avec des mises à jour régulières, et dont la livraison est totalement distincte de SQL Server, le SGBD. SSMS, tout comme SSDT, ne ont plus livrés sur le média d’installation du moteur relationnel mais téléchargeable ici.

Je vous encourage a télécharger et installer la dernière version en date, estampillée 17.3, qui outre le support de SQL Server 2017 (mais les versions précédentes l’étaient aussi, apporte quelques améliorations, dont deux ont retenu mon attention.

Tout d’abord, et c’était une attente forte de toute les personnes, dont je fais partie, qui lors de démos passent un temps considérable à configurer une session xEvent pour ne pas avoir à utiliser le bon vieux Profiler, ou l’API SQL Trace. D’un point de vue Troubleshooting, ils sont tous deux utiles, mais que de consommation de ressource ! D’où le conseil de basculer sur le profiler. Oui, c’est un peu plus long à mettre en œuvre. C’était devrais-je dire.

Un nouvel item est apparu dans l’interface de SSMS : le XE Profiler

image

Cela permet de, très rapidement, configurer une session de xEvent, de la démarrer et de visualiser le contenu à l’écran. Un équivalent de trace par défaut du profiler. Bien joué !

Deux sessions sont proposées : Standard et TSQL. Chacune d’elle lors du premier démarrage va créer une “vrai” session XE.

image

Passons rapidement sur la session TSQL qui n’offre à mes yeux, moins d’intérêt que sa consœur. Seulement du BatchStarting ou RPCStarting, ce n’est pas suffisent pour faire du Troubleshooting.

image

La session Standard est bien plus intéressante puisqu’elle reprend les évènements Starting mais aussi les events Completed. D’ailleurs, si j’avais eu mot à dire, je n’auris opté que pour les Completed, mais bon …

image

Si vous êtes du même avis, je vous suggère de modifier le xEvent créé et votre modèle sera conservé tant que vous ne supprimerez pas la session.

Le point vraiment positif reste sans conteste le lancement vraiment rapide de la “trace”. Un click droit “Launch” et la session démarre immédiatement et produit un affichage. Pensez à faire un Stop Session, fermer la fenêtre ne suffit pas !

image

Ensuite, rien de neuf, on garde toute la puissance des xEvents et surtout de la capacité native de SSMS à fournir des opérations de regroupement et d’agrégation qu’on lui connaissait avant.

Bref, un petit incontournable.

 

La seconde fonctionnalité, du coup peut paraitre anecdotique. Mais à y regarde de plus près, l’import de fichier texte, même relativement bien formé, à la mode CSV, peut parfois s’avérer problématique lors de démos au pied levé, alors que cela devrait être on ne peut plus fluide.

Un nouvel assistant voit le jour : Import Flat File

image

Quoi de neuf me direz vous ?

Imaginez un fichier de ce type : on voit bien un format CSV qui se dessine, mais il y a un certain nombre de lignes à “exclure” en début de fichier.

image

Simple à gérer avec un BULKINSERT (idem avec un OPENROWSET). Mais il faut prendre le temps de créer la table, de coder l’insert …

image

Lors d’une démo c’est clairement moins pratique. Ce nouvel assistant va permettre d’importer rapidement le fichier sans erreur :

imageimageimageimage

Dans ce fichier, SQL Server n’a pas réussi à deviner le nom des colonnes. D’ailleurs en regardant de près les données importées, je me suis aperçu qu’un certain nombre de lignes manquaient. Les premières de mon fichier ! Comme si la machine réalisait un “apprentissage” des données. Pas trop gênant en démo, beaucoup plus en production.

Pour les curieux, c’est basé sur sur le PROSE SDK (https://microsoft.github.io/prose/), le programme va rechercher des patterns dans les données pour en déduire la structure.

Par contre, il faut admettre qu’un certain effort a été fait sur la reconnaissance des type de données. Tout comme le traitement automatique de chaines de caractère avec des caractères de type DoubleQuote qui auparavant faisait échouer le Wizard. Je vous le concède, ce n’est pas parfait, mais c’est toujours mieux que l’assistant d’import de données historique.

Je vous encourage à télécharger et installer …

md c:\sources
cd c:\sources
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=858904" -OutFile ssms-setup-enu.exe 
.\ssms-setup-enu.exe /install /passive

Enjoy

Publicités
Publié dans SQL Server | Tagué | 1 commentaire

SQL Server 2012 SP4 disponible

Avec la sortie récente de SQL Server 2017 certaines news passent un peu inaperçu. Voici donc un petit rappel : le Service Pack 4 pour SQL Server 2012 vient d’être publié. Rien d’extraordinaire me direz vous : eh bien si. Il s’agit tout simplement du dernier service pack pour cette version. Aucun autre ne verra le jour, SQL Server 2012 étant en fin de support “Mainstream”. Donc a moins que vous ne payez pour un support étendu, il n’y aura pas d’autres correctifs pour cette version. De quoi vous inciter à migrer vers une version plus récente !

Selon le communiqué officiel, outre des corrections de bug, plus de 20 améliorations ont été apportées, tant au niveau performance que scalabilité ou diagnostic.

A télécharger d’urgence ici.

Enjoy

Publié dans SQL Server | Tagué , | Laisser un commentaire

SQL Server 2017 disponible au téléchargement

Il y a quelques jours, SQL Server 2017 a été publiquement annoncé. Première version de SQL Server pouvant être exécuté sur Windows, Linux et Docker, les images étaient disponibles sur Azure sur les différentes plateformes.

image

Pour ceux qui souhaitent utiliser OnPrem SQL Server 2017, une édition Express, une édition développeur et une version d’essai, édition entreprise limitée à 180 jours peut être téléchargée ici.

image

Pour les personnes disposant d’un abonnement MSDN, le portail présente les édition Développeur et Express. Espérons que les autres éditions seront rapidement disponibles.

image

Happy download …

Publié dans SQL Server | Tagué , | Laisser un commentaire

SQL Server 2016–Failover d’un groupe de disponibilité distribué

Dans le précédent article, afin de pouvoir bénéficier d’un groupe de disponibilité distribué entre 2 sites, nous avons créé 2 clusters. Chaque cluster, et donc chaque groupe de disponibilité assurait la HA localement sur un site. Le groupe de disponibilité distribué, lui, assurait le Disaster Recovery en cas de perte de l’un des sites.

Pour faire suite, donc à ce première article, je vous propose donc une petite procédure permettant de basculer sur le site de secours, de manière planifiée.

Encore une fois, rien de vraiment complexe au niveau des scripts. Mais il convient d’être méticuleux et patient, de ne pas basculer trop tôt sur le site de DR sans avoir attendu que la synchronisation des données soit terminée avant de rendre le site actif.

Dans un premier temps, il faut basculer en mode synchrone le réplica secondaire du DAG, correspondant au Listener de l’AG local au site 2.

$tSQL = "
ALTER AVAILABILITY GROUP [distributedag]  
   MODIFY   
   AVAILABILITY GROUP ON  
      'DC1-AG' WITH    
   (   
         LISTENER_URL = 'tcp://DC1-AG-VIP.demo.local:5022',    
          AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT
      ),   
      'DC2-AG' WITH    
      (   
         LISTENER_URL = 'tcp://DC2-AG-VIP.demo.local:5022',   
         AVAILABILITY_MODE = SYNCHRONOUS_COMMIT
      );    
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"

Il faut alors attendre que la synchronisation soit totalement effectuée pour s’assurer qu’il n’y aura pas de perte de donnée. La requête suivante affiche l’état de synchronisation des différentes réplicas des AG et du DAG. Ainsi, tant que le réplica primaire du site secondaire n’est pas SYNCHRONIZED, il convent d’attendre.

tSQL = "
SELECT   ar.replica_server_name
       , ag.name as availabilitygroup_name
       , ag.is_distributed
       , DB_NAME(drs.database_id) As database_name
       , drs.is_primary_replica
       , drs.synchronization_state_desc
       , drs.synchronization_health_desc
       , drs.log_send_queue_size
       , drs.redo_queue_size
       , drs.end_of_log_lsn 
       , drs.last_sent_lsn
       , drs.last_received_lsn
       , drs.last_hardened_lsn
       , drs.last_redone_lsn
       , drs.secondary_lag_seconds
FROM sys.dm_hadr_database_replica_states drs 
INNER JOIN sys.availability_groups ag ON drs.group_id = ag.group_id
inner join sys.availability_replicas ar on ar.replica_id = drs.replica_id

"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1" | Out-GridView

Pour effectuer ne bascule vers le site de secours, il faut ensuite spécifier au site 1 qui set primaire qu’il prend le rôle de secondaire.

# first transform primary into secondary
$tSQL = "
ALTER AVAILABILITY GROUP [distributedag] SET (ROLE = SECONDARY);    
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"

Et ensuite de provoquer la bascule depuis le réplica primaire de l’AG du site 2.

# and then failover from a secondary
$tSQL = "
ALTER AVAILABILITY GROUP [distributedag] FORCE_FAILOVER_ALLOW_DATA_LOSS;
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"

Une fois cette manipulation terminée, on peut revenir sur un mode Asynchrone pour tous les réplicas.

$tSQL = "
ALTER AVAILABILITY GROUP [distributedag]  
   MODIFY   
   AVAILABILITY GROUP ON  
      'DC1-AG' WITH    
  (   
          LISTENER_URL = 'tcp://DC1-AG-VIP.demo.local:5022',    
           AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT
      ),   
      'DC2-AG' WITH    
      (   
         LISTENER_URL = 'tcp://DC2-AG-VIP.demo.local:5022',   
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT
      );    
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"

 

Le DAG est maintenant primaire sur le site 2.

Le Fail Back ne présente aucune difficultés. Il suffit de changer les noms de réplicas sur le script précédent.

Point important : il n’est pas possible de créer de listener sur un DAG. Les plus attentifs parmi vous auront noté que je n’en ai pas parlé dans l’article précédent. Il reste donc une opération manuelle sur un serveur DNS par exemple afin de rediriger le trafic sur le listener du second site. Il set aussi possible de passer par des Load Balancers du marché.

Happy DR !

Publié dans SQL Server | Tagué , , , | Laisser un commentaire

SQL Server 2016–Ajout d’une base dans un groupe de disponibilité distribué

Dans le précédent article, afin de pouvoir bénéficier d’un groupe de disponibilité distribué entre 2 sites, nous avons créé 2 clusters. Chaque cluster, et donc chaque groupe de disponibilité assurait la HA localement sur un site. Le groupe de disponibilité distribué, lui, assurait le Disaster Recovery en cas de perte de l’un des sites.

Pour faire suite, donc à ce première article, je vous propose donc une petite procédure permettant d’ajouter une base dans un groupe de disponibilité local et donc de propager cette base sur le DAG.

Le script est relativement simple. Globalement, l’ajout dans l’AG sur le site principal se fait au travers du Direct Seeding et du ALTER AVAILABILITY GROUP ADD DATABASE.

Mais pour le site secondaire il est nécessaire de procéder à l’initialisation des réplicas (les deux, le primaire et le secondaire) au travers d’un backup/restore. Ensuite, la base rejoint le DAG et l’AG local.


$Database = "NewDB"
$tSQL = "
CREATE DATABASE [$Database];
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"


# because we need to manually deploy the database to secondary site
# a regular backup is mandatory
$tSQL = "
BACKUP DATABASE [$Database] TO DISK = '$Database.bak' WITH INIT,FORMAT;
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"

$tSQL = "
BACKUP LOG [$Database] TO DISK = '$Database.trn' WITH INIT,FORMAT;
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"



$tSQL = "
ALTER AVAILABILITY GROUP [DC1-AG]
ADD DATABASE [$Database];
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"


Copy-Item E:\MSSQL\Backup\$Database.bak  \\DC2-SQL3\E$\MSSQL\Backup\$Database.bak 
Copy-Item E:\MSSQL\Backup\$Database.trn  \\DC2-SQL3\E$\MSSQL\Backup\$Database.trn 
Copy-Item E:\MSSQL\Backup\$Database.bak  \\DC2-SQL4\E$\MSSQL\Backup\$Database.bak 
Copy-Item E:\MSSQL\Backup\$Database.trn  \\DC2-SQL4\E$\MSSQL\Backup\$Database.trn


$tSQL = "
RESTORE DATABASE [$Database] FROM DISK = '$Database.bak' WITH NORECOVERY;
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

$tSQL = "
RESTORE LOG [$Database] FROM DISK = '$Database.trn' WITH NORECOVERY;
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"



$tSQL = "
ALTER DATABASE [$Database] 
SET HADR AVAILABILITY GROUP = [distributedag];
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"


$tSQL = "
ALTER DATABASE [$Database] 
SET HADR AVAILABILITY GROUP = [DC2-AG];
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

 

Enjoy !

Publié dans SQL Server | Tagué , , , | Laisser un commentaire

SQL Server 2016 – Groupes de disponibilité distribués

Depuis SQL Server 2012 il set possible de créer des groupes de disponibilité, un mix plutôt intéressant enter le failover cluster (un nom réseau et une adresse IP gérée par le Cluster Windows, tout comme la bascule automatique en cas de panne sur le primaire) et le database mirroring apparu avec SQL Server 2005 qui permet de s’affranchir de point de défaillance unique que constitue le stockage dans un failover cluster. Ajouter un peu de log shipping pour autoriser la lecture de données sur un serveur secondaire et vous obtenez les groupes de disponibilités, solution de haute disponibilité, mais de disaster recovery également.

Initialement prévu pour fonctionner avec 1 réplica primaire (pour la lecture écriture) et 4 réplicas secondaires, rapidement s’est imposée l’idée qu’il fallait ajouter des réplicas secondaires, 8 à l’heure actuelle.

Les réplicas secondaires peuvent être accessibles en lecture seule, soit directement, soit au travers du listener qui permet de se connecter au “groupe de bases”. Si l’on spécifie l’application intent à ReadOnly, alors les routing list nous aiguillent vers un réplica secondaire. Depuis SQL Server 2016, il existe également la possibilité de disposer d’un load balancing afin de distribuer la charge sur des réplicas secondaires. Initialement 2 réplicas pouvaient êter choisis opur assurer al haute disponibilité au travers d’un basculement automatique. 3 réplicas sont possibles aujourd’hui. Le basculement automatique n’est autorisé que si le réplica est en mode synchrone, c’set à dire que la commit sur le serveur principal n’est effectif que lorsque les données ont été écrites physiquement dans le journal de transaction du (ou des) réplicas secondaires. cela permet de s’assurer d’une perte de données nulle (RPO = 0). Par conter, cela implique un peu de latence sur les transactions. Si l’on souhaite privilégier la performance, il set possible d’opter pour un mode asynchrone. Dans ca cas, le commit sur le réplica principal n’attend pas l’acquittement des serveur secondaires.

Initialement réservée à l’édition entreprise, SQL Server 2016 a permis une évolution du database mirroring vers les groupes de disponibilité basiques accessibles depuis l’édition standard

Les groupes de disponibilité ont sans conteste possible été une réussite, au vu du nombre d’implémentation que j’ai pu réaliser chez mes clients, tout comme les différentes sessions que j’ai pu animer aux TechDays, Journées SQLServer, SQLSaturday, …

Principalement utilisée pour offrir une stratégie de haute disponibilité, il est tout a fait possible de l’utiliser dans un cadre de disaster recovery avec des réplicas sur un second site ou bien dans Azure. Cela fonctionne parfaitement.

Mais l’affaire se corse un peu lorsque il est nécessaire de disposer d’une résilience totale de site avec du multi maitre, a savoir que chaque site doit pouvoir héberger des bases actives en lecture écriture, même en cas de coupure de lien réseau inter-site. C’est là que les groupes de disponibilité distribués prennent tout leur intérêt.

Voici donc une reproduction d’un cas client mis en œuvre à la fin de l’été. Désolé pour le retard de post, je n’ai pas eu le temps de rédiger l’article plus tôt. Et je tien également à m’excuser auprès de Jonathan Kehayias (SQLskills) qui a publié dans la newsletter de ce mois ci une vidéo sur les Distributed availability Groups. Désolé pour cette malheureuse collision de calendriers.

L’idée principale était de pouvoir disposer de X databases dans un groupe de disponibilité sur le site 1. Sur ce site, un second réplica, synchrone, assurait la haute disponibilité. Deux autres réplicas, sur un site de secours auraient pu assurer la partie disaster recovery. Donc un AG réparti sur les 4 instances SQL aurait pu faire l’affaire. Sauf que sur le second site, il me fallait aussi disposer d’un autre AG, avec d’autres bases. Jusque là, pas de problèmes au niveau de la configuration, le site 1 pouvait également faire office de disaster recovery pour ce second AG.

Malheureusement, en cas de coupure réseau entre les sites, sur ce cluster 4 nœuds, il fallait choisir où poser le dernier vote, communément appelé Quorum. Si le partage réseau (File Share Witness) se trouve sur le site 1, l’AG du site 2 devient indisponible. Nous n’avions pas non plus la possibilité d’utiliser un Quorum Azure, possibilité offerte depuis Windows 2016.

Restait donc une nouveauté de SQL Server 2016 : les groupes de disponibilité distribués. Cerise sur le gâteau, cela permet également de réduire le trafic réseau intersites, car seul le primaire du site 1 envoie les journaux sur le primaire du site 2.

Sur un premier hyperviseur j’ai donc créé 1 VM Active Directory et 2 VMs SQL Server. Je passe volontairement sur le création d’une VM, l’installation de SQL Server en mode StandAlone avec compte managés en compte de service pour le moteur, rien de particulier de ce côté là. Idem pour l’AD, rien de neuf.

image

Sur un second hyperviseur, 3 VMs également. Un AD, qui est donc le second contrôleur de domaine de mon domaine de test.

image

Attention, soyez patient, la réplica intersites entre des contrôleurs de domaine n’est pas immédiate ! Ou alors vous al forcez sur le NTDS …

image

image

Ce qui donne côté DNS :

  • Site1 :
    • DC1-AD : 10.0.1.10
    • DC1-SQL1 : 10.0.1.11
    • DC1-SQL2 : 10.0.1.1
  • Site2 :
    • DC2-AD : 10.0.2.10
    • DC2-SQL3 : 10.0.2.13
    • DC2-SQL4 : 10.0.2.14

image

Etant donné que l’on cherche de la résilience de site, l’étape suivant consiste à créer un Cluster, au sens Windows du terme, sur chaque site.

Un petit script PowerShell permet de réaliser cette opération rapidement. Notez au passage le –NoStorage sur la commande de création du cluster. C’est important. Au même titre que lors d’un ajout de nœud dans la configuration cluster.

Install-WindowsFeature -Name Failover-Clustering -IncludeAllSubFeature -IncludeManagementTools -ComputerName DC1-SQL1
Install-WindowsFeature -Name Failover-Clustering -IncludeAllSubFeature -IncludeManagementTools -ComputerName DC1-SQL2
Install-WindowsFeature -Name Failover-Clustering -IncludeAllSubFeature -IncludeManagementTools -ComputerName DC2-SQL3
Install-WindowsFeature -Name Failover-Clustering -IncludeAllSubFeature -IncludeManagementTools -ComputerName DC2-SQL4


Test-Cluster -Node DC1-SQL1,DC1-SQL2
New-Cluster -Name DC1-WSFC -Node DC1-SQL1,DC1-SQL2 -NoStorage -StaticAddress 10.0.1.20
Get-Cluster  | Set-ClusterQuorum -FileShareWitness "\\DC1-AD1\FSW" 


Test-Cluster -Node DC2-SQL3,DC2-SQL4
New-Cluster -Name DC2-WSFC -Node DC2-SQL3,DC2-SQL4 -NoStorage -StaticAddress 10.0.2.20
Get-Cluster  | Set-ClusterQuorum -FileShareWitness "\\DC2-AD2\FSW" 

Une fois terminé nous obtenons 2 clusters, totalement indépendants l’un de l’autre, chacune pouvant supporter des groupes de disponibilités “locaux”.

imageimage

Une fois les cluster “locaux” créés il est possible d’activer la fonctionnalité AlwaysOn Availability Groups sur les instances SQL.

# DC1
Enable-SqlAlwaysOn -Path SQLSERVER:\SQL\DC1-SQL1\DEFAULT -Force
Restart-Service -InputObject $(Get-Service -Computer DC1-SQL1 -Name "MSSQLSERVER") -Force

Enable-SqlAlwaysOn -Path SQLSERVER:\SQL\DC1-SQL2\DEFAULT -Force
Restart-Service -InputObject $(Get-Service -Computer DC1-SQL2 -Name "MSSQLSERVER") -force

# DC2
Enable-SqlAlwaysOn -Path SQLSERVER:\SQL\DC2-SQL3\DEFAULT -Force
Restart-Service -InputObject $(Get-Service -Computer DC2-SQL3 -Name "MSSQLSERVER") -Force

Enable-SqlAlwaysOn -Path SQLSERVER:\SQL\DC2-SQL4\DEFAULT -Force
Restart-Service -InputObject $(Get-Service -Computer DC2-SQL4 -Name "MSSQLSERVER") -force

Je passe sur l’ouverture des ports sur les firewall locaux des serveurs (port 5022 par défaut mais c’est tout a fait paramétrable).

L’étape suivante consiste à mettre en place la tuyauterie permettant à tous les instances de dialoguer les une avec les autres. Cela passe par la création de point de terminaison, la création de Logins correspondants aux comptes de service des instances et aux autorisation de connexion sur ces points de terminaison.


# create the endpoints on SQL Server for DBM and AG
$endpoint = New-SqlHadrEndpoint MirroringEndpoint -Port 5022 -Path SQLSERVER:\SQL\DC1-SQL1\DEFAULT
Set-SqlHadrEndpoint -InputObject $endpoint -State "Started"

$endpoint = New-SqlHadrEndpoint MirroringEndpoint -Port 5022 -Path SQLSERVER:\SQL\DC1-SQL2\DEFAULT
Set-SqlHadrEndpoint -InputObject $endpoint -State "Started" 

$endpoint = New-SqlHadrEndpoint MirroringEndpoint -Port 5022 -Path SQLSERVER:\SQL\DC2-SQL3\DEFAULT
Set-SqlHadrEndpoint -InputObject $endpoint -State "Started"

$endpoint = New-SqlHadrEndpoint MirroringEndpoint -Port 5022 -Path SQLSERVER:\SQL\DC2-SQL4\DEFAULT
Set-SqlHadrEndpoint -InputObject $endpoint -State "Started" 



# create the login and grant the service account on the endpoints
$tSQL = "CREATE LOGIN [demo\DC1-SQL1$] FROM WINDOWS;"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL2"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

$tSQL = "CREATE LOGIN [demo\DC1-SQL2$] FROM WINDOWS;"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

$tSQL = "CREATE LOGIN [demo\DC2-SQL3$] FROM WINDOWS;"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL2"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

$tSQL = "CREATE LOGIN [demo\DC2-SQL4$] FROM WINDOWS;"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL2"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"


$tSQL = "GRANT CONNECT ON ENDPOINT::[MirroringEndpoint] TO [demo\DC1-SQL1$];"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL2"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

$tSQL = "GRANT CONNECT ON ENDPOINT::[MirroringEndpoint] TO [demo\DC1-SQL2$];"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

$tSQL = "GRANT CONNECT ON ENDPOINT::[MirroringEndpoint] TO [demo\DC2-SQL3$];"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL2"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

$tSQL = "GRANT CONNECT ON ENDPOINT::[MirroringEndpoint] TO [demo\DC2-SQL4$];"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL2"
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"

Maintenant que les instances sont capables de dialoguer les une avec les autres, il ne reste qu’à créer des groupes de disponibilité sur chaque cluster.

Encore une fois, rien de très compliqué, mais les choses doivent être faites dans l’ordre. Notez dans le script suivant l’utilisation du paramètre SEEDING_MODE = AUTOMATIC. Encore une nouveauté liée à SQL Server 2016 qui permet d’initialiser les bases sur le serveur secondaire d’un AG de manière automatique sans procéder à une restore de la base suivi du journal de transaction. C’est la raison pour laquelle le groupe de disponibilité reçoit la permission CREATE DATABASE .


# AG on site 1
$tSQL = "
CREATE AVAILABILITY GROUP [DC1-AG]
FOR REPLICA ON 
'DC1-SQL1' 
    WITH (   ENDPOINT_URL = 'TCP://DC1-SQL1.demo.local:5022', 
             AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, 
             FAILOVER_MODE = AUTOMATIC,
             SEEDING_MODE = AUTOMATIC  ),
'DC1-SQL2' 
    WITH (   ENDPOINT_URL = 'TCP://DC1-SQL2.demo.local:5022', 
             AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, 
             FAILOVER_MODE = AUTOMATIC,
             SEEDING_MODE = AUTOMATIC )
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"

# grant the AG to create a database
$tSQL = "ALTER AVAILABILITY GROUP [DC1-AG] GRANT CREATE ANY DATABASE"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"


# join the seconday node and also grant create database
$tSQL = "
ALTER AVAILABILITY GROUP [DC1-AG] JOIN
ALTER AVAILABILITY GROUP [DC1-AG] GRANT CREATE ANY DATABASE
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL2"

New-SqlAvailabilityGroupListener -Name "DC1-AG-VIP" -StaticIp "10.0.1.30/255.0.0.0" -Path "SQLSERVER:\Sql\DC1-SQL1\DEFAULT\AvailabilityGroups\DC1-AG"


image


# AG on site 2
$tSQL = "
CREATE AVAILABILITY GROUP [DC2-AG]
FOR REPLICA ON 
'DC2-SQL3' 
    WITH (   ENDPOINT_URL = 'TCP://DC2-SQL3.demo.local:5022', 
             AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, 
             FAILOVER_MODE = AUTOMATIC,
             SEEDING_MODE = AUTOMATIC  ),
'DC2-SQL4' 
    WITH (   ENDPOINT_URL = 'TCP://DC2-SQL4.demo.local:5022', 
             AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, 
             FAILOVER_MODE = AUTOMATIC,
             SEEDING_MODE = AUTOMATIC )
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"

# grant the AG to create a database
$tSQL = "ALTER AVAILABILITY GROUP [DC2-AG] GRANT CREATE ANY DATABASE"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"


# join the seconday node and also grant create database
$tSQL = "
ALTER AVAILABILITY GROUP [DC2-AG] JOIN
ALTER AVAILABILITY GROUP [DC2-AG] GRANT CREATE ANY DATABASE
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL4"

New-SqlAvailabilityGroupListener -Name "DC2-AG-VIP" -StaticIp "10.0.2.30/255.0.0.0" -Path "SQLSERVER:\Sql\DC2-SQL3\DEFAULT\AvailabilityGroups\DC2-AG"


image

Il ne reste qu’à présent qu’à ajouter une base dans le groupe de disponibilité. L’auto seeding est une avancée majeure pour les groupes de disponibilité mais cela ne dispense pas du prérequis BACKUP DATABASE. Please, ne pas faire de backup vers NUL en production !!!


# add a database into the AG to verify all is working fine
$Database = "DemoDB01"
$tSQL = "
CREATE DATABASE [$Database];
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"


# Dummy backup to fake the controls for addinf a DB into an AG
# Do not run on a production environment
$tSQL = "
BACKUP DATABASE [$Database] TO DISK = 'NUL';
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"


$tSQL = "
ALTER AVAILABILITY GROUP [DC1-AG]
ADD DATABASE [$Database];
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"

La base se trouve à présent dans le groupe de disponibilité, sur le serveur DC1-SQL1 et DC1-SQL2.

image

Jusque là, rien de nouveau. La partie fun commence maintenant : la création du groupe de disponibilité distribué afin de propager cette base sur les serveurs sur Site 2 (DC2-SQL3 et DC2-SQL4).

La différence entre un AG et un DAG (Distributed Availability Group) est fine … Voyez le DAG comme un AG qui repose sur deux AGs. Autrement dit, on remplace ENDPOINT_URL par LISTENER_URL et on point sur les nom DNS des listeners. That’s all.


# Create DAG
$tSQL = "
CREATE AVAILABILITY GROUP [distributedag]  
   WITH (DISTRIBUTED)   
   AVAILABILITY GROUP ON  
      'DC1-AG' WITH    
      (   
         LISTENER_URL = 'tcp://DC1-AG-VIP.demo.local:5022',    
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,   
         FAILOVER_MODE = MANUAL,   
         SEEDING_MODE = AUTOMATIC   
      ),   
      'DC2-AG' WITH    
      (   
         LISTENER_URL = 'tcp://DC2-AG-VIP.demo.local:5022',   
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,   
         FAILOVER_MODE = MANUAL,   
         SEEDING_MODE = AUTOMATIC   
      );    
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1"



# wait for total synchronisation
$tSQL = "
SELECT   ar.replica_server_name
       , ag.name as availabilitygroup_name
       , ag.is_distributed
       , DB_NAME(drs.database_id) As database_name
       , drs.is_primary_replica
       , drs.synchronization_state_desc
       , drs.synchronization_health_desc
       , drs.log_send_queue_size
       , drs.redo_queue_size
       , drs.end_of_log_lsn 
       , drs.last_sent_lsn
       , drs.last_received_lsn
       , drs.last_hardened_lsn
       , drs.last_redone_lsn
       , drs.secondary_lag_seconds
FROM sys.dm_hadr_database_replica_states drs 
INNER JOIN sys.availability_groups ag ON drs.group_id = ag.group_id
inner join sys.availability_replicas ar on ar.replica_id = drs.replica_id

"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC1-SQL1" | Out-GridView

# Join DAG
$tSQL = "
ALTER AVAILABILITY GROUP [distributedag]   
   JOIN   
   AVAILABILITY GROUP ON  
      'DC1-AG' WITH    
      (   
         LISTENER_URL = 'tcp://DC1-AG-VIP.demo.local:5022',    
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,   
         FAILOVER_MODE = MANUAL,   
         SEEDING_MODE = AUTOMATIC   
      ),   
      'DC2-AG' WITH    
      (   
         LISTENER_URL = 'tcp://DC2-AG-VIP.demo.local:5022',   
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,   
         FAILOVER_MODE = MANUAL,   
         SEEDING_MODE = AUTOMATIC   
      );    
"
Write-Host $tSQL 
Invoke-SqlCmd -Query $tSQL -Serverinstance "DC2-SQL3"


 

Ne jouez pas le script d’une traite, soyez patients. Jouez les portions de script les unes après les autres.

La base set maintenant disponible les sur les réplicas du site 2 …

image

 

And voilà ! comme disent les anglo-saxons avec  un mot de français Sourire

Le groupe de disponibilité distribué est à présent opérationnel. Les données vont bien être “recopiées” de manière synchrone entre les réplicas de chaque site, mais de manière asynchrone entre les sites. a solution de disaster recovery est opérationnelle. Et il est tout a fait possible de créer un second DAG, primaire sur le site 2 avec son disaster recovery sur le site 1. Cela correspond à l’architecture demandée : la résilience de site en cas de coupure réseau.

Happy DAG !

Note : La méthode et les scripts vous sont fournis clé en main. Merci de jouer franc-jeu. Si vous les utilisez, ajoutez une ligne de crédit. Rien n’oblige à partager et voir notre travail présenté par des tiers de manière publique dans afficher la source n’est pas vraiment fairplay. A bon entendeur …

Publié dans PowerShell, SQL Server, Windows | Tagué , , , | 2 commentaires

SQL Server 2017 disponible le 2 Octobre 2017

L’annonce vient d’être faite … SQL Server 2017, première version cross-plateform de SQL Server sera disponible le 2 Octobre 2017.

As Scott Guthrie wrote, today we announced general availability of SQL Server 2017, coming October 2! This is an incredible milestone representing the first version of SQL Server to run on Windows Server, Linux and Docker—and it already has been pulled on Docker X 2 million times since November.

https://blogs.technet.microsoft.com/dataplatforminsider/2017/09/25/microsoft-for-the-modern-data-estate/

Enjoy Smile

Publié dans SQL Server | Tagué | 1 commentaire

SQL Saturday 658 – Les bases du dépannage–les slides

Le #SQLSatToulouse S’est terminé hier. Merci aux participants pour leur présence. Merci aussi à tous les speakers qui donnent de leurs temps et de leur énergie pour animer les sessions et partager leur passion.

Merci également aux sponsors sans qui ce type d’évènement ne serait pas possible.

image

Un big UP également à Jean-Pierre (@djeepy1 Azéo) et à Frédéric (@Fredg_31 Groupe SRA) pour leur implication dans l’organisation de cet évènement en région.

Pour ma part, je tiens à vous remercier de m’avoir supporté lors de la session sur les bases de dépannage SQL Server dont le nombre de mots/minute était difficilement compatible avec une fin de journée. Vous avez été courageux.

clip_image004

Vous pouvez télécharger les slides à l’adresse suivante : https://1drv.ms/b/s!AqEDUOmSujklhNN8TuO1R6DOW0R-Mw

Happy Tshooting !

Publié dans Evènements | Tagué | Laisser un commentaire

SQLSaturday #658 Toulouse – The raffle

Dur de se motiver à travailler un vendredi après-midi, alors que nombre de vos collègues sont encore en congés et vous narguent avec des photos de plage ou d’apéro-piscine par 30° à l’ombre …

Bref, plutôt que de regarder des vidéos de chatons attendrissant sur Facebook, cliquez et inscrivez vous pour le SQLSaturday Toulouse du 16 septembre. Non seulement vous passerez une bonne journée en compagnie de passionnés de SQL Server, mais en outre, vous pourrez remporter une voiture en kit à monter vous-même. A base d’Arduino, ce robot car est vraiment sympa. 100% des gagnants sont inscrits !

2017-08-25 13.58.282017-08-25 13.59.38

Le colis est arrivé ce matin, il n’attend que vous ! Quoi que .. si je me le gardais pour moi ?

Publié dans Evènements | Laisser un commentaire

SQLSaturday #658 Toulouse – Installation et configuration SQL Server

Le SQLSaturday Toulouse est en bonne voie. Tous les organisateurs et sponsors s’activent pour vous préparer un bel évènement SQL Server à La Cantine le Samedi 16 Septembre.

Prochaines formations

La veille, le vendredi 15 septembre sont organisées deux préconfs, au tarif de 150 euros la journée repas inclus, dans les locaux de notre partenaire iForm.

Durant cette journée, nous allons, sur la track DBA, parler installation et configuration SQL Server. Ou comment faire mieux qu’un simple “Next Next Next Finish” et parler des bonnes pratiques …

Pour vous inscrire, c’est ici.

PreConf

Djeepy pour sa part parlera PowerBI

PreConfJP

Au plaisir de vous y retrouver …

Publié dans Evènements | Laisser un commentaire