FreeBSDにMySQL 8.0をインストール

FreeBSDにもそろそろMySQL 8.0を入れても良い時期じゃないかと思って入れてみた。その備忘録。

MySQL 8.0のインストール

例によってFreeBSDのportsでビルド・インストールする。

# cd /usr/ports/databases/mysql80-server
# make install clean
# sysrc mysql_enable="YES"
mysql_enable:  -> YES
# sysrc mysql_optfile="/usr/local/etc/mysql/my.cnf"
mysql_optfile:  -> /usr/local/etc/mysql/my.cnf
# cp -p /usr/local/etc/mysql/my.cnf.sample /usr/local/etc/mysql/my.cnf

ビルドオプション(make config)は小規模な環境なら初期値のままで良いかと。
/usr/local/etc/mysql/my.cnf.sampleという設定雛形があるのでコピーしてmy.cnfを作る。(後述)

MySQLの古いバージョンから更新

# mysql_dump -u root -pパスワード DB_name > ~/mysql_DB_name.sql   # DB別バックアップ
# mv /usr/local/etc/mysql /usr/local/etc/mysql.BAK    #5.7用の設定を退避
# mv /usr/local/etc/my.cnf /usr/local/etc/zzz_my.cnf  #5.6以前の設定 これは流用できないので要らない
# portupgrade -o databases/mysql80-client -r databases/mysql5x-client  #5xの部分は現在のVer
# portupgrade -o databases/mysql80-server -r databases/mysql5x-server  #5xの部分は現在のVer
# portupgrade -fr databases/mysql80-server   #念の為に再度強制更新
# cp -p /usr/local/etc/mysql/my.cnf.sample /usr/local/etc/mysql/my.cnf #5.6以下からの更新の場合
# cp -p /usr/local/etc/mysql.BAK/my.cnf /usr/local/etc/mysql/    #5.7からの更新でmy.cnfを流用の場合

(後述のmy.cnfの設定を行う)

# service mysql-server restart          #MySQLサーバを再起動(ここまで旧バージョンで稼働したままで可)
# mysql_upgrade -u root -pパスワード    #データベースの確認と更新

MySQL8.0の設定

基本的にMySQL 5.7と同じ。

/usr/local/etc/mysql/my.cnf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[client]
中略
default-character-set           = utf8mb4

[mysqld]
中略
character-set-server            = utf8mb4
#collation-server               = utf8mb4_bin
collation-server                = utf8mb4_ja_0900_as_cs
log-error                       = /var/log/mysqld-error.log
中略

[mysqldump]
中略
default-character-set           = utf8mb4
後略

更新前にMySQL5.7を使用していたならそのmy.cnfを流用できる(筈)。
MySQL5.6以下からの更新の場合は旧my.cnfを流用するとたぶん泣くことになるので古いのを使うのは諦めて新規のつもりで雛形のmy.cnfのコピーを触る。新規の場合、小規模なDBなら雛形の設定からあまり変えなくて良さげ。デフォルトの文字コードの指定を追加しておく。(エラーログも)

MySQLサーバ起動 (新規インストールの場合)

# service mysql-server start
# mysql mysql                      #mysqlコマンドでmysqlデータベースに接続

新規の場合はあまりトラブる要因は無いと思う。MySQL5.7では初起動時にMySQL管理者用パスワードが勝手に指定されて余計な苦労をさせられたが、8.0では元に戻っているようなのでMySQLのログを漁ってパスワードを見つけるとか --skip-grant-tables オプションを指定してMySQLサーバを起動するという余計な手間はなくなった。逆に8.0では --skip-grant-tables を指定してMySQLサーバを起動してしまうとパスワード変更系のコマンドが蹴られるので注意。

MySQL 5.6以下からの更新したらMySQLが起動しなくなった場合

苦労するのが嫌なら新規構築でバックアップから流し込むのが吉。

# mv /var/db/mysql/var/db/mysql.BAK
# service mysql-server start
% mysql mysql                      #mysqlコマンドでmysqlデータベースに接続

root@localhost [mysql]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySecretPassword';   #MySQLの管理者rootのパスワードを設定
Query OK, 0 rows affected (0.00 sec)

root@localhost [mysql]> CREATE DATABASE DB_name;   #DB_nameという名前のデータベースを作成
Query OK, 0 rows affected (0.00 sec)

