2015年10月22日木曜日

MySQL 5.6 query_cache_typeをmy.cnfに設定したらエラー

MySQL 5.6 のメモリのチューニングをしていた際のハマりです。
query_cache_typeを設定していなかったので、起動中のMySQLを一旦止めて、my.cnfに下記を追記して再起動。
query_cache_limit = 16M
query_cache_size = 512M
query_cache_type = 1
するとエラー。

The server quit without updating PID file...

もうこれ見飽きた...

my.cnfにquery_cache_typeの設定をするとこのエラーが出てしまうのですが
記述に問題あるようにも見えなくて、実際、記述自体に問題はないわけです。
でもただ起動できないでどうしてエラーなのかさっぱりわからず
MySQLからset global を使って、グローバルでセットしてみるも
やはりエラー。(当たり前)

Query cache is disabled; restart the server with query_cache_type=1 to enable it

【結果】
query_cache_type は、設定/変更する際、ログファイルの削除が必要だったんです。

【手順】
クエリキャッシュを変更するときには
1.MySQL サービス停止
2.ib_logfile0、ib_logfile1を削除(不安だったらリネーム)
3.my.cnfを書き換え
4.MySQLサービス起動
という流れになります。

余談ですが、MySQLを再起動するとき、残っていたロックファイル(lock/subsys/mysql)を削除しようとしたのですが、killしてもkillしても復活してきたので潔くOSをrebootしました。

2015年9月10日木曜日

MySQL 5.6で Assertion failure in thread

■現象
my.cnfにquery_cacheの設定を追記してmysqlを再起動したら起動に失敗
追記した部分↓(問題あり?)
query_cache_limit = 16M
query_cache_size = 512M
query_cache_type = 1
■エラーログ確認
○/var/mysql/logs/error.log
2015-09-08 20:02:41 7f9721e4e720  InnoDB: Assertion failure in thread 140287085438752 in file ut0mem.cc line 105
InnoDB: Failing assertion: ret || !assert_on_error
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
11:02:41 UTC - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
key_buffer_size=8388608
read_buffer_size=131072
max_used_connections=0
max_threads=151
thread_count=0
connection_count=0
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 68241 K  bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0 thread_stack 0x40000
/usr/local/mysql/bin/mysqld(my_print_stacktrace+0x35)[0x8e1b75]
/usr/local/mysql/bin/mysqld(handle_fatal_signal+0x41b)[0x650a1b]
/lib64/libpthread.so.0[0x37bd00f4a0]
/lib64/libc.so.6(gsignal+0x35)[0x37bcc32885]
/lib64/libc.so.6(abort+0x175)[0x37bcc34065]
/usr/local/mysql/bin/mysqld[0xa2b557]
/usr/local/mysql/bin/mysqld[0xaafb60]
/usr/local/mysql/bin/mysqld[0xaae7f6]
/usr/local/mysql/bin/mysqld[0xa4f0ee]
/usr/local/mysql/bin/mysqld[0xa5c9cf]
/usr/local/mysql/bin/mysqld[0xa09f6f]
/usr/local/mysql/bin/mysqld[0x95a7f7]
/usr/local/mysql/bin/mysqld(_Z24ha_initialize_handlertonP13st_plugin_int+0x48)[0x58d388]
/usr/local/mysql/bin/mysqld[0x6e1f86]
/usr/local/mysql/bin/mysqld(_Z11plugin_initPiPPci+0xb3e)[0x6e567e]
/usr/local/mysql/bin/mysqld[0x580905]
/usr/local/mysql/bin/mysqld(_Z11mysqld_mainiPPc+0x4d8)[0x585898]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x37bcc1ecdd]
/usr/local/mysql/bin/mysqld[0x577bdd]
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
crash(;゚Д゚)!?
エラーメッセージでググッてみると、「MySQLがクラッシュした」という記事ばかりで青くなりました。
不用意に再起動した自分を呪いつつ、設定ファイルを変えたタイミングだったわけでまずはそちらを確認。
結果、上述したmy.cnfの記述に問題があったようなのですが。
なにが悪かったのか良くわからず・・・query_cacheの記述が違うのかもしれません。
これについてはまたきちんと原因を調べるとして、起動までにやったことを残しておきます。
リカバリーはしなくて済みました。

