Jump to content

Add new disk to array but keeping data already on it


queeg

Recommended Posts

If I have a hard drive already formatted with reiserfs and containing data...I want to add this to the array, keeping the data that is on it.  I just need the array to add the new drive to the parity disk.  Is there some way to do this?

 

 

Link to comment

If I have a hard drive already formatted with reiserfs and containing data...I want to add this to the array, keeping the data that is on it.  I just need the array to add the new drive to the parity disk.  Is there some way to do this?

 

 

You can ONLY do that if the disk is currently partitioned exactly as unRAID would have done it.  Otherwise, it will consider it a foreign disk and offer to clear it.

 

I answered a very similar request in this post http://lime-technology.com/forum/index.php?topic=5159.msg47727#msg47727

It will lead you to a utility I write to check a partition table to determine if it is as unRAID expects.  unraid_partition_disk.sh

 

Joe L.

Link to comment

Thanks Joe.  I got the utility and ran it.  Since I formatted the drive using unMenu I knew it would be formatted for unRAID. 

 

It seems like the parity calc will have to read from all disks.  Is there no way that just the new drive and the parity drive be read when doing the recalc? 

Link to comment

Thanks Joe.  I got the utility and ran it.  Since I formatted the drive using unMenu I knew it would be formatted for unRAID. 

 

It seems like the parity calc will have to read from all disks.  Is there no way that just the new drive and the parity drive be read when doing the recalc? 

No, there is no way to only read the two disks. (Theoretically, it could be written to do that, but it is not)

 

Since unMENU does not partition a disk, it was still possible for it to not be correctly partitioned.  My pre-clear script does partition a disk, so if you used it, you are in good shape. 

Link to comment

Yes I used your preclear and unMenu to format it.  

 

I wonder how difficult it would be to write an add-on utility that could add or delete a single disk to the array simply by recomputing parity.  It would sure be safer than suddenly throwing all the drives out of protected mode.

Link to comment

The moment you start changing even 1 bit on the Parity drive, NONE of the disks are protected until the operation finishes. If the process crashes in the middle, your Parity data is worthless.

 

The only possible way it would be safer is by possibly being faster from only having to read from 2 of your N drives, parity and the new data drive instead of parity and all data drives.

Link to comment

The moment you start changing even 1 bit on the Parity drive, NONE of the disks are protected until the operation finishes. If the process crashes in the middle, your Parity data is worthless.

 

The only possible way it would be safer is by possibly being faster from only having to read from 2 of your N drives, parity and the new data drive instead of parity and all data drives.

 

So this is the way it works now.  But there is a certain situation that occurs all the time.  When data is being copied onto a disk in the array, the data disk and the parity disk are the only ones in action.  All the other drives are still protected.  

 

A hypothetical situation:  The drive with data is added and unRAID pretends the drive size is the same as the data that has been added to parity.   Yes, I agree that the newly added drive is unprotected until the process finishes.  Maybe a good compromise would be to mount the new disk read-only until the recalc is finished.   I guess unRAID itself would need to be modified instead of an add-on.  If unRAID internally could maintain the position where the imitation copy is and effectively view that as either the end of the drive until it finishes then I think it would work.

 

Link to comment

Just to make sure everyone understands correctly, let me state it again. As it stands now All Drives, not just the new drive, are unprotected until the process finishes.

 

Your proposed situation does have merit.

 

If the operation crashes before it's finished, the recovery step is to discard existing parity and recalculate from scratch.

 

I had thought about recovering from the last point changed (In-Process Sector Indicator) but there's several possible trouble spots that can easily occur that could cause data corruption. In one case, if you update the In-Process Sector Indicator BEFORE you write the new Parity Sector (Sector N), the update of the Sector N might have been lost (power glitch, drive crashed, system never sent it, controller never wrote it, drive never flushed it, etc). If the other case, if you update the In-Process Sector Indicator AFTER you write to Sector N, the update of the In-Process Sector Indicator might have been lost. In both cases, you need to repeat the process on Sector N. In another case, the drive might have cached the write to the In-Process Sector Indicator but NOT the updates to Sector N. Also, in typical fashion upon a crash forcing a reboot or restart, the reiserfs might replay journalled transactions which might change the data drives involved.

 

