Skip to content

Commit 949efd0

Browse files
authored
Merge pull request #192 from SUNET/jocar-mariadb-backup
Replicated backup node for MariaDB
2 parents 68ecc3e + 13bde2c commit 949efd0

File tree

10 files changed

+166
-7
lines changed

10 files changed

+166
-7
lines changed

lib/puppet/functions/ipv4_to_int.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
4+
# Convert a single IPv4 address to an int
5+
6+
require 'ipaddr'
7+
8+
Puppet::Functions.create_function(:ipv4_to_int) do
9+
def ipv4_to_int(*arguments)
10+
IPAddr.new(arguments[0]).to_i
11+
end
12+
end

manifests/mariadb.pp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
Integer $bootstrap=0,
55
Array[Integer] $ports = [3306, 4444, 4567, 4568],
66
Array[String] $dns = [],
7+
Boolean $galera = true,
78
)
89
{
10+
911
$mariadb_root_password = lookup('mariadb_root_password', undef, undef,'NOT_SET_IN_HIERA')
1012
$mariadb_user = lookup('mariadb_user', undef, undef,undef)
1113
$mariadb_user_password = lookup('mariadb_user_password', undef, undef,undef)
@@ -14,7 +16,6 @@
1416
$clients = lookup('mariadb_clients', undef, undef,['127.0.0.1'])
1517
$cluster_nodes = lookup('mariadb_cluster_nodes', undef, undef,[])
1618
$mariadb_dir = '/opt/mariadb'
17-
$server_id = 1000 + Integer($facts['networking']['hostname'][-1])
1819

1920
# Hack to not clash with docker_compose which tries to create the same directory
2021
exec {'mariadb_dir_create':
@@ -54,26 +55,26 @@
5455
ok_criteria => ['exit_status=0','max_age=2d'],
5556
warn_criteria => ['exit_status=1','max_age=3d'],
5657
}
57-
file { '/usr/local/bin/cluster-size':
58+
file { '/usr/local/bin/mariadb-galera-size':
5859
ensure => present,
5960
content => template('sunet/mariadb/cluster-size.erb.sh'),
6061
mode => '0744',
6162
}
62-
file { '/usr/local/bin/cluster-status':
63+
file { '/usr/local/bin/mariadb-galera-status':
6364
ensure => present,
6465
content => template('sunet/mariadb/cluster-status.erb.sh'),
6566
mode => '0744',
6667
}
67-
file { '/etc/sudoers.d/99-size-test':
68+
file { '/etc/sudoers.d/99-cluster-size-test':
6869
ensure => file,
69-
content => "script ALL=(root) NOPASSWD: /usr/local/bin/cluster-size\n",
70+
content => "script ALL=(root) NOPASSWD: /usr/local/bin/mariadb-galera-size\n",
7071
mode => '0440',
7172
owner => 'root',
7273
group => 'root',
7374
}
74-
file { '/etc/sudoers.d/99-status-test':
75+
file { '/etc/sudoers.d/99-cluster-status-test':
7576
ensure => file,
76-
content => "script ALL=(root) NOPASSWD: /usr/local/bin/cluster-status\n",
77+
content => "script ALL=(root) NOPASSWD: /usr/local/bin/mariadb-galera-status\n",
7778
mode => '0440',
7879
owner => 'root',
7980
group => 'root',
@@ -92,6 +93,8 @@
9293
content => template('sunet/mariadb/credentials.cnf.erb'),
9394
mode => '0744',
9495
}
96+
97+
$server_id = ipv4_to_int($facts['networking']['ip'])
9598
file { "${mariadb_dir}/conf/my.cnf":
9699
ensure => present,
97100
content => template('sunet/mariadb/my.cnf.erb'),

manifests/mariadb/backup.pp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# This is a asyncronous replica of the Maria DB Cluster for SUNET
2+
class sunet::mariadb::backup(
3+
String $mariadb_version=latest,
4+
Array[String] $dns = [],
5+
Boolean $backup_to_baas = true,
6+
Boolean $nrpe = true,
7+
) {
8+
9+
sunet::mariadb { 'sunet_mariadb_simple':
10+
mariadb_version => $mariadb_version,
11+
ports => [3306],
12+
dns => $dns,
13+
galera => false,
14+
}
15+
16+
$cluster_nodes = lookup('mariadb_cluster_nodes', undef, undef,[])
17+
$replicate_from = $cluster_nodes[0]
18+
19+
# Secrets from local.eyaml
20+
$mariadb_root_password = safe_hiera('mariadb_root_password')
21+
$mariadb_backup_password = safe_hiera('mariadb_root_password')
22+
$mariadb_user_password = safe_hiera('mariadb_user_password')
23+
24+
file { '/opt/mariadb/scripts/start_replica_from_init.sh':
25+
ensure => present,
26+
content => template('sunet/mariadb/backup/start_replica_from_init.erb.sh'),
27+
mode => '0744',
28+
}
29+
file { '/opt/mariadb/scripts/do_backup.sh':
30+
ensure => present,
31+
content => template('sunet/mariadb/backup/do_backup.erb.sh'),
32+
mode => '0744',
33+
}
34+
35+
if $backup_to_baas {
36+
file { '/usr/local/bin/backup2baas':
37+
ensure => present,
38+
content => template('sunet/mariadb/backup/backup2baas.erb'),
39+
mode => '0744',
40+
}
41+
42+
sunet::scriptherder::cronjob { 'backup2baas':
43+
cmd => '/usr/local/bin/backup2baas',
44+
hour => '6',
45+
minute => '10',
46+
ok_criteria => ['exit_status=0', 'max_age=24h'],
47+
warn_criteria => ['exit_status=1'],
48+
}
49+
}
50+
51+
file { '/usr/lib/nagios/plugins/check_mariadb-replication':
52+
ensure => present,
53+
content => template('sunet/mariadb/backup/check_replication.erb'),
54+
mode => '0744',
55+
}
56+
file { '/usr/local/bin/mariadb-replication-status':
57+
ensure => present,
58+
content => template('sunet/mariadb/backup/replication-status.erb'),
59+
mode => '0744',
60+
}
61+
file { '/etc/sudoers.d/99-mariadb-replication-test':
62+
ensure => file,
63+
content => "script ALL=(root) NOPASSWD: /usr/local/bin/mariadb-replication-status",
64+
mode => '0440',
65+
owner => 'root',
66+
group => 'root',
67+
}
68+
69+
if $nrpe {
70+
sunet::sudoer {'nagios_run_replication_command':
71+
user_name => 'nagios',
72+
collection => 'nrpe_replication_check',
73+
command_line => '/usr/lib/nagios/plugins/check_mariadb-replication'
74+
}
75+
sunet::nagios::nrpe_command {'check_async_replication':
76+
command_line => '/usr/bin/sudo /usr/lib/nagios/plugins/check_mariadb-replication'
77+
}
78+
}
79+
80+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
docker exec mariadb-db-1 /scripts/do_backup.sh
6+
7+
BACKUPDIR=/opt/mariadb/backups
8+
find "${BACKUPDIR}" -type f -mtime +31 -exec rm -f {} \;
9+
find "${BACKUPDIR}" -empty -type d -delete
10+
11+
/usr/bin/dsmc backup
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
result="$(/usr/local/bin/mariadb-replication-status)"
4+
if [[ "${result}" == "Slave_running ON" ]]; then
5+
echo "OK: Replica running"
6+
exit 0
7+
else
8+
echo "CRITICAL: Replica not running"
9+
exit 2
10+
fi
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
stream_name="mariadb-stream-$(date +%Y-%m-%dT%H.%M.%S).gz"
3+
dump_name="mariadb-dump-$(date +%Y-%m-%dT%H.%M.%S).sql.gz"
4+
backup_dir="/backups/$(date +%Y/%m/%d)"
5+
mkdir -p "${backup_dir}"
6+
7+
buopts="--slave-info --safe-slave-backup"
8+
dumpopts="--dump-slave"
9+
mysql -p"${MYSQL_ROOT_PASSWORD}" -e "stop slave"
10+
mariadb-backup --backup ${buopts} -u root -p"${MYSQL_ROOT_PASSWORD}" --stream=xbstream | gzip >"${backup_dir}/${stream_name}"
11+
mysqldump --all-databases --single-transaction ${dumpopts} -u root -p${MYSQL_ROOT_PASSWORD} | gzip >"${backup_dir}/${dump_name}"
12+
mysql -p${MYSQL_ROOT_PASSWORD} -e "start slave"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
3+
docker exec mariadb-db-1 mysql -u root -p'<%= @mariadb_root_password %>' -N -B -e "show status like 'Slave_running'"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
mysql="mysql -u root -p${MYSQL_ROOT_PASSWORD}"
3+
init_file='/backups/init.sql.gz'
4+
if [[ -f ${init_file} ]]; then
5+
${mysql} -e "STOP SLAVE;RESET SLAVE;"
6+
master_command=$(zgrep 'CHANGE MASTER TO MASTER_LOG_FILE' ${init_file} | sed -e 's/^-- //' -e 's/;$//')
7+
master_command="${master_command}, MASTER_HOST='<%= @replicate_from %>', MASTER_USER='backup'"
8+
master_command="${master_command}, MASTER_PASSWORD='<%= @mariadb_backup_password%>', MASTER_SSL=1"
9+
master_command="${master_command}, MASTER_CONNECT_RETRY=20"
10+
zcat ${init_file} | ${mysql}
11+
${mysql} -e "${master_command}"
12+
${mysql} -e "START SLAVE"
13+
sleep 3s
14+
${mysql} -e "SHOW SLAVE STATUS\G"
15+
fi
16+
17+
exit 0

templates/mariadb/docker-compose_mariadb.yml.erb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ services:
1111
- /opt/mariadb/datadir:/var/lib/mysql
1212
- /opt/mariadb/init:/docker-entrypoint-initdb.d
1313
- /opt/mariadb/scripts:/scripts
14+
<%- if @backup -%>
15+
- /opt/mariadb_backup/start_replica_from_init.sh:/start_replica_from_init.sh
16+
<% end -%>
17+
<%- if @galera -%>
1418
network_mode: host
19+
<% end -%>
1520
<%- if [email protected]? -%>
1621
dns:
1722
<% @dns.each do |resolver| -%>
@@ -29,8 +34,10 @@ services:
2934
<%- if @mariadb_database -%>
3035
- MYSQL_DATABASE=<%= @mariadb_database %>
3136
<%- end -%>
37+
<%- if @galera -%>
3238
- BOOTSTRAP=<%= @bootstrap %>
3339
- FORCE_BOOTSTRAP=0
3440
command: "--wsrep_cluster_address=gcomm://<%= @cluster_nodes.join(',') %>"
3541
tty: true
42+
<%- end -%>
3643

templates/mariadb/my.cnf.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ gtid_strict_mode = ON
1919
log_bin = binlog
2020
log_slave_updates = ON
2121
server_id = <%= @server_id %>
22+
# Default hostname base relay_log is no good in containers
23+
relay_log = 'relay-log'
2224

2325
# Innodb
2426
innodb_autoinc_lock_mode = 2
@@ -34,6 +36,7 @@ innodb_rollback_on_timeout = 1
3436
innodb_write_io_threads = 4 # CPU dependent
3537
transaction_isolation = 'READ-COMMITTED'
3638

39+
<% if @galera -%>
3740
# Galera
3841
wsrep_cluster_name = "Sunet_MariaDB_Cluster"
3942
wsrep_gtid_domain_id = 1000 # same on all Galera nodes in the same segment
@@ -45,3 +48,4 @@ wsrep_provider_options = "gcache.size=2G;gmcast.segment=0" # gmcast.seg
4548
wsrep_slave_threads = 4 # CPU dependent
4649
wsrep_sst_method = mariabackup
4750
wsrep_sync_wait = 1
51+
<% end -%>

0 commit comments

Comments
 (0)