■やったこと
○my.cnfの上記をコメントアウトして再起動
→下記エラーで起動せず
[root@dev init.d]# ./mysql.server start
Starting MySQL. ERROR! The server quit without updating PID file (/var/mysql/data/dev.xxxxxx-xxx.net.pid).
上記エラーをスタンダードな手順での解消を試みます。

○起動に失敗したときに残ってしまったプロセスを確認
[root@dev logs]# ps aux | grep mysql
root     24734  0.0  0.0 106152  1384 pts/0    S    20:02   0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock -
mysql    24805  0.0  0.1 261160 21736 pts/0    Sl   20:02   0:00 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/et=/var/lib/mysql/mysql.sock
root     28203  0.0  0.0 107516   940 pts/0    S+   21:20   0:00 grep mysql

○mysqlが起動しているmysqldをkill
[root@dev logs]# kill 24805
[root@dev logs]# ps aux | grep mysql
root     28207  0.0  0.0 107516   944 pts/0    S+   21:20   0:00 grep mysql

○再起動前に念のためステータス確認するとロックファイルがあったのでそれをリネーム(削除でもいいと思います)
[root@dev logs]# /etc/rc.d/init.d/mysql.server status
 ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists
[root@dev logs]# cd /var/lock/subsys
[root@dev subsys]# mv mysql _mysql

○再起動
[root@dev subsys]# /etc/rc.d/init.d/mysql.server start
Starting MySQL.. SUCCESS!

★教訓
稼働中のDBを不用意に設定変更・再起動しない
my.cnfをいじるときはかならず確実な情報をもとに編集・再起動
クラッシュを疑う前に胸に手をあてて自分の行動を鑑み、小さな部分から対応を潰していく

★Tips
mysql強制起動オプション(my.cnfに追記する)
innodb_force_recovery = 3
※1~6まで指定できて、1が一番やさしい強制。通常は1から順番に設定しながら起動確認していくようです。

2015年9月8日火曜日

CentOS opensslで自前の認証局+自己署名証明書を作成(オレオレ証明書)

【注意】2015.10.9 追記
本記事で作成できるサーバ証明書はsha1になります。
sha1はセキュリティ上の問題より廃止の方向となり、sha2証明書への以降が進められています。
そのため本記事は単なる備忘録としてお読みください。


読み返したら2012年にもオレオレ証明書サーバで開発をしていました。
3年前はまだX0代だったんだ…(=ω=)トオイメ

今回構築している社内用のアプリケーションは証明書とかなにもない入れっぱなしのSSLのためアクセスするたび警告が出ます。
それを自己署名証明書(所謂オレオレ証明書)で回避するため、自前の認証局を構築し、自己署名証明書を作成し、ブラウザにインポートするまでの自分用備忘録です。

■環境
OS:CentOS release 6.6 (Final)
Webサーバ:Apache/2.2.29 (Unix)
openssl:OpenSSL 1.0.1j 15 Oct 2014

■まえがき
CentOS 5以上(?)の場合、mod_sslパッケージをインストールするとオレオレ証明書の設定後、SSLが利用できます。
しかしアクセスするたび警告は出るのが鬱陶しくなってきたのでここは一手間踏んででも回避したいと思い、証明書を社内の皆様にインポートしていただくべく、自前の認証局を構築しそれで証明書を署名したものを配布することにしました。
構築時の備忘録です。足りないところは適宜他のサイト様で補完下さい。

■前準備(前提)
・サーバ名
 IPアドレス(ドメインの場合はドメイン指定。私はIPアドレス運用だったので)
・実行ファイルと設定ファイル
 CA実行ファイル:/etc/pki/tls/misc/CA
 openssl.cnfファイル:/etc/pki/tls/openssl.cnf
 /etc/pki配下にあるフォルダ:CA  ca-trust  java  nssdb  rpm-gpg  rsyslog  tls
・権限
 コマンドはここからすべてrootで行っています
・作業ディレクトリ
 最初から「CA」ディレクトリがある前提で、ここをベースにCAを構築していきます。