In your hypothetical situation, I can see it becoming an overly complex issue to ensure cache (buffer) coherency. It can become beyond complex in dealing with an in-flight parity update of adding a drive with existing data and allowing updates of the existing drives because those secondary updates will force parity updates too. What happens when the in-flight add of the data drive and the existing data drive wants to update the same sector of the parity drive? This forces all READS/WRITES of the Parity Drive to be serialized in order to properly account for the simultaneous operations while maintaining data integrity. You need to either share the same buffer/cache of the parity drive data or not buffer/cache it at all. Now maybe this situation is already accounted for in the code, but I have my doubts since currently adding a new drive is treated as an atomic operation that prevents the array from doing anything else.

 

 

Link to comment

In theory, when you add a new disk that already contains useful information, all that's needed to build new parity is the old good parity and the new disk: you xor their respective bits and write the result to parity. You don't need any of the other disks for that.

 

In practice, unRAID can't build new parity from just the two disks -- it reads from all the disks (as of the current version).

I can think of one way of doing the two-disk trick, but it's more effort than it's worth, and also involves an extra spare disk, so never mind that.

 

 

Link to comment

 

If the operation crashes before it's finished, the recovery step is to discard existing parity and recalculate from scratch.

I'm not sure I agree.  In my hypothetical scenario:

 

