Swaping MySQL table engines on the fly - mysql

I have a relatively large table (a couple millions of records), multiple websites are querying this table, and from the very beginning the table's engine was MyISAM, currently I'm experiencing difficulties with table locks.
So. i decided to change the Table engine from MyISAM to InnoDB.
The question: are there any hidden stones in that? The DB is live. So i need to be sure that it won't affect any web-sites' functionality.
There are no full-text indexes are currently set up in this table.

Basically, you'd have to do this:
ALTER TABLE t1 ENGINE=InnoDB;
or this:
INSERT INTO my_innodb_table SELECT * FROM my_myisam_table
Check this: Converting Tables from Other Storage Engines to InnoDB for considerations on the matter, specially:
InnoDB does not have a special optimization for separate index
creation the way the MyISAM storage engine does. Therefore, it does
not pay to export and import the table and create indexes afterward.
The fastest way to alter a table to InnoDB is to do the inserts
directly to an InnoDB table. That is, use ALTER TABLE ...
ENGINE=INNODB, or create an empty InnoDB table with identical
definitions and insert the rows with INSERT INTO ... SELECT * FROM
....
Also these:
http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
http://dev.mysql.com/doc/refman/5.1/en/forcing-innodb-recovery.html

Related

Most common and important SQL commands that solely apply to MyIsam storage engine?

It has been recently come up into one of our discussions that moving an old legacy system using old MyISAM based MySQL deployment can't be easily replaced by an InnoDB based MySQL or MariaDB deployment. The reason that came up was that there were too many MyISAM only SQL commands all over the place. I haven't seen the code yet so I'm wondering what SQL commands where they referring to.
I only know of SEVERAL like below which are associated with table locking. It will probably work with InnoDB still in theory, but more appropriate for MyISAM , MERGE, and MEMORY storage engines which support table locking.
LOCK TABLES
UNLOCK TABLES
If there are more, or point me to a collection of it. It will be highly appreciated.
--edit--
I'll put everything else I find below this line.
MATCH (http://dev.mysql.com/doc/refman/5.5/en//fulltext-search.html)
You can LOCK TABLES for an InnoDB table too, so that's not MyISAM-specific. Though it's unnecessary to lock InnoDB tables. It's preferable to use transactions, MVCC, and SELECT...FOR UPDATE.
There are a number of configuration variables and status variables that are relevant only for MyISAM, such as key_buffer_size to dedicate some memory to caching indexes. But these are not commands.
A couple of features of MyISAM tables aren't supported by InnoDB. One is grouped auto-increment primary keys:
CREATE TABLE foo (
group_id INT,
position INT AUTO_INCREMENT,
PRIMARY KEY (group_id, position)
);
The table above increments position as you insert rows, but starts over at 1 for each distinct value of group_id. This works only in MyISAM.
CREATE FULLTEXT INDEX, and hence the MATCH()...AGAINST() query predicate are currently supported only in MyISAM. But these are being implemented for InnoDB in MySQL 5.6.
CREATE SPATIAL INDEX is supported only in MyISAM.
CHECKSUM TABLE applies only to MyISAM tables.
OPTIMIZE TABLE is in some ways specific to MyISAM, but when you run this command against an InnoDB table, it's automatically translated to a recreate + analyze operation.
CREATE TABLE options that are supported only by MyISAM:
AVG_ROW_LENGTH=nnn
DATA_DIRECTORY=path
INDEX_DIRECTORY=path
DELAY_KEY_WRITE=1
PACK_KEYS=1
ROW_FORMAT=FIXED
The MERGE storage engine can merge only MyISAM tables.
My favorite command to apply to a MyISAM table is the following. :-)
ALTER TABLE tablename ENGINE=InnoDB;
I prefer create a "temporary" table, insert/update and delete, drop the old table and than rename the new table to the old name.
otherwise you can in the last step
TRUNCATE TABLE x;
INSERT INTO x SELECT * from temp_x;

Foreign keys for myISAM and InnoDB tables

I have a DB table that is myISAM, used for fulltext searching. I also have a table that is InnoDB. I have a column in my myISAM table that I want to match with a column in my InnoDB table. Can that be done? I cant seem to work it out!
http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
Foreign keys definitions are subject to the following conditions:
Both tables must be InnoDB tables and they must not be TEMPORARY tables.
So, I'm afraid you wont be able to achieve what you want done.
I would recommend altering your DB architecture such that you have one set of tables designed with data integrity for writing (all InnoDB), and a second set designed for search - possibly on a different box, and possibly not even using MySQL, but maybe a search server like Solr or Sphinx, which should outperform a fulltext MySQL table. You could then populate your search DB periodically from your write DB.

If i change mysql engine from Myisam to innodb, will it affect on my data

