{"id":8140,"date":"2019-11-19T15:52:32","date_gmt":"2019-11-19T14:52:32","guid":{"rendered":"https:\/\/blog.capdata.fr\/?p=8140"},"modified":"2021-08-30T15:44:49","modified_gmt":"2021-08-30T14:44:49","slug":"postgresql-la-streaming-replication-en-12","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/","title":{"rendered":"PostgreSQL : la streaming replication en 12."},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8140&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8140&#038;title=PostgreSQL%20%3A%20la%20streaming%20replication%20en%2012.\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PostgreSQL%20%3A%20la%20streaming%20replication%20en%2012.&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8140\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-8141\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/11\/Capture-300x274.jpg\" alt=\"\" width=\"300\" height=\"274\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/11\/Capture-300x274.jpg 300w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/11\/Capture.jpg 368w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>La version 12 de PostgreSQL est sorti le 3 octobre dernier avec l&#8217;arriv\u00e9e de quelques nouveaut\u00e9s assez int\u00e9ressantes.<br \/>\nOn citera l&#8217;authentification renforc\u00e9e, le data checksum activable m\u00eame apr\u00e8s instance cr\u00e9\u00e9e, la reindexation concurrentielle et bien d&#8217;autres\u2026.<\/p>\n<p>Le sujet du jour qui va nous int\u00e9resser est celui de la r\u00e9plication.<br \/>\nPour rappel, depuis la version 9.0 PostgreSQL valide la replication au fil de l&#8217;eau, appel\u00e9e &#8220;streaming replication&#8221;.<\/p>\n<p>Voyons ce qui a chang\u00e9 dans cette fonctionnalit\u00e9 PostgreSQL<\/p>\n<p>&nbsp;<\/p>\n<h1><span style=\"color: #339966;\">Mise en place de la streaming replication<\/span><\/h1>\n<p>Rappelons quelques concepts.<\/p>\n<p>3 sc\u00e9narii de haute disponibilit\u00e9 existent pour PostgreSQL:<\/p>\n<ul>\n<li>La r\u00e9plication de type \u00ab\u00a0warm_standby\u00a0\u00bb. Les fichiers WAL archiv\u00e9s de l\u2019instance primaire sont envoy\u00e9s \u00e0 la standby, qui les rejouera 1 par 1. Dans cette configuration, l\u2019instance standby n\u2019est pas accessible en lecture et le retard peut \u00eatre d\u2019au moins 1 WAL de 16Mo.<\/li>\n<li>La r\u00e9plication de type \u00ab\u00a0Hot_standby\u00a0\u00bb. Fonctionnement identique \u00e0 \u00ab\u00a0warm_standby\u00a0\u00bb mais avec l\u2019instance standby ouverte en lecture seule.<\/li>\n<li>La r\u00e9plication au fil de l\u2019eau \u00ab\u00a0streaming replication\u00a0\u00bb. Dans cette configuration, toute transaction enregistr\u00e9e sur la base primaire est \u00e9galement enregistr\u00e9e sur la standby via la connexion r\u00e9seau. C\u2019est le m\u00e9canisme qui permet d\u2019avoir une standby la plus \u00e0 jour car elle se base sur le WAL courant de la base primaire. Nous pouvons perdre tout au plus 1 transaction dans le mode asynchrone.<\/li>\n<\/ul>\n<p>C&#8217;est cette derni\u00e8re que nous allons tester en version PostgreSQL 12.<br \/>\nA peu de choses pr\u00e8s, la mise en place ressemblera \u00e0 ce qui se fait depuis la version 9.<\/p>\n<h3>Pr\u00e9parer notre instance primaire<\/h3>\n<p>Tout d\u2019abord, s\u2019assurer que le fichier ${PGDATA}\/postgresql.conf dispose des valeurs suivantes pour la mise en place de la streaming replication\u00a0:<\/p>\n<ul>\n<li><span style=\"color: #339966;\">wal_level = replica\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0<\/span><\/li>\n<li><span style=\"color: #339966;\">max_wal_sender = 2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0<\/span><\/li>\n<li><span style=\"color: #339966;\">wal_keep_segments = 100\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/li>\n<li><span style=\"color: #339966;\">hot_standby = on\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Ce param\u00e8tre sera utile sur la standby pour la lecture<\/li>\n<\/ul>\n<p>Il s\u2019agira ensuite de cr\u00e9er un nouveau user\/role dans PostgreSQL qui sera utilis\u00e9 par la standby pour lire les WAL au fil de l\u2019eau.<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ psql -x -c \u201cCREATE USER repli WITH REPLICATION ENCRYPTED PASSWORD '*****'\u201d<\/span>\r\n<span style=\"color: #800080;\">CREATE ROLE<\/span><\/pre>\n<p>Nous partons du principe que notre serveur primaire a l\u2019IP <span style=\"color: #800080;\">192.168.2.43.<\/span><br \/>\nNotre serveur de secours poss\u00e8de l\u2019IP <span style=\"color: #800080;\">192.168.2.13.<\/span><\/p>\n<p>Ajouter la ligne suivante dans le \u201c<span style=\"color: #0000ff;\">pg_hba.conf<\/span>\u201d de l\u2019instance primaire :<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ vi ${PGDATA}\/pg_hba.conf<\/span>\r\n<span style=\"color: #008000;\">\u2026<\/span>\r\n<span style=\"color: #008000;\"># TYPE\u00a0   DATABASE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0   USER\u00a0\u00a0\u00a0\u00a0   ADDRESS\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  \u00a0 METHOD<\/span>\r\n<span style=\"color: #008000;\">Host\u00a0\u00a0\u00a0\u00a0\u00a0 replication\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 repli\u00a0\u00a0\u00a0\u00a0\u00a0 192.168.2.13\/32\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 md5<\/span>\r\n<span style=\"color: #008000;\">Host\u00a0\u00a0\u00a0\u00a0\u00a0 replication\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 repli\u00a0\u00a0\u00a0\u00a0\u00a0 192.168.2.43\/32\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 md5<\/span><\/pre>\n<p>L\u2019adresse IP de l\u2019h\u00f4te standby sera \u00e0 renseigner afin qu\u2019il puisse se connecter avec l\u2019utilisateur \u00ab\u00a0repli\u00a0\u00bb de l\u2019instance primaire.<br \/>\nNous renseignerons \u00e9galement l\u2019IP de l\u2019instance primaire, car en cas de changement de r\u00f4le, c\u2019est celle-ci qui r\u00e9pondra aux connexions de la nouvelle standby.<br \/>\nNe pas oublier de renseigner \u00e9galement le PASSFILE avec les informations du user \u00ab\u00a0repli\u00a0\u00bb.<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ vi $HOME\/.passfile<\/span>\r\n<span style=\"color: #800080;\">192.168.2.43:5432:*:repli:********<\/span>\r\n<span style=\"color: #800080;\">192.168.2.13:5432:*:repli:********<\/span><\/pre>\n<p>Recharger la configuration une fois ceci effectuer.<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ psql -c \"select pg_reload_conf()\"\r\n\r\n<\/span><\/pre>\n<h3>Pr\u00e9parer notre standby<\/h3>\n<p>La suite consistera \u00e0 effectuer un transfert des fichiers de l\u2019instance PostgreSQL avec Pg_basebackup (outil de backup \u00e0 chaud).<br \/>\nEffectuer une copie, avant cela, des fichiers de conf de la standby.<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ cp ${PGDATA}\/*.conf \/data\/postgres\/backup<\/span>\r\n<span style=\"color: #800080;\">STANDBY&gt; $ ls -l \/data\/postgres\/backup<\/span>\r\n<span style=\"color: #800080;\">total 44<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0 4513 Nov 14 13:13 pg_hba.conf<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0 1636 Nov 14 13:13 pg_ident.conf<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0\u00a0\u00a0 88 Nov 14 13:13 postgresql.auto.conf<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres 26754 Nov 14 13:13 postgresql.conf<\/span>\r\n\r\n<\/pre>\n<p>Puis supprimer ce qu\u2019il y\u2019a dans ${PGDATA}<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ rm -rf ${PGDATA}\/*<\/span><\/pre>\n<p>L\u2019utilisateur \u00ab\u00a0postgres\u00a0\u00bb sur la machine de standby devra \u00eatre configur\u00e9 comme celui de la machine primaire, \u00e0 savoir\u00a0:<\/p>\n<ul>\n<li>Les m\u00eames variables d\u2019environnement (reprendre le fichier .pgsql_profile du $HOME)<\/li>\n<li>La partition \/data identique pour les fichiers bases de donn\u00e9es PostgreSQL<\/li>\n<li>Le passwordfile $HOME\/.passfile avec les droits 600.<\/li>\n<\/ul>\n<p>Pour le backup via \u00ab\u00a0pg_basebackup\u00a0\u00bb, nous utiliserons l\u2019option<strong> -R<\/strong> afin de sp\u00e9cifier \u00e0 l\u2019outil que nous souhaitons faire cette sauvegarde pour une r\u00e9plication.<\/p>\n<p>La commande sera \u00e0 passer sur la standby. On sait que l\u2019adresse IP du serveur primaire est 192.168.2.43.<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ pg_basebackup -h 192.168.2.43 -U repli -D $PGDATA -Fp -Xs -P -R<\/span>\r\n<span style=\"color: #800080;\">Password:<\/span>\r\n<span style=\"color: #800080;\">32637\/32637 kB (100%), 1\/1 tablespace<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>On v\u00e9rifie ce qui est pr\u00e9sent dans le r\u00e9pertoire $PGDATA de la standby.<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ ls -l<\/span>\r\n<span style=\"color: #800080;\">total 128<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0\u00a0 224 Nov 14 13:47 backup_label<\/span>\r\n<span style=\"color: #800080;\">drwx------. 6 postgres postgres\u00a0 4096 Nov 14 13:47 base<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0\u00a0\u00a0 30 Nov 14 13:47 current_logfiles<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 global<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 log<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_commit_ts<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_dynshmem<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0 4623 Nov 14 13:47 pg_hba.conf<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0 1636 Nov 14 13:47 pg_ident.conf<\/span>\r\n<span style=\"color: #800080;\">drwx------. 4 postgres postgres\u00a0 4096 Nov 14 13:47 pg_logical<\/span>\r\n<span style=\"color: #800080;\">drwx------. 4 postgres postgres\u00a0 4096 Nov 14 13:47 pg_multixact<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_notify<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_replslot<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_serial<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_snapshots<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_stat<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_stat_tmp<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_subtrans<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_tblspc<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_twophase<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0\u00a0\u00a0\u00a0 3 Nov 14 13:47 PG_VERSION<\/span>\r\n<span style=\"color: #800080;\">drwx------. 3 postgres postgres\u00a0 4096 Nov 14 13:47 pg_wal<\/span>\r\n<span style=\"color: #800080;\">drwx------. 2 postgres postgres\u00a0 4096 Nov 14 13:47 pg_xact<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0\u00a0 262 Nov 14 13:47 postgresql.auto.conf<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres 26748 Nov 14 13:47 postgresql.conf<\/span>\r\n<span style=\"color: #800080;\">-rw-------. 1 postgres postgres\u00a0\u00a0\u00a0\u00a0 0 Nov 14 13:47 standby.signal<\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Bye Bye le &#8220;recovery.conf&#8221; !!<\/h4>\n<p>Nous sommes sur une version PostgreSQL 12, nous n\u2019avons plus de fichier \u00ab recovery.conf \u00bb comme avec les versions ant\u00e9rieures.<br \/>\nEn revanche, comme nous avons sp\u00e9cifi\u00e9 l\u2019option -R pour pg_basebackup, nous avons maintenant le fichier \u00ab\u00a0s<strong>tandby.signal\u00a0<\/strong>\u00bb dans $PGDATA.<br \/>\nCe fichier indique \u00e0 notre moteur PostgreSQL local qu\u2019il est standby.<\/p>\n<p>De plus, avec notre version PostgreSQL 12, l\u2019outil pg_basebackup a aliment\u00e9 le fichier nomm\u00e9 \u00ab\u00a0<strong>postgresql.auto.conf\u00a0<\/strong>\u00bb avec la ligne suivante\u00a0:<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ cat postgresql.auto.conf<\/span>\r\n<span style=\"color: #800080;\">primary_conninfo = 'user=repli password=****** host=192.168.2.43 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'<\/span><\/pre>\n<p>Rappelons que le fichier \u00ab<strong>\u00a0postgresql.auto.conf<\/strong>\u00a0\u00bb est un fichier de configuration embarquant automatiquement les param\u00e8tres pass\u00e9s via la commande ALTER SYSTEM .<br \/>\nCe fichier est lu par le \u00ab postmaster \u00bb juste apr\u00e8s le \u00ab<strong> postgresql.conf<\/strong> \u00bb au moment du d\u00e9marrage de l\u2019instance.<\/p>\n<p>Afin de respecter la s\u00e9curit\u00e9, il sera n\u00e9cessaire de changer cette cha\u00eene de connexion dans le fichier \u00ab <strong>postgresql.auto.conf<\/strong> \u00bb.<br \/>\nChanger la valeur \u00ab password= \u00bb par l\u2019appel au passwordfile.<br \/>\nSoit<\/p>\n<pre><span style=\"color: #800080;\">primary_conninfo = 'user=repli passfile=\/var\/lib\/pgsql\/.passfile host=192.168.2.43 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'<\/span>\r\n\r\n\r\n<\/pre>\n<h3>Synchronisation<\/h3>\n<p>L\u2019instance standby peut alors \u00eatre red\u00e9marr\u00e9e afin de se synchroniser avec la primaire.<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ pg_ctl start<\/span><\/pre>\n<p>On peut voir dans le log de d\u00e9marrage que la base standby effectue un recover du WAL 0\/6000028 -&gt; 0\/6000100. Puis elle se synchronise directement avec la primaire sur son WAL courant (0\/7000000).<\/p>\n<pre><span style=\"color: #800080;\">2019-11-14 14:00:31.689 UTC [1771] LOG:\u00a0 entering <strong>standby mode\r\n<\/strong>2019-11-14 14:00:31.693 UTC [1771] LOG:\u00a0 redo starts at 0\/6000028<\/span>\r\n<span style=\"color: #800080;\">2019-11-14 14:00:31.695 UTC [1771] LOG:\u00a0 consistent recovery state reached at 0\/6000100<\/span>\r\n<span style=\"color: #800080;\">2019-11-14 14:00:31.695 UTC [1769] LOG:\u00a0 database system is ready to accept <strong>read only connections\r\n<\/strong>2019-11-14 14:00:31.776 UTC [1775] LOG:\u00a0 <strong>started streaming WAL from primary<\/strong> at 0\/7000000 on timeline 1\r\n\r\n\r\n<\/span><\/pre>\n<h3>V\u00e9rifications<\/h3>\n<p>Sur la base primaire,\u00a0lancer la commande\u00a0:<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ psql -x -c \"select * from pg_stat_replication\"\r\n-[ RECORD 1 ]----+------------------------------\r\npid\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 2470\r\nusesysid\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 16389\r\nusename\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | repli\r\napplication_name | walreceiver\r\nclient_addr\u00a0\u00a0\u00a0\u00a0\u00a0 | 192.168.2.13\r\nclient_hostname\u00a0 |\r\nclient_port\u00a0\u00a0\u00a0\u00a0\u00a0 | 37218\r\nbackend_start\u00a0\u00a0\u00a0 | 2019-11-14 14:00:31.701736+00\r\nbackend_xmin\u00a0\u00a0\u00a0\u00a0 |\r\nstate\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | streaming\r\n<strong>sent_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/7000148<\/strong>\r\n<strong>write_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/7000148<\/strong>\r\n<strong>flush_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/7000148<\/strong>\r\n<strong>replay_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/7000148<\/strong>\r\nwrite_lag\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\r\nflush_lag\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\r\nreplay_lag\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\r\nsync_priority\u00a0\u00a0\u00a0 | 0\r\nsync_state\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | async\r\nreply_time\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 2019-11-14 14:03:02.091004+00<\/span><\/pre>\n<p>Sur l\u2019instance standby, lancer la commande<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ psql -x -c \"select * from pg_stat_wal_receiver\"\r\n-[ RECORD 1 ]---------+--------------------------------------------\r\npid\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 1775\r\nstatus\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | streaming\r\nreceive_start_lsn\u00a0\u00a0\u00a0\u00a0 | 0\/7000000\r\nreceive_start_tli\u00a0\u00a0\u00a0\u00a0 | 1\r\n<strong>received_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/7000148<\/strong>\r\nreceived_tli\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 1\r\nlast_msg_send_time\u00a0\u00a0\u00a0 | 2019-11-14 14:06:02.55313+00\r\nlast_msg_receipt_time | 2019-11-14 14:06:02.552627+00\r\n<strong>latest_end_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/7000148<\/strong>\r\nlatest_end_time\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 2019-11-14 14:00:31.776142+00\r\nslot_name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\r\nsender_host\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 192.168.2.43\r\nsender_port\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0| 5432\r\nconninfo\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | user=repli password=******** dbname=replication host=192.168.2.43 port=5432 fallback_application_name=walreceiver sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any<\/span><\/pre>\n<p><strong>\u00a0<\/strong><\/p>\n<p>On validera qu\u2019il n\u2019y ait pas de \u00ab lag \u00bb dans le processus, soit v\u00e9rifier que \u00ab <strong>received_lsn<\/strong> \u00bb = \u00ab <strong>latest_end_lsn<\/strong> \u00bb.<br \/>\nL\u2019autre test consistera \u00e0 cr\u00e9er une table sur la primaire et s\u2019assurer qu\u2019elle est pr\u00e9sente cot\u00e9 standby<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ psql -dmanuelo -Umanu<\/span>\r\n<span style=\"color: #800080;\">manuelo=# create table replicatest (nom varchar(10));<\/span>\r\n<span style=\"color: #800080;\">CREATE TABLE<\/span>\r\n<span style=\"color: #800080;\">manuelo=# insert into replicatest values ('table OK');<\/span>\r\n<span style=\"color: #800080;\">INSERT 0 1<\/span><\/pre>\n<p>Puis<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; ]$ psql -dmanuelo -Umanu<\/span>\r\n<span style=\"color: #800080;\">manuelo=# select * from replicatest;<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0 nom<\/span>\r\n<span style=\"color: #800080;\">----------<\/span>\r\n<span style=\"color: #800080;\">\u00a0table OK<\/span>\r\n<span style=\"color: #800080;\">(1 row)<\/span><\/pre>\n<p>&nbsp;<\/p>\n<h1><span style=\"color: #339966;\">Le switchover<\/span><\/h1>\n<h3><span style=\"color: #ff9900;\">Concept<\/span><\/h3>\n<p>Nous allons nous mettre dans la situation ou l\u2019on souhaite changer de r\u00f4le, c\u2019est-\u00e0-dire que notre serveur primaire va passer standby et le standby sera primaire.<\/p>\n<h3>Arr\u00eat de l&#8217;instance primaire<\/h3>\n<p>Le mode fast sera choisi pour fermer proprement les connexions.<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ <strong>pg_ctl stop -m fast\r\n<\/strong>waiting for server to shut down.... done<\/span>\r\n<span style=\"color: #800080;\">server stopped\r\n\r\n<\/span><\/pre>\n<p>Dans le log de la primaire<\/p>\n<pre><span style=\"color: #800080;\">2019-11-15 11:14:18.048 UTC [725] LOG:\u00a0 shutting down<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 11:14:18.110 UTC [725] LOG:\u00a0 checkpoint starting: shutdown immediate<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 11:14:18.183 UTC [725] LOG:\u00a0 checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.000 s, sync=0.000 s, total=0.078 s; sync files=0, longest=0.000 s, average=0.000 s; distance=16383 kB, estimate=16383 kB<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 11:14:18.287 UTC [717] LOG:\u00a0 <strong>database system is shut down<\/strong><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Sur la standby, nous irons voir quel est le dernier WAL re\u00e7u de la primaire<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ psql -x -c \u00ab select pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(), pg_last_xact_replay_timestamp(); \u00bb<\/span>\r\n<span style=\"color: #800080;\">-[ RECORD 1 ]-----------------+----------<\/span>\r\n<span style=\"color: #800080;\">pg_last_wal_receive_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/90000A0<\/span>\r\n<span style=\"color: #800080;\">pg_last_wal_replay_lsn\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 0\/90000A0<\/span>\r\n<span style=\"color: #800080;\">pg_last_xact_replay_timestamp |<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Sur la standby, le dernier WAL re\u00e7u et trait\u00e9 est le 0\/90000A0. Si celui-ci n\u2019\u00e9volue plus au cours des derni\u00e8res secondes, on passe \u00e0 la suite.<\/p>\n<p>&nbsp;<\/p>\n<h3>Changement de r\u00f4le sur la standby<\/h3>\n<p>Nous allons pouvoir effectuer le \u00ab promote \u00bb de la standby pour changer son r\u00f4le.<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; \u00a0<strong>pg_ctl promote\r\n<\/strong>waiting for server to promote.... done<\/span>\r\n<span style=\"color: #800080;\">server promoted<\/span><\/pre>\n<p>Dans le log de la standby. Nous remarquons un changement de Timeline suite \u00e0 cela. Nous sommes maintenant dans le Timeline 2 sur notre nouvelle instance primaire.<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">2019-11-15 11:22:38.853 UTC [732] LOG:\u00a0 received promote request<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 11:22:38.853 UTC [732] LOG:\u00a0 redo done at 0\/9000028<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 11:22:38.857 UTC [732] <strong>LOG:\u00a0 selected new timeline ID: 2\r\n<\/strong>2019-11-15 11:22:38.902 UTC [732] LOG:\u00a0 archive recovery complete<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 11:22:38.924 UTC [733] LOG:\u00a0 checkpoint starting: force<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 11:22:38.925 UTC [729] LOG:\u00a0 database system is ready to accept connections<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>On s\u2019assurera que notre ancienne standby n\u2019est plus en mode RECOVERY (tagger \u00e0 f comme false).<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ psql -x -c \"select pg_is_in_recovery();\"\r\n-[ RECORD 1 ]-----+--\r\npg_is_in_recovery | f<\/span><\/pre>\n<p>&nbsp;<\/p>\n<pre>Le fichier \u00ab<strong>\u00a0standby.signal<\/strong>\u00a0\u00bb a \u00e9galement disparu sur le serveur standby dans le $PGDATA.\r\n\r\n<span style=\"color: #800080;\">STANDBY&gt; $ \u00a0ls -l $PGDATA\/standby.signal<\/span>\r\n<span style=\"color: #800080;\">ls: cannot access '\/data\/postgres\/12\/stabdy.signal': No such file or directory<\/span><\/pre>\n<h3>Changement de r\u00f4le sur la primaire<\/h3>\n<p>L\u2019objectif est de passer notre ancienne instance primaire en nouvelle standby.<br \/>\nNous allons pour cela, alimenter le fichier \u00ab\u00a0<strong>postgresql.auto.conf<\/strong>\u00a0\u00bb avec la cha\u00eene de connexion vers notre nouvelle primaire.<\/p>\n<p>Il suffira d\u2019ajouter la ligne suivante\u00a0:<\/p>\n<pre><span style=\"color: #800080;\">NEW_STANDBY&gt; $ echo \u00ab\u00a0primary_conninfo = 'user=repli passfile=\/var\/lib\/pgsql\/.passfile host=<strong>192.168.2.13<\/strong> sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'\u00a0\u00bb &gt;&gt; $PGDATA\/postgresql.auto.conf<\/span><\/pre>\n<p>L\u2019IP 192.168.2.13 correspond \u00e0 notre ancienne standby qui maintenant, est notre primaire.<br \/>\nPuis ne pas oublier de cr\u00e9er le fichier \u00ab\u00a0<strong>standby.signal<\/strong>\u00a0\u00bb sur notre nouvelle instance standby.<\/p>\n<p>Rappelons qu&#8217;en version PostgreSQL 12, nous n&#8217;avons plus de &#8220;recovery.conf&#8221; \u00e0 g\u00e9rer !<\/p>\n<pre><span style=\"color: #800080;\">NEW_STANDBY&gt; $ touch $PGDATA\/standby.signal<\/span><\/pre>\n<p>Par la suite, nous red\u00e9marrerons la nouvelle standby.<\/p>\n<pre><span style=\"color: #800080;\">NEW_STANDBY&gt; $ pg_ctl start<\/span><\/pre>\n<p>La log de notre nouvelle standby donne les informations suivantes<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">2019-11-15 12:56:47.589 UTC [1777] LOG:\u00a0 entering standby mode<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 12:56:47.593 UTC [1777] LOG:\u00a0 consistent recovery state reached at 0\/90000A0<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 12:56:47.593 UTC [1777] LOG:\u00a0 invalid record length at 0\/90000A0: wanted 24, got 0<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 12:56:47.594 UTC [1775] LOG:\u00a0 database system is ready to accept read only connections<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 12:56:47.679 UTC [1781] LOG:\u00a0 fetching timeline history file for timeline 2 from primary server<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 12:56:47.684 UTC [1781] LOG:\u00a0 started streaming WAL from primary at 0\/9000000 on timeline 1<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 12:56:47.685 UTC [1781] LOG:\u00a0 replication terminated by primary server<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 12:56:47.685 UTC [1781] <strong>DETAIL:\u00a0 End of WAL reached on timeline 1 at 0\/90000A0.\r\n<\/strong>2019-11-15 12:56:47.685 UTC [1777] <strong>LOG:\u00a0 new target timeline is 2\r\n<\/strong>2019-11-15 12:56:47.686 UTC [1781] <strong>LOG:\u00a0 restarted WAL streaming at 0\/9000000 on timeline 2\r\n<\/strong>2019-11-15 12:56:47.734 UTC [1777] LOG:\u00a0 redo starts at 0\/90000A0<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Le log de notre standby nous indique bien ce changement de TIMELINE que nous avons \u00e9galement relev\u00e9 au moment du \u00ab\u00a0promote\u00a0\u00bb de la standby.<br \/>\nNous sommes actuellement dans le Timeline 2.<\/p>\n<h3>V\u00e9rfications<\/h3>\n<p>La v\u00e9rification consistera \u00e0 jouer les 2 requ\u00eates de contr\u00f4le des status sur la primaire, et la standby<\/p>\n<p><span style=\"color: #800080;\">PRIMARY&gt; $ psql -x -c \u00ab\u00a0select * from pg_stat_replication;\u00a0\u00bb<\/span><\/p>\n<p><span style=\"color: #800080;\">STANDBY&gt; $ psql -x -c \u00ab select * from pg_stat_wal_receiver ; \u00bb<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>On remarque ainsi ais\u00e9ment, que l\u2019op\u00e9ration switchover dans le cadre d\u2019instances PostgreSQL 12 est facilit\u00e9e car nous n\u2019avons que ce fichier t\u00e9moin nomm\u00e9 \u00ab<strong>\u00a0standby.signal\u00a0<\/strong>\u00bb \u00e0 recr\u00e9er manuellement.<\/p>\n<h1><span style=\"color: #339966;\">Le Failover<\/span><\/h1>\n<h3><span style=\"color: #ff9900;\">Concept<\/span><\/h3>\n<p>L\u2019op\u00e9ration de failover se produit lorsque l\u2019instance primaire devient indisponible. L\u2019instance standby n\u2019arrive plus \u00e0 communiquer avec, et l\u2019on consid\u00e8re que les connexions utilisateurs doivent \u00eatre envoy\u00e9s vers la standby. Il faut donc d\u00e9clarer celle-ci comme nouvelle primaire et casser le lien de r\u00e9plication.<\/p>\n<p>L\u2019objectif est de rendre la base standby autonome.<br \/>\nApr\u00e8s cela, une resynchronisation devra \u00eatre r\u00e9effectu\u00e9e avec un backup\/restore de l\u2019instance nouvellement primaire ou bien via l\u2019outil \u00ab\u00a0pg_rewind\u00a0\u00bb.<\/p>\n<h3>Arr\u00eat brutale de l&#8217;instance primaire<\/h3>\n<p>L\u2019arr\u00eat du serveur primaire se fait soudainement, et dans le log de l\u2019instance standby, nous voyons<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">2019-11-15 13:51:18.045 UTC [1929] LOG:\u00a0 recovery restart point at 0\/A0000D0<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:12:40.641 UTC [1932] FATAL:\u00a0 could not receive data from WAL stream: FATAL:\u00a0 terminating connection\u00a0\u00a0\u00a0 due to administrator command<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:12:40.642 UTC [1928] LOG:\u00a0 invalid record length at 0\/A0001B8: wanted 24, got 0<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:12:40.720 UTC [1969] FATAL:\u00a0 could not connect to the primary server: FATAL:\u00a0 the database system i\u00a0\u00a0 s shutting down<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:13:52.703 UTC [1973] FATAL:\u00a0 could not connect to the primary server: could not connect to server: No route to host<\/span>\r\n<span style=\"color: #800080;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Is the server running on host \"192.168.2.43\" and accepting<\/span>\r\n<span style=\"color: #800080;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 TCP\/IP connections on port 5432?<\/span>\r\n<span style=\"color: #800080;\"><strong>2019-11-15 14:13:55.775 UTC [1974] FATAL:\u00a0 could not connect to the primary server: could not connect to server: No route to host<\/strong><\/span>\r\n<span style=\"color: #800080;\"><strong>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Is the server running on host \"192.168.2.43\" and accepting<\/strong><\/span>\r\n<span style=\"color: #800080;\"><strong>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 TCP\/IP connections on port 5432?<\/strong><\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:13:58.847 UTC [1975] FATAL:\u00a0 could not connect to the primary server: could not connect to server: No route to host<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>On suppose un souci grave cot\u00e9 serveur primaire que nous ne pourrons r\u00e9soudre rapidement.<br \/>\nNous allons donc passer l\u2019instance standby en tant qu\u2019instance primaire et autonome.<\/p>\n<h3>Changement de r\u00f4le de l&#8217;instance standby<\/h3>\n<p>On passe le promote sur l\u2019instance standby<\/p>\n<pre><span style=\"color: #800080;\">STANDBY&gt; $ \u00a0<strong>pg_ctl promote\r\n<\/strong>waiting for server to promote.... done<\/span>\r\n<span style=\"color: #800080;\">server promoted<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Le log de la standby indique un changement de r\u00f4le et un nouvel ID de timeline, l\u2019ID 4.<\/p>\n<pre><span style=\"color: #800080;\">2019-11-15 14:16:19.850 UTC [1928] LOG:\u00a0 received promote request<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:16:19.850 UTC [1928] LOG:\u00a0 redo done at 0\/A000180<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:16:19.854 UTC [1928] <strong>LOG:\u00a0 selected new timeline ID: 4\r\n<\/strong>2019-11-15 14:16:19.907 UTC [1928] LOG:\u00a0 archive recovery complete<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:16:19.916 UTC [1929] LOG:\u00a0 checkpoint starting: force<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:16:19.917 UTC [1926] LOG:\u00a0 database system is ready to accept connections<\/span>\r\n<span style=\"color: #800080;\">2019-11-15 14:16:19.946 UTC [1929] LOG:\u00a0 checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.000 s, sync=0.000 s, total=0.029 s; sync files=0, longest=0.000 s, average=0.000 s; distance=0 kB, estimate=0 kB<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Le fichier \u00ab\u00a0<strong>standby.signal<\/strong>\u00a0\u00bb n\u2019est plus pr\u00e9sent dans $PGDATA et le mode recovery sur l\u2019instance est pass\u00e9 \u00e0 <strong>FALSE<\/strong><\/p>\n<pre><span style=\"color: #800080;\">NEW_PRIMARY&gt; $ ls -l standby.signal<\/span>\r\n<span style=\"color: #800080;\">ls: cannot access 'standby.signal': No such file or directory<\/span>\r\n\r\n<span style=\"color: #800080;\">NEW_PRIMARY&gt; $ psql -x -c \"select pg_is_in_recovery()\"<\/span>\r\n<span style=\"color: #800080;\">-[ RECORD 1 ]-----+--<\/span>\r\n<span style=\"color: #800080;\">pg_is_in_recovery | f<\/span><\/pre>\n<p>&nbsp;<\/p>\n<h3>La resynchronisation<\/h3>\n<p>Une fois le noeud anciennement primaire r\u00e9activ\u00e9, il s&#8217;agira de faire une op\u00e9ration de resynchonisation entre les 2 instances. Rappelons que nous avons chang\u00e9 de TIMELINE sur notre nouvelle primaire. L&#8217;ancienne doit donc \u00eatre r\u00e9actualis\u00e9e.<\/p>\n<h4><span style=\"color: #3366ff;\">L&#8217;outil &#8220;pg_rewind&#8221;<\/span><\/h4>\n<p>L\u2019outil pg_rewind est, depuis la version 9.5 de PostgreSQL, int\u00e9gr\u00e9 dans les binaires.<br \/>\nIl sera donc possible, si l\u2019instance de base de donn\u00e9es de l\u2019ancien site primaire n\u2019est pas trop endommag\u00e9e, de reprendre les blocks de donn\u00e9es qui sont diff\u00e9rents vis-\u00e0-vis de la source.<\/p>\n<p>Attention, pg_rewind comporte quelques pr\u00e9requis de fonctionnement\u00a0:<\/p>\n<ul>\n<li>Le \u00ab\u00a0data_checksum\u00a0\u00bb doit \u00eatre activ\u00e9.\u00a0Ce qui est le cas dans notre installation qui un cluster 12, donc activable ult\u00e9rieurement.<\/li>\n<li>Pg_rewind va reprendre les fichiers de conf sans regarder les diff\u00e9rences. Faire donc un backup si possible au cas o\u00f9, une fois le serveur en \u00e9chec remont\u00e9 proprement et avant de lancer la commande pg_rewind.<\/li>\n<li>Comme le serveur anciennement primaire ne s\u2019est pas arr\u00eat\u00e9 correctement ( en cas de coupure \u00e9lectrique, arr\u00eat brutale \u2026..), il sera n\u00e9cessaire de faire un arr\u00eat\/red\u00e9marrage propre de l\u2019instance \u00e0 resynchroniser.<\/li>\n<\/ul>\n<p>Avant d\u2019utiliser pg_rewind, penser, si ce n\u2019est pas fait, \u00e0 renseigner le \u00ab\u00a0pg_hba.conf\u00a0\u00bb afin que les n\u0153uds acceptent les connexions depuis l\u2019utilisateur \u00ab\u00a0postgres\u00a0\u00bb avec le mode md5. Ajouter ces lignes sur les 2 instances.<\/p>\n<pre><span style=\"color: #993366;\"># connexions pour pg_rewind<\/span>\r\n<span style=\"color: #993366;\">host\u00a0\u00a0\u00a0 all\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 postgres\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 192.168.2.13\/32\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 md5<\/span>\r\n<span style=\"color: #993366;\">host\u00a0\u00a0\u00a0 all\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 postgres\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 192.168.2.43\/32\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 md5<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Faire un \u00ab\u00a0reload\u00a0\u00bb de la configuration apr\u00e8s cette modification.<\/p>\n<pre><span style=\"color: #993366;\">$ psql -c \u00ab\u00a0select pg_reload_conf()\u00a0;\u00a0\u00bb\r\n\r\n<\/span><\/pre>\n<h3>Remonter l&#8217;ancienne primaire et lancer la reconstruction via &#8220;pg_admin&#8221;<\/h3>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #993366;\">OLD_PRIMARY&gt; $ pg_ctl start<\/span><\/pre>\n<p>Arr\u00eater la de fa\u00e7on propre.<\/p>\n<pre><span style=\"color: #993366;\">OLD_PRIMARY&gt; $ pg_ctl stop -m fast<\/span>\r\n<span style=\"color: #993366;\">waiting for server to shut down.... done<\/span>\r\n<span style=\"color: #993366;\">server stopped<\/span><\/pre>\n<p>Il sera possible d\u2019\u00e9valuer l\u2019op\u00e9ration en utilisant l\u2019option \u00ab\u00a0&#8211;dry-run\u00a0\u00bb de pg_rewind.<\/p>\n<pre><span style=\"color: #993366;\">OLD_PRIMARY&gt; $ pg_rewind --target-pgdata=\/data\/postgres\/12 --source-server=\"host=192.168.2.13 port=5432 user=postgres passfile=\/var\/lib\/pgsql\/.passfile\" <span style=\"color: #0000ff;\"><strong>--dry-run<\/strong><\/span> --progress\r\npg_rewind: connected to server<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: servers diverged at WAL location 0\/A0001B8 on timeline 3<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: rewinding from last common checkpoint at 0\/A000108 on timeline 3<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: reading source file list<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: reading target file list<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: reading WAL in target<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: need to copy 149 MB (total source directory size is 175 MB)<\/span>\r\n<span style=\"color: #993366;\">152678\/152678 kB (100%) copied<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: creating backup label and updating control file<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: syncing target data directory<\/span>\r\n<span style=\"color: #993366;\">pg_rewind: Done!<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Lancer ensuite la reconstruction via pg_admin sans le dry&#8211;run.<\/p>\n<pre><span style=\"color: #800080;\">OLD_PRIMARY&gt; $ \u00a0\u00a0pg_rewind --target-pgdata=\/data\/postgres\/12 --source-server=\"host=192.168.2.13 port=5432 user=postgres passfile=\/var\/lib\/pgsql\/.passfile\" --progress \r\npg_rewind: connected to server<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: servers diverged at WAL location 0\/A0001B8 on timeline 3<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: rewinding from last common checkpoint at 0\/A000108 on timeline 3<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: reading source file list<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: reading target file list<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: reading WAL in target<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: need to copy 149 MB (total source directory size is 175 MB)<\/span>\r\n<span style=\"color: #800080;\">152678\/152678 kB (100%) copied<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: creating backup label and updating control file<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: syncing target data directory<\/span>\r\n<span style=\"color: #800080;\">pg_rewind: Done!<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>L\u2019instance PostgreSQL, nouvelle standby, devra \u00eatre red\u00e9marr\u00e9e et on validera la synchronisation.<br \/>\nLes commandes suivantes seront utilis\u00e9es sur la primaire et la standby.<\/p>\n<pre><span style=\"color: #800080;\">PRIMARY&gt; $ psql -x -c \u00ab\u00a0select * from pg_stat_replication;\u00a0\u00bb<\/span>\r\n\r\n<span style=\"color: #800080;\">STANDBY&gt; $ psql -x -c \u00ab select * from pg_stat_wal_receiver ; \u00bb<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>n&#8217;h\u00e9sitez pas \u00e0 faire des commentaires \u00e0 ce sujet.<\/p>\n<p>Emmanuel RAMI<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8140&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8140&#038;title=PostgreSQL%20%3A%20la%20streaming%20replication%20en%2012.\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PostgreSQL%20%3A%20la%20streaming%20replication%20en%2012.&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8140\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>&nbsp; La version 12 de PostgreSQL est sorti le 3 octobre dernier avec l&#8217;arriv\u00e9e de quelques nouveaut\u00e9s assez int\u00e9ressantes. On citera l&#8217;authentification renforc\u00e9e, le data checksum activable m\u00eame apr\u00e8s instance cr\u00e9\u00e9e, la reindexation concurrentielle et bien d&#8217;autres\u2026. Le sujet du&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":32,"featured_media":8141,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[266],"tags":[],"class_list":["post-8140","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-postgresql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PostgreSQL : la streaming replication en 12. - Capdata TECH BLOG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL : la streaming replication en 12. - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"&nbsp; La version 12 de PostgreSQL est sorti le 3 octobre dernier avec l&#8217;arriv\u00e9e de quelques nouveaut\u00e9s assez int\u00e9ressantes. On citera l&#8217;authentification renforc\u00e9e, le data checksum activable m\u00eame apr\u00e8s instance cr\u00e9\u00e9e, la reindexation concurrentielle et bien d&#8217;autres\u2026. Le sujet du&hellip; Continuer la lecture &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2019-11-19T14:52:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-08-30T14:44:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/11\/Capture.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"368\" \/>\n\t<meta property=\"og:image:height\" content=\"336\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Emmanuel RAMI\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Emmanuel RAMI\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\"},\"author\":{\"name\":\"Emmanuel RAMI\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae\"},\"headline\":\"PostgreSQL : la streaming replication en 12.\",\"datePublished\":\"2019-11-19T14:52:32+00:00\",\"dateModified\":\"2021-08-30T14:44:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\"},\"wordCount\":1810,\"commentCount\":11,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"articleSection\":[\"PostgreSQL\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\",\"name\":\"PostgreSQL : la streaming replication en 12. - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2019-11-19T14:52:32+00:00\",\"dateModified\":\"2021-08-30T14:44:49+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL : la streaming replication en 12.\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae\",\"name\":\"Emmanuel RAMI\",\"sameAs\":[\"https:\/\/blog.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/erami\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PostgreSQL : la streaming replication en 12. - Capdata TECH BLOG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/","og_locale":"fr_FR","og_type":"article","og_title":"PostgreSQL : la streaming replication en 12. - Capdata TECH BLOG","og_description":"&nbsp; La version 12 de PostgreSQL est sorti le 3 octobre dernier avec l&#8217;arriv\u00e9e de quelques nouveaut\u00e9s assez int\u00e9ressantes. On citera l&#8217;authentification renforc\u00e9e, le data checksum activable m\u00eame apr\u00e8s instance cr\u00e9\u00e9e, la reindexation concurrentielle et bien d&#8217;autres\u2026. Le sujet du&hellip; Continuer la lecture &rarr;","og_url":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2019-11-19T14:52:32+00:00","article_modified_time":"2021-08-30T14:44:49+00:00","og_image":[{"width":368,"height":336,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/11\/Capture.jpg","type":"image\/jpeg"}],"author":"Emmanuel RAMI","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"Emmanuel RAMI","Dur\u00e9e de lecture estim\u00e9e":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/"},"author":{"name":"Emmanuel RAMI","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae"},"headline":"PostgreSQL : la streaming replication en 12.","datePublished":"2019-11-19T14:52:32+00:00","dateModified":"2021-08-30T14:44:49+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/"},"wordCount":1810,"commentCount":11,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"articleSection":["PostgreSQL"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/","url":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/","name":"PostgreSQL : la streaming replication en 12. - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2019-11-19T14:52:32+00:00","dateModified":"2021-08-30T14:44:49+00:00","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-la-streaming-replication-en-12\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL : la streaming replication en 12."}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae","name":"Emmanuel RAMI","sameAs":["https:\/\/blog.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/erami\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/8140","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/32"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=8140"}],"version-history":[{"count":15,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/8140\/revisions"}],"predecessor-version":[{"id":8794,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/8140\/revisions\/8794"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/8141"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=8140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=8140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=8140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}