我该如何还原似乎由于PostgreSQL数据库迁移而损坏的Gerrit代码审查用户?

时间:2018-12-06 02:59:04

标签: gerrit

我的用户帐户已损坏,我不知道该如何解决。

环境: Gerrit代码审查2.14.1 Ubuntu 14.04 正在使用SAML SSO插件。

我如何到达这里 我关闭了我的gerrit实例,并执行了整个gerrit数据库的PostgreSQL 9.3 db dump。我在新的Ubuntu服务器上将该数据迁移到了PostgreSQL 9.5。我使用postgres的已发布方法来完成此任务。它没有错误。 我重新配置了//etc/gerrit.config文件,使其指向此新的postgesql服务器。 我成功地重新启动了gerrit。在这一点上,我可以看到我自己的评论,其他人的评论和推送的补丁集等。但是,令我沮丧的是,所有其他用户都不为人所知。我在gerrit仪表板中看到的所有非我补丁都归因于“匿名Co夫(accountId)”,其中accountId是在首次使用服务时分配给该用户的实际gerrit帐号。 当服务启动并指向该新数据库时,附近的一位用户听到了我的喘息声,并尝试使用gerrit服务。他遇到了第一次用户提示。这绝对是出乎意料的,因为我本人并不面对这一点。

我开始放松自己的变化。基本上,将gerrit.config文件的db条目快速编辑为先前的IP,然后重新启动。

现在,我可以在仪表板中看到所有用户属性都是正确的。现在,该用户再次尝试打Gerrit,但现在他得到了403。这是意外的。

值得注意的是: 我们公司将SAML用于SSO。我为Gerrit使用TheSamet SAML插件。 用户的所有元数据都通过标头来自工厂的LDAP。当新用户遇到首次用户对话框时,所有字段都是预先填写的且不可变。

一些故障排除: 仔细阅读gerrit error_log会发现以下内容:(清除了实际的用户名)

[2018-12-05 18:57:43,130] [ReceiveCommits-1] INFO  com.google.gerrit.server.config.PluginConfigFactory : No /gerrit/etc/gitiles.config; assuming defaults
[2018-12-05 18:57:52,293] [HTTP-65] WARN  com.google.gerrit.server.query.account.InternalAccountQuery : Ambiguous external ID gerrit:jdoefor accounts: 1000001, 1000004
[2018-12-05 18:57:52,311] [HTTP-65] ERROR com.google.gerrit.httpd.auth.container.HttpLoginServlet : Unable to authenticate user "jdoe"
com.google.gerrit.server.account.AccountException: Cannot assign external ID "gerrit:jdoe" to account 1000109; external ID already in use.
    at com.google.gerrit.server.account.AccountManager.create(AccountManager.java:237)
    at com.google.gerrit.server.account.AccountManager.authenticate(AccountManager.java:118)
    at com.google.gerrit.httpd.auth.container.HttpLoginServlet.doGet(HttpLoginServlet.java:119)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:286)
    at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:276)
    at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:181)
    at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85)
    at com.google.gerrit.httpd.raw.StaticModule$PolyGerritFilter.doFilter(StaticModule.java:451)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gerrit.httpd.GetUserFilter.doFilter(GetUserFilter.java:75)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gerrit.httpd.RequireSslFilter.doFilter(RequireSslFilter.java:73)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gerrit.httpd.UniversalWebLoginFilter.doFilter(UniversalWebLoginFilter.java:74)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gerrit.httpd.RunAsFilter.doFilter(RunAsFilter.java:111)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gwtexpui.server.CacheControlFilter.doFilter(CacheControlFilter.java:70)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gerrit.httpd.RequestMetricsFilter.doFilter(RequestMetricsFilter.java:57)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gerrit.httpd.AllRequestFilter$FilterProxy$1.doFilter(AllRequestFilter.java:133)
    at com.google.gerrit.httpd.AllRequestFilter$FilterProxy.doFilter(AllRequestFilter.java:135)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.gerrit.httpd.RequestContextFilter.doFilter(RequestContextFilter.java:72)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:120)
    at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:135)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.thesamet.gerrit.plugins.saml.SamlWebFilter.doFilter(SamlWebFilter.java:157)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:224)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:534)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:748)

我试图通过使用Gerrit中记录的gsql进一步解决此问题。

java -jar gerrit.war gsql -d /path/to/my/gerrit/instance
select * from accounts where account_id='1000001';  //this returns the user.
select * from accounts where account_id='1000004';  //this returns nil.

我在帐户db中看不到该冒犯用户1000004。现在我更加困惑了。

问题:

  1. 任何人都可以告知该用户的account_id来自何处吗?
  2. 有人可以帮我解决这个问题,以便我解决吗。

1 个答案:

答案 0 :(得分:0)

这是Gerrit的已知问题。 gerrit_bug
**请注意,我的经验是稍有不同的表现,我的解决方法与缺陷的作者也略有不同。

我的解决方法如下:
1.删​​除整个/ path / to / gerrit目录,并将其完全替换为刚执行升级之前拍摄的快照。如果您事先没有拍摄快照(gerrit已停止),则必须跳过此步骤。
2.对帐户和更改执行离线手动重新索引(请参阅下面的代码部分)。后者可能需要一些时间,具体取决于您的回购规模。

java -jar /path/to/gerrit.war reindex --index accounts -d /path/to/gerrit
java -jar /path/to/gerrit.war reindex --index changes -d /path/to/gerrit

示例:
假设Gerrit安装位于/gerrit,gerrit.war文件位于/ gerrit / bin

java -jar /gerrit/bin/gerrit.war reindex --index accounts -d /gerrit