首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自动重新创建表以释放InnoDB空间的过程。

自动重新创建表以释放InnoDB空间的过程。
EN

Database Administration用户
提问于 2019-10-30 20:01:54
回答 1查看 1.1K关注 0票数 0

我为一个运行的网站提供了几个MySQL表,它不断地变得越来越大。例如,作业表当前为18 it,其中共有6行。我有一个日志表,在删除和重新创建它之前,它通常超过200 it。我已经尝试了命令OPTIMIZE TABLE jobs,没有任何大小的改变。

对于jobs表,事情不断地被添加到它中,然后当它们被处理时,它们被删除,但是这个空间永远不会被回收或重用。这是正常的吗?

以下是表的定义:

代码语言:javascript
运行
复制
CREATE TABLE `jobs` 
             ( 
                          `id`    bigint(20) NOT NULL auto_increment, 
                          `queue` varchar(255) characterSET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
                          `payload` longtext characterSET utf8mb4 COLLATE utf8mb4_0900_ai_ci, 
                          `attempts`     tinyint(3) unsigned DEFAULT NULL, 
                          `reserved_at`  int(10) unsigned DEFAULT NULL, 
                          `available_at` int(10) unsigned DEFAULT NULL, 
                          `created_at`   int(10) unsigned DEFAULT NULL, 
                          PRIMARY KEY (`id`) using btree, 
                          UNIQUE KEY `UNIQUE` (`queue`,`reserved_at`) using btree 
             ) 
             engine=innodb auto_increment=415621 DEFAULT charset=utf8mb4 COLLATE=utf8mb4_0900_ai_ci row_format=dynamic

前几天,我正在使用SQLite中的一个表,当我通过添加一个列来改变结构时,它所做的方式是使用以下步骤:

代码语言:javascript
运行
复制
PRAGMA foreign_keys = 0;
CREATE TABLE sqlitestudio_temp_table AS 
SELECT * 
FROM   netid;DROP TABLE netid;CREATE TABLE netid 
             ( 
                          automodifiedtimestamp VARCHAR (20), 
                          type                  VARCHAR (1), 
                          netid                 VARCHAR (4), 
                          usage                 VARCHAR (1), 
                          _unused1              VARCHAR (3), 
                          extracol              VARCHAR (50) 
             );INSERT INTO netid 
            ( 
                        automodifiedtimestamp, 
                        type, 
                        netid, 
                        usage, 
                        _unused1 
            ) 
SELECT automodifiedtimestamp, 
       type, 
       netid, 
       usage, 
       _unused1 
FROM   sqlitestudio_temp_table;
DROP TABLE sqlitestudio_temp_table;
PRAGMA foreign_keys = 1;

这让我想到,MySQL也可以做到这一点,这将释放出对许多人来说似乎是一个持续存在的空白空间。

与其在开始时删除表,不如像第一步中所做的那样创建一个新表,禁用外键,从第一个表中应用索引,删除第一个表,然后重命名如下:

代码语言:javascript
运行
复制
mysql> delimiter //
mysql> CREATE PROCEDURE RecreateTable(IN TableName)
    -> BEGIN
    ->   // SHOW CREATE TABLE TableName; -> use results to recreate indexes, keys and such into variable ==> ALTER_TABLE_STRING
    ->   CREATE TABLE temp_table AS SELECT * FROM TableName;
    ->   foreign_keys = 0;
    ->   ALTER TABLE temp_table + ALTER_TABLE_STRING
    ->   DROP TABLE TableName;
    ->   ALTER TABLE temp_table RENAME TableName;
    ->   foreign_keys = 1;
    -> END//

这是否可能和合理?我有一个生产数据库,每5分钟接受数百个办公室的JSON帖子。如果我要让系统完全备份/恢复(这需要10-15分钟),可能会导致其中一些办公室离线,甚至几个小时甚至几天都不会回来。如果有这样的解决方案,可以作为一个常规的工作,这将是更好的。

我在一个表上尝试了第一步,该表当前为447 on,有300,000行。它花了15秒才把尺寸降到485 It。从那里更改表可能需要几毫秒时间,这将使这成为一个生产准备过程,无需完全备份就可以管理InnoDB大小。

有小费吗?这个问题已经有一个我不知道的解决办法了吗?更好的主意?

EN

回答 1

Database Administration用户

回答已采纳

发布于 2019-11-02 01:06:10

至于圣坛..。ALTER TABLE ... ALGORITHM=COPY;将执行alter操作,并确保同时复制表,从而有效地在过程中执行OPTIMIZE

TRUNCATE丢失了数据;您真的想这么做吗?

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/252249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档