patternsqlMajor
MySql - changing innodb_file_per_table for a live db
Viewed 0 times
innodb_file_per_tablemysqlliveforchanging
Problem
I have a large MySql DB (150GB) and only now I've noticed that the
innodb_file_per_table is set to off which causes the entire DB to be hosted on one single file (ibdata1). I want to activate innodb_file_per_table and have it retroactively split the DB into several files, what's the best way to do this?Solution
There is really only one way to pull this off. You will have to export the data using mysqldumps, drop all databases, shutdown mysqld, delete ib_logfile0, delete ib_logfile1, delete ibdata1, add
I posted this answer in StackOverflow back in October 2010
Here are the steps listed vertically:
Step 01) MySQLDump all databases into a SQL text file (call it SQLData.sql)
Step 02) Drop all databases (except mysql schema)
Step 03) Shutdown mysql
CAVEAT: To totally clean out uncommitted transactions from the InnoDB Files, run this
Step 04) Add the following lines to /etc/my.cnf
Sidenote: Whatever your set for innodb_buffer_pool_size, make sure innodb_log_file_size is 25% of innodb_buffer_pool_size.
Step 05) Delete ibdata1, ib_logfile0 and ib_logfile1
At this point, there should only be the mysql schema in /var/lib/mysql
Step 06) Restart mysql
This will recreate ibdata1 at 10MB, ib_logfile0 and ib_logfile1 at 1G each
Step 07) Reload SQLData.sql into mysql
ibdata1 will grow but only contain table metadata
Each InnoDB table will exist outside of ibdata1
Suppose you have an InnoDB table named mydb.mytable. If you go into /var/lib/mysql/mydb, you will see two files representing the table
ibdata1 will never contain InnoDB data and Indexes anymore.
With the innodb_file_per_table option in /etc/my.cnf, you can run OPTIMIZE TABLE mydb.mytable and the file /var/lib/mysql/mydb/mytable.ibd will actually shrink.
I have done this many times in my career as a MySQL DBA
In fact, the first time I did this, I collapsed a 50GB ibdata1 file into 500MB.
Give it a try. If you have further questions on this, email me. Trust me. This will work in the short term and over the long haul. !!!
There is an alternative that will extract the InnoDB table without shrinking ibdata1.
Step 01) Add the following lines to /etc/my.cnf
Step 02)
Step 03) To extract a single InnoDB table called mydb.mytable, do this:
This will create one file pleus keep the original structure file
You can do this for every InnoDB table. Unfortunately, ibdata1 will stay 150GB.
innodb_file_per_table under the [mysqld] heading, start mysql.I posted this answer in StackOverflow back in October 2010
Here are the steps listed vertically:
Step 01) MySQLDump all databases into a SQL text file (call it SQLData.sql)
Step 02) Drop all databases (except mysql schema)
Step 03) Shutdown mysql
CAVEAT: To totally clean out uncommitted transactions from the InnoDB Files, run this
mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stopStep 04) Add the following lines to /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4GSidenote: Whatever your set for innodb_buffer_pool_size, make sure innodb_log_file_size is 25% of innodb_buffer_pool_size.
Step 05) Delete ibdata1, ib_logfile0 and ib_logfile1
At this point, there should only be the mysql schema in /var/lib/mysql
Step 06) Restart mysql
This will recreate ibdata1 at 10MB, ib_logfile0 and ib_logfile1 at 1G each
Step 07) Reload SQLData.sql into mysql
ibdata1 will grow but only contain table metadata
Each InnoDB table will exist outside of ibdata1
Suppose you have an InnoDB table named mydb.mytable. If you go into /var/lib/mysql/mydb, you will see two files representing the table
- mytable.frm (Storage Engine Header)
- mytable.ibd (Home of Table Data and Table Indexes for mydb.mytable)
ibdata1 will never contain InnoDB data and Indexes anymore.
With the innodb_file_per_table option in /etc/my.cnf, you can run OPTIMIZE TABLE mydb.mytable and the file /var/lib/mysql/mydb/mytable.ibd will actually shrink.
I have done this many times in my career as a MySQL DBA
In fact, the first time I did this, I collapsed a 50GB ibdata1 file into 500MB.
Give it a try. If you have further questions on this, email me. Trust me. This will work in the short term and over the long haul. !!!
There is an alternative that will extract the InnoDB table without shrinking ibdata1.
Step 01) Add the following lines to /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4GStep 02)
service mysql restartStep 03) To extract a single InnoDB table called mydb.mytable, do this:
ALTER TABLE mydb.mytable ENGINE=InnoDB;This will create one file pleus keep the original structure file
- /var/lib/mysql/mydb/mytable.frm
- /var/lib/mysql/mydb/mytable.ibd
You can do this for every InnoDB table. Unfortunately, ibdata1 will stay 150GB.
Code Snippets
mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4GALTER TABLE mydb.mytable ENGINE=InnoDB;Context
StackExchange Database Administrators Q#11043, answer score: 33
Revisions (0)
No revisions yet.