D'un point de vue d'oiseau, il semblerait que lorsqu'il s'agit de migrer les charges de travail PostgreSQL vers le cloud, le choix du fournisseur de cloud ne devrait faire aucune différence. Prêt à l'emploi, PostgreSQL facilite la réplication des données, sans temps d'arrêt, via la réplication logique, bien qu'avec certaines restrictions. Afin de rendre leur offre de services plus attrayante, les fournisseurs de cloud peuvent mettre en place certaines de ces restrictions. Alors que nous commençons à réfléchir aux différences entre les versions, la compatibilité, les limites, les limitations et les performances de PostgreSQL disponibles, il devient clair que les services de migration sont des facteurs clés de l'offre de services globale. Il ne s'agit plus du « on le propose, on le migre ». C'est devenu plus "nous l'offrons, nous le migrons, avec le moins de limitations".
La migration est importante pour les petites comme pour les grandes organisations. Il ne s'agit pas tant de la taille du cluster PostgreSQL que du temps d'arrêt acceptable et de l'effort post-migration.
Sélectionner une stratégie
La stratégie de migration doit tenir compte de la taille de la base de données, du lien réseau entre la source et la cible, ainsi que des outils de migration proposés par le fournisseur de cloud.
Matériel ou logiciel ?
Tout comme les clés USB et les DVD des débuts d'Internet, dans les cas où la bande passante du réseau n'est pas suffisante pour transférer les données à la vitesse souhaitée, les fournisseurs de cloud proposent des solutions matérielles, capables transporter jusqu'à des centaines de pétaoctets de données. Vous trouverez ci-dessous les solutions actuelles de chacun des trois grands :
Un tableau pratique fourni par Google indiquant les options disponibles :
L'appareil GCP est Transfer Appliance
Une recommandation similaire d'Azure basée sur la taille des données par rapport à la bande passante du réseau :
L'appliance Azure est une boîte de données
Vers la fin de sa page sur les migrations de données, AWS donne un aperçu de ce à quoi nous pouvons nous attendre, ainsi que sa recommandation de la solution :
Dans les cas où la taille de la base de données dépasse 100 Go et la bande passante réseau limitée, AWS suggère un solution matérielle.
L'appliance AWS est Snowball Edge
Exportation/Importation de données
Les organisations qui tolèrent les temps d'arrêt peuvent bénéficier de la simplicité des outils communs fournis par PostgreSQL prêts à l'emploi. Cependant, lors de la migration des données d'un fournisseur de cloud (ou d'hébergement) vers un autre fournisseur de cloud, méfiez-vous du coût de sortie.
AWS
Pour tester les migrations, j'ai utilisé une installation locale de ma base de données Nextcloud exécutée sur l'un de mes serveurs de réseau domestique :
postgres=# select pg_size_pretty(pg_database_size('nextcloud_prod'));
pg_size_pretty
----------------
58 MB
(1 row)
nextcloud_prod=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------------------------------+-------+-----------
public | awsdms_ddl_audit | table | s9sdemo
public | oc_accounts | table | nextcloud
public | oc_activity | table | nextcloud
public | oc_activity_mq | table | nextcloud
public | oc_addressbookchanges | table | nextcloud
public | oc_addressbooks | table | nextcloud
public | oc_appconfig | table | nextcloud
public | oc_authtoken | table | nextcloud
public | oc_bruteforce_attempts | table | nextcloud
public | oc_calendar_invitations | table | nextcloud
public | oc_calendar_reminders | table | nextcloud
public | oc_calendar_resources | table | nextcloud
public | oc_calendar_resources_md | table | nextcloud
public | oc_calendar_rooms | table | nextcloud
public | oc_calendar_rooms_md | table | nextcloud
...
public | oc_termsofservice_terms | table | nextcloud
public | oc_text_documents | table | nextcloud
public | oc_text_sessions | table | nextcloud
public | oc_text_steps | table | nextcloud
public | oc_trusted_servers | table | nextcloud
public | oc_twofactor_backupcodes | table | nextcloud
public | oc_twofactor_providers | table | nextcloud
public | oc_users | table | nextcloud
public | oc_vcategory | table | nextcloud
public | oc_vcategory_to_object | table | nextcloud
public | oc_whats_new | table | nextcloud
(84 rows)
The database is running PostgreSQL version 11.5:
postgres=# select version();
version
------------------------------------------------------------------------------------------------------------
PostgreSQL 11.5 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1), 64-bit
(1 row)
J'ai également créé un utilisateur PostgreSQL à utiliser par AWS DMS qui est le service d'Amazon pour importer PostgreSQL dans Amazon RDS :
postgres=# \du s9sdemo
List of roles
Role name | Attributes | Member of
-----------+------------+-------------
s9sdemo | | {nextcloud}
AWS DMS offre de nombreux avantages, exactement comme on peut s'y attendre d'une solution gérée dans le cloud :
- mise à l'échelle automatique (stockage uniquement, car l'instance de calcul doit être correctement dimensionnée)
- provisionnement automatique
- modèle de paiement à l'utilisation
- basculement automatique
Cependant, le maintien de la cohérence des données pour une base de données en direct est un meilleur effort. Une cohérence à 100 % n'est atteinte que lorsque la base de données est en mode lecture seule, ce qui est une conséquence de la manière dont les modifications de la table sont capturées.
En d'autres termes, les tables ont un basculement à un instant donné :
Comme pour tout dans le cloud, il y a un coût associé au service de migration.
Afin de créer l'environnement de migration, suivez le guide de démarrage pour configurer une instance de réplication, une source, un endpoint cible et une ou plusieurs tâches.
Instance de réplication
La création de l'instance de réplication est simple pour toute personne familiarisée avec les instances EC2 sur AWS :
Le seul changement par rapport aux valeurs par défaut a été de sélectionner AWS DMS 3.3.0 ou plus tard car mon moteur PostgreSQL local était 11.5 :
Et voici la liste des versions AWS DMS actuellement disponibles :
Les grandes installations doivent également tenir compte des limites AWS DMS :
Il existe également un ensemble de limitations qui sont une conséquence de la réplication logique PostgreSQL restrictions. Par exemple, AWS DMS ne migrera pas les objets secondaires :
Il convient de mentionner que dans PostgreSQL tous les index sont des index secondaires, et que n'est pas une mauvaise chose, comme indiqué dans cette discussion plus détaillée.
Point de terminaison source
Suivez l'assistant pour créer le point de terminaison source :
Dans le scénario d'installation Configuration d'un réseau vers un VPC à l'aide d'Internet, mon Le réseau domestique a nécessité quelques ajustements afin de permettre à l'adresse IP du point de terminaison source d'accéder à mon serveur interne. Tout d'abord, j'ai créé une redirection de port sur le routeur périphérique (173.180.222.170) pour envoyer le trafic sur le port 30485 vers ma passerelle interne (10.11.11.241) sur le port 5432 où je peux affiner l'accès en fonction de l'adresse IP source via les règles iptables. De là, le trafic réseau passe par un tunnel SSH vers le serveur Web exécutant la base de données PostgreSQL. Avec la configuration décrite, le client_addr dans la sortie de pg_stat_activity apparaîtra comme 127.0.0.1.
Avant d'autoriser le trafic entrant, les journaux iptables affichent 12 tentatives depuis l'instance de réplication à l'adresse ip=3.227.167.58) :
Jan 19 17:35:28 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23973 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:35:29 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23974 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:35:31 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23975 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:35:35 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23976 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:35:48 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4328 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:35:49 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4329 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:35:51 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4330 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:35:55 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4331 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:36:08 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8298 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:36:09 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8299 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:36:11 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8300 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Jan 19 17:36:16 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8301 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0
Une fois l'adresse IP du point de terminaison source autorisée (3.227.167.58), le test de connexion réussit et la configuration du point de terminaison source est terminée. Nous avons également une connexion SSL afin de crypter le trafic via les réseaux publics. Cela peut être confirmé sur le serveur PostgreSQL à l'aide de la requête ci-dessous ainsi que dans la console AWS :
postgres=# SELECT datname, usename, client_addr, ssl, cipher, query, query_start FROM pg_stat_activity a, pg_stat_ssl s where a.pid=s.pid and usename = 's9sdemo';
datname | usename | client_addr | ssl | cipher | query | query_start
---------+---------+-------------+-----+--------+-------+-------------
(0 rows)
… puis regardez pendant l'exécution de la connexion à partir de la console AWS. Les résultats devraient ressembler à ce qui suit :
postgres=# \watch
Sun 19 Jan 2020 06:50:51 PM PST (every 2s)
datname | usename | client_addr | ssl | cipher | query | query_start
----------------+---------+-------------+-----+-----------------------------+------------------------------------------------------------------------------------+-------------------------------
nextcloud_prod | s9sdemo | 127.0.0.1 | t | ECDHE-RSA-AES256-GCM-SHA384 | select cast(setting as integer) from pg_settings where name = 'server_version_num' | 2020-01-19 18:50:51.463496-08
(1 row)
…alors que la console AWS devrait signaler un succès :
Comme indiqué dans la section des prérequis, si nous choisissons l'option de migration Full load , réplication en cours, nous devrons modifier les autorisations de l'utilisateur PostgreSQL. Cette option de migration nécessite des privilèges de superutilisateur, j'ai donc ajusté les paramètres de l'utilisateur PostgreSQL créé précédemment :
nextcloud_prod=# \du s9sdemo
List of roles
Role name | Attributes | Member of
-----------+------------+-----------
s9sdemo | Superuser | {}
Le même document contient des instructions pour modifier postgresql.conf. Voici une différence par rapport à l'original :
--- a/var/lib/pgsql/data/postgresql.conf
+++ b/var/lib/pgsql/data/postgresql.conf
@@ -95,7 +95,7 @@ max_connections = 100 # (change requires restart)
# - SSL -
-#ssl = off
+ssl = on
#ssl_ca_file = ''
#ssl_cert_file = 'server.crt'
#ssl_crl_file = ''
@@ -181,6 +181,7 @@ dynamic_shared_memory_type = posix # the default is the first option
# - Settings -
+wal_level = logical
#wal_level = replica # minimal, replica, or logical
# (change requires restart)
#fsync = on # flush data to disk for crash safety
@@ -239,6 +240,7 @@ min_wal_size = 80MB
#max_wal_senders = 10 # max number of walsender processes
# (change requires restart)
#wal_keep_segments = 0 # in logfile segments; 0 disables
+wal_sender_timeout = 0
#wal_sender_timeout = 60s # in milliseconds; 0 disables
#max_replication_slots = 10 # max number of replication slots
@@ -451,6 +453,7 @@ log_rotation_size = 0 # Automatic rotation of logfiles will
#log_duration = off
#log_error_verbosity = default # terse, default, or verbose messages
Enfin, n'oubliez pas d'ajuster les paramètres de pg_hba.conf afin d'autoriser la connexion SSL à partir de l'adresse IP de l'instance de réplication.
Nous sommes maintenant prêts pour la prochaine étape.
Point de terminaison cible
Suivez l'assistant pour créer le point de terminaison cible :
Cette étape suppose que l'instance RDS avec le point de terminaison spécifié existe déjà avec la base de données vide nextcloud_awsdms. La base de données peut être créée lors de la configuration de l'instance RDS.
À ce stade, si la mise en réseau AWS est correctement configurée, nous devrions être prêts à exécuter le test de connexion :
Avec l'environnement en place, il est maintenant temps de créer la tâche de migration :
Tâche de migration
Une fois l'assistant terminé, la configuration ressemble à ceci :
...et la deuxième partie de la même vue :
Une fois la tâche démarrée, nous pouvons surveiller la progression — ouvrez la tâche détails et faites défiler jusqu'à Table Statistics :
AWS DMS utilise le schéma mis en cache pour migrer les tables de la base de données. Pendant que la migration progresse, nous pouvons continuer à "surveiller" les requêtes sur la base de données source et le journal des erreurs PostgreSQL, en plus de la console AWS :
En cas d'erreurs, l'état d'échec est affiché dans la console :
Un endroit pour chercher des indices est CloudWatch, bien que pendant mes tests les journaux n'a pas été publié, ce qui pourrait n'être qu'un autre problème dans la version bêta d'AWS DMS 3.3.0, comme il s'est avéré être vers la fin de cet exercice :
La progression de la migration est bien affichée dans la console AWS DMS :
Une fois la migration terminée, examinez une fois de plus le journal des erreurs PostgreSQL , révèle un message surprenant :
Ce qui semble se passer, c'est que dans PostgreSQL 9.6, 10 la table pg_class contient la colonne nommée relhaspkey, mais ce n'est pas le cas dans 11. Et c'est le problème de la version bêta d'AWS DMS 3.3.0 auquel je faisais référence plus tôt.
GCP
L'approche de Google est basée sur l'outil open source PgBouncer. L'excitation a été de courte durée, car la documentation officielle parle de la migration de PostgreSQL vers un environnement de moteur de calcul.
De nouvelles tentatives pour trouver une solution de migration vers Cloud SQL qui ressemble à AWS DMS ont échoué. Les stratégies de migration de la base de données ne contiennent aucune référence à PostgreSQL :
Les installations PostgreSQL sur site peuvent être migrées vers Cloud SQL à l'aide des services de l'un des partenaires Google Cloud.
Une solution potentielle peut être PgBouncer vers Cloud SQL, mais cela n'entre pas dans le cadre de ce blog.
Services cloud Microsoft (Azure)
Afin de faciliter la migration des charges de travail PostgreSQL sur site vers la base de données Azure gérée pour PostgreSQL, Microsoft fournit Azure DMS qui, selon la documentation, peut être utilisé pour migrer avec un temps d'arrêt minimal. Le didacticiel Migrer PostgreSQL vers Azure Database pour PostgreSQL en ligne à l'aide de DMS décrit ces étapes en détail.
La documentation Azure DMS décrit en détail les problèmes et les limites associés à la migration des charges de travail PostgreSQL vers Azure.
Une différence notable par rapport à AWS DMS est l'obligation de créer manuellement le schéma :
Une démo de ceci sera le sujet d'un futur blog. Restez à l'écoute.