• gitlabの導入方法のメモ

    こんにちは。小宮です。先輩から要望されていそうな気がしたのでgitlab導入時のメモです。。

    やたらめったら長いし手順が複雑でこのとおりやって再現できるかはお使いの環境に依存する可能性があり保障できかねます。 この手順で再現した環境はOSはCentOS6.5でした。 postgresを許容できるのであれば自動的に入れられるオムニバス版があるのでそちらをお使いいただくのがよろしいかと。 個人的にpostgresの運用の知見が心もとなかったのと、RDSに逃げられなくなるのがアレだったのでmysqlで頑張りました。

    自分で自動化する時は、passengerとgitlab:setup時の対話処理をなんとか自動化するオプションを付けるとこがキモかと思いました。 この手順自体は部分的にchefがでてきますがほぼ手動です。自動化オプションは最後のほうにちょろっと書いときます。

    1.このへんからmysqlをなんとかして入れとく
    $ wget http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.6/MySQL-5.6.17-1.linux_glibc2.5.x86_64.rpm-bundle.tar -P site-cookbooks/mysqld/files/default/usr/local/src/
    
    2.rbenv等でrubyをなんとかして入れておく

    (chefでなにもせずにやるとchefgemに寄るので注意がひつよう) rubyのバージョンが低いとGemfileのシンタックスチェックでエラー出てmysql2とかが入らないことも。

    3.Gitのインストール
        # yum -y install libcurl-devel libxslt-devel libxml2-devel expat-devel gettext openssl-devel zlib-devel
    Installed:
      libcurl-devel.x86_64 0:7.19.7-37.el6_4        libxml2-devel.x86_64 0:2.7.6-14.el6
      libxslt-devel.x86_64 0:1.1.26-2.el6_3.1
    
    Dependency Installed:
      libgcrypt-devel.x86_64 0:1.4.5-11.el6_4      libgpg-error-devel.x86_64 0:1.7-4.el6
    
    
    # su - chef;cd infra-chef-repo/
    
    $ knife cookbook create git -o site-cookbooks
    $ knife cookbook create redis -o site-cookbooks
    $ vi site-cookbooks/git/recipes/default.rb
    #
    # Cookbook Name:: git
    # Recipe:: default
    #
    # Copyright 2014, YOUR_COMPANY_NAME
    #
    # All rights reserved - Do Not Redistribute
    #
    %W{libcurl-devel
     libxslt-devel
     libxml2-devel
     expat-devel
     gettext
     openssl-devel
     zlib-devel
     libgcrypt-devel
     libgpg-error-devel}.each do |pkg|
      package pkg do
        not_if "rpm -qa|grep #{pkg}"
        action :install
      end
    end
    bash "bash-install-git" do
      not_if "ls -d /usr/local/src/git-1.9.0"
      code <<-EOC
        wget https://git-core.googlecode.com/files/git-1.9.0.tar.gz -P /usr/local/src
        cd /usr/local/src/
        tar zxf git-1.9.0.tar.gz
        cd /usr/local/src/git-1.9.0
        ./configure --prefix=/usr/local/git
        make all
        make install
        ln -sf /usr/local/git/bin/git* /usr/local/bin/
      EOC
    end
    
    $ knife solo cook localhost -o git
    
        # wget https://git-core.googlecode.com/files/git-1.9.0.tar.gz -P /usr/local/src
    
        # cd /usr/local/src/
        # tar zxf git-1.9.0.tar.gz
        # cd /usr/local/src/git-1.9.0
        # ./configure --prefix=/usr/local/git
        # make all
        # make install
    
        # ln -s /usr/local/git/bin/git* /usr/local/bin/
    # which git
    /usr/local/bin/git
    # git --version
    git version 1.9.0
    
    4.redisのインストール
        # yum install -y --enablerepo=remi redis
        Installed:
          redis.x86_64 0:2.8.9-1.el6.remi
    
        Dependency Installed:
          gperftools-libs.x86_64 0:2.0-11.el6.3            libunwind.x86_64 0:1.1-2.el6
    
        # /etc/init.d/redis start
    
        # chkconfig redis on
    
    # redis-cli ping
    PONG
    
    $ vi site-cookbooks/redis/recipes/default.rb
    bash "yum-install-redis-from-remi" do
      not_if "which redis-cli"
      code <<-EOC
        yum install -y --enablerepo=remi redis
      EOC
    end
    
    service "redis" do
      supports :status => true, :restart => true
      action [ :enable, :start ]
    end
    $ knife cookbook test redis
    $ knife solo cook localhost -o redis
    
    5.ユーザ作成
    # useradd -c 'GitLab' git
    # chmod 755 /home/git
    
    # su - git -s /bin/bash
    
    $ mkdir .ssh
    $ touch .ssh/authorized_keys
    $ chmod 600 .ssh/authorized_keys
    $ chmod 700 .ssh
    $ git config --global user.name  "GitLab"
    $ git config --global user.email "gitlab@localhost"
    
    ##### 6.gitlab-shellのインストール
    $ git clone https://github.com/gitlabhq/gitlab-shell.git -b v1.9.4
    $ cp -a /home/git/gitlab-shell/config.yml{.example,}
    $ /home/git/gitlab-shell/bin/install
    
    install失敗する場合は、gitユーザの.bashrcか/etc/profile.d/の下あたりに環境変数を追加し読み込みしてから再実行
    export PATH=/path-to-ruby:$PATH
    
    8.gitlabインストール
    $ git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-8-stable gitlab
    
    $ cp -a /home/git/gitlab/config/gitlab.yml{.example,}
    
    不要っぽい
    --------------------------
    $ chmod -R u+rwX  /home/git/gitlab/log/
    $ chmod -R u+rwX  /home/git/gitlab/tmp/
    $ mkdir /home/git/gitlab/tmp/pids/
    $ mkdir /home/git/gitlab/tmp/sockets/
    $ chmod -R u+rwX  /home/git/gitlab/tmp/pids/
    $ chmod -R u+rwX  /home/git/gitlab/tmp/sockets/
    $ mkdir /home/git/gitlab/public/uploads
    $ chmod -R u+rwX  /home/git/gitlab/public/uploads
    --------------------------
    
    $ mkdir /home/git/gitlab-satellites
    $ ll -d /home/git/gitlab-satellites
    drwxrwxr-x 2 git git 4096  5月 19 12:20 2014 /home/git/gitlab-satellites
    $ 
    $ ll -d /home/git/gitlab-satellites
    drwxr-x--- 2 git git 4096  5月 19 12:20 2014 /home/git/gitlab-satellites
    
    $ cp -a /home/git/gitlab/config/unicorn.rb{.example,}
    
    $ cp -a /home/git/gitlab/config/initializers/rack_attack.rb{.example,}
    
    $ cd /home/git/gitlab
    $ git config --global user.name "GitLab"
    $ git config --global user.email "gitlab@localhost"
    $ git config --global core.autocrlf input
    
    9.DB設定
    $ cp -a /home/git/gitlab/config/database.yml{.mysql,}
    
    $ vi /home/git/gitlab/config/database.yml
    $ diff /home/git/gitlab/config/database.yml{.mysql,}
    10,12c10,12
    <   username: git
    <   password: "secure password"
    <   # host: localhost
    ---
    >   username: gitxxxxx
    >   password: "xxxxxxxx"
    >   host: localhost
    
    $ ls -al /home/git/gitlab/config/database.yml
    -rw-rw-r-- 1 git git 777  5月 19 12:32 2014 /home/git/gitlab/config/database.yml
    $ chmod o-rwx /home/git/gitlab/config/database.yml
    $ ls -al /home/git/gitlab/config/database.yml
    -rw-rw---- 1 git git 777  5月 19 12:32 2014 /home/git/gitlab/config/database.yml
    
    $ vi /home/git/gitlab/config/gitlab.yml
    $ diff /home/git/gitlab/config/gitlab.yml{,.example}
    227c227
    <     bin_path: /usr/local/bin/git
    ---
    >     bin_path: /usr/bin/git
    

    ローカル等てきとうなところ(database.ymlに指定したところ)にDBをなんとかしていれる

    ...
  • innodb_stats_on_metadata=1でディスク容量激増とCPU負荷が発生

    こんにちは。小宮です。 ある日chefのレシピをなおしていると、同僚がこんなことをいってきました。

    「おきゃくさまがphpmyadminのinformation_schemaのリンクをクリックしたとたんに
     サイトが重くなってディスク容量が数十GBも増えて今下がって落ち着いたって言ってます。
     なにか原因わかりますか?」
    

    phpmyadminでinformation_schemaをクリックするのが危険過ぎる - K52.NIKKI ver3.0というのが添えられていました。

    よくわからなかったので現象を呟いたところ、親切なMySQLのACE(えーす)のyoku0825さんがinnodb_stats_on_metadata=1があやしいんじゃないかと教えてくれました。 ググってみたところ、innodb_stats_on_metadata に要注意 - TAKUMI SAKAMOTO’S BLOGというページを見かけて何が起きたかわかった気になったのでした。

    起きたことの予測:  ・テーブルの更新状況が統計情報更新の発生条件に達している状態だった  ・information_schemaのリンクをクリックすることでshow table status相当の統計情報更新のきっかけになるクエリが走った  ・統計情報更新のためにANALYZE_TABLE相当の処理が走った  ・ディスクがあふれたのはテーブルのコピーがtmpdirに作られたためで挿げ替えられて処理が完了したために使用率が下がった  ・cpu負荷はALTER相当のTABLEメンテナンス処理とそれに伴うディスクI/Oによるものと考えられる

    innodbの統計情報更新の発生条件については、漢のブログに書いてあるのをみつけました。いつもありがとうございます。 めでたしめでたし。とこれだけだと物足りないのでちょっと足します。

    どのバージョンでONかOFFかについて、公式のマニュアルをみると5.6.6からOFFでそれ以前はONのようです。

    つぎに仮にinnodb-stats-on-metadataを0にしたばあいメンテナンスを自分で行う必要が生じるけどどうしたらええんやという話について。

    基本メンテ入れて統計情報更新するだけならANALYZE TABLEするかデフラグもしたいならALTER TABLEしたほうがいいです。 InnoDBのOPTIMIZEは内部的にALTERが実行されるだけなのでREADのロックがかかるのが嫌ならALTER TABLE使うといいです。 データ(とスペック)を極力本番同様にした試験環境でかかる時間を見積もるのがオススメです。 表にマニュアルのリンクを貼っておきました。左は5.1日本語で右は5.6英語のリンクです。

    構文説明
    ANALYZE TABLEインデックス統計情報の更新に使います
    CHECK TABLE破損の可能性があるテーブルをチェックする際に使います
    REPAIR TABLE破損が確認できた場合に、復旧を試みます
    ALTER TABLEテーブルが再作成されることによりインデックス情報もデータも再作成され、デフラグメントが解消されます
    OPTIMYZE TABLEMyISAMの可変長フォーマット(テーブル定義に可変長のカラムを持つ)と、InnoDBのデータ部分にフラグメンテーションが起こったのを解消するために実行します。MyISAMの場合は、インデックス統計情報の更新、デフラグの解消、インデックスページの並べ替えが行われます。InnoDBの場合は、内部的にALTER TABLEが行われてテーブルが再作成されることにより、インデックス情報もデータも再作成され、デフラグメントが解消されます。

    ・参考サイト innodb_stats_on_metadata に要注意 - TAKUMI SAKAMOTO’S BLOG 漢(オトコ)のコンピュータ道: 大人のためのInnoDBテーブルとの正しい付き合い方。 漢(オトコ)のコンピュータ道: ALTER TABLEを上手に使いこなそう。 MySQLトラブル解析入門 テーブル メンテナンス ステートメント MySQL :: MySQL 5.5 Reference Manual :: 13.7.2 Table Maintenance Statements Percona Toolkit pt-online-schema-change でサービス無停止スキーマ変更 | 外道父の匠 pt-online-schema-changeを安全につかう - Around the World

    ...
  • 素のRubyでMySQLクエリの結果を取得する

    Ruby+MySQLの処理をする時、たいていはMySQL操作系のライブラリでruby-mysqlmysql2とかを使うケースが多いのだろうが、それらのライブラリなしの素のRuby環境でMySQLのクエリ操作を行う必要があったので、その際に書いたソースを汎用化してまとめてみた。まぁ…ほとんどニーズはないかもしれんが、一応TIPSとして共有化しておこうかと。

    mysql_query.rb

    db = { :db_config => "~/.user.cnf", :db_name => "database_name" }
    
    query = "SELECT * FROM db_table_name WHERE primary_key_id = 1;"
    res = `/usr/bin/mysql --defaults-extra-file=#{db.fetch(:db_config)} -D #{db.fetch(:db_name)} -e \"#{query}\" `
    
    if res.empty? then
        p "data is none."
    else
        lines = res.split("\n")
        columns = lines.first.split("\t")
        results = []
        lines.each_with_index { |line, i| 
            if i > 0 then
                tmp_hash = {}
                values = line.split("\t")
                values.each_index { |j| 
                    if values[j].match(/^\d+$/) then
                        tmp_hash[columns[j]] = values[j].to_i
                    else
                        tmp_hash[columns[j]] = values[j].to_s
                    end
                }
                results << tmp_hash
            end
        }
        p results
    end
    

    やってることは、コマンドラインでMySQLのクエリを発行しているのと同義で、標準出力としてのMySQLクエリの結果をRuby側で取り込んでハッシュにパースしているだけです。 なお、MySQL5.6からコマンドラインにパスワードを付与してmysqlコマンドを実行すると警告が出てしまうので、MySQLへの接続は.user.cnfのファイルに書いて、そっちからインポートするようにしている。

    ...
  • Chefで既存手順のレシピを書く4(DBサーバ)

    おつかれさまです。小宮です。

    前回に引き続きdbserverのレシピについて書いていきます。
    のこってるのはmunin、zabbxとserverspecでのテストだけです。もうすこしの辛抱です。

    webと同じくバージョン固定インストールなので、外部レシピは基本的に使わない方向とする

    ・mysqlのインストールと起動と自動起動の有効化

    [shell]# cd /root/chef-repo/site-cookbooks/mysqld/recipes

    mkdir -p /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms

    mkdir -p ../templates/default/etc/init.d

    mkdir -p ../files/default/etc/init.d

    mkdir -p ../files/default/root

    mkdir -p /root/chef-repo/site-cookbooks/mysqld/files/default/etc/logrotate.d

    mkdir -p /root/chef-repo/site-cookbooks/mysqld/files/default/opt/{backup,bin}

    scp -Cp xxx-db02:/opt/bin/mysql-back.sh /root/chef-repo/site-cookbooks/mysqld/files/default/opt/bin/

    cp -p /etc/logrotate.d/mysqld /root/chef-repo/site-cookbooks/mysqld/files/default/etc/logrotate.d/

    scp -Cp xxx-db01:/etc/init.d/mysqld ../files/default/etc/init.d/

    scp -Cp xxx-db02:/etc/my.cnf ../templates/default/etc/

    cp -p /root/.path_to_file ../files/default/root/

    cd /opt/src/rpms/

    tar czf /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms/db-rpm.tar.gz ./db-rpm/

    tar czf /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms/db-tools-rpm.tar.gz ./db-tools-rpm/

    tar tzf /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms/db-rpm.tar.gz

    vi ../templates/default/etc/my.cnf

    diff /etc/my.cnf ../templates/default/etc/my.cnf

    53c53

    ...
  • mysqlパフォーマンス改善への道(その1、現状の確認)

    パワー不足のmysqlをチューニングしてみます。

    こんばんわ。プラットフォーム担当の宮下です。

    今回は、バックアップ兼集計用に稼働しているmysqlのレプリケーションンサーバの
    パフォーマンス改善していきたいと思います。
    これまでにもいくつか対策はしてきましたが、まずは環境をおさらいします。

    ◇稼働してる環境は、AWSのEC2でlargeインスタンスを使用しています。
     サービスは、OpenPNEを使用したSNSのサービスとなります。対象のMysqlはバックアップとデータ集計が目的で稼働しています。
     (本番サービスでは使用していません)

    ◇mysqlのバージョンはちょっと古くて「5.0.77」になっています。multiで起動させていていて
     この他に開発環境用のmysqlも稼働していたりします。  ちなみに今の遅延秒数は、「1512561 秒」でまだ増加中です。

    ◇これまでに変更した点ですが、
     「innodb_buffer_pool_size」を512Mから2028Mまで増加、
     「innodb_flush_log_at_trx_commit」を2から0に変更、
     (リカバリの精度よりもスループットを優先)
     「key_buffer_size」を32Mから300Mに変更、
     「query_cache_size = 0」にして無効化しました。
     効果は、DISKのI/Oが半分くらい減りましたが、遅延解消とまではいってません。

    ◇最後にmuninで取得しているデータを確認します。

    delay0527

    遅延が日々増えています。たまに減る事もありますが要因は分かりません。

    io0527

    常にDISKのread I/Oが大量に発生しています。

    原因ははっきりしていて、DBデータに画像や動画データが格納されている為となります。
     buffer pool sizeでは収まり切らないデータサイズなので常にDISKのread/writeが発生しています。
     またMyISAMとInnodbが混在していてリソースが効率的に利用出来ていない事や、
     OpenPNEが「delete aaa filename LIKE ‘%bbb%’」というクエリを大量に発行している事
     などが解決すべき課題がたくさんあります。

    現状を整理した事で、次回からは一つずつ改善対策を実施していきたいと思います。

    ...
  • MHAの動作確認と切替検証

    MHAの動作確認と切替検証
    前回のつづきです。以下の図のように切り替わるようテストします。

    mha_after_failover  ※本検証はマスタ1台、スレーブ2台、マネージャ1台構成。(多段構成は中間ノード障害時の復旧が猥雑になるので回避)
      スレーブにmanagerを同居させるとpurge_relay_logsとかぶると上手く切り替わらない可能性があるようです。
     ※2台しかない場合で上手く切り替わらないことがあるようです。以下参考。
      http://heartbeats.jp/hbblog/2013/05/mysql-mha-haproxy.html

    ⑥ 起動前チェック

    ・sshの動作チェック
    [shell] # masterha_check_ssh –conf=/etc/app1.cnf [/shell] OKな場合最終的に以下のように出力される
    [shell] Tue Oct 23 15:02:22 2012 - [info] All SSH connection tests passed successfully. [/shell]
    ・replicationの動作チェック
    [shell] # masterha_check_repl –conf=/etc/app1.cnf [/shell] OKな場合最終的に以下のように出力される(※mysql5.6からはMHAのバージョンによってはbinlog-checksum=NONEにしないとここで失敗するかもしれません)
    [shell] MySQL Replication Health is OK. [/shell] ※失敗するパターン
    レプリケーションのフィルタリングルールが合っていない
    LVSとMHAマネージャが相乗りの場合、チェックタイミングが重複しホスト毎DBサーバに拒否されてしまう(要flush hosts;)

    ...
  • MHA(MasterHighAvailabilityManager)の導入設定

    MHA(MasterHighAvailabilityManager)の導入設定 使用バージョン:mha4mysql-manager-0.53-0、MySQL-5.5

    mha-img1

    ①簡単な利点などの解説

    MHAとはmysqlのマスタ障害時に最新のスレーブをマスタとして他のスレーブの差分を補完しマスタの向き先を変えてくれるプロダクト。
    Heartbeat+mon+mysqlに比べるとreplicationの再構成も行ってくれるので切り替わってもDBがシングルにならないのが利点。(3台以上の構成の場合)

    作者のスライド
    公式サイト
    MHAの制約:mysql5.0以上、SBR(ステートメントベースレプリケーション)の場合LOAD DATA INFILEを使えない
    ※マネージャはadminサーバ、ノードはDBサーバ(マスタ・スレーブ共通)

    ② マネージャにてインストール    ※以下、admサーバから実施

    ・インストール
    [php]

    wget http://mysql-master-ha.googlecode.com/files/mha4mysql-node-0.53-0.noarch.rpm

    wget http://mysql-master-ha.googlecode.com/files/mha4mysql-manager-0.53-0.noarch.rpm

    yum –enablerepo=rpmforge install \

    perl-Config-Tiny \ perl-Time-HiRes \ perl-Log-Dispatch \ perl-Parallel-ForkManager \ perl-Params-Validate

    yum install perl-DBD-MySQL

    rpm -ivh mha4mysql*

    [/php] 入ってなかったら

    [shell]yum install –enablerepo=remi mysql mysql-server perl-DBD-MySQL[/shell] ※マネージャはmysql-serverいらないかも

    ③ ノードにてインストール ※以下、dbサーバから実施
    [shell]

    ...