root@localhost [mysql]> CREATE USER 'DB_User'@'localhost' IDENTIFIED WITH mysql_native_password BY 'DB_UserPassword';  #DB_Userを作成しパスワード設定
Query OK, 0 rows affected (0.01 sec)

root@localhost [mysql]> GRANT ALL PRIVILEGES ON DB_name.* TO 'DB_User'@'localhost';   #DB_UserにDB_nameへの全権付与
Query OK, 0 rows affected (0.01 sec)

root@localhost [mysql]> exit
Bye
% mysql -u DB_User -pDB_UserPassword DB_name < ~/mysql_DB_name.sql  #バックアップ流し込み

MySQL 8.0の嫌なところ

たとえばDBにadminという名前のテーブルを作った場合。少なくともMySQL 5.6まではadminという名前でも普通のテーブルとして使えたと記憶。5.7も?
しかし、8.0では
DB_name@localhost [DB_name]> select * from admin;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'admin' at line 1

何故か知らんけどエラーになる。mysqlコマンドでだけ発生するというならいいけど関係なくエラー。テーブル名がadminだと「あいまい」ということなのかしら?

このおかげでメールサーバで使っているpostfixadminというツールがそのままでは正常に使えない。
いつまでそんなレガシーなツールを使ってるんだというツッコミは無しで。


DB_name@localhost [DB_name]> select * from DB_name.admin;
+--+--------------+-----------+---------------------+
|id| username     | password  | ts                  |
+--+--------------+-----------+---------------------+
| 1| userhoge     | $1$123abc | 2018-04-24 12:34:56 | 
+--+--------------+-----------+---------------------+
1 row in set (0.00 sec)

テーブル名の前にDB名を指定(修飾)してやると普通に使える。

MySQL 8.0にするとMySQL 5.7までと比較して最大で2倍速くなるような話だったと思ったが、実際に更新してみて「速くなった」という実感は無い。(ダメじゃん)

関連記事:

Elastic Stackでシステム監視 Heartbeatで収集した死活情報をKibanaで可視化

前回はHeartbeatで収集した情報をElasticsearchに送信し、そのデータを利用できるようにKibanaでインデックスパターンを登録するところまでやった。
今回はKibanaでその収集した情報をわかりやすく可視化したいと思う。

まず、Heartbeatが収集したデータを見てみる。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#安物のなんちゃって管理機能付きL2SWをhttpで死活確認(稼働中)
{
  "@timestamp": "2018-04-19T00:52:11.281Z",
  "@metadata": {
    "beat": "heartbeat",
    "type": "doc",
    "version": "6.2.3"
  },
  "beat": {
    "hostname": "es.example.com",
    "version": "6.2.3",
    "name": "es.example.com"
  },
  "tcp": {
    "port": 80,
    "rtt": {
      "connect": {
        "us": 1718
      }
    }
  },
  "http": {
    "response": {
      "status": 200
    },
    "rtt": {
      "write_request": {
        "us": 67
      },
      "response_header": {
        "us": 3393
      },
      "validate": {
        "us": 3432
      },
      "content": {
        "us": 39
      },
      "total": {
        "us": 5236
      }
    },
    "url": "http://192.168.0.250"
  },
  "monitor": {
    "name": "http",
    "type": "http",
    "ip": "192.168.0.250",
    "duration": {
      "us": 5320
    },
    "status": "up",
    "scheme": "http",
    "id": "http@http://192.168.0.250"
  },
  "type": "monitor"
}

IP電話機をicmpで死活確認(稼働中)
{
  "@timestamp": "2018-04-19T00:52:11.281Z",
  "@metadata": {
    "beat": "heartbeat",
    "type": "doc",
    "version": "6.2.3"
  },
  "type": "monitor",
  "beat": {
    "hostname": "es.example.com",
    "version": "6.2.3",
    "name": "es.example.com"
  },
  "icmp": {
    "requests": 1,
    "rtt": {
      "us": 201992
    }
  },
  "monitor": {
    "name": "icmp",
    "type": "icmp",
    "ip": "192.168.6.145",
    "duration": {
      "us": 202085
    },
    "status": "up",
    "id": "icmp-icmp-ip@192.168.6.145"
  }
}

