How to temporary lock a database in mysql - mysql

I am using Engine InnoDB on my MySQL server.
I have a patch script to upgrade my tables like add new columns and fill in default data.
I want to make sure there is no other session using the database. So I need a way to lock the database:
The lock shouldn't kick out an existing session. If their is any other existing session just fail the lock and report error
The lock need to prevent other sessions to read/write/change the database.
Thanks a lot everyone!

You don't need to worry about locking tables yourself. As the MySQL documentation (http://dev.mysql.com/doc/refman/5.1/en/alter-table.html) says:
In most cases, ALTER TABLE makes a temporary copy of the original
table. MySQL waits for other operations that are modifying the table,
then proceeds. It incorporates the alteration into the copy, deletes
the original table, and renames the new one. While ALTER TABLE is
executing, the original table is readable by other sessions. Updates
and writes to the table that begin after the ALTER TABLE operation
begins are stalled until the new table is ready, then are
automatically redirected to the new table without any failed updates.

Related

How to do an ALTER TABLE with a table in-use

I have a script that runs 24-7 on a table to perform necessary functions on it. However, when it is running, it is almost impossible to do an ALTER TABLE ADD INDEX statement, as it seems like it just hangs indefinitely. Is there any way around this? How should I go about adding this index?
The Alter table statement is getting a metadata lockout. You cannot perform your alter statement while another transaction is in process on the same table. Since your script runs 24-7, it is not possible to do what you are asking.
To ensure transaction serializability, the server must not permit one session to perform a data definition language (DDL) statement on a table that is used in an uncompleted explicitly or implicitly started transaction in another session. The server achieves this by acquiring metadata locks on tables used within a transaction and deferring release of those locks until the transaction ends. A metadata lock on a table prevents changes to the table's structure. This locking approach has the implication that a table that is being used by a transaction within one session cannot be used in DDL statements by other sessions until the transaction ends.
You can read more about this Here at dev.mysql.
Version 5.6 has ALTER TABLE ... ALGORITHM=INLACE ... to do ADD INDEX and several other ALTERs without blocking everything.
pt-online-table-alter (from Percona.com) can do it in older versions of MySQL. It uses a TRIGGER.

migrate MyISAM table to InnoDB on live site

How should I convert MyISAM table to InnoDB on live working site in real time?
Should I just change in phpmyadmin in operations menu "Storage Engine" to InnoDB?
Would it lock all table during conversion?
You will indeed get a write lock on the table. You will still be able to read from the table while the new table is being created and copied over.
From the documentation on ALTER TABLE:
While ALTER TABLE is executing, the original table is readable by
other sessions (with the exception noted shortly). Updates and writes
to the table that begin after the ALTER TABLE operation begins are
stalled until the new table is ready, then are automatically
redirected to the new table without any failed updates.
...
The exception referred to earlier is that ALTER TABLE blocks reads
(not just writes) at the point where it is ready to install a new
version of the table .frm file, discard the old file, and clear
outdated table structures from the table and table definition caches.
At this point, it must acquire an exclusive lock. To do so, it waits
for current readers to finish, and blocks new reads (and writes).
Check out pt-online-schema-change. See example in this answer https://dba.stackexchange.com/questions/60570/best-way-to-add-a-new-column-to-a-large-table-mysql-myisam/60576#60576
It will block a table for a second or so to rename two tables.
While it might work you'd better make a copy of your table and try the storage engine change operation on the copy.
That would also give you an estimate of time needed for the operation.
Even better would be if you do that on a copy of your application and make extensive checks whether it would work at all with the new storage engine.

How does table locking affect table engine change from MyISAM to InnoDB?

