MariaDB 10.1.1:监控 InnoDB 在线 DDL 的进度和临时内存使用

引言

在线 DDL 是 MariaDB 10.0 中的一个新功能。在线 DDL 按顺序通过以下 4 个任务进行处理。

  1. InnoDB::ha_prepare_inplace_alter_table(..)
  2. InnoDB::ha_inplace_alter_table(..)
  3. InnoDB::ha_commit_inplace_alter_table(..)
  4. mysql_rename_table(..)

InnoDB 存储引擎在阶段 1 分配临时内存缓冲区用于事务日志记录,此阶段中的行变更会被记录。此缓冲区的大小初始为 sort_buffer_size,最大可增长到 innodb_online_alter_log_max 大小。在阶段 2 中,处理 ALTER 语句的线程会将旧表的行复制到新的修改后的表中。之后,MariaDB 将对目标表加排他锁,并将行日志缓冲区应用到新的修改后的表中。

这引入了一个新的、不可预测的故障情况:行日志缓冲区溢出。如果行日志缓冲区溢出,MariaDB 服务器将回滚 ALTER 语句。因此,存在以下问题:

  • 如果行日志缓冲区大小太小,ALTER 语句将被回滚,您将浪费宝贵的时间和资源。
  • 如果行日志缓冲区太大,您将浪费宝贵的内存,这些内存本可以用于例如缓冲池。
  • 目前,无法查看行日志缓冲区使用了多少空间以及剩余多少可用空间。
  • 目前,甚至无法估算已经完成多少工作以及还有多少工作待完成。
  • 目前,归并排序阶段也可能花费很长时间,并且没有进度信息。

改进

MariaDB 10.1 有两项改进:新的状态变量和在线 DDL 的进度信息。

新的状态变量和进度信息

MariaDB Corporation 要感谢 Matt 和来自 Kakao 的 Seong Uck Lee 贡献了一个补丁,该补丁现已合并到 MariaDB 10.1 中。

首先,有三个新的全局状态变量。

  • Innodb_onlineddl_rowlog_rows: 显示行日志缓冲区中存储的行数。
  • Innodb_onlineddl_rowlog_pct_used: 以 5 位整数显示行日志缓冲区使用率  (10000 表示 100.00%)。
  • Innodb_onlineddl_pct_progress: 显示原地修改表(in-place alter table)的进度。这可能不是非常精确,因为原地修改高度依赖于磁盘和缓冲池的状态。

让我们考虑一个例子,我们有一个包含 150000 行的 InnoDB 表,并且我们尝试添加一个新列。

