mirror of
https://github.com/ansible-collections/community.mysql.git
synced 2025-04-18 16:31:26 -07:00
Fix deprecated options from MySQL 8.2 (#662)
* Fix show master status for MySQL 8.2+ * Fix mysqldump option form --master-data to --source-data * Fix incompatibility between mysqldump 8.0 and MySQL 8.4 Installing the same version between the client and the server makes sense anyway. The incompatibility arise when you use mysqldump with --source-data. The the tool tries to perform a SHOW MASTER STATUS which is deprecated in MySQL 8.2+. * Fix missing condition * Fix unit tests * Add a query resolver depending on implementation and version * Sanity * Fix SHOW REPLICA STATUS queries * Fix mariadb's SHOW REPLICA HOSTS query * Fix CHANGE MASTER for MySQL 8.0.23+ * Fix integration test for CHANGE MASTER * Fix integration test for CHANGE MASTER * Fix replication queries for MySQL 8.0.23+ and 8.4+ * Revert file edited by mistake * Enhance tests format
This commit is contained in:
parent
c503dc5b6b
commit
cd9f4fcf57
14 changed files with 503 additions and 94 deletions
|
@ -20,11 +20,12 @@ author:
|
|||
- Balazs Pocze (@banyek)
|
||||
- Andrew Klychkov (@Andersson007)
|
||||
- Dennis Urtubia (@dennisurtubia)
|
||||
- Laurent Indermühle (@laurent-indermuehle)
|
||||
options:
|
||||
mode:
|
||||
description:
|
||||
- Module operating mode. Could be
|
||||
C(changeprimary) (CHANGE MASTER TO),
|
||||
C(changeprimary) (CHANGE MASTER TO) - also works for MySQL 8.0.23 and later since community.mysql 3.10.0,
|
||||
C(changereplication) (CHANGE REPLICATION SOURCE TO) - only supported in MySQL 8.0.23 and later,
|
||||
C(getprimary) (SHOW MASTER STATUS),
|
||||
C(getreplica) (SHOW REPLICA STATUS),
|
||||
|
@ -298,8 +299,10 @@ queries:
|
|||
import os
|
||||
import warnings
|
||||
|
||||
from ansible_collections.community.mysql.plugins.module_utils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.mysql.plugins.module_utils.command_resolver import (
|
||||
CommandResolver
|
||||
)
|
||||
from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
||||
get_server_version,
|
||||
get_server_implementation,
|
||||
|
@ -313,18 +316,9 @@ from ansible.module_utils._text import to_native
|
|||
executed_queries = []
|
||||
|
||||
|
||||
def get_primary_status(cursor):
|
||||
term = "MASTER"
|
||||
|
||||
version = get_server_version(cursor)
|
||||
server_implementation = get_server_implementation(cursor)
|
||||
if server_implementation == "mysql" and LooseVersion(version) >= LooseVersion("8.2.0"):
|
||||
term = "BINARY LOG"
|
||||
|
||||
if server_implementation == "mariadb" and LooseVersion(version) >= LooseVersion("10.5.2"):
|
||||
term = "BINLOG"
|
||||
|
||||
cursor.execute("SHOW %s STATUS" % term)
|
||||
def get_primary_status(cursor, command_resolver):
|
||||
query = command_resolver.resolve_command("SHOW MASTER STATUS")
|
||||
cursor.execute(query)
|
||||
|
||||
primarystatus = cursor.fetchone()
|
||||
return primarystatus
|
||||
|
@ -410,8 +404,8 @@ def reset_replica_all(module, cursor, connection_name='', channel='', fail_on_er
|
|||
return reset
|
||||
|
||||
|
||||
def reset_primary(module, cursor, fail_on_error=False):
|
||||
query = 'RESET MASTER'
|
||||
def reset_primary(module, cursor, command_resolver, fail_on_error=False):
|
||||
query = command_resolver.resolve_command('RESET MASTER')
|
||||
try:
|
||||
executed_queries.append(query)
|
||||
cursor.execute(query)
|
||||
|
@ -420,7 +414,7 @@ def reset_primary(module, cursor, fail_on_error=False):
|
|||
reset = False
|
||||
except Exception as e:
|
||||
if fail_on_error:
|
||||
module.fail_json(msg="RESET MASTER failed: %s" % to_native(e))
|
||||
module.fail_json(msg="%s failed: %s" % (command_resolver.resolve_command('RESET MASTER'), to_native(e)))
|
||||
reset = False
|
||||
return reset
|
||||
|
||||
|
@ -447,11 +441,12 @@ def start_replica(module, cursor, connection_name='', channel='', fail_on_error=
|
|||
return started
|
||||
|
||||
|
||||
def changeprimary(cursor, chm, connection_name='', channel=''):
|
||||
def changeprimary(cursor, command_resolver, chm, connection_name='', channel=''):
|
||||
query_head = command_resolver.resolve_command("CHANGE MASTER")
|
||||
if connection_name:
|
||||
query = "CHANGE MASTER '%s' TO %s" % (connection_name, ','.join(chm))
|
||||
query = "%s '%s' TO %s" % (query_head, connection_name, ','.join(chm))
|
||||
else:
|
||||
query = 'CHANGE MASTER TO %s' % ','.join(chm)
|
||||
query = '%s TO %s' % (query_head, ','.join(chm))
|
||||
|
||||
if channel:
|
||||
query += " FOR CHANNEL '%s'" % channel
|
||||
|
@ -566,8 +561,11 @@ def main():
|
|||
else:
|
||||
module.fail_json(msg="unable to find %s. Exception message: %s" % (config_file, to_native(e)))
|
||||
|
||||
server_version = get_server_version(cursor)
|
||||
server_implementation = get_server_implementation(cursor)
|
||||
command_resolver = CommandResolver(server_implementation, server_version)
|
||||
cursor.execute("SELECT VERSION()")
|
||||
if 'mariadb' in cursor.fetchone()["VERSION()"].lower():
|
||||
if server_implementation == 'mariadb':
|
||||
from ansible_collections.community.mysql.plugins.module_utils.implementations.mariadb import replication as impl
|
||||
else:
|
||||
from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql import replication as impl
|
||||
|
@ -582,7 +580,7 @@ def main():
|
|||
primary_use_gtid = 'slave_pos'
|
||||
|
||||
if mode == 'getprimary':
|
||||
status = get_primary_status(cursor)
|
||||
status = get_primary_status(cursor, command_resolver)
|
||||
if status and "File" in status and "Position" in status:
|
||||
status['Is_Primary'] = True
|
||||
else:
|
||||
|
@ -610,52 +608,52 @@ def main():
|
|||
chm = []
|
||||
result = {}
|
||||
if primary_host is not None:
|
||||
chm.append("MASTER_HOST='%s'" % primary_host)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_HOST'), primary_host))
|
||||
if primary_user is not None:
|
||||
chm.append("MASTER_USER='%s'" % primary_user)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_USER'), primary_user))
|
||||
if primary_password is not None:
|
||||
chm.append("MASTER_PASSWORD='%s'" % primary_password)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_PASSWORD'), primary_password))
|
||||
if primary_port is not None:
|
||||
chm.append("MASTER_PORT=%s" % primary_port)
|
||||
chm.append("%s=%s" % (command_resolver.resolve_command('MASTER_PORT'), primary_port))
|
||||
if primary_connect_retry is not None:
|
||||
chm.append("MASTER_CONNECT_RETRY=%s" % primary_connect_retry)
|
||||
chm.append("%s=%s" % (command_resolver.resolve_command('MASTER_CONNECT_RETRY'), primary_connect_retry))
|
||||
if primary_log_file is not None:
|
||||
chm.append("MASTER_LOG_FILE='%s'" % primary_log_file)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_LOG_FILE'), primary_log_file))
|
||||
if primary_log_pos is not None:
|
||||
chm.append("MASTER_LOG_POS=%s" % primary_log_pos)
|
||||
chm.append("%s=%s" % (command_resolver.resolve_command('MASTER_LOG_POS'), primary_log_pos))
|
||||
if primary_delay is not None:
|
||||
chm.append("MASTER_DELAY=%s" % primary_delay)
|
||||
chm.append("%s=%s" % (command_resolver.resolve_command('MASTER_DELAY'), primary_delay))
|
||||
if relay_log_file is not None:
|
||||
chm.append("RELAY_LOG_FILE='%s'" % relay_log_file)
|
||||
if relay_log_pos is not None:
|
||||
chm.append("RELAY_LOG_POS=%s" % relay_log_pos)
|
||||
if primary_ssl is not None:
|
||||
if primary_ssl:
|
||||
chm.append("MASTER_SSL=1")
|
||||
chm.append("%s=1" % command_resolver.resolve_command('MASTER_SSL'))
|
||||
else:
|
||||
chm.append("MASTER_SSL=0")
|
||||
chm.append("%s=0" % command_resolver.resolve_command('MASTER_SSL'))
|
||||
if primary_ssl_ca is not None:
|
||||
chm.append("MASTER_SSL_CA='%s'" % primary_ssl_ca)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_SSL_CA'), primary_ssl_ca))
|
||||
if primary_ssl_capath is not None:
|
||||
chm.append("MASTER_SSL_CAPATH='%s'" % primary_ssl_capath)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_SSL_CAPATH'), primary_ssl_capath))
|
||||
if primary_ssl_cert is not None:
|
||||
chm.append("MASTER_SSL_CERT='%s'" % primary_ssl_cert)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_SSL_CERT'), primary_ssl_cert))
|
||||
if primary_ssl_key is not None:
|
||||
chm.append("MASTER_SSL_KEY='%s'" % primary_ssl_key)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_SSL_KEY'), primary_ssl_key))
|
||||
if primary_ssl_cipher is not None:
|
||||
chm.append("MASTER_SSL_CIPHER='%s'" % primary_ssl_cipher)
|
||||
chm.append("%s='%s'" % (command_resolver.resolve_command('MASTER_SSL_CIPHER'), primary_ssl_cipher))
|
||||
if primary_ssl_verify_server_cert:
|
||||
chm.append("SOURCE_SSL_VERIFY_SERVER_CERT=1")
|
||||
chm.append("%s=1" % command_resolver.resolve_command('MASTER_SSL_VERIFY_SERVER_CERT'))
|
||||
if primary_auto_position:
|
||||
chm.append("MASTER_AUTO_POSITION=1")
|
||||
chm.append("%s=1" % command_resolver.resolve_command('MASTER_AUTO_POSITION'))
|
||||
if primary_use_gtid is not None:
|
||||
chm.append("MASTER_USE_GTID=%s" % primary_use_gtid)
|
||||
chm.append("MASTER_USE_GTID=%s" % primary_use_gtid) # MariaDB only
|
||||
try:
|
||||
changeprimary(cursor, chm, connection_name, channel)
|
||||
changeprimary(cursor, command_resolver, chm, connection_name, channel)
|
||||
except mysql_driver.Warning as e:
|
||||
result['warning'] = to_native(e)
|
||||
except Exception as e:
|
||||
module.fail_json(msg='%s. Query == CHANGE MASTER TO %s' % (to_native(e), chm))
|
||||
module.fail_json(msg='%s. Query == %s TO %s' % (to_native(e), command_resolver.resolve_command('CHANGE MASTER'), chm))
|
||||
result['changed'] = True
|
||||
module.exit_json(queries=executed_queries, **result)
|
||||
elif mode == "startreplica":
|
||||
|
@ -671,7 +669,7 @@ def main():
|
|||
else:
|
||||
module.exit_json(msg="Replica already stopped", changed=False, queries=executed_queries)
|
||||
elif mode == 'resetprimary':
|
||||
reset = reset_primary(module, cursor, fail_on_error)
|
||||
reset = reset_primary(module, cursor, command_resolver, fail_on_error)
|
||||
if reset is True:
|
||||
module.exit_json(msg="Primary reset", changed=True, queries=executed_queries)
|
||||
else:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue