什么是表空间,为什么要使用它?
What is a tablespace and why is it used?
在调查问题时,我遇到了这个错误:
30503 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace mysql/innodb_index_stats uses space ID: 2 at filepath: ./mysql/innodb_index_stats.ibd. Cannot open tablespace Mydb/be_command_log which uses space ID: 2 at filepath: ./Mydb/be_command_log.ibd
在阅读了有关此问题的一些内容后,我才知道这是 a known issue of MySQL。
但我的问题是我不太了解表空间的实际工作原理。它们有什么用?我读了 this definition,但它没有提供所有信息。
有人可以分享一些关于什么是表空间及其工作原理的详细信息吗?
默认情况下,InnoDB只包含一个tablespace调用系统tablespace,其标识符为0。更多tablespaces 可以使用 innodb_file_per_table 配置参数间接创建。 tablespace 由文件链组成。文件的大小不必被数据库块大小整除,因为我们可能只保留最后一个不完整的块未使用。当新文件附加到 tablespace 时,还会指定文件的最大大小。目前,我们认为最好在创建文件时就将文件扩展到最大大小,因为这样我们就可以避免在 table 需要更多 space 时动态扩展文件]space。数据文件是动态扩展的,但重做日志文件是预先分配的。另外,如前所述,只有系统 tablespace 可以拥有多个数据文件。还明确提到,即使 tablespace 可以有多个文件,它们也被认为是一个连接在一起的大文件。所以 tablespace 中的文件顺序很重要。
来自https://blogs.oracle.com/mysqlinnodb/entry/data_organization_in_innodb
MySQL Innodb TableSpace 是数据驻留在磁盘中的位置,称为 数据目录 (默认情况下 “系统 table 空间” )。示例:
"/var/lib/mysql"
从 MySQL 版本 5.6.6 开始,用户可以创建和指定他们想要存储数据的 table 空间,从而实现数据操作和恢复过程的吞吐量。 InnoDB 的 file-per-table 功能提供每个 tables 有单独的 .ibd 数据和索引文件,代表一个单独的通用 table 空间。这样一个数据库中的每个table都可以指向various locations of data directories.
例如:
/home/{user}/test/data/{dbName}/{tableName}.ibd
/home/{user}/work/data/{dbName}/{tableName}.ibd
有关每个 table table 空间的文件的更多信息,请参阅此 mysql documentation。
sql 客户端应仅使用 sql 对象,而不关心数据库服务器物理存储该信息的位置。
这就是为什么需要 table空间的概念。 sql 像 table 数据这样的对象从 sql 客户端的角度进入 table 空间。
数据库服务器管理员现在可以自由地将 table 空间实际放置在他们想要的物理位置,sql 客户端程序仍然有效。
一个数据文件,可以保存一个或多个 InnoDB table 和相关索引的数据。
有多种类型的table根据配置w.r.t信息俱乐部每个table空间。这些是,
一个。系统table空间
b.每个 table 空间的文件
C。一般table空间
系统table空间包含,
- InnoDB 数据字典。
- 双写缓冲区。
- 更改缓冲区
- 撤消日志。
除此之外还包含,
- 表格和
- 索引数据
关联文件是 .idbdata1
innodb_file_per_table 选项 在 MySQL 5.6 及更高版本中默认启用,允许在文件中创建 tables -per-table table 空间,每个 table 有一个单独的数据文件。启用 innodb_file_per_table 选项可以使用其他 MySQL 功能,例如 table 压缩和传输 table table 空间。
关联文件是 .idbd
InnoDB 在 MySQL 5.7.6 中引入了通用的 tablespaces。一般 table 空间是使用 CREATE TABLESPACE 语法创建的共享 table 空间。它们可以在 MySQL 数据目录之外创建,能够容纳多个 table,并支持所有行格式的 table。
添加@BhupeshPant 提供的出色答案
InnoDB 的存储分为table空间。 Table空间是与多个数据文件(对象)关联的逻辑结构。每个 table 空间包含页面(块)、范围和段。
Pages - InnoDB 的最小数据块,也称为块。一页可以容纳一行或多行,具体取决于行大小。
一般来说,每个 table 都有自己的 table 与一个数据文件关联的空间
以下命令显示table空间和相应数据文件的完整列表-
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
为了获得更正确的理解,请创建示例数据库 - database1
CREATE DATABASE database1;
USE database1;
现在创建一个示例table table1
-
CREATE TABLE table1 (
-> col1 INT
-> );
现在可以看到对应的table空间和数据文件也已经创建好了-
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+--------------------------+--------------------------+
| TABLESPACE_NAME | FILE_NAME |
+--------------------------+--------------------------+
|database1/table1 | ./database1/table1.ibd |
+--------------------------+--------------------------+
这里的 .ibd
扩展名表示 Innodb 数据文件
现在创建另一个示例 table table2
-
CREATE TABLE table2 (
-> col1 INT
-> );
我们又可以看到对应的table空间和数据文件已经创建好了-
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
+---------------------------+--------------------------+
此处系统正在为table空间创建默认名称。这些系统生成的 table 空间称为 - Single-Table tablespaces
单-Table table只有当innodb_file_per_table
为ON
时系统才会创建空间
可以通过-
查看
SHOW VARIABLES LIKE "innodb_file_per_table";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
默认情况下,值为 ON。它可以通过 -
关闭
SET GLOBAL innodb_file_per_table = OFF;
SHOW VARIABLES LIKE "innodb_file_per_table";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF |
+-----------------------+-------+
如果该值关闭,则不会创建单Table table空间。
为了证明这一点,我们再次创建一个示例 table -
CREATE TABLE table10 (
-> col1 INT
-> );
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
+---------------------------+--------------------------+
因此,我们可以看到没有创建名为 - database1/table10
的 table空间
在这种情况下,table 存储在 innodb_system
table 空间;
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES WHERE FILE_NAME LIKE "%ibdata1";
+-----------------+-----------+
| TABLESPACE_NAME | FILE_NAME |
+-----------------+-----------+
| innodb_system | ./ibdata1 |
+-----------------+-----------+
但这不是一个好的做法,因为它会给系统 table空间带来更多负担,从而导致与性能相关的问题。
在系统生成 table 空间的情况下,删除 table 时 table 空间也会自动删除。
还有另一种类型的 tablespace 称为 - General Tablespaces,我们可以在其中为 tablespace 创建自定义名称。
为此,我们需要发出以下命令 -
CREATE TABLESPACE tablespace1 ADD DATAFILE '/var/lib/mysql/tablespace1.ibd' engine = Innodb;
我们可以检查table空间和相应的数据文件是否已经创建 -
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
| tablespace1 | /var/lib/mysql/tablespace1.ibd |
+---------------------------+--------------------------------+
这里所有的table空间都是在Mysqldatadir
中创建的,默认情况下是/var/lib/mysql/
datadir
值可以通过以下命令查看-
SELECT @@datadir;
+-----------------+
| @@datadir |
+-----------------+
| /var/lib/mysql/ |
+-----------------+
在 MySQL 中,每个 table 空间只能添加一个数据文件。但在 Oracle 或 SQL 服务器中,可以将多个数据文件添加到一个 table 空间。
要在 table 空间中创建一个 table - tablespace1
我们需要发出命令 -
CREATE TABLE table3 (
-> col1 INT
-> )
-> TABLESPACE = tablespace1;
如果是一般的table空间,一个table空间内可以创建多个table -
CREATE TABLE table4 (
-> col1 INT
-> )
-> TABLESPACE = tablespace1;
创建 table空间时,数据文件的位置可能不会单独说明。以下命令也将起作用 -
CREATE TABLESPACE tablespace2 ADD DATAFILE 'tablespace2.ibd' engine = Innodb;
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
| tablespace1 | /var/lib/mysql/tablespace1.ibd |
| tablespace2 | ./tablespace2.ibd |
+---------------------------+--------------------------------+
默认情况下,所有 table 空间都在 datadir
目录中创建
Tablespace 创建默认值的页面大小。但是,我们也可以在创建 table 空间时设置自己的页面大小。但是,大小必须在默认页面大小以内,否则会出错。默认页面大小可以在 MySQL 服务器安装期间设置。
允许的页面大小为 - 4 kb、8 kb、16 kb、32 kb、64 kb。
通常在安装过程中,默认页面大小设置为 16 kb。
以下命令用于查看默认页面大小-
SHOW VARIABLES LIKE 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
创建具有自定义页面大小的 table空间的命令是 -
CREATE TABLESPACE tablespace3_8kb ADD DATAFILE '/var/lib//mysql/tablespace3_8kb.ibd' FILE_BLOCK_SIZE = 8192 ENGINE = Innodb;
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+-------------------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+-------------------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
| tablespace1 | /var/lib/mysql/tablespace1.ibd |
| tablespace2 | ./tablespace2.ibd |
| tablespace3_8kb | /var/lib//mysql/tablespace3_8kb.ibd |
+---------------------------+-------------------------------------+
要将 table 存储在具有用户定义页面大小的 table 空间中,需要不同的语法 -
CREATE TABLE table5 (
-> col1 INT
-> )
-> TABLESPACE = tablespace3_8kb
-> KEY_BLOCK_SIZE = 8;
与系统生成的 table 空间不同,如果我们删除 table 空间,一般 table 空间不会自动删除,需要明确删除 table 空间.
命令是-
DROP TABLESPACE tablespace_name;
在调查问题时,我遇到了这个错误:
30503 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace mysql/innodb_index_stats uses space ID: 2 at filepath: ./mysql/innodb_index_stats.ibd. Cannot open tablespace Mydb/be_command_log which uses space ID: 2 at filepath: ./Mydb/be_command_log.ibd
在阅读了有关此问题的一些内容后,我才知道这是 a known issue of MySQL。
但我的问题是我不太了解表空间的实际工作原理。它们有什么用?我读了 this definition,但它没有提供所有信息。
有人可以分享一些关于什么是表空间及其工作原理的详细信息吗?
默认情况下,InnoDB只包含一个tablespace调用系统tablespace,其标识符为0。更多tablespaces 可以使用 innodb_file_per_table 配置参数间接创建。 tablespace 由文件链组成。文件的大小不必被数据库块大小整除,因为我们可能只保留最后一个不完整的块未使用。当新文件附加到 tablespace 时,还会指定文件的最大大小。目前,我们认为最好在创建文件时就将文件扩展到最大大小,因为这样我们就可以避免在 table 需要更多 space 时动态扩展文件]space。数据文件是动态扩展的,但重做日志文件是预先分配的。另外,如前所述,只有系统 tablespace 可以拥有多个数据文件。还明确提到,即使 tablespace 可以有多个文件,它们也被认为是一个连接在一起的大文件。所以 tablespace 中的文件顺序很重要。
来自https://blogs.oracle.com/mysqlinnodb/entry/data_organization_in_innodb
MySQL Innodb TableSpace 是数据驻留在磁盘中的位置,称为 数据目录 (默认情况下 “系统 table 空间” )。示例:
"/var/lib/mysql"
从 MySQL 版本 5.6.6 开始,用户可以创建和指定他们想要存储数据的 table 空间,从而实现数据操作和恢复过程的吞吐量。 InnoDB 的 file-per-table 功能提供每个 tables 有单独的 .ibd 数据和索引文件,代表一个单独的通用 table 空间。这样一个数据库中的每个table都可以指向various locations of data directories.
例如:
/home/{user}/test/data/{dbName}/{tableName}.ibd
/home/{user}/work/data/{dbName}/{tableName}.ibd
有关每个 table table 空间的文件的更多信息,请参阅此 mysql documentation。
sql 客户端应仅使用 sql 对象,而不关心数据库服务器物理存储该信息的位置。
这就是为什么需要 table空间的概念。 sql 像 table 数据这样的对象从 sql 客户端的角度进入 table 空间。
数据库服务器管理员现在可以自由地将 table 空间实际放置在他们想要的物理位置,sql 客户端程序仍然有效。
一个数据文件,可以保存一个或多个 InnoDB table 和相关索引的数据。
有多种类型的table根据配置w.r.t信息俱乐部每个table空间。这些是,
一个。系统table空间 b.每个 table 空间的文件 C。一般table空间
系统table空间包含,
- InnoDB 数据字典。
- 双写缓冲区。
- 更改缓冲区
- 撤消日志。
除此之外还包含,
- 表格和
- 索引数据
关联文件是 .idbdata1
innodb_file_per_table 选项 在 MySQL 5.6 及更高版本中默认启用,允许在文件中创建 tables -per-table table 空间,每个 table 有一个单独的数据文件。启用 innodb_file_per_table 选项可以使用其他 MySQL 功能,例如 table 压缩和传输 table table 空间。
关联文件是 .idbd
InnoDB 在 MySQL 5.7.6 中引入了通用的 tablespaces。一般 table 空间是使用 CREATE TABLESPACE 语法创建的共享 table 空间。它们可以在 MySQL 数据目录之外创建,能够容纳多个 table,并支持所有行格式的 table。
添加@BhupeshPant 提供的出色答案
InnoDB 的存储分为table空间。 Table空间是与多个数据文件(对象)关联的逻辑结构。每个 table 空间包含页面(块)、范围和段。
Pages - InnoDB 的最小数据块,也称为块。一页可以容纳一行或多行,具体取决于行大小。
一般来说,每个 table 都有自己的 table 与一个数据文件关联的空间
以下命令显示table空间和相应数据文件的完整列表-
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
为了获得更正确的理解,请创建示例数据库 - database1
CREATE DATABASE database1;
USE database1;
现在创建一个示例table table1
-
CREATE TABLE table1 (
-> col1 INT
-> );
现在可以看到对应的table空间和数据文件也已经创建好了-
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+--------------------------+--------------------------+
| TABLESPACE_NAME | FILE_NAME |
+--------------------------+--------------------------+
|database1/table1 | ./database1/table1.ibd |
+--------------------------+--------------------------+
这里的 .ibd
扩展名表示 Innodb 数据文件
现在创建另一个示例 table table2
-
CREATE TABLE table2 (
-> col1 INT
-> );
我们又可以看到对应的table空间和数据文件已经创建好了-
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
+---------------------------+--------------------------+
此处系统正在为table空间创建默认名称。这些系统生成的 table 空间称为 - Single-Table tablespaces
单-Table table只有当innodb_file_per_table
为ON
可以通过-
查看SHOW VARIABLES LIKE "innodb_file_per_table";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
默认情况下,值为 ON。它可以通过 -
关闭SET GLOBAL innodb_file_per_table = OFF;
SHOW VARIABLES LIKE "innodb_file_per_table";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF |
+-----------------------+-------+
如果该值关闭,则不会创建单Table table空间。
为了证明这一点,我们再次创建一个示例 table -
CREATE TABLE table10 (
-> col1 INT
-> );
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
+---------------------------+--------------------------+
因此,我们可以看到没有创建名为 - database1/table10
的 table空间
在这种情况下,table 存储在 innodb_system
table 空间;
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES WHERE FILE_NAME LIKE "%ibdata1";
+-----------------+-----------+
| TABLESPACE_NAME | FILE_NAME |
+-----------------+-----------+
| innodb_system | ./ibdata1 |
+-----------------+-----------+
但这不是一个好的做法,因为它会给系统 table空间带来更多负担,从而导致与性能相关的问题。
在系统生成 table 空间的情况下,删除 table 时 table 空间也会自动删除。
还有另一种类型的 tablespace 称为 - General Tablespaces,我们可以在其中为 tablespace 创建自定义名称。
为此,我们需要发出以下命令 -
CREATE TABLESPACE tablespace1 ADD DATAFILE '/var/lib/mysql/tablespace1.ibd' engine = Innodb;
我们可以检查table空间和相应的数据文件是否已经创建 -
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
| tablespace1 | /var/lib/mysql/tablespace1.ibd |
+---------------------------+--------------------------------+
这里所有的table空间都是在Mysqldatadir
中创建的,默认情况下是/var/lib/mysql/
datadir
值可以通过以下命令查看-
SELECT @@datadir;
+-----------------+
| @@datadir |
+-----------------+
| /var/lib/mysql/ |
+-----------------+
在 MySQL 中,每个 table 空间只能添加一个数据文件。但在 Oracle 或 SQL 服务器中,可以将多个数据文件添加到一个 table 空间。
要在 table 空间中创建一个 table - tablespace1
我们需要发出命令 -
CREATE TABLE table3 (
-> col1 INT
-> )
-> TABLESPACE = tablespace1;
如果是一般的table空间,一个table空间内可以创建多个table -
CREATE TABLE table4 (
-> col1 INT
-> )
-> TABLESPACE = tablespace1;
创建 table空间时,数据文件的位置可能不会单独说明。以下命令也将起作用 -
CREATE TABLESPACE tablespace2 ADD DATAFILE 'tablespace2.ibd' engine = Innodb;
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+--------------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+--------------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
| tablespace1 | /var/lib/mysql/tablespace1.ibd |
| tablespace2 | ./tablespace2.ibd |
+---------------------------+--------------------------------+
默认情况下,所有 table 空间都在 datadir
目录中创建
Tablespace 创建默认值的页面大小。但是,我们也可以在创建 table 空间时设置自己的页面大小。但是,大小必须在默认页面大小以内,否则会出错。默认页面大小可以在 MySQL 服务器安装期间设置。
允许的页面大小为 - 4 kb、8 kb、16 kb、32 kb、64 kb。
通常在安装过程中,默认页面大小设置为 16 kb。
以下命令用于查看默认页面大小-
SHOW VARIABLES LIKE 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
创建具有自定义页面大小的 table空间的命令是 -
CREATE TABLESPACE tablespace3_8kb ADD DATAFILE '/var/lib//mysql/tablespace3_8kb.ibd' FILE_BLOCK_SIZE = 8192 ENGINE = Innodb;
SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;
+---------------------------+-------------------------------------+
| TABLESPACE_NAME | FILE_NAME |
+---------------------------+-------------------------------------+
| database1/table1 | ./database1/table1.ibd |
| database1/table2 | ./database1/table2.ibd |
| tablespace1 | /var/lib/mysql/tablespace1.ibd |
| tablespace2 | ./tablespace2.ibd |
| tablespace3_8kb | /var/lib//mysql/tablespace3_8kb.ibd |
+---------------------------+-------------------------------------+
要将 table 存储在具有用户定义页面大小的 table 空间中,需要不同的语法 -
CREATE TABLE table5 (
-> col1 INT
-> )
-> TABLESPACE = tablespace3_8kb
-> KEY_BLOCK_SIZE = 8;
与系统生成的 table 空间不同,如果我们删除 table 空间,一般 table 空间不会自动删除,需要明确删除 table 空间.
命令是-
DROP TABLESPACE tablespace_name;