0

Reclusteriser une instance standalone

twitterlinkedinmail

C’est arrivé près de chez vous: un upgrade de cluster SQL Server 2008 R2 vers 2012 qui passe de travers et qui sort en erreur. Au final, l’instance clusterisée ne démarre plus, le service est indisponible. Rechercher les causes du problème initial prendra trop de temps et il faut remonter le service en ligne le plus vite possible. L’instance est donc réinstallée en standalone sur un des anciens nœuds du cluster, les volumes remontés, les bases rattachées, et le service peut repartir.

La question : comment revenir à la situation de départ et reclusteriser cette instance ?

Situation de départ:

Il n’y a pas de recette magique, pas d’assistant pour reclusteriser une instance standalone, parce que les fonctionnalités cluster doivent être installées avant SQL Server, et que l’install de SQL Server en cluster est une installation très différente d’une installation standalone. Nous voici donc à notre point de départ…

La machine SQLN1 est la machine qui a été remontée en standalone. Elle est enregistrée dans le domaine et le SQL Server qui a été remonté a récupéré les 2 LUNS historiques avec les fichiers de données des bases. La machine SQLN2 est l’ancien noeud en échec qui a dû être ‘nettoyé’ (désinstall SQL Server complète, et suppression du cluster initial). Les deux LUNS SQLDATA et SQLLOG sont aussi visibles par SQLN2, pour simplifier la démo, elles sont montées via un FREENAS:

Etape 1: recréer un cluster à 1 nœud

La stratégie va être tout d’abord de constuire un cluster à 1 noeud sur SQLN2 avec une troisième LUN d’une taille juste suffisante pour mettre le répertoire racine de l’instance et les bases systèmes. On partira donc avec un volume SYS de 2 Gb (LUN sqltesttemp1), et le volume de QUORUM (LUN sqltestquorum1) de l’ancien cluster qui a pu être récupéré. Avantage, on peut travailler ‘à côté‘  de la production sans impact, en journée. La cible de cette première étape:

  • Ajouter les features cluster + Framework 3.5SP1:

  • Préparer les volumes:

Lancer l’outil de gestion iSCSI (iscsicpl.exe), et déclarer le portal iSCSI (dans mon cas 30.0.0.5:3260, pas d’authent CHAP):

Et connecter les deux disques qui nous intéressent: sqltestquorum1 et sqltesttemp1, via notre carte réseau iSCSI (en 30.0.0.0/24):

Ensuite initialiser les disques (GPT) et formater avec notre cluster size de 64K. On est en Windows 2008R2, pas de problèmes d’alignement en vue.

 

  • Créer le cluster (cluadmin.msc):

Ne sélectionner que notre nœud SQLN2 pour l’instant:

Lancer tous les tests de validation avant la création du cluster.

 

Nommer le cluster et renseigner son IP sur le LAN, dans notre cas 10.12.47.111, et terminer la création:

  • Déclarer les disques T:\ et Q:\ dans le cluster:

 

  • Passer le quorum en node majority + Disk en utilisant notre disque Q:

La console avertit que dans la configuration actuelle, seul un nœud est déclaré et donc le quorum en tant que tel ne peut être établi. Pour l’instant, c’est voulu, pas de soucis:

 

  • Installer une instance SQL Server 2012 sur le noeud SQLN2:

Je passe sur les étapes d’installation d’une instance sur une cluster 2008R2, voir l’article très complet de Christophe Laporte sur le sujet. Il est juste bien important que la config du cluster ait été validée sans quoi SQL Server ne pourra pas être installé. Je mets juste quelques étapes clés:

Le SQL Network Name pointera vers l’IP 10.12.47.110:

On met tout sous le T:\ pour l’instant, la situation est temporaire jusqu’à la bascule sur les autres volumes:

 

Etape 2: rattacher les volumes de l’instance standalone à l’instance clusterisée.

C’est l’étape délicate. Elle nécessite une coupure des services et de l’instance sur SQLN1. La manœuvre consiste à déconnecter les volumes de SQLN1 une fois l’instance stoppée, et les reconnecter sur SQLN2, puis remplacer les bases systèmes par celles provenant de SQLN1. Comme SQLN1 est une instance standalone, les bases systèmes se trouvent sur un disque local. Il faudra donc les déplacer sur un des disques partagés avant de basculer les volumes. On se donne rendez-vous sur le parking à 05h45, démarrage à 06h00. Un petit café et on est parti…

  • Avant faire un backup de master / msdb / model en local (ça ne coûte pas grand chose et ça peut sauver la vie)
