【问题标题】:Ghost/copy table is many times bigger than original table幽灵/复制表比原始表大很多倍
【发布时间】:2021-02-14 05:13:00
【问题描述】:

信息:我正在使用 AWS RDS Mysql 5.6.34 (500GB) 实例(没有副本,只有主实例)

注意: Binlog 已启用并设置为 Row

目标:将列field_1从枚举修改为tinyint

额外信息:我正在使用 Rails 应用程序。所以每次我想为枚举添加一个值时,我都需要编写一个迁移。因此,将枚举字段转换为 tinyint,这样我就可以添加或删除枚举值,而无需使用 Active Enum 编写迁移。

其他信息:我也尝试了LHM,但 RDS 实例内存不足 93%

运行 gh-ost 之前的数据库信息:

mysql> select table_schema, sum((data_length+index_length)/1024/1024) AS MB from information_schema.tables group by 1;
+--------------------+-----------------+
| table_schema       | MB              |
+--------------------+-----------------+
| information_schema |      0.00976560 |
| mysql              |      5.96277428 |
| performance_schema |      0.00000000 |
| my_app_db          | 223941.79882818 |
+--------------------+-----------------+

gh-ost前原表的大小:(从列表中只显示需要修改的表)

mysql> SELECT table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024), 2) `Size (MB)` FROM information_schema.TABLES WHERE table_schema = "my_app_db";
+----------------------------------------+-----------+
| Table                                  | Size (MB) |
+----------------------------------------+-----------+
| table_abc                              |     70.41 |
| my_table                               |  86058.73 |

开始迁移:

gh-ost \
--user="user" \
--password="password" \
--host="my-endpoint.rds.amazonaws.com" \
--database="my_app_db" \
--table="my_table" \
--alter="MODIFY field_1 TINYINT(2) DEFAULT 1 NOT NULL" \
--assume-rbr \
--allow-on-master \
--verbose \
--execute

当迁移完成近 93% 时,RDS 可用内存降至 20GB。所以我停止了 gh-ost。

停止 gh-ost 后的数据库信息:

mysql> select table_schema, sum((data_length+index_length)/1024/1024) AS MB from information_schema.tables group by 1;
+--------------------+-----------------+
| table_schema       | MB              |
+--------------------+-----------------+
| information_schema |      0.00976560 |
| mysql              |      5.96277428 |
| performance_schema |      0.00000000 |
| my_app_db          | 446299.17968756 |
+--------------------+-----------------+

停止gh-ost后原表的大小:

mysql> SELECT table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024), 2) `Size (MB)` FROM information_schema.TABLES WHERE table_schema = "my_app_db";
+----------------------------------------+-----------+
| Table                                  | Size (MB) |
+----------------------------------------+-----------+
| _my_table_ghc                       |      0.41 |
| _my_table_gho                       | 273157.00 |
| my_table                            |  85011.62 |

问题:

为什么gh-ost表比原表大很多倍?

如果需要有关表、索引或数据库的更多信息,我可以提供:)

这是在 gh-ost 存储库中创建的问题的链接:https://github.com/github/gh-ost/issues/890

【问题讨论】:

  • 你检查过两个表中的tabke定义和记录数吗?
  • 如果你使用OPTIMIZE TABLE table_name会发生什么?
  • @O.Jones 优化锁定表。我有一张包含 2.3 亿条记录的表。所以优化需要很多时间,我做不到。
  • @Shadow 是的。表定义是相同的。 ghost/copy 表中的记录数较少,因为在我取消复制过程之前只复制了 93% 的记录。原表记录数:229699180 副本表记录数:175215000 我也查了字数github.com/github/gh-ost/issues/890#issuecomment-720231952

标签: mysql amazon-web-services amazon-rds schema-migration


【解决方案1】:

我从生产数据库的备份创建了 mysql 数据库。

生产有innodb_file_format参数为Barracuda

新环境的innodb_file_format参数为Antelope

生产表的ROW_FORMATCOMPRESSED

很遗憾,Antelope db 不支持 ROW_FORMAT 作为 COMPRESSED

如果我更多地研究 information_schema 的细节,我可以更轻松地解决它!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多