(新しくディレクトリを作る場合はそれも良いです。その場合はtls/misc/CA を/etc/pki/CA とか適当なフォルダ名でコピーしてそちらを使います。フォルダ名はCAでなくとも何でも可能です。)
 openssl.cnfは「/usr/local/openssl/openssl.cnf」等他の場所にもあるので、こちらを指定しないようCA(実行ファイル)を後ほど修正します。
 CAと同様にcnfファイルはどこに置いても良いです。CA内に置いてもわかりやすいと思います。
・その他
 何かのエラーが出てCAに失敗した場合、CAディレクトリを削除してからもう一度実行します。
 CAは認証局(Certification Authority)のことです。

■構築
1.ルート CA(認証局) 構築

●cnfファイルを環境に合わせて修正
[root@dev]#vi /etc/pki/tls/openssl.cnf
[ CA_default ]
dir             = /etc/pki/CA    # Where everything is kept

[ req_distinguished_name ]
countryName                    = Country Name (2 letter code)
countryName_default            = JP
countryName_min                = 2
countryName_max                = 2

stateOrProvinceName            = State or Province Name (full name)
stateOrProvinceName_default    = Tokyo

localityName                   = Locality Name (eg, city)
localityName_default           = SHINAGAWA-KU

0.organizationName             = Organization Name (eg, company)
0.organizationName_default     = Sample Company Co., Ltd.


[ usr_cert ]
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

# nsComment                    = "OpenSSL Generated Certificate" ###コメントアウト
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

[ v3_ca ]
keyUsage = cRLSign, keyCertSign

●CAファイルを環境に合わせて修正
[root@dev]#vi /etc/pki/tls/misc/CA

if [ -z "$DAYS" ] ; then DAYS="-days 365" ; fi  # 1 year
SSLEAY_CONFIG="-config /etc/pki/tls/openssl.cnf"    ### ここにcnfのパスを挿入
CADAYS="-days 1095"     # 3 years
REQ="$OPENSSL req $SSLEAY_CONFIG"
CA="$OPENSSL ca $SSLEAY_CONFIG"
VERIFY="$OPENSSL verify"
X509="$OPENSSL x509"
PKCS12="openssl pkcs12"

if [ -z "$CATOP" ] ; then CATOP=/etc/pki/CA ; fi    ### ここにCAのパスを挿入
CAKEY=./cakey.pem
CAREQ=./careq.pem
CACERT=./cacert.pem
...
-newca)
...
            echo "Making CA certificate ..."
            $REQ -new -keyout ${CATOP}/private/$CAKEY \
                           -out ${CATOP}/$CAREQ
            $CA -create_serial -out ${CATOP}/$CACERT $CADAYS -batch \
                           -keyfile ${CATOP}/private/$CAKEY -selfsign \
                           -extensions v3_ca \       ### 記述がなければここに追記
                           -infiles ${CATOP}/$CAREQ
            RET=$?
        fi
●秘密鍵・公開鍵・自己署名証明書を生成
[root@dev]# /etc/pki/tls/misc/CA -newca
CA certificate filename (or enter to create)
Making CA certificate ...
Generating a 2048 bit RSA private key
...................................+++
.........................................................+++
writing new private key to '/etc/pki/CA/private/./cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
(略)
-----
Country Name (2 letter code) [JP]:JP
State or Province Name (full name) [Tokyo]:Tokyo
Locality Name (eg, city) [SHINAGAWA-KU]:
Organization Name (eg, company) [Sample Company Co., Ltd.]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:IPアドレス or ドメイン
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:   (※空)
An optional company name []: (※空)
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/./cakey.pem:
Check that the request matches the signature
Signature ok
-----
(略)
-----
Certificate is to be certified until Sep  6 09:50:22 2018 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated
※challenge password:Apacheの起動時に毎回パスワードを求められる。空のまま推奨

●証明書の作成
[root@dev]# echo "00" > /etc/pki/CA/crlnumber   (※後述)
[root@dev]# openssl ca -config /etc/pki/tls/openssl.cnf -gencrl -out crl.pem
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
※An optional company name:オプションの会社名略称。特に入力の必要なし
※crlnumber:期限切れの証明書などを失効させるのに必要。最初は自分で作る

【できあがりのルートCAファイル】※ファイル名はサンプル
CA証明書:cacert.pem, newcerts/V9V2V9VA7V42VCFVE.pem
CA秘密鍵:private/cakey.pem
CA証明書発行要求:certs/V9V2V9VA7V42VCFVE.pem

