sql >> Database >  >> RDS >> MariaDB

Database-automatisering met Puppet:MySQL- en MariaDB-replicatie implementeren

Puppet is een open source systeembeheertool voor het centraliseren en automatiseren van configuratiebeheer. Automatiseringstools helpen handmatige en repetitieve taken te minimaliseren en kunnen veel tijd besparen.

Puppet werkt standaard in een server/agent-model. Agenten halen hun "catalogus" (uiteindelijke gewenste staat) op bij de master en passen deze lokaal toe. Daarna rapporteren ze terug aan de server. De catalogus wordt berekend op basis van "feiten" die de machine naar de server stuurt, gebruikersinvoer (parameters) en modules (broncode).

In deze blog laten we u zien hoe u MySQL/MariaDB-instanties via Puppet implementeert en beheert. Er zijn een aantal technologieën rond MySQL/MariaDB zoals replicatie (master-slave, Galera of groepsreplicatie voor MySQL), SQL-bewuste load balancers zoals ProxySQL en MariaDB MaxScale, back-up- en hersteltools en nog veel meer, die we in deze zullen behandelen blogreeks. Er zijn ook veel modules beschikbaar in de Puppet Forge, gebouwd en onderhouden door de gemeenschap, die ons kunnen helpen de code te vereenvoudigen en te voorkomen dat we het wiel opnieuw moeten uitvinden. In deze blog gaan we ons concentreren op MySQL-replicatie.

poppenlabs/mysql

Dit is de meest populaire Puppet-module voor MySQL en MariaDB (en waarschijnlijk de beste op de markt) op dit moment. Deze module beheert zowel de installatie en configuratie van MySQL als de uitbreiding van Puppet voor het beheer van MySQL-bronnen, zoals databases, gebruikers en subsidies.

De module wordt officieel onderhouden door het Puppet-team (via de Github-repository van puppetlabs) en ondersteunt alle belangrijke versies van Puppet Enterprise 2019.1.x, 2019.0.x, 2018.1.x, Puppet>=5.5.10 <7.0.0 op RedHat, Ubuntu, Debian, SLES, Scientific, CentOS, OracleLinux-platforms. Gebruiker heeft opties om MySQL, MariaDB en Percona Server te installeren door de pakketrepository aan te passen

Het volgende voorbeeld laat zien hoe u een MySQL-server implementeert. Installeer op de poppenspeler de MySQL-module en maak het manifestbestand:

(puppet-master)$ puppet module install puppetlabs/mysql
(puppet-master)$ vim /etc/puppetlabs/code/environments/production/manifests/mysql.pp

Voeg de volgende regels toe:

node "db1.local" {
  class { '::mysql::server':
    root_password => 't5[sb^D[+rt8bBYu',
    remove_default_accounts => true,
    override_options => {
      'mysqld' => {
        'log_error' => '/var/log/mysql.log',
        'innodb_buffer_pool_size' => '512M'
      }
      'mysqld_safe' => {
        'log_error' => '/var/log/mysql.log'
      }
    }
  }
}

Voer vervolgens op het marionet-agentknooppunt de volgende opdracht uit om de configuratiecatalogus toe te passen:

(db1.local)$ puppet agent -t

Bij de eerste run krijgt u mogelijk de volgende foutmelding:

Info: Certificate for db1.local has not been signed yet

Voer gewoon het volgende commando uit op de Puppet master om het certificaat te ondertekenen:

(puppet-master)$ puppetserver ca sign --certname=db1.local
Successfully signed certificate request for db1.local

Probeer het opnieuw met de opdracht "puppet agent -t" om de verbinding met het ondertekende certificaat opnieuw tot stand te brengen.

De bovenstaande definitie zal de standaard MySQL-gerelateerde pakketten installeren die beschikbaar zijn in de OS-distributierepository. Op Ubuntu 18.04 (Bionic) zou u bijvoorbeeld MySQL 5.7.26-pakketten geïnstalleerd krijgen:

