Gbak and Firebird Versions
Posted on the Firebird development list 14 Dec 2009. In reply to a question by Lester Caine, Claudio Valderrama writes about gbak.
I have a number of sites currently that have Firebird 1.5 on, and it will be some time before the machines are due for renewal, which is the only time they will be upgraded. Firebird 2.1.2 is my current upgrade point having skipped Firebird 2.0 and all the machines here run that, but I have a Firebird 1.5 gbak on the system so that I can pull data from site - play with it - and then in an emergency - push it back to the site.
We are not talking about 'new features' since the database schema is always the older version, but is there anything stopping a version of gbak being made available which WOULD handle a backport from Firebird 2.5 to something earlier?
gbak is not that simple as some people think:
It handles native and portable backups.
It should restore in a way that the server doesn't choke with the depedencies among objects.
It tries has to backup metadata and (by default, but optionally) data.
It needs to know the source db's ODS when backing up.
If it tries to read a system table that doesn't exist, it will get an error and the backup is aborted. For example, rdb$roles didn't exist in InterBase 4; rdb$field_precision didn't exist in InterBase 5; rdb$roles and rdb$generators didn't have a rdb$description column in Firebird 1.5; there's no rdb$relation_type in rdb$relations in Firebird 2.0; rdb$messages was 255 in FireBird 1.5 and before, 1021 in Firebird 2.0 and Firebid 2.1 and 1023 in Firebi9rd 2.5; table rdb$packages only exists since Firebird 3.0 and so on.
Since the beginning, gbak has had the concept of RESTORE_format. This is the same backup version number that was used when backing up. It's not 1:1 with the server versions. For example, gbak for Firebird 1 and Firebird 1.5 have version 6 because the system tables weren't enhanced between Firebird 1 and Firebird 1.5, new data types weren't created and database wide settings weren't introduced (SQL dialect was put in the db header in InterBase 6/Firebird 1 and must be backed up). You know what you can store in each backup version, hence if some tag is unrecognized or it's recognized but didn't exist in such backup level (version), we have a corrupt backup. I've tried to do all the possible checks to avoid garbage being accepted as valid. For example, a backup produced with Firebird 1's gbak is version 6. If Firebird 2.1's gbak tries to restore that backup in a Firebird 2.1 server and finds a tag for rdb$relation_type, it's valid for gbak_2.1 but is invalid for that backup file, since such a tag was introduced in Firebird 2.1 and gbak in Firebird 1 couldn't have produced it. This means that backup is corrupt.
When restoring, gbak always assumed it was using the same server version as itself. This is not true if you are trying to downgrade the database through a backup and therefore I introduced the value RESTORE_ods in FB2.1. When restoring, gbak creates a database and can ask the server immediately what ODS version it created. RESTORE_ods is the ODS supported by the target server when restoring. If I have a backup of a system table or system field that didn't exist in that older ODS, I should skip it. The feature complicates the code and is of very limited use because gbak doesn't analyze BLR thus it won't discard unknown BLR verbs in previous server versions. Procedures that use new BLR verbs won't compile on older servers. Only data can be downgraded. I did a few tests years ago and had some success with a Firebird 2.1 backup restored with gbak 2.1 against Firebird 2.0, but when I tried to do the same from Firebird 2.5 to Firebird 2.1 some months ago, I found problems because security classes handling was changed in gbak in Firebird 2.5 and in the server, the name generation logic for security classes was changed, too. I seem to remember that I found some data that didn't fit in one of the gbak variables.
The other path is to use Firebird 1.5 gbak to connect to Firebird 2.1 and do a backup. I think it won't work, because gbak 1.5 is compiled statically to handle the field lengths that it knows in Firebird 1.5, but some fields were enlarged in Firebird 2.0 and newer and thus we'll see a nice string truncation message. If you were able to finish the backup, probably the data would be valid to do a restore on Firebird 1.5, since gbak is the same version.
Probably not what you wanted to hear. Save the new server's database's metadata in a script, tweak it to the old server, keep it in a safe place and pump the data from the new to the old server when you need it.