Fix mysqldump ignoring errors (#403)

* Add schema and tables for the tests

* Add tests for full dump with and without compression

* Add test for distinct dump with and without compression

* Fix sh not seeing errors for command before the pipe

sh is missing the pipefail flag. We must use bash for this.

* Add cleanup to prevent the following tests from failing

* Fix fqcn in module_defaults

* Add changelog fragment

* Add check to the error message to ensure we captured the right one

* Add option to activate the fix on systems with bash

* Fix errors when data schema is already absent

* Update changelogs/fragments/fix-256-mysql_dump-errors.yml

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Add markup for commands in the documentation string

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Add markup and next release version in the documentation string

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Fix missing dependency for MySQL 8

* Add pipefail to tests of uncompressed dumps to enure it still works

* Fix "bash command not found" if pipefail is used for uncompressed dump

* Fix sanity pep8

* Document example of dump with pipefail

* Add dedpulication to command construct

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
This commit is contained in:
Laurent Indermühle 2022-06-30 06:54:26 +02:00 committed by GitHub
parent 6f87620d9b
commit 5108ca5e66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 188 additions and 5 deletions

View file

@ -0,0 +1,148 @@
---
# When mysqldump encountered an issue, mysql_db was still happy. But the
# dump produced was empty or worse, only contained `DROP TABLE IF EXISTS...`
- module_defaults:
community.mysql.mysql_db: &mysql_defaults
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
community.mysql.mysql_query: *mysql_defaults
block:
- name: Dumps errors | Setup test | Create 2 schemas
community.mysql.mysql_db:
name:
- "db1"
- "db2"
state: present
- name: Dumps errors | Setup test | Create 2 tables
community.mysql.mysql_query:
query:
- "CREATE TABLE db1.t1 (id int)"
- "CREATE TABLE db1.t2 (id int)"
- "CREATE VIEW db2.v1 AS SELECT id from db1.t1"
- name: Dumps errors | Full dump without compression
community.mysql.mysql_db:
state: dump
name: all
target: /tmp/full-dump.sql
register: full_dump
- name: Dumps errors | Full dump with gunzip
community.mysql.mysql_db:
state: dump
name: all
target: /tmp/full-dump.sql.gz
register: full_dump_gz
- name: Dumps errors | Distinct dump without compression
community.mysql.mysql_db:
state: dump
name: db2
target: /tmp/dump-db2.sql
register: dump_db2
- name: Dumps errors | Distinct dump with gunzip
community.mysql.mysql_db:
state: dump
name: db2
target: /tmp/dump-db2.sql.gz
register: dump_db2_gz
- name: Dumps errors | Check distinct dumps are changed
ansible.builtin.assert:
that:
- dump_db2 is changed
- dump_db2_gz is changed
# Now db2.v1 targets an inexistant table so mysqldump will fail
- name: Dumps errors | Drop t1
community.mysql.mysql_query:
query:
- "DROP TABLE db1.t1"
- name: Dumps errors | Full dump after drop t1 without compression
community.mysql.mysql_db:
state: dump
name: all
target: /tmp/full-dump-without-t1.sql
pipefail: true # This should do nothing
register: full_dump_without_t1
ignore_errors: true
- name: Dumps errors | Full dump after drop t1 with gzip without the fix
community.mysql.mysql_db:
state: dump
name: all
target: /tmp/full-dump-without-t1.sql.gz
register: full_dump_without_t1_gz_without_fix
ignore_errors: true
- name: Dumps errors | Full dump after drop t1 with gzip with the fix
community.mysql.mysql_db:
state: dump
name: all
target: /tmp/full-dump-without-t1.sql.gz
pipefail: true
register: full_dump_without_t1_gz_with_fix
ignore_errors: true
- name: Dumps errors | Check full dump
ansible.builtin.assert:
that:
- full_dump_without_t1 is failed
- full_dump_without_t1.msg is search(
'references invalid table')
- full_dump_without_t1_gz_without_fix is changed
- full_dump_without_t1_gz_with_fix is failed
- full_dump_without_t1_gz_with_fix.msg is search(
'references invalid table')
- name: Dumps errors | Distinct dump after drop t1 without compression
community.mysql.mysql_db:
state: dump
name: db2
target: /tmp/dump-db2-without_t1.sql
pipefail: true # This should do nothing
register: dump_db2_without_t1
ignore_errors: true
- name: Dumps errors | Distinct dump after drop t1 with gzip without the fix
community.mysql.mysql_db:
state: dump
name: db2
target: /tmp/dump-db2-without_t1.sql.gz
register: dump_db2_without_t1_gz_without_fix
ignore_errors: true
- name: Dumps errors | Distinct dump after drop t1 with gzip with the fix
community.mysql.mysql_db:
state: dump
name: db2
target: /tmp/dump-db2-without_t1.sql.gz
pipefail: true
register: dump_db2_without_t1_gz_with_fix
ignore_errors: true
- name: Dumps errors | Check distinct dump
ansible.builtin.assert:
that:
- dump_db2_without_t1 is failed
- dump_db2_without_t1.msg is search(
'references invalid table')
- dump_db2_without_t1_gz_without_fix is changed
- dump_db2_without_t1_gz_with_fix is failed
- dump_db2_without_t1_gz_with_fix.msg is search(
'references invalid table')
- name: Dumps errors | Cleanup
community.mysql.mysql_db:
name:
- "db1"
- "db2"
state: absent

View file

@ -63,3 +63,6 @@
vars:
db_name: "{{ item }}"
loop: "{{ db_names }}"
- name: Check errors from mysqldump are seen issue 256
ansible.builtin.include_tasks: issue_256_mysqldump_errors.yml

View file

@ -18,8 +18,8 @@
# ============================================================
- name: remove database if it exists
command: >
"{{ mysql_command }} -sse 'drop database {{ db_name }}'"
ignore_errors: True
"{{ mysql_command }} -sse 'DROP DATABASE IF EXISTS {{ db_name }}'"
ignore_errors: true
- name: make sure the test database is not there
command: "{{ mysql_command }} {{ db_name }}"