zoukankan      html  css  js  c++  java
  • How to reclaim space in InnoDB when innodb_file_per_table is ON

    When innodb_file_per_table is OFF and all data is going to be stored in ibdata files. If you drop some tables of delete some data then there is no any other way to reclaim that unused disk space except dump/reload method.

    When Innodb_file_per_table is ON, each table stores data and indexes in it’s own tablespace file. However, the shared tablespace-ibdata1 can still grow and you can check more information here about why it grows and what are the solutions.

    http://www.mysqlperformanceblog.com/2013/08/20/why-is-the-ibdata1-file-continuously-growing-in-mysql/

    Following the recent blog post from Miguel Angel Nieto titled “Why is the ibdata1 file continuously growing in MySQL?“, and since this is a very common question for Percona Support, this post covers how to reclaim the space when we are using innodb_file_per_table. Also, I will show you how to do it without causing performance or availability problems with the help of our Percona Toolkit.

    When you remove rows, they are just marked as deleted on disk but space will be consumed by InnoDB files which can be re-used later when you insert/update more rows but it will never shrink. Very old MySQL bug : http://bugs.mysql.com/bug.php?id=1341

    But, if you are using innodb_file_per_table then you can reclaim the space by running OPTIMIZE TABLE on that table.OPTIMIZE TABLE will create a new identical empty table. Then it will copy row by row data from old table to the new one. In this process a new .ibd tablespace will be created and the space will be reclaimed.

     1 mysql> select count(*) From test;
     2 +----------+
     3 | count(*) |
     4 +----------+
     5 | 3145728 |
     6 +----------+
     7 root@nil:/var/lib/mysql/mydb# ll -h
     8 ...
     9 -rw-rw---- 1 mysql mysql 168M Sep 5 11:52 test.ibd
    10 mysql> delete from test limit 2000000;
    11 mysql> select count(*) From test;
    12 +----------+
    13 | count(*) |
    14 +----------+
    15 | 1145728 |
    16 +----------+
    17 root@nil:/var/lib/mysql/mydb# ll -h
    18 ...
    19 -rw-rw---- 1 mysql mysql 168M Sep 5 11:52 test.ibd

    You can see that after deleting 2M records, the test.ibd size was 168M.

     1 mysql> optimize table test;
     2 +-----------+----------+----------+-------------------------------------------------------------------+
     3 | Table | Op | Msg_type | Msg_text |
     4 +-----------+----------+----------+-------------------------------------------------------------------+
     5 | mydb.test | optimize | note | Table does not support optimize, doing recreate + analyze instead |
     6 | mydb.test | optimize | status | OK |
     7 +-----------+----------+----------+-------------------------------------------------------------------+
     8 root@nil:/var/lib/mysql/mydb# ll -h
     9 ...
    10 -rw-rw---- 1 mysql mysql 68M Sep 5 12:47 test.ibd

    After OPTIMIZE, you will be able to reclaim the space. As you can see, test.ibd file size is decreased from 168M to 68M.

    I would like to mention here that during that process the table will be locked.(Table locked for just Writes) Which can affect to the performance when you’ll have large table. So If you don’t want to lock the table then you can use one of the best utility by Percona, pt-online-schema-change. It can ALTER without locking tables. You can run ALTER TABLE with ENGINE=INNODB which will re-create the table and reclaim the space.

    (It’s always recommended to use latest version of pt-* utilities)

     1 mysql> select count(*) from test;
     2 +----------+
     3 | count(*) |
     4 +----------+
     5 | 2991456 |
     6 +----------+
     7 mysql> delete from test limit 2000000;
     8 mysql> select count(*) from test;
     9 +----------+
    10 | count(*) |
    11 +----------+
    12 | 991456 |
    13 +----------+
    14 root@nil:/var/lib/mysql/mydb# ll -h
    15 ...
    16 -rw-rw---- 1 mysql mysql 157M Sep 6 11:52 test.ibd
    17 nilnandan@nil:~$ pt-online-schema-change --alter "ENGINE=InnoDB" D=mydb,t=test --execute
    18 Operation, tries, wait:
    19 copy_rows, 10, 0.25
    20 create_triggers, 10, 1
    21 drop_triggers, 10, 1
    22 swap_tables, 10, 1
    23 update_foreign_keys, 10, 1
    24 Altering `mydb`.`test`...
    25 Creating new table...
    26 Created new table mydb._test_new OK.
    27 Altering new table...
    28 Altered `mydb`.`_test_new` OK.
    29 2013-09-06T15:37:46 Creating triggers...
    30 2013-09-06T15:37:47 Created triggers OK.
    31 2013-09-06T15:37:47 Copying approximately 991800 rows...
    32 Copying `mydb`.`test`: 96% 00:01 remain
    33 2013-09-06T15:38:17 Copied rows OK.
    34 2013-09-06T15:38:17 Swapping tables...
    35 2013-09-06T15:38:18 Swapped original and new tables OK.
    36 2013-09-06T15:38:18 Dropping old table...
    37 2013-09-06T15:38:18 Dropped old table `mydb`.`_test_old` OK.
    38 2013-09-06T15:38:18 Dropping triggers...
    39 2013-09-06T15:38:18 Dropped triggers OK.
    40 Successfully altered `mydb`.`test`.
    41 root@nil:/var/lib/mysql/mydb# ll -h
    42 ...
    43 -rw-rw---- 1 mysql mysql 56M Sep 6 15:38 test.ibd

    Same here, you can notice that test.ibd file size decreased from 157M to 56M.

    NOTE: Please make sure that you have ample space before you run pt-online-schema-change because it will create a temporary table that contains roughly the size of the original table. By running this on the primary node, the changes will be replicated to your slaves.

    quoted from:

    http://www.mysqlperformanceblog.com/2013/09/25/how-to-reclaim-space-in-innodb-when-innodb_file_per_table-is-on/

  • 相关阅读:
    c#驱动操作mongodb辅助类MongoDBHelper
    c#多线程lock无效
    利用Aspose.Words将html转成pdf和将html转成word
    前后端值映射的问题
    本机部署流程详解
    Git 安装配置手册
    js对象数组(JSON) 根据某个共同字段 分组
    jquery中的$.fn的用法
    JSON.parse()与JSON.stringify()的区别
    添加编辑 时 数据不可重复验证
  • 原文地址:https://www.cnblogs.com/xiaotengyi/p/3572663.html
Copyright © 2011-2022 走看看