Spec-Zone .ru
спецификации, руководства, описания, API
|
InnoDB
is a multi-versioned
storage engine: it keeps information about old versions of changed rows, to support transactional features
such as concurrency and rollback. This
information is stored in the tablespace in a data structure called a rollback
segment (after an analogous data structure in Oracle). InnoDB
uses the
information in the rollback segment to perform the undo operations needed in a transaction rollback. It also
uses the information to build earlier versions of a row for a consistent read.
Internally, InnoDB
adds three fields to each row stored in the database. A 6-byte
DB_TRX_ID
field indicates the transaction identifier for the last transaction that
inserted or updated the row. Also, a deletion is treated internally as an update where a special bit in the row
is set to mark it as deleted. Each row also contains a 7-byte DB_ROLL_PTR
field
called the roll pointer. The roll pointer points to an undo log record written to the rollback segment. If the
row was updated, the undo log record contains the information necessary to rebuild the content of the row before
it was updated. A 6-byte DB_ROW_ID
field contains a row ID that increases
monotonically as new rows are inserted. If InnoDB
generates a clustered index
automatically, the index contains row ID values. Otherwise, the DB_ROW_ID
column
does not appear in any index.
Undo logs in the rollback segment are divided into insert and update undo logs. Insert undo logs are needed only
in transaction rollback and can be discarded as soon as the transaction commits. Update undo logs are used also
in consistent reads, but they can be discarded only after there is no transaction present for which InnoDB
has assigned a snapshot that in a consistent read could need the
information in the update undo log to build an earlier version of a database row.
In MySQL 5.5, the limit on concurrent data-modifying transactions was significantly increased by removing a bottleneck that resulted from a single InnoDB rollback segment that supported a maximum of 1023 concurrent data-modifying transactions. The single rollback segment was divided into 128 segments, each supporting up to 1023 transactions, creating a new limit of approximately 128K concurrent transactions.
In MySQL 5.7.2, the 128K transaction limit is reduced to 96K in order to support the introduction of a new type of undo log for normal and compressed temporary tables and related objects. 32 of the 128 rollback segments are now reserved for temporary table transactions.
Each transaction that updates a temporary table, excluding read-only transactions, is assigned two rollback segments, one redo rollback segment and one non-redo rollback segment. Read-only transactions are only assigned non-redo rollback segments, as read-only transactions are only permitted to modify temporary tables.
This change leaves 96 segments, each supporting up to 1023 transactions, for a limit of 96K concurrent data-modifying transactions. The 96K limit assumes that transactions do not modify temporary tables. If all data-modifying transactions also modify temporary tables, the limit would be 32K concurrent transactions.
Commit your transactions regularly, including those transactions that issue only consistent reads. Otherwise,
InnoDB
cannot discard data from the update undo logs, and the rollback segment may
grow too big, filling up your tablespace.
The physical size of an undo log record in the rollback segment is typically smaller than the corresponding inserted or updated row. You can use this information to calculate the space needed for your rollback segment.
In the InnoDB
multi-versioning scheme, a row is not physically removed from the
database immediately when you delete it with an SQL statement. InnoDB
only
physically removes the corresponding row and its index records when it discards the update undo log record
written for the deletion. This removal operation is called a purge, and it is quite fast,
usually taking the same order of time as the SQL statement that did the deletion.
If you insert and delete rows in smallish batches at about the same rate in the table, the purge thread can
start to lag behind and the table can grow bigger and bigger because of all the "dead" rows, making everything disk-bound and very slow. In such a case,
throttle new row operations, and allocate more resources to the purge thread by tuning the innodb_max_purge_lag
system variable. See Section
14.2.6, "InnoDB
Startup Options and System Variables" for more information.