[Shell Script] DBバックアップ、S3へアップロード

S3バックアップ用IAMユーザーの作成

Management Consoleより、IAMのポリシーを作成し、ユーザーをアタッチする。

S3バックアップ用ポリシー例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1506579924000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionAcl",
                "s3:PutObjectVersionTagging",
                "s3:ReplicateDelete",
                "s3:ReplicateObject",
                "s3:RestoreObject"
            ],
            "Resource": [
                "arn:aws:s3:::{BUCKET_NAME}",
                "arn:aws:s3:::{BUCKET_NAME}/*"
            ]
        }
    ]
}
# AWS CLIからS3 APIへ接続
$ aws configure --profile s3-bk
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]: text

# 確認
$ aws s3 ls s3://{BUCKET_NAME}/ --profile s3-bk

MySQL接続用ファイルの作成

mysql接続用のユーザー名/パスワードはスクリプト外のファイルで管理する。
./.access-db.conf

[client]
user     = "{DB_USER_NAME}"
password = "{DB_USER_PASS}"

権限を変更する。

chmod 0600 ./.access-db.conf

シェルスクリプト

変数は外部参照。
if文やエラー処理等は省略している。

#!/bin/bash
#
# Backup Database.
#
# Ex. sh database_backup.sh
#
###############################################

BK_PATH=/backups/databases
PROFILE=s3-bk
DB_NAME=test
DB_HOST=test.ap-northeast-1.rds.amazonaws.com
BUCKET_NAME_BACKUP="s3://{BUCKET_NAME}/"

if [ ! -e ${BK_PATH} ]; then
    mkdir -p ${BK_PATH}
fi

cd /root/scripts/backup_script

echo '~~~~~~~~~~~~ Start Backup ~~~~~~~~~~~~'

# MySQLdump DB server
mysqldump --defaults-extra-file=./.access-db.conf --databases ${DB_NAME} --default-character-set=utf8 --add-drop-database --host=${DB_HOST} > ${BK_PATH}/${DB_NAME}-dump.sql

# GZIP SQL files
# -C で絶対パスによるエラー出力を抑制
GZIP=-9 tar czf ${BK_PATH}/${DB_NAME}-dump-`date +%Y%m%d%H%M`.tar.gz -C / backups/databases/${DB_NAME}-dump.sql

echo '~~~~~~~~~~~~ Remove backup files more than 7 days ~~~~~~~~~~~~'
find ${BK_PATH}/ -name "*.tar.gz" -type f -mtime +7 | xargs rm -fv
rm -fv ${BK_PATH}/${DB_NAME}-dump.sql

# Sync S3
aws s3 sync ${BK_PATH}/ ${BUCKET_NAME_BACKUP} --acl private --profile=${PROFILE}

echo '~~~~~~~~~~~~ Finished Backup ~~~~~~~~~~~~'

exit 0
  • 外部ファイルから、DB(MySQL)接続ユーザーとパスワードは指定する。
  • 最高品質を保つ圧縮の”GZIP=-9″で”tar.gz”を作成。
  • 本日より7日前以上のファイルは削除。

Cronへ仕込み

$ crontab > /root/crontab
$ vim /root/crontab
$ crontab < /root/crontab
$ crontab -l
05 2 * * * /bin/sh /root/scripts/backup_script/contents_backup.sh 1> /dev/null 2> /dev/null
10 2 * * * /bin/sh /root/scripts/backup_script/database_backup.sh 1> /dev/null 2> /dev/null

参考サイト

関連記事

[AWS][WordPress] サーバー移管/初期設定

環境例

環境 Ver.
OS Amazon Linux AMI 2017.03.1.20170812 x86_64 HVM GP2
WordPress 4.8.1
Apache 2.4
MySQL 5.7
PHP 7.0
EC2 type t2.micro

環境構築

インスタンスを立てる

VPCの構築、Security Groupの設定、ELBの設定、RDSの構築、DNSの登録、Certificate Managerから証明書の発行等は今回、省略する。

既存サーバの状況確認

ミドルウェアインストール状況、DBの状態、バージョン確認等。

$ php -m
mysql> SELECT HOST, USER FROM `mysql`.`user`;
mysql> SHOW GRANTS FOR '{USER_NAME}'@'{HOST_NAME}'\G;

パッケージアップデート

$ yum update

# セキュリティパッケージの更新のみの場合
$ yum update --security

パッケージインストール

$ yum install tree dstat sysstat iotop htop

Crontab(オプション)

開発環境の場合、節約の為に例えば毎日22時にインスタンスが停止するよう設定する。
/etc/crontab

0 22 * * *     root    /sbin/shutdown -h now >/dev/null 2>&1

TimeZoneの変更

# オリジナルをバックアップ
$ cp /etc/localtime /etc/localtime.org
$ diff /etc/localtime /etc/localtime.org

$ ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ cp /etc/sysconfig/clock /etc/sysconfig/clock.org
$ diff /etc/sysconfig/clock /etc/sysconfig/clock.org

/etc/sysconfig/clock

# ZONEの変更
ZONE="Asia/Tokyo"
# falseにするとハードウェアのクロックもローカルタイムで設定されてしまう為、変更しない
UTC=true

反映の確認

$ /etc/init.d/crond restart
$ strings /etc/localtime
TZif2
TZif2
JST-9

ntpdateの起動

Amazon Linuxは初期状態でNTPによるシステムクロックの同期を行っている。

$ chkconfig ntpdate on
$ chkconfig --list | grep ntpdate

iptablesの停止

セキュリティグループを利用しているため、iptablesは停止する。

chkconfig iptables off
chkconfig ip6tables off
chkconfig --list | grep ip

文字コードの変更

/etc/sysconfig/i18n

LANG="ja_JP.UTF-8"

ホスト名の変更

/etc/sysconfig/network

HOSTNAME={YOUR_HOSTNAME}

各種パッケージインストール

$ yum install httpd24 php70 mysql php70-mysqlnd php70-mbstring php70-bcmath php70-gd php70-pecl-imagick php70-imap php70-intl php70-pecl-oauth php70-pgsql php70-soap php70-xmlrpc php70-opcache
$ service httpd start
$ chkconfig httpd on

# httpdが有効であることを確認。実行レベル 2/3/4/5 がonの必要がある。
$ chkconfig --list httpd
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off

Apacheのテストページがブラウザへ表示されることを確認。
PHP情報ページが表示されることを確認。

$ echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php

現行環境とPHPモジュールの差異がないことを確認。

PHP設定ファイル更新

$ cp /etc/php.ini /etc/php.ini.org

/etc/php.ini

# 検証/開発環境のみ
display_errors = On
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
date.timezone = Asia/Tokyo
expose_php = Off
[imagick]
extension=imagick.so

RDSのパラメータグループの設定

以下の設定でRDSのパラメータグループを作成/適用。

  • character-set-client-handshake: 1
  • skip-character-set-client-handshake: 1
  • character_set_client: utf8
  • character_set_connection: utf8
  • character_set_database: utf8
  • character_set_filesystem: utf8
  • character_set_results: utf8
  • character_set_server: utf8
  • time_zone: Asia/Tokyo
  • collation_connection: utf8_general_ci
  • collation_server: utf8_general_ci
  • max_connect_errors: 999999999
  • max_connections: 2048
  • wait_timeout: 100

httpd.confとVirtualHostの設定

$ cd /etc/httpd/conf/
$ cp -p httpd.conf httpd.conf.org
$ mkdir /etc/httpd/conf/vhosts
$ mkdir -p /var/www/vhosts/xxx/htdocs

/etc/httpd/conf/httpd.conf

# 96行目付近
#ServerName www.example.com:80
ServerName xxx.com:80

# 121行目付近
DocumentRoot "/var/www/vhosts"

#
# Relax access to content within /var/www.
#
#<Directory "/var/www">
#    AllowOverride None
#    # Allow open access:
#    Require all granted
#</Directory>

# 133行目付近
#<Directory "/var/www/html">
<Directory "/var/www/vhosts">

# 154行目付近
#AllowOverride None
AllowOverride All

# 最終行付近
Include /etc/httpd/conf/vhosts/*.conf
KeepAlive On
KeepAliveTimeout 15
Timeout 300
$ mkdir /var/www/dvh

/etc/httpd/conf/vhosts/00_default_virtualhost.conf

<VirtualHost *:80>
    DocumentRoot /var/www/dvh/
    ServerName dummy
    ServerSignature Off
    <Location />
       Order deny,allow
       Deny from All
       Allow from 172
    </Location>
</VirtualHost>

/etc/httpd/conf/vhosts/httpd-vhosts.conf

<VirtualHost *:80>
    ServerName xxx.com
    DocumentRoot /var/www/vhosts/xxx/htdocs/wordpress
    <Directory "/var/www/vhosts/xxx/htdocs/wordpress">
        Require all granted
    </Directory>
</VirtualHost>

コンテンツ/DBデータを復元

# コンテンツ/dumpの取得
$ mysqldump --databases {DB_NAME} --default-character-set=utf8 --add-drop-database --user={USER_NAME} --password --host={HOST_NAME} > ./xxx.sql
$ GZIP=-9 tar czf xxx.tar.gz /path/to/directory

$ scp -P {PORT_NUM} -p {USER_NAME}@{HOST_NAME}:/path/to/xxx.sql.tar.gz ~/

# コンテンツ/dumpの復元
$ tar -zxf contents.tar.gz
$ tar -zxf dump.sql.tar.gz
$ mysql --databases {DB_NAME} --user={USER_NAME} --password --host={HOST_NAME} < ./xxx.sql

コンテンツディレクトリのPermission変更

$ chown apache:apache htdocs
$ find . -type d -exec chmod 0755 {} \;
$ find . -type f -exec chmod 0644 {} \;
$ chown -R apache:apache .
$ chmod -R g+w .
$ chmod 400 wp-config.php
$ chmod 644 .htaccess

wp-config.php の書き換え

/var/www/vhosts/xxx/htdocs/xxx/wp-config.php

define('DB_NAME', '{DB_NAME}');

/** MySQL のユーザー名 */
define('DB_USER', '{DB_USER}');

/** MySQL のパスワード */
define('DB_PASSWORD', '{DB_PASS}');

/** MySQL のホスト名 (ほとんどの場合変更する必要はありません。) */
define('DB_HOST', '{DB_HOST}:3306');

/** データベーステーブルのキャラクターセット (ほとんどの場合変更する必要はありません。) */
define('DB_CHARSET', 'utf8');

# 開発環境の場合は、Jetpackを開発者モードへ変更する。
define( 'JETPACK_DEV_DEBUG', true );

DB日付確認

日本時間となっていることを確認する。

mysql> SELECT now();
+---------------------+
| now()               |
+---------------------+
| 2017-04-xx 17:39:19 |
+---------------------+
1 row in set (0.00 sec)

DB内URL置換

xxx.jp → xxx.com/xxx 等へURLを変換する。
https://interconnectit.com/products/search-and-replace-for-wordpress-databases/ のツールを利用する。
“Search Regex” というWordPressプラグインでも置換が可能。

管理画面のサイトURL

http://xxx/wp-admin/options-general.php
サイトURLが新規URLへ変更されていることを確認する。

.htaccessの設定

  • wp-config.phpのアクセス制御
  • SSLへリダイレクト (ELB/CloudFrontへも対応)

/var/www/vhosts/xxx/htdocs/wordpress/wp-config.php

