Commit b668e408 authored by Alain Takoudjou's avatar Alain Takoudjou

repman: correctly cleanup destroyed slave databases

parent 355d6e9c
...@@ -18,7 +18,7 @@ md5sum = 55c7fd4dd6a39b31878889fbfb00f995 ...@@ -18,7 +18,7 @@ md5sum = 55c7fd4dd6a39b31878889fbfb00f995
[instance-repman.cfg] [instance-repman.cfg]
_update_hash_filename_ = instance-repman.cfg.jinja2.in _update_hash_filename_ = instance-repman.cfg.jinja2.in
md5sum = 4ce8808677773a033f4b59bdf6b8e653 md5sum = 529411c1c6233f0a0d2740c9dd6be4f0
[config-toml.in] [config-toml.in]
_update_hash_filename_ = templates/config.toml.in _update_hash_filename_ = templates/config.toml.in
...@@ -34,7 +34,7 @@ md5sum = 0eeb24c6aa0760f0d33c4cc2828ddf30 ...@@ -34,7 +34,7 @@ md5sum = 0eeb24c6aa0760f0d33c4cc2828ddf30
[template-mariadb.cfg] [template-mariadb.cfg]
_update_hash_filename_ = instance-mariadb.cfg.jinja2.in _update_hash_filename_ = instance-mariadb.cfg.jinja2.in
md5sum = 34eed1b6d7fc45dc078f30235e22d04f md5sum = e17d3aa282e6b0e22585b86a07d23ffd
[template-my-cnf] [template-my-cnf]
_update_hash_filename_ = templates/my.cnf.in _update_hash_filename_ = templates/my.cnf.in
...@@ -58,7 +58,7 @@ md5sum = c203f40a58386310a433b58fd345a341 ...@@ -58,7 +58,7 @@ md5sum = c203f40a58386310a433b58fd345a341
[repman-manager-sh.in] [repman-manager-sh.in]
_update_hash_filename_ = templates/repman-manager.sh.in _update_hash_filename_ = templates/repman-manager.sh.in
md5sum = 852dfab6d798aa1382eec4de2fd624f9 md5sum = 5d22f599b39c25c285d0e9c02e7074a3
[dbjobs-in] [dbjobs-in]
_update_hash_filename_ = templates/dbjobs.in _update_hash_filename_ = templates/dbjobs.in
...@@ -74,4 +74,4 @@ md5sum = 455aaf369bf5141758dc57f2c0e67b08 ...@@ -74,4 +74,4 @@ md5sum = 455aaf369bf5141758dc57f2c0e67b08
[slave-db-manage.in] [slave-db-manage.in]
_update_hash_filename_ = templates/slave-db-manage.in _update_hash_filename_ = templates/slave-db-manage.in
md5sum = b45313ae5fb06972cc7fc945e34e434a md5sum = cefcb8c7d17367b14414314ffd325c26
...@@ -166,9 +166,9 @@ url = {{ parameter_dict['template-init-root-wrapper'] }} ...@@ -166,9 +166,9 @@ url = {{ parameter_dict['template-init-root-wrapper'] }}
[{{ section('mysql-slave-db-cleanup') }}] [{{ section('mysql-slave-db-cleanup') }}]
< = jinja2-template-script-base < = jinja2-template-script-base
output = ${directory:scripts}/manage-slave-db output = ${directory:scripts}/manage-slave-db
db-name = {{ slapparameter_dict['database-name'] }} db-name = {{ dumps(slapparameter_dict['database-name']) }}
extra-context = extra-context =
key database_name :db-name key database_name_list :db-name
url = {{ parameter_dict['template-manage-db'] }} url = {{ parameter_dict['template-manage-db'] }}
[mysqld] [mysqld]
...@@ -381,9 +381,6 @@ config = ${directory:etc}/mysql/my.cnf ...@@ -381,9 +381,6 @@ config = ${directory:etc}/mysql/my.cnf
command = ${mysql-get-config:output} command = ${mysql-get-config:output}
update-command = ${:command} update-command = ${:command}
[dash]
dash = {{ dumps(dash) }}
[{{ section('promise-check-computer-memory') }}] [{{ section('promise-check-computer-memory') }}]
<= monitor-promise-base <= monitor-promise-base
promise = check_command_execute promise = check_command_execute
......
...@@ -113,12 +113,6 @@ ...@@ -113,12 +113,6 @@
"patternProperties": { "patternProperties": {
".*": { ".*": {
"properties": { "properties": {
"name": {
"title": "Name of the cluster",
"description": "Name of the cluster: Should not contains spaces or any special characters.",
"type": "string",
"default": ""
},
"database-amount": { "database-amount": {
"title": "Amount of databases for cluster", "title": "Amount of databases for cluster",
"description": "Database amount to deploy with this cluster. Minimal amount is 2 required to enable replication.", "description": "Database amount to deploy with this cluster. Minimal amount is 2 required to enable replication.",
......
{ {
"$schema": "http://json-schema.org/draft-04/schema", "$schema": "http://json-schema.org/draft-04/schema",
"properties": { "properties": {
"db_user": {
"description": "Database User, default is 'user'. This parameter is set only if database is not created yet.",
"title": "Database User",
"type": "string",
"default": "user"
},
"db_password": { "db_password": {
"description": "Database password. If no password set, a password will be generated. This parameter is set only if database is not created yet.", "description": "Database password. If no password set, a password will be generated. This parameter is set only if database is not created yet.",
"title": "Initial database password", "title": "Initial database password",
......
...@@ -91,21 +91,21 @@ output = ${directory:bin}/update-proxysql-config ...@@ -91,21 +91,21 @@ output = ${directory:bin}/update-proxysql-config
{% for instance_dict in slave_instance_list -%} {% for instance_dict in slave_instance_list -%}
{% set slave_dict = { {% set slave_dict = {
'name': 'db_%s' % instance_dict['slave_reference'].replace('-', '_').lower(), 'name': 'db_%s' % instance_dict['slave_reference'].replace('-', '_').lower(),
'user': instance_dict.get('db_user', 'user'), 'user': instance_dict['slave_reference'].replace('_', '').replace('-', '').lower(),
'password': instance_dict.get('db_password', '${' ~ instance_dict['slave_reference'] ~ '-password:passwd}'), 'password': instance_dict.get('db_password', '${' ~ instance_dict['slave_reference'] ~ '-password:passwd}'),
'slave_reference': instance_dict['slave_reference'], 'slave_reference': instance_dict['slave_reference'],
'charset': instance_dict.get('db_charset', ''), 'charset': instance_dict.get('db_charset', ''),
'require_ssl': True 'require_ssl': True
} -%} } -%}
{% do database_slave_list.append(slave_dict) -%} {% do database_slave_list.append(slave_dict) -%}
{% do db_name_list.append(slave_dict['name']) -%} {% do db_name_list.append([slave_dict['name'], slave_dict['user']]) -%}
{{ password(instance_dict['slave_reference']) }} {{ password(instance_dict['slave_reference']) }}
{% endfor %} {% endfor %}
[database-slave-information] [database-slave-information]
{% for slave_dict in database_slave_list -%} {% for slave_dict in database_slave_list -%}
{{ slave_dict['name'] }} = !py!{{ slave_dict }} {{ slave_dict['name'] }} = !py!{{ slave_dict }}
{% endfor %} {% endfor %}
{% set db_list = db_name_list | join(' ') -%} {% set db_list = db_name_list -%}
{% do mariadb_dict.__setitem__('computer-memory-percent-threshold', 80) -%} {% do mariadb_dict.__setitem__('computer-memory-percent-threshold', 80) -%}
{% set default_parameter_dict = {"cluster1": {"name": "cluster1", "db-prefered-master": "", {% set default_parameter_dict = {"cluster1": {"name": "cluster1", "db-prefered-master": "",
......
#!{{ bash_bin }} #!{{ bash_bin }}
#set -e set -e
curl () { curl () {
{{ curl_bin }} -k --silent -H "Accept: application/json" "$@" {{ curl_bin }} -k --silent -H "Accept: application/json" "$@"
...@@ -33,6 +33,19 @@ wait_database () { ...@@ -33,6 +33,19 @@ wait_database () {
done done
} }
check_cluster () {
# Check if cluster is boostrapped
NAME=$1
TOKEN=$(get_token | {{ jq_bin }} -r '.token')
ERRORS=$(curl -H "Authorization: Bearer ${TOKEN}" {{ secure_url }}/api/clusters/$NAME/topology/alerts | {{ jq_bin }} -r '.errors')
if [ "$ERRORS" != "null" ] && [ ! -z "$ERRORS" ]; then
echo "ERROR: Bootstrap replication of cluster $NAME failed!";
echo $ERRORS;
return 1;
fi
return 0
}
activate_proxy () { activate_proxy () {
NAME=$1 NAME=$1
URL="{{ secure_url }}/api/clusters/$NAME/settings/actions/switch/database-hearbeat" URL="{{ secure_url }}/api/clusters/$NAME/settings/actions/switch/database-hearbeat"
...@@ -66,7 +79,6 @@ if [ ! -f "{{ parameter_dict['bootstrap'] }}/{{ name }}_bootstrapped" ]; then ...@@ -66,7 +79,6 @@ if [ ! -f "{{ parameter_dict['bootstrap'] }}/{{ name }}_bootstrapped" ]; then
curl -H "Authorization: Bearer ${TOKEN}" \ curl -H "Authorization: Bearer ${TOKEN}" \
{{ secure_url }}/api/clusters/{{ name }}/actions/replication/cleanup {{ secure_url }}/api/clusters/{{ name }}/actions/replication/cleanup
CODE=$(curl -H "Authorization: Bearer ${TOKEN}" -o /dev/null -w "%{http_code}" {{ secure_url }}/api/clusters/{{ name }}/actions/replication/bootstrap/master-slave) CODE=$(curl -H "Authorization: Bearer ${TOKEN}" -o /dev/null -w "%{http_code}" {{ secure_url }}/api/clusters/{{ name }}/actions/replication/bootstrap/master-slave)
SUCCESS=0
if [ $CODE -eq 200 ]; then if [ $CODE -eq 200 ]; then
activate_proxy {{ name }} activate_proxy {{ name }}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
...@@ -77,6 +89,9 @@ if [ ! -f "{{ parameter_dict['bootstrap'] }}/{{ name }}_bootstrapped" ]; then ...@@ -77,6 +89,9 @@ if [ ! -f "{{ parameter_dict['bootstrap'] }}/{{ name }}_bootstrapped" ]; then
else else
echo "ERROR: Failed to bootstrap cluster {{ name }}... http_code $CODE" echo "ERROR: Failed to bootstrap cluster {{ name }}... http_code $CODE"
fi fi
else
# Check cluster health
check_cluster {{ name }}
fi fi
{% endfor %} {% endfor %}
...@@ -17,6 +17,21 @@ run_mysql () { ...@@ -17,6 +17,21 @@ run_mysql () {
TOKEN=$(get_token | {{ jq_bin }} -r '.token') TOKEN=$(get_token | {{ jq_bin }} -r '.token')
DATADIR=$(curl -H "Authorization: Bearer ${TOKEN}" \ {{ secure_url }}/api/clusters/{{ cluster_name }}/topology/master | {{ jq_bin }} -r '.slaposDatadir') DATADIR=$(curl -H "Authorization: Bearer ${TOKEN}" \ {{ secure_url }}/api/clusters/{{ cluster_name }}/topology/master | {{ jq_bin }} -r '.slaposDatadir')
revoke_user () {
DB=$1
UNAME=$2
if [ ! -z "$UNAME" ]; then
echo "Revoking all grants for user '$USER'";
run_mysql -Be "
REVOKE ALL PRIVILEGES, GRANT OPTION FROM '$UNAME';
DROP USER IF EXISTS '$UNAME'@'%';
DROP USER IF EXISTS '$UNAME'@'localhost';
DROP USER IF EXISTS '$UNAME'@'::';
FLUSH PRIVILEGES;
"
fi
}
# Only write or delete on master database else, we break replication. # Only write or delete on master database else, we break replication.
if [ "$DATADIR" = "{{ partition_dir }}" ]; then if [ "$DATADIR" = "{{ partition_dir }}" ]; then
...@@ -26,21 +41,24 @@ use repman_slave_definition; ...@@ -26,21 +41,24 @@ use repman_slave_definition;
CREATE TABLE IF NOT EXISTS \`slave\` ( CREATE TABLE IF NOT EXISTS \`slave\` (
\`name\` varchar(80) NOT NULL, \`name\` varchar(80) NOT NULL,
\`state\` tinyint(1) DEFAULT NULL, \`state\` tinyint(1) DEFAULT NULL,
\`user\` varchar(80) NOT NULL,
PRIMARY KEY (\`name\`) PRIMARY KEY (\`name\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
UPDATE \`slave\` set \`state\`=false; UPDATE \`slave\` set \`state\`=false;
{% for name in database_name.split(' ') -%} {% for name, user in database_name_list -%}
{% if name -%} {% if name -%}
REPLACE INTO \`slave\` VALUES ('{{ name }}', true); REPLACE INTO \`slave\` VALUES ('{{ name }}', true, '{{ user }}');
{% endif -%} {% endif -%}
{% endfor -%} {% endfor -%}
EOF EOF
# Update requested slaves database # Update requested slaves database
OUTPUT="{{ tmp_dir }}/removed_db.txt"
run_mysql < {{ tmp_dir }}/.script.sql run_mysql < {{ tmp_dir }}/.script.sql
rm -f {{ tmp_dir }}/.script.sql rm -f {{ tmp_dir }}/.script.sql
run_mysql -NBe "SELECT name, user FROM repman_slave_definition.slave WHERE state=false" > $OUTPUT
DBNAME=$(run_mysql --skip-column-names -Be "SELECT name FROM repman_slave_definition.slave WHERE state=false"); DBNAME=$(run_mysql --skip-column-names -Be "SELECT name FROM repman_slave_definition.slave WHERE state=false");
RET=$? RET=$?
...@@ -49,12 +67,17 @@ EOF ...@@ -49,12 +67,17 @@ EOF
echo "Mysql command failed: $DBNAME" echo "Mysql command failed: $DBNAME"
exit $RET exit $RET
fi fi
if [ -z "$DBNAME" ]; then if [ -z "$DBNAME" ]; then
echo "No database for slave to remove."; echo "No database for slave to remove.";
fi fi
for NAME in $DBNAME; do for NAME in $DBNAME; do
if [ ! -z "$NAME" ]; then if [ ! -z "$NAME" ]; then
USER=$(grep -oP "$NAME\s*\K\w+" $OUTPUT);
if [ ! -z "$USER" ]; then
revoke_user $NAME $USER;
fi
echo "Deleting database $NAME..." echo "Deleting database $NAME..."
run_mysql -e "DROP DATABASE IF EXISTS $NAME"; run_mysql -e "DROP DATABASE IF EXISTS $NAME";
run_mysql -e "DELETE FROM repman_slave_definition.slave WHERE name='$NAME'"; run_mysql -e "DELETE FROM repman_slave_definition.slave WHERE name='$NAME'";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment