天天看點

Ubuntu 14.04 Gerrit 資料庫遷移: H2 遷移為 Mysql(包括 changes/group/account/permissions):

Gerrit 資料庫遷移 H2 遷移為 mysql(包括 changes):

曆史環境:

目前系統安裝 Gerrit 為 2.11,且資料庫使用 H2;

但随着開發規模擴大,H2 資料庫逐漸無法滿足上百個開發的送出;

是以決定将 Gerrit 的 H2 資料庫更換為 Mysql;

需要用到一個工具 h2tomysql_for_gerrit ,網上說這個工具隻是在 gerrit 2.9.1 上測試通過;

我本地是用的 2.11 版本也可以通過

下載下傳位址:

https://github.com/uppet/h2tomysql_for_gerrit

需要注意的是:下載下傳後要編譯裡面的java檔案(可以用 eclipse build)

從理論上分析需要的步驟:

分兩種情況:

1. 在同一台伺服器上遷移:

    a. 先 stop 原先的 gerrit 服務;

    b. 安裝新的 gerrit 站點服務(安裝時設定 mysql 資料庫),

        需要與原先的不同站點目錄,例如原先為  gerrit_site ,新服務為 gerrit_site2;

        不要啟動該 gerrit 服務,如果啟動了,就停止;

    c. 拷貝原 gerrit 站點中的所有 git 庫到新的 gerrit 指向的git庫目錄(如果新舊 gerrit 的代碼庫目錄一緻,則跳過),

        注意:不包括 All-Projects 和 All-Users ;

    d. 通過 h2tomysql_for_gerrit 這個工具,将原始 gerrit 的 H2 資料導入到新站點的 Mysql 資料庫中;

    e. 由于資料庫已經被更新,是以需要更新新 gerrit 中 All-Project 的 groups 檔案中的 Administrator UUID;

        并且,需要更新 data-gerrit/All-Projects.git/refs/meta/config 中的 hash 值為更新上述group檔案之後的commit點;

    f. 進入新 gerrit 站點目錄 gerrit_site2,需要重建索引(這步尤其重要,否則 changes 不會被顯示出來):

        java -jar bin/gerrit.war reindex

        這個操作比較耗時,主要取決于目前包含的git代碼庫和changes;

    g. 啟動新 gerrit 服務;

    h. 清除舊的 gerrit 站點;

2. 在不同伺服器上遷移:

    原理與同一台伺服器上一樣,隻是需要注意兩點:

    a. 将舊 gerrit 的服務站點目錄,例如 gerrit_site 拷貝到新的伺服器;

    b. 将舊 gerrit 伺服器中所有的 git 代碼庫拷貝到新 gerrit 伺服器中指定目錄(All-Projects 和 All-Users)

    其他的步驟都跟在同一個伺服器操作完全一緻

具體實施步驟:

以本地為例,新舊 gerrit 處于不同伺服器中(本人親測成功):

伺服器 A 為 Gerrit 2.11,H2

伺服器 B 為 Gerrit 2.11,Mysql

上述新舊 gerrit 伺服器請優先安裝

(注意,一定要保證兩個伺服器的 gerrit 版本一緻,因為不同 gerrit 版本的資料庫結構可能是不一樣的)

所有 Gerrit 的安裝配置步驟略過,安裝過程沒有特殊情況,可以參考網上其他文章。

開始執行:

1. 在伺服器 B 上安裝相同版本的 gerrit+mysql 

2. 在 A 上将 gerrit_site 目錄(目錄下所有檔案),scp 到 B 上;

3. 拷貝 A 上的所有 git 庫到 B 上 gerrit 指定的 git 代碼庫目錄(注意不要拷貝原始 gerirt 的 All-Projects 和 All-Users);

4. 在 B 上 stop gerrit 服務;

5. 下載下傳 h2tomysql_for_gerrit 工具到任意目錄,并通過 eclipse 編譯其中的 java 檔案,然後會生成 bin 目錄:

bin/

└── com

    └── ucweb

        └── gerrit

            └── tools

                └── converter

                    ├── GerritDatabaseConverter.class

                    ├── H2DatabaseSession.class

                    ├── H2ToMySQLLauncher.class

                    ├── IDatabaseSession.class

                    ├── MySQLDatabaseSession.class

                    └── Util.class

