Troubleshooting errors 450 and 3191
These 450, 3191 errors indicate
record corruption. Specifically that a
field within the record has an invalid format.
- You will need to delete and recreate each corrupted record, if possible.
- You can attempt to dump each corrupt records' fields, so that you can get as much information as possible from each record.
- You need to use a field list to sequentially get each field prior to the corrupt one/s.
1. List the Table's fields and the order they are stored in the record.
- Replace "yourtablename" with the failing table:
FIND _file WHERE _file._file-name = "yourtablename".
FOR EACH _field OF _file BY _field._field-physpos.
DISPLAY _field._field-name
_field._field-physpos.
END.
2. Dump all fields prior to the field that is corrupt.
- You will need to go through this process for each corrupt record.
- Replace 12345 with the appropriate RECID of the record that is failing.
- Replace yourtablename with your failing table.
- Replace yourfield_{1-4} with the appropriate fields from the previous code output. iow: All fields that are not corrupt:
DEFINE VARIABLE myrecid AS INT NO-UNDO INIT 12345.
OUTPUT TO VALUE(string(myrecid) + ".txt").
FOR EACH yourtablename FIELDS (
yourfield_1
yourfield_2
yourfield_3
yourfield_4
) WHERE RECID(yourtablename) = myrecid:
PUT UNFORMATTED
"yourfield_1 = " STRING(yourfield_1) chr(10)
"yourfield_2 = " STRING(yourfield_2) chr(10)
"yourfield_3 = " STRING(yourfield_3) chr(10)
"yourfield_4 = " STRING(yourfield_4) chr(10).
END.
OUTPUT CLOSE.
The EXPORT command can also be used to export the record in its entirety can also be used. Only
fields that can be read, can be exported.
Once the available field data are known, when there are many records to interrogatea an EXPORT code example is provided in:
How to recover data from a record when getting errors 450 and 3191.
// Use the following to understand which fields are still available, sometimes fields +15 can be skipped and the next found in tables with many fields.
OUTPUT TO VALUE(string(<recid>) + ".txt").
FIND <table-name> WHERE RECID(<table-name>) = <recid>.
// export 'known fields' or exclude corrupt fields with the EXPORT statement
EXPORT DELIMITER ";" <field-name> <field-name> <field-name>
// EXPORT <table-name> EXCEPT <field-name> <field-name> <field-name> <field-name> <field-name> <field-name>.
// An .xml EXPORT example is attached to this Article which can be modified to requirement: XMLExportTable.p (Caveats apply)
3. Delete the record
Having recovered all field information that can be read, the record then needs to be deleted from the database using IDXFIX:
$ proutil dbname -C idxfix
- Select Option 6. Delete one record and it's index entries.
- "Type the RECID to delete: <Enter the recid>
- "Type the area for the RECID(s).": <enter the area number>
Repeat for each RECID that is corrupt. When there are many records to be deleted, this can be scripted by parsing a list of the recid's. The following Article provides an example:
Once these records have been removed, run IDXFIX Option 2 (scan indexes), assuring
"Validate recids for index entries" &
"Fix indexes on Scan" are confirmed (Y).
4. Re-instate data
Re-create these records field data from scratch, using the data obtained earlier with export. The information obtained from exporting the RECID can be used to compare the corrupted record field content with earlier copies of the record for example from earlier database backups to identify the missing fields.
Add the missing fields (the ones that were corrupted) to the text file that was exported. The output file can now be imported back into the database for the purpose of recreating the record.