5次元のカオス

南の島の学生がつらつらと日々を書き連ねます

Chef SoloでVagrant上にMySQLをインストールする

Chef SoloでVagrant上にMySQLをインストールする

Vagrantの導入とちょっとしたサーバの初期設定をしてみた を書いてから、

自分でもレシピを書いてみようと思い, mysqlのインストールを行うレシピを書いてみました.

しかし、なかなかまとまった情報や、コレ!といったものがないため

自分自身で色々と試さなければいけないことも多く学習コストは高いかもと感じました.

とりあえず、動くものが書けてよかった...

初めてのレシピですが, 一応 githubにて公開してみたので、色々とフィードバックして頂けると幸いです.

MyChef-repo/mysql at master · seka/MyChef-repo

なかなか時間はかかってしまったのですが, 一度書いてしまえばレシピを使い回すことができて便利かなと思っています.

他のサーバを使うということになってもコードとして残しているため

簡単に環境構築を済ませることができるし,パラメータの調整がしやすくなるはず...!

( あとはハッカソンのような開発スパンが短いものにも便利かと思う

自分での試行錯誤が多くなってしまったので以下、健忘録としてメモ.

開発環境

各環境のバージョンは下記の通り.

chef-solo   : 11.6.2
Vagrant     : 1.3.5
virtual box : 4.3.2
OS          : centos64box (virtualbox)
mysql       : 5.6.15

mysqlのレシピのひな形を作る

基本的な流れは, 以前のブログに記述した通り

  1. Chefのリポジトリ作成
  2. nodeをchefに対応させる
  3. cookbookを作る
  4. cookbookをnodeに反映させる

※ 1は knife solo init chef-repo のこと

※ 2は : knife solo prepare ユーザ名@ドメイン のこと

cookbookを作成する

cookbookの作成

knife cookbook create mysql -o site-cookbooks/

mysql用のクックブックを作成します.

cookbookを実行するレシピを書き込む

chef-repo/nodes/ドメイン.json の編集

{
    "run_list":[
        "recipe[mysql]"
    ]
}

今回はとりあえず、mysqlのクックブックのみ実行する

mysqlをインストールする

mysql-libsを削除する

chef-repo/site-cookbooks/mysql/recipes/default.rb の編集

package 'mysql-libs' do
  action :remove
end

MySQL-serverをインストールしようとすると, デフォルトで入っているmysql-libsと競合してしまう.

そのため, mysql-libsを削除を行う必要がある.

mysqlに関係するファイルをダウンロードし、配置する.

mysql 5.6 はデフォルトのyumではインストールされないため、rpmを使ってリポジトリを追加していく.

以下から環境に合わせたrpmをダウンロードする.

※ downloads > No thanks, just start my download. で署名せずにダウンロードできる.

ダウンロードするrpmのファイルは以下の通り.

ダウンロード後, chef-repo/site-cookbooks/mysql/files/default に設置.

chef-repo/site-cookbooks/mysql/files/default を確認すると以下の通り.

$ ls chef-repo/site-cookbooks/mysql/files/default
MySQL-client-5.6.15-1.el6.x86_64.rpm
MySQL-server-5.6.15-1.el6.x86_64.rpm
MySQL-shared-compat-5.6.15-1.el6.x86_64.rpm
MySQL-devel-5.6.15-1.el6.x86_64.rpm
MySQL-shared-5.6.15-1.el6.x86_64.rpm

レシピを書く

以下の記事を参考にしてcookbook_fileとpackageリソースを組み合わせて実行する.

ChefでCookbookを作成するときのちょっとしたコツ 9選 - インフラエンジニアway - Powered by HEARTBEATS

chef-repo/site-cookbooks/mysql/attributes/default.rb の編集

# rpm files
default['mysql']['rpm'] = [
  'MySQL-server-5.6.15-1.el6.x86_64.rpm',
  'MySQL-client-5.6.15-1.el6.x86_64.rpm',
  'MySQL-devel-5.6.15-1.el6.x86_64.rpm',
  'MySQL-shared-5.6.15-1.el6.x86_64.rpm',
  'MySQL-shared-compat-5.6.15-1.el6.x86_64.rpm'
]
  • attributesに定義した変数はrecipes内から参照できる

chef-repo/site-cookbooks/mysql/recipes/default.rb の編集

node['mysql']['rpm'].each do |rpm|
  cookbook_file "/tmp/#{rpm}" do
    action :create
    source "#{rpm}"
  end

  rpm_package "#{rpm}" do
    action :install
    source "/tmp/#{rpm}"
  end
end
  • ファイルは/tmpに展開されたあと、サーバにインストールされる
  • cookbook_file : chefを実行するホストに指定されたパスにcookbookのfilesディレクトリからファイルを転送する
  • rpm_package : RPMパッケージマネージャのプラットフォーム用のパッケージを管理するために使用される

my.cnfの作成

my.cnfをgithubにて公開してる方がいたため、それを参考にします.

チューニングのポイントも紹介していらっしゃるため、大変参考になりました...

※ 今回は、innoDBの部分を抜き出しました

上記のブログを参考に、メモリの何%を目安にしてくださいという部分を自動化してみます.

site-cookbooks/mysql/libraries/innodb-param.rb の編集

module InnodbParam
  # 全般設定
  INNODB_BUFFER_POOL_SIZE_RATIO = 0.75    # 最大メモリ容量の何%を利用するか 1=100% 目安:75%
  INNODB_BUFFER_POOL_SIZE_MIN   = 65536   # KB単位.64MB以下と出た場合は強制的にこの値にセット
  PARAM_MAX_CONNECTIONS = 1024

  # スレッド バッファ (KB)
  PARAM_SORT_BUFFER_SIZE      = 1024
  PARAM_JOIN_BUFFER_SIZE       = 128          # joinすること自体が避けるべきことなのであまり大きな値を取る必要は無い
  PARAM_READ_BUFFER_SIZE      = 1024
  PARAM_READ_RND_BUFFER_SIZE  = 512     # インデックスによるソートを実行するとき、ソートしたレコードの読み出しに使うメモリ上の領域
  PARAM_NET_BUFFER_LENGTH     = 8

  # グローバル バッファ (KB)
  PARAM_KEY_BUFFER_SIZE            = 1024 * 16  # 空きメモリの30%ぐらい
  PARAM_QUERY_CACHE_SIZE        = 1024 * 64  # テーブルの更新が少なく、かつ同じクエリを繰り返す場合、このパラメータを大きくするとクエリの解析と実行をスキップできる
  PARAM_INNODB_LOG_BUFFER_SIZE  = 1024 * 16  # 目安:8MB ~ 64MB
  PARAM_INNODB_LOG_FILE_SIZE       = 1024 * 128 # コミットされたトランザクションをテーブルスペースに反映する前に一時的に書き出しておくためのファイル 目安:1MB ≦ innodb_log_file_size ≦ 4GB(32bit OS)
  PARAM_INNODB_ADDITIONAL_MEM_POOL_SIZE = 1024 # InnoDBの定義情報などをキャッシュするメモリ上の領域(エラーログに警告が出たら増やす

  def get_innodb_params(items)
    items[ "innodb_log_buffer_size" ]          = PARAM_INNODB_LOG_BUFFER_SIZE.to_s + "K"
    items[ "innodb_log_file_size" ]               = PARAM_INNODB_LOG_FILE_SIZE.to_s + "K"
    items[ "innodb_additional_mem_pool_size" ] = PARAM_INNODB_ADDITIONAL_MEM_POOL_SIZE.to_s + "K"

    innodb_buffer_pool_size =
      (`cat /proc/meminfo | grep MemTotal | awk '{ print $2 }'`).to_i \
      * INNODB_BUFFER_POOL_SIZE_RATIO \
      - (PARAM_SORT_BUFFER_SIZE + PARAM_JOIN_BUFFER_SIZE + PARAM_READ_BUFFER_SIZE + PARAM_READ_RND_BUFFER_SIZE + PARAM_NET_BUFFER_LENGTH) \
      * PARAM_MAX_CONNECTIONS \
      - PARAM_KEY_BUFFER_SIZE \
      - PARAM_QUERY_CACHE_SIZE \
      - PARAM_INNODB_LOG_BUFFER_SIZE \
      - PARAM_INNODB_ADDITIONAL_MEM_POOL_SIZE

    if innodb_buffer_pool_size > INNODB_BUFFER_POOL_SIZE_MIN
      items[ "innodb_buffer_pool_size" ] = innodb_buffer_pool_size.round.to_s + "K"
    else
      items[ "innodb_buffer_pool_size" ] = INNODB_BUFFER_POOL_SIZE_MIN.to_s + "K"
    end
  end
end

chef-repo/site-cookbooks/mysql/recipes/default.rb の編集

template '/etc/my.cnf' do
  source 'my.cnf.erb'
  owner 'root'
  group 'root'
  mode 644

  mysql_params = Hash::new
  get_mysql_params(mysql_params)

  innodb_params = Hash::new
  get_innodb_params(innodb_params)

  variables({
    # ~ 略 ~
    :data_dir => node['mysql']['data_dir'],
    :mysql_params => mysql_params,
    :innodb_params => innodb_params
  })
end

site-cookbooks/mysql/templates/default/my.cnf.erb の編集

[mysqld]
datadir = <%= @data_dir %>
socket = <%= @socket %>

~ 省略 ~

<% @mysql_params.each_pair do | name, value | %>
  <%= name %> = <%= value %>
<% end %>

<% @innodb_params.each_pair do | name, value | %>
  <%= name %> = <%= value %>
<% end %>

~ 省略 ~

mysql を指定した先へ移動する

execute "move" do
  command "mv /var/lib/mysql /usr/local/var/"
  only_if { ::File.exists?("/var/lib/mysql")}
end

デフォルトだと /var/lib/mysql 以下にmysqlがインストールされる.

datadirやsocketの場所を任意の場所にしたかったため、executeを使ってmysqlディレクトリを移動させる.

mysqlの起動

service 'mysql' do
  action [:start, :enable]
end
  • enable : ブート時にサービスを有効にする

nodeに反映させる

4.cookbookをnodeに反映させる を行う.

knife solo cook ユーザ名@ドメイン

エラーがなく、無事に完了すればひとまず成功.

インストール後の確認

vagrantへアクセスし、mysqlの起動を確認する.

※ psコマンドやmysql status で確認できる

mysql 5.6からデフォルトのパスワードが設定されている.

/root/.mysql_secret にパスワードファイルが設置されているため内容を確認する.

MySQLのインストール方法が進化していた! - sakaikの日々雑感~(T)編

その後、mysqlへパスワードを使って無事にアクセスできれば成功.

参考