(db1.local) $ dpkg --list | grep -i mysql
ii  mysql-client-5.7                5.7.26-0ubuntu0.18.04.1           amd64        MySQL database client binaries
ii  mysql-client-core-5.7           5.7.26-0ubuntu0.18.04.1           amd64        MySQL database core client binaries
ii  mysql-common                    5.8+1.0.4                         all          MySQL database common files, e.g. /etc/mysql/my.cnf
ii  mysql-server                    5.7.26-0ubuntu0.18.04.1           all          MySQL database server (metapackage depending on the latest version)
ii  mysql-server-5.7                5.7.26-0ubuntu0.18.04.1           amd64        MySQL database server binaries and system database setup
ii  mysql-server-core-5.7           5.7.26-0ubuntu0.18.04.1           amd64        MySQL database server binaries

U kunt kiezen voor andere leveranciers zoals Oracle, Percona of MariaDB met extra configuratie op de repository (raadpleeg de sectie README voor details). De volgende definitie zal de MariaDB-pakketten van MariaDB apt-repository installeren (vereist apt Puppet-module):

$ puppet module install puppetlabs/apt
$ vim /etc/puppetlabs/code/environments/production/manifests/mariadb.pp
# include puppetlabs/apt module
include apt

# apt definition for MariaDB 10.3
apt::source { 'mariadb':
  location => 'http://sgp1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu/',
  release  => $::lsbdistcodename,
  repos    => 'main',
  key      => {
    id     => 'A6E773A1812E4B8FD94024AAC0F47944DE8F6914',
    server => 'hkp://keyserver.ubuntu.com:80',
  },
  include => {
    src   => false,
    deb   => true,
  },
}

# MariaDB configuration
class {'::mysql::server':
  package_name     => 'mariadb-server',
  service_name     => 'mysql',
  root_password    => 't5[sb^D[+rt8bBYu',
  override_options => {
    mysqld => {
      'log-error' => '/var/log/mysql/mariadb.log',
      'pid-file'  => '/var/run/mysqld/mysqld.pid',
    },
    mysqld_safe => {
      'log-error' => '/var/log/mysql/mariadb.log',
    },
  }
}

# Deploy on db2.local
node "db2.local" {
Apt::Source['mariadb'] ->
Class['apt::update'] ->
Class['::mysql::server']
}

Let op de key->id-waarde, waar er een speciale manier is om de id van 40 tekens op te halen, zoals weergegeven in dit artikel:

$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
$ apt-key adv --list-public-keys --with-fingerprint --with-colons
uid:-::::1459359915::6DC53DD92B7A8C298D5E54F950371E2B8950D2F2::MariaDB Signing Key <[email protected]>::::::::::0:
sub:-:4096:1:C0F47944DE8F6914:1459359915::::::e::::::23:
fpr:::::::::A6E773A1812E4B8FD94024AAC0F47944DE8F6914:

Waar de id-waarde in de regel staat die begint met "fpr", dat is 'A6E773A1812E4B8FD94024AAC0F47944DE8F6914'.

Nadat de Puppet-catalogus is toegepast, kunt u rechtstreeks toegang krijgen tot de MySQL-console als root zonder expliciet wachtwoord, aangezien de module ~/.my.cnf automatisch configureert en beheert. Als we het root-wachtwoord naar iets anders willen resetten, verander dan gewoon de root_password-waarde in de Puppet-definitie en pas de catalogus toe op het agentknooppunt.

MySQL-replicatie-implementatie

Om een ​​MySQL-replicatie-installatie te implementeren, moet men ten minste twee soorten configuraties maken om de master- en slave-configuratie te scheiden. De master heeft alleen-lezen uitgeschakeld om lezen/schrijven toe te staan, terwijl slaves worden geconfigureerd met alleen-lezen ingeschakeld. In dit voorbeeld gaan we op GTID gebaseerde replicatie gebruiken om de configuratie te vereenvoudigen (aangezien de configuratie van alle knooppunten erg op elkaar zou lijken). We willen de replicatielink naar de master starten direct nadat de slave is ingeschakeld.

