Pourquoi mes «octets de volume utilisés» augmentent-ils toujours sur mon cluster Amazon Aurora?

11

J'ai un cluster Amazon (AWS) Aurora DB, et chaque jour, il [Billed] Volume Bytes Usedaugmente.

VolumeBytesUtilisation de la mesure CloudWatch dans le temps

J'ai vérifié la taille de toutes mes tables (dans toutes mes bases de données sur ce cluster) en utilisant la INFORMATION_SCHEMA.TABLEStable:

SELECT ROUND(SUM(data_length)/1024/1024/1024) AS data_in_gb, ROUND(SUM(index_length)/1024/1024/1024) AS index_in_gb, ROUND(SUM(data_free)/1024/1024/1024) AS free_in_gb FROM INFORMATION_SCHEMA.TABLES;
+------------+-------------+------------+
| data_in_gb | index_in_gb | free_in_gb |
+------------+-------------+------------+
| 30         | 4           | 19         |
+------------+-------------+------------+

Total: 53 Go

Alors pourquoi un I facturé près de 75 Go en ce moment?

Je comprends que l'espace provisionné ne peut jamais être libéré, de la même manière que les fichiers ibdata sur un serveur MySQL standard ne peuvent jamais rétrécir; Je suis d'accord avec ça. Ceci est documenté et acceptable.

Mon problème est que chaque jour, l'espace que je facture est augmenté. Et je suis sûr que je n'utilise PAS 75 Go d'espace temporairement. Si je devais faire quelque chose comme ça, je comprendrais. C'est comme si l'espace de stockage que je libérais, en supprimant des lignes de mes tables, ou en supprimant des tables, ou même en supprimant des bases de données, n'était jamais réutilisé.

J'ai contacté le support AWS (premium) plusieurs fois et je n'ai jamais pu obtenir une bonne explication sur la raison.
J'ai reçu des suggestions pour exécuter OPTIMIZE TABLEsur les tables sur lesquelles il y en a beaucoup free_space(par INFORMATION_SCHEMA.TABLEStable), ou pour vérifier la longueur de l'historique InnoDB, pour vous assurer que les données supprimées ne sont pas encore conservées dans le segment d'annulation (réf: MVCC ) et redémarrez les instances pour vous assurer que le segment d'annulation est vidé.
Aucun de ceux-là n'a aidé.

Guillaume Boudreau
la source

Réponses:

18

Il y a plusieurs choses en jeu ici ...

  1. Chaque table est stockée dans son propre espace de table

    Par défaut, le groupe de paramètres pour les clusters Aurora (nommé default.aurora5.6) définit innodb_file_per_table = ON. Cela signifie que chaque table est stockée dans un fichier distinct, sur le cluster de stockage Aurora. Vous pouvez voir quel espace disque logique est utilisé pour chacune de vos tables à l'aide de cette requête:

    SELECT name, space FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;

    Remarque: je n'ai pas essayé de passer innodb_file_per_tableà OFF. Peut-être que cela aiderait ..?

  2. L'espace de stockage libéré par la suppression des espaces de table n'est PAS réutilisé

    Citant le support premium AWS:

    En raison de la conception unique du moteur de stockage Aurora pour augmenter ses performances et sa tolérance aux pannes, Aurora n'a pas de fonctionnalité pour défragmenter les espaces de table fichier par table de la même manière que MySQL standard.

    Actuellement, Aurora n'a malheureusement pas de moyen de réduire les espaces de table comme le fait MySQL standard et tout l'espace fragmenté est facturé car il est inclus dans VolumeBytesUsed.
    La raison pour laquelle Aurora ne peut pas récupérer l'espace d'une table supprimée de la même manière que MySQL standard est que les données de la table sont stockées d'une manière complètement différente d'une base de données MySQL standard avec un seul volume de stockage.

    Si vous supprimez une table ou une ligne dans Aurora, l'espace n'est pas récupéré sur le volume du cluster Auroras en raison de cette conception compliquée.
    Cette incapacité à récupérer de petites quantités d'espace de stockage est un sacrifice fait pour obtenir les gains de performances supplémentaires du volume de stockage du cluster Auroras et la tolérance aux pannes considérablement améliorée d'Aurora.

    Mais il existe un moyen obscur de réutiliser une partie de cet espace gaspillé ...
    Encore une fois, citez le support premium AWS:

    Une fois que votre ensemble de données total dépasse une certaine taille (environ 160 Go), vous pouvez commencer à récupérer de l'espace dans des blocs de 160 Go pour la réutilisation, par exemple si vous avez 400 Go dans votre volume de cluster Aurora et DROP 160 Go ou plus de tables qu'Aurora peut alors réutilisez automatiquement 160 Go de données. Cependant, il peut être lent de récupérer cet espace.
    La raison de la grande quantité de données devant être libérées en même temps est due à la conception unique d'Auroras en tant que moteur de base de données à l'échelle de l'entreprise contrairement au standard MySQL qui ne peut pas être utilisé à cette échelle.

  3. OPTIMISER LA TABLE, c'est mal!

    Parce qu'Aurora est basé sur MySQL 5.6, OPTIMIZE TABLEest mappé à ALTER TABLE ... FORCE, ce qui reconstruit la table pour mettre à jour les statistiques d'index et libérer de l'espace inutilisé dans l'index cluster. En fait, innodb_file_per_table = ONcela signifie que l'exécution d'un OPTIMIZE TABLEcrée un nouveau fichier d'espace disque logique et supprime l'ancien. Étant donné que la suppression d'un fichier d'espace disque logique ne libère pas le stockage qu'il utilisait, cela signifie OPTIMIZE TABLEtoujours que davantage de stockage sera provisionné. Aie!

    Réf: https://dev.mysql.com/doc/refman/5.6/en/optimize-table.html#optimize-table-innodb-details

  4. Utilisation de tables temporaires

    Par défaut, le groupe de paramètres pour les instances Aurora (nommé default.aurora5.6) définit default_tmp_storage_engine = InnoDB. Cela signifie que chaque fois que je crée une TEMPORARYtable, elle est stockée, avec toutes mes tables habituelles , sur le cluster de stockage Aurora. Cela signifie qu'un nouvel espace est prévu pour contenir ces tables, augmentant ainsi le VolumeBytesUsed total.
    La solution est assez simple: changez la default_tmp_storage_enginevaleur du paramètre en MyISAM. Cela obligera Aurora à créer les TEMPORARYtables sur le stockage local de l'instance.
    À noter: le stockage local des instances est limité; consultez la Free Local Storagemétrique sur CloudWatch pour voir le volume de stockage de vos instances. Les instances plus grandes (plus coûteuses) ont plus de stockage local.

    Réf: aucun pour l'instant; la documentation actuelle d'Amazon Aurora ne le mentionne pas. J'ai demandé à l'équipe de support AWS de mettre à jour la documentation et mettra à jour ma réponse si / une fois qu'ils le font.

Guillaume Boudreau
la source
1
C'est une excellente réponse, et yowch , ce sont quelques mises en garde majeures. Content d'avoir vu ça.
ceejayoz
Idem. Remarqué qu'un serveur de base de données pouvait atteindre 300 Go, pour une base de données avec une taille déclarée par MySQL de 54 Go ... si l'espace n'est jamais récupéré, c'est un bon exemple de ce qui se passe lorsque vous avez beaucoup de tables fréquemment écrites ( ex: tables de log, tables d'index, etc.).
geerlingguy