web-dev-qa-db-fra.com

Définition de innodb_log_file_size correct dans mysql

Aujourd'hui, nous avons dirigé une autre table qui a supprimé la DB. Nous avons échoué à l'esclave, et dans l'autopsie, nous avons découvert cela dans le mysql error.log

InnoDB: ERROR: the age of the last checkpoint is 90608129,
InnoDB: which exceeds the log group capacity 90593280.
InnoDB: If you are using big BLOB or TEXT rows, you must set the
InnoDB: combined size of log files at least 10 times bigger than the
InnoDB: largest such row.

Cette erreur sonne vraie, car nous travaillions sur une très grande table contenant des types de données BLOB.

Le meilleure réponse nous avons trouvé en ligne dit

Pour le résoudre, vous devez arrêter MySQL proprement (très important), supprimer les fichiers journaux InnoDB existants (probablement lb_logfile * dans votre répertoire de données MySQL, sauf si vous les avez déplacés), puis ajuster la taille innodb_log_file_size en fonction de vos besoins, puis redémarrez MySQL. Cet article du blog sur les performances de MySQL peut être instructif.

et dans les commentaires

Oui, le serveur de base de données suspendra efficacement toute mise à jour des tables InnoDB lorsque le journal se remplira. Cela peut paralyser un site.

ce qui est, je suppose, ce qui s'est passé, sur la base de notre courant (par défaut) innodb_log_file_size de 48 Mo?

SHOW GLOBAL VARIABLES LIKE '%innodb_log%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 8388608  |
| innodb_log_compressed_pages | ON       |
| innodb_log_file_size        | 50331648 |
| innodb_log_files_in_group   | 2        |
| innodb_log_group_home_dir   | ./       |
+-----------------------------+----------+

Donc, cela m'amène à deux questions pointues et une ouverte:

  1. Comment déterminer la plus grande ligne afin de pouvoir définir notre innodb_log_file_size être plus grand que ça?
  2. Quelle est la conséquence de l'action de l'étape 1? J'avais lu de longs temps de récupération avec des journaux plus gros.
  3. Y a-t-il autre chose dont je devrais m'inquiéter concernant les migrations, étant donné que nous avons une grande table (650 000 lignes, 6169,8 Go) avec des champs BLOB de longueur variable et sans restriction.

Nous exécutons mysql 5.6 et voici notre my.cnf.

[mysqld]

#defaults
basedir                   = /opt/mysql/server-5.6
datadir                   = /var/lib/mysql
port                      = 3306
socket                    = /var/run/mysqld/mysqld.sock
tmpdir                    = /tmp
bind-address              = 0.0.0.0

#logs
log_error                 = /var/log/mysql/error.log
expire_logs_days          = 4
slow_query_log            = on
long_query_time           = 1


innodb_buffer_pool_size   = 11G

#http://stackoverflow.com/a/10866836/182484
collation-server          = utf8_bin
init-connect              ='SET NAMES utf8'
init_connect              ='SET collation_connection = utf8_bin'
character-set-server      = utf8
max_allowed_packet        = 64M
skip-character-set-client-handshake

