0

I have 3 AWS MariaDB instances - one for production, one for user testing and one development - and I set up a script to clone the production data across to the testing and dev DBs using mysqldump and a migration script to change the schema as required.

I start off the operation using DROP DATABASE and CREATE DATABASE, set the character set and collation, and load up the dump. These are all InnoDB tables and there's no database replication involved.

Now I've done it a few times, I'm running out of space on my dev and test DBs and the AWS CloudWatch metrics show missing space.

I am in an awkward situation because the corporation that I'm doing this for does not allow me AWS or host access, so everything I do is via the client command prompt. The corporation's DBAs are unfortunately quite ignorant of MariaDb and MySQL, being mostly SQL Server trained, and are new to AWS as well.

I can relay requests to them via chat and they then come back with the answers.

This is how it looks now (still waiting for dev db info):

DB    Provisioned    Used        Free        Unknown!
dev   100GB          -           -           -
test  100GB          42.1GB      15.9GB      42.0GB
prod  100GB          60.3GB      29.3GB      10.4GB

general_log and slow_query are set off already. log_output is set to TABLE - I'm unclear if this affects the error log log_error is /rdsdbdata/log/error/mysql-error.log innodb_file_per_table is ON

I can't tell from the AWS docs at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/mon-scripts.html what their scripts use to generate the stats:

... collects and sends the DiskSpaceUsed metric for the selected disks. The metric is reported by default in gigabytes.

Due to reserved disk space in Linux operating systems, disk space used and disk space available might not accurately add up to the amount of total disk space.

So AWS warns that they might not add up, but I would expect any 'unreported space' in linux to remain constant and it seems pretty obvious that it's my cloning activities that are causing MariaDB to lose its free disk space.

I have found this very informative: I have delete database from mysql but storage is not freed but neither I nor my DBAs have permissions to run PURGE BINARY LOGS which looks like the first thing we should try.

I dropped my database and the DBA helping me just did a MariaDB restart (or perhaps an AWS host restart, not sure) and I have all the free space back again.

So how do I solve this or work around it?

It would also be good for me to be able to check the space in use directly from the SQL prompt.

I can do this:

SELECT table_schema AS "Database",
       ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size(MB)"
FROM information_schema.TABLES GROUP BY table_schema;
+--------------------+----------+
| Database           | Size(MB) |
+--------------------+----------+
| information_schema |     0.17 |
| mysql              |     5.76 |
| performance_schema |     0.00 |
| my_db              | 32643.52 |
+--------------------+----------+
4 rows in set (0.02 sec)

but it doesn't show all the extra used space I'm losing.

This screenshot provided by CloudWatch shows free disk storage. There are 4 times where it shoots up. The first 3 are DROP DATABASE events, the last is where the DBA decided to restart the host. The declines back down to zero are where the load from a dump are running.

Here is the exact script of what I'm doing:

mysql -h $db -u $DB_USERNAME -p$pw  -D my_db \
                   --max-allowed-packet=536M \
                   --default-character-set=utf8mb4 < ./drop-recreate-db.sql

/usr/bin/mysqldump -h $DBPROD \
                   -u $DB_USERNAME \
                   -p$PWPROD \
                   --default-character-set utf8mb4 \
                   --single-transaction \
                   -ev my_db \
| mysql -h $db -u $DB_USERNAME -p$pw -D my_db \
                   --max-allowed-packet=536M \
                   --default-character-set=utf8mb4

mysql -h $db -u $DB_USERNAME -p$pw  -D my_db \
                   --max-allowed-packet=536M \
                   --default-character-set=utf8mb4 < ./group-migration.sql

and the two SQL scripts are:

drop-recreate-db.sql

DROP DATABASE IF EXISTS my_db;

CREATE DATABASE my_db;

ALTER DATABASE my_db
   DEFAULT CHARACTER SET = 'utf8mb4'
   DEFAULT COLLATE = 'utf8mb4_unicode_ci';

group-migration.sql

CREATE TABLE ad_group (
id INT UNSIGNED NOT NULL AUTO_INCREMENT, --
name CHAR(100) NOT NULL UNIQUE,
created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_updated DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
    ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT pk_ad_group PRIMARY KEY (id)
) ENGINE=InnoDB
  DEFAULT CHARSET=utf8mb4
  COLLATE=utf8mb4_unicode_ci
  MAX_ROWS 1000;

ALTER TABLE widget DROP COLUMN globalRead;
ALTER TABLE widget DROP COLUMN globalWrite;
ALTER TABLE widget DROP FOREIGN KEY fk_widget_unit;
ALTER TABLE widget DROP COLUMN unitId;
ALTER TABLE widget ADD COLUMN read_group_id INT UNSIGNED NOT NULL DEFAULT 1;
ALTER TABLE widget ADD COLUMN write_group_id INT UNSIGNED NOT NULL DEFAULT 2;
ALTER TABLE widget ADD COLUMN owner_group_id INT UNSIGNED NOT NULL DEFAULT 3;
ALTER TABLE widget ADD CONSTRAINT fk_widget_read_group
    FOREIGN KEY (read_group_id)
    REFERENCES ad_group(id);