Verondersteld dat we 3 nodes hebben MySQL master-slave replicatie:

  • db1.local - meester
  • db2.local - slaaf #1
  • db3.local - slaaf #2

Om aan de bovenstaande vereisten te voldoen, kunnen we ons manifest opschrijven als volgt:

# Puppet manifest for MySQL GTID-based replication MySQL 5.7 on Ubuntu 18.04 (Puppet v6.4.2) 
# /etc/puppetlabs/code/environments/production/manifests/replication.pp

# node's configuration
class mysql {
  class {'::mysql::server':
    root_password           => '[email protected]#',
    create_root_my_cnf      => true,
    remove_default_accounts => true,
    manage_config_file      => true,
    override_options        => {
      'mysqld' => {
        'datadir'                 => '/var/lib/mysql',
        'bind_address'            => '0.0.0.0',
        'server-id'               => $mysql_server_id,
        'read_only'               => $mysql_read_only,
        'gtid-mode'               => 'ON',
        'enforce_gtid_consistency'=> 'ON',
        'log-slave-updates'       => 'ON',
        'sync_binlog'             => 1,
        'log-bin'                 => '/var/log/mysql-bin',
        'read_only'               => 'OFF',
        'binlog-format'           => 'ROW',
        'log-error'               => '/var/log/mysql/error.log',
        'report_host'             => ${fqdn},
        'innodb_buffer_pool_size' => '512M'
      },
      'mysqld_safe' => {
        'log-error'               => '/var/log/mysql/error.log'
      }
    }
  }
  
  # create slave user
  mysql_user { "${slave_user}@192.168.0.%":
      ensure        => 'present',
      password_hash => mysql_password("${slave_password}")
  }

  # grant privileges for slave user
  mysql_grant { "${slave_user}@192.168.0.%/*.*":
      ensure        => 'present',
      privileges    => ['REPLICATION SLAVE'],
      table         => '*.*',
      user          => "${slave_user}@192.168.0.%"
  }

  # /etc/hosts definition
  host {
    'db1.local': ip => '192.168.0.161';
    'db2.local': ip => '192.169.0.162';
    'db3.local': ip => '192.168.0.163';
  }

  # executes change master only if $master_host is defined
  if $master_host {
    exec { 'change master':
      path    => '/usr/bin:/usr/sbin:/bin',
      command => "mysql --defaults-extra-file=/root/.my.cnf -e \"CHANGE MASTER TO MASTER_HOST = '$master_host', MASTER_USER = '$slave_user', MASTER_PASSWORD = '$slave_password', MASTER_AUTO_POSITION = 1; START SLAVE;\"",
      unless  => "mysql --defaults-extra-file=/root/.my.cnf -e 'SHOW SLAVE STATUS\G' | grep 'Slave_SQL_Running: Yes'"
    }
  }
}

## node assignment

# global vars
$master_host = undef
$slave_user = 'slave'
$slave_password = 'Replicas123'

# master
node "db1.local" {
  $mysql_server_id = '1'
  $mysql_read_only = 'OFF'
  include mysql
}

# slave1
node "db2.local" {
  $mysql_server_id = '2'
  $mysql_read_only = 'ON'
  $master_host = 'db1.local'
  include mysql
}

# slave2
node "db3.local" {
  $mysql_server_id = '3'
  $mysql_read_only = 'ON'
  $master_host = 'db1.local'
  include mysql
}

Dwing de agent om de catalogus toe te passen:

(all-mysql-nodes)$ puppet agent -t

Op de master (db1.local) kunnen we alle aangesloten slaven verifiëren:

mysql> SHOW SLAVE HOSTS;
+-----------+-----------+------+-----------+--------------------------------------+
| Server_id | Host      | Port | Master_id | Slave_UUID                           |
+-----------+-----------+------+-----------+--------------------------------------+
|         3 | db3.local | 3306 |         1 | 2d0b14b6-8174-11e9-8bac-0273c38be33b |
|         2 | db2.local | 3306 |         1 | a9dfa4c7-8172-11e9-8000-0273c38be33b |
+-----------+-----------+------+-----------+--------------------------------------+

