Add MySQL database hook "add_drop_database" configuration option to control whether dumped MySQL databases get dropped right before restore (#642).

This commit is contained in:
Dan Helfman 2023-02-20 15:32:47 -08:00
parent f5a448c7c2
commit 418ebc8843
4 changed files with 37 additions and 1 deletions

2
NEWS
View file

@ -1,4 +1,6 @@
1.7.7 1.7.7
* #642: Add MySQL database hook "add_drop_database" configuration option to control whether dumped
MySQL databases get dropped right before restore.
* #643: Fix for potential data loss (data not getting backed up) when dumping large "directory" * #643: Fix for potential data loss (data not getting backed up) when dumping large "directory"
format PostgreSQL/MongoDB databases. Prior to the fix, these dumps would not finish writing to format PostgreSQL/MongoDB databases. Prior to the fix, these dumps would not finish writing to
disk before Borg consumed them. Now, the dumping process completes before Borg starts. This only disk before Borg consumed them. Now, the dumping process completes before Borg starts. This only

View file

@ -892,6 +892,13 @@ properties:
file of that format, allowing more convenient file of that format, allowing more convenient
restores of individual databases. restores of individual databases.
example: directory example: directory
add_drop_database:
type: boolean
description: |
Use the "--add-drop-database" flag with
mysqldump, causing the database to be dropped
right before restore. Defaults to true.
example: false
options: options:
type: string type: string
description: | description: |

View file

@ -81,7 +81,7 @@ def execute_dump_command(
dump_command = ( dump_command = (
('mysqldump',) ('mysqldump',)
+ (tuple(database['options'].split(' ')) if 'options' in database else ()) + (tuple(database['options'].split(' ')) if 'options' in database else ())
+ ('--add-drop-database',) + (('--add-drop-database',) if database.get('add_drop_database', True) else ())
+ (('--host', database['hostname']) if 'hostname' in database else ()) + (('--host', database['hostname']) if 'hostname' in database else ())
+ (('--port', str(database['port'])) if 'port' in database else ()) + (('--port', str(database['port'])) if 'port' in database else ())
+ (('--protocol', 'tcp') if 'hostname' in database or 'port' in database else ()) + (('--protocol', 'tcp') if 'hostname' in database or 'port' in database else ())

View file

@ -159,6 +159,33 @@ def test_execute_dump_command_runs_mysqldump():
) )
def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
process = flexmock()
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
flexmock(module.os.path).should_receive('exists').and_return(False)
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
flexmock(module).should_receive('execute_command').with_args(
('mysqldump', '--databases', 'foo', '>', 'dump',),
shell=True,
extra_environment=None,
run_to_completion=False,
).and_return(process).once()
assert (
module.execute_dump_command(
database={'name': 'foo', 'add_drop_database': False},
log_prefix='log',
dump_path=flexmock(),
database_names=('foo',),
extra_environment=None,
dry_run=False,
dry_run_label='',
)
== process
)
def test_execute_dump_command_runs_mysqldump_with_hostname_and_port(): def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
process = flexmock() process = flexmock()
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump') flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')