I am new to Mysql .
will it affect my data on server if i change mysql engine from Myisam to innodb.
Thanks
Changing engine from MyISAM to INNODB should not affect your data, but safe side you can easily take backup of your table before changine engine.
Taking backup:
CREATE TABLE backup_table LIKE your_table;
INSERT INTO backup_table SELECT * FROM your_table;
It may affect the performance of your queries. You need to configure Innodb specific System variables. e.g.
innodb_buffer_pool_size = 16G
innodb_additional_mem_pool_size = 2G
innodb_log_file_size = 1G
innodb_log_buffer_size = 8M
Changing engine to INNODB:
ALTER TABLE table_name ENGINE=INNODB;
I found two caveats when converting MyISAM tables to InnoDB: row size and support for full-text indexes
I ran into an issue converting some tables from an off-the-shelf application from MyISAM to InnoDB because of the maximum record size. MyISAM supports longer rows than InnoDB does. The maximum in a default InnoDB installation is about 8000 bytes. You can work around this by TRUNCATE'ing a table that fails, but this will bite you later on the INSERT. You might have to break your data up into multiple tables or restructure it with variable length column types such as TEXT (which can be slower).
A stock Innodb installation doesn't support FULLTEXT indexes. This may or may not impact your application. For one application's table I was converting, we decided to look in other fields for the data we needed rather than doing full text scans. (I did an "ALTER TABLE DROP INDEX..." on it to remove the FULLTEXT index before converting to InnoDB.) I wouldn't recommend full-text indexes for a write-heavy table anyway.
If converting a big table full of data with "ALTER TABLE..." works on the first try, you're probably okay.
http://dev.mysql.com/doc/refman/5.5/en/innodb-restrictions.html
Lastly, if you want to convert from MyISAM to InnoDB on a running system that is read heavy (where UPDATEs and INSERTs are rare), you can run this without interrupting your users. (The RENAME runs atomically. It will back out all of the changes if any of them don't work.)
CREATE TABLE mytable_ind AS SELECT * FROM mytable;
ALTER TABLE mytable_ind ENGINE=InnoDB;
RENAME TABLE mytable TO mytable_myi, mytable_ind TO mytable;
DROP TABLE mytable_myi;

MySQL default database and how to make existing non-InnoDB become InnoDB

I am in the beginning stages of a project and I have so far been using the default MySQL database.
By the way, does the default database have name?
My question is how I can change the existing tables to be utf-8 and InnoDB without deleting the current ones and making new tables. Is there an alter table to make the table utf-8 and InnoDB?
Thanks,
Alex
MyISAM is the default Storage Engine for MySQL (until 5.5.5, at which point InnoDB became the default). There is no concept of a default database.
To make an existing table use InnoDB, use the following:
ALTER TABLE tbl_name ENGINE = InnoDB;
To change the character set of an existing table to utf8, use the following:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8;
If you want to play it safe with changing a table to InnoDB, I have a nice suggestion:
Create a new table as InnoDB and load it
For this example you have a MyISAM table called mytable in the mydb database. You can perform the following:
use mydb
CREATE TABLE mytable_innodb LIKE mytable;
ALTER TABLE mytable_innodb ENGINE=InnoDB;
INSERT INTO mytable_innodb SELECT * FROM mytable;
ALTER TABLE mytable RENAME mytable_myisam;
ALTER TABLE mytable_innodb RENAME mytable;
That's it. The new table is InnoDB plus you have a backup of the original table in MyISAM with its original contents and layout. You are free to perform whatever other conversions you need on the new InnoDB table.
CAVEAT
Make sure you optimize InnoDB
InnoDB performance tweaks
Howto: Clean a mysql InnoDB storage engine?
How to Safely Change InnoDB Log File Size
Major Differences Between InnoDB and MyISAM

mysql create table command add ons question

My team has added these statements with the create tables after the columns are defined:
ENGINE=MyISAM DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC AUTO_INCREMENT=465
The question is the table is a country lookup table. so we know it has a fixed list values of about 275-ish. And this table will be 99% a read only table. Very rare will be any write if i need to update any colunm property.
So do i need all that stuff beyond 'ENGINE=MyISAM DEFAULT CHARSET=utf8'? this is just one table, they have these for all most all tables and i cant understand why lookup tables will have all these commands/
You can look up all those in the CREATE TABLE doc.
You're right though. For the context you describe, they're almost surely completely unnecessary.
Asides
Re: AUTO_INCREMENT as part of your CREATE TABLE -- yeah, that's just because it was part of the SHOW CREATE TABLE of a live table, not because it was part of your teams intentions/ongoing script. No biggie.
Note that CHECKSUM and DELAY_KEY_WRITE are for MyISAM tables only. If that table was InnoDB, the features those two parameters bring are arguably implicitly taken care of (i.e. table integrity and write issues).
Why do we need innoDB for read only lookup tables? I thought innoDB is better for write intensive tables?
Sorry. I didn't mean to imply that you needed InnoDB. It's just a reflex. :)
Wheater or not InnoDB performs better for writing depends on the usage pattern / application. For your context, I wouldn't expect you seeing a performance difference weither you use MyISAM or InnoDB. At any rate, as a rule of thumb, since InnoDB can be acid complient, more resistant to corruption, and stored in memory (in InnoDB's buffer pool) I always advocate for it. MyISAM fails on all those counts.