So I have been asked to change the engine of a few tables in a production database from MyISAM to InnoDB. I am trying to figure out how that will affect usage in production (as the server can afford no downtime).
I have read some conflicting information. Some information I have read state that the tables are locked and will not receive updates until after the conversion completes (IE, updates are not queued, just discarded until it completes).
In other places, I have read that while the table is locked, the inserts and updates will be queued until the operation is complete, and THEN the write actions are performed.
So what exactly is the story here?
This is directly from the manual:
In most cases, ALTER TABLE makes a temporary copy of the original
table. MySQL waits for other operations that are modifying the table,
then proceeds. It incorporates the alteration into the copy, deletes
the original table, and renames the new one. While ALTER TABLE is
executing, the original table is readable by other sessions. Updates
and writes to the table that begin after the ALTER TABLE operation
begins are stalled until the new table is ready, then are
automatically redirected to the new table without any failed updates.
So, number two wins. They're not "failed", they're "stalled".
The latter is correct. All queries against a table that's being altered are blocked until the alter completes, and are processed once the alter finishes. Note that this includes read queries (SELECT) as well as write queries (INSERT, UPDATE, DELETE).

MySQL Drop INDEX and REPLICATION

In a MySQL MASTER MASTER scenario using InnoDB
When dropping an index on one instance will the same table on the other instance be available?
What is the sequence of activities?
I assume the following sequence:
DROP INDEX on 1st instance
Added to the binary log
DROP INDEX on 2nd instance
Can anyone confirm?
I believe the following will happen:
Your DROP INDEX (which really runs an ALTER TABLE ... DROP INDEX) runs on the master
If the ALTER completes successfully the statement will then be added to the binlog and will be run on the slave
This means that the ALTER TABLE on the other machine won't start until the ALTER TABLE has successfully completed on the first (master) machine.
While the ALTER TABLE is running on either machine the table will be readable for a while and then neither readable/writeable as MySQL first makes a copy of the table internally then applies the changes.
From http://dev.mysql.com/doc/refman/5.0/en/alter-table.html
In most cases, ALTER TABLE works by
making a temporary copy of the
original table. The alteration is
performed on the copy, and then the
original table is deleted and the new
one is renamed. While ALTER TABLE is
executing, the original table is
readable by other sessions. Updates
and writes to the table are stalled
until the new table is ready, and then
are automatically redirected to the
new table without any failed updates.
The temporary table is created in the
database directory of the new table.
This can be different from the
database directory of the original
table if ALTER TABLE is renaming the
table to a different database.
In a MySQL MASTER MASTER scenario using InnoDB
In so far as I'm aware, such a thing is not possible. You'd need to use NDB, or be in a multi-master-slave environment with auto-incrementing fields configured to increment by 1/2/3/more. So assuming the latter. (Note: if you're aware of an InnoDB based solution, please share.)
When dropping an index on one instance will the same table on the other instance be available?
Dropping an index only means your index won't be available. Not the table. It'll be written (and propagated) to the binary log and begone with.

What happens if you kill a long-running alter query?

What happens if you kill a long-running alter query? Will the alter query simply revert? How long could that take (as a proportion of the time it has already been running)?
What if that query is being replicated onto another server? Will killing the process on the other server revert the original server's alter query?
We're running mysql
It depends what you're doing. If you're running an alter table...add index command on an InnoDB table (not so sure about MyISAM), then it will just run and run as it copies the whole darn table lock-stock-and-barrel first: if it's in the middle of "copy to temp table" then it's pretty much unstoppable.
See here:
In most cases, ALTER TABLE works by
making a temporary copy of the
original table. The alteration is
performed on the copy, and then the
original table is deleted and the new
one is renamed. While ALTER TABLE is
executing, the original table is
readable by other sessions. Updates
and writes to the table are stalled
until the new table is ready, and then
are automatically redirected to the
new table without any failed updates.
What if that query is being replicated onto another server?
The ALTER will be executed on that server as well, with the associated impacts.
Will killing the process on the other server revert the original server's alter query?
Nope. The original server has no back channel to learn about what occurred (or didn't) on the slave. If you kill the ALTER on the slave, then you will wind up in the situation where the master has the new constraint or index, and the slave doesn't. This is rarely a recipe for happiness :)
Once an ALTER enters the replication log, you either have to let it run everywhere, or kill it everywhere.