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.
Related
Is there a way to perform ALTER TABLE in MySQL, telling the server to skip creating a backup of the table first? I have a backup of the table already and I'm doing some tests on it (adding indexes), so I don't care if the table gets corrupted in the process. I'll just restore it from the backup. But what I do care about is for the ALTER TABLE to finish quickly, so I can see the test results.
Given that I have a big MyISAM table (700 GB) it really isn't an option to wait for couple of hours so that MySQL can first finish creating a backup of the original table, before actually adding an index to it.
It's not doing a backup; it is building the new version. (The existing table serves as a backup in case of a crash.)
With InnoDB, there are many flavors of ALTER TABLE -- some of which take essentially zero time, regardless of the size of the table. MyISAM (mostly) does the brute force way: Create an empty table with the new schema; copy all the data and build all the indexes; swap tables. For some alters, InnoDB must also do the brute force way: Example changing the PRIMARY KEY.
I wanted to create a temporary table in MySQL database which is a member of Master-Master replication. I run the query and created the temporary table, however, the table was created in one of the servers and has not been created in the other member of replication.
My question is, should not all of the queries be run in both of the replication members?
No, not at all.
Quoting the manual:
A TEMPORARY table is visible only within the current session, and is dropped automatically when the session is closed.
This means, even when you open another connection on the same server, you won't see the table.
Therefore it wouldn't make sense to create the temporary table on multiple servers, at least when you don't use it in a DML statement.
If you use this table to do an UPDATE, DELETE or INSERT statement, it gets replicated, but it depends on the way you replicate.
If your binlog format is STATEMENT, your temporary table is created on disk on the replicating server in the directory you specified in your tmp_data variable.
If it's MIXED or ROW, it gets transmitted in ROW format, if I remember correctly.
I have a table with the primary key of max signed INT hit, 2147483647
Imagine I want to switch it to unsigned, and there are no negative values in the table since it is a primary key, because Im under the current belief that it is the fastest way to get the table going again.
Should the ALTER TABLE statement to switch it to an unsigned INT be a relatively quick process, since the values of the ids shouldn't change? What about locking?
Mysql documentation on ALTER TABLE command describes quite in a detailed manner under "Storage, Performance, and Concurrency Considerations" section which changes can be done quickly, without table copy and index rebuild, and what locks mysql will apply during the course of the command. Changing the column type is unfortunately not listed as something that can be done in place (of course, read the documentation corresponding to your mysql version, I just linked the newest one).
For some operations, an in-place ALTER TABLE is possible that does not
require a temporary table:
For ALTER TABLE tbl_name RENAME TO new_tbl_name without any other options, MySQL simply renames any files that correspond to the table
tbl_name without making a copy. (You can also use the RENAME TABLE
statement to rename tables. See Section 13.1.28, “RENAME TABLE
Syntax”.) Any privileges granted specifically for the renamed table
are not migrated to the new name. They must be changed manually.
Alterations that modify only table metadata and not table data are immediate because the server only needs to alter the table .frm file,
not touch table contents. The following changes are fast alterations
that can be made this way:
Renaming a column.
Changing the default value of a column.
Changing the definition of an ENUM or SET column by adding new enumeration or set members to the end of the list of valid member
values, as long as the storage size of the data type does not change.
For example, adding a member to a SET column that has 8 members
changes the required storage per value from 1 byte to 2 bytes; this
will require a table copy. Adding members in the middle of the list
causes renumbering of existing members, which requires a table copy.
ALTER TABLE with DISCARD ... PARTITION ... TABLESPACE or IMPORT ... PARTITION ... TABLESPACE do not create any temporary tables or
temporary partition files.
ALTER TABLE with ADD PARTITION, DROP PARTITION, COALESCE PARTITION, REBUILD PARTITION, or REORGANIZE PARTITION does not create
any temporary tables (except when used with NDB tables); however,
these operations can and do create temporary partition files.
ADD or DROP operations for RANGE or LIST partitions are immediate operations or nearly so. ADD or COALESCE operations for HASH or KEY
partitions copy data between all partitions, unless LINEAR HASH or
LINEAR KEY was used; this is effectively the same as creating a new
table, although the ADD or COALESCE operation is performed partition
by partition. REORGANIZE operations copy only changed partitions and
do not touch unchanged ones.
Renaming an index.
Adding or dropping an index, for InnoDB.
Locking:
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 temporary
copy of the original table is created in the database directory of the
new table. This can differ from the database directory of the original
table for ALTER TABLE operations that rename the table to a different
database.
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).
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.
We started an ALTER TABLE which dropped one index and added another. Although we were only expecting the table to be locked for writes, reads started queueing up, so we killed the ALTER process. But when the KILL finished, the old index was gone, and the new index was there in its place, with a much lower cardinality than expected.
Searching on the table seems to be faster now, so it seems like the ALTER went through fine, but we're not sure. Is it possible that our KILL has left the index in a partially-built stage?
If the index is there you may assume that it is complete.
You can use SHOW CREATE TABLE or SHOW INDEXES to see the indexes on the table.
As noted in the comments, the cardinality listed by SHOW INDEXES is just an estimate.
One test you can try is to run SHOW INDEXES, then run ANALYZE TABLE, then run SHOW INDEXES again and see how the estimated cardinality value changes.
By your description (both reads/writes locked) you are most likely using an older version of InnoDB, or adding an index to a column in utf8 character set.
Here is how it works in your version:
Empty table is created with the new table definition.
Rows are copied 1 after the other from old table to new table (new indexes are also created).
Once copy is complete, old table is deleted, new table is renamed.
(If you cancel between steps 2&3 the new table is just safely removed.)
For full disclosure - here is how it works in InnoDB plugin (default for MySQL 5.5, available from 5.1+):
Table is read through to find data for the index, and written to a temporary file.
The temporary file is sorted.
The index is created by inserting the data in order.
(This method is more optimized. InnoDB calls is "fast-index creation".)