ALTER TABLE without locking the table?

后端 未结 19 1847
梦毁少年i
梦毁少年i 2020-11-30 17:41

When doing an ALTER TABLE statement in MySQL, the whole table is read-locked (allowing concurrent reads, but prohibiting concurrent writes) for the duration of the statement

相关标签:
19条回答
  • 2020-11-30 17:54

    I would recommend one of two approaches:

    1. Design your database tables with the potential changes in mind. For example, I've worked with Content Management Systems, which change data fields in content regularly. Instead of building the physical database structure to match the initial CMS field requirements, it is much better to build in a flexible structure. In this case, using a blob text field (varchar(max) for example) to hold flexible XML data. This makes structural changes very less frequent. Structural changes can be costly, so there is a benefit to cost here as well.

    2. Have system maintenance time. Either the system goes offline during changes (monthly, etc), and the changes are scheduled during the least heavily trafficked time of the day (3-5am, for example). The changes are staged prior to production rollout, so you will have a good fixed window estimate of downtime.

    2a. Have redundant servers, so that when the system has downtime, the whole site does not go down. This would allow you to "roll" your updates out in a staggered fashion, without taking the whole site down.

    Options 2 and 2a may not be feasible; they tend to be only for larger sites/operations. They are valid options, however, and I have personally used all of the options presented here.

    0 讨论(0)
  • 2020-11-30 17:55

    Percona makes a tool called pt-online-schema-change that allows this to be done.

    It essentially makes a copy of the table and modifies the new table. To keep the new table in sync with the original it uses triggers to update. This allows the original table to be accessed while the new table is prepared in the background.

    This is similar to Dems suggested method above, but this does so in an automated fashion.

    Some of their tools have a learning curve, namely connecting to the database, but once you have that down, they are great tools to have.

    Ex:

    pt-online-schema-change --alter "ADD COLUMN c1 INT" D=db,t=numbers_are_friends
    
    0 讨论(0)
  • 2020-11-30 17:57

    This question from 2009. Now MySQL offers a solution:

    Online DDL (Data Definition Language)

    A feature that improves the performance, concurrency, and availability of InnoDB tables during DDL (primarily ALTER TABLE) operations. See Section 14.11, “InnoDB and Online DDL” for details.

    The details vary according to the type of operation. In some cases, the table can be modified concurrently while the ALTER TABLE is in progress. The operation might be able to be performed without doing a table copy, or using a specially optimized type of table copy. Space usage is controlled by the innodb_online_alter_log_max_size configuration option.

    It lets you adjust the balance between performance and concurrency during the DDL operation, by choosing whether to block access to the table entirely (LOCK=EXCLUSIVE clause), allow queries but not DML (LOCK=SHARED clause), or allow full query and DML access to the table (LOCK=NONE clause). When you omit the LOCK clause or specify LOCK=DEFAULT, MySQL allows as much concurrency as possible depending on the type of operation.

    Performing changes in-place where possible, rather than creating a new copy of the table, avoids temporary increases in disk space usage and I/O overhead associated with copying the table and reconstructing secondary indexes.

    see MySQL 5.6 Reference Manual -> InnoDB and Online DDL for more info.

    It seems that online DDL also available in MariaDB

    Alternatively you can use ALTER ONLINE TABLE to ensure that your ALTER TABLE does not block concurrent operations (takes no locks). It is equivalent to LOCK=NONE.

    MariaDB KB about ALTER TABLE

    0 讨论(0)
  • 2020-11-30 17:57

    See Facebook's online schema change tool.

    http://www.facebook.com/notes/mysql-at-facebook/online-schema-change-for-mysql/430801045932

    Not for the faint of heart; but it will do the job.

    0 讨论(0)
  • 2020-11-30 17:57

    As SeanDowney has mentioned, pt-online-schema-change is one of the best tools to do what you have described in the question here. I recently did a lot of schema changes on a live DB and it went pretty well. You can read more about it on my blog post here: http://mrafayaleem.com/2016/02/08/live-mysql-schema-changes-with-percona/.

    0 讨论(0)
  • 2020-11-30 17:58

    The only other option is to do manually what many RDBMS systems do anyway...
    - Create a new table

    You can then copy the contents of the old table over a chunk at a time. Whilst always being cautious of any INSERT/UPDATE/DELETE on the source table. (Could be managed by a trigger. Although this would cause a slow down, it's not a lock...)

    Once finished, change the name of the source table, then change the name of the new table. Preferably in a transaction.

    Once finished, recompile any stored procedures, etc that use that table. The execution plans will likely no longer be valid.

    EDIT:

    Some comments have been made about this limitation being a bit poor. So I thought I'd put a new perspective on it to show why it's how it is...

    • Adding a new field is like changing one field on every row.
    • Field Locks would be much harder than Row locks, never mind table locks.

    • You're actually changing the physical structure on the disk, every record moves.
    • This really is like an UPDATE on the Whole table, but with more impact...
    0 讨论(0)
提交回复
热议问题