logo header
logo header
logo header
logo header
  • 2017.04.21
  • 技術ブログ

GitBucketのDBをPostgreSQLに移行した話

はじめに

GitBucketについて調べているときに組み込みDBのH2のデータが壊れた事例をいくつか目にしました。
弊社では1年以上利用する間にデータが壊れたことはないのですが、何がトリガーなのか分からないので外部DBに移行してみました。
外部DBはMySQLとPostgreSQLがサポートされていて、PostgreSQLを選びました。
MySQLは後述する理由からトラブルの可能性があり、あまりお勧めできません。

DB移行手順

External database configuration · gitbucket/gitbucket Wikiの説明に従って、以下の手順で進めていきます。

  1. PostgreSQLをセットアップする
  2. 既存データをエクスポートする
  3. database.confのDB接続先を変更する
  4. GitBucketを再起動する
  5. エクスポートしたデータをインポートする

PostgreSQLをセットアップする

GitBucketはdockerで運用しているので、PostgreSQLもdockerを利用します。
特にカスタマイズせずに以下のdocker-compose.ymlで大丈夫でした。

既存データをエクスポートする


admin権限があるユーザでこの画面からエクスポートしたデータをダウンロードできます。
ファイルは gitbucket-export-7065622906696034784.sql のような名前になります。

database.confのDB接続先を変更する

GitBucketのDB接続先を先程セットアップしたPostgreSQLに変更します。
database.confは${GITBUCKET_HOME}~/.gitbucketにあります。

変更前

変更後

GitBucketを再起動する

PostgreSQLにテーブルを作成するため、GitBucketを再起動します。

エクスポートしたデータをインポートする

データのインポートは管理画面から可能ですが、PostgreSQLの場合はシーケンスの更新もあるのでコマンドラインから行います。

データのインポート

シーケンスの更新SQL

以上で移行完了です。
特に画面表示に速度差は感じませんが、H2のデータベースファイルが600MBくらいだったのにPostgreSQLでは80MBくらいに減ったのが驚きでした。

MySQLでNGパターン

当初、MySQLに移行しようとしたのですが、以下のように格納できないデータがあり断念しました。
どちらもレアケースですが、片方は回避手段がないのが困り所です。

大文字小文字のみ違うユーザ、リポジトリを作成できない

GitBucketのACCOUNTテーブルやREPOSITORYテーブルなど、いくつかのテーブルはVARCHAR型のカラムがPKです。
そしてMySQLは5.7までutf8かつci(case-insensitive)なcollationしかないので、大文字小文字のみ違うユーザやリポジトリを作る事ができません。
このパターンに引っかかるデータがあると以下のようなエラーになります。

この場合、MySQL 8.0.1で導入されたcollation utf8mb4_ja_0900_as_csならcs(case-sensitive)なので回避することができます。

長すぎるダッシュボードメッセージを保存できない

GitBucketのダッシュボードのメッセージはTEXT型のカラムに格納されています。
TEXT型の上限サイズは65535文字なのでほとんどの場合は問題になりませんが、大量のコミットを一度にpushするとメッセージサイズがこの上限を越えてしまい、pushできません。
このパターンに引っかかるデータがあると以下のようなエラーになります。

問題となるのはダッシュボードのメッセージなので該当レコードを削除すればよいのですが、DB移行後に大量のコミットメッセージを含むpushができなくなります。そのため根本的に解決するには、カラムの型をサイズ上限が大きなMEDIUMTEXTやLONGTEXTに変えたりメッセージをサイズ上限に納まるように切り詰める処理が必要になります。

おまけ

GitBucketのPages pluginを改造した話で投げたPull Requestは無事に取り込まれて、Pages pluginを導入すると利用できます!

参考リンク

ともに世界をアップグレードできる、そんな日を夢見て。
Upgrade the World!