47

While investigating an issue, I came across this error:

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

After reading a bit about this issue, I came to know that this is a known issue of MySQL.

But my problem is that I don't know much about how tablespaces really work. How are they useful? I read this definition, but it does not give all the information.

Can someone share some detailed information about what are tablespaces and how do they work?

Cy Rossignol
  • 16,216
  • 4
  • 57
  • 83
Bhupesh Pant
  • 4,053
  • 5
  • 45
  • 70
  • This post also give you some background information about Tablespaces: http://stackoverflow.com/questions/18959643/what-is-the-use-of-tablespace-in-the-above-query – ArBro Jun 14 '16 at 12:44
  • I think the link @ABr offered answers the question, but since you tagged MySQL, you might also be interested in the [`CREATE TABLESPACE` statement](https://dev.mysql.com/doc/refman/5.6/en/create-tablespace.html). – bishop Jun 14 '16 at 12:46
  • Agree on that, but depended on you MySql version you would like to see the reference for the 5.7 release: http://dev.mysql.com/doc/refman/5.7/en/create-tablespace.html – ArBro Jun 14 '16 at 12:51
  • @ABr, I am using 5.6.15. – Bhupesh Pant Jun 14 '16 at 13:20
  • Almost never does anyone running MySQL need to know anything about the term "tablespace". Please provide `SHOW CREATE TABLE` and anything else relevant to what is going on. – Rick James Jun 20 '16 at 06:20
  • Did you recently update to 5.6.15? From what version? Did you run `mysql_update`? – Rick James Jun 20 '16 at 06:21
  • I am sorry but I am not sure of update date and process. But, I don't understand how can this information be useful for this question. – Bhupesh Pant Jun 20 '16 at 09:51

5 Answers5

23

A data file that can hold data for one or more InnoDB tables and associated indexes.

There are many types of tablespaces based on the configuration w.r.t the information clubbing per table. These are,

a. System tablespace b. File per tablespace c. General tablespace

System tablespace contains,

  1. InnoDB data dictionary.
  2. DoubleWrite Buffer.
  3. Change buffer
  4. Undo Logs.

Apart from this it also contains,

  1. Tables &
  2. Index data

Associated file is .idbdata1

The innodb_file_per_table option, which is enabled by default in MySQL 5.6 and higher, allows tables to be created in file-per-table tablespaces, with a separate data file for each table. Enabling the innodb_file_per_table option makes available other MySQL features such as table compression and transportable tablespaces.

Associated file is .idbd

InnoDB introduced general tablespaces in MySQL 5.7.6. General tablespaces are shared tablespaces created using CREATE TABLESPACE syntax. They can be created outside of the MySQL data directory, are capable of holding multiple tables, and support tables of all row formats.

Bhupesh Pant
  • 4,053
  • 5
  • 45
  • 70
12

Adding to the excellent answer provided by @BhupeshPant

Storage of InnoDB is divided into tablespaces. A Tablespace is a logical structure associated with multiple data files (objects). Each tablespace contains pages(blocks), extents and segments.

enter image description here

Pages - A smallest piece of data for InnoDB also known as blocks. A page can hold one or more rows depending upon row size.

In general, every table has it's own tablespace that is associated with one datafile

The following command displays a full list of tablespace and the corresponding datafile -

SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;

To get a more proper under standing create a sample database - database1

CREATE DATABASE database1;
USE database1;

Now create a sample table table1 -

CREATE TABLE table1 (
    -> col1 INT
    -> );

Now we can see that the corresponding tablespace and datafile has also been created -

SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;

+--------------------------+--------------------------+
| TABLESPACE_NAME          | FILE_NAME                |
+--------------------------+--------------------------+
|database1/table1          | ./database1/table1.ibd   |
+--------------------------+--------------------------+

Here the .ibd extension signifies Innodb datafile

Now create another sample table table2 -

CREATE TABLE table2 (
    -> col1 INT
    -> );

We can again see that the corresponding tablespace and datafile has been created -

SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES;

+---------------------------+--------------------------+
| TABLESPACE_NAME           | FILE_NAME                |
+---------------------------+--------------------------+
| database1/table1          | ./database1/table1.ibd   |
| database1/table2          | ./database1/table2.ibd   |
+---------------------------+--------------------------+

Here the system is creating a default name for the tablespace. These system generated tablespaces are called - Single-Table tablespaces

Single-Table tablespaces are created by system only when innodb_file_per_table is ON

It can be checked by -

SHOW VARIABLES LIKE "innodb_file_per_table";
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+

By default, the values is ON. It can be turned off by -

SET GLOBAL innodb_file_per_table = OFF;

SHOW VARIABLES LIKE "innodb_file_per_table";
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF   |
+-----------------------+-------+

If the value is turned off, no Single-Table tablespaces are created.

To demonstrate this we again create a sample 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   |
+---------------------------+--------------------------+

Thus, we can see that no tablespace named - database1/table10 gets created

In such cases the table gets stored in innodb_system tablespace;

SELECT TABLESPACE_NAME, FILE_NAME FROM information_schema.FILES WHERE FILE_NAME LIKE "%ibdata1";
+-----------------+-----------+
| TABLESPACE_NAME | FILE_NAME |
+-----------------+-----------+
| innodb_system   | ./ibdata1 |
+-----------------+-----------+

But this is not a good practice as it gives more burden to system tablespace which results in performance related issue.

In case of system generated tablespace, on dropping the table the tablespace also gets dropped automatically.




There is another type of tablespace called - General Tablespaces where we can create a custom name for tablespace.

To do it we need to issue the following command -

CREATE TABLESPACE tablespace1 ADD DATAFILE '/var/lib/mysql/tablespace1.ibd' engine = Innodb;

We can check that the tablespace and corresponding datafile has been created -

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 |
+---------------------------+--------------------------------+

Here all tablespaces are created in Mysql datadir which by default is /var/lib/mysql/

The datadir value can be checked by the following command -

SELECT @@datadir;
+-----------------+
| @@datadir       |
+-----------------+
| /var/lib/mysql/ |
+-----------------+

In MySQL only one datafile can be added per tablespace. But in Oracle or SQL Server multiple datafiles can be added to a tablespace.

To create a table in the tablespace - tablespace1 we need to issue the command -

CREATE TABLE table3 (
    -> col1 INT 
    -> )
    -> TABLESPACE = tablespace1;

In case of general tablespaces, multiple tables can be created inside one tablespace -

CREATE TABLE table4 (
    -> col1 INT
    -> )
    -> TABLESPACE = tablespace1;

While creating a tablespace, the datafile location may not be stated exclusively. The following command will also work -

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              |
+---------------------------+--------------------------------+

Here by default all tablespaces get created in the datadir directory

Tablespace creates a page size of default value. However we can also set a page size of our own while creating a tablespace. However, the size must be within default page size, else there will be error. The default page size can be set during installation of MySQL server.

Permitted page sizes are - 4 kb, 8 kb, 16 kb, 32 kb, 64 kb.

In general during installation, 16 kb is set as default page size.

The following command is used to view the default page size -

SHOW VARIABLES LIKE 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+

The command to create a tablespace with a custom page size is -

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 |
+---------------------------+-------------------------------------+

To store a table in a tablespace with user-defined page size a different syntax is needed -

CREATE TABLE table5 (
    -> col1 INT
    -> )
    -> TABLESPACE = tablespace3_8kb 
    -> KEY_BLOCK_SIZE = 8;

Unlike system generated tablespace, general tablespace does not get dropped automatically if we drop the tables, the tablespaces need to be dropped explicitly.

The command is -

DROP TABLESPACE tablespace_name;
Payel Senapati
  • 1,134
  • 1
  • 11
  • 27
7

MySQL Innodb TableSpace is a location where the data resides in the disk called data directory (By default "system tablespace"). Example:

"/var/lib/mysql"

From MySQL version 5.6.6, an user can create and specify the tablespace they want to store the data which enables throughput of data manipulation and recovery process. InnoDB's file-per-table feature offers each tables to have separate .ibd data & index files which represents an individual general tablespace. So that each table in a database can point various locations of data directories.

Ex :

/home/{user}/test/data/{dbName}/{tableName}.ibd

/home/{user}/work/data/{dbName}/{tableName}.ibd

For more about the file-per-table tablespace, refer this mysql documentation.

Community
  • 1
  • 1
S.K. Venkat
  • 1,749
  • 2
  • 23
  • 35
5

By default, InnoDB contains only one tablespace called the system tablespace whose identifier is 0. More tablespaces can be created indirectly using the innodb_file_per_table configuration parameter. A tablespace consists of a chain of files. The size of the files does not have to be divisible by the database block size, because we may just leave the last incomplete block unused. When a new file is appended to the tablespace, the maximum size of the file is also specified. At the moment, we think that it is best to extend the file to its maximum size already at the creation of the file, because then we can avoid dynamically extending the file when more space is needed for the tablespace. Data files are dynamically extended, but redo log files are pre-allocated. Also, as already mentioned earlier, only the system tablespace can have more than one data file. It is also clearly mentioned that even though the tablespace can have multiple files, they are thought of as one single large file concatenated together. So the order of files within the tablespace is important.

From https://blogs.oracle.com/mysqlinnodb/entry/data_organization_in_innodb

Rukshan Hassim
  • 505
  • 6
  • 15
1

sql clients shall only use sql objects and not be concerned with where the database server physically stores that information.

that's why the concept of tablespace is needed. sql objects like table data goes into a tablespace from the point of view of the sql client.

The db server admins are now free to physically place the tablespace where they want it to go physically, the sql client programs still work.

user2587106
  • 315
  • 1
  • 5