From 41d851387cec122f4795d447458fd81e48e256b0 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Wed, 9 Apr 2014 16:33:02 +0900 Subject: [PATCH] Add timestamp checking in AccountBroker.is_status_deleted Account-reaper works only at account-server with the first replica, and reaps account with "deleted" status. On the other hand, account-replicator doesn't replicate the status, only replicates *_timestamp. When swift fails to delete the first account replica, account-reaper never reaps the account, because the first replica never gets marked as "deleted". This patch adds a timestamp checking into is_status_deleted method, and account-reaper will start to reap the account after account-replicator replicates *_timestamp. Change-Id: I75e3f15ad217a71b4fd39552cf6db2957597efca Closes-Bug: #1304755 --- swift/account/backend.py | 5 +++-- test/unit/account/test_backend.py | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/swift/account/backend.py b/swift/account/backend.py index e19a5e8bbf..9fc3c27468 100644 --- a/swift/account/backend.py +++ b/swift/account/backend.py @@ -312,9 +312,10 @@ class AccountBroker(DatabaseBroker): """Only returns true if the status field is set to DELETED.""" with self.get() as conn: row = conn.execute(''' - SELECT status + SELECT put_timestamp, delete_timestamp, status FROM account_stat''').fetchone() - return (row['status'] == "DELETED") + return row['status'] == "DELETED" or ( + row['delete_timestamp'] > row['put_timestamp']) def get_policy_stats(self): """ diff --git a/test/unit/account/test_backend.py b/test/unit/account/test_backend.py index eb0bccc8a4..21fe2acf0b 100644 --- a/test/unit/account/test_backend.py +++ b/test/unit/account/test_backend.py @@ -91,6 +91,21 @@ class TestAccountBroker(unittest.TestCase): POLICIES.default.idx) self.assert_(broker.empty()) + def test_is_status_deleted(self): + # Test AccountBroker.is_status_deleted + broker1 = AccountBroker(':memory:', account='a') + broker1.initialize(Timestamp(time()).internal) + self.assert_(not broker1.is_status_deleted()) + broker1.delete_db(Timestamp(time()).internal) + self.assert_(broker1.is_status_deleted()) + broker2 = AccountBroker(':memory:', account='a') + broker2.initialize(Timestamp(time()).internal) + # Set delete_timestamp greater than put_timestamp + broker2.merge_timestamps( + time(), Timestamp(time()).internal, + Timestamp(time() + 999).internal) + self.assert_(broker2.is_status_deleted()) + def test_reclaim(self): broker = AccountBroker(':memory:', account='test_account') broker.initialize(Timestamp('1').internal)