6. 指令行進入 h2tomysql_for_gerrit 目錄,執行指令:

    java -cp "bin:lib/*" com.ucweb.gerrit.tools.converter.H2ToMySQLLauncher [path/to/old/gerrit.config] [path/to/new/gerrit.config]

    此指令将會将舊 gerrit H2 中的資料導入到新 gerrit mysql 中(需要注意最後兩個參數的順序);

    錯誤提示:

    a. Database may be already in use: "Locked by another process". Possible solutions: close all other connection(s); use the server mode [90020-174]

       在執行上述指令時必須要将所有 gerrit 服務關閉;

    b. Access denied for user 'gerrit'@'127.0.0.1' (using password: YES)

        由于 mysql 資料庫是需要指定賬号密碼的,而在 gerrit.config 中預設是沒有密碼的明文顯示,是以需要在 gerrit.config 中指定mysql的賬号密碼:

        [database]

            type = mysql

            hostname = localhost

            database = gerrit

            username = gerrit

            password = <password>

    出現如下提示,表示執行成功:

      Feeding data into patch_set_approvals

      Feeding data into patch_sets

      Feeding data into schema_version

      Feeding data into starred_changes

      Feeding data into submodule_subscriptions

      Feeding data into system_config

     Fixing increment into change_message_id

     Fixing increment into account_id

     Fixing increment into change_id

     Special fix for account_group_id

     Special fix for account_id

     Special fix for uuid of admin

      Done tranfer database data from H2 to MySQL.

      REMEMBER to update `groups' file in meta/config tag of `All-Project' to make Administrator UUID correct.

      請尤其注意最後一行提示 "REMEMBER to update `groups' file in meta/config tag of `All-Project' to make Administrator UUID correct."

      由于更新之後資料庫中所有資料都是舊 gerrit 伺服器中的資料,是以對于新 gerrit 中的 All-Project 這個 git 庫中的内容是需要手動更新的;

      具體更新方法稍後再提。

7. 需要重建索引表(這一步非常重要):

    進入 B 伺服器的 Gerrit 站點目錄(gerrit_site),執行指令:

    java -jar gerrit-site/bin/gerrit.war reindex          #注意不要完全複制,用自己實際情況的目錄

    此步驟一般不會有太大的問題,主要就是耗時,視目前 git 庫的多少和 changes 數目定。

    提示:可以使用 --threads 50 參數指定程序數。 

8. 更新 B 伺服器的 All-Projects(針對步驟6中的最後說明):

    此庫主要儲存的是 All-Projects 設定的權限配置,以及各個 group 的UUID

    更新(隻有1個檔案):

    groups -------各個groups的UUID ,這個檔案暫時先不更新

    project.config 項目的權限配置,這個檔案如果沒有改動,也可跳過

    具體操作:

    分别 clone 新舊 Gerrit 伺服器上對應的 All-Projects 庫,然後将舊的同步到新的上;

    修改完成,然後 commit push (在新的gerrit中)

    記錄下最後一次 commit 的 hash 值,可以通過 git log 檢視

    将這個 hash 值更新到新 gerrit git 代碼庫中的:

    All-Projects.git/refs/meta/config (注意此處不是剛才clone的庫)檔案中,删除原有内容,直接替換為新的 hash。

9. 啟動 B 伺服器(新)Gerrit 服務;

    注意,别忘記拷貝使用者密碼檔案,如果你用的是 http 認證,則 gerrit_site/etc/passwords .

10. 就可以登入新的 Gerrit 服務了,一切資料都完好;

最後,擴充一下:

如果既要遷移資料庫,又要更新 gerrit 版本,那麼隻能分為兩步走:

1. 先在同一個 gerrit 版本中遷移資料庫(H2 --> Mysql);

2. 然後再安裝新的 gerrit 版本;

本地試驗從 Gerrit 2.11 + H2 ---> Gerrit 2.14.5 + Mysql 是可以成功的。

寫得比較啰嗦,希望可以幫到大家,歡迎指正!