Git receive / upload-pack prend toute la RAM en poussée

J'ai un server Redmine avec Git dessus. Il a 2 Go de RAM.

Lorsque quelqu'un tente de pousser un référentiel avec des données supérieures à 2 Go, j'obtiens l'erreur suivante:

Counting objects: 957, done. Delta compression using up to 12 threads. Compressing objects: 100% (577/577), done. Writing objects: 100% (957/957), 2.18 GiB | 29.66 MiB/s, done. Total 957 (delta 255), reused 862 (delta 229) fatal: The remote end hung up unexpectedly fatal: The remote end hung up unexpectedly Everything up-to-date 

Avant le premier fatal: ... , ruby ​​commence à prendre toute la RAM sur le server.

Lorsque vous atteignez ~ 2 Go d'utilisation de la RAM, les erreurs fatal: ... se produisent. Erreur sur le server:

 App 9339 stderr: Errno::ENOMEM: Cannot allocate memory - git 

Donc, je suppose que Git ou Redmine essaie de mettre ces 2,18 Go dans la RAM, ce qui ne fonctionnerait évidemment pas.

Après l'erreur:

  • le référentiel sur le server est toujours vide;
  • l'utilisation de la RAM est toujours à 95 +% jusqu'à ce que je redémarre Redmine.

Comment puis-je le faire fonctionner? Est-ce Redmine ou Git qui mange toute la RAM?

Pousser datatables "partie par partie" ( comme ici ) pourrait-il être une solution?

J'ai déjà essayé d' augmenter la taille du tampon post-HTTP ( git config http.postBuffer 524288000 ) sans succès.


EDIT (2017-06-01):

Quelques spécifications:

  • Ubuntu LTS 12.04.05
  • Redmine v2.6.9
  • Git v1.7.9.5

Redmine est déployé derrière un server Apache (v2.2.22) avec le module passager. Il utilise Grack (dernière révision) pour son intégration Git avec le plugin Redmine SCM pour créer des repositorys.

Après avoir regardé les bûches, on dirait que le coupable est Grack.

 App 9339 stderr: Errno::ENOMEM: Cannot allocate memory - git App 29461 stderr: /opt/grack/lib/git_adapter.rb:24:in ``' App 29461 stderr: /opt/grack/lib/git_adapter.rb:24:in `command' App 29461 stderr: /opt/grack/lib/git_adapter.rb:34:in `upload_pack' App 29461 stderr: /opt/grack/lib/grack.rb:84:in `get_info_refs' App 29461 stderr: /opt/grack/lib/grack.rb:55:in `call' App 29461 stderr: /opt/grack/lib/grack.rb:55:in `call' 

En d'autres termes, l'erreur se produit lorsque Grack lance une command git upload-pack .


EDIT (2017-06-01) (2):

Le référentiel local avait en effet un pack de 2 + GB. Je l'ai remballé avec ce qui suit:

 git repack -a -d --window-memory=512m --max-pack-size=512m 

Pour réduire ce gros package en plusieurs packages plus petits. J'ai également configuré le côté client et server suivant:

 git config pack.windowMemory 512m git config pack.packSizeLimit 512m 

Mais le problème se produit toujours.

 App 30005 stderr: [ 2017-06-01 09:15:04.4393 30122/0x000000019264a8(Worker 1) utils.rb:72 ]: *** Exception Errno::ENOMEM in Rack body object #each method (Cannot allocate memory - git) (process 30122, thread 0x000000019264a8(Worker 1)): App 30005 stderr: from /opt/grack/lib/git_adapter.rb:19:in `popen' App 30005 stderr: from /opt/grack/lib/git_adapter.rb:19:in `command' App 30005 stderr: from /opt/grack/lib/git_adapter.rb:43:in `receive_pack' App 30005 stderr: from /opt/grack/lib/grack.rb:70:in `block in service_rpc' 

EDIT (2017-06-01) (3):

Ajout d'une connection sur Grack pour voir ce qu'il lance exactement:

 git receive-pack --advertise-refs --stateless-rpc /var/git/mygit.git 

Comme il ne lance pas la command depuis le directory du repository Git, j'ai essayé ce qui suit:

 git config --global pack.windowMemory 512m git config --global pack.packSizeLimit 512m 

Malheureusement, ne fonctionne toujours pas.

EDIT (2017-06-01) (4):

Essayé à nouveau mais avec 64m au lieu de 512m , toujours pas d'effets.

Il semble que Git ait encore besoin de prendre tous les objects sur la RAM pour démarrer l'emballage. Côté client, la command git repack prend en effet 2 + Go pour s'exécuter, même si la sortie résultante est composée de plusieurs files de 512 Mo.

Solutions Collecting From Web of "Git receive / upload-pack prend toute la RAM en poussée"

Puisque cette question descend dans les profondeurs, voici la solution de contournement que j'ai utilisée comme réponse.

Il semble que receive / upload-pack doit charger tout sur la RAM. Peut-être que je me trompe, mais je n'ai rien trouvé pour réduire l'utilisation de la RAM en petits packages. Donc ce que j'ai fait est de créer un file d'échange transitoire.

 # create a file of 4GB sudo dd if=/dev/zero of=/swap bs=1024 count=4194303 # make it a swap file sudo mkswap /swap # enable the swap on this swap file sudo swapon /swap 

2Go ne suffisait pas: la poussée a pris comme ~ 3.5Go, donc le file d'échange de 4Go.

La poussée a pris du time (non sh * t Sherlock) mais au less ça a réussi.

J'ai laissé le nouveau file d'échange pour de futurs problèmes similaires, mais si vous voulez le supprimer après le push, vous pouvez faire ce qui suit:

 # disable the swap (will automatically move used memory into RAM or another swap) sudo swapoff /swap # delete the file sudo rm /swap 

Référence sur le guide UNIX