MariaDB
 sql >> Baza danych >  >> RDS >> MariaDB

Automatyzacja baz danych za pomocą Puppet:wdrażanie replikacji MySQL i MariaDB

Puppet to narzędzie do zarządzania systemami typu open source służące do centralizacji i automatyzacji zarządzania konfiguracją. Narzędzia do automatyzacji pomagają zminimalizować ręczne i powtarzalne zadania oraz mogą zaoszczędzić dużo czasu.

Puppet domyślnie działa w modelu serwer/agent. Agenci pobierają swój „katalog” (ostateczny pożądany stan) z mastera i stosują go lokalnie. Następnie zgłaszają się z powrotem do serwera. Katalog jest obliczany w zależności od „faktów”, które maszyna wysyła do serwera, danych wejściowych użytkownika (parametry) i modułów (kod źródłowy).

W tym blogu pokażemy, jak wdrażać i zarządzać instancjami MySQL/MariaDB za pośrednictwem Puppet. Istnieje wiele technologii związanych z MySQL/MariaDB, takich jak replikacja (master-slave, Galera lub replikacja grupowa dla MySQL), systemy równoważenia obciążenia uwzględniające SQL, takie jak ProxySQL i MariaDB MaxScale, narzędzia do tworzenia kopii zapasowych i odzyskiwania i wiele innych, które omówimy w tym artykule seria blogów. Istnieje również wiele modułów dostępnych w Kuźni Lalek zbudowanych i utrzymywanych przez społeczność, które mogą pomóc nam uprościć kod i uniknąć ponownego wymyślania koła. W tym blogu skupimy się na replikacji MySQL.

puppetlabs/mysql

Jest to obecnie najpopularniejszy moduł Puppet dla MySQL i MariaDB (i prawdopodobnie najlepszy na rynku). Ten moduł zarządza zarówno instalacją, jak i konfiguracją MySQL, a także rozszerza Puppet, aby umożliwić zarządzanie zasobami MySQL, takimi jak bazy danych, użytkownicy i granty.

Moduł jest oficjalnie obsługiwany przez zespół Puppet (za pośrednictwem repozytorium puppetlabs Github) i obsługuje wszystkie główne wersje Puppet Enterprise 2019.1.x, 2019.0.x, 2018.1.x, Puppet>=5.5.10 <7.0.0 na RedHat, Ubuntu, Platformy Debian, SLES, Scientific, CentOS, OracleLinux. Użytkownik ma możliwość zainstalowania MySQL, MariaDB i Percona Server, dostosowując repozytorium pakietów

Poniższy przykład pokazuje, jak wdrożyć serwer MySQL. Na mistrzu marionetek zainstaluj moduł MySQL i utwórz plik manifestu:

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

Dodaj następujące wiersze:

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'
      }
    }
  }
}

Następnie w węźle agenta marionetkowego uruchom następujące polecenie, aby zastosować katalog konfiguracji:

(db1.local)$ puppet agent -t

Przy pierwszym uruchomieniu może pojawić się następujący błąd:

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

Aby podpisać certyfikat, uruchom następujące polecenie na urządzeniu głównym Puppet:

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

Spróbuj ponownie, używając polecenia „puppet agent -t”, aby ponownie zainicjować połączenie z podpisanym certyfikatem.

Powyższa definicja zainstaluje standardowe pakiety związane z MySQL dostępne w repozytorium dystrybucji systemu operacyjnego. Na przykład na Ubuntu 18.04 (Bionic) zainstalowano pakiety MySQL 5.7.26:

(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

Możesz wybrać innych dostawców, takich jak Oracle, Percona lub MariaDB z dodatkową konfiguracją w repozytorium (szczegóły w sekcji README). Poniższa definicja zainstaluje pakiety MariaDB z repozytorium MariaDB apt (wymaga modułu apt Puppet):

$ 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']
}

Zwróć uwagę na wartość key->id, gdzie istnieje specjalny sposób pobrania 40-znakowego identyfikatora, jak pokazano w tym artykule:

$ 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:

Gdzie wartość identyfikatora znajduje się w wierszu zaczynającym się od „fpr”, czyli „A6E773A1812E4B8FD94024AAC0F47944DE8F6914”.

Po zastosowaniu katalogu Puppet, możesz bezpośrednio uzyskać dostęp do konsoli MySQL jako root bez jawnego hasła, ponieważ moduł automatycznie konfiguruje ~/.my.cnf i zarządza nim. Jeśli chcielibyśmy zresetować hasło roota na coś innego, po prostu zmień wartość root_password w definicji Puppet i zastosuj katalog w węźle agenta.

Wdrażanie replikacji MySQL

Aby wdrożyć konfigurację MySQL Replication, należy utworzyć co najmniej dwa typy konfiguracji, aby oddzielić konfigurację master i slave. Master będzie miał wyłączoną opcję tylko do odczytu, aby umożliwić odczyt/zapis, podczas gdy urządzenia podrzędne będą skonfigurowane z włączoną opcją tylko do odczytu. W tym przykładzie użyjemy replikacji opartej na GTID, aby uprościć konfigurację (ponieważ konfiguracja wszystkich węzłów byłaby bardzo podobna). Będziemy chcieli zainicjować łącze replikacji do urządzenia głównego zaraz po uruchomieniu urządzenia podrzędnego.

