J'essaie de restaurer les décharges de la base de données du Ghtorrent (fichiers CSV contenant GitHub Metadata). La table commits
a plus de 891 millions de lignes et le project_commits
a plus de 5,4 milliards de lignes. Puisque ces tables sont assez grandes, je devais les charger à l'aide de LOAD DATA INFILE
avec une vérification de la clé étrangère. J'utilise le moteur MyISAM
. Après avoir terminé les enregistrements d'importation dans les tables, j'essaie de créer des index pour ces tables.
J'exécute la commande mysql suivante pour la table commits
et il n'a pas fini de plus de 12 heures.
CREATE UNIQUE INDEX `sha` ON `ghtorrent_restore`.`commits` (`sha` ASC) COMMENT '';
La table commettre ressemble ci-dessous:
J'ai lu d'autres questions Stackexchange sur l'indexation lente et définir ce qui suit dans my.cnf
Fichier dans /etc/mysql
répertoire.
[mysqld]
bulk_insert_buffer_size=1G
myisam_sort_buffer_size=8G
key_buffer_size=6G
sort_buffer_size=10M
Étant donné que la commande précédente ne finissait pas à temps, je devais l'arrêter avec Ctrl + Z de la console. J'ai vérifié la table sur MySQL Workbench, il ne figure pas comme corrompu, mais cela montre une longueur d'index de 36 Go.
L'importation de ce tableau a pris environ 25 minutes, alors je m'attends à ce que l'indexation ne devrait pas prendre plus d'une heure, mais je suis maintenant à la commande "Créer un indice unique" pendant environ 2 heures sans aucun signe de progrès.
Quand j'exécute la commande, MySQLD prend beaucoup de processeur et cela continue de prendre la mémoire. Après avoir atteint quelque 6 Go, il devient moins actif et semble presque rien faire.
Voici comment la commande (sélectionnée sur la photo suivante) est à partir du Workbench MySQL.
Je cours mysql 5.7.22-0ubuntu0.16.04.1 sur une machine Linux Mint 17.03 avec 16 Go de RAM.
Comme je ne suis pas un utilisateur avancé, aucune aide sera d'une grande aide.
Mise à jour [comme Wilson H. suggéré]:
My.cnf Fichier [06/05/2018 01:06]
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
secure-file-priv = ""
[mysqld]
bulk_insert_buffer_size=1G
myisam_sort_buffer_size=8G
key_buffer_size=6G
sort_buffer_size=10M
Voici des instantanés de tampon et cache lié variables.
Je n'ai rien modifié d'autre dans mon installation MySQL. MySQLD prend une quantité de mémoire différente en fonction de différentes tables hors de la RAM totale de 16 Go disponible dans le système. Je n'exécute aucune application intensive de CPU/mémoire à côté de MySQL.
Observation intéressante: certains tests avec d'autres tables montrant une durée croissante en ce qui concerne le nombre croissant de lignes. La tendance a l'air polynomial.
Les statistiques suivantes ont été capturées alors que la dernière commande MySQL de la photo ci-dessus était en cours d'exécution (c'est-à-dire l'indexation de "projets" de table).
Ulimit -A:
DF -H:
Mettre à jour 2 : Etant donné que la création d'index sur la table "commettre" ne finissait pas, j'essayais d'autres tables et j'ai finalement tenté d'indexer sur la table "Project_Commits" avant de darder la nuit dernière. À ma grande surprise, j'ai trouvé que 18 minutes seulement pour terminer l'indexation.
Je n'ai pas fait de modification supplémentaire et je ne comprends pas pourquoi "commettre" la table n'est jamais terminée. Je connais à nouveau l'indexation sur la table des "commettre" et voyez jusqu'où il se passe.
Mise à jour 3 :
'Montrer Create Table commits;'
CREATE TABLE `commits` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sha` varchar(40) DEFAULT NULL,
`author_id` int(11) DEFAULT NULL,
`committer_id` int(11) DEFAULT NULL,
`project_id` int(11) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `commits_ibfk_1` (`author_id`),
KEY `commits_ibfk_2` (`committer_id`),
KEY `commits_ibfk_3` (`project_id`)
) ENGINE=MyISAM AUTO_INCREMENT=922093754 DEFAULT CHARSET=utf8
Afficher la liste des processus :
Bottomline:
L'indexation pour toutes les tables est complétée à l'exception de la table 'commit' (c'est-à-dire la commande suivante n'est pas terminée en cours d'exécution).
CREATE UNIQUE INDEX `sha` ON `ghtorrent_restore`.`commits` (`sha` ASC) COMMENT '';
Lorsque j'exécute une requête (voir la photo ci-dessous) qui compte environ 19 000 rangées de 891 millions de lignes, il faut environ 76 secondes. Est-ce que cette heure est trop élevée, je dispose d'un ordinateur avec Core i707700HQ CPU @,8 GHz x 4, 16 Go DDR4 RAM et la base de données sont installés sur le disque dur avec 7200RPM? Les 76 secondes indiquent-elles que l'indexation ne fonctionne pas correctement dans la table "commet" ? Veuillez noter que cette requête a été exécutée juste après avoir démarré l'ordinateur pour éviter les impacts des tampons.
Il y a plusieurs problèmes.
Auto_inc de 922m est à mi-chemin de la limite de 2 milliards de INT SIGNED
. Suggérez que vous modifiez INT UNSIGNED
(4 milliards limites) au cours de la prochaine ALTER
.
Myisam enregistre l'espace disque, mais est aussi "pire" que InnoDB. Remarque: Changer à InnoDB nécessitera de modifier plusieurs paramètres.
FOREIGN KEYS
Sont ignorés par Myisam.
Si sha
est un hachage SHA-1, il est terrible pour l'indexation.
Si sha
est un hachage SHA-1, il pourrait être comprimé à BINARY(20)
via UNHEX()
. Cela diminuerait la table de plus de 20 Go, 30% de la taille actuelle!
Si sha
est un hachage SHA-1, n'utilisez pas UTF8; Utilisez ASCII ou LATIN1.
Si sha
est un hachage SHA-1, et c'est la colonne que vous créez l'index UNIQUE
ON, cochez SHOW PROCESSLIST
. S'il est indiqué "Réparer par key_buffer", vous devriez le tuer; Il faudra mois pour terminer. Si cela indique "Réparer par trier", alors il y a de l'espoir qu'il finira.
Envisagez d'utiliser des identifiants plus petits que le 4 octet Int pour l'auteur, le committer et le projet - à moins que vous n'ayez vraiment pas beaucoup de valeurs distinctes. Attendre! Quelle? Chacun de ceux-ci va être UNIQUE
? J'en doute.
Quel SELECTs
avez-vous? Certains d'entre eux auraient pu nécessiter des indices "composites"?
Mettre plusieurs ALTERs
(y compris la création d'index) dans une seule déclaration. Chaque ALTER
est une copie complète de la table (dans Myisam).
myisam_sort_buffer_size = 8G
Est la moitié de la RAM. C'est mauvais. Suggérez 3G.
polynôme
La tendance a l'air polynomial.
J'espère que vous n'ajoutez pas de UNIQUE INDEX
Sur une colonne sur une table déjà a la même colonne que PRIMARY KEY
. Ce serait totalement redondant. S'il vous plaît fournir SHOW CREATE TABLE
Pour l'un d'entre eux.
Pourquoi "polynôme"? Si c'est (et je pose des questions telles), alors ce serait à cause de la nature de "réparation par clé_buffer":
Pour chaque ligne, recherchez la colonne de tous les index uniques (y compris primaires) pour vous assurer qu'il n'est pas un "duplicata". Cette recherche nécessite de récupérer le bloc de l'index du BTRee et de la mettre dans le "Key_Buffer" pour tester. En fonction de la "commande" de la clé, par rapport à "l'ordre" des données:
891 millions de rangées sont un peu mal. C'est un problème avec MyISAM et les index uniques.
Peut-être que vous pourriez migrer vers PostgreSQL , qui n'a pas ce problème? Ghtorrent semble prendre en charge PostgreSQL