2.サーバ証明書発行

●CAで新しい鍵ペアとリクエスト作成
[root@dev]# /etc/pki/tls/misc/CA -newreq
Generating a 2048 bit RSA private key
..............................+++
.......................................+++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:(パスフレーズ)
Verifying - Enter PEM pass phrase:(パスフレーズ)
-----
(略)
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [Tokyo]:
Locality Name (eg, city) [SHINAGAWA-KU]:
Organization Name (eg, company) [Sample Company Co., Ltd.]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:IPアドレス
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:   (※空)
An optional company name []: (※空)
Request is in newreq.pem, private key is in newkey.pem

●証明書を認証(発行)
[root@dev]# /etc/pki/tls/misc/CA -sign
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:(パスフレーズ)
Check that the request matches the signature
Signature ok
Certificate Details:
-----
(略)
-----
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Certificate:
-----
(略)
-----
Signed certificate is in newcert.pem

newcerts内のファイルから一番新しいもの(値が大きい物)を探し、証明書及びキーとしてCAディレクトリに保存し、サーバ証明書として名前をつけて保存
[root@dev]# cd newcerts
[root@dev]# ls
V9V2V9VA7V42VCFVE.pem  V9V2V9VA7V42VCFVF.pem
[root@dev]# mv newreq.pem certs/V9V2V9VA7V42VCFVF.pem
[root@dev]# mv newkey.pem private/V9V2V9VA7V42VCFVF.pem
[root@dev]# rm newcert.pem(不要なので削除)
rm: remove regular file `newcert.pem'? y
[root@dev]# openssl x509 -in newcerts/V9V2V9VA7V42VCFVF.pem -out www.crt
[root@dev]# openssl rsa -in private/V9V2V9VA7V42VCFVF.pem -out www.key
Enter pass phrase for private/V9V2V9VA7V42VCFVF.pem:
writing RSA key
【出来上がりのサーバ証明書ファイル】※httpd-ssl.confに設定するファイル
SSLCertificateFile:www.crt
SSLCertificateKeyFile:www.key

3.サーバ証明書ファイルをWebサーバに設定

●httpd-ssl.confに以下を設定
SSLEngine on
SSLCertificateFile "/etc/pki/CA/www.crt"
SSLCertificateKeyFile "/etc/pki/CA/www.key"
※ファイル・フォルダ名は適宜書き換えること

4.IEにサーバ証明書を「信頼されたルート証明機関」としてインポート

●ドキュメントルート配下に形式をcrtにしてコピーし、ブラウザからダウンロードできるようにする
[root@dev]# cp cacert.pem /var/www/html/cacert.crt
1. ブラウザから証明書ファイルにアクセスし、ファイルを開くか、保存して実行
2. 証明書ダイアログが表示されるので「証明書のインストール」をクリック
3. 証明書のインポートウィザードが表示されるので「次へ」をクリック
4. 【重要】証明書ストアの選択で「証明書をすべて次のストアに配置する」を選ぶ
5. 「参照」をクリックし『信頼されたルート証明機関』を選択して「OK」をクリック
6. 証明書ストアが「信頼されたルート証明機関」となっているのを確認し「次へ」をクリック
7. ユーザが選択した証明書ストアが「信頼されたルート証明機関」となっているのを確認し「完了」
8. 『正しくインポートされました』というアラートがポップアップするので「OK」

5.ブラウザからアクセスする

自己署名証明書のためか「セキュリティが弱い」黄色いマークが出ていますが、真っ赤な証明書エラーはでなくなったのでとりあえず完了。

■参考サイト
基本的にこれらのサイト様のとおり実行しました

オレオレ認証局の作り方~SSL証明書を無料で作る方法 on CentOS 5
http://www.webtech.co.jp/blog/optpix_labs/server/1159/

オレオレ認証局でSSLクライアント認証しようとしたら、色々ハマったから手順をまとめた
http://aki2o.hatenablog.jp/entry/2015/01/12/223011

ほんとうにありがとうございます。

実際に作成するときの有効期限は1年ではなく10年でも良いかもしれません。
SSL証明書の有効期限を10年で作成
http://www.plustar.jp/lab/blog/?p=7353