CREATE TABLE tb_onlineddl1 (
pk1 int(11) NOT NULL,
pk2 bigint(20) NOT NULL,
fd1 bigint(20) DEFAULT NULL,
fd2 bigint(20) DEFAULT NULL,
fd3 datetime DEFAULT NULL,
fd4 text,
fd5 varchar(50) DEFAULT NULL,
fd6 bigint(20) DEFAULT NULL,
fd7 bigint(20) DEFAULT NULL,
PRIMARY KEY (pk1, pk2),
UNIQUE KEY ux1 (pk2, pk1),
KEY ix1 (fd6, fd7)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE tb_onlineddl1 ADD x VARCHAR(5), LOCK=NONE, ALGORITHM=INPLACE;

同时,如果我们添加新行,更新一些行并删除几行

insert into tb_onlineddl1 values (200000, 200000, 1,1, NULL,'insert', 'insert', 1,1);
update tb_onlineddl1 set fd5='update' where pk1 between 2000 and 3000;
delete from tb_onlineddl1 where pk1 between 6000 and 7000;
show status like 'Innodb_onlineddl%';

Variable_name	Value
Innodb_onlineddl_rowlog_rows	2003
Innodb_onlineddl_rowlog_pct_used	26
Innodb_onlineddl_pct_progress	5677

这意味着在执行 status 语句时,行日志中有 2003 行,分配给行日志的内存使用了 23%,并且在线修改表(online alter table)已完成其工作的 56.77%。

错误日志中也有额外的输出,例如

141022 15:49:59 [Note] InnoDB: Online DDL : Start
141022 15:49:59 [Note] InnoDB: Online DDL : Start reading clustered index of the table and create temporary files
141022 15:50:01 [Note] InnoDB: Online DDL : End of reading clustered index of the table and create temporary files
141022 15:50:01 [Note] InnoDB: Online DDL : Start merge-sorting index PRIMARY (1 / 3), estimated cost : 18.0263
141022 15:50:01 [Note] InnoDB: Online DDL : merge-sorting has estimated 33 runs
141022 15:50:01 [Note] InnoDB: Online DDL : merge-sorting current run 1 estimated 33 runs
141022 15:50:01 [Note] InnoDB: Online DDL : merge-sorting current run 2 estimated 17 runs
141022 15:50:01 [Note] InnoDB: Online DDL : merge-sorting current run 3 estimated 9 runs
141022 15:50:01 [Note] InnoDB: Online DDL : merge-sorting current run 4 estimated 5 runs
141022 15:50:01 [Note] InnoDB: Online DDL : merge-sorting current run 5 estimated 3 runs
141022 15:50:02 [Note] InnoDB: Online DDL : merge-sorting current run 6 estimated 2 runs
141022 15:50:02 [Note] InnoDB: Online DDL : End of  merge-sorting index PRIMARY (1 / 3)
141022 15:50:02 [Note] InnoDB: Online DDL : Start building index PRIMARY (1 / 3), estimated cost : 27.0395
141022 15:50:11 [Note] InnoDB: Online DDL : End of building index PRIMARY (1 / 3)
141022 15:50:11 [Note] InnoDB: Online DDL : Completed
141022 15:50:11 [Note] InnoDB: Online DDL : Start merge-sorting index ux1 (2 / 3), estimated cost : 5.7895
141022 15:50:11 [Note] InnoDB: Online DDL : merge-sorting has estimated 2 runs
141022 15:50:11 [Note] InnoDB: Online DDL : merge-sorting current run 1 estimated 2 runs
141022 15:50:11 [Note] InnoDB: Online DDL : End of  merge-sorting index ux1 (2 / 3)
141022 15:50:11 [Note] InnoDB: Online DDL : Start building index ux1 (2 / 3), estimated cost : 8.6842
141022 15:50:17 [Note] InnoDB: Online DDL : End of building index ux1 (2 / 3)
141022 15:50:17 [Note] InnoDB: Online DDL : Completed
141022 15:50:17 [Note] InnoDB: Online DDL : Start merge-sorting index ix1 (3 / 3), estimated cost : 6.1842
141022 15:50:17 [Note] InnoDB: Online DDL : merge-sorting has estimated 3 runs
141022 15:50:17 [Note] InnoDB: Online DDL : merge-sorting current run 1 estimated 3 runs
141022 15:50:17 [Note] InnoDB: Online DDL : merge-sorting current run 2 estimated 2 runs
141022 15:50:17 [Note] InnoDB: Online DDL : End of  merge-sorting index ix1 (3 / 3)
141022 15:50:17 [Note] InnoDB: Online DDL : Start building index ix1 (3 / 3), estimated cost : 9.2763
141022 15:50:23 [Note] InnoDB: Online DDL : End of building index ix1 (3 / 3)
141022 15:50:23 [Note] InnoDB: Online DDL : Completed

归并排序进度

此外,show processlist 语句将输出索引归并排序的预估进度,例如:

MariaDB [test]> show processlist;
+----+------+-----------+------+---------+------+----------------+--------------------------------------------------------------------------+----------+
| Id | User | Host      | db   | Command | Time | State          | Info                                                                     | Progress |
+----+------+-----------+------+---------+------+----------------+--------------------------------------------------------------------------+----------+
|  3 | root | localhost | test | Sleep   |   23 |                | NULL                                                                     |    0.000 |
|  4 | root | localhost | test | Query   |    0 | init           | show processlist                                                         |    0.000 |
|  5 | root | localhost | test | Query   |   28 | altering table | ALTER TABLE tb_onlineddl1 ADD x VARCHAR(5), LOCK=NONE, ALGORITHM=INPLACE |    0.356 |
+----+------+-----------+------+---------+------+----------------+--------------------------------------------------------------------------+----------+
3 rows in set (0.00 sec)

链接

http://seonguck.blogspot.kr/2014/09/what-is-problem-of-mysql-online-ddl.html
http://kakao-dbe.blogspot.kr/2014/09/mysql-status-variables-for-innodb.html