Git receive / upload-pack在推送时

时间:2017-05-31 13:12:12

标签: ruby git redmine

我有一个带有Git的Redmine服务器。它有2GB的RAM。

当有人试图推送数据大于2GB的存储库时,我收到以下错误:

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

在第一个fatal: ...之前,ruby开始占用服务器上的所有RAM。

当达到约2GB的RAM使用时,会发生fatal: ...错误。服务器出错:

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

所以我的猜测是Git或Redmine试图将这些2.18 GB放入RAM,这显然不起作用。

错误之后:

  • 服务器上的存储库仍为空;
  • 在我重新启动Redmine之前,RAM使用率仍为95 +%。

我怎样才能让它发挥作用?是Redmine还是Git吃了所有的RAM?

可以推送数据"逐个部分" (like here)是一个解决方案吗?

我已尝试increase the HTTP post buffer sizegit config http.postBuffer 524288000)但未成功。

编辑(2017-06-01):

一些规格:

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

Redmine部署在带有乘客模块的Apache服务器(v2.2.22)后面。它使用Grack(最后修订版)将其Git与Redmine SCM插件集成以创建存储库。

重新查看日志之后,看起来罪魁祸首就是格拉克。

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'

换句话说,当Grack启动git upload-pack命令时会发生错误。

编辑(2017-06-01)(2):

本地存储库确实有一包2 + GB。我用以下内容重新包装:

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

将大包装减少为多个较小的包装。我还配置了以下客户端和服务器端:

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

但问题仍然存在。

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'

编辑(2017-06-01)(3):

在Grack上添加了一些日志记录,以查看它的确切启动内容:

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

由于它没有从Git存储库目录启动命令,我尝试了以下内容:

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

可悲的是仍然没有工作。

编辑(2017-06-01)(4):

再次尝试,但使用64m代替512m,仍然没有效果。

看起来Git仍需要将所有对象放在RAM上以启动打包。客户端,git repack命令确实需要2 + GB才能执行,即使结果输出是多个512 MB文件。

1 个答案:

答案 0 :(得分:0)

由于这个问题正在深入研究,这里是我用作答案的解决方法。

看起来receive / upload-pack需要加载RAM上的所有内容。也许我错了,但我发现没有什么可以将RAM使用量减少到小包。所以我所做的就是创建一个瞬态交换文件。

# 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

2GB还不够:推送量大约为3.5GB,因此4GB交换文件。

推动需要很长时间(没有sh * Sherlock),但至少它成功了。

我留下了新的交换文件以备将来出现类似的问题,但如果您想在推送后删除它,可以执行以下操作:

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

# delete the file
sudo rm /swap

Reference on UNIX guide