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:
innodb_log_file_size
être plus grand que ça?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
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
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.