Załóżmy, że mamy 3 węzły replikacji MySQL typu master-slave:

  • db1.local — główny
  • db2.local — urządzenie podrzędne nr 1
  • db3.local — urządzenie podrzędne nr 2

Aby spełnić powyższe wymagania, możemy zapisać nasz manifest w następujący sposób:

# 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
}

Zmuś agenta do zastosowania katalogu:

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

Na urządzeniu głównym (db1.local) możemy zweryfikować wszystkie podłączone urządzenia podrzędne:

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 |
+-----------+-----------+------+-----------+--------------------------------------+

Zwróć szczególną uwagę na sekcję "exec { 'change master' :", gdzie oznacza to, że polecenie MySQL zostanie wykonane w celu zainicjowania łącza replikacji, jeśli warunek zostanie spełniony. Wszystkie zasoby "exec" wykonywane przez Puppet muszą być idempotentne, co oznacza operację, która będzie miała ten sam efekt, niezależnie od tego, czy uruchomisz ją raz, czy 10001 razy. Istnieje wiele atrybutów warunku, których możesz użyć, takich jak „unless”, „onlyif” i „create”, aby zabezpieczyć poprawny stan i zapobiec zepsuciu konfiguracji przez Puppet. Możesz usunąć/skomentować tę sekcję, jeśli chcesz ręcznie zainicjować łącze replikacji.

Zarządzanie MySQL

Ten moduł może być używany do wykonywania wielu zadań związanych z zarządzaniem MySQL:

  • opcje konfiguracji (modyfikacja, zastosowanie, konfiguracja niestandardowa)
  • zasoby bazy danych (baza danych, użytkownik, dotacje)
  • kopia zapasowa (tworzenie, planowanie, użytkownik kopii zapasowej, pamięć)
  • proste przywracanie (tylko mysqldump)
  • instalacja/aktywacja wtyczek

Zasób bazy danych

Jak widać w powyższym przykładzie manifestu, zdefiniowaliśmy dwa zasoby MySQL - mysql_user i mysql_grant - aby odpowiednio utworzyć użytkownika i nadać mu uprawnienia. Możemy również użyć klasy mysql::db, aby zapewnić obecność bazy danych z powiązanym użytkownikiem i uprawnieniami, na przykład:

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

Zwróć uwagę, że w replikacji MySQL wszystkie zapisy muszą być wykonywane tylko na masterze. Upewnij się więc, że powyższy zasób jest przypisany do mastera. W przeciwnym razie może dojść do błędnych transakcji.

Kopia zapasowa i przywracanie

Zwykle dla całego klastra wymagany jest tylko jeden host kopii zapasowej (chyba że replikujesz podzbiór danych). Do przygotowania zasobów kopii zapasowej możemy użyć klasy mysql::server::backup. Załóżmy, że w naszym manifeście mamy następującą deklarację:

  # 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 skonfiguruje wszystkie wymagania wstępne przed uruchomieniem kopii zapasowej - utworzenie użytkownika kopii zapasowej, przygotowanie ścieżki docelowej, przypisanie własności i uprawnień, ustawienie zadania cron i ustawienie opcji poleceń kopii zapasowej do użycia w dostarczonym skrypcie kopii zapasowej znajdującym się w /usr/local /sbin/mysqlbackup.sh. Następnie do użytkownika należy uruchomienie lub zaplanowanie skryptu. Aby wykonać natychmiastową kopię zapasową, po prostu wywołaj:

$ mysqlbackup.sh

Jeśli wyodrębnimy rzeczywiste polecenie mysqldump na podstawie powyższego, wygląda to tak:

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

Dla tych, którzy chcą korzystać z innych narzędzi do tworzenia kopii zapasowych, takich jak Percona Xtrabackup, MariaDB Backup (tylko MariaDB) lub MySQL Enterprise Backup, moduł zapewnia następujące prywatne klasy:

  • mysql::backup::xtrabackup (Percona Xtrabackup i MariaDB Backup)
  • mysql::backup::mysqlbackup (Kopia zapasowa MySQL Enterprise)

Przykładowa deklaracja z 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
  }

Powyższe zaplanuje dwie kopie zapasowe, jedną pełną kopię zapasową w każdą niedzielę o 23:30 i jedną przyrostową kopię zapasową codziennie z wyjątkiem niedzieli w tym samym czasie, jak pokazano w danych wyjściowych zadania cron po zastosowaniu powyższego manifestu:

(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

Aby uzyskać więcej informacji i opcji dostępnych dla tej klasy (i innych klas), zapoznaj się z opisem opcji tutaj.

W aspekcie przywracania moduł obsługuje tylko przywracanie metodą kopii zapasowej mysqldump, importując plik SQL bezpośrednio do bazy danych za pomocą klasy mysql::db, na przykład:

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
}

