I am running MySQL 5.6.13 and I would like to run a CREATE INDEX ... BTREE statement on my production database.
The table is InnoDB and has ~ 4 million rows, and I would like very much not to lock it.
According to the docs, it appears as if this statement will not completely lock my table and return quickly. But, I wanted a second opinion before I made this change.
Would it be safe to create this index?
By default, InnoDB in MySQL 5.6 will perform a read lock while creating the index, so you can still have other concurrent clients SELECT from the table, but not do insert/update/delete on that table while the index is being created.
You can optionally allow the index creation to be completely online and not even do the read lock:
ALTER TABLE my_table ADD INDEX a (a), LOCK=NONE;
See http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html for more details about online DDL statements in MySQL.
Also see this blog posted today from a MySQL Community Manager: Top 10 advances to availability since MySQL 5.5
PS: It's not necessary to specify BTREE for the index type. InnoDB supports only BTREE indexes, so it ignores that option.
Related
I need to create an index on a large InnoDB production table and want to do this without locking the table in any way. I am using MySQL 5.6 (.38-83.90).
I tried
create index my_index on my_table(col1, col2);
Neither columns are primary keys. col1 is a foreign key.
Well, this totally locked the table. Other queries were stalled with "Waiting for table metadata lock" bringing my website to its knees. I had to kill the create index query.
From this https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html I thought that it would not lock the table: "... no syntax changes are required... The table remains available for read and write operations while the index is being created or dropped."
I see that I can set LOCK=NONE or LOCK=SHARED, but I don't see that it should be necessary or, if it is, which one I need to use.
"You can specify LOCK=NONE to assert that concurrent DML is permitted during the DDL operation. MySQL automatically permits concurrent DML when possible."
"You can specify LOCK=SHARED to assert that concurrent queries are permitted during a DDL operation. MySQL automatically permits concurrent queries when possible."
None of the limitations https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-limitations.html seem to apply to my case.
What am I missing?
My guess (just a guess) is that you are missing the ALGORITHM=INPLACE clause on the CREATE INDEX statement.
CREATE INDEX my_index ON my_table(col1, col2) ALGORITHM=INPLACE ;
^^^^^^^^^^^^^^^^^
Also be aware of transactions acquiring and holding metadata locks.
https://dev.mysql.com/doc/refman/5.6/en/metadata-locking.html
Any transaction that has referenced my_table will continue to hold a metadata lock on that table until the transaction is committed or rolled back. I suggest checking the TRANSACTIONS section of SHOW ENGINE INNODB STATUS output.
I am using MySQL Server-5.1.58 Community log. The problem is after deleting the data the allocated space of MySQL database is not getting free and as a result day by day the backup size of my using database is increasing.
Please kindly let me know any tool which can resolve the issue.
Remember that MySQL locks the table during the time OPTIMIZE TABLE is running
For your MySQL version from the official documentation:
OPTIMIZE TABLE should be used if you have deleted a large part of a
table or if you have made many changes to a table with variable-length
rows (tables that have VARCHAR, VARBINARY, BLOB, or TEXT columns).
Deleted rows are maintained in a linked list and subsequent INSERT
operations reuse old row positions. You can use OPTIMIZE TABLE to
reclaim the unused space and to defragment the data file
Additional notes for InnoDB:
For InnoDB tables, OPTIMIZE TABLE is mapped to ALTER TABLE, which
rebuilds the table to update index statistics and free unused space in
the clustered index. Beginning with MySQL 5.1.27, this is displayed in
the output of OPTIMIZE TABLE when you run it on an InnoDB table, as
shown here:
mysql> OPTIMIZE TABLE foo;
Table does not support optimize, doing recreate + analyze instead
So:
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE
tbl_name [, tbl_name] ...
By default, OPTIMIZE TABLE statements are written to the binary log so
that they will be replicated to replication slaves. Logging can be
suppressed with the optional NO_WRITE_TO_BINLOG keyword or its alias
LOCAL.
I have a MySQL InnoDB database running on the Google App-Engine.
One of the tables has the current date and a user_id as primary key stored with some additional data.
The table had around 7 million rows and I deleted 6 million of them with a DELETE query. Since that any query using this table is much slower than before.
Any ideas what could cause this behavior or how to solve this?
Thanks in advance!
After such a massive delete on innodb you would better to use OPTIMISE table statement
Use OPTIMIZE TABLE in these cases, depending on the type of table:
After doing substantial insert, update, or delete operations on an InnoDB table that has its own .ibd file because it was created with
the innodb_file_per_table option enabled. The table and indexes are
reorganized, and disk space can be reclaimed for use by the operating
system.
After doing substantial insert, update, or delete operations on columns that are part of a FULLTEXT index in an InnoDB table. Set the
configuration option innodb_optimize_fulltext_only=1 first. To keep
the index maintenance period to a reasonable time, set the
innodb_ft_num_word_optimize option to specify how many words to
update in the search index, and run a sequence of OPTIMIZE TABLE
statements until the search index is fully updated.
Prior to optimize, check the table's state using ANALYSE TABLE, and it's indexes using SHOW INDEX. These instructions will provide you with information regarding the "flaws" that OPTIMIZE can fix.
All this is easy to do in phpmyadmin.
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;
I'm trying to reverse a date type index on a InnoDB database schema via. MySQL Workbench
But every time i try to apply the changes they are ignored?
Do i need to use the command line to configure the database?
According to http://www.oracle.com/partners/en/knowledge-zone/mysql-5-5-innodb-myisam-522945.pdf
Page 10. InnoDB supports BTREE indexes.