Besteed extra aandacht aan de "exec { 'change master':" sectie, waar dit betekent dat een MySQL-commando zal worden uitgevoerd om de replicatielink te starten als aan de voorwaarde is voldaan. Alle "exec"-resources die door Puppet worden uitgevoerd, moeten idempotent zijn, wat betekent dat de bewerking hetzelfde effect zal hebben, of u het nu een keer of 10.0001 keer uitvoert. Er zijn een aantal conditieattributen die je kunt gebruiken, zoals "tenzij", "onlyif" en "create" om de juiste status te waarborgen en te voorkomen dat Puppet je setup verprutst. U kunt die sectie verwijderen/opmerkingen geven als u de replicatielink handmatig wilt starten.

MySQL-beheer

Deze module kan worden gebruikt om een ​​aantal MySQL-beheertaken uit te voeren:

  • configuratie-opties (wijzigen, toepassen, aangepaste configuratie)
  • databasebronnen (database, gebruiker, subsidies)
  • back-up (maken, plannen, back-up gebruiker, opslag)
  • eenvoudig herstel (alleen mysqldump)
  • installatie/activering van plug-ins

Databasebron

Zoals je kunt zien in het voorbeeldmanifest hierboven, hebben we twee MySQL-bronnen gedefinieerd - mysql_user en mysql_grant - om respectievelijk gebruikers aan te maken en privileges toe te kennen. We kunnen ook de mysql::db-klasse gebruiken om ervoor te zorgen dat een database met bijbehorende gebruiker en privileges aanwezig is, bijvoorbeeld:

  # make sure the database and user exist with proper grant
  mysql::db { 'mynewdb':
    user          => 'mynewuser',
    password      => 'passw0rd',
    host          => '192.168.0.%',
    grant         => ['SELECT', 'UPDATE']
  } 

Houd er rekening mee dat in MySQL-replicatie alle schrijfbewerkingen alleen op de master moeten worden uitgevoerd. Zorg er dus voor dat de bovenstaande resource is toegewezen aan de master. Anders kan er een foutieve transactie plaatsvinden.

Back-up maken en terugzetten

Gewoonlijk is er slechts één back-uphost vereist voor het hele cluster (tenzij u een subset van gegevens repliceert). We kunnen de mysql::server::backup-klasse gebruiken om de back-upbronnen voor te bereiden. Stel dat we de volgende verklaring in ons manifest hebben:

  # Prepare the backup script, /usr/local/sbin/mysqlbackup.sh
  class { 'mysql::server::backup':
    backupuser     => 'backup',
    backuppassword => 'passw0rd',
    backupdir      => '/home/backup',
    backupdirowner => 'mysql',
    backupdirgroup => 'mysql',
    backupdirmode  => '755',
    backuprotate   => 15,
    time           => ['23','30'],   #backup starts at 11:30PM everyday
    include_routines  => true,
    include_triggers  => true,
    ignore_events     => false,
    maxallowedpacket  => '64M',
    optional_args     => ['--set-gtid-purged=OFF'] #extra argument if GTID is enabled
  }

Puppet configureert alle vereisten voordat een back-up wordt uitgevoerd - het maken van de back-upgebruiker, het voorbereiden van het bestemmingspad, het toewijzen van eigendom en toestemming, het instellen van de cron-taak en het instellen van de back-upopdrachtopties voor gebruik in het meegeleverde back-upscript op /usr/local /sbin/mysqlbackup.sh. Het is dan aan de gebruiker om het script uit te voeren of te plannen. Om een ​​onmiddellijke back-up te maken, roept u eenvoudig:

$ mysqlbackup.sh

Als we het eigenlijke mysqldump-commando uitpakken op basis van het bovenstaande, ziet het er als volgt uit:

$ mysqldump --defaults-extra-file=/tmp/backup.NYg0TR --opt --flush-logs --single-transaction --events --set-gtid-purged=OFF --all-databases