Plik SQL będzie ładowany tylko raz, a nie przy każdym uruchomieniu, chyba że zostanie użyte polecenie force_sql => true.

Opcje konfiguracji

W tym przykładzie użyliśmy manage_config_file => true z override_options do ustrukturyzowania naszych linii konfiguracyjnych, które później zostaną wypchnięte przez Puppet. Wszelkie modyfikacje pliku manifestu będą odzwierciedlać tylko zawartość docelowego pliku konfiguracyjnego MySQL. Ten moduł nie załaduje konfiguracji do środowiska wykonawczego ani nie zrestartuje usługi MySQL po wepchnięciu zmian do pliku konfiguracyjnego. Obowiązkiem administratora jest ponowne uruchomienie usługi w celu aktywowania zmian.

Aby dodać niestandardową konfigurację MySQL, możemy umieścić dodatkowe pliki w "includedir", domyślnie w /etc/mysql/conf.d. Pozwala nam to nadpisać ustawienia lub dodać dodatkowe, co jest pomocne, jeśli nie używasz override_options w klasie mysql::server. Zdecydowanie zaleca się skorzystanie z szablonu Puppet. Umieść niestandardowy plik konfiguracyjny w katalogu szablonów modułu (domyślnie , /etc/puppetlabs/code/environments/production/modules/mysql/templates), a następnie dodaj następujące wiersze w manifeście:

# 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')
}

Aby zaimplementować parametry specyficzne dla wersji, użyj dyrektywy version, na przykład [mysqld-5.5]. Pozwala to na jedną konfigurację dla różnych wersji MySQL.

Puppet a ClusterControl

Czy wiesz, że możesz również zautomatyzować wdrażanie replikacji MySQL lub MariaDB za pomocą ClusterControl? Możesz użyć modułu ClusterControl Puppet, aby go zainstalować lub po prostu pobierając go z naszej strony internetowej.

W porównaniu z ClusterControl można spodziewać się następujących różnic:

  • Trochę nauki, aby zrozumieć składnię Puppet, formatowanie, struktury, zanim będziesz mógł pisać manifesty.
  • Manifest musi być regularnie testowany. Bardzo często pojawia się błąd kompilacji kodu, zwłaszcza jeśli katalog jest stosowany po raz pierwszy.
  • Puppet zakłada, że ​​kody są idempotentne. Warunek testu/sprawdzenia/weryfikacji leży w gestii autora, aby uniknąć zepsucia się z uruchomionym systemem.
  • Puppet wymaga agenta w zarządzanym węźle.
  • Niezgodność wsteczna. Niektóre stare moduły nie działały poprawnie w nowej wersji.
  • Monitorowanie bazy danych/hosta należy skonfigurować osobno.

Kreator wdrażania ClusterControl prowadzi proces wdrażania:

Alternatywnie możesz użyć interfejsu wiersza poleceń ClusterControl o nazwie „s9s”, aby osiągnąć podobne wyniki. Następujące polecenie tworzy trzywęzłowy klaster replikacji MySQL (pod warunkiem, że wszystkie węzły są bez hasła, które zostało wcześniej skonfigurowane):

$ 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
Powiązane zasoby Moduł Puppet for ClusterControl — dodawanie zarządzania i monitorowania do istniejących klastrów baz danych Jak zautomatyzować wdrażanie klastra MySQL Galera przy użyciu interfejsu wiersza polecenia s9s i szefa kuchni Przewodnik DevOps dotyczący automatyzacji infrastruktury baz danych dla handlu elektronicznego — powtórka i slajdy

Obsługiwane są następujące konfiguracje replikacji MySQL/MariaDB:

  • Replikacja master-slave (oparta na plikach/pozycji)
  • Replikacja master-slave z GTID (MySQL/Percona)
  • Replikacja master-slave z identyfikatorem MariaDB GTID
  • Replikacja master-master (semi-sync/async)
  • Replikacja łańcucha master-slave (semi-sync/async)

Po wdrożeniu, węzły/klastry mogą być monitorowane i w pełni zarządzane przez ClusterControl, w tym automatyczne wykrywanie awarii, przełączanie awaryjne urządzenia głównego, promowanie urządzeń podrzędnych, automatyczne odzyskiwanie, zarządzanie kopiami zapasowymi, zarządzanie konfiguracją i tak dalej. Wszystkie te elementy są połączone w jeden produkt. Edycja społecznościowa (bezpłatna na zawsze!) oferuje wdrażanie i monitorowanie. Średnio klaster bazy danych będzie gotowy do działania w ciągu 30 minut. Potrzebuje tylko bezhasłowego SSH do węzłów docelowych.

W następnej części przeprowadzimy Cię przez wdrożenie klastra Galera przy użyciu tego samego modułu Puppet. Bądź na bieżąco!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak działa UNCOMPRESS() w MariaDB

  2. 3 sposoby na sortowanie serwerów w MariaDB

  3. Jak SIGN() działa w MariaDB

  4. Jak działa QUARTER() w MariaDB

  5. Jak zaprojektować rozproszony geograficznie klaster MariaDB