# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # Preparation: - name: Create user for replication shell: "echo \"GRANT REPLICATION SLAVE ON *.* TO '{{ replication_user }}'@'localhost' IDENTIFIED BY '{{ replication_pass }}'; FLUSH PRIVILEGES;\" | mysql -P {{ master_port }} -h 127.0.0.1" - name: Create test database mysql_db: login_host: 127.0.0.1 login_port: '{{ master_port }}' state: present name: '{{ test_db }}' - name: Dump all databases from the master shell: 'mysqldump -P {{ master_port }} -h 127.0.0.1 --all-databases --master-data=2 > {{ dump_path }}' - name: Restore the dump to the standby shell: 'mysql -P {{ standby_port }} -h 127.0.0.1 < {{ dump_path }}' # Test getmaster mode: - name: Get master status mysql_replication: login_host: 127.0.0.1 login_port: "{{ master_port }}" mode: getmaster register: master_status - assert: that: - master_status.Is_Master == true - master_status.Position != 0 - master_status is not changed # Test startslave fails without changemaster first. This needs fail_on_error - name: Start slave and fail because master is not specified; failing on error as requested mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: startslave fail_on_error: yes register: result ignore_errors: yes - assert: that: - result is failed # Test startslave doesn't fail if fail_on_error: no - name: Start slave and fail without propagating it to ansible as we were asked not to mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: startslave fail_on_error: no register: result - assert: that: - result is not failed # Test startslave doesn't fail if there is no fail_on_error. # This is suboptimal because nothing happens, but it's the old behavior. - name: Start slave and fail without propagating it to ansible as previous versions did not fail on error mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: startslave register: result - assert: that: - result is not failed # Test changemaster mode: # master_ssl_ca will be set as '' to check the module's behaviour for #23976, # must be converted to an empty string - name: Run replication mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: changemaster master_host: 127.0.0.1 master_port: "{{ master_port }}" master_user: "{{ replication_user }}" master_password: "{{ replication_pass }}" master_log_file: "{{ master_status.File }}" master_log_pos: "{{ master_status.Position }}" master_ssl_ca: '' register: result - assert: that: - result is changed - result.queries == ["CHANGE MASTER TO MASTER_HOST='127.0.0.1',MASTER_USER='replication_user',MASTER_PASSWORD='********',MASTER_PORT=3306,MASTER_LOG_FILE='{{ master_status.File }}',MASTER_LOG_POS={{ master_status.Position }},MASTER_SSL_CA=''"] # Test startslave mode: - name: Start slave mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: startslave register: result - assert: that: - result is changed - result.queries == ["START SLAVE"] # Test getslave mode: - name: Get standby status mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: getslave register: slave_status - assert: that: - slave_status.Is_Slave == true - slave_status.Master_Host == '127.0.0.1' - slave_status.Exec_Master_Log_Pos == master_status.Position - slave_status.Master_Port == {{ master_port }} - slave_status.Last_IO_Errno == 0 - slave_status.Last_IO_Error == '' - slave_status is not changed # Create test table and add data to it: - name: Create test table shell: "echo \"CREATE TABLE {{ test_table }} (id int);\" | mysql -P {{ master_port }} -h 127.0.0.1 {{ test_db }}" - name: Insert data shell: > echo "INSERT INTO {{ test_table }} (id) VALUES (1), (2), (3); FLUSH LOGS;" | mysql -P {{ master_port }} -h 127.0.0.1 {{ test_db }} - name: Small pause to be sure the bin log, which was flushed previously, reached the slave pause: seconds: 2 # Test master log pos has been changed: - name: Get standby status mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: getslave register: slave_status # master_status.Position is not actual and it has been changed by the prev step, # so slave_status.Exec_Master_Log_Pos must be different: - assert: that: - slave_status.Exec_Master_Log_Pos != master_status.Position - name: Start slave that is already running mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: startslave fail_on_error: true register: result - assert: that: - result is not changed # Test stopslave mode: - name: Stop slave mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: stopslave register: result - assert: that: - result is changed - result.queries == ["STOP SLAVE"] # Test stopslave mode: - name: Stop slave that is no longer running mysql_replication: login_host: 127.0.0.1 login_port: "{{ standby_port }}" mode: stopslave fail_on_error: true register: result - assert: that: - result is not changed