Documente Academic
Documente Profesional
Documente Cultură
By default InnoDB uses a shared tablespace for all tables that consists of one or
more files. These
files are used to store metadata for all the InnoDB tables across all databases on
the server, and
are usually referred to as ibdata files, because the default name for the first
file is ibdata1.
These ibdata files are, by default, stored in the datadir directory.
By default, ibdata files also contain all the data and indexes for all the InnoDB
tables. When
an InnoDB table is defragmented in a shared tablespace configuration, the ibdata
files will not
shrink, even though the data and indexes are successfully defragmented. The good
news is that
the space is not lost InnoDB will add that space to its pool of free space and
put new rows
in it. The amount of InnoDB free space that is reported in the TABLE_COMMENT field
of the
INFORMATION_SCHEMA.TABLES system view and the Comment field of SHOW TABLE STATUS
for a defragmented InnoDB table will increase. The bad news is that the operating
system
cannot reclaim that disk space and use it for other purposes if needed. The space
is used by the
tablespace files.
By default ibdata files are located in datadir. Any options for the InnoDB storage
engine
should be listed in the [mysqld] directive of the configuration file. The following
example
shows two ibdata files in the default data directory. One file is a gigabyte in
size, and the
second is configured to begin at a gigabyte in size but grow larger as needed:
innodb_data_file_path=ibdata1:1024M;ibdata2:1024M:autoextend
The innodb_data_home_dir option is used to specify the location of the ibdata files
explicitly,
to store them somewhere other than datadir. In the following example two ibdata
files
are in the /data directory:
innodb_data_home_dir = /data
innodb_data_file_path=ibdata1:1024M;ibdata2:1024M:autoextend
A third option would be to have the ibdata files located in different directories
from each
other. Using this method the files can be placed on separate hard drives for
performance gains
or because of low storage space. Here is how it is done:
innodb_data_home_dir =
innodb_data_file_path=/d1/ibdata1:1024M;/d2/ibdata2:1024M:autoextend
A single ibdata file can grow very large (over 300 gigabytes). In these cases, it
may be desirable
to add a new tablespace. Maybe the partition where the ibdata file is located is
running out of
space. The procedure to add an additional ibdata file is straightforward:
innodb_data_file_path=ibdata1:1024M:autoextend
Determine the actual size of ibdata1. This must be done to the nearest megabyte.
On
Unix-based systems a simple ls lh command executed in the data directory will
return
the current size in megabytes.
Once this is known the new innodb_data_file_path can be written. If the size of
the
ibdata1 file is 1824 megabytes and the second ibdata is to begin at 2 gigabytes in
size,
the new line would look this:
innodb_data_file_path=ibdata1:1824M;ibdata2:2G:autoextend
Adding this file is not very complicated. The previous section shows how you can
configure
your innodb_data_file_path
NB:
Do not think that just because an additional ibdata file is added that data will be
balanced across the files. If there were only 400 megabytes of data in ibdata1 (out
of a configured 1 gigabyte of space) when ibdata2 was added no table data will be
written to
ibdata2 until ibdata1 is completely full. Similarly, when ibdata1 is full, new data
is written
to ibdata2, and tables can be thus split across data files.
If you overestimated the size of the shared tablespace or it has grown much larger
than your
data (for example, if you have dropped some larger tables or your data is heavily
fragmented),
you may wish to remove an ibdata file from a shared tablespace. You may also wish
to
reorganize the current ibdata files for example, if one ibdata file is 100Mb and
another is
500 Mb, you may wish to have each ibdata file be 300 Mb. Unfortunately, this is not
as easy
as adding an ibdata file. To remove or reorganize shared tablespace files:
Perform a logical export (using a logical export tool such as mysqldump) of all
the InnoDB
tables.
Shut down mysqld.
Change the configuration options as desired to remove or reorganize a tablespace.
Move the existing ibdata files, ib_logfile log files, and .frm table definition
files to a
backup location.
Restart mysqld. The new ibdata file(s) will take some time to initialize.
Import the InnoDB tables.
After a successful import, you can delete the backup ibdata, ib_logfile, and .frm
files. Should you need to roll back to the previous ibdata files, shut down mysqld,
change the configuration options back to the previous values, and move the ibdata,
ib_logfile, and .frm files back.
If you decide to move from a shared tablespace to using per-table tablespaces the
process is somewhat
involved. Moving to a per-table tablespace allows you to easily see on-disk how
large the data
and indexes for the tables are. If a tablespace is significantly larger than the
metadata from SHOW
TABLE STATUS and the TABLES system view of the INFORMATION_SCHEMA database, it is
very
likely the table is fragmented. As previously stated, with per-table tablespaces,
defragmentation
reclaims disk space; storing all the data and indexes in the shared tablespace does
not.
Converting your database to use per-table data and index files is very similar to
reorganizing or
removing shared tablespace files:
Perform a logical export (using a logical export tool such as mysqldump) of all
the InnoDB
tables.
Shut down mysqld.
Edit the configuration file and add innodb_file_per_table in the [mysqld]
directive.
Though it is still necessary to retain an ibdata1 file it will remain relatively
small
compared to the overall amount of data in InnoDB tables. This is because it will
only contain
metadata about the tables. Because of this you will almost certainly want to edit
your
innodb_data_file_path. Something like this will probably be more appropriate:
innodb_data_file_path=ibdata1:256M:autoextend
Move the current InnoDB table format files (.frm files), ibdata file(s), and the
InnoDB
log files (ib_logfile) to a backup location until you are assured everything works
properly.
Restart mysqld. At this point a new central tablespace and InnoDB log files will
be
initialized.
Verify that you can create an InnoDB table and that an individual .ibd data file
is created
in the database directory.
Restore your files from the backup. Once this is done the InnoDB tables are all
stored in
per-table tablespace.
After a successful import, you can delete the backup ibdata and .frm files.
Should you
need to roll back to the previous ibdata files, shut down mysqld, change the
configuration
options back to the previous values, and move the ibdata and .frm files back.
The unsung heroes of InnoDB are the log files. They are what makes InnoDB automatic
crash recovery possible.