ALTER TABLE widget ADD CONSTRAINT fk_widget_write_group
    FOREIGN KEY (write_group_id)
    REFERENCES ad_group(id);
ALTER TABLE widget ADD CONSTRAINT fk_widget_owner_group
    FOREIGN KEY (owner_group_id)
    REFERENCES ad_group(id);

-- rename old modification table
ALTER TABLE modification RENAME old_mod;

-- create new one
CREATE TABLE modification (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  username CHAR(30) NOT NULL,
  display_name VARCHAR(255) NULL,
  epoch_time BIGINT NOT NULL,
  widget_id INT UNSIGNED NOT NULL,
  widget_symbol VARCHAR(255) NOT NULL,
  group_id INT UNSIGNED NOT NULL,
  group_name CHAR(100) NOT NULL,
  description CHAR(12) NOT NULL,
  aux_text TEXT NULL,
  aux_date DATE NULL,
  CONSTRAINT pk_modification PRIMARY KEY (id)
) ENGINE=InnoDB
  DEFAULT CHARSET=utf8mb4
  COLLATE=utf8mb4_unicode_ci
  MAX_ROWS 500123123;


-- add username to modification via userid
INSERT INTO modification (username, epoch_time, widget_id, widget_symbol,
                          group_id, group_name,
                          description, aux_text, aux_date)
SELECT u.name, m.epochTime, m.widgetId, f.name, 1, 'Not recorded',
       m.description, m.auxText, m.auxDate
FROM old_mod m
     LEFT JOIN `user` u ON u.id = m.userId
     LEFT JOIN widget f ON f.id = m.widgetId;

-- drop table so we can re-use the same constraint names
DROP TABLE IF EXISTS old_mod;

-- create constraints and indices
CREATE INDEX ix_modification_widget_symbol
ON modification (widget_symbol);

CREATE INDEX ix_modification_query_by_user_and_widget
ON modification (username, widget_id, description, aux_date, epoch_time);

CREATE INDEX ix_modification_last_save_query
ON modification (widget_id, description, aux_date);



ALTER TABLE data CHANGE COLUMN widgetId widget_id INT UNSIGNED NOT NULL;
ALTER TABLE data CHANGE COLUMN modifiedDate modified_date DATE NOT NULL;
ALTER TABLE data CHANGE COLUMN valueDate value_date DATE NOT NULL;

DROP TABLE IF EXISTS usergroup;
DROP TABLE IF EXISTS groupwidget;
DROP TABLE IF EXISTS userwidget;
DROP TABLE IF EXISTS `user`;
DROP TABLE IF EXISTS `group`;
DROP TABLE IF EXISTS unitconversion;
DROP TABLE IF EXISTS unit;

enter image description here

Originally I made the changes to table modification in place, but I kept getting other errors - see here if interested: MariaDB "ERROR 1034 (HY000) at line 41: Index for table 'xyz' is corrupt" on importing dump

This is: Server version: 10.2.12-MariaDB-log MariaDB Server

  • Is the "Unknown" amount decreasing over time? – Rick James May 2 at 5:48
  • Did you delete something big recently? – Rick James May 2 at 5:49
  • @RickJames Only DROP DATABASE as stated. – Adam May 2 at 9:52
  • It takes them 3 hours to respond, if the DBAs respond :( But I suspect you mean "does is decrease as the db is used?" which I don't know the answer to. I guess I could put a load test on it and observe. The problem is that the database load gets interrupted so I haven't been able to use it normally. – Adam May 2 at 9:54
  • On some operating systems DROP DATABASE, if there is a lot of data, will take a long time. (But I would expect minutes, not hours.) – Rick James May 2 at 12:52
0

Dump & load --

  1. Dump -- copies data to another part of disk, thereby consuming disk space.
  2. Load -- copies data from the dump to the database (making a new db), still more disk space
  3. Free up the disk space from step 1.
  4. DROP DATABASE may free up more space -- depends on innodb_file_per_table.

However, to take "hours" to do step 3 makes me think that the OS (or the complex disk system that AWS has) is slow to release the space.

Bottom line: Live with it.

  • My (1) pipes direct to (2) without writing to disk, from a third host too. I omitted to say that my 3 DBs are actual instances on different hosts. The production host is set up with all sorts of hot backup options. And my step (1) is actually DROP DATABASE. I'm thinking from the info in that link in my question and from the way the free space declines that the problem really must be 'run-away InnoDB table space' but I shall have to re-read it slowly. – Adam May 2 at 15:53
  • @Adam - Perhaps you should add the exact commands, so we won't guess wrong. – Rick James May 2 at 22:16
  • Added scripts fwiw – Adam May 3 at 10:46
  • @Adam - I guess INSERT INTO modification .. SELECT .. is the big part? It starts with one copy of modification, and makes a second. I don't think a temp table is needed by that SELECT. Each CREATE INDEX leads to some amount of disk space -- what version of MySQL is it? (Adding indexes has changed radically in recent versions.) – Rick James May 3 at 13:21
  • Exactly but no, it's not needed, but the reason I'm doing it like that is: MariaDB Error 1034 hy000 table is corrupt – Adam May 3 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.