Auteur/autrice : bastien

Radioamateur & sportif.

The PHP framework interoperability, why is important in 2022 ?

Hello everybody !

Let me show you how we can build a game with PHP here a small train game ( user interopt via web interface, system can be control via human small interface ), with 2 sytstem’s : php-symfony and php-crx-framework.

When you write a lib, you can use it in different way, like direct call, virtualisation call what ever the sense,
interoperability is the most important for a framework.

Few years, i’ve started my own framework and i discover the important
of that. Here is a short code for interoperability with a framework.

I start by install PHP composer packages manager on my LINUX by :

$> php -r « copy(‘’, ‘composer-setup.php’); »
$> php composer-setup.php –install-dir=/usr/local/bin –filename=composer
$> chmod +x /usr/local/bin/composer
$> composer -v
$> composer self-upgrade

In this case, composer is install globally on the system LINUX.
For DEBIAN OS, i simply do that :

$> aptitude search composer
$> composer -v

Witch install :

composer jsonlint{a} php-composer-ca-bundle{a} php-composer-semver{a} php-composer-spdx-licenses{a} php-composer-xdebug-handler{a} php-json-schema{a}
php-psr-container{a} php-psr-log{a} php-react-promise{a} php-symfony-console{a} php-symfony-filesystem{a} php-symfony-finder{a} php-symfony-polyfill-php80{a}
php-symfony-process{a} php-symfony-service-contracts{a}

Get: 1 http://// bullseye/main amd64 php-composer-ca-bundle all 1.2.9-1 [11.0 kB]
Get: 2 bullseye/main amd64 php-composer-semver all 3.2.4-2 [20.4 kB]
Get: 3 bullseye/main amd64 php-composer-spdx-licenses all 1.5.5-2 [13.3 kB]
Get: 4 bullseye/main amd64 php-psr-log all 1.1.3-2 [9232 B]
Get: 5 bullseye/main amd64 php-composer-xdebug-handler all 1.4.5-1 [16.9 kB]
Get: 6 bullseye/main amd64 php-json-schema all 5.2.10-2 [37.8 kB]
Get: 7 bullseye/main amd64 jsonlint all 1.8.3-2 [13.5 kB]
Get: 8 bullseye/main amd64 php-symfony-polyfill-php80 all 1.22.1-1 [9976 B]
Get: 9 bullseye/main amd64 php-psr-container all 1.0.0-2 [3436 B]
Get: 10 bullseye/main amd64 php-symfony-service-contracts all 1.1.10-2 [8052 B]
Get: 11 bullseye/main amd64 php-symfony-console all 4.4.19+dfsg-2 [82.7 kB]
Get: 12 bullseye/main amd64 php-symfony-filesystem all 4.4.19+dfsg-2 [26.1 kB]
Get: 13 bullseye/main amd64 php-symfony-finder all 4.4.19+dfsg-2 [31.4 kB]
Get: 14 bullseye/main amd64 php-symfony-process all 4.4.19+dfsg-2 [36.3 kB]
Get: 15 bullseye/main amd64 php-react-promise all 2.7.0-2 [18.6 kB]
Get: 16 bullseye/main amd64 composer all 2.0.9-2 [407 kB]

Now here i install composer is specific way for my train « game » call for example « smalltraingame »,
witch can be stored on COMPOSER app store or on another part of the Internet network :

$> php -r « copy(‘’, ‘composer-setup.php’); »
$> cd /home/hosting/www_root/ && mkdir -p bin
$> php composer-setup.php –install-dir=bin –filename=composer
$> chmod +x bin/composer
$> composer self-upgrade
$> cd /home/hosting/www_root/
$> mkdir /home/hosting/www_root/
$> composer require frvmcontrolapp/Box2Interuptors
$> composer require frvmcontrolapp/GameSystemControlFr

$> composer require frvmcontrolapp/VRControlerFr
$> composer require frvmcontrolapp/RandomSystem

Of course, composer is in my PATH, here this few command update my : composer.json
Here is my gaming engine example of my header  :

namespace crxcms;
use \crx\crxOrchestratorV0;
use \crx\crxDataSource;
use \crx\TrainGame;
use \crx\TrainController;
use \crx\VRControl;
$p = _APPLI_MAIN_MODULES_PATH_.’myModule/php-ml-master/src’;
$ia = new crxLoaderForLib($p,’frvmcontrolapp’);
use frvmcontrolapp/GameSystemControlFr;
use frvmcontrolapp/VRControlerFr;
use frvmcontrolapp/RandomSystem;
use frvmcontrolapp/BoxWith3Interrupteurs