Voor degenen die andere back-uptools willen gebruiken, zoals Percona Xtrabackup, MariaDB Backup (alleen MariaDB) of MySQL Enterprise Backup, biedt de module de volgende privéklassen:

  • mysql::backup::xtrabackup (Percona Xtrabackup en MariaDB Backup)
  • mysql::backup::mysqlbackup (MySQL Enterprise-back-up)

Voorbeeldaangifte met Percona Xtrabackup:

  class { 'mysql::backup::xtrabackup':
    xtrabackup_package_name => 'percona-xtrabackup',
    backupuser     => 'xtrabackup',
    backuppassword => 'passw0rd',
    backupdir      => '/home/xtrabackup',
    backupdirowner => 'mysql',
    backupdirgroup => 'mysql',
    backupdirmode  => '755',
    backupcompress => true,
    backuprotate   => 15,
    include_routines  => true,
    time              => ['23','30'], #backup starts at 11:30PM
    include_triggers  => true,
    maxallowedpacket  => '64M',
    incremental_backups => true
  }

Het bovenstaande plant twee back-ups, één volledige back-up elke zondag om 23:30 uur en één incrementele back-up elke dag behalve zondag op hetzelfde tijdstip, zoals blijkt uit de cron-taakuitvoer nadat het bovenstaande manifest is toegepast:

(db1.local)$ crontab -l
# Puppet Name: xtrabackup-weekly
30 23 * * 0 /usr/local/sbin/xtrabackup.sh --target-dir=/home/backup/mysql/xtrabackup --backup
# Puppet Name: xtrabackup-daily
30 23 * * 1-6 /usr/local/sbin/xtrabackup.sh --incremental-basedir=/home/backup/mysql/xtrabackup --target-dir=/home/backup/mysql/xtrabackup/`date +%F_%H-%M-%S` --backup

Voor meer details en beschikbare opties voor deze klasse (en andere klassen), bekijk hier de optiereferentie.

Voor het herstelaspect ondersteunt de module alleen herstel met de mysqldump-back-upmethode, door het SQL-bestand rechtstreeks in de database te importeren met behulp van de mysql::db-klasse, bijvoorbeeld:

mysql::db { 'mydb':
  user     => 'myuser',
  password => 'mypass',
  host     => 'localhost',
  grant    => ['ALL PRIVILEGES'],
  sql      => '/home/backup/mysql/mydb/backup.gz',
  import_cat_cmd => 'zcat',
  import_timeout => 900
}

Het SQL-bestand wordt slechts één keer geladen en niet bij elke run, tenzij force_sql => true wordt gebruikt.

Configuratie-opties

In dit voorbeeld hebben we manage_config_file => true met override_options gebruikt om onze configuratieregels te structureren die later door Puppet naar buiten zullen worden gepusht. Elke wijziging aan het manifestbestand geeft alleen de inhoud van het MySQL-doelconfiguratiebestand weer. Deze module laadt de configuratie niet in runtime en start de MySQL-service ook niet opnieuw nadat de wijzigingen in het configuratiebestand zijn doorgevoerd. Het is de verantwoordelijkheid van de systeembeheerder om de service opnieuw te starten om de wijzigingen te activeren.

Om een ​​aangepaste MySQL-configuratie toe te voegen, kunnen we extra bestanden in "includedir" plaatsen, standaard in /etc/mysql/conf.d. Dit stelt ons in staat om instellingen te overschrijven of extra toe te voegen, wat handig is als u override_options niet gebruikt in de mysql::server-klasse. Het gebruik van het Puppet-sjabloon wordt hier ten zeerste aanbevolen. Plaats het aangepaste configuratiebestand onder de modulesjabloonmap (standaard , /etc/puppetlabs/code/environments/production/modules/mysql/templates) en voeg vervolgens de volgende regels toe aan het manifest:

# Loads /etc/puppetlabs/code/environments/production/modules/mysql/templates/my-custom-config.cnf.erb into /etc/mysql/conf.d/my-custom-config.cnf