1. The unRAID process was amended to include the functionality (I don't think it can be an add-on anymore)

2. The process maintained a rolling address to where on the new drive it had gotten to so that was available at the time of the crash

3. The new drive was keep read-only until the recalc was finished

 

Then after the crash unRAID could continue on where it had left off knowing that the data on the new drive had not changed.

 

In any case, if an all-drive parity check was performed like it is currently when the server crashes, at any time the parity is wrong it is simply updated.  And while unRAID was performing that check it could still *see* the new drive's size based on the last sector or bit that was written before the crash.  Then after the parity check has finished, the add-new-drive process could continue.  

 

 

 

In your hypothetical situation, I can see it becoming an overly complex issue to ensure cache (buffer) coherency. It can become beyond complex in dealing with an in-flight parity update of adding a drive with existing data and allowing updates of the existing drives because those secondary updates will force parity updates too. What happens when the in-flight add of the data drive and the existing data drive wants to update the same sector of the parity drive? This forces all READS/WRITES of the Parity Drive to be serialized in order to properly account for the simultaneous operations while maintaining data integrity. You need to either share the same buffer/cache of the parity drive data or not buffer/cache it at all. Now maybe this situation is already accounted for in the code, but I have my doubts since currently adding a new drive is treated as an atomic operation that prevents the array from doing anything else.

 

I believe that already happens when writing data to multiple drives in the array.  Remember, I'm saying that the new process would be built into unRAID (not an add-on).

Link to comment

As this thread has morphed into a feature enhancement discussion I'd like to rename the thread to indicate it's not a current feature of unRAID.  Is it possible to rename threads?

I'm becoming increasingly interested in this the more I think about it.  I think it would be a huge feature.  Allowing drives to be moved between arrays or held out as backups and then re-inserted in the arrays when needed.  Expecially for Pro sized arrays this could be a killer feature.

Link to comment

queeg, I suggest you reread my post, as you are ignoring several cases that make continuing from where you left off impossible without having corrupted parity data. I'll repeat the part you're missing. The last case forces a recalc parity from scratch. The real issue at hand is you do not know what the case might be during a crash.

 

I had thought about recovering from the last point changed (In-Process Sector Indicator) but there's several possible trouble spots that can easily occur that could cause data corruption. In one case, if you update the In-Process Sector Indicator BEFORE you write the new Parity Sector (Sector N), the update of the Sector N might have been lost (power glitch, drive crashed, system never sent it, controller never wrote it, drive never flushed it, etc). If the other case, if you update the In-Process Sector Indicator AFTER you write to Sector N, the update of the In-Process Sector Indicator might have been lost. In both cases, you need to repeat the process on Sector N. In another case, the drive might have cached the write to the In-Process Sector Indicator but NOT the updates to Sector N.

Link to comment

queeg, I suggest you reread my post, as you are ignoring several cases that make continuing from where you left off impossible without having corrupted parity data. I'll repeat the part you're missing. The last case forces a recalc parity from scratch. The real issue at hand is you do not know what the case might be during a crash.

 

I had thought about recovering from the last point changed (In-Process Sector Indicator) but there's several possible trouble spots that can easily occur that could cause data corruption. In one case, if you update the In-Process Sector Indicator BEFORE you write the new Parity Sector (Sector N), the update of the Sector N might have been lost (power glitch, drive crashed, system never sent it, controller never wrote it, drive never flushed it, etc). If the other case, if you update the In-Process Sector Indicator AFTER you write to Sector N, the update of the In-Process Sector Indicator might have been lost. In both cases, you need to repeat the process on Sector N. In another case, the drive might have cached the write to the In-Process Sector Indicator but NOT the updates to Sector N.

 

Well, your right I don't understand what you said because I'm not familiar with the specific working parts of unRAID and/or the specific driver aspects in writing to the sectors.  But - I'm basing my belief on what unRAID can already do.  What happens in unRAID when the system crashes while writing to multiple data drives currently?  How is that fixed when rebooted?  

I see the new drive as existing within the array at the time of the crash.  The size of the drive is where the data being recalc'd was.  So to me it's the same as crashing while writing to the last sector of any data drive in the array.  Do you disagree?

Link to comment

I disagree. It's because you're writing to 2 different sectors. Both are vitally important to keep data integrity. One of them contains the sector number that was just updated (the resume point). The other contains the recalculated parity data. If at any point, those two get out of sync with each other, you need to resort to a full recalculate parity from reading all of the data.

 

When you crash while writing to a data drive, typically the system recovers with the Reiserfs replaying the journaled transaction or reverting to an earlier transaction point. When this occurs, unRAID typically forces a full parity rebuild to update the parity data. If you the user cancels the full parity rebuild, you're at risk for having data corruption as your parity data is out of sync.

Link to comment

I disagree. It's because you're writing to 2 different sectors. Both are vitally important to keep data integrity. One of them contains the sector number that was just updated (the resume point). The other contains the recalculated parity data. If at any point, those two get out of sync with each other, you need to resort to a full recalculate parity from reading all of the data.

 

When you crash while writing to a data drive, typically the system recovers with the Reiserfs replaying the journaled transaction or reverting to an earlier transaction point. When this occurs, unRAID typically forces a full parity rebuild to update the parity data. If you the user cancels the full parity rebuild, you're at risk for having data corruption as your parity data is out of sync.

 

Ok, then in that case...the case where the system crashes while conducting the add-new-drive-with-data process running then unRAID would behave exactly as it does now.  Any bad outcome from a system crash is totally negated.  It just resorts to existing functionality.

 

I think that would be very acceptable to users.  

Link to comment

To sum up a little and refine the feature...which doesn't yet exist

 

Add-drive-containing-data to array:

 

The user would add the drive.  Doing this would start a parity sync with the new drive.  When unRAID reached the end of the drive it would remount the drive as writable.  During the parity sync, updates to parity would be handled in the same manner as current writes to any drive update parity.  unRAID would see the new drive size increasing as it synced the sectors.

If during the add process the server crashed or the user interrupted the sync then unRAID would be forced to do an all-drives recalc of parity.  Whether or not the added drive was included in the all-drives is just a matter of policy.  For instance, if the crash could be the fault of the added drive then excluding it would be best, otherwise just let it be part of the array during the recalc.

 

 

The functionality of this feature would promote a wider and probably more professional audience to use unRAID.  It would expand the way unRAID is employed.  I also believe the complexity of the modification is not extremely difficult to understand and I don't think it would require a substantial rewrite.  I don't think testing would require entire reqression.

Link to comment

I agree with all parts, save one. I'll stop short of stating the degree of implementation difficulty.

 

To make it possibly easier for the tracking aspects and to prevent having to write new parts of the system, I'd only allow for the addition of single drive at a time.

 

To allow for adding multiple drives with existing data at a time, you'd have to read the existing parity data, read all the new drives' data, calculate the new parity data, write the new parity data, and write the in-progress sector. This might be able to leverage some of the existing code between the parity-check and parity-correct, but I'm in the dark and guessing at this point.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...