Read Only Database - Functional Specification
InterBase database files (InterBase V5.x and before) were required to have read/write permissions in order to be accessed by the server process. The proposal here introduces the feature by which databases may be accessed as "read-only" (RO). This document describes changes that are required in the server and some InterBase files & utilities in order to implement the above proposal.
Our developers can make InterBase databases available on CD-ROM media and end users can directly access them from the CD-ROM, purely for RO purposes.
Databases that need to be read-only for certain applications can make use of this feature. This will improve database security and thus disallow any unintended/malicious updates to the database.
GBAK utility will have a new option -mode with two possible values read_only and read_write. This will enable users to restore the databases as they choose. Further access to a read_only restored database allows only "read" operations. For e.g.:
gbak -create -mode read_only foo.gbk foo.gdb
Default mode (i.e. without -mode option) for the restore operation will be compatible with previous InterBase releases. i.e. read-write enabled databases. As a part of the "read-only" restore operation, GBAK will instruct the server to fill all data pages completely, thus not reserving any space for back-version records. See GBAK option -use_all_space for more information. This will result in better performance by reading more records from less data pages. A backup file of a RO database will restore the database as RO by default on a restore operation (the state of the RO flag is stored in the backup file). Once the restore operation is complete GBAK will print an informational message "setting database to read-only access", if the database has been restored RO.
GFIX utility will have a new option -mode with two possible values read_only and read_write which will enable users to set a database access mode to either "read_only" (RO) or "read_write" (RW). These operations require EXCLUSIVE database access. The error:
"unsuccessful metadata update, -lock time-out on wait transaction, -object <DB_file> is in use"
will be reported if these operations were tried while other application(s) were accessing the database at the same time. For e.g:
gfix -mode read_only foo.gdb
Error messages for invalid switches have been added. See New Error Messages If metadata/data changes need to be made to a database that has been restored RO using GBAK, gfix utility can be used on the database with the "-mode read_write" option.
"read_only" and "read_write" can be used to toggle database access mode.
All the above options to gbak and gfix need to be supported by InterBase API, InterBase Services API & InterClient.
GSTAT utility will show "read only" in the "Attributes" line of the "header page information" output. If this status is not shown, the database is assumed to be in a "read write" status.
`isc_database_info()` will have a new item-list option isc_info_db_read_only. This could be used to request information whether the database is read-only or not.
External files (tables with external file definitions) are also opened in a ReadOnly access mode if the database is defined to be ReadOnly. This will be the case irrespective of whether the external file's file-system permission is RO or RW. Any INSERT operations on such a file will return with the error "attempted update on read-only database".
Generators in a RO database will only be allowed to return the current value. No increment operations are allowed. For eg. the statement:
SELECT GEN_ID (generator_name, 0) FROM TABLE
succeeds, while the statement:
SELECT GEN_ID (generator_name, 1) FROM TABLE
fails with the error "attempted update on read-only database".
INSERT/UPDATE/DELETE operations on a RO database will generate the following error with SQLCODE -817. The error number is 335544765 in ibase.h. The error is "attempted update on read-only database"
|Error string||Comments||Facility||SQLCODE||Message #in msg.gdb (internal)||symbol in ibase.h||Public?|
|attempted update on read-only database||for DDL/DML statements||JRD||817||445||isc_read_only_database||Y|
|-mode read_only or read_write||GFIX Usage||GFIX||901||109||gfix_opt_mode||N|
|"read_only" or "read_write" required||GFIX incomplete option||GFIX||901||110||gfix_mode_req||Y|
|-MO(DE) <access> "read_only" or "read_write" access||GBAK Usage||GBAK||901||278||gbak_opt_mode||N|
|"read_only" or "read_write" required||GBAK incomplete option||GBAK||901||279||gbak_mode_req||Y|
|setting database to read-only access||GBAK informational message after restore operation||GBAK||N/A||280||N/A||N|
Requirements and Constraints
This feature will allow the database server to operate on a database in a read-only mode. Thus, the database is free to reside on any random-access hardware media. There are no known software platform restrictions for this feature.
- No Metadata changes will be allowed in a RO database.
- No Generator changes will be allowed in a RO database.
- The database server will not be able to perform any INSERT/UPDATE/DELETE operations on the database, either on its behalf or on behalf of the user.
- As a result of this, we could take this opportunity to not load any system or user triggers when the database is read-only, since triggers are only associated with INSERT/DELETE/UPDATE operations. Please note that the triggers are restored (GBAK -restore operation) in a read-only database (to support read/write toggle using GFIX), but they are not loaded into the server memory when the corresponding relations are scanned. This will result in performance improvement while querying the database. This performance feature is invisible to the user (from a "visual" perspective).
- External files are subject to database access mode restrictions. i.e. If database is RO, INSERT operation will not be allowed on an external file belonging to the database. This is consistent with the database access mode itself.
Does this feature introduce a major ODS change?
YES. This feature will introduce a major ODS change (ODS 10). All database servers (V6 and later) understanding ODS 10 and above will be able to make use of this feature. Database servers (V5 and earlier) will not be able to touch this database. The major ODS change is required so that databases created with InterBase V6 and subsequently made RO, should not be accessed by InterBase V5 and earlier servers since they lack the understanding of RO status of the database and thus will end up using it as a RW database. The ODS change is required to cover this possibility. This feature is unavailable for databases with ODS < 10 (since they could potentially be accessed later by an InterBase V5 server).
How do BDE, ODBC & InterClient applications accomodate the RO databases? What do they need to implement in order to be complaint?
The InterBase Services API (InterBase V6.0 and after) defines a new service isc_action_svc_properties in which database properties can be (un)set (including read-only). BDE, ODBC and JDBC drivers can make use of this API to communicate the needed functionality to the database server.
How will an InterBase V5 client application react when it tries to connect and set a database to RO ?
InterBase V5 client apps (gbak and gfix) will not understand the new options and will punt with an "invalid option" error.
How will InterBase V5 clients behave when accessing an InterBase V6 database that is RO?
InterBase V5 clients will be able to access RO InterBase V6 databases. They are subject to the same restrictions as InterBase V6 clients. i.e. DDL & DML operations (other than SELECT) are not allowed.
How will an InterBase V6 client app react when it tries to connect and set a database to RO ?
InterBase V6 client apps will understand the new options for setting a database to RO or RW and will accordingly pass the request on to the server. The server will then take action on the request. The InterBase server will react in a manner depicted in the following table to a request from InterBase V6 client apps.
|InterBase server||ODS 8.x / 9.0 database||ODS 10.0 database|
|V5.x (includes 5.0)||Will ignore DPB parameter isc_dpb_set_db_readonly, and thus does not understand RO (un)setting of database.||Server will not work on this ODS at all.|
|V6.0||Server does not attach to older ODS versions (namely 8 & 9)||Server will perform requested setting (RO/RW) on the database.|
|File/DB permissions||Behaviour in InterBase V6||Behaviour in InterBase V5 and earlier|
|Header page RO flag Set||Database will be treated as a RO database. All transactions will be RO. Appropriate errors will be produced for INSERT/UPDATE/DELETE operations. See error description above.||The RO flag is settable only in ODS>=10 databases. Since a V5 InterBase server does not understand this ODS it returns an ODS error.|
|Header page RO flag Unset||Default. Database will be treated as a RW database. All operations will be allowed subject to permissions defined for database users.||Default. Ditto as post-V5 versions.|
|Database file with RW (file-system) permission||Default. Database will be treated as RW or RO, subject to the header page flag setting (RO or not).||Default. Mandatory requirement. Database will be treated as RW enabled.|
|Database file with RO (file-system) permission||CONNECT to database will return "no privilege to do read_write on database" if header page flag is not set to RO. Access mode change from RO to RW will not be allowed through "gfix", since this requires write access to the file on a file-system level.||CONNECT to database will return file access permission error. No change here.|