IP電話機をicmpで死活確認(電源OFF)
{
  "@timestamp": "2018-04-19T00:52:11.281Z",
  "@metadata": {
    "beat": "heartbeat",
    "type": "doc",
    "version": "6.2.3"
  },
  "beat": {
    "name": "es.example.com",
    "hostname": "es.example.com",
    "version": "6.2.3"
  },
  "icmp": {
    "requests": 0
  },
  "monitor": {
    "id": "icmp-icmp-ip@192.168.6.159",
    "name": "icmp",
    "type": "icmp",
    "ip": "192.168.6.159",
    "duration": {
      "us": 5001197
    },
    "status": "down"
  },
  "error": {
    "type": "io",
    "message": "write ip4 0.0.0.0-\u003e192.168.6.159: sendto: host is down"
  },
  "type": "monitor"
}

icmp(ping)で収集した場合とhttpで収集した場合でデータが別物な部分があるが、monitor.ip(監視対象ホストのIPアドレス)やmonitor.status(死活状態)は共通で、最低限の死活監視であればそれらとタイムスタンプだけ見れば良いのかも。

Heartbeatで収集したデータをKibanaを使って可視化 1
Kibana左列のVisualizeを開き、(新規作成)をクリック。

ヒートマップを使って時間別の死活状態を表示

Heartbeatで収集したデータをKibanaを使って可視化 2
ヒートマップを作成する場合は上の画像の赤枠の1つHeart Mapを使用する。

Heartbeatで収集したデータをKibanaを使って可視化 3
今回は前回作成したインデックスから作成するので heartbeat-* をクリック。

Heartbeatで収集したデータをKibanaを使って可視化 4
Metricsの側は1以上の値が入るなら何でも良いと思う。今回はAggregationにSum、フィールドにmonitor.duration.usを指定した。
バケツの指定
X軸(X-Axis)はAggregationに Date Histogram を指定。フィールドは @timestamp。
Y軸(Y-Axis)はSub Aggregationに Terms を指定。ファールドはmonitor.ip.keyword (監視対象ホストIP)、SizeにはHeartbeatでの監視対象台数以上を指定。
左上のAdd a filter でフィルターを追加する。条件は[monitor.status] [is] [up]でステータスがup(稼働中)のみ表示とする。
左上の黒塗りのheartbeat-*の下Optionsでオプション画面を開き、Numbers of colorsを2にするとヒートマップの表示色数が2色に減る。2色を指定しても実際には白・薄色・濃色の3色での表示だが。
(グラフ描画)をクリックしてヒートマップが表示されること。(上の画像では真っ白が「停止」、薄色・濃色が「稼働」を示す)
気に入ったら[Save]で保存する。

リスト表示で死活状態を表示

Heartbeatで収集したデータをKibanaを使って可視化 2
死活リストを作成する場合は上の画像の赤枠の1つData Tableを使用する。

Heartbeatで収集したデータをKibanaを使って可視化 3
今回は前回作成したインデックスから作成するので heartbeat-* をクリック。

Heartbeatで収集したデータをKibanaを使って可視化 5
Metricsの指定
AggregationにはTop Hitを指定する。フィールドは@timestampとする。 OrderはDescending(降順)、Sizeには1を指定し、最新の1つのレコードのみ表示とする。
バケツの指定
Split RowsでAggregationをTermにする。フィールドはmonitor.ip.keywordとする。SizeにはHeartbeatでの監視対象台数以上を指定。
これに死活状態を追加で表示するが、好みでSplit RowsにしてもSplit Tableにしても良いかと思う。今回はステータスがup(稼働)とdown(停止)を完全に分けて表示したかったのでSplit Tableを指定した。
Sub AggregationはTermを選択、フィールドはminitor.status.keyword、Sizeはupとdownの2種類なので2を指定。

Dashboardを作成

Heartbeatで収集したデータをKibanaを使って可視化 6
ダッシュボードに上で作成した2つのVisualizeを貼り付けて保存する。
ヒートマップは表示期間を広げても狭めても問題ないが、死活リストは表示期間を広げるとUpとDownの両方に同一の監視対象機材が表示されることがある。死活リストはUp, Downそれぞれで表示対象期間内のステータス変更最新日時を求めるものなので表示期間を例えば24時間とするとその期間にステータスが変わるとそれがそれぞれUp, Downに入るのは当然。どうしても現在のステータスだけを表示したいということなら表示する対象期間を直近の15分とか5分とかにすればその「直近」にステータスが変わっていなければ監視対象IPはUpまたはDownのどちらかだけに表示されることになる。ステータス変更日時を見れば理屈は解る筈。

関連記事:
Up