(5-2) Façons de migrer une grande table SQL

Présentation


Bonjour à tous! Ceci est mon premier article et je l'écris au nom d'un ingénieur de développement junior en C #. Il n'y aura donc pas d'informations détaillées sur SQL, seulement des informations pratiques et des réflexions sur la résolution d'un problème plutôt pas évident que j'ai dû affronter pour les mêmes nouveaux arrivants que moi.

Tout d'abord, je vais décrire la formulation de mon problème à titre d'exemple, dans lequel il existe un réel besoin de déplacer une grande table.

Supposons donc que vous disposiez d'un service Web et d'une base de données SQL (MS-SQL) avec une table de lettres html que votre service envoie aux utilisateurs. Les lettres sont stockées pendant un certain nombre d'années et ne peuvent pas être supprimées, car elles sont nécessaires pour collecter des statistiques et des analyses. Cependant, chaque année, le nombre de lettres augmente, la base de données augmente et l'espace sur le serveur SQL diminue (dans notre cas, un autre facteur était de restaurer la base de données sur le site de test, car son temps augmentait proportionnellement) et quelque chose doit être fait avec cela à faire. Heureusement, dans notre cas, il existe un serveur gratuit avec un tas d'espace libre (en réalité, ce n'est peut-être pas le cas, et bien sûr, c'est une solution temporaire, mais cela dépasse le cadre de l'article). Le problème s'est donc posé de déplacer une grande table (et en disant «grande», je veux dire une très grande table, tout ce que j'ai vu en recherchant des solutions similaires était de l'ordre de 60 à 100 Go, dans notre cas, la table pesait plus de 300 Go).

Nous considérerons plusieurs façons de résoudre ce problème, mais elles ne concerneront pas toutes le transfert de type serveur-serveur. Parfois, il peut être nécessaire de transférer une table entre des bases de données au sein du même serveur. De plus, certaines méthodes sont purement théoriques, je ne les ai pas toutes testées en pratique, mais elles devraient probablement fonctionner.

Méthode -1. Les données


Peu importe à quel point cela semble évident, mais vous devez savoir quelles données vous allez transférer. Le plus souvent, les données ne sont pas stockées de la manière la plus optimale et les informations excédentaires peuvent également être stockées. Il est probable que dans votre cas particulier, vous puissiez vous passer de transférer toutes les données.

Tout d'abord, la suppression d'une colonne peut probablement vous aider, mais il s'agit d'une opération de blocage et il n'est pas toujours possible d'arrêter un service Web. Et sur Habré, il y a un article dans lequel on explique comment cela peut se faire.

Deuxièmement, n'oubliez pas la normalisation. Peut-être que certaines données peuvent être transférées dans le dictionnaire (dans le cas des lettres, il était possible de stocker non pas le corps des lettres, mais des modèles avec les données qui y sont insérées), et seul l'identifiant de ces éléments pourrait être stocké dans un grand tableau, cela peut vous libérer beaucoup d'espace.

Méthode 0. SELECT INTO


Blague =) Vous ne pouvez donc que vous mettre une base. Cependant, si nous parlons de la petite taille de la table (alors que faites-vous ici), vous pouvez essayer de transférer la base de données en utilisant cette instruction. De plus, si vous avez une base de test, vous pouvez effectuer une expérience pour évaluer le temps de transfert total en utilisant cette méthode "sur le front".

Méthode 1. Sauvegarde


La manière la plus «canonique», c'est celle-ci qui est devenue la solution à mon problème. Nous faisons une sauvegarde de la base de données contenant notre table, nous la restaurons sur un autre serveur et la supprimons de tout ce qui est inutile. De plus, s'il est possible d'arrêter le service Web, vous pouvez le redéployer en configurant l'enregistrement dans la table transférée et supprimer l'ancien * * (ici, il est fort probable qu'il puisse y avoir un moment où il sera nécessaire de lui écrire des requêtes avec des jointures, pour ce Google comment lier sql- serveurs). Si cela n'est pas possible, nous corrigeons l'identifiant de la dernière lettre (pour la synchronisation), puis nous devrons supprimer * toutes les lettres transférées (nous continuerons d'écrire dans l'ancien tableau).

* En supprimant un sujet séparé pour la conversation, il peut sembler que c'est beaucoup plus rapide que le transfert, mais ce n'est pas le cas et dans le cas général, je conseille de le supprimer par portions.

Méthode 2: MS-SQL Management Studio


Si vous avez ce studio, vous pouvez essayer d'utiliser l'outil intégré pour exporter et importer des données. Personnellement, j'ai lu sur le débordement de pile que cette chose était accrochée à une table de 60 gig et ne prenait aucun risque.

Méthode 3. Partition


Amélioration de la méthode du front. L'idée est de transférer les données de la manière habituelle avec un temporisateur entre les itérations. Vous coupez toutes les lignes en portions (par exemple, 100k chacune), transférez la portion (et vous pouvez la supprimer tout de suite, mais vous ne savez pas à quel point elle est sûre), puis endormez-vous et ainsi de suite jusqu'à la fin amère. Il est préférable de transférer depuis la fin pour ne pas avoir à synchroniser les données à la fin. La méthode est évidemment très lente, mais de cette façon vous allez tout transférer sans arrêter le service web. Il sera probablement plus pratique de l'implémenter non pas avec un script SQL, mais avec l'aide de certains ORM.

Résumé


Le processus de transfert d'une grande quantité de données prend toujours un certain temps, et vous devez vous y préparer. Il n'y a aucun moyen magique de résoudre instantanément votre problème. Dans chaque cas, vous devez tirer parti de vos volumes et de vos limites. Si aucune des méthodes ne fonctionne pour vous, demandez-vous si vous pouvez utiliser n'importe quelle combinaison d'entre elles.

À la fin, je voudrais ajouter 2 points importants.

Tout processus de transfert / suppression de lignes dans SQL est enregistré dans le journal des transactions pour pouvoir tout annuler en cas d'erreur (je supposais auparavant que cela n'était effectué que dans le cadre d'une transaction). De plus, la taille du journal est même un peu plus que la quantité de données. Assurez-vous que vous disposez de l'espace nécessaire ou désactivez la journalisation, mais ce n'est pas sûr.

Avant le transfert, vous devez vous assurer que le fichier de données et le fichier journal sont de la bonne taille, car les opérations d'extension prennent un temps considérable et les configurent en conséquence. Vous optimisez ainsi la migration.
Merci à tous ceux qui ont lu! Je serai heureux de toute critique, commentaire et clarification. Partagez vos méthodes et techniques pour travailler avec les mégadonnées, comme il s'agit souvent d'informations très importantes et nécessaires qui ne sont pas si faciles à trouver.

Source: https://habr.com/ru/post/fr434800/


All Articles