mirror of
https://github.com/sqlite/sqlite.git
synced 2024-11-22 12:17:40 +01:00
86 lines
4.1 KiB
Markdown
86 lines
4.1 KiB
Markdown
|
|
||
|
Shared-Schema Mode Notes
|
||
|
========================
|
||
|
|
||
|
This branch contains a patch to allow SQLite connections to share schemas
|
||
|
between database connections within the same process in order to save memory.
|
||
|
Schemas may be shared between multiple databases attached to the same or
|
||
|
distinct connection handles.
|
||
|
|
||
|
To activate shared-schemas, a database connection must be opened using the
|
||
|
sqlite3_open_v2() API with the SQLITE_OPEN_SHARED_SCHEMA
|
||
|
flag specified. The main database and any attached databases will then share
|
||
|
an in-memory Schema object with any other database opened within the process
|
||
|
for which:
|
||
|
|
||
|
* the contents of the sqlite_master table, including all object names,
|
||
|
SQL statements and root pages are identical, and
|
||
|
* have the same values for the schema-cookie.
|
||
|
|
||
|
Temp databases (those populated with "CREATE TEMP TABLE" and similar
|
||
|
statements) never share schemas.
|
||
|
|
||
|
Connections opened with the SQLITE_OPEN_SHARED_SCHEMA flag
|
||
|
specified may not modify any database schema except that belonging to the
|
||
|
temp database in anyway. This includes creating or dropping database
|
||
|
objects, vacuuming the database, or running ANALYZE when the
|
||
|
sqlite_stat\[14\] tables do not exist.
|
||
|
|
||
|
If the schema of a database attached to an
|
||
|
SQLITE_OPEN_SHARED_SCHEMA database handle is corrupt, or if
|
||
|
corruption is encountered while parsing the database schema, then the
|
||
|
database is treated as empty. This usually means that corruption results in
|
||
|
a "no such table: xxx" error instead of a more specific error message.
|
||
|
|
||
|
For SQLITE_OPEN_SHARED_SCHEMA connections, the
|
||
|
SQLITE_DBSTATUS_SCHEMA_USED sqlite3_db_used() distributes
|
||
|
the memory used for a shared schema object evenly between all database
|
||
|
connections that share it.
|
||
|
|
||
|
## Implementation Notes
|
||
|
|
||
|
A single Schema object is never used by more than database simultaneously,
|
||
|
regardless of whether or not those databases are attached to the same or
|
||
|
different database handles. Instead, a pool of schema objects is maintained
|
||
|
for each unique sqlite_master-contents/schema-cookie combination
|
||
|
opened within the process. Each time database schemas are required by a
|
||
|
connection, for example as part of an sqlite3_prepare\*(),
|
||
|
sqlite3_blob_open() or sqlite3_blob_open() call, it obtains
|
||
|
the minimum number of schemas required from the various schema-pools, returning
|
||
|
them at the end of the call. This means that a single schema-pool only ever
|
||
|
contains more than one copy of the schema if:
|
||
|
|
||
|
* Two threads require schemas from the same pool at the same time, or
|
||
|
* A single sqlite3_prepare\*() call requires schemas for two or more
|
||
|
attached databases that use the same schema-pool.
|
||
|
|
||
|
The size of a schema-pool never shrinks. Each schema pool always maintains
|
||
|
a number of schema objects equal to the highwater mark of schema objects
|
||
|
simultaneously required by clients.
|
||
|
|
||
|
This approach is preferred to allowing multiple databases to use the same
|
||
|
Schema object simultaneously for three reasons:
|
||
|
|
||
|
* The Schema object is not completely read-only. For example, the
|
||
|
Index.zIdxAff string is allocated lazily.
|
||
|
* Throughout the statement compiler, SQLite uses variables like
|
||
|
Table.pSchema and Index.pSchema with the sqlite3SchemaToIndex() routine
|
||
|
in order to determine which attached database a Table or Index object
|
||
|
resides in. This mechanism does not work if the same Schema may be
|
||
|
used by two or more attached databases.
|
||
|
* It may be easier to modify this approach in order to allow
|
||
|
SQLITE_OPEN_SHARED_SCHEMA connections to modify database
|
||
|
schemas, should that be required.
|
||
|
|
||
|
SQLITE_OPEN_SHARED_SCHEMA connections do not store their
|
||
|
virtual-table handles in the Table.pVTable list of each table. This would not
|
||
|
work, as (a) there is no guarantee that a connection will be assigned the same
|
||
|
Schema object each time it requests one from a schema-pool and (b) a single
|
||
|
Schema (and therefore Table) object may correspond to tables in two or more
|
||
|
databases attached to a single connection. Instead, all virtual-table handles
|
||
|
associated with a single database are stored in a linked-list headed at
|
||
|
Db.pVTable.
|
||
|
|
||
|
|
||
|
|