14.10.2 Performance and Concurrency Considerations for Online DDL 在线DDL的性能和并发考虑
在线DDL 改善MySQL操作的几个方面,比如性能,并发,可用性和扩展性。
- 因为查询和DML操作在表上可以被处理 当DDL是在处理,应用访问表是更加灵敏的,
降低锁和等待其他资源尽管因此MySQL server 导致更大的扩展性,
即使操作不涉及的表被改变
2.对于就地操作,通过避免磁盘I/O和CPU 周期来重建表,你尽量最小化数据库的负载和维护好的性能和高吞吐量在DDL操作期间
3.因为较少的数据被读入到buffer pool 相比所有的数据被复制,你可以避免频繁的purge 被访问的数据,
如果一个在线的操作需要temporary 文件,InnoDB 创建它们在临时文件目录, 不是包含原始表的目录。
如果这个目录不是不够大来容纳这些文件,你不要设置tempdir 系统变量到不同的目录
mysql> show variables like ‘%tmpdir%’;
+——————-+——-+
| Variable_name | Value |
+——————-+——-+
| slave_load_tmpdir | /tmp |
| tmpdir | /tmp |
+——————-+——-+
2 rows in set (0.00 sec)
锁定选项用于在线DDL操作,表可能或者不能被锁定,依赖操作的内部运作和ALTER TABLE 语句的LOCK 子句。
默认的,MySQL 使用尽可能少的锁在DLL操作期间,你指定了子句可以使锁更加局限相比通常的限制
(因此限制并发DML, 或者DML和查询),或者确认一些预期程度的锁对于一个操作。
如果LOCK子句指定锁的级别,不适用于特定类型的DDL操作,
比如 LOCK=SHARED 或者LOCK=NONE 当创建或者删除 一个主键, 子句就像一个声明,
导致语句失败。下面的列表显示LOCK 子句不同的可能性,从最宽松到最限制。
1.对于DDL 操作像LOCK=NONE, 查询和并发请求是允许的,
这个子句让 ALTER TABLE 失败如果 DLL操作的类型不能被执行所请求的锁类型,
因此指定LOCK=NONE 保持表完全可用时重要的,如果这是不可能的你可能需要退出DDL。
比如,你可能使用子句在DDL 操作 涉及客户注册或者购买的表,为了避免这些表不可用通过错误的执行一个昂贵的ALTER TABLE语
句。
2.对于DDL 操作会用LOCK=SHARED,
任何对表的写入(DML操作) 是被堵塞,
但是表的数据可以被读取。 这个子句让ALTER TABLE 失败,因此指定了LOCK=SHARED
保证表可以用于查询是非常重要的。
比如,你可能私用这个子句在DDLs对于表在数据仓库里,它可以延迟数据加载操作直到DDL完成,
但是查询不能长时间延迟。
对于DDL 操作 LOCK=DEFAULT, 或者 LOCK 子句省略,MySQL 使用最小级别的锁定
允许并发的查询,DML。
对于DDL 操作 LOCK=EXCLUSIVE, 查询和DML操作都会被堵塞,
mysql> lock table t200 write;
Query OK, 0 rows affected (0.00 sec)
Database changed
mysql> select * from t200; –select 会被hang
一个在线的DDL 语句对于一个InnoDB 表总是等待并发执行的事务,访问表提交或者回滚
因为它需要排它访问表,当DDL语句是在准备期间。同样地,
它需要排它访问表一个短暂时间在完成前。 因此,一个在线DDL语句等待任何其他的事务,在DDL执行开始起动,
查询或者修改表,提交或者回滚 在DDL操作完成前。
因为有些处理工作涉及记录并发DML操作的改变, 然后在最后应用这些改变,
一个在线DDL操作可能需要很长的时间相比老的机制 阻止其他会话的访问。
一个新建的InnoDB secondary index 只包含提交的数据 在创建索引或者ALTER TABLE 语句完成执行
它不包含任何的未提交的值,旧版本的值,或者标记为删除的值,但是没有从老索引删除。
Performance of In-Place versus Table-Copying DDL Operations
一个在线DDL操作的原始性能是很大程序上有操作是否执行到位决定的,
或者需要复制和重建整个表。See Table 14.6, “Summary of Online Status for DDL Operations”
查看那些操作可以被执行到位的
in-place:妥当的
妥当的执行DDL操作应用在secondary indexes, 不对于primary key index.
InnoDB 表的记录是存储在一个clustered index基于主键组织, 一些数据库叫做 “index-organized table”.
因为表结构和主键是紧密联系的, 重新定义主键仍旧需要复制数据。
当一个操作在主键上使用 ALGORITHM=INPLACE, 尽管数据仍然被复制,
相比使用 ALGORITHM=COPY会更有效率 因为:
1.没有undo被记录或者 相关的redo 日志时需要用于ALGORITHM=INPLACE.
- secondary index 条目是预先排序的, 可以按顺序加载
3.change buffer 没有被使用,因为没有随机访问插入到secondary indexes.
判断在线DDL操作相关的性能, 你可以运行这样的操作 在一个大的InnoDB表 使用
当前和更早的MySQL的版本。
你可以运行所有的性能测试在最近的MySQL 版本,
模拟先前的DDL行为 对于先前的结果, 通过设置old_alter_table system variable.
执行语句 设置old_alter_table=1 在会话里, 测量 DDL性能来记录先前的数值。
然后设置old_alter_table=0来重新启用新的,快速的行为,再次运行DDL 操作来记录后面的数值
一个基本的思想是否一个DLL操作改变妥当的或者执行一个table copy,
看下在命令完成后影响的值。
改变列的默认值(超快速, 根本不影响数据)
增加一个索引(需要时间,但是0条记录受影响)
比如,在大表上运行DDL操作,