#cache
query_cache_size          = 268435456
query_cache_type          = 1
query_cache_limit         = 1048576
```

Pour donner suite aux suggestions énumérées ci-dessous, j'ai commencé à enquêter sur la taille du fichier du tableau en question. J'ai exécuté un script qui a écrit la taille d'octet combinée des trois champs BLOB dans une table appelée pen_sizes. Voici le résultat de l'obtention de la plus grande taille d'octet:

select pen_size as bytes,·
  pen_size  /  1024 / 1024 as mb,·
  pen_id from pen_sizes
  group by pen_id
  order by bytes desc
  limit 40

+---------+------------+--------+
| bytes   | mb         | pen_id |
+---------+------------+--------+
| 3542620 | 3.37850571 |  84816 |
| 3379107 | 3.22256756 |  74796 |
| 3019237 | 2.87936878 | 569726 |
| 3019237 | 2.87936878 | 576506 |
| 3019237 | 2.87936878 | 576507 |
| 2703177 | 2.57795048 | 346965 |
| 2703177 | 2.57795048 | 346964 |
| 2703177 | 2.57795048 |  93706 |
| 2064807 | 1.96915340 | 154627 |
| 2048592 | 1.95368958 | 237514 |
| 2000695 | 1.90801144 |  46798 |
| 1843034 | 1.75765419 | 231988 |
| 1843024 | 1.75764465 | 230423 |
| 1820514 | 1.73617744 |  76745 |
| 1795494 | 1.71231651 | 650208 |
| 1785353 | 1.70264530 |  74912 |
| 1754059 | 1.67280102 | 444932 |
| 1752609 | 1.67141819 |  76607 |
| 1711492 | 1.63220596 | 224574 |
| 1632405 | 1.55678272 |  76188 |
| 1500157 | 1.43066120 |  77256 |
| 1494572 | 1.42533493 | 137184 |
| 1478692 | 1.41019058 | 238547 |
| 1456973 | 1.38947773 | 181379 |
| 1433240 | 1.36684418 |  77631 |
| 1421452 | 1.35560226 | 102930 |
| 1383872 | 1.31976318 |  77627 |
| 1359317 | 1.29634571 | 454109 |
| 1355701 | 1.29289722 | 631811 |
| 1343621 | 1.28137684 |  75256 |
| 1343621 | 1.28137684 |  75257 |
| 1334071 | 1.27226925 |  77626 |
| 1327063 | 1.26558590 | 129731 |
| 1320627 | 1.25944805 | 636914 |
| 1231918 | 1.17484856 | 117269 |
| 1223975 | 1.16727352 |  75103 |
| 1220233 | 1.16370487 | 326462 |
| 1220233 | 1.16370487 | 326463 |
| 1203432 | 1.14768219 | 183967 |
| 1200373 | 1.14476490 | 420360 |
+---------+------------+--------+

Cela me fait croire que la taille moyenne des lignes est plus proche de 1 Mo que les 10 suggérées. Peut-être que la taille de la table que j'ai répertoriée précédemment inclut également les index?

L'Iran

SELECT table_name AS "Tables", 
round(((data_length + index_length) / 1024 / 1024), 2) "Size in MB" 
FROM information_schema.TABLES 
WHERE table_schema = 'codepen'

+-------------------+------------+
| Tables            | Size in MB |
+-------------------+------------+
...snip
| pens              |    6287.89 |
...snip
12
timsabat

0. Informations préliminaires

Vos paramètres:

innodb_log_file_size = 50331648
innodb_log_files_in_group = 2

Par conséquent, votre " capacité du groupe de journaux " = 2 x 50331648 = 96 Mo

1. Comment déterminer la plus grande ligne

Il n'y a pas de méthode directe. Mais on peut facilement calculer la taille d'une ligne donnée sur la base de ces tableaux (la compression ne devrait pas nous intéresser ici si, comme je suppose, les lignes ne sont pas compressées dans les fichiers journaux).

2. Impact de innodb_log_file_size

Manuel de référence :

Plus la valeur est élevée, moins l'activité de vidage du point de contrôle est nécessaire dans le pool de tampons, ce qui permet d'économiser les E/S de disque. Les fichiers journaux plus volumineux ralentissent également la récupération après incident, bien que les améliorations des performances de récupération dans MySQL 5.5 et supérieures rendent la taille du fichier journal moins importante.

3. Autre chose à craindre

6169,8 Go/650 000 lignes = environ 10 Mo par ligne en moyenne C'est un problème grave en soi si vous avez l'intention d'utiliser votre base de données dans une situation transactionnelle multi-utilisateurs. Pensez à stocker vos BLOB sous forme de fichiers en dehors de la base de données. Ou, au moins, stockez-les dans une table MyISAM (non transactionnelle) distincte.

9
RandomSeed