Now like in CPP, i can declare my engine :

And now in my code i can do :
class VRControler{
function __construct(){
function run(){
$orchestrator = new \crx\crxOrchestratorV0();
if($orchestrator->status()==5){ return array(‘ag1′,’step1’);}
if($orchestrator->status()){ return array(‘ag2′,’step2’);}
if($orchestrator->status()){ return array(‘ag3′,’step1’);}

class TrainGame{
function __construct(){}
function __runInstance(){

$dbi = \crx\crxDataSource::getDs(‘mysql2’);
$user1 = new \crx\crxUser(‘A’,’20’);
$user2 = new \crx\crxUser(‘B’,’20’);
$randomSystem = new RandomSystem();
$my_object = new Train(‘red’,’8′,’tgv’);
$control = new BoxWith3Interrupteurs();
$vr_system = new \crx\VRControl($user1,$user2,$randomSystem,$control);
$crxGame = new \crx\GameStd($my_object,$vr_system,$users);




Here :
=> TrainGame is one of my PHP class.
=> TrainController is a simple SERIAL PORT reader for example ( with custom protocol based on 2 interuptors button system ).
=> crxOrchestrator system engine use : TCP-IP/SEMAPHORES control system loop.

So finnaly we got this gaming system :

PHP framework A => Call composer librairies (framework B) => Call Python ( machine learning system )

A bientôt !

Sources :

Nouvelle interface WEB CRX CLOUD

Bonjour à tous,

Après un peu plus de 4 mois de boulot, la nouvelle interface WEB de CRX est en ligne,
pour le 7ème anniversaire de la version HAM ( et les 16 de la version 11M )  :

Un grand merci aux personnes qui ont participées à cette nouvelle version.
73 à tous et bon dimanche,

HAM remote station on mobile phone.

Hello everyone,

Today I implemented the remote station on the CRX phone application (

It works well i made few QSO’s in UHF with the remote station, with control in a browser and sound via MUMBLE.

73 to all,

PS: I am using a CHROME WEB browser, and a RASPBERRY PI.
For people who want to test, you have to configure first your remote station on PC website ( 



Take notes in the cloud !

Hello to all,

« My notes » app is a new feature available into CRX-LOGBOOK :

-> For the moment, a note is limited to ~ 6000 caracters (limitation is only the WEB call here).
-> All the notes are protected by encryption (with your PIN code from 4 to 127 caracters).
-> Remember to write down this code or memorize it, because it is not possible to recover it and therefore to read your notes without this code !
-> Pin code is store into your webrowser via a COOKIE (encrypted by security) and for 1 year.
-> So if you change your browser, you will have to re-enter your pin code.
-> When you clic on « Exit » link, COOKIE will be erased.
-> If you enter the wrong code, the notes are visible but simply empty.

From a technical point of view :

-> Encryption is done on server side, not client side.

-> The cookie containing the pin code and the note are encrypted via AEAD (authenticated encryption with additional data),
with the PHP « SODIUM » library : crypto_aead_xchacha20poly1305_ietf  ( )

as input :
-> the message encrypted here the content of your note (in plain text).
-> the pin code (number or letter of 4 minimum, you can put a lot more).
-> the nounce (Number used only once) generated via: random_bytes SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES
-> a unique encryption key linked to the CRX site, here generated via: random_bytes : SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES

Of course I use a base 64 envelope via php base64_encode to store the global key in configuration.

Good weekend, 73!


Connect CQRLOG logbook to CRX-LOGBOOK.

Hello everyone,

The LINUX CQRLOG Logbook is now compatible with the « CRXLOGBOOK » (online Logbook cloud instance).

=> It allows new QSOs from CQRLOG to be forwarded in the online log, the system operates in « offline » mode (portable/dx operation)
and can be launched manually or automatically via a LINUX CRON.

=> It works with all versions of CQRLOG and is independent.

=> It’s available here :


Automatisation de la gestion des utilisateurs et des mises à jour.


Ce petit article à pour but de présenter « une gestion des utilisateurs et des mises à jour système » ( ici sous LINUX/DEBIAN ),
avec un système centralisé appelé « ANSIBLE ».

ANSIBLE permet via le protocole SSH de gérer des configurations et d’automatiser des actions (comme des installations d’applications par exemple),
sur des serveurs « distants » ceci est aussi appelé « infrastructure as code ».

Prérequis :

ANSIBLE est installé sur ma machine locale et aussi sur mon serveur distant,
pour commencer j’ai créé le référentiel de mes machines  » /home/bba/hosts  » :

bba@crx-ans01 ~ $ cat hosts

Soit un serveur « crx-dev01.crxcluster.lan » qui se trouve dans un groupe appelé « webserversdev ».
On n’est pas obligé d’utiliser un FQDN, une IP suffit.

Voici ma configuration ANSIBLE :

bba@crx-ans01 ~ $ cat ansible.cfg
interpreter_python = auto_silent
inventory       =  /home/bba/hosts

bba@crx-ans01 ~ $ ansible-config dump --only-changed
DEFAULT_HOST_LIST(/home/bba/ansible.cfg) = [u'/home/bba/hosts']
INTERPRETER_PYTHON(/home/bba/ansible.cfg) = auto_silent

La commande « only-changed » m’assure que ANSIBLE a bien parsé mon fichier de configuration,
Et cela va m’afficher que les variables qui changent par rapport à la configuration globale ( /etc/ansible/ansible.cfg ).

Notez que :
-> interpreter_python = auto_silent   :   permet d’éviter les messages de ce type au lancement d’un playbook :

[WARNING]: Platform linux on host crx-dev01.crxcluster.lan is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See for more information.

1. Gestion des utilisateurs

L’objectif ici est de gérer mes utilisateurs avec ANSIBLE, les clés SSH sont dans ce dossier « ssh-keys ».
Je commence donc par créer ce dossier à la racine de mon projet :


Ensuite j’ajoute la clé publique SSH pour chaque utilisateur que je vais déployer, ici mon utilisateur est « f4eyq » :


Maintenant je vais créer un script ANSIBLE aussi appelé « playbook », pour utiliser ce dossier et créer / supprimer un utilisateur.
=> L’instruction « become: yes » va simplement exécuter les commandes en « root » :

bba@crx-ans01 ~ $ cat add-remote-user-ssh.yml
- name: Create new user
  hosts: all
  #  vars:
  #  - user_password: 'test'
  #  - user_login: 'f4eyq'

  gather_facts: no
  become: yes

    - name: Add a new user
          name: "{{ user_login }}"
          shell: /bin/bash

          password: "{{ user_password | password_hash('sha512') }}"
          groups: sudo

          #remove user :
          #state: absent
          #remove: yes

    - name: Deploy SSH Key
        user: "{{ user_login }}"
        key: "{{ lookup('file', 'ssh-keys-dep/{{ user_login }}.pub') }}"
        state: present
        exclusive: True

Je peux ensuite l’appeler pour créer mon utilisateur « f4eyq » avec mon mot de passe « test »,
cela va créer l’utilisateur le mettre dans le groupe que j’ai indiqué et cela va créer son home enfin déployer sa clé SSH :

bba@crx-ans01 ~ $ ansible-playbook add-remote-user-ssh.yml --limit webserversdev  --extra-vars "user_password=test user_login=f4eyq"

PLAY [Create new user] ****************************************************************************************************************************************************************************************

TASK [Add a new user] *****************************************************************************************************************************************************************************************
changed: [crx-dev01.crxcluster.lan]

TASK [Deploy SSH Key] *****************************************************************************************************************************************************************************************
changed: [crx-dev01.crxcluster.lan]

PLAY RECAP ****************************************************************************************************************************************************************************************************
crx-dev01.crxcluster.lan   : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Si par le suite je dois mettre la clé à jour, j’édite simplement le fichier dans le dossier « ssh-keys-dep » et relance le playbook.
Enfin pour supprimer l’utilisateur je décommente ceci dans le playbook :

          #state: absent
          #remove: yes

Et je relance le tout.

Notez que :
-> le home de l’utilisateur est supprimé sur le serveur cible ainsi que toute existence sur le serveur ( passwd/ group ) donc faut bien contrôler vos commandes 🙂
-> pour changer le mot de passe de l’utilisateur rejouer simplement le playbook avec un nouveau mot de passe.

2. Gestion des mises à jour

Pour ce faire j’utilise le playbook suivant :

bba@crx-ans01 ~ $ cat debian_upgrade2.yml
 - name: Update servers OS
   hosts: all
   become: true
    - name: Update cache and packages
      register: updatesys
        name: "*"
        state: latest
        update_cache: yes

    - name: Check status
        msg: "{{updatesys.stdout_lines}}"
        #msg:  "{{updatesys.stdout_lines|last}}"

Ensuite pour lancer ma mise à jour uniquement sur mon serveur de dev qui dans le groupe « webserversdev »,
Je lance ceci :

bba@crx-ans01 ~ $ ansible-playbook debian_upgrade2.yml --limit webserversdev

PLAY [Update servers OS] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Update cache and packages] ******************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Check status] *******************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan] => {
    "msg": "Building tag database..."

PLAY RECAP ****************************************************************************************************************************************************************************************************
crx-dev01.crxcluster.lan   : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Pour afficher le détail et pas juste la dernière ligne j’indique simplement :

msg: "{{updatesys.stdout_lines}}"
à la place de :
msg: "{{updatesys.stdout_lines|last}}"
bba@crx-ans01 ~ $ ansible-playbook debian_upgrade2.yml --limit webserversdev

PLAY [Update servers OS] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Update cache and packages] ******************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Check status] *******************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan] => {
    "msg": [
        "Reading package lists...",
        "Building dependency tree...",
        "Reading state information...",
        "Reading extended state information...",
        "Initializing package states...",
        "Writing extended state information...",
        "Building tag database...",
        "No packages will be installed, upgraded, or removed.",
        "0 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.",
        "Need to get 0 B of archives. After unpacking 0 B will be used.",
        "Writing extended state information...",
        "Reading package lists...",
        "Building dependency tree...",
        "Reading state information...",
        "Reading extended state information...",
        "Initializing package states...",
        "Writing extended state information...",
        "Building tag database..."

PLAY RECAP ****************************************************************************************************************************************************************************************************
crx-dev01.crxcluster.lan   : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

A partir de là, il est possible via une CRON d’automatiser complétement les mises à jour de serveurs, si vous souhaitez un outil graphique,
ANSIBLE-AWX permet de gérer cela via une interface WEB.

Bonne automatisation à tous !

Configuration de l’hyperviseur XEN sous Ubuntu.

Bonjour à tous,

je vous propose ici un petit guide d’utilisation de XEN sur UBUNTU,

Bonne lecture !

1. Configuration de l’hyperviseur sous UBUNTU 

Ici j’utilise la version Focal (20.04.2 LTS).

1.1. Installation de XEN

Je commence par installer XEN, l’outil de création de VM et aussi l’outil qui permet de créer des ponts réseau :

# sudo apt-get install xen-hypervisor-amd64 xen-tools bridge-utils

1.2. Configuration du démarrage de XEN

Je configure 2G de RAM dédié au serveur (appelé ici Domain-0), c’est la peine de mettre trop de RAM car c’est utilisé uniquement pour gérer les machines virtuelles qui vont tourner,
Tout le reste de la RAM sera disponible pour les machines virtuelles :

# sudo vim /etc/default/grub.d/xen.cfg

#Je change cette ligne : 

#Puis je met à jour GRUB : 
sudo update-grub

#Et reboot le tout : 
#sudo reboot

1.3. Configuration réseau de l’hyperviseur

La configuration réseau est effectuée via NETPLAN (qui remplace le classique /etc/network/interfaces)
voir ici :

Pour que XEN fonctionne il faut activer un pont entre les VM et le réseau LAN, par défaut c’est xenbr0, ici je l’appel br0,
Je viens donc ajouter le bloc « br0 », celui ci va prendre la configuration de l’interface eno1 ( équivalent à eth0 avant ), du coup
je passe la configuration d’en0 à br0.

#configuration avec NETPLAN : 
# cat /etc/netplan/00-installer-config.yaml
 version: 2
     dhcp4: false
     dhcp6: false
      interfaces: [eno1]
      addresses: []
      mtu: 1500
        addresses: [,]
        stp: true
        forward-delay: 4
      dhcp4: no
      dhcp6: no

Une fois en place, j’applique la configuration NETPLAN et je redémarre le tout :

# netplan generate 
# netplan --debug apply

2.1 Création et configuration de la VM LINUX

J’installe ici une machine virtuelle UBUNTU 18 (Bionic), j’aurai pu prendre une DEBIAN, mais c’est plus simple à gérer côté KERNEL LINUX vu qu’on a un fichier KERNEL local disponible sur l’hyperviseur.

Je lance la création de la VM  » vmlinux1  » grâce à cette commande :

# xen-create-image --dist=bionic --hostname vmlinux1 --randommac --netmask= --ip= --gateway= --dir /vmroot/vmlinux1 --size=18G --role=udev

Si vous chercher la liste des distributions disponibles c’est ici :

artful.d/         common/           etch.d/           fedora-core-17.d/ gentoo.d/         lucid.d/          raring.d/         trusty.d/         zesty.d/
bionic.d/         fedora-core-10.d/ fedora-core-4.d/  gutsy.d/          maverick.d/       sarge.d/          unstable.d/
bookworm.d/       cosmic.d/         fedora-core-11.d/ fedora-core-5.d/  hardy.d/          natty.d/          saucy.d/          utopic.d/
bullseye.d/       dapper.d/         fedora-core-12.d/ fedora-core-6.d/  intrepid.d/       oldoldstable.d/   sid.d/            vivid.d/
buster.d/         debian.d/         fedora-core-13.d/ fedora-core-7.d/  jaunty.d/         oldstable.d/      squeeze.d/        wheezy.d/
centos-4.d/       devel.d/          fedora-core-14.d/ fedora-core-8.d/  jessie.d/         oneiric.d/        stable.d/         wily.d/
centos-5.d/       disco.d/          fedora-core-15.d/ fedora-core-9.d/  karmic.d/         precise.d/        stretch.d/        xenial.d/
centos-6.d/       edgy.d/           fedora-core-16.d/ feisty.d/         lenny.d/          quantal.d/        testing.d/        yakkety.d/

Pour ma VM, j’utilise un stockage fichier et non LVM, une fois la commande lancée, je fais quelques ajustements côté configuration, le fichier suivant est créé automatiquement à la création de la VM :


J’indique simplement que ma VM va utiliser l’interface « br0 » comme bridge en ajoutant « bridge=br0 », puis démarre la VM :

vif         = [ 'ip= ,mac=00:16:3E:3A:92:12, bridge=br0' ]
#démarrage de la VM : 
#xl create /etc/xen/vmlinux1.cfg

#listage des VM qui tourne via : 
#xl list 

2.2 Problèmes rencontrés et opérations diverses :

Sur l’hyperviseur :

j’ai du désactiver la sécurité du KERNEL le temps de faire la configuration, pour ce faire :

sudo systemctl disable apparmor
sudo reboot

Puis j’ai tout réactiver, une fois ma VM en place :

sudo systemctl enable apparmor
sudo systemctl start apparmor

Pour la VM, ici c’est la distribution UBUNTU « minimale » qui est installée (l’éditeur vim se lance via la command editor),
la configuration réseau se fait via :

# sudo editor /etc/netplan/01-netcfg.yaml
# sudo netplan generate 
# sudo netplan --debug apply

Cela me donne :

# cat /etc/netplan/01-netcfg.yaml

# Arno: Set static IP for VM interface eth0
  version: 2
  renderer: networkd
      addresses: []
          addresses: []

Une fois la VM installée, il faut refaire la configuration via NETPLAN et tester la configuration DNS via :

#Test DNS : 
# systemd-resolve --status

Enfin pour lancer la VM automatiquement je fais ceci sur l’hyperviseur :

mkdir -p /etc/xen/auto/
ln -s /etc/xen/vmlinux1.cfg /etc/xen/auto/vmlinux1.cfg

Le dossier « auto » est scanné par le script : /etc/init.d/xendomains et sa configuration : /etc/default/xendomains.

Voilà j’espère que cela vous aura été utile !

Ultra marin 2021

Petit bilan de ma petite balade dans le Golf du Morbihan cette année !

J’ai du abandonner la course (au km 93), encore une fois mes pieds m’ont lâchés (douleurs sous les pieds + gonflement sous les pieds) tout le reste était encore bon.

=> Ce que j’en retiens : sac encore trop lourd, un plus de 5kg (j’ai terminé chaque ravito avec de l’eau encore dispo dans la poche à eau sauf 1 ou j’étais limite) je dois dire que le sac m’a rassuré sur la course mais d’un autre côté j’ai payé cher le poids en plus. Pour la prochaine je passerai de 1.5L à 1L pour la poche à eau avec 2 flasques de 500ML à l’avant ( 1 vide pour la nuit ).

=> j’ai donc terminé la 1ere partie avec plein de bouffe dispo dans le sac, il m’a manqué une paire de chaussette de rechange (à prévoir 3 par partie pour la prochaine fois).

=> pour le sac je vais passer à du plus petit comme la majorité des coureurs sur l’ultra marin là j’étais à 20L donc un sac plus adapté à la course par étapes ex: Marathon des sables. Faut aussi que je revois la copie pour la frontale car la mienne et pas assez costaud côté éclairage j’ai encore tapé des racines la nuit.

=> pour la compression je l’ai mise qu’à partir du 70km quand j’ai commencé à avoir des douleurs aux pieds, pour la prochaine, je la mettrai dès le début je pense.

La première nuit de la course à était très technique (boues/cross+côtes+pluies) et je dois dire que l’entrainement à la frontale m’a manqué,
pour la prochaine j’ajouterai : +de sortie vélo/des sorties marches (je vais axer aussi le travail de la marche pour la prochaine fois) et relâchement que sur J – 5 .

=> Enfin, côté chaussure je vais lâcher Salomon pour ces longues courses et chercher +épais/confortables côté amortis.

J’espère à l’année prochaine !

PS: pour la prochaine il faudra que je pense à couper le GPS au moment du bateau,
car ça a bugé ici en 2eme partie avec STRAVA.


Configuration d’un réplica MYSQL avec MariaDB

Bonjour à tous,

À la suite de l’incendie d’OVH de Mars 2021, j’ai dû réinstaller mon serveur de secours, c’est l’occasion de vous présenter ici la mise en place d’un nœud MARIADB dans un cluster GTID. L’idée est d’avoir une base disponible en permanence, les backups étant fait sur le nœud passif.

Ici mes données MYSQL sont :
les bases dans : /var/lib/mysql/databases/
les logs binaires dans : /var/lib/mysql/logbin/

Anciennement j’utilisais un simple snapshot LVM pour faire la réinstallation d’un nœud mais l’utilisation d’INODB ne fonctionne pas simplement avec ce type de backup à chaud. C’est pourquoi après des recherches je suis tombé sur l’outil de BACKUP : mariabackup.

1. Création du backup sur le nœud actif, ici crx-bdd01 :

Ici je commence par créer le dossier cible qui va contenir les fichiers du backup,
puis je lance celui-ci :

mkdir /var/lib/mysql/backup/

mariabackup --defaults-file=/etc/mysql/my.cnf --target-dir=/var/lib/mysql/backup --user=root --password="mypassword" --backup --parallel=4

2. Restauration/ajout du nœud passif ici crx-bdd02 :

Ici je commence par récupérer les fichiers par SCP, puis je prépare le backup :

mkdir /backup/backup_full_crx-bdd01/

scp -rp root@crx-bdd01:/var/lib/mysql/backup /backup/backup_full_crx-bdd01

mariabackup --prepare --target-dir=/backup/backup_full_crx-bdd01/

Maintenant, je vais effacer les anciennes données MYSQL, puis déplacer les données du backup dans le dossier de bases mysql  ( mon service mysql étant coupé ), contrôler que vous êtes bien sur votre nœud passif avant toute chose et que le service mysql est coupé :

service mysql stop 

rm -fr /var/lib/mysql/logbin/*
rm -fr /var/lib/mysql/databases/*

mv /backup/backup_full_crx-bdd01/* /var/lib/mysql/databases/

chown mysql:mysql -R /var/lib/mysql/databases/

Ensuite je récupère les informations de réplication GTID contenues dans le backup :

cat /var/lib/mysql/databases/xtrabackup_info | grep -i GTID

binlog_pos = filename 'mysql-bin.000041', position '151038936', GTID of the last change '1-1-94949100'

Je peux maintenant démarrer le service mysql, puis activer la réplication GTID :

service mysql start

mysql > 

stop slave; reset slave; reset slave all; reset master;

SET GLOBAL gtid_slave_pos = '1-1-94949100';

CHANGE MASTER TO master_use_gtid=slave_pos;

CHANGE MASTER TO master_host="IP-DU-PRIMAIRE", master_port=3306, master_user="replication_user", master_password="********", master_use_gtid=slave_pos;

start slave;

show slave status \G;

Enfin je peux contrôler que la réplication se fait bien, ici je vais regarder le décalage horaire entre le slave et le master qui doit être le plus proche possible de 0, après plusieurs minutes, j’arrive à zéro, cela signifie que la réplication est maintenant faite en temps réel :


show slave status \G;

Seconds_Behind_Master: 0

Et voilà j’ai maintenant un cluster actif passif MARIADB !


Source :