Kbase P1746: 'Hit end of record indicator' error after a schema change in Progress 9.1B and 9.1C
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  10/16/2008 |
|
Status: Verified
FACT(s) (Environment):
Progress 9.1C
Progress 9.1B
SYMPTOM(s):
Database corruption after applying incremental .df
Error occurs after changing the schema of a database
Data fails to dump after schema changes with error (450) and (3191)
Record of the changed table(s) fails to display with errors (450) and (3191)
Hit end of record indicator before finding newly added field
SYSTEM ERROR: Cannot read field from record, not enough fields. (450)
SYSTEM ERROR: Failed to extract field from record (table ) with recid . (3191)
Error occurs whenever Progress tries to read a record from the changed table(s)
SYSTEM ERROR: bffld: nxtfld: scan past last field. (16)
CHANGE:
Database schema modification.
CAUSE:
Bug# 20010629-019
CAUSE:
'Hit end of record ...' usually indicates data corruption. However, in this case, the error is due to a schema change that changes the physical record layout in such a way that the Progress Client cannot read it back. There is no data corruption, the bug fix makes sure that the Progress Client can read the record back. If applying the latest patch is not possible, a workaround is described below; please bear in mind that, as opposed to applying the latest patch or upgrading to the latest release, the workaround will result in loss of the unreadable records.
FIX:
1. Upgrade to Progress 9.1D or higher where the bug has been fixed.
2. Contact Technical Support to obtain and apply the last patch to 9.1C or 9.1B.
3. If neither upgrading to 9.1D or higher nor applying the last patch to 9.1B or 9.1C is possible the workaround below is given.
This workaround will result in loss of the unreadable records.
Dump and Load around unreadable records method:
1. Dump table definitions from Data Administration ( .df ) for the table-name concerned.
2. Save the records into a text file, before and after the trouble record
/*before*/
OUTPUT TO "before.d".
FOR EACH table-name BY ROWID(table-name):
EXPORT table-name.
END.
OUTPUT CLOSE.
These errors will appear again, but all the records before the bad record will be saved into "before.d" file
/* after */
OUTPUT TO "after.d".
FOR EACH table-name BY ROWID(table-name) DESCENDING :
EXPORT table-name.
END.
OUTPUT CLOSE.
These errors will appear again, but all the records after the bad record are saved into "after.d" file
If there is more then one bad record, the record identifier reported in the 'before' export operation, will not be the same as the record reported in the 'after' export operation. In this case, the "before" code then needs to be re-run only in ASCENDING order to recover the maximum possible records. This method records the last ROWID in a text file "befoid.txt" to keep track of where the export has succeeded up to by using:
"STRING ( ROWID(table-name) )" as follows:
/* before_skip1.p */
DEFINE STREAM data1.
DEFINE STREAM data2.
OUTPUT STREAM data1 TO "before.d".
OUTPUT STREAM data2 TO "befoid.txt".
FOR EACH customer BY ROWID(customer):
EXPORT STREAM data1 customer.
/* this line is left in if you want to SEE all the rowids on the screen */
/* DISPLAY STRING(ROWID(customer)) FORMAT "x(20)". */
/* the SEEK STREAM, resets the data2 stream back to zero each iteration,
so that you don't get a really large txt file, we're only interested in
the last ROWID that is exported */
SEEK STREAM data2 TO 0.
EXPORT STREAM data2 STRING(ROWID(customer)) FORMAT "x(20)".
END.
OUTPUT STREAM data1 CLOSE.
OUTPUT STREAM data2 CLOSE.
In following iterations (remember, each time we're skipping over the corruption) add:
"WHERE" clause like ROWID(table-name) > int_val_rowid",
to skip the bad record, where:
"int_val_rowid" is the last rowid given in before_skip1.p in HEX()
for example: WHERE ROWID(table-name) > TO-ROWID("0x0000006f").
/* before_skip2.p */
DEFINE STREAM data1.
DEFINE STREAM data2.
OUTPUT STREAM data1 TO "before.d" APPEND.
OUTPUT STREAM data2 TO