file { '/etc/mysql/conf.d/my-custom-config.cnf':
  ensure  => file,
  content => template('mysql/my-custom-config.cnf.erb')
}

Om versiespecifieke parameters te implementeren, gebruikt u de versierichtlijn, bijvoorbeeld [mysqld-5.5]. Dit maakt één configuratie mogelijk voor verschillende versies van MySQL.

Puppet vs ClusterControl

Wist u dat u ook de MySQL- of MariaDB-replicatie-implementatie kunt automatiseren met ClusterControl? U kunt de ClusterControl Puppet-module gebruiken om deze te installeren, of u kunt deze eenvoudig downloaden van onze website.

In vergelijking met ClusterControl kunt u de volgende verschillen verwachten:

  • Een beetje een leercurve om Puppet-syntaxis, opmaak en structuren te begrijpen voordat je manifesten kunt schrijven.
  • Het manifest moet regelmatig worden getest. Het is heel gebruikelijk dat u een compilatiefout krijgt op de code, vooral als de catalogus voor de eerste keer wordt toegepast.
  • Puppet gaat ervan uit dat de codes idempotent zijn. De test/controleer/verifieer voorwaarde valt onder de verantwoordelijkheid van de auteur om te voorkomen dat een draaiend systeem wordt verstoord.
  • Puppet vereist een agent op het beheerde knooppunt.
  • Achterwaartse incompatibiliteit. Sommige oude modules zouden niet correct werken op de nieuwe versie.
  • Database/host-monitoring moet apart worden ingesteld.

De implementatiewizard van ClusterControl begeleidt het implementatieproces:

Als alternatief kunt u de ClusterControl-opdrachtregelinterface met de naam "s9s" gebruiken om vergelijkbare resultaten te bereiken. Met de volgende opdracht wordt een MySQL-replicatiecluster met drie knooppunten gemaakt (waarvan vooraf geen wachtwoord is geconfigureerd voor alle knooppunten):

$ s9s cluster --create \
  --cluster-type=mysqlreplication \
      --nodes=192.168.0.41?master;192.168.0.42?slave;192.168.0.43?slave;192.168.0.44?master; \
  --vendor=oracle \
  --cluster-name='MySQL Replication 8.0' \
  --provider-version=8.0 \
  --db-admin='root' \
  --db-admin-passwd='$ecR3t^word' \
  --log
Gerelateerde bronnen Puppet-module voor ClusterControl - Beheer en bewaking toevoegen aan uw bestaande databaseclusters Hoe u de implementatie van MySQL Galera-cluster kunt automatiseren met s9s CLI en Chef Een DevOps-gids voor automatisering van database-infrastructuur voor eCommerce - Replay &Slides

De volgende MySQL/MariaDB-replicatie-instellingen worden ondersteund:

  • Master-slave-replicatie (op bestand/positie gebaseerd)
  • Master-slave-replicatie met GTID (MySQL/Percona)
  • Master-slave-replicatie met MariaDB GTID
  • Master-master replicatie (semi-sync/async)
  • Master-slave-ketenreplicatie (semi-sync/async)

Na de implementatie kunnen knooppunten/clusters worden bewaakt en volledig worden beheerd door ClusterControl, inclusief automatische foutdetectie, masterfailover, slave-promotie, automatisch herstel, back-upbeheer, configuratiebeheer, enzovoort. Al deze zijn gebundeld in één product. De community-editie (voor altijd gratis!) biedt implementatie en monitoring. Gemiddeld is uw databasecluster binnen 30 minuten operationeel. Wat het nodig heeft, is alleen SSH zonder wachtwoord naar de doelknooppunten.

In het volgende deel zullen we u door de implementatie van Galera Cluster leiden met dezelfde Puppet-module. Blijf op de hoogte!


  1. Toestemming geweigerd bij het importeren van een CSV-bestand vanuit PGAdmin

  2. Retourneer alleen numerieke waarden in MariaDB

  3. tabelrijen bijwerken in postgres met behulp van subquery

  4. Beste manier om afbeeldingen op te slaan die afkomstig zijn van de server in Android