Commit 34ab5ea6 authored by Grégory Wisniewski's avatar Grégory Wisniewski

Implement dropPartition() on database manager to remove objects and transactions

not related to partitions currently assigned to a storage node. This is required
because an old node can come back, get a new UUID, start replication and a
conflict on (oid, serial) with the cluster it is joining. As there is now check
on the object integrity, the object will not be replicated and a bad object will
be kept. So during storage initialization, after getting the full partition
table, a storage look if there is partitions unassigned to it and drop data for
those partitions.


git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@1228 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent e159ab3a
...@@ -127,6 +127,12 @@ class DatabaseManager(object): ...@@ -127,6 +127,12 @@ class DatabaseManager(object):
thrown away.""" thrown away."""
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
def dropPartition(self, offset):
""" Drop objects and transactions assigned to a partition table,
this should be called only during storage initialization, to clear
existing data that could be stored by a previous cluster life """
raise NotImplementedError('this method must be overriden')
def dropUnfinishedData(self): def dropUnfinishedData(self):
"""Drop any unfinished data from a database.""" """Drop any unfinished data from a database."""
raise NotImplementedError('this method must be overridden') raise NotImplementedError('this method must be overridden')
......
...@@ -48,8 +48,16 @@ class InitializationHandler(BaseMasterHandler): ...@@ -48,8 +48,16 @@ class InitializationHandler(BaseMasterHandler):
# Install the partition table into the database for persistency. # Install the partition table into the database for persistency.
cell_list = [] cell_list = []
for offset in xrange(app.pt.getPartitions()): for offset in xrange(app.pt.getPartitions()):
assigned_to_me = False
for cell in pt.getCellList(offset): for cell in pt.getCellList(offset):
cell_list.append((offset, cell.getUUID(), cell.getState())) cell_list.append((offset, cell.getUUID(), cell.getState()))
if cell.getUUID() == app.uuid:
assigned_to_me = True
if not assigned_to_me:
logging.warning('drop data for partition %d' % offset)
# not for me, delete objects database
app.dm.dropPartition(app.pt.getPartitions(), offset)
app.dm.setPartitionTable(ptid, cell_list) app.dm.setPartitionTable(ptid, cell_list)
self.app.has_partition_table = True self.app.has_partition_table = True
......
...@@ -369,6 +369,18 @@ class MySQLDatabaseManager(DatabaseManager): ...@@ -369,6 +369,18 @@ class MySQLDatabaseManager(DatabaseManager):
def setPartitionTable(self, ptid, cell_list): def setPartitionTable(self, ptid, cell_list):
self.doSetPartitionTable(ptid, cell_list, True) self.doSetPartitionTable(ptid, cell_list, True)
def dropPartition(self, num_partitions, offset):
q = self.query
self.begin()
try:
q("""DELETE FROM obj WHERE MOD(oid, %d) = %d""" %
(num_partitions, offset))
q("""DELETE FROM trans WHERE MOD(oid, %d) = %d""" %
(num_partitions, offset))
except:
self.rollback()
self.commit()
def dropUnfinishedData(self): def dropUnfinishedData(self):
q = self.query q = self.query
self.begin() self.begin()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment