弊社ではかなり前からGitLab(CE)を自社環境で運用しているのですが、ふと気付くと、バージョンがだいぶ先に行ってしまっていました。
とくに最近のバージョンでは Auto DevOps なども使えるようになっていたりするので、さすがにそろそろキャッチアップしたいと考えたわけです。
現行の環境は次の通りです:
で、ある程度予想はしてたんですが、ただ単純にGitLabコンテナをバージョンアップしただけでは起動しなかったのです。
問題は結局次の7点ありました。
経緯を追うと長くなりそうですが、おそらくこれだけ見ると意味がわからないので、それぞれできるだけ短く記載していきます。
GitLab 9.3 で、MySQLでのサブグループ機能が廃止されました。
https://docs.gitlab.com/ce/user/group/subgroups/index.html#database-requirements
もともと対応環境として「PostgreSQL推奨/MySQLも可」とはなっていましたが、状況によってはMySQLでのDBマイグレーションが通らないようなので、あきらめてPostgreSQLへの移行を決意しました。
さてではどのようにPostgreSQLへ移行するか、ということですが、GitLab公式ドキュメントで pgloader を推奨しているようです。
https://docs.gitlab.com/ee/update/mysql_to_postgresql.html
2018-10月現在の最新版は 3.5.2 のようですが、これが Control stack exhausted
とエラーが表示されて動作しませんでした。
同様のIssueがあり、3.5.1を使用することとします。
https://github.com/dimitri/pgloader/issues/810
さて、公式リファレンスに書かれた手順で pgloader をテスト実行してみましたが、どうやら WITH
オプションのどれかが通らないようです。
リファレンスでは pgloader 3.4.1+
と書かれているので、3.4.1 では動くのかもしれません。
試行錯誤の結果、 WITH
オプションは WITH preserve index names
だけがあればとりあえず問題が無いようです。
(この点は保証がありません)
移行後のDBとしてPostgreSQLを用意し、GitLabと仮接続して確認してみたところ、
いくつかの操作でGitLab内のエラーが発生しました。
念のため確認してみたところ、PostgreSQL 10は対応環境外とされているようですね。
https://gitlab.com/gitlab-org/gitlab-ce/issues/42047
ということで、 PostgreSQLは9.6を使用することとしました。
GitLab 9.1.2のデータをMySQLからPostgreSQLに入れ替え、GitLab 11.4.0でDBマイグレーションを実行してみたところ、失敗し中断しました。
エラーメッセージを追ってみたところ、9.x から 10.0 の間のDBマイグレーションに問題があるようです。
https://gitlab.com/gitlab-org/gitlab-ce/issues/38283
PostgreSQLにデータを移行しなおしてから、events
テーブルのINDEXを見ると、確かにプライマリキーのINDEX名が idx_xxxxx_primary
のようになっているので、PostgreSQL上で
ALTER INDEX '(eventテーブルのプライマリキーのINDEX名)' RENAME TO 'events_pkey';
と実行すると、DBマイグレーションが通るようになりました。
sameersbn/gitlab
のドキュメントにあるように、GitLabコンテナを稼働させる前に、rake:migrate
を実行してDBマイグレーションを実行したところ、GitLabコンテナが起動中しなくなりました。
条件・原因がいまいちパっとわからない状況ではあったのですが、 sameersbn/gitlab
の起動時の挙動を追うと、起動時に自動的にDBマイグレーションも走るようだったので、事前に実行せず、起動時処理に任せることにしました。
GitLabコンテナを起動したところ、「管理者パスワードの変更画面」が表示されました。
これはGitLabをクリーンインストールした場合の状態のはずですので、PostgreSQLのデータを確認してみると、やはりデータが初期化されています。
ソースを追ってみたところ、GitLab起動時に毎回、「(PostgreSQLの場合)public
スキーマ内のテーブルの数をカウントし0である場合はクリーンインストール」する挙動となっていることがわかりました。
ということはつまり、 pgloader でのデータ移行時に、テーブルが public
スキーマ以外に作成されているということになります。
改めてPostgreSQLを初期状態に戻し、 pgloader でデータ移行しなおしてからPostgreSQL内を見てみると、データベース名と同じスキーマ名になっています。
ということでどうやら、pgloaderのデフォルト挙動では、データベース名と同名のスキーマを新規追加するようです。
この状況を防ぐためには、 pgloader のオプションとして ALTER schema '(データベース名)' rename to 'public'
が必須となります。
https://github.com/dimitri/pgloader/issues/645
ということで、手順ベースでまとめると:
events
テーブルのINDEX名を手動で変更ずいぶんシンプルになってしまいますね…。
なお、実際にアップグレードを実行する際には、いくつか注意が必要です。
既存GitLabのディレクトリ(gitレポジトリなどが配置されている)はまるごと全てバックアップしておく必要があります。
(マイグレーションの一環として、このディレクトリの構造が変化してしまうため)
こういうとき、GCPなどスナップショットが保存できる環境だと楽ですね。
当然ながら、既存DBのバックアップは、絶対にx3必須です。
実際にPostgreSQLにデータを入れる際は、安全のため次のような手順で実施しています。
弊社ではGitLabのようなツール・ミドルウェアなどの導入設置・運用なども承っております。
今回のように、なかなか手間のかかるものなど、お気軽にお問い合わせください。