backup database master to disk='c:\temp\master_avantmigr.bak' with stats, init, compression;
GO
backup database msdb to disk='c:\temp\msdb_avantmigr.bak' with stats, init, compression;
GO
backup database model to disk='c:\temp\model_avantmigr.bak' with stats, init, compression;
GO
  • Arrêt des applications et de l’instance sur SQLN1:
C:\Users\administrator.NANTES>net stop MSSQLSERVER
The following services are dependent on the SQL Server (MSSQLSERVER) service.
Stopping the SQL Server (MSSQLSERVER) service will also stop these services.

SQL Server Agent (MSSQLSERVER)

Do you want to continue this operation? (Y/N) [N]: Y
The SQL Server Agent (MSSQLSERVER) service is stopping.
The SQL Server Agent (MSSQLSERVER) service was stopped successfully.

The SQL Server (MSSQLSERVER) service is stopping.
The SQL Server (MSSQLSERVER) service was stopped successfully.
  • Une fois que tout est coupé, copier les fichiers MDF et LDF de master, msdb et model sur le drive SQLDATA.

  • Puis détacher les volumes de la machine SQLN1. Sélectionner les 2 volumes correspondants à nos SQLDATA et SQLLOG, et les déconnecter depuis la machine SQLN1:

  • Ensuite les rattacher sur la machine SQLN2 de la même manière, les passer online:

  •  et les ajouter comme ressource de stockage au cluster:

  • Il faut aussi vérifier que les lettres sont bien respectées E: pour SQLDATA, et L: pour SQLLOG.

Si ce n’est pas le cas, il faut renommer la lettre via la console d’administration du cluster:

 

A partir de là, on va devoir stopper l’instance sur SQLN2, pour rattacher les nouveaux disques au groupe de ressources SQL Server, refaire les dépendances, ajouter MSDTC, et redéposer nos bases systèmes à la place des anciennes sur le T:\

  • On stoppe SQL Server sur SQLN2 (en utilisant la console du cluster ! ):

 

  • On rattache les deux nouveaux volumes au groupe de ressources SQL Server (refaire la manip pour chaque disque):

 

  • On modifie les dépendances disque de SQL Server pour ajouter E: et L:

 

  • On ajoute notre MSDTC, qui va dépendre d’un disque + du nom réseau, et le passer online:

 

 

  • On va ensuite recopier les fichiers de données de master, msdb et model sur les fichiers dans l’arborescence attendue sous le T:\ (optionnel pour model)

Par précaution on va renommer les anciens fichiers en _old:

  • Modifier les chemins d’accès à MSDB et model, en démarrant en mode master recovery only:

En effet, les anciennes bases systèmes étaient stockées sous le C:\Program Files\…  sur l’ancienne instance. Le chemin de master est ok (sur le T:\), mais les chemins de msdb et model pointent toujours vers le C:\ et sont gravés dans master.mdf. L’instance ne pouvant pas démarrer sans model à cause de tempdb, il faut passer par cette étape en démarrant l’instance avec le traceflag -T3608.

Attention il y a une autre astuce, car par défaut SQL Server associe -T3608 avec le mode single-user. Mais dans un cluster, la première connexion est utilisée par la dll qui contrôle l’état de la ressource (ref), donc il faut démarrer via le service en shuntant la console du cluster :

C:\Users\administrator.NANTES>net start MSSQLSERVER /t3608
The SQL Server (MSSQLSERVER) service is starting.
The SQL Server (MSSQLSERVER) service was started successfully.

On se connecte et on modifie d’abord msdb:

C:\Users\administrator.NANTES>sqlcmd -E -S SQLTEST
1> select name from sys.master_files where database_id = db_id('msdb')
2> go
name
--------------------------------------------------------------------------------------------------------------------------------
MSDBData
MSDBLog

