14.6 InnoDB Table Management mysql
14.6.1 Creating InnoDB Tablesios
14.6.2 Moving or Copying InnoDB Tables to Another Machinegit
14.6.3 Grouping DML Operations with Transactions算法
14.6.4 Converting Tables from MyISAM to InnoDBsql
14.6.5 AUTO_INCREMENT Handling in InnoDBshell
14.6.6 InnoDB and FOREIGN KEY Constraints數據庫
14.6.7 Limits on InnoDB Tables緩存
14.6.1 Creating InnoDB Tables 安全
To create an InnoDB table, use the CREATE TABLE statement. You do not need to specify the ENGINE=InnoDB clause if InnoDB is defined as the default storage engine, which is the default as of MySQL 5.5. You might still use ENGINE=InnoDB clause if you plan to use mysqldump or replication to replay the CREATE TABLE statement on a server where the default storage engine is not InnoDB.服務器
可使用CREATE TABLE語句建立一個InnoDB表。從MySQL5.5開始,InnoDB就是默認的存儲引擎,因此你不須要指定ENGINE=InnoDB子句。當你準備在默認引擎不是InnoDB的實例上使用mysqldump或者複製重現CREATE TABLE的時候仍然可使用ENGINE=InnoDB。
-- Default storage engine = InnoDB.
CREATE TABLE t1 (a INT, b CHAR (20), PRIMARY KEY (a));
-- Backward-compatible with older MySQL.
CREATE TABLE t2 (a INT, b CHAR (20), PRIMARY KEY (a)) ENGINE=InnoDB;
An InnoDB table and its indexes can be created in the system tablespace or in a file-per-table tablespace. When innodb_file_per_table is enabled, which is the default setting as of MySQL 5.6.6, an InnoDB table is implicitly created in an individual file-per-table tablespace. Conversely, when innodb_file_per_table is disabled, an InnoDB table is implicitly created in the system tablespace.
InnoDB的表和索引能夠建立在系統表空間或者file-per-table表空間裏。當開啓了自MySQL5.6.6開始默認的innodb_file_per_table,InnoDB表會隱式地建立在一個獨立的file-per-table表空間裏。相反,當innodb_file_per_table關閉的時候,InnoDB表會隱式地建立在系統表空間裏。
When you create an InnoDB table, MySQL creates a .frm file in a database directory under the MySQL data directory. For a table created in a file-per-table tablespace, an .ibd file is also created. A table created in the system tablespace is created in the existing system tablespace ibdata files.
當你建立了一個InnoDB表的時候,MySQL會在MySQL的數據目錄的數據庫目錄裏建立一個.frm,以及一個.ibd文件。建立在系統表空間裏的表會被放在現有的系統表空間ibdata文件裏。
Internally, InnoDB adds an entry for each table to the InnoDB data dictionary. The entry includes the database name. For example, if table t1 is created in the test database, the data dictionary entry is 'test/t1'. This means you can create a table of the same name (t1) in a different database, and the table names do not collide inside InnoDB.
在內部,InnoDB會爲每一個表在InnoDB的數據字典裏面建立一個包含數據庫名的條目。例如,表t1建立在test數據庫裏,數據字典條目就是'test/t1'。這也就意味着你能夠在不一樣的數據庫裏面建立名字相同的表。在InnoDB內部這些表的名字並不會衝突。
Viewing the Properties of InnoDB Tables
To view the properties of InnoDB tables, issue a SHOW TABLE STATUS statement:
執行SHOW TABLE STATUS語句查看InnoDB表的屬性:
mysql> SHOW TABLE STATUS FROM test LIKE 't%' \G;
*************************** 1. row ***************************
Name: t1
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2015-03-16 16:26:52
Update_time: NULL
Check_time: NULL
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
In the status output, you see the Row format property of table t1 is Compact. Although that setting is fine for basic experimentation, consider using the Dynamic or Compressed row format to take advantage of InnoDB features such as table compression and off-page storage for long column values. Using these row formats requires that innodb_file_per_table is enabled (the default as of MySQL 5.6.6) and that innodb_file_format is set to Barracuda:
在狀態輸出裏面,你能夠看到t1表的Row format屬性是Compact。雖然根據基本的實驗這是一個不錯的設定,可是也能夠考慮使用InnoDB的特性優點使用Dynamic或者Compressed行格式,例如爲很長的列值使用表壓縮和不一樣的頁大小存儲(off-page storage)。
SET GLOBAL innodb_file_per_table=1;
SET GLOBAL innodb_file_format=barracuda;
CREATE TABLE t3 (a INT, b CHAR (20), PRIMARY KEY (a)) ROW_FORMAT=DYNAMIC;
CREATE TABLE t4 (a INT, b CHAR (20), PRIMARY KEY (a)) ROW_FORMAT=COMPRESSED;
InnoDB table properties may also be queried using the InnoDB Information Schema system tables:
InnoDB表的熟悉一樣也經過查詢InnoDB Information Schema的系統表:
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1' \G
*************************** 1. row ***************************
TABLE_ID: 42
NAME: test/t1
FLAG: 1
N_COLS: 5
SPACE: 24
FILE_FORMAT: Antelope
ROW_FORMAT: Compact
ZIP_PAGE_SIZE: 0
1 row in set (0.02 sec)
Defining a Primary Key for InnoDB Tables
Always set up a primary key for each InnoDB table, specifying the column or columns that:
爲每一個InnoDB表在這些列上創建主鍵:
For example, in a table containing information about people, you would not create a primary key on (firstname, lastname) because more than one person can have the same name, some people have blank last names, and sometimes people change their names. With so many constraints, often there is not an obvious set of columns to use as a primary key, so you create a new column with a numeric ID to serve as all or part of the primary key. You can declare an auto-increment column so that ascending values are filled in automatically as rows are inserted:
例如,在一個關於人口信息的表裏,你不能在(firstname, lastname)上建立主鍵由於有可能會有同名的狀況,有些只有last name,還有些人會修改他們的名字。正由於有這麼多的約束,這裏沒有明顯的列來做爲主鍵,那你能夠建立一個新的數字ID列來做爲主鍵。你能夠把列定義成自增加列,使得在insert的時候自動填充遞增的值:
-- The value of ID can act like a pointer between related items in different tables.
CREATE TABLE t5 (id INT AUTO_INCREMENT, b CHAR (20), PRIMARY KEY (id));
-- The primary key can consist of more than one column. Any autoinc column must come first.
CREATE TABLE t6 (id INT AUTO_INCREMENT, a INT, b CHAR (20), PRIMARY KEY (id,a));
Although the table works correctly without defining a primary key, the primary key is involved with many aspects of performance and is a crucial design aspect for any large or frequently used table. It is recommended that you always specify a primary key in the CREATE TABLE statement. If you create the table, load data, and then run ALTER TABLE to add a primary key later, that operation is much slower than defining the primary key when creating the table.
雖然即便沒有定義主鍵表也能工做,可是主鍵涉及了不少性能方面的問題,以及對大表或者頻繁使用的表的核心設計問題,因此建議你在CREATE TABLE的時候仍是要指定一個主鍵。若是你建立了表,加載了數據,而後再運行ALTER TABLE來加主鍵,那這個操做將會比在建表的時候定義主鍵要慢得不少。
14.6.2 Moving or Copying InnoDB Tables to Another Machine
This section describes techniques for moving or copying some or all InnoDB tables to a different server. For example, you might move an entire MySQL instance to a larger, faster server; you might clone an entire MySQL instance to a new replication slave server; you might copy individual tables to another server to develop and test an application, or to a data warehouse server to produce reports.
這一章節講述瞭如何複製或者移動InnoDB表到不一樣的實例裏。例如,你要把整個MySQL實例移動到一個更大,速度更快的服務器上;你要克隆整個MySQL實例到一個新的主從架構的從機上;你能夠也能夠複製個別表到開發或者測試環境裏,又或者是數據倉庫裏。
Techniques for moving or copying InnoDB tables include:
這些移動複製InnoDB表的方法有:
Using Lowercase Names for Cross-Platform Moving or Copying
On Windows, InnoDB always stores database and table names internally in lowercase. To move databases in a binary format from Unix to Windows or from Windows to Unix, create all databases and tables using lowercase names. A convenient way to accomplish this is to add the following line to the [mysqld] section of your my.cnf or my.ini file before creating any databases or tables:
在Windows上,InnoDB在內部用小寫來存儲數據庫和表的名字。要把二進制格式的數據庫從Unix移動到Windows上或者從Windows到Unix上,數據庫和表的名字最好都用小寫。還有一種方法能夠實現這樣的目的就是在建立任何的數據庫或表以前,在配置文件my.cnf or my.ini的[mysqld]里加入下面的內容:
[mysqld]
lower_case_table_names=1
Introduced in MySQL 5.6.6, the transportable tablespaces feature uses FLUSH TABLES ... FOR EXPORT to ready InnoDB tables for copying from one server instance to another. To use this feature, InnoDB tables must be created with innodb_file_per_table set to ON so that each InnoDB table has its own tablespace. For usage information, see Section 14.5.6, "Copying File-Per-Table Tablespaces to Another Server".
在MySQL5.6.6裏,可使用FLUSH TABLES ... FOR EXPORT的傳輸表空間特性來把一個InnoDB表複製到另外一個實例上。要使用這個特性,innodb_file_per_table必須是要打開的,讓每一個InnoDB表都有本身的表空間。相關的使用信息能夠查看Section 14.5.6, "Copying File-Per-Table Tablespaces to Another Server"。
The MySQL Enterprise Backup product lets you back up a running MySQL database, including InnoDB and MyISAM tables, with minimal disruption to operations while producing a consistent snapshot of the database. When MySQL Enterprise Backup is copying InnoDB tables, reads and writes to both InnoDB and MyISAM tables can continue. During the copying of MyISAM and other non-InnoDB tables, reads (but not writes) to those tables are permitted. In addition, MySQL Enterprise Backup can create compressed backup files, and back up subsets of InnoDB tables. In conjunction with the MySQL binary log, you can perform point-in-time recovery. MySQL Enterprise Backup is included as part of the MySQL Enterprise subscription.
MySQL Enterprise Backup可讓你備份一個正在運行的MySQL數據庫,包括InnoDB和MyISAM表,並且在生產數據庫一致性快照的時候可以最小化地中斷正常的操做。當MySQL Enterprise Backup複製InnoDB表的時候,InnoDB和MyISAM表都可以繼續讀和寫的操做。在複製MyISAM和其餘非InnoDB表的時候,讀操做(不包括寫)是被容許的。另外,MySQL Enterprise Backup可以建立壓縮過的備份文件,並以此來備份InnoDB表的子集。連同MySQL的binary log,你還能夠執行基於時間點的恢復。MySQL Enterprise Backup包含在MySQL Enterprise裏面的。
For more details about MySQL Enterprise, see Section 25.2, "MySQL Enterprise Backup Overview".
更多關於MySQL Enterprise的細節能夠查看Section 25.2, "MySQL Enterprise Backup Overview"。
Copying Data Files (Cold Backup Method)
You can move an InnoDB database simply by copying all the relevant files listed under "Cold Backups" in Section 14.16, "InnoDB Backup and Recovery".
如Section 14.16, "InnoDB Backup and Recovery"裏面"Cold Backups"所講述的,你能夠複製全部相關的文件來簡單地移動InnoDB數據庫。
Like MyISAM data files, InnoDB data and log files are binary-compatible on all platforms having the same floating-point number format. If the floating-point formats differ but you have not used FLOAT or DOUBLE data types in your tables, then the procedure is the same: simply copy the relevant files.
相似於MyISAM的數據文件,InnoDB的數據和日誌文件在全部使用相同浮點格式的平臺上都是兼容的。若是浮點格式不一樣可是在表裏也沒有使用FLOAT or DOUBLE的數據類型,也是能夠進行簡單複製的。
Portability Considerations for .ibd Files
When you move or copy .ibd files, the database directory name must be the same on the source and destination systems. The table definition stored in the InnoDB shared tablespace includes the database name. The transaction IDs and log sequence numbers stored in the tablespace files also differ between databases.
當你移動或者複製.ibd文件的時候,源端和目標端的數據庫名必須是相同的。表定義存儲的InnoDB共享表空間裏也包括了數據庫名。不一樣數據庫之間transaction IDs and log sequence numbers也是不一樣的。
To move an .ibd file and the associated table from one database to another, use a RENAME TABLE statement:
要把一個.ibd文件和相關的表從一個數據庫移動到另外一個的時候,可使用RENAME TABLE語句:
RENAME TABLE db1.tbl_name TO db2.tbl_name;
If you have a "clean" backup of an .ibd file, you can restore it to the MySQL installation from which it originated as follows:
若是你有一個"乾淨的".ibd文件備份,你能夠在下面的MySQL原始安裝步驟裏恢復它:
1.The table must not have been dropped or truncated since you copied the .ibd file, because doing so changes the table ID stored inside the tablespace.
1.自從你複製了.ibd文件以後表必須是沒有drop或者truncate的,由於這些操做會修改存儲在表空間裏的 table ID
2.Issue this ALTER TABLE statement to delete the current .ibd file:
2.執行ALTER TABLE語句來刪除當前的.ibd文件:
ALTER TABLE tbl_name DISCARD TABLESPACE;
3.Copy the backup .ibd file to the proper database directory.
3.複製備份的.ibd文件到適當的數據庫目錄。
4.Issue this ALTER TABLE statement to tell InnoDB to use the new .ibd file for the table:
4.執行ALTER TABLE語句告訴InnoDB爲表使用新的.ibd文件:
ALTER TABLE tbl_name IMPORT TABLESPACE;
Note
The ALTER TABLE ... IMPORT TABLESPACE feature does not enforce foreign key constraints on imported data.
ALTER TABLE ... IMPORT TABLESPACE特性不會在導入的數據上強制實施外鍵約束。
In this context, a "clean" .ibd file backup is one for which the following requirements are satisfied:
在這個環境裏,"乾淨的".ibd文件備份是要知足下面的要求的:
You can make a clean backup .ibd file using the following method:
你可使用下面的方法建立一個乾淨的.ibd備份文件:
1.Stop all activity from the mysqld server and commit all transactions.
1.在mysqld服務上中止全部的活動,並提交全部的事務。
2.Wait until SHOW ENGINE INNODB STATUS shows that there are no active transactions in the database, and the main thread status of InnoDB is Waiting for server activity. Then you can make a copy of the .ibd file.
2.等到SHOW ENGINE INNODB STATUS顯示的數據庫裏已經沒有活動的事務的,InnoDB的主線程狀態是Waiting for server activity。這個時候就能夠複製.ibd文件了。
Another method for making a clean copy of an .ibd file is to use the MySQL Enterprise Backup product:
另外一個建立乾淨的.ibd文件的方法是使用MySQL Enterprise Backup:
1.Use MySQL Enterprise Backup to back up the InnoDB installation.
1.使用MySQL Enterprise Backup來備份InnoDB安裝。
2.Start a second mysqld server on the backup and let it clean up the .ibd files in the backup.
2.在備份上啓動第二個mysqld服務,並在備份裏面清除.ibd文件。
You can use mysqldump to dump your tables on one machine and then import the dump files on the other machine. Using this method, it does not matter whether the formats differ or if your tables contain floating-point data.
你可使用mysqldump從一臺機器上導出表,再在另外一臺機器上導入這些dump文件。這種方法能夠忽略平臺的差別。
One way to increase the performance of this method is to switch off autocommit mode when importing data, assuming that the tablespace has enough space for the big rollback segment that the import transactions generate. Do the commit only after importing a whole table or a segment of a table.
這種方式下想要增長性能能夠在導入的時候關閉autocommit,可是要確保表空間有足夠的回滾空間來存放導入的事務。而後在導入完整個表或者表的分段的時候再執行commit。
14.6.3 Grouping DML Operations with Transactions
By default, connection to the MySQL server begins with autocommit mode enabled, which automatically commits every SQL statement as you execute it. This mode of operation might be unfamiliar if you have experience with other database systems, where it is standard practice to issue a sequence of DML statements and commit them or roll them back all together.
默認狀況下,鏈接到MySQL服務開始的時候使用的是autocommit模式,這會在你執行的每一個SQL語句後面自動進行commit。這種操做模式可能不一樣於其餘的數據庫系統,其餘數據庫的標準慣例是執行完DML語句以後在進行commit或者rollback。
To use multiple-statement transactions, switch autocommit off with the SQL statement SET autocommit = 0 and end each transaction with COMMIT or ROLLBACK as appropriate. To leave autocommit on, begin each transaction with START TRANSACTION and end it with COMMIT or ROLLBACK. The following example shows two transactions. The first is committed; the second is rolled back.
要使用多語句事務,則要使用SET autocommit = 0來關閉autocommit,並在每一個事務的尾端執行適當的COMMIT或者ROLLBACK。還有一種方式能夠關閉autocommit,在每一個事務開始的時候運行START TRANSACTION,在結尾的地方運行COMMIT或者ROLLBACK。下面的例子顯示了兩個事務,第一個進行了commit,第二個作了rollback。
shell> mysql test
mysql> CREATE TABLE customer (a INT, b CHAR (20), INDEX (a));
Query OK, 0 rows affected (0.00 sec)
mysql> -- Do a transaction with autocommit turned on.
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO customer VALUES (10, 'Heikki');
Query OK, 1 row affected (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql> -- Do another transaction with autocommit turned off.
mysql> SET autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO customer VALUES (15, 'John');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO customer VALUES (20, 'Paul');
Query OK, 1 row affected (0.00 sec)
mysql> DELETE FROM customer WHERE b = 'Heikki';
Query OK, 1 row affected (0.00 sec)
mysql> -- Now we undo those last 2 inserts and the delete.
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM customer;
+------+--------+
| a | b |
+------+--------+
| 10 | Heikki |
+------+--------+
1 row in set (0.00 sec)
mysql>
Transactions in Client-Side Languages
In APIs such as PHP, Perl DBI, JDBC, ODBC, or the standard C call interface of MySQL, you can send transaction control statements such as COMMIT to the MySQL server as strings just like any other SQL statements such as SELECT or INSERT. Some APIs also offer separate special transaction commit and rollback functions or methods.
在一些其餘程序的接口如PHP, Perl DBI, JDBC, ODBC, or the standard C上,你能夠和其餘的SQL語句同樣經過發送COMMIT到MySQL服務器來控制事務。一些接口還提供獨立的特殊事務的commit和rollback函數。
14.6.4 Converting Tables from MyISAM to InnoDB
If you have existing tables, and applications that use them, that you want to convert to InnoDB for better reliability and scalability, use the following guidelines and tips. This section assumes most such tables were originally MyISAM, which was formerly the default.
若是你已經有一些表,應用程序也都在使用它們,你想把它們轉化成InnoDB以得到更好的可靠性和可擴展性,就可使用下面的知道建議。這一章節假設有不少原來默認的就是MyISAM的表。
Reduce Memory Usage for MyISAM, Increase Memory Usage for InnoDB
As you transition away from MyISAM tables, lower the value of the key_buffer_size configuration option to free memory no longer needed for caching results. Increase the value of the innodb_buffer_pool_size configuration option, which performs a similar role of allocating cache memory for InnoDB tables. The InnoDB buffer pool caches both table data and index data, so it does double duty in speeding up lookups for queries and keeping query results in memory for reuse.
由於MyISAM表是不能使用事務的,那麼能夠把key_buffer_size配置成一個較小的值來節約更多的內存。增長innodb_buffer_pool_size配置參數的值,讓InnoDB能夠分配更多的內存。InnoDB buffer pool能夠同時緩存表數據和索引數據,因此它有雙重的責任來加速查詢的速度,並把查詢結果緩存在內存裏進行重複使用。
Watch Out for Too-Long Or Too-Short Transactions
Because MyISAM tables do not support transactions, you might not have paid much attention to the autocommit configuration option and the COMMIT and ROLLBACK statements. These keywords are important to allow multiple sessions to read and write InnoDB tables concurrently, providing substantial scalability benefits in write-heavy workloads.
由於MyISAM表不支持事務,你可能不怎麼會關注autocommit的配置以及COMMIT,ROLLBACK語句。但這些關鍵字對於多session併發讀寫InnoDB表則是很是重要的,它們可以在寫負載高的狀況下提供更好的擴展性。
While a transaction is open, the system keeps a snapshot of the data as seen at the beginning of the transaction, which can cause substantial overhead if the system inserts, updates, and deletes millions of rows while a stray transaction keeps running. Thus, take care to avoid transactions that run for too long:
當開啓了一個事務,系統會保持一個事務開啓點時數據的快照,那麼若是事務繼續在運行,那麼系統就要大量地Insert,update和delete成千上萬的行數據,並帶來大量的系統資源損耗。所以,要避免事務太長:
The preceding tips save memory and disk space that can be wasted during too-long transactions. When transactions are shorter than they should be, the problem is excessive I/O. With each COMMIT, MySQL makes sure each change is safely recorded to disk, which involves some I/O.
太長的事務會浪費內存和磁盤的空間。可是當事務過短的時候,過多的I/O也那會是個問題。每一個COMMIT語句,MySQL都要確保每一個修改都已經安全寫入到磁盤上,這就涉及到了不少的I/O操做。
Don't Worry Too Much About Deadlocks
You might see warning messages referring to "deadlocks" in the MySQL error log, or the output of SHOW ENGINE INNODB STATUS. Despite the scary-sounding name, a deadlock is not a serious issue for InnoDB tables, and often does not require any corrective action. When two transactions start modifying multiple tables, accessing the tables in a different order, they can reach a state where each transaction is waiting for the other and neither can proceed. MySQL immediately detects this condition and cancels (rolls back) the "smaller" transaction, allowing the other to proceed.
你可能會在MySQL的error log或者是SHOW ENGINE INNODB STATUS的輸出裏看到相關"deadlocks(死鎖)"的警告信息。除去不怎麼好的名字,死鎖對於InnoDB表來講並非什麼嚴重的問題,也不須要什麼補救的動做。當兩個事務以不一樣的順序訪問修改多個表的時候,那就會發生相互等待對方的狀況。MySQL會當即發現這種狀況,並取消(回滾)較小的那個事務,以便另外一個操做可以繼續。
Your applications do need error-handling logic to restart a transaction that is forcibly cancelled like this. When you re-issue the same SQL statements as before, the original timing issue no longer applies: either the other transaction has already finished and yours can proceed, or the other transaction is still in progress and your transaction waits until it finishes.
你的應用程序要有錯誤處理邏輯來重啓事務以便強制取消。當你再執行和以前相同的SQL語句的時候,原來事務的時間戳將再也不適用:要麼是其餘的事務已經結束而你的仍然在繼續,要麼是其餘的事務仍然在處理而你的事務則要等到其結束。
If deadlock warnings occur constantly, you might review the application code to reorder the SQL operations in a consistent way, or to shorten the transactions. You can test with the innodb_print_all_deadlocks option enabled to see all deadlock warnings in the MySQL error log, rather than only the last warning in the SHOW ENGINE INNODB STATUS output.
若是不斷地發生死鎖的警告,你須要review應用程序的代碼以一致的方式從新排序SQL的操做,又或者再減短事務。你能夠經過開啓innodb_print_all_deadlocks參數進行測試來查看MySQL的error log裏面全部的死鎖警告(SHOW ENGINE INNODB STATUS的輸出裏只有最後一次的警告)。
Plan the Storage Layout
To get the best performance from InnoDB tables, you can adjust a number of parameters related to storage layout.
InnoDB表要等到最佳的性能,你能夠調整一系列存儲佈局相關的參數。
When you convert MyISAM tables that are large, frequently accessed, and hold vital data, investigate and consider the innodb_file_per_table, innodb_file_format, and innodb_page_size configuration options, and the ROW_FORMAT and KEY_BLOCK_SIZE clauses of the CREATE TABLE statement.
當你要轉換的MyISAM表很是大,並且還要頻繁訪問,又是相當重要的時候,那就要調查考慮這幾個參數:innodb_file_per_table, innodb_file_format, and innodb_page_size,還有在CREATE TABLE語句中的ROW_FORMAT and KEY_BLOCK_SIZE子句。
During your initial experiments, the most important setting is innodb_file_per_table. When this setting is enabled, which is the default as of MySQL 5.6.6, new InnoDB tables are implicitly created in file-per-table tablespaces. In contrast with the InnoDB system tablespace, file-per-table tablespaces allow disk space to be reclaimed by the operating system when a table is truncated or dropped. File-per-table tablespaces also support the Barracuda file format and associated features such as table compression and off-page storage for long variable-length columns. For more information, see Section 14.5.4, "InnoDB File-Per-Table Tablespaces".
開始的實驗證實innodb_file_per_table是最爲重要的參數。當這個參數開啓(從MySQL5.6.6開始默認是開啓的)的時候,新的InnoDB表會隱式地建立在file-per-table表空間裏。相對於InnoDB的系統表空間,當表被truncate或者drop的時候file-per-table表空間容許磁盤空間能被操做系統進行回收利用。file-per-table表空間還支持Barracuda文件格式以及其相關的特性,例如表壓縮,以及off-page storage for long variable-length columns。更多信息能夠查看Section 14.5.4, "InnoDB File-Per-Table Tablespaces"。
Converting an Existing Table
To convert a non-InnoDB table to use InnoDB use ALTER TABLE:
使用ALTER TABLE把非InnoDB錶轉成InnoDB表:
ALTER TABLE table_name ENGINE=InnoDB;
Important
Do not convert MySQL system tables in the mysql database (such as user or host) to the InnoDB type. This is an unsupported operation. The system tables must always be of the MyISAM type.
不要把在mysql數據庫裏的MySQL系統錶轉化成InnoDB的類型。這個操做是不支持的。系統表必需要是MyISAM類型的。
Cloning the Structure of a Table
You might make an InnoDB table that is a clone of a MyISAM table, rather than doing the ALTER TABLE conversion, to test the old and new table side-by-side before switching.
你能夠把一個MyISAM表克隆成InnoDB表,而不用執行ALTER TABLE來進行轉換,這樣能夠在切換以前對新舊錶分別進行測試。
Create an empty InnoDB table with identical column and index definitions. Use show create table table_name\G to see the full CREATE TABLE statement to use. Change the ENGINE clause to ENGINE=INNODB.
建立一個空的有相同列和索引定義的InnoDB表。使用create table table_name\G能夠看到完整的CREATE TABLE語句來使用,只要把ENGINE子句改爲ENGINE=INNODB。
Transferring Existing Data
To transfer a large volume of data into an empty InnoDB table created as shown in the previous section, insert the rows with INSERT INTO innodb_table SELECT * FROM myisam_table ORDER BY primary_key_columns.
要把大量的數據傳輸到上文建立的空InnoDB表裏,能夠經過INSERT INTO innodb_table SELECT * FROM myisam_table ORDER BY primary_key_columns來插入數據。
You can also create the indexes for the InnoDB table after inserting the data. Historically, creating new secondary indexes was a slow operation for InnoDB, but now you can create the indexes after the data is loaded with relatively little overhead from the index creation step.
你還能夠在插入數據以後爲InnoDB表建立索引。之前,對於InnoDB來講建立一個新的secondary index是一個很是慢的操做,但如今在加載完數據以後建立索引只要不多的成本開銷。
If you have UNIQUE constraints on secondary keys, you can speed up a table import by turning off the uniqueness checks temporarily during the import operation:
若是你在secondary index上有UNIQUE約束,那你能夠在導入操做的時候臨時關閉惟一檢查來加快導入的速度:
SET unique_checks=0;
... import operation ...
SET unique_checks=1;
For big tables, this saves disk I/O because InnoDB can use its change buffer to write secondary index records as a batch. Be certain that the data contains no duplicate keys. unique_checks permits but does not require storage engines to ignore duplicate keys.
對於大表來講,這可以減小磁盤的I/O,由於InnoDB能夠用它本身的change buffer來批量寫secondary index記錄。固然你須要本身去確認導入的沒有重複的key,unique_checks會容許你插入重複key但不會要求存儲引擎去忽略重複的key。
To get better control over the insertion process, you might insert big tables in pieces:
爲了更好地控制插入操做,你能夠分片插入大表:
INSERT INTO newtable SELECT * FROM oldtable
WHERE yourkey > something AND yourkey <= somethingelse;
After all records have been inserted, you can rename the tables.
在全部的記錄都被插入以後,那你就能夠重命名錶了。
During the conversion of big tables, increase the size of the InnoDB buffer pool to reduce disk I/O, to a maximum of 80% of physical memory. You can also increase the sizes of the InnoDB log files.
在轉換大表的過程當中,適當增長InnoDB buffer pool的值可以減小磁盤的I/O,最大能夠增長到物理內存的80%。一樣你也能夠增長InnoDB日誌文件的大小。
Storage Requirements
If you intend to make several temporary copies of your data in InnoDB tables during the conversion process, it is recommended that you create the tables in file-per-table tablespaces so that you can reclaim the disk space when you drop the tables. As mentioned previously, when the innodb_file_per_table option is enabled, newly created InnoDB tables are implicitly created in file-per-table tablespaces.
若是你想要在轉換的過程當中多作幾個臨時拷貝,那就要求你把表建在file-per-table的表空間裏,這樣當你刪除表的時候就能再利用磁盤空間。就如前面是所說的,當開啓了innodb_file_per_table,最新建立的InnoDB表會隱式地建立在file-per-table表空間裏。
Whether you convert the MyISAM table directly or create a cloned InnoDB table, make sure that you have sufficient disk space to hold both the old and new tables during the process. InnoDB tables require more disk space than MyISAM tables. If an ALTER TABLE operation runs out of space, it starts a rollback, and that can take hours if it is disk-bound. For inserts, InnoDB uses the insert buffer to merge secondary index records to indexes in batches. That saves a lot of disk I/O. For rollback, no such mechanism is used, and the rollback can take 30 times longer than the insertion.
不管你是直接轉換MyISAM表仍是建立了一個克隆的InnoDB表,都要確保有足夠的磁盤空間在處理過程當中可以同時保存新舊錶的數據。相對於MyISAM表,InnoDB表會要求更多的磁盤空間。若是ALTER TABLE運行的時候磁盤空間不夠了,那麼實例就會進行回滾,那可能就會要花費數個小時。對於插入操做,InnoDB會使用insert buffer來批量合併secondary index記錄,這樣就能節省不少的磁盤I/O。For rollback, no such mechanism is used, and the rollback can take 30 times longer than the insertion.
In the case of a runaway rollback, if you do not have valuable data in your database, it may be advisable to kill the database process rather than wait for millions of disk I/O operations to complete. For the complete procedure, see Section 14.19.2, "Forcing InnoDB Recovery".
對於這種失控回滾的狀況,若是數據庫中的數據不是過重要,那麼比較明智的作法是kill掉數據庫的操做線程,而不是等待上百萬的磁盤I/O操做完成。整個完整的過程能夠查看Section 14.19.2, "Forcing InnoDB Recovery"。
Carefully Choose a PRIMARY KEY for Each Table
The PRIMARY KEY clause is a critical factor affecting the performance of MySQL queries and the space usage for tables and indexes. Perhaps you have phoned a financial institution where you are asked for an account number. If you do not have the number, you are asked for a dozen different pieces of information to "uniquely identify" yourself. The primary key is like that unique account number that lets you get straight down to business when querying or modifying the information in a table. Every row in the table must have a primary key value, and no two rows can have the same primary key value.
主鍵是影響MySQL查詢性能以及表和索引使用空間的關鍵要素。假設你打電話給金融機構要求一個賬號號碼。若是你沒有號碼,那你就須要一達不一樣的信息來"惟一標識"你本身。主鍵就像那個惟一的賬號號碼,當你查詢或者修改一個的表的信息的時候能夠當即找到。表裏的每一行記錄都要有一個主鍵值,並且不會有兩行記錄有相同主鍵值的狀況。
Here are some guidelines for the primary key, followed by more detailed explanations.
這裏是一些針對於主鍵的指導方針:
Consider adding a primary key to any table that does not already have one. Use the smallest practical numeric type based on the maximum projected size of the table. This can make each row slightly more compact, which can yield substantial space savings for large tables. The space savings are multiplied if the table has any secondary indexes, because the primary key value is repeated in each secondary index entry. In addition to reducing data size on disk, a small primary key also lets more data fit into the buffer pool, speeding up all kinds of operations and improving concurrency.
爲沒有主鍵的表考慮增長一個主鍵。在大表上可使用最小的實際數值類型的列來作主鍵。這樣可使得每一行更爲緊湊,在大表上能夠節約大量的空間。若是表有不少的secondary index,那這節約的空間都是成倍的,由於主鍵值是要重疊在每一個secondary index條目上的。另外這還能減小磁盤上的數據大小。小的主鍵可以讓buffer pool裝載更多的數據,這樣也就加快各類類型的操做,提高了併發性。
If the table already has a primary key on some longer column, such as a VARCHAR, consider adding a new unsigned AUTO_INCREMENT column and switching the primary key to that, even if that column is not referenced in queries. This design change can produce substantial space savings in the secondary indexes. You can designate the former primary key columns as UNIQUE NOT NULL to enforce the same constraints as the PRIMARY KEY clause, that is, to prevent duplicate or null values across all those columns.
若是表已經在一個比較長的列上有主鍵了,例如VARCHAR類型的列,那麼能夠考慮增長一個自增加的列併爲主鍵,即便這個在查詢中不會被引用。這樣設計的修改可以爲secondary index節省大量的空間。你能夠把原來設計的主鍵列改爲UNIQUE NOT NULL來強制其的值和主鍵有相同的約束,這樣也就可以阻止重複值或者空值寫入了。
If you spread related information across multiple tables, typically each table uses the same column for its primary key. For example, a personnel database might have several tables, each with a primary key of employee number. A sales database might have some tables with a primary key of customer number, and other tables with a primary key of order number. Because lookups using the primary key are very fast, you can construct efficient join queries for such tables.
若是你要在多個表之間傳播相關的信息,一般都會使用相同的列來做爲主鍵。例如,personnel數據庫有不少個表,並且每一個表都有一個員工號來做爲主鍵。sales 數據庫裏部分使用客戶號做爲主鍵,其餘的表用訂單號來做爲主鍵。由於經過主鍵的查詢是很是快速的,因此你可使用這些列來構造高效的join查詢。
If you leave the PRIMARY KEY clause out entirely, MySQL creates an invisible one for you. It is a 6-byte value that might be longer than you need, thus wasting space. Because it is hidden, you cannot refer to it in queries.
若是你沒有顯式指定主鍵,那麼MySQL會爲你建立一個隱藏的主鍵。那是一個6-byte的值,遠大於你所須要的,所以會浪費大量的空間。由於是隱藏的,因此你還不能在查詢中使用它。
Application Performance Considerations
The extra reliability and scalability features of InnoDB do require more disk storage than equivalent MyISAM tables. You might change the column and index definitions slightly, for better space utilization, reduced I/O and memory consumption when processing result sets, and better query optimization plans making efficient use of index lookups.
InnoDB額外的可靠性和可擴展性會比MyISAM要求更多的磁盤空間。你能夠稍微修改列和索引的定義,這樣在處理結果集的時候能獲得更好空間利用率,減小I/O和內存的消耗,也能讓執行計劃更有效地使用索引。
If you do set up a numeric ID column for the primary key, use that value to cross-reference with related values in any other tables, particularly for join queries. For example, rather than accepting a country name as input and doing queries searching for the same name, do one lookup to determine the country ID, then do other queries (or a single join query) to look up relevant information across several tables. Rather than storing a customer or catalog item number as a string of digits, potentially using up several bytes, convert it to a numeric ID for storing and querying. A 4-byte unsigned INT column can index over 4 billion items (with the US meaning of billion: 1000 million). For the ranges of the different integer types, see Section 11.2.1, "Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT".
若是你創建一個數字ID列做爲主鍵,那麼就用這列做爲和其餘表進行join的join列。例如,相對於使用country name來進行join,使用country ID來做爲join條件更好。字符串類型的數字,會消耗更多的空間,更好的辦法是使用數值的的數字。一個4-byte unsigned INT列最大可以到4294967295。對於不一樣整數類型的範圍,能夠查看Section 11.2.1, "Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT"。
Understand Files Associated with InnoDB Tables
InnoDB files require more care and planning than MyISAM files do:
相對於MyISAM文件,InnoDB的文件須要更多的關注和規劃:
14.6.5 AUTO_INCREMENT Handling in InnoDB
InnoDB provides a configurable locking mechanism that can significantly improve scalability and performance of SQL statements that add rows to tables with AUTO_INCREMENT columns. To use the AUTO_INCREMENT mechanism with an InnoDB table, an AUTO_INCREMENT column must be defined as part of an index such that it is possible to perform the equivalent of an indexed SELECT MAX(ai_col) lookup on the table to obtain the maximum column value. Typically, this is achieved by making the column the first column of some table index.
在添加新的數據行到AUTO_INCREMENT列的時候,InnoDB提供了一種可配置的鎖機制,能夠顯著改善SQL語句的可擴展性和性能。要在InnoDB表上使用AUTO_INCREMENT的機制,AUTO_INCREMENT列必需要被定義成索引的一部分,這樣就可以執行等價於SELECT MAX(ai_col)的查詢來查找這列的最大值。一般,還要把這列做爲索引的第一個列(前綴列)。
This section describes the behavior of AUTO_INCREMENT lock modes, usage implications for different AUTO_INCREMENT lock mode settings, and how InnoDB initializes the AUTO_INCREMENT counter.
這章講述了AUTO_INCREMENT行爲的鎖模式,不一樣AUTO_INCREMENT鎖模式設定的使用影響,以及InnoDB如何初始化AUTO_INCREMENT計數器。
InnoDB AUTO_INCREMENT Lock Modes
This section describes the behavior of AUTO_INCREMENT lock modes used to generate auto-increment values, and how each lock mode affects replication. Auto-increment lock modes are configured at startup using the innodb_autoinc_lock_mode configuration parameter.
這一章節講述了AUTO_INCREMENT的鎖模式,以及每一個鎖模式是如何影響主從複製的。AUTO_INCREMENT的鎖模式能夠在實例啓動的時候經過innodb_autoinc_lock_mode配置參數來設定。
The following terms are used in describing innodb_autoinc_lock_mode settings:
下面的內容描述了innodb_autoinc_lock_mode的設定:
All statements that generate new rows in a table, including INSERT, INSERT ... SELECT, REPLACE, REPLACE ... SELECT, and LOAD DATA. Includes "simple-inserts", "bulk-inserts", and "mixed-mode" inserts.
生成新數據行的全部語句,包括INSERT, INSERT ... SELECT, REPLACE, REPLACE ... SELECT, and LOAD DATA。也包括"simple-inserts", "bulk-inserts", and "mixed-mode"。
Statements for which the number of rows to be inserted can be determined in advance (when the statement is initially processed). This includes single-row and multiple-row INSERT and REPLACE statements that do not have a nested subquery, but not INSERT ... ON DUPLICATE KEY UPDATE.
語句要插入的行數能夠提早確認(語句預先處理)。這包括了單行或者多行的INSERT,以及沒有嵌套子查詢的REPLACE 語句,可是不包括INSERT ... ON DUPLICATE KEY UPDATE。
Statements for which the number of rows to be inserted (and the number of required auto-increment values) is not known in advance. This includes INSERT ... SELECT, REPLACE ... SELECT, and LOAD DATA statements, but not plain INSERT. InnoDB will assign new values for the AUTO_INCREMENT column one at a time as each row is processed.
語句要插入的行數(以及要自增加數的數量)預先是未知的。這包括了INSERT ... SELECT, REPLACE ... SELECT, and LOAD DATA ,可是不包括普通的INSERT。InnoDB會爲AUTO_INCREMENT列每一行處理一次地分配新值。
These are "simple insert" statements that specify the auto-increment value for some (but not all) of the new rows. An example follows, where c1 is an AUTO_INCREMENT column of table t1:
這是爲新的行(但不是全部)指定自增加值的"simple insert"語句。例以下面的例子,c1是t1表的AUTO_INCREMENT列:
INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
Another type of "mixed-mode insert" is INSERT ... ON DUPLICATE KEY UPDATE, which in the worst case is in effect an INSERT followed by a UPDATE, where the allocated value for the AUTO_INCREMENT column may or may not be used during the update phase.
INSERT ... ON DUPLICATE KEY UPDATE是另外一種類型的"mixed-mode insert",實際上最壞的狀況是INSERT後面緊跟着UPDATE,這樣爲AUTO_INCREMENT分配的值可能在update階段沒法使用。
There are three possible settings for the innodb_autoinc_lock_mode configuration parameter. The settings are 0, 1, or 2, for "traditional", "consecutive", or "interleaved" lock mode, respectively.
innodb_autoinc_lock_mode配置參數有三種可能的設定,分別是0, 1, or 2,分別對應"traditional(傳統的)", "consecutive(連續的)", or "interleaved(交錯的)"鎖模式。
The traditional lock mode provides the same behavior that existed before the innodb_autoinc_lock_mode configuration parameter was introduced in MySQL 5.1. The traditional lock mode option is provided for backward compatibility, performance testing, and working around issues with "mixed-mode inserts", due to possible differences in semantics.
傳統的鎖模式提供了自MySQL5.1引進innodb_autoinc_lock_mode以前已存在相同的行爲。傳統鎖模式主要用於向後兼容,性能測試,以及因爲可能的有語義問題的"mixed-mode inserts"。
In this lock mode, all "INSERT-like" statements obtain a special table-level AUTO-INC lock for inserts into tables with AUTO_INCREMENT columns. This lock is normally held to the end of the statement (not to the end of the transaction) to ensure that auto-increment values are assigned in a predictable and repeatable order for a given sequence of INSERT statements, and to ensure that auto-increment values assigned by any given statement are consecutive.
在這種鎖模式下,全部的"INSERT-like"語句都包含了一個特別的表級別的AUTO-INC鎖,用於往AUTO_INCREMENT列插入數據。這個鎖一般會保持到語句結束(不是事務結束)來確保分配的自增加的值是可預測的,以及對於給定順序的INSERT語句的順序是可重現的,還有要確保對於給定語句分配的自增加值是連續的。
In the case of statement-based replication, this means that when an SQL statement is replicated on a slave server, the same values are used for the auto-increment column as on the master server. The result of execution of multiple INSERT statements is deterministic, and the slave reproduces the same data as on the master. If auto-increment values generated by multiple INSERT statements were interleaved, the result of two concurrent INSERT statements would be nondeterministic, and could not reliably be propagated to a slave server using statement-based replication.
在基於語句(statement-based)的主從複製狀況下,這也就意味着當一個SQL語句重複到slave端的時候,自增加列的值會和master端的相同。多個INSERT語句的執行結果是肯定的,slave端產生的值會和master端相同。若是多ISNERT語句生成的自增加值是交錯的,兩個併發的INSERT語句產生的結果是不肯定的,那就不能使用基於語句的主從複製把結果可靠地傳播到slave端上。
To make this clear, consider an example that uses this table:
爲了更清楚說明狀況,能夠查看下面的例子:
CREATE TABLE t1 (
c1 INT(11) NOT NULL AUTO_INCREMENT,
c2 VARCHAR(10) DEFAULT NULL,
PRIMARY KEY (c1)
) ENGINE=InnoDB;
Suppose that there are two transactions running, each inserting rows into a table with an AUTO_INCREMENT column. One transaction is using an INSERT ... SELECT statement that inserts 1000 rows, and another is using a simple INSERT statement that inserts one row:
假設有兩個事務正在運行,每一個都往表裏插入自增加值。一個事務使用INSERT ... SELECT插入1000行記錄,另外一個使用簡單的INSERT語句插入一行記錄:
Tx1: INSERT INTO t1 (c2) SELECT 1000 rows from another table ...
Tx2: INSERT INTO t1 (c2) VALUES ('xxx');
InnoDB cannot tell in advance how many rows will be retrieved from the SELECT in the INSERT statement in Tx1, and it assigns the auto-increment values one at a time as the statement proceeds. With a table-level lock, held to the end of the statement, only one INSERT statement referring to table t1 can execute at a time, and the generation of auto-increment numbers by different statements is not interleaved. The auto-increment value generated by the Tx1 INSERT ... SELECT statement will be consecutive, and the (single) auto-increment value used by the INSERT statement in Tx2 will either be smaller or larger than all those used for Tx1, depending on which statement executes first.
在Tx1裏面InnoDB不會預先告訴你INSERT語句裏面的SELECT會檢索多少行的記錄,它會在語句處理過程當中每次一個分配自增加值。這個表級的鎖會保持到語句結束,一次執行只執行一個INSERT語句,那麼不一樣的語句產生的自增加值就不會是交錯的。Tx1 INSERT ... SELECT產生的自增加值將會是連續的,而Tx2的自增加值只會小於或者大於Tx1生產的值,只取決於哪一個語句先實行。
As long as the SQL statements execute in the same order when replayed from the binary log (when using statement-based replication, or in recovery scenarios), the results will be the same as they were when Tx1 and Tx2 first ran. Thus, table-level locks held until the end of a statement make INSERT statements using auto-increment safe for use with statement-based replication. However, those table-level locks limit concurrency and scalability when multiple transactions are executing insert statements at the same time.
在從binary log重現的時候(使用基於語句的主從複製,或者恢復場景中)只要SQL語句是以相同的順序執行的,那麼結果集合Tx1 and Tx2運行的順序同樣。所以,保持到語句結束的表級鎖使得在基於主從複製中INSERT語句使用自增加更爲安全。然而,當多個事務在同一個時間點指定insert的時候,這些表級鎖也限制了併發性和可擴展性。
In the preceding example, if there were no table-level lock, the value of the auto-increment column used for the INSERT in Tx2 depends on precisely when the statement executes. If the INSERT of Tx2 executes while the INSERT of Tx1 is running (rather than before it starts or after it completes), the specific auto-increment values assigned by the two INSERT statements are nondeterministic, and may vary from run to run.
在上面的例子裏,若是沒有表級鎖,那麼Tx2裏的INSERT的自增加值就要取決於語句執行的準確時間。若是Tx2的INSERT執行的時候Tx1的INSERT正在運行(不是在它開始以前或者完成以後),這兩個INSERT語句分配的自增加值將會是非肯定性的,幾回運行之間也可能會不一樣。
Under the consecutive lock mode, InnoDB can avoid using table-level AUTO-INC locks for "simple insert" statements where the number of rows is known in advance, and still preserve deterministic execution and safety for statement-based replication.
在連續鎖(consecutive )模式下面,InnoDB會避免對"simple insert"語句使用表級別的AUTO-INC鎖,由於它們產生的新行數是可預期的,但對於基於語句的主從複製仍是會保持執行語句的肯定性和安全性。
If you are not using the binary log to replay SQL statements as part of recovery or replication, the interleaved lock mode can be used to eliminate all use of table-level AUTO-INC locks for even greater concurrency and performance, at the cost of permitting gaps in auto-increment numbers assigned by a statement and potentially having the numbers assigned by concurrently executing statements interleaved.
若是你沒有使用使用binary log重現SQL來做爲恢復或者主從複製的一部分,交錯的(interleaved )鎖模式能夠用於消除全部的表級AUTO-INC鎖,並以此得到更高的併發性和性能。這種狀況會容許在語句生成的自增加值上有間隙,由於併發執行的語句多是交錯執行的。
This is the default lock mode. In this mode, "bulk inserts" use the special AUTO-INC table-level lock and hold it until the end of the statement. This applies to all INSERT ... SELECT, REPLACE ... SELECT, and LOAD DATA statements. Only one statement holding the AUTO-INC lock can execute at a time.
這是默認的鎖模式。在這種模式下,"bulk inserts"會使用特殊的AUTO-INC表級鎖,並保持到語句執行結束。這適用於全部的INSERT ... SELECT, REPLACE ... SELECT, and LOAD DATA語句。同一個時間點上只有一個語句持有AUTO-INC鎖來執行。
"Simple inserts" (for which the number of rows to be inserted is known in advance) avoid table-level AUTO-INC locks by obtaining the required number of auto-increment values under the control of a mutex (a light-weight lock) that is only held for the duration of the allocation process, not until the statement completes. No table-level AUTO-INC lock is used unless an AUTO-INC lock is held by another transaction. If another transaction holds an AUTO-INC lock, a "simple insert" waits for the AUTO-INC lock, as if it were a "bulk insert".
"Simple inserts"(插入行的數量是可預期的)經過在一個mutex的控制下或者要求的自增加值的數量來避免表級別的AUTO-INC鎖。這個mutex只會才分配的過程當中持有,不須要等到語句結束。除非另外一個事務持有了一個 AUTO-INC鎖,那麼InnoDB將不會使用表級別的 AUTO-INC鎖。若是另外一個事務持有了 AUTO-INC鎖,"simple insert"將會等待AUTO-INC鎖,就如"bulk insert"同樣。
This lock mode ensures that, in the presence of INSERT statements where the number of rows is not known in advance (and where auto-increment numbers are assigned as the statement progresses), all auto-increment values assigned by any "INSERT-like" statement are consecutive, and operations are safe for statement-based replication.
這種模式會確保在面對不能預知插入行的數量(語句分配自增加值的數量)的INSERT的語句的時候,任何"INSERT-like"語句分配的 全部自增加值都是連續的,對於基於語句複製的主從複製的操做是安全的。
Simply put, this lock mode significantly improves scalability while being safe for use with statement-based replication. Further, as with "traditional" lock mode, auto-increment numbers assigned by any given statement are consecutive. There is no change in semantics compared to "traditional" mode for any statement that uses auto-increment, with one important exception.
簡而言之,對於使用基於語句的主從複製環境,這種鎖模式不只可以保證安全性,還能顯著改善可擴展性。更進一步地說,和"traditional"鎖模式同樣,任何語句分配的自增加值都是連續的。對於任何使用自增加的語句來講,這和"traditional"模式在語義上是沒有改變的,只有有一個重要的例外。
The exception is for "mixed-mode inserts", where the user provides explicit values for an AUTO_INCREMENT column for some, but not all, rows in a multiple-row "simple insert". For such inserts, InnoDB allocates more auto-increment values than the number of rows to be inserted. However, all values automatically assigned are consecutively generated (and thus higher than) the auto-increment value generated by the most recently executed previous statement. "Excess" numbers are lost.
這個例外是針對"mixed-mode inserts"的。這種狀況下用戶會爲自增加列提供一些明確的值,但又不是所有的。對於這樣insert語句,InnoDB會分配比插入行數更多的自增加值。但是,全部自動分配的值都是連續產生的,所以要比由最近上次執行的語句生成的自增加值要多。"超出"的數值將會被丟棄。
In this lock mode, no "INSERT-like" statements use the table-level AUTO-INC lock, and multiple statements can execute at the same time. This is the fastest and most scalable lock mode, but it is not safe when using statement-based replication or recovery scenarios when SQL statements are replayed from the binary log.
在這種鎖模式下,沒有"INSERT-like"語句會使用表級別的AUTO-INC鎖,同一個時間點上也能執行多個語句。這是最快的,也是最易升級的鎖模式,可是在使用基於語句的主從複製或者恢復場景中從binary log進行基於語句的重現將會是不安全的。
In this lock mode, auto-increment values are guaranteed to be unique and monotonically increasing across all concurrently executing "INSERT-like" statements. However, because multiple statements can be generating numbers at the same time (that is, allocation of numbers is interleaved across statements), the values generated for the rows inserted by any given statement may not be consecutive.
在這種鎖模式下,併發執行的"INSERT-like"語句產生的自增加值是惟一單調遞增的。然而,由於在同一個時間上會有多個語句生成值(也就是說多個語句分配的值是交錯的),那語句插入行生成的值就可能會是不連續的。
If the only statements executing are "simple inserts" where the number of rows to be inserted is known ahead of time, there will be no gaps in the numbers generated for a single statement, except for "mixed-mode inserts". However, when "bulk inserts" are executed, there may be gaps in the auto-increment values assigned by any given statement.
若是隻會執行"simple inserts"(插入行的數量預先可知的)語句,除非是mixed-mode inserts",那麼對於單個語句生成的數值是不會有間隙的。然而,當執行了"bulk inserts",那麼語句分配的自增加值就可能會有間隙了。
InnoDB AUTO_INCREMENT Lock Mode Usage Implications
If you are using statement-based replication, set innodb_autoinc_lock_mode to 0 or 1 and use the same value on the master and its slaves. Auto-increment values are not ensured to be the same on the slaves as on the master if you use innodb_autoinc_lock_mode = 2 ("interleaved") or configurations where the master and slaves do not use the same lock mode.
若是你使用基於語句的主從複製,innodb_autoinc_lock_mode的值爲0或1可讓主從端有相同的值。若是innodb_autoinc_lock_mode = 2 ("interleaved")或者主從端使用了不一樣的鎖模式的時候,則就不能確保主從端的自增加值相同。
If you are using row-based or mixed-format replication, all of the auto-increment lock modes are safe, since row-based replication is not sensitive to the order of execution of the SQL statements (and the mixed format uses row-based replication for any statements that are unsafe for statement-based replication).
若是你使用基於行(row-based)或者混合模式(mixed-format)的主從複製,全部的自增加鎖模式都是安全的,由於基於行的主從複製(row-based replication)不受SQL語句執行順序的影響(對於基於語句的主從複製中不安全的語句,混合模式會使用基於行的主從複製)。
In all lock modes (0, 1, and 2), if a transaction that generated auto-increment values rolls back, those auto-increment values are "lost". Once a value is generated for an auto-increment column, it cannot be rolled back, whether or not the "INSERT-like" statement is completed, and whether or not the containing transaction is rolled back. Such lost values are not reused. Thus, there may be gaps in the values stored in an AUTO_INCREMENT column of a table.
在全部的鎖模式中(0, 1, and 2),若是一個事務裏產生了自增加值,但這個事務回滾了,那麼這些自增加值也就"丟失"了。一旦自增加列生成了值,那這個值是不能被回滾掉的,不論這個"INSERT-like"語句是否完成,也不會管這個事務時不會被會滾了。這些丟失的值是補充從新利用的,所以,表的自增加列上存儲的值是有可能有間隙的。
In all lock modes (0, 1, and 2), if a user specifies NULL or 0 for the AUTO_INCREMENT column in an INSERT, InnoDB treats the row as if the value was not specified and generates a new value for it.
在全部的鎖模式裏(0, 1, and 2),若是在INSERT裏面爲AUTO_INCREMENT列指定NULL或者0,InnoDB就會像沒指定值同樣生成新值。
In all lock modes (0, 1, and 2), the behavior of the auto-increment mechanism is not defined if you assign a negative value to the AUTO_INCREMENT column.
在全部的鎖模式裏(0, 1, and 2),若是你爲AUTO_INCREMENT列分配一個負值,那麼自增加機制就不會工做(不會分配新值)。
In all lock modes (0, 1, and 2), the behavior of the auto-increment mechanism is not defined if the value becomes larger than the maximum integer that can be stored in the specified integer type.
在全部的鎖模式裏(0, 1, and 2),若是自增加值開始大於定義的整數類型的最大值,那麼自增加機制就不工做了。
With innodb_autoinc_lock_mode set to 0 ("traditional") or 1 ("consecutive"), the auto-increment values generated by any given statement will be consecutive, without gaps, because the table-level AUTO-INC lock is held until the end of the statement, and only one such statement can execute at a time.
當innodb_autoinc_lock_mode被設置成0 ("traditional") or 1 ("consecutive")的時候,任何語句產生的自增加值都會是連續的,沒有間隙,由於表級別的AUTO-INC鎖會被持有到語句執行結束,但同一時間點也就只能有一個語句能被執行。
With innodb_autoinc_lock_mode set to 2 ("interleaved"), there may be gaps in the auto-increment values generated by "bulk inserts," but only if there are concurrently executing "INSERT-like" statements.
當innodb_autoinc_lock_mode被設置成2 ("interleaved"),那麼"bulk inserts,"就有可能產生有間隙的自增加值,但也只有在併發執行"INSERT-like"語句時候纔會發生。
For lock modes 1 or 2, gaps may occur between successive statements because for bulk inserts the exact number of auto-increment values required by each statement may not be known and overestimation is possible.
對於1 or 2的鎖模式來講,連續的語句是可能發生間隙的,由於批量插入的每一個語句要求的確切的自增加值的數量是不可知的,只能進行過量估計。
Consider a "mixed-mode insert," where a "simple insert" specifies the auto-increment value for some (but not all) resulting rows. Such a statement will behave differently in lock modes 0, 1, and 2. For example, assume c1 is an AUTO_INCREMENT column of table t1, and that the most recent automatically generated sequence number is 100.
要考慮一種"mixed-mode insert"的狀況:其中一個"simple insert"語句爲在結果集中部分指定了自增加列的確切的值,但又不是所有的。這種狀況徹底不一樣於0, 1, and 2的鎖模式。例如,假設t1表有自增加列c1,最近自動生成的自增加序號是100。
mysql> CREATE TABLE t1 (
-> c1 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> c2 CHAR(1)
-> ) ENGINE = INNODB;
mysql> INSERT INTO t1 VALUES(1,'a'),(101,'b'),(5,'c'),(102,'d');
Now, consider the following "mixed-mode insert" statement:
如今考慮一下下面的"mixed-mode insert"語句:
mysql> INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
With innodb_autoinc_lock_mode set to 0 ("traditional"), the four new rows will be:
當innodb_autoinc_lock_mode=0("traditional")的時候,四行新記錄將會是:
mysql> SELECT c1, c2 FROM t1 ORDER BY c2;
+-----+------+
| c1 | c2 |
+-----+------+
| 1 | a |
| 101 | b |
| 5 | c |
| 102 | d |
+-----+------+
The next available auto-increment value will be 103 because the auto-increment values are allocated one at a time, not all at once at the beginning of statement execution. This result is true whether or not there are concurrently executing "INSERT-like" statements (of any type).
下一個自增加值將是103,由於這些自增加值是每次分配一個的,並非全部的都在語句開始執行的時候分配的。不管是否併發執行了"INSERT-like"語句結果都是這樣的。
With innodb_autoinc_lock_mode set to 1 ("consecutive"), the four new rows will also be:
當innodb_autoinc_lock_mode=1("consecutive")的時候,新的四行記錄也是同樣的:
mysql> SELECT c1, c2 FROM t1 ORDER BY c2;
+-----+------+
| c1 | c2 |
+-----+------+
| 1 | a |
| 101 | b |
| 5 | c |
| 102 | d |
+-----+------+
However, in this case, the next available auto-increment value will be 105, not 103 because four auto-increment values are allocated at the time the statement is processed, but only two are used. This result is true whether or not there are concurrently executing "INSERT-like" statements (of any type).
然而,在這種狀況下,下一個自增加值將會是105,而不是103,由於在語句處理的時候已經分配了四個自增加值,但只是用了兩個。不管是否併發執行了"INSERT-like"語句結果都是這樣的。
With innodb_autoinc_lock_mode set to mode 2 ("interleaved"), the four new rows will be:
當innodb_autoinc_lock_mode=2("interleaved"),新的四行記錄將會是:
mysql> SELECT c1, c2 FROM t1 ORDER BY c2;
+-----+------+
| c1 | c2 |
+-----+------+
| 1 | a |
| x | b |
| 5 | c |
| y | d |
+-----+------+
The values of x and y will be unique and larger than any previously generated rows. However, the specific values of x and y will depend on the number of auto-increment values generated by concurrently executing statements.
這裏面的x,y都是惟一的,並且會比以前生成的要大。但是,這些特定的x,y也是要依賴於來併發執行語句生成自增加值的數量的。
Finally, consider the following statement, issued when the most-recently generated sequence number was the value 4:
最後,考慮一下下面的語句,這句執行的時候最近生成的序號數是4:
mysql> INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
With any innodb_autoinc_lock_mode setting, this statement will generate a duplicate-key error 23000 (Can't write; duplicate key in table) because 5 will be allocated for the row (NULL, 'b') and insertion of the row (5, 'c') will fail.
不管innodb_autoinc_lock_mode的設置是什麼,這個語句都會報重複鍵error 23000 的錯誤,由於(NULL, 'b')會分配到5,而 (5, 'c') 的插入就會失敗。
In all lock modes (0, 1, and 2), modifying an AUTO_INCREMENT column value in the middle of a sequence of INSERT statements could lead to "Duplicate entry" errors. For example, if you perform an UPDATE operation that changes an AUTO_INCREMENT column value to a value larger than the current maximum auto-increment value, subsequent INSERT operations that do not specify an unused auto-increment value could encounter "Duplicate entry" errors. This behavior is demonstrated in the following example.
在全部的鎖模式中(0, 1, and 2),在一系列INSERT語句中間修改AUTO_INCREMENT列的值將會致使"Duplicate entry"錯誤。例如,若是你執行了一個UPDATE操做把AUTO_INCREMENT列的值修改的超過當前自增加的最大值了,那麼隨後沒有指定自增加值的INSERT操做就會遭遇到"Duplicate entry"錯誤。下面的例子演示了這種狀況。
mysql> CREATE TABLE t1 (
-> c1 INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (c1)
-> ) ENGINE = InnoDB;
mysql> INSERT INTO t1 VALUES(0), (0), (3);
mysql> SELECT c1 FROM t1;
+----+
| c1 |
+----+
| 1 |
| 2 |
| 3 |
+----+
mysql> UPDATE t1 SET c1 = 4 WHERE c1 = 1;
mysql> SELECT c1 FROM t1;
+----+
| c1 |
+----+
| 2 |
| 3 |
| 4 |
+----+
mysql> INSERT INTO t1 VALUES(0);
ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'
InnoDB AUTO_INCREMENT Counter Initialization
This section describes how InnoDB initializes AUTO_INCREMENT counters.
這部分講述了InnoDB如何初始化AUTO_INCREMENT計數器。
If you specify an AUTO_INCREMENT column for an InnoDB table, the table handle in the InnoDB data dictionary contains a special counter called the auto-increment counter that is used in assigning new values for the column. This counter is stored only in main memory, not on disk.
若是你爲InnoDB表指定了一個AUTO_INCREMENT列,InnoDB在數據字典裏就會包含一個稱之爲auto-increment的計數器,用於爲AUTO_INCREMENT列分配新值。這個計數器只存儲在主內存裏,而不是在磁盤上。
To initialize an auto-increment counter after a server restart, InnoDB executes the equivalent of the following statement on the first insert into a table containing an AUTO_INCREMENT column.
在實例重啓以後爲了初始化一個auto-increment counter,InnoDB會在AUTO_INCREMENT列插入的時候執行等價於下面的語句。
SELECT MAX(ai_col) FROM table_name FOR UPDATE;
InnoDB increments the value retrieved by the statement and assigns it to the column and to the auto-increment counter for the table. By default, the value is incremented by 1. This default can be overridden by the auto_increment_increment configuration setting.
InnoDB會增長語句返回的值,而後將其分配到列以及auto-increment counter上。默認狀況下,遞增的值是1。這個默認值是能夠被auto_increment_increment配置參數覆蓋的。
If the table is empty, InnoDB uses the value 1. This default can be overridden by the auto_increment_offset configuration setting.
若是表是空的,InnoDB使用的值是1。這個默認值是能夠被auto_increment_offset配置參數覆蓋的。
If a SHOW TABLE STATUS statement examines the table before the auto-increment counter is initialized, InnoDB initializes but does not increment the value. The value is stored for use by later inserts. This initialization uses a normal exclusive-locking read on the table and the lock lasts to the end of the transaction. InnoDB follows the same procedure for initializing the auto-increment counter for a newly created table.
若是在初始化auto-increment counter初始化以前執行了SHOW TABLE STATUS,InnoDB會初始化但不會增長這個值。這個值會被存儲起來以供後來insert使用。這個初始化的操做會在表上加一個排他的讀鎖直到事務結束。對於最新建立的表InnoDB也是以一樣的方式處理auto-increment counter的。
After the auto-increment counter has been initialized, if you do not explicitly specify a value for an AUTO_INCREMENT column, InnoDB increments the counter and assigns the new value to the column. If you insert a row that explicitly specifies the column value, and the value is greater than the current counter value, the counter is set to the specified column value.
在auto-increment counter被初始化以後,若是你沒有爲AUTO_INCREMENT列明確指定一個 值,那麼InnoDB會增長這個計數器併爲列分配一個新增。若是你插入的時候明確指定了值,而且這個值大於當前的counter值,那counter將會被設定爲這個指定的值。
InnoDB uses the in-memory auto-increment counter as long as the server runs. When the server is stopped and restarted, InnoDB reinitializes the counter for each table for the first INSERT to the table, as described earlier.
只要實例在運行,InnoDB會在內存裏使用auto-increment counter。當實例關閉和重啓的時候,InnoDB爲每張表的第一個INSERT從新初始化counter,就如前面所說的。
A server restart also cancels the effect of the AUTO_INCREMENT = N table option in CREATE TABLE and ALTER TABLE statements, which you can use with InnoDB tables to set the initial counter value or alter the current counter value.
實例重啓會取消當時CREATE TABLE and ALTER TABLE語句中AUTO_INCREMENT = N的影響。
14.6.6 InnoDB and FOREIGN KEY Constraints
This section describes differences in the InnoDB storage engine's handling of foreign keys as compared with that of the MySQL Server.
這一部分講述了InnoDB在處理外鍵上和其餘引擎之間的不一樣之處。
Foreign Key Definitions
Foreign key definitions for InnoDB tables are subject to the following conditions:
InnoDB對於外鍵的定義有下面幾條:
Referential Actions
Referential actions for foreign keys of InnoDB tables are subject to the following conditions:
InnoDB外鍵的referential actions有下面幾條:
Foreign Key Usage and Error Information
You can obtain general information about foreign keys and their usage from querying the INFORMATION_SCHEMA.KEY_COLUMN_USAGE table, and more information more specific to InnoDB tables can be found in the INNODB_SYS_FOREIGN and INNODB_SYS_FOREIGN_COLS tables, also in the INFORMATION_SCHEMA database. See also Section 13.1.17.3, "Using FOREIGN KEY Constraints".
你能夠經過查詢INFORMATION_SCHEMA.KEY_COLUMN_USAGE表來得到外鍵及其使用的相關信息,InnoDB中更多詳細的信息能夠在INFORMATION_SCHEMA數據庫的INNODB_SYS_FOREIGN和INNODB_SYS_FOREIGN_COLS表裏找到。相關內容可見Section 13.1.17.3, "Using FOREIGN KEY Constraints"。
In addition to SHOW ERRORS, in the event of a foreign key error involving InnoDB tables (usually Error 150 in the MySQL Server), you can obtain a detailed explanation of the most recent InnoDB foreign key error by checking the output of SHOW ENGINE INNODB STATUS.
除了SHOW ERRORS以外,在涉及InnoDB表外鍵錯誤(在MySQL裏一般是Error 150)的事件裏,你能夠檢查SHOW ENGINE INNODB STATUS來得到最近的InnoDB外鍵錯誤的詳細解讀。
14.6.7 Limits on InnoDB Tables
Warning
Do not convert MySQL system tables in the mysql database from MyISAM to InnoDB tables. This is an unsupported operation. If you do this, MySQL does not restart until you restore the old system tables from a backup or regenerate them by reinitializing the data directory (see Section 2.10.1, "Initializing the Data Directory").
不要把mysql數據庫裏的系統表從MyISAM轉成InnoDB。這個操做是不支持的。若是你這麼作了,在你從備份裏恢復這些表從新初始化了數據字典以前不要重啓MySQL(詳見2.10.1, "Initializing the Data Directory")。
Warning
It is not a good idea to configure InnoDB to use data files or log files on NFS volumes. Otherwise, the files might be locked by other processes and become unavailable for use by MySQL.
不要把InnoDB的數據文件或者日誌文件放到NFS捲上。不然,對於MySQL來講這些文件可能會被其餘進程鎖住而變得不可用。
Maximums and Minimums
Attempting to use an index prefix length that is greater than the allowed maximum value produces an error. To avoid such errors for replication configurations, avoid setting the innodb_large_prefix option on the master if it cannot also be set on the slaves, and the slaves have unique indexes that could be affected by this limit.
假設使用的索引前綴的長度大於了最大容許的值並報了錯。To avoid such errors for replication configurations, avoid setting the innodb_large_prefix option on the master if it cannot also be set on the slaves, and the slaves have unique indexes that could be affected by this limit.
If a row is less than half a page long, all of it is stored locally within the page. If it exceeds half a page, variable-length columns are chosen for external off-page storage until the row fits within half a page, as described in Section 14.10.2, "File Space Management".
若是一個行的長度不到頁大小的一半,那麼它的所有內容都會被存儲在這個數據頁裏面。若是超過了數據頁的一半,那麼可變長度列會選擇外部off-page存儲直到這行可以放入到數據頁的一半的空間裏,詳見Section 14.10.2, "File Space Management"。
mysql> CREATE TABLE t (a VARCHAR(8000), b VARCHAR(10000),
-> c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
-> f VARCHAR(10000), g VARCHAR(10000)) ENGINE=InnoDB;
ERROR 1118 (42000): Row size too large. The maximum row size for the
used table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs
See Section C.10.4, "Limits on Table Column Count and Row Size".
詳見Section C.10.4, "Limits on Table Column Count and Row Size".
Note
Increasing the page size is not a supported operation: there is no guarantee that InnoDB will function normally with a page size greater than 16KB. Problems compiling or running InnoDB may occur. In particular, ROW_FORMAT=COMPRESSED in the Barracuda file format assumes that the page size is at most 16KB and uses 14-bit pointers.
是不能增長數據頁的大小的:InnoDB沒法保證可以處理超過16KB的數據頁。這樣在在編譯或者運行InnoDB的時候會發生錯誤。另外,Barracuda文件格式裏的ROW_FORMAT=COMPRESSED假設數據頁最可能是16KB,並使用了14-bit的指針。
A MySQL instance using a particular InnoDB page size cannot use data files or log files from an instance that uses a different page size. This limitation could affect restore or downgrade operations using data from MySQL 5.6, which does support page sizes other than 16KB.
同一個MySQL實例上不能把InnoDB的數據文件和日誌文件使用不一樣的大小的數據頁。這個限制會影響MySQL5.6的恢復和先下升級操做,由於它們不支持大於16KB的數據頁。
Index Types
Restrictions on InnoDB Tables
You can make the statistics collected by ANALYZE TABLE more precise and more stable by turning on the innodb_stats_persistent configuration option, as explained in Section 14.4.11.1, "Configuring Persistent Optimizer Statistics Parameters". When that setting is enabled, it is important to run ANALYZE TABLE after major changes to indexed column data, because the statistics are not recalculated periodically (such as after a server restart) as they traditionally have been.
如Section 14.4.11.1, "Configuring Persistent Optimizer Statistics Parameters"所講述的,你能夠經過nnodb_stats_persistent配置參數使得ANALYZE TABLE獲得的結果更精確,更穩定。當開啓了這個參數的時候,那對在大的索引列數據改動以後運行ANALYZE TABLE是很是重要的,because the statistics are not recalculated periodically (such as after a server restart) as they traditionally have been.
You can change the number of random dives by modifying the innodb_stats_persistent_sample_pages system variable (if the persistent statistics setting is turned on), or the innodb_stats_transient_sample_pages system variable (if the persistent statistics setting is turned off).
你能夠經過修改innodb_stats_persistent_sample_pages系統變量來修改random dives的數量(要求開啓持久的統計信息),或者是innodb_stats_transient_sample_pages系統變量(關閉持久化統計信息的狀況下)。
MySQL uses index cardinality estimates only in join optimization. If some join is not optimized in the right way, you can try using ANALYZE TABLE. In the few cases that ANALYZE TABLE does not produce values good enough for your particular tables, you can use FORCE INDEX with your queries to force the use of a particular index, or set the max_seeks_for_key system variable to ensure that MySQL prefers index lookups over table scans. See Section 5.1.4, "Server System Variables", and Section B.5.5, "Optimizer-Related Issues".
MySQL只有在join優化的時候纔會使用索引基數的評估信息。若是一些join操做沒有以正確的方式進行優化,那麼你就須要運行ANALYZE TABLE。在少部分的狀況下ANALYZE TABLE沒法爲個別表生成足夠優質的數據,那麼你能夠在 查詢中使用FORCE INDEX來強制使用一個特定的索引,或者是設置max_seeks_for_key系統變量來確保MySQL更喜歡使用索引查找而不是表掃描。詳見Section 5.1.4, "Server System Variables"和Section B.5.5, "Optimizer-Related Issues"。
With innodb_autoinc_lock_mode=0, InnoDB uses a special AUTO-INC table lock mode where the lock is obtained and held to the end of the current SQL statement while accessing the auto-increment counter. Other clients cannot insert into the table while the AUTO-INC table lock is held. The same behavior occurs for "bulk inserts" with innodb_autoinc_lock_mode=1. Table-level AUTO-INC locks are not used with innodb_autoinc_lock_mode=2. For more information, See Section 14.6.5, "AUTO_INCREMENT Handling in InnoDB".
當innodb_autoinc_lock_mode=0,InnoDB會使用特殊的AUTO-INC表鎖模式,當要訪問auto-increment counter的時候,這個鎖會被得到並被保持到當前語句執行結束。當持有了AUTO-INC表鎖的時候其餘客戶端是沒法向表裏插入數據的。對於innodb_autoinc_lock_mode=1,"bulk inserts"也有相同的狀況。當innodb_autoinc_lock_mode=2的時候表界別的AUTO-INC鎖是沒法使用的。更多的信息查看Section 14.6.5, "AUTO_INCREMENT Handling in InnoDB"。
Locking and Transactions