Add --purge helper flag to archive_deleted_rows
Since many people will want to fully purge shadow table data after archiving, this adds a --purge flag to archive_deleted_rows which will automatically do a full db purge when complete. Related to blueprint purge-db Change-Id: Ibd824a77b32cbceb60973a89a93ce09fe6d1050d
This commit is contained in:
@@ -60,7 +60,7 @@ Nova Database
|
|||||||
determined by ``[database]/connection`` in the configuration file passed to
|
determined by ``[database]/connection`` in the configuration file passed to
|
||||||
nova-manage.
|
nova-manage.
|
||||||
|
|
||||||
``nova-manage db archive_deleted_rows [--max_rows <number>] [--verbose] [--until-complete]``
|
``nova-manage db archive_deleted_rows [--max_rows <number>] [--verbose] [--until-complete] [--purge]``
|
||||||
|
|
||||||
Move deleted rows from production tables to shadow tables. Note that the
|
Move deleted rows from production tables to shadow tables. Note that the
|
||||||
corresponding rows in the instance_mappings and request_specs tables of the
|
corresponding rows in the instance_mappings and request_specs tables of the
|
||||||
@@ -68,7 +68,10 @@ Nova Database
|
|||||||
--verbose will print the results of the archive operation for any tables that
|
--verbose will print the results of the archive operation for any tables that
|
||||||
were changed. Specifying --until-complete will make the command run
|
were changed. Specifying --until-complete will make the command run
|
||||||
continuously until all deleted rows are archived. Use the --max_rows option,
|
continuously until all deleted rows are archived. Use the --max_rows option,
|
||||||
which defaults to 1000, as a batch size for each iteration.
|
which defaults to 1000, as a batch size for each iteration. Specifying --purge
|
||||||
|
will cause a `full` DB purge to be completed after archival. If a date range
|
||||||
|
is desired for the purge, then run ``nova-manage db purge --before
|
||||||
|
<date>`` manually after archiving is complete.
|
||||||
|
|
||||||
``nova-manage db purge [--all] [--before <date>] [--verbose]``
|
``nova-manage db purge [--all] [--before <date>] [--verbose]``
|
||||||
|
|
||||||
|
|||||||
@@ -488,8 +488,10 @@ Error: %s""") % six.text_type(e))
|
|||||||
default=False,
|
default=False,
|
||||||
help=('Run continuously until all deleted rows are archived. Use '
|
help=('Run continuously until all deleted rows are archived. Use '
|
||||||
'max_rows as a batch size for each iteration.'))
|
'max_rows as a batch size for each iteration.'))
|
||||||
|
@args('--purge', action='store_true', dest='purge', default=False,
|
||||||
|
help='Purge all data from shadow tables after archive completes')
|
||||||
def archive_deleted_rows(self, max_rows=1000, verbose=False,
|
def archive_deleted_rows(self, max_rows=1000, verbose=False,
|
||||||
until_complete=False):
|
until_complete=False, purge=False):
|
||||||
"""Move deleted rows from production tables to shadow tables.
|
"""Move deleted rows from production tables to shadow tables.
|
||||||
|
|
||||||
Returns 0 if nothing was archived, 1 if some number of rows were
|
Returns 0 if nothing was archived, 1 if some number of rows were
|
||||||
@@ -544,6 +546,12 @@ Error: %s""") % six.text_type(e))
|
|||||||
dict_value=_('Number of Rows Archived'))
|
dict_value=_('Number of Rows Archived'))
|
||||||
else:
|
else:
|
||||||
print(_('Nothing was archived.'))
|
print(_('Nothing was archived.'))
|
||||||
|
|
||||||
|
if table_to_rows_archived and purge:
|
||||||
|
if verbose:
|
||||||
|
print(_('Rows were archived, running purge...'))
|
||||||
|
self.purge(purge_all=True, verbose=verbose)
|
||||||
|
|
||||||
# NOTE(danms): Return nonzero if we archived something
|
# NOTE(danms): Return nonzero if we archived something
|
||||||
return int(bool(table_to_rows_archived))
|
return int(bool(table_to_rows_archived))
|
||||||
|
|
||||||
|
|||||||
@@ -447,15 +447,18 @@ Archiving.....complete
|
|||||||
def test_archive_deleted_rows_until_complete_quiet(self):
|
def test_archive_deleted_rows_until_complete_quiet(self):
|
||||||
self.test_archive_deleted_rows_until_complete(verbose=False)
|
self.test_archive_deleted_rows_until_complete(verbose=False)
|
||||||
|
|
||||||
|
@mock.patch('nova.db.sqlalchemy.api.purge_shadow_tables')
|
||||||
@mock.patch.object(db, 'archive_deleted_rows')
|
@mock.patch.object(db, 'archive_deleted_rows')
|
||||||
def test_archive_deleted_rows_until_stopped(self, mock_db_archive,
|
def test_archive_deleted_rows_until_stopped(self, mock_db_archive,
|
||||||
|
mock_db_purge,
|
||||||
verbose=True):
|
verbose=True):
|
||||||
mock_db_archive.side_effect = [
|
mock_db_archive.side_effect = [
|
||||||
({'instances': 10, 'instance_extra': 5}, list()),
|
({'instances': 10, 'instance_extra': 5}, list()),
|
||||||
({'instances': 5, 'instance_faults': 1}, list()),
|
({'instances': 5, 'instance_faults': 1}, list()),
|
||||||
KeyboardInterrupt]
|
KeyboardInterrupt]
|
||||||
result = self.commands.archive_deleted_rows(20, verbose=verbose,
|
result = self.commands.archive_deleted_rows(20, verbose=verbose,
|
||||||
until_complete=True)
|
until_complete=True,
|
||||||
|
purge=True)
|
||||||
self.assertEqual(1, result)
|
self.assertEqual(1, result)
|
||||||
if verbose:
|
if verbose:
|
||||||
expected = """\
|
expected = """\
|
||||||
@@ -467,6 +470,7 @@ Archiving.....stopped
|
|||||||
| instance_faults | 1 |
|
| instance_faults | 1 |
|
||||||
| instances | 15 |
|
| instances | 15 |
|
||||||
+-----------------+-------------------------+
|
+-----------------+-------------------------+
|
||||||
|
Rows were archived, running purge...
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
expected = ''
|
expected = ''
|
||||||
@@ -475,15 +479,18 @@ Archiving.....stopped
|
|||||||
mock_db_archive.assert_has_calls([mock.call(20),
|
mock_db_archive.assert_has_calls([mock.call(20),
|
||||||
mock.call(20),
|
mock.call(20),
|
||||||
mock.call(20)])
|
mock.call(20)])
|
||||||
|
mock_db_purge.assert_called_once_with(None, status_fn=mock.ANY)
|
||||||
|
|
||||||
def test_archive_deleted_rows_until_stopped_quiet(self):
|
def test_archive_deleted_rows_until_stopped_quiet(self):
|
||||||
self.test_archive_deleted_rows_until_stopped(verbose=False)
|
self.test_archive_deleted_rows_until_stopped(verbose=False)
|
||||||
|
|
||||||
@mock.patch.object(db, 'archive_deleted_rows', return_value=({}, []))
|
@mock.patch.object(db, 'archive_deleted_rows', return_value=({}, []))
|
||||||
def test_archive_deleted_rows_verbose_no_results(self, mock_db_archive):
|
def test_archive_deleted_rows_verbose_no_results(self, mock_db_archive):
|
||||||
result = self.commands.archive_deleted_rows(20, verbose=True)
|
result = self.commands.archive_deleted_rows(20, verbose=True,
|
||||||
|
purge=True)
|
||||||
mock_db_archive.assert_called_once_with(20)
|
mock_db_archive.assert_called_once_with(20)
|
||||||
output = self.output.getvalue()
|
output = self.output.getvalue()
|
||||||
|
# If nothing was archived, there should be no purge messages
|
||||||
self.assertIn('Nothing was archived.', output)
|
self.assertIn('Nothing was archived.', output)
|
||||||
self.assertEqual(0, result)
|
self.assertEqual(0, result)
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,6 @@
|
|||||||
features:
|
features:
|
||||||
- |
|
- |
|
||||||
The nova-manage command now has a 'db purge' command that will delete data
|
The nova-manage command now has a 'db purge' command that will delete data
|
||||||
from the shadow tables after 'db archive_deleted_rows' has been run.
|
from the shadow tables after 'db archive_deleted_rows' has been run. There
|
||||||
|
is also now a ``--purge`` option for 'db archive_deleted_rows' that will
|
||||||
|
automatically do a full purge after archiving.
|
||||||
|
|||||||
Reference in New Issue
Block a user