<?php
# add under for ELB
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
    $_SERVER['HTTPS'] = 'on';
}
/**
 * The base configuration for WordPress

/var/www/vhosts/xxx/htdocs/wordpress/.htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !^https$
RewriteCond %{HTTP:CloudFront-Forwarded-Proto} !=https
RewriteCond %{REQUEST_URI} !^_health_check\.html$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>


<files wp-config.php>
    order allow,deny
    deny from all
</files>

# Not allowed access to .htaccess and .htpasswd
<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</Files>

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

/var/www/vhosts/xxx/htdocs/wordpress/wp-admin/.htpasswd

# http://www.luft.co.jp/cgi/htpasswd.php で作成した値を貼り付け。

/var/www/vhosts/xxx/htdocs/wordpress/wp-admin/.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

# Basic Auth
AuthType Basic
AuthName "Input your ID and Password."
AuthUserFile /var/www/vhosts/xxx/htdocs/wordpress/wp-admin/.htpasswd
AuthGroupfile /dev/null
require valid-user

# Not allowed access to .htaccess and .htpasswd
<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</Files>

# maybe admin-ajax.php used by some plugin
<FilesMatch "(admin-ajax.php)$">
    Satisfy Any
    Order allow,deny
    Allow from all
    Deny from none
</FilesMatch>

Swapの作成

MB単位でTotal行のメモリ出力を行う。

$ free -tm
total       used       free     shared    buffers     cached
Mem:          3953       3315        637          0        161       2501
-/+ buffers/cache:        652       3300
Swap:            0          0          0
Total:        3953       3315        637

同程度のSwap容量を確保。

$ dd if=/dev/zero of=/swapfile bs=1M count=4000
4000+0 レコード入力
4000+0 レコード出力
4194304000 バイト (4.2 GB) コピーされました、 55.568 秒、 75.5 MB/秒
$ mkswap /swapfile
$ swapon /swapfile
$ chmod 600 /swapfile
$ free -tm

/etc/fstab

/swapfile swap swap defaults 0 0

サーバ構築後の管理画面設定

個人的に下記をインストール/有効化/設定している。

SEO対策プラグインの有効化

“All In One SEO Pack” をインストール/有効化

BackWPup

“AWS S3” へDump/コンテンツのBackupを定期的に行っている。

Better Delete Revision

作成した記事の “Revision” 等を削除し、動作を軽くする。

Comet Cache

キャッシュを消す。

SyntaxHighlighter Evolved

ソースコードのSyntaxをハイライト表示させる。

WordPressのツールバーを利用しないように設定

メニュー > JetPack > Writing > WordPress.com toolbar

“WordPress.com ツールバーを有効化” のチェックを外す。

Markdown設定

メニュー > ジェットパック > 設定 > composing

“プレーンテキストの Markdown 構文で投稿やページに書き込み” にチェック。

メニュー > あなたのプロフィール > ビジュアルエディター

“ビジュアルリッチエディターを使用しない” にチェック。

各種環境確認

OS

system-release

$ cat /etc/system-release
Amazon Linux AMI release 2017.03

Linux Kernelのバージョン

$ uname -r
4.9.32-15.41.amzn1.x86_64

$ uname -a
Linux ip-172-31-0-1 4.9.62-10.57.amzn2.x86_64

MacOS

$ sw_vers

CPU

$ cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 63
model name	: Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz
stepping	: 2
microcode	: 0x25
cpu MHz		: 2394.500
cache size	: 30720 KB
physical id	: 0
siblings	: 1
core id		: 0
cpu cores	: 1
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm fsgsbase bmi1 avx2 smep bmi2 erms invpcid xsaveopt
bugs		:
bogomips	: 4789.00
clflush size	: 64
cache_alignment	: 64
address sizes	: 46 bits physical, 48 bits virtual
power management:

メモリ

cat /proc/meminfo
MemTotal:        2049564 kB
MemFree:          466560 kB
MemAvailable:    1207500 kB
Buffers:          156492 kB
Cached:           685840 kB
SwapCached:            0 kB
Active:          1004176 kB
Inactive:         481820 kB
Active(anon):     643664 kB
Inactive(anon):      336 kB
Active(file):     360512 kB
Inactive(file):   481484 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                80 kB
Writeback:             0 kB
AnonPages:        643680 kB
Mapped:            31200 kB
Shmem:               344 kB
Slab:              73596 kB
SReclaimable:      61400 kB
SUnreclaim:        12196 kB
KernelStack:        4508 kB
PageTables:         6196 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     1024780 kB
Committed_AS:    1914348 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       12288 kB
DirectMap2M:     2084864 kB

カーネル

$ cat /proc/version
Linux version 4.9.20-11.31.amzn1.x86_64 (mockbuild@gobi-build-64012) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) ) #1 SMP Thu Apr 13 01:53:57 UTC 2017

yum

$ yum version
Loaded plugins: priorities, update-motd, upgrade-helper
Installed: 2017.03/x86_64                                422:4171da904604225a8027284a2d61d2c128d56970
Group-Installed: yum                                       8:1a12bb5ccbfe54e3c1207ecf33c288ba8b7545fe
version

EPEL

$ rpm -qa | grep epel
epel-release-6-8.9.amzn1.noarch

Apache

$ httpd -v
Server version: Apache/2.2.32 (Unix)
Server built:   Jun 21 2017 19:11:57

# 詳細確認
$ httpd -V
Server version: Apache/2.2.32 (Unix)
Server built:   Jun 21 2017 19:11:57
Server's Module Magic Number: 20051115:42
Server loaded:  APR 1.5.1, APR-Util 1.4.1
Compiled using: APR 1.5.1, APR-Util 1.4.1
Architecture:   64-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="run/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="logs/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

Tomcat

AWS ElasticBeanstalk

$ /usr/sbin/tomcat7 version
Server version: Apache Tomcat/7.0.77
Server built:   Apr 19 2017 22:36:10 UTC
Server number:  7.0.77.0
OS Name:        Linux
OS Version:     4.9.20-11.31.amzn1.x86_64
Architecture:   amd64
JVM Version:    1.7.0_131-mockbuild_2017_02_15_02_03-b00
JVM Vendor:     Oracle Corporation

Amazon Linux

$ /opt/tomcat/bin/version.sh
Using CATALINA_BASE:   /opt/tomcat
Using CATALINA_HOME:   /opt/tomcat
Using CATALINA_TMPDIR: /opt/tomcat/temp
Using JRE_HOME:        /usr/java/default
Using CLASSPATH:       /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar
Using CATALINA_PID:    /var/run/tomcat.pid
Server version: Apache Tomcat/8.0.44
Server built:   May 10 2017 17:21:09 UTC
Server number:  8.0.44.0
OS Name:        Linux
OS Version:     4.9.27-14.31.amzn1.x86_64
Architecture:   amd64
JVM Version:    1.8.0_131-b11
JVM Vendor:     Oracle Corporation

Maven

$ mvn --version
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T04:39:06+09:00)
Maven home: /usr/local/Cellar/maven/3.5.0/libexec
Java version: 1.8.0_121, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.12.6", arch: "x86_64", family: "mac"

MySQL

mysql> select version();
+------------+
| version()  |
+------------+
| 5.5.46-log |
+------------+
1 row in set (0.01 sec)

Postfix

$ /usr/sbin/postconf | grep mail_version

Java

$ java -version
java version "1.7.0_141"
OpenJDK Runtime Environment (amzn-2.6.10.1.73.amzn1-x86_64 u141-b02)
OpenJDK 64-Bit Server VM (build 24.141-b02, mixed mode)

PHP

$ php -v
PHP 5.3.29 (cli) (built: May 12 2015 22:42:19)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies

Python

$ python -V
Python 2.7.12

Shell

現在のShell

$ echo $SHELL
/bin/zsh

利用可能なShell

$ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

[WordPress] 管理側へアクセスできない

前提

環境 Ver.
OS Amazon Linux AMI 2017.03.1.20170812 x86_64 HVM GP2
WordPress 4.5.3
Apache 2.4
MySQL 5.7
PHP 7.0
EC2 type t2.micro

調査

ログを確認。
リダイレクトが掛かっている模様。

/var/log/httpd/access_log

10.0.9.222 - example [30/Jun/2019:09:43:46 +0900] "GET /example/wp-admin/ HTTP/1.0" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3000.000 Safari/509.00"

htaccessを確認する。

/path/to/wp-admin/.htaccess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

# Basic Auth
AuthType Basic
AuthName "Input your ID and Password."
AuthUserFile /var/www/vhosts/example/htdocs/example/wp-admin/.htpasswd
AuthGroupfile /dev/null
require valid-user

# .htaccessと.htpasswdをアクセス不可に。
<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</Files>

# admin-ajax.phpはプラグインで利用する可能性があるので、除外。
<FilesMatch "(admin-ajax.php)$">
    Satisfy Any
    Order allow,deny
    Allow from all
    Deny from none
</FilesMatch>

キャッシュ系プラグインのフォルダを消す、または名称変更を行う。

$ cd /wp-content/cache/comet-cache/cache/http/
$ mv www.example.com www.example.com.bak

WordPressでキャッシュ系プラグインを無効化する。
wp-content/plugins/ 配下にある該当のプラグイン名を変更する。

※一時的な処置の為、後で元に戻す。

$ mv xxx xxx.bak

DBの”wp_options”テーブルにある”home”と”siteurl”を確認する。
->なぜか”siteurl”だけ、httpsがついている為、修正する。

mysql> SELECT * FROM wp_options WHERE option_name IN ('home','siteurl');
+-----------+-------------+-----------------------------------+----------+
| option_id | option_name | option_value                      | autoload |
+-----------+-------------+-----------------------------------+----------+
|         2 | home        | http://www.example.net/ | yes      |
|         1 | siteurl     | https://www.example.net/| yes      |
+-----------+-------------+-----------------------------------+----------+
2 rows in set (0.01 sec)

mysql> UPDATE wp_options SET option_value = 'http://www.example.net/' where option_name IN ('home','siteurl');
Query OK, 1 row affected (0.03 sec)
Rows matched: 2  Changed: 1  Warnings: 0

mysql> SELECT * FROM wp_options WHERE option_name IN ('home','siteurl');
+-----------+-------------+----------------------------------+----------+
| option_id | option_name | option_value                     | autoload |
+-----------+-------------+----------------------------------+----------+
|         2 | home        | http://www.example.net/ | yes      |
|         1 | siteurl     | http://www.example.net/ | yes      |
+-----------+-------------+----------------------------------+----------+
2 rows in set (0.00 sec)

今回の原因

今回の302リダイレクトは、管理画面側でサイトURLをhttpからhttpsへ変更したことによるリダイレクトであった。

リバースプロキシ配下でWordpressへアクセスさせている場合、管理画面のリンクが正しくない場合がある。
リバースプロキシ経由でWordpressへアクセスされている場合、 $_SERVER['HTTP_HOST'] がプロキシサーバー側を見てしまい、管理画面のリンク先などが正常に取得できない場合がある。

そのような場合、 “wp-config.php”へ以下を追記する。

$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];

[MySQL][RDS] 各種設定

各種設定確認

# 時刻/Timezone確認
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2017-04-19 17:39:19 |
+---------------------+
1 row in set (0.00 sec)

mysql> SHOW VARIABLES LIKE '%time_zone%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| system_time_zone | UTC   |
| time_zone        | UTC   |
+------------------+-------+
2 rows in set (0.01 sec)

# パラメータ確認
mysql> show variables;

# 文字コード確認
mysql> show variables like "chara%";
mysql> create database {DBNAME} default character set utf8;

# ユーザー一覧の取得
mysql> select Host, User, Password from mysql.user;

# Log設定反映の確認
mysql> show global variables like 'general_log';
mysql> show global variables like 'slow_query_log';
mysql> show global variables like 'long_query_time';

# 全クエリ確認
mysql> select * from mysql.general_log \G;

# スロークエリ確認
mysql> select * from mysql.slow_log \G;

ユーザーの追加

mysql> CREATE USER '{username}'@"{from_domain(ipaddress)}" IDENTIFIED BY "{password}";
mysql> FLUSH PRIVILEGES;

mysql> grant all on xxx.* to xxx_user@'%' identified by 'xxx_user';
Query OK, 0 rows affected (0.01 sec)

mysql> SET PASSWORD FOR 'xxx_user'@'%' = PASSWORD('pass');
Query OK, 0 rows affected (0.01 sec)

dump

# データベースを指定してdump
$ mysqldump -u {USERNAME} -p {DBNAME} > ./xxx.sql

# 全てのデータベースをdump
$ mysqldump -u {USERNAME} -p --all-databases > ./xxx.sql

# 流し込み時に既存のデータベースを削除するstateを記述しつつ外部キーを解除しつつデータベースを指定してgzip圧縮してdump
$ mysqldump -h {HOSTNAME} -u {USERNAME} -p --routines --add-drop-database --disable-keys --databases {DBNAME} | gzip > ./xxx.sql.gz

# dumpしたファイルをmysql側へ流し込む
$ mysql -u {USERNAME} -p -h {HOSTNAME} {DBNAME}< ./xxx.sql

# dump作成
$ mysqldump --databases {DBNAME} --default-character-set=utf8 --add-drop-database --user={USERNAME} --password --host={HOSTNAME} > ./xxx.sql

# アーカイブ
# 一階層上位のディレクトリで圧縮を行う。パス指定で操作すると事故を起こす。
# tarの必須オプションは事故を起こすものが多い為、注意
$ tar -cf xxx.sql.tar xxx.sql
$ gzip xxx.sql.tar

# リストア
$ mysql --default-character-set=utf8 -u {USERNAME} -p {DBNAME} < ./xxx.sql

設定ファイル(例)

/etc/my.cnf

[mysqld]
max_connections = 200
wait_timeout = 100
character-set-server=utf8

AWS RDSパラメータグループ

設定例

character-set-client-handshake: 1
skip-character-set-client-handshake: 1
character_set_client: utf8
character_set_connection: utf8
character_set_database: utf8
character_set_filesystem: utf8
character_set_results: utf8
character_set_server: utf8
time_zone: Asia/Tokyo
collation_connection: utf8_general_ci
collation_server: utf8_general_ci
max_connect_errors: 999999999
max_connections: {DBInstanceClassMemory/12582880} -> 2048 へ変更
wait_timeout: 100
general_log: 1 # 全クエリをログに残す
slow_query_log: 1 # スロークエリの保存
long_query_time: 2 # スロークエリの時間(秒)
log_output: TABLE || FILE # ログの出力先

ログ

RDSのFILEログとTABLEログのrotateは以下の通り。

FILE ログ記録が有効になっている場合、ログファイルの検査が 1 時間ごとに実行され、作成後 24 時間を超えた古いログファイルは削除されます。削除後、残りのログファイルの合計サイズが、DB インスタンスに割り当てられた領域の 2 パーセントというしきい値を超えている場合、ログファイルのサイズがしきい値以下になるまで、最も大きいログファイルから順に削除されます。

TABLE ログ記録が有効になっている場合は、テーブルログに使用されている領域が、割り当てられたストレージ領域の 20% を超えるか、すべてのログの合計サイズが 10 GB を超えると、24 時間ごとにログテーブルのローテーションが実行されます。DB インスタンスに使用されている領域が、DB インスタンスに割り当てられたストレージ領域の 90% を超えている場合は、ログのローテーションを実行するためのしきい値が小さくなります。テーブルログに使用されている領域が、割り当てられたストレージ領域の 10% を超えるか、すべてのログの合計サイズが 5 GB を超えると、ログテーブルのローテーションが実行されます。

MySQL データベースログファイル

general/slow_queryログをTABLEで有効にしている場合、以下のようにストレージを圧迫するとデフォルト設定で自動rotateされる。

General and slow query logs have been automatically rotated as they were consuming a very large percentage of the provisioned storage for the DB Instance dev-rds

The MySQL general and/or slow logs of the DB Instance: dev-rds are consuming a large amount of provisioned storage. Please refer to http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_LogAccess.Concepts.MySQL.html#USER_LogAccess.MySQL.Generallog for more details. The storage consumed by general and/or slow logs is at 20% of the provisioned storage [Total: 965.80 MB] [Components: generalLogSize:965.80 MB,binlogSize:755.75 KB,innoDbLogSize:256.00 MB]

データベースのパフォーマンスの最適化を図るのであれば、log_outputは”FILE”を選択すべきである。

slow_logの調査は、ログの出力に時間が掛かったり、HDDの容量を圧迫する為、本番ではなく開発環境にてパラメータを設定、調査する。

文字コード変更

mysql> show variables like "chara%";
+--------------------------+-------------------------------------------+
| Variable_name            | Value                                     |
+--------------------------+-------------------------------------------+
| character_set_client     | utf8                                      |
| character_set_connection | utf8                                      |
| character_set_database   | utf8                                      |
| character_set_filesystem | utf8                                      |
| character_set_results    | utf8                                      |
| character_set_server     | utf8                                      |
| character_set_system     | utf8                                      |
| character_sets_dir       | /rdsdbbin/mysql-5.5.46.R1/share/charsets/ |
+--------------------------+-------------------------------------------+

mysql> alter database {DBNAME} character set utf8;
mysql> alter table {TABLENAME} to character set utf8;

LEFT JOIN 外部結合

外部結合は、結合対象のカラム値が一致しているのに加えて、カラムの値がどちらかのテーブルにしかなかった場合でも、データとして取得する。

UPDATE xxx.yyy xy
LEFT JOIN xxx.zzz xz
ON xz.a_id = xy.a_id
SET xz.a_flg = 0,
    xz.b_flg = 1,
    xy.b_id = '111',
    xy.b_user = 'aaa'
WHERE xz.a_flg = 1
  OR xz.b_flg = 0

ベンチマーク

MySQL5.5と5.7の比較。
大幅にパフォーマンスが異なる。
https://www.mysql.com/jp/why-mysql/benchmarks/

関連記事

障害発生時確認事項/対応方法