MySQL migration: MyISAM to InnoDB
페이지 정보
작성자 차동박 쪽지보내기 메일보내기 홈페이지 자기소개 아이디로 검색 전체게시물 댓글 0건 조회 31,965회 작성일 08-10-31 23:19본문
MySQL migration: MyISAM to InnoDB
By Keith Winston on July 18, 2005 (8:00:00 AM)
The MySQL database is unique in that it offers multiple storage engines. The SQL parser and front end interfaces are separate from the storage engines, so you can choose among nine low-level table formats the one that suits your application best. I recently needed to convert a production application from the default indexed sequential format, MyISAM, to InnoDB. Here's my no-hassle guide to performing the conversion.
Why would you want to convert an existing MySQL database from MyISAM to InnoDB? While the MyISAM format has low overhead and generally the fastest performance among MySQL storage engines, it does not have advanced features like transactions, rollbacks, and row-level locking. InnoDB has these features and is also fully ACID-compliant (atomicity, consistency, isolation, and durability). ACID compliance is one of the touchstones of high-end database systems. I needed these features to solve my problem.
One of the applications I inherited is a course registration system using the ubiquitous LAMP architecture (Linux, Apache, MySQL, PHP) and the default MyISAM table format. During peak usage (about 100 simultaneous users) some of the records added to the system were incorrectly linked with other records in related tables. The problem was that no locking was done on the database, leading to some SQL insert commands being executed out of order. While the MyISAM engine provides table locking to simulate transactions, that wasn't good enough for such a heavily used application. I needed the row-level locking and ACID transaction support of InnoDB. Here are the steps I took to convert a MySQL database from MyISAM to InnoDB:
Dump the database with
mysqldump
The first step is to dump the existing database using the
mysqldump
utility. The dump provides a complete backup of the database in case something goes wrong, and is also used to restore it later in the InnoDB format. Make sure the application is not in use while performing the conversion.Here is syntax I use:
Change the user and password as needed for your database. The
mysqldump --user=user --password=password --add-drop-table --databases db1 > db1.sql
Change the user and password as needed for your database. The
--add-drop-table
option generates the SQL instructions to create all the tables. Change the name db1 to the name of your database. The output of the dump is an ASCII file with SQL commands to rebuild the database from scratch. The output is redirected and stored in file db1.sql.Change TYPE=ISAM to TYPE=INNODB
The second step is to edit the db1.sql dump file with a text editor and change the table type to InnoDB. Make of copy of the dump file before you edit it in case you need to restore it later. Here is a sample table definition:
CREATE TABLE audience_def (
AUDIENCE_NO int(10) unsigned NOT NULL auto_increment,
DESCRIPTION varchar(150) default NULL,
STATUS varchar(10) default NULL,
PRIMARY KEY (AUDIENCE_NO)
) TYPE=ISAM;
For each table definition in the dump file, change the TYPE=ISAM to TYPE=INNODB. If your database is very large, the dump file may be too large to fit in your text editor. If so, you can use a batch editor like sed to make the changes.
To vastly increase the speed of the reload, add the SQL command
SET AUTOCOMMIT = 0;
to the beginning of the dump file, and add the COMMIT;
command to the end. By default, autocommit is on, meaning that each and every insert command in the dump file will be treated as a separate transaction and written to disk before the next one is started. If you don't add these commands, reloading a large database into InnoDB can take many hours.Add entries to<nobr> <wbr></nobr>/etc/my.cnf and restart MySQL
If MySQL is already configured to support InnoDB on your system, skip this step. Some distributions come with MySQL packages that are not configured to use the InnoDB storage engine, and some may require an extra package to be installed to support InnoDB. Check the documentation of your distribution to be sure.
A few extra entries are needed in the MySQL configuration file,<nobr> <wbr></nobr>/etc/my.cnf, to support InnoDB. For a basic configuration, add these settings under the [mysqld] group of settings in<nobr> <wbr></nobr>/etc/my.cnf:
[mysqld]
# InnoDB settings
innodb_data_home_dir =<nobr> <wbr></nobr>/var/lib/mysql/
innodb_data_file_path = ibdata1:100M:autoextend
set-variable = innodb_buffer_pool_size=100M
set-variable = innodb_additional_mem_pool_size=10M
innodb_flush_log_at_trx_commit=1
The
innodb_data_home_dir
setting defines the location where InnoDB should create data files. The innodb_data_file_path
setting defines the name of the data files. In this case, it will create a 100MB data file called ibdata1 and will extend the size as needed. A data file in InnoDB parlance is a tablespace.Next, restart the MySQL service. To see all the startup messages, you may want to start it from the command line instead of using the normal startup script. The first time you start MySQL with InnoDB support, it will take a lot longer to start, because it has to create the InnoDB data files (tablespaces) and transaction log files and initialize everything. After the first successful start, future restarts happen quickly.
After a successful start, you should see files with names like these in your<nobr> <wbr></nobr>/var/lib/mysql directory:
admin@linux01 [/var/lib/mysql]$ ls -l
-rw-rw---- 1 mysql mysql 104857600 Jul 4 11:13 ibdata1
-rw-rw---- 1 mysql mysql 5242880 Jul 4 11:13 ib_logfile0
-rw-rw---- 1 mysql mysql 5242880 Jul 4 11:13 ib_logfile1
The data file is ibdata1. The transaction log files are ib_logfile0 and ib_logfile1.
Load the database with
mysql
The final step is to drop the old database and reload it using the dump file. I prefer to log in to the database and issue a
drop db1;
command to delete it. To reload it in InnoDB format, simply feed the dump file back into MySQL with the command mysql --user=user --password=password
.Once that command completes, you should have a fully functional InnoDB database. Your application should not require any changes to work with InnoDB because the storage engine is isolated from the application code.
SQL wrap up
Now that your database is converted to InnoDB, you can take advantage of advanced features in your application. There were two places in my PHP application where the SQL
insert
statements needed to be executed atomically to ensure the data remained consistent. In those two places, I wrapped the SQL statements with the commands to start and stop a transaction. I added the SQL command BEGIN;
where I wanted the transaction to start, and COMMIT;
where I wanted the transaction to end. All the complicated details of the transaction are handled by InnoDB.Using the InnoDB storage engine in MySQL is relatively easy, but it does come with a price. The extra features in InnoDB require more resources in terms of CPU, memory, and disk space. After conversion to InnoDB, the database in my application used triple the disk space it did as MyISAM. In addition, because multiple databases are stored in the same data file, backups and restores may be more complicated.
Comments
on MySQL migration: MyISAM to InnoDBNote: Comments are owned by the poster. We are not responsible for their content.
i. there's a COMMIT. where's the ROLLBACK?
ii. how about handling foreign keys?
not nitpicking. just honestly asking how
you handled them, if you did.
ii. how about handling foreign keys?
not nitpicking. just honestly asking how
you handled them, if you did.
i. COMMIT and ROLLBACK always come in pairs. The former would be pointless without the later.
ii. Yes, they're there. That's one of the points for using InnoDB.
Not to nitpick, just honestly asking why you couldn't be bothered to look on the MySQL site before implying FUD.
ii. Yes, they're there. That's one of the points for using InnoDB.
Not to nitpick, just honestly asking why you couldn't be bothered to look on the MySQL site before implying FUD.
i was asking about the author's experience
with respect to using mysql and his
corresponding code changes. that's the point of
the article and not strictly mysql usage,
which i could easily have looked up in the their
site.
the COMMIT/ROLLBACK pair's impact on the code
is the point. not their existence.
same with how he handled foerign keys in
the code.
the problem with you mysql churchgoers
is that you identify anything short of an
obvious question as FUD against mysql,
which is not.
go eat some shit, wiseass.
with respect to using mysql and his
corresponding code changes. that's the point of
the article and not strictly mysql usage,
which i could easily have looked up in the their
site.
the COMMIT/ROLLBACK pair's impact on the code
is the point. not their existence.
same with how he handled foerign keys in
the code.
the problem with you mysql churchgoers
is that you identify anything short of an
obvious question as FUD against mysql,
which is not.
go eat some shit, wiseass.
I considered going into more detail about the changes in the PHP code, but wanted to limit the article to the MySQL conversion mechanics. Otherwise, it would have made the article way too long.
In my case, I added ROLLBACK to each "or die()" statement when calling MySQL from PHP. In my testing, InnoDB will do a rollback automatically if the script fails anywhere between the BEGIN/START and COMMIT, but it is always good form to be explicit.
Since MyISAM doesn't handle foreign keys, the application code already dealt with cascade deletes. It would be more efficient and safer to let InnoDB handle that, but it was beyond the scope of my initial conversion. I may go back and make those changes in the future. Again, I didn't go into foreign keys to keep the article succinct.
Good questions.
In my case, I added ROLLBACK to each "or die()" statement when calling MySQL from PHP. In my testing, InnoDB will do a rollback automatically if the script fails anywhere between the BEGIN/START and COMMIT, but it is always good form to be explicit.
Since MyISAM doesn't handle foreign keys, the application code already dealt with cascade deletes. It would be more efficient and safer to let InnoDB handle that, but it was beyond the scope of my initial conversion. I may go back and make those changes in the future. Again, I didn't go into foreign keys to keep the article succinct.
Good questions.
The easy way to convert a myisam table to innodb is:
Google for "mysql convert myisam to innodb". Or <a href="http://dev.mysql.com/doc/mysql/en/converting-tables-to-innodb.html" title="mysql.com">Click here</a mysql.com>.<tt>alter table mytable type=innodb;</tt>
Hi,
I'm sorry to say so, but your article is rather incomplete. Someone already said that only one ALTER statement would do the conversion. Your method, though has the benefit of having a backup. Also, as someone said, you forgot to talk about the rollback, that is as important as the commit. In my opinion, an introduction to transactions would have been welcomed.
I think it is incomplete since you failed to enumerate all the benefits of InnoDB and explaining the consequences of such a change.
InnoDB use an innovative lock mechanism, while MyISAM uses table locks. It also implements all four levels of isolation and referential integrity. You can get much better concurrency with InnoDB, since it user row-level locks and a version-control-like mechanism (called MVCC to make sure no action is uselessly stopped by a lock. Of course, this increases the CPU overhead. There are also other differences (indexes, for example).
For the question of disk usage, I am curious to see where you got your numbers? Directly from file sizes? I hope not.
Backups more difficult? Not really, as you can still use mysqldump just like you did with MyISAM tables, but you can't do hot backups without the software sold by InnoDB, and its, in my opinion, reasonably priced (by this, I mean that if you have the volume to need hot backups absolutely, the 1300USD$ for the perpetual licence won't scare you off).
Also, you should have warned the readers that they may loose functionnality when switching to InnoDB. Count()s will be slower and full-text indexing is not supported in InnoDB. One must make sure this will not affect the design or performance ot the application.
I'm sorry to say so, but your article is rather incomplete. Someone already said that only one ALTER statement would do the conversion. Your method, though has the benefit of having a backup. Also, as someone said, you forgot to talk about the rollback, that is as important as the commit. In my opinion, an introduction to transactions would have been welcomed.
I think it is incomplete since you failed to enumerate all the benefits of InnoDB and explaining the consequences of such a change.
InnoDB use an innovative lock mechanism, while MyISAM uses table locks. It also implements all four levels of isolation and referential integrity. You can get much better concurrency with InnoDB, since it user row-level locks and a version-control-like mechanism (called MVCC to make sure no action is uselessly stopped by a lock. Of course, this increases the CPU overhead. There are also other differences (indexes, for example).
For the question of disk usage, I am curious to see where you got your numbers? Directly from file sizes? I hope not.
Backups more difficult? Not really, as you can still use mysqldump just like you did with MyISAM tables, but you can't do hot backups without the software sold by InnoDB, and its, in my opinion, reasonably priced (by this, I mean that if you have the volume to need hot backups absolutely, the 1300USD$ for the perpetual licence won't scare you off).
Also, you should have warned the readers that they may loose functionnality when switching to InnoDB. Count()s will be slower and full-text indexing is not supported in InnoDB. One must make sure this will not affect the design or performance ot the application.
Although I totally jive with the migration from MyISAM to InnoDB, I can see a potential problem with such a migration.
Consider this scenario: I have an application with its own built-in search engine that employs the MyISAM table's native FULLTEXT index types for keyword searches. Conversion of the tables from MyISAM to InnoDB would cause fatal MySQL errors as long as the FULLTEXT indexes are in place, however, removing them would also cause fatal errors with the SELECT MATCH () AGAINST () queries that employ the FULLTEXT indexes.
What would you do in such a situation like this if it were asked to ensure ACID integrity of the table structures via conversion to InnoDB in light of this roadblock?
Thanx
Phil
Consider this scenario: I have an application with its own built-in search engine that employs the MyISAM table's native FULLTEXT index types for keyword searches. Conversion of the tables from MyISAM to InnoDB would cause fatal MySQL errors as long as the FULLTEXT indexes are in place, however, removing them would also cause fatal errors with the SELECT MATCH () AGAINST () queries that employ the FULLTEXT indexes.
What would you do in such a situation like this if it were asked to ensure ACID integrity of the table structures via conversion to InnoDB in light of this roadblock?
Thanx
Phil
AFAIK, you would have to leave the tables that use the FULLTEXT feature as MyISAM. You could convert the other tables to InnoDB. The only other solution I can think of is to move the text search into your application code which would be difficult and probably slower. Each storage engine has advantages and disadvantages. Good luck!
It's a good article, but it shouldn't have been necessary. MySQL has far too many options for its backend; and InnoDB should be the default, because it's the only one that gives you a real database.
There's some really good software in MySQL, but the defaults suck, in general. Somebody who picks the defaults at installation time should get a real database, and as strict compliance with standard SQL as is possible with MySQL.
MySQL migration: MyISAM to InnoDB
Posted by: Anonymous [ip: 61.247.255.57] on September 05, 2007 12:53 PMTypes Of MYSQl
Tremendously useful guide, just what i was looking for, thank you!
We have a drupal intranet serving just under 6000 people with about 100 authors, and MyISAM just don't cut the mustard
Thanks again.
We have a drupal intranet serving just under 6000 people with about 100 authors, and MyISAM just don't cut the mustard
Thanks again.
MySQL migration: MyISAM to InnoDB
Posted by: Anonymous [ip: 203.200.48.59] on December 01, 2007 05:23 PMThanks a lot
MySQL migration: MyISAM to InnoDB
Posted by: Anonymous [ip: 192.168.11.130] on January 17, 2008 09:06 AMI have followed this steps and I does not have encountered any errors, but when I dump again the migrated database (w/ type=InnoDB) then, when I was checking the dumped file the type I saw again was type=MyISAM instead of TYPE=InnoDB..... Please help me, what's should I do?...
MySQL migration: MyISAM to InnoDB
Posted by: Anonymous [ip: 85.5.150.27] on February 17, 2008 08:13 PMthank you! did the trick for me. save me a lot of time.
MySQL migration: MyISAM to InnoDB
Posted by: Anonymous [ip: 85.221.230.230] on February 22, 2008 12:10 PMHowever it's helpful guide please consider the fact, that your foreign keys declarations will be lost. MyISAM ignores F-keys declarations upon creation of tables and if you haven't original database schema, you're probably lost. That's pity.
I'm going to try it - but like phil above - i have a full text index used for searches. I think instead of this I will be moving the fulltext search to another table.
관련링크
- http://www.linux.com/articles/46370 5964회 연결
댓글목록
등록된 댓글이 없습니다.
Thanks
Posted by: Anonymous Coward on July 19, 2005 04:07 AM