Corrupt database?

Chris Muller ma.chris.m at gmail.com
Fri May 8 01:12:41 UTC 2009


>>> Hi,

Hi Jerry,

>>> I seem to have some sort of corruption in one of my Magma databases.

Incidentally, corruption can occur if, on a particular system, the
Squeak call to StandardFileStream>>#flush does not guarantee, upon
return, bits were indeed flushed to the platter and the system
experiences a hard power-off.

If this happens and happened to cause a corruption, the easiest remedy
is to restore from last full backup, then roll-forward to the second
before the power-out.

But the type of corruption you have seems to be related to the various
history of instance migrations of STBUser, not a power-outage.

>>> I'm running a Seaside application with Magma 0.41gamma1 and

I hope you meant 42, not 41.

>>> I have 2 test images and 2 databases.   Both images can access one of the
>>> databases with no problems.  Trying to access the other database from
>>> either
>>> image results in a error.   So I assume that there is something wrong
>>> with
>>> the "bad" database and not a problem with my images.

Please clarify whether you are connecting with brand new MagmaSession
instances in each case, as opposed to an old session.

>>> The error occurs during initial startup,  beginning with:

BTW, the stack-trace attachment is always helpful.

>>> Index: 1 Version: 4 ivar count: 5
>>> Index: 2 Version: 5 ivar count: 6
>>> Index: 3 Version: 2 ivar count: 9
>>> Index: 4 Version: 1 ivar count: 10
>>> Index: 5 Version: 3 ivar count: 11

Hm, that shouldn't happen.

>>> The instance variable counts look right, but the version numbers appear

Would you clarify what you mean by, "The instance variable counts look right"?

>>> to
>>> be wrong.  Also, the inImageSerializer believes that we are on version 3:
>>>
>>> def := (MaObjectSerializer allInstances first classIdManager
>>> inImageDefinition: STBUser).
>>> def version -> 3
>>> def namedInstSize -> 11 (which is the correct number)

Great information, thanks!

>>> So it appears that there are too many versions in Magmas' class
>>> definition
>>> collection for my class, and those versions are out of order.

You absolutely don't have "too many", your image may run with any
"version" you want.  Magma simply maps the instance-variables by name.
 There is no inherent requirement for Magma to be running at any
particular version in the image, but obviously an image running with
fewer inst-vars may truncate data from buffers committed by images
running with more.  Magma issues a warning in that case.

>>> Somehow I always manage to make interesting errors!

How did you stumble into this thicket?

>>> Also: after re-arranging those class definitions and closing the Magma
>>> session, closing my image without saving, and restarting the image, my
>>> application opened with no problems.   So I guess my changes to the Magma
>>> class definitions were persisted.   However, that does leave me with
>>> version
>>> 4 and 5 definitions; while the in-image version of STBUser is 3.   I'm
>>> sure
>>> I could go in and remove those definitions, and close the session and
>>> everything will be OK.

Please don't remove any of the definitions.  If you still have an
instances of that version in the repository the session will blow up
when trying to materialize them.

>>> So my questions are:
>>>
>>> Any idea how this could have possibly happened?

No, but if you are running a repository with buffers with five
different versions of the same class, it is necessary to understand
the details of how Magma handles all scenarios.  It is worth
documenting somewhere your process for evolving legacy instances from
5 to 11 inst-vars.  Having 5 versions of the same class of instances
in the database is common during development, but rarer in production.
 Production systems ensure instance migrations are handled
deliberately and with some care.

>>> How can I fix it permanently, preferably through a code patch and not
>>> manual
>>> "live" tinkering?

Option 1:  The quickest and easiest fix was at the top of the e-mail;
restore from backup and roll forward to just before the commit that
caused the corruption (You can use the MagmaBufferBrowser to determine
the commitNumber of the mis-ordered OC, then look at the time-stamp.
You can roll-forward to just before that.

Option 2:  What matters is that STBUser buffers in the repository all
point consistently to the correct class version.  Write a script using
MagmaFileTraverser to interrogate all of the Fixed buffers ("type =
3") where classId=126, check that their versions all are correct and
consistent with their number of instVars of the Buffer
(#objectInstSize).

If they are all consistent, then connect a fresh MagmaSession to the
database and commit your change to the mis-ordered OC.  Stop and
dispose of all other running sessions, replace them with fresh ones.

>>> Is there any way to make sure it does not happen again?

Consider committing a change to all of the classDefinitionsById to a
Dictionary of *SortedCollections* instead of OrderedCollection.  The
sortBlock would be:

  [ : a : b | a version < b version ]

 - Chris


More information about the Magma mailing list