1> alter database msdb modify file (name='MSDBData',filename='T:\MSSQL11.MSSQLSERVER\MSSQL\DATA\MSDBData.mdf')
2> alter database msdb modify file (name='MSDBLog',filename='T:\MSSQL11.MSSQLSERVER\MSSQL\DATA\MSDBLog.ldf')
3> go
The file "MSDBData" has been modified in the system catalog. The new path will be used the next time the database is started.
The file "MSDBLog" has been modified in the system catalog. The new path will be used the next time the database is started.

Puis model:

1> select name from sys.master_files where database_id = db_id('model')
2> go
name
--------------------------------------------------------------------------------------------------------------------------------
modeldev
modellog

(2 rows affected)
1> alter database model modify file (name='modeldev',filename='T:\MSSQL11.MSSQLSERVER\MSSQL\DATA\model.mdf')
2> alter database model modify file (name='modellog',filename='T:\MSSQL11.MSSQLSERVER\MSSQL\DATA\modellog.ldf')
3> go
The file "modeldev" has been modified in the system catalog. The new path will be used the next time the database is started.
The file "modellog" has been modified in the system catalog. The new path will be used the next time the database is started.

Puis on stoppe et on relance l’instance en repassant la ressource en ligne:

C:\Users\administrator.NANTES>net stop MSSQLSERVER
The SQL Server (MSSQLSERVER) service is stopping.
The SQL Server (MSSQLSERVER) service was stopped successfully.

 

 

On se connecte et on vérifie qu’on a bien récupéré tous nos petits … (bases, logins, jobs, plans de maintenance)…

=> Et on relance les applications !!

Il reste à faire un peu de nettoyage : l’ancienne tempdb potentiellement, et les fichiers _old des bases master, msdb et model. Et voilà. On a récupéré notre prod sur un cluster à 1 nœud.

Etape 3: ajouter le second nœud au cluster.

Bon après – et bien que je sois en partie d’accord avec mon camarade MVP Linchi Shea (voir article) – un cluster à un noeud n’a pas beaucoup d’intérêt en soi. La dernière partie, qui elle aussi peut se faire à chaud, consiste à intégrer l’ancienne machine standalone comme second noeud du cluster. Par rapport à ce qu’on vient de faire, du tourisme quoi…

La cible une fois l’opération terminée:

Comme SQLN1 est un ancien nœud de cluster, les features (.NET 3.5SP1 + cluster) sont déjà là, pas la peine de les réinstaller. Il faut désinstaller par contre tout ce qui a attrait à SQL Server, on va repartir d’une machine ‘clean‘: (on peut laisser les runtimes vc++):

Ensuite il faut reconnecter les 4 disques clusterisés en utilisant iscsicpl:

Une fois la machine nettoyée et les disques reconnectés, on va la rajouter comme nœud à notre cluster:

Lancer la validation mais évidemment laisser le groupe de ressources SQL Server online pendant les tests, sinon le téléphone risque de sonner rapidement…

 

Quelques warnings seront générés dans la mesure où les disques n’ont pas pu être mis hors-ligne pour faire les tests. Pas de soucis. On retrouvera les mêmes warnings lors de l’installation du second SQL Server clusterisé. Et sinon un avertissement pour nous indiquer toutefois que les ressources SQL Server / SQL Agent, etc… ne sont pas déclarées sur le second donc une bascule n’est pas encore possible. On y arrive…

A cette étape, il faut aussi penser à autoriser le nouveau noeud SQLN1 à pouvoir posséder les disques clusterisés déclarés, donc dans les propriétés de chaque disque sous ‘storage’, Advanced Policies, il faut cocher SQLN1:

On a donc enfin notre second nœud vierge dans le cluster. Sur SQLN1, lancer l’install du second nœud SQL Server:

 

 
Et bien sûr tester une bascule en heures non ouvrées pour valider le retour en nominal. Attention, lors du test de bascule, il est extrêmement important d’avoir bien le même build de chaque côté, sans quoi si la version est supérieure sur le nœud sur lequel on va basculer, les bases vont passer en script upgrade, et selon la volumétrie ça peut durer un certain temps avant qu’elles ne soient mises online (1 heure de script upgrade pour une base de 2.3Tb à titre d’exemple).

Allez record de screenshots battu. A+ David B.

 

Continuez votre lecture sur le blog :

twitterlinkedinmail

David Baffaleuf

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.