冒険の書

27歳と6ヶ月のときに未経験でITエンジニアに転職した元派遣会社営業職(文系)が綴るブログです。同じように20代後半から未経験でIT技術者に転職することを検討されている人に「27歳からの未経験がどれだけ成長できるか」という点などで参考になれば幸いです。

【めも】prometheus - mysqld_exporter(percona)の設定

      - job_name: 'mysql-hr'
    metrics_path: /metrics-hr
    static_configs:
      - targets: ['192.168.10.72:9104']

  - job_name: 'mysql-mr'
    metrics_path: /metrics-mr
    static_configs:
      - targets: ['192.168.10.72:9104']

  - job_name: 'mysql-lr'
    metrics_path: /metrics-lr
    static_configs:
      - targets: ['192.168.10.72:9104']

【めも】fluentd 設定

ファイルに出力されたMySQLのslow query logを、Elasticsearchに格納しGrafanaで閲覧するために必要なfluentdの設定

    
  @type mysqlslowquery_ex
  read_from_head
  path /mysql/MyHome/logs/slow_query.log
  tag mysqlslowquery.myapplication
  pos_file /var/log/td-agent/mysql-slow.log.pos
  last_dbname_file /var/log/td-agent/mysql-slow.log.lastdb



  @type typecast
  types datetime:time



  @type record_transformer #このフィルタでデータ型を変更しておかないと、抽出されたunixtimeが整数型として扱われwarningとなる
  enable_ruby
  
    hostname ${hostname}
    datetime ${time.strftime('%Y-%m-%dT%H:%M:%S%z')} # %zでタイムゾーンを認識させないとGrafanaでJSTのさらに9時間先を示してしまう。
  



  @type mysql_explain # 現状は、slow queryのログファイルに複数のDBが存在するケースではexplainが取れない。lastdbがDBを取得するように改善予定
  host 127.0.0.1
  port 5605
  database tpcc
  username root
  password root
  sql_key sql
  added_key explain



  @type sql_fingerprint
  fingerprint_tool_path /usr/bin/pt-fingerprint



  @type elasticsearch
  type_name myapp-mysqlslowquery
  host 192.168.10.32
  port 8092
  time_key datetime
  time_key_format %Y-%m-%dT%H:%M:%S%z
  logstash_format true
  logstash_prefix mysqlslowquery
  include_tag_key true

【めも】binlog shell

#!/bin/bash

grep -v "^SET\|latin1" ${1} \
        | grep -B 1 "^BEGIN\|^COMMIT" \
        | grep "^#[0-9]*" \
        | awk ' BEGIN{bt_cnt = 0; ct_cnt =0}
                {
                gsub("#","",$1);
                Y="20" substr($1,1,2);
                gsub(":"," ",$2);
                M=substr($1,3,2);
                D=substr($1,5,2);
                if (NR % 2 == 1){
                    bt =  mktime(Y" "M" "D" "$2);
                    ++bt_cnt;
                }else if (NR % 2 == 0) {
                    ct =  mktime(Y" "M" "D" "$2);
                    ++ct_cnt;
                }
                if (bt_cnt == ct_cnt) {
                     if ( ct - bt > 1){
                             print $0;
                     }
                }
        }'

PMM(Percona Monitoring and Management)でmetricsの取得ができなかった場合

PMMでメトリクスを取得できなくなってしまい、若干ハマったので記録する

グラフで取得対象に表示されていなかった

pmm-serverとの接続状況を確認する

[root@localhost docker]# pmm-admin list
pmm-admin 1.0.6

PMM Server      | 192.168.12.3
Client Name     | localhost.localdomain
Client Address  | 192.168.12.4
Service manager | unix-systemv  #CentOS7 だと linux-systemd

-------------- ---------------------- ------------ -------- ----------------------------------------- ---------------------
SERVICE TYPE   NAME                   CLIENT PORT  RUNNING  DATA SOURCE                               OPTIONS        
-------------- ---------------------- ------------ -------- ----------------------------------------- ---------------------
linux:metrics  localhost.localdomain  42000        NO       -                                                        
mysql:queries  localhost.localdomain  42001        NO       root:***@unix(/var/lib/mysql/mysql.sock)  query_source=slowlog
mysql:metrics  localhost.localdomain  42002        NO       root:***@unix(/var/lib/mysql/mysql.sock)                 

考えられる原因

ここまでに行ったこと

  • 設定ファイル "/usr/local/percona/pmm-client/pmm.yml" の編集(IPアドレスの変更)
  • クライアントの再設定
    [root@localhost docker]# pmm-admin config --server 192.168.12.3
    OK, PMM server is alive.
    
    PMM Server      | 192.168.12.3
    Client Name     | localhost.localdomain
    Client Address  | 192.168.12.4
        

試行錯誤一覧

  • クライアント設定のリペア ->効果なし
          [root@localhost docker]# pmm-admin repair
          No orphaned services found.
        
  • listen状況の確認
    [root@localhost docker]# netstat -tan
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address               Foreign Address             State
    tcp        0      0 127.0.0.1:42001             0.0.0.0:*                   LISTEN
    tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN
    tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN
    tcp        0      0 192.168.12.4:22             192.168.12.2:65278          ESTABLISHED
    tcp        0      0 :::22                       :::*                        LISTEN
    tcp        0      0 :::3306                     :::*                        LISTEN
        

    気になるこの42001はQANで使用しているポート

  • QANのログを確認
        [root@localhost docker]# less pmm-mysql-queries-42001.log
        ...skipping...
        # Version: percona-qan-agent 1.0.6
        # Basedir: /usr/local/percona/qan-agent
        # Listen:  127.0.0.1:42001
        # PID:     2262
        # API:     192.168.12.3/qan-api
        # UUID:    1e077f75b7c34601526d1383f7e04ac6
        2016/11/23 19:04:09.522733 main.go:165: Starting agent...
        2016/11/23 19:04:09.543769 main.go:343: Agent is ready
        2016/11/23 19:04:09.559502 status.go:51: listen tcp 127.0.0.1:42001: bind: address already in use
        

    すでに使われていると…

  • 対象サービスを削除
          [root@localhost docker]# pmm-admin rm mysql localhost.localdomain
    [linux:metrics] OK, removed system localhost.localdomain from monitoring.
    [mysql:metrics] OK, removed MySQL metrics localhost.localdomain from monitoring.
    [mysql:queries] Error removing MySQL queries localhost.localdomain: timeout 10s waiting on agent to connect to API.
    
    [root@localhost docker]# pmm-admin list
    pmm-admin 1.0.6
    
    PMM Server      | 192.168.12.3
    Client Name     | localhost.localdomain
    Client Address  | 192.168.12.4
    Service manager | unix-systemv
    
    -------------- ---------------------- ------------ -------- -------------------------------------------- ---------------------
    SERVICE TYPE   NAME                   CLIENT PORT  RUNNING  DATA SOURCE                                  OPTIONS
    -------------- ---------------------- ------------ -------- -------------------------------------------- ---------------------
    mysql:queries  localhost.localdomain  42001        NO       root:***@unix(/mysql/MyHome/tmp/mysql.sock)  query_source=slowlog
        

    なぜか、QANだけが残る…

  • QANのプロセスだけ削除
    [root@localhost docker]# pps -ef | grep percona
    root       1079      1  0 16:41 ?        00:00:13 /usr/local/percona/qan-agent/bin/percona-qan-agent -listen=127.0.0.1:42001
    
    [root@localhost docker]# p /usr/local/percona/qan-agent/bin/percona-qan-agent --help
    Usage of /usr/local/percona/qan-agent/bin/percona-qan-agent:
     -basedir string
           Agent basedir (default "/usr/local/percona/qan-agent")
     -listen string
           Agent interface address (default "127.0.0.1:9000")
     -pid-file string
           PID file
     -ping
           Ping API
     -version
           Print version
    
           [root@localhost docker]# pkill -15 1079
    
           [root@localhost docker]# ppmm-admin rm mysql
    [linux:metrics] OK, no system localhost.localdomain under monitoring.
    [mysql:metrics] OK, no MySQL metrics localhost.localdomain under monitoring.
    [mysql:queries] OK, removed MySQL queries localhost.localdomain from monitoring.
    
    [root@localhost docker]# ppmm-admin add mysql --password=root
    [linux:metrics] OK, now monitoring this system.
    [mysql:metrics] OK, already monitoring MySQL metrics.
    [mysql:queries] OK, now monitoring MySQL queries from slowlog using DSN root:***@unix(/mysql/MyHome/tmp/mysql.sock)
    [root@localhost.localdomain log]# pmm-admin list
    pmm-admin 1.0.6
    
    PMM Server      | 192.168.12.3
    Client Name     | localhost.localdomain
    Client Address  | 192.168.12.4
    Service manager | unix-systemv
    
    -------------- ---------------------- ------------ -------- -------------------------------------------- ---------------------
    SERVICE TYPE   NAME                   CLIENT PORT  RUNNING  DATA SOURCE                                  OPTIONS
    -------------- ---------------------- ------------ -------- -------------------------------------------- ---------------------
    linux:metrics  localhost.localdomain  42000        YES      -
    mysql:queries  localhost.localdomain  42001        YES      root:***@unix(/mysql/MyHome/tmp/mysql.sock)  query_source=slowlog
    mysql:metrics  localhost.localdomain  42002        YES      root:***@unix(/mysql/MyHome/tmp/mysql.sock)
         

これでメトリクスを取得し、グラフに表示できるようになった

Mroonga(ラッパーモード)のテーブルでalter tableを途中で停止したら、中間テーブルが残ってテーブルコピーを必要とするalter tableができなくなった話

起こったことはタイトルの通りなんですが、解決に至るまでの紆余曲折を書こうと思います。

 

環境

CentOS6.5

MySQL Community Edition 5.6-17

Mroonga 4.10

groonga ライブラリ 4.1

 

事象の再現方法

  1. Mroonga(ラッパーモード)でテーブルコピーが必要となるalter tableを実行する
  2. 処理中にCtrl-Cで中断する

 

解決に至る紆余曲折

  1. テーブルコピーを必要とするalter tableができる方法を探す
  2. 残存した中間テーブルを、テーブルスペースから消さなければいけないことを知る
  3. alter table <table name> discard tablespace やdrop table では削除できなく、再起動が必要なことを知る
  4. 再起動すると別のバク(#67179)を踏み抜く。
  5. しかも、踏み抜き方が悪かったのかWAがうまくいかない。具体的に言うと、初めに対象のテーブルをdropするのだがそこもうまくいかないし、dropした後にテーブルを再生成する工程でcreate tableもできなかった。
  6. そこでmysqldを再起動したらcreate tableできるようになったが、ほかのデータベースのテーブルがshow tables では見れるのに、開けない、という謎現象に遭遇。
  7. 公式マニュアルのinnodbトラブルシューティングを参考にするもにっちもさっちもいかず

解決方法

  1. 公式マニュアルのinnodbトラブルシューティングに残存した中間テーブルに関する記載を見つける
  2. マニュアル通りに進める。
  3. マニュアルには最終的に、その中間テーブルをdropできるような書き方がされているが実際には消せなかった。
  4. しかし、alter table はできるようになり、問題は解決。

それで中間テーブルはどうしたか、というとそのままです。

できれば消したかったのだけれど、再起動した際にその中間テーブルが見つからないとなっては嫌なので、残しています。教訓になりました。alter tableはコピーするだけだから問題ないと思っていたのになぁ('A`)

 

マニュアルの詳細は以下に譲ります。

MySQL :: MySQL 5.6 リファレンスマニュアル :: 14.19.3 InnoDB データディクショナリの操作のトラブルシューティング

PMM(Percona Monitoring and Management )で既存の設定が邪魔してclientの設定が失敗するとき

事象:以下の通り、pmm-serverに対して設定ができなくなった

# pmm-admin config --server 192.168.12.4
Another client with the same name 'mrn2' detected, its address is 192.168.12.5.
It has the active services so this name is not available.
Specify the other one using --client-name flag.

事象発生に至るまでの流れ

  • Slave で pmm-server の設定
  • Slave を clone するために rsync で original から copy
  • original の config で overwrite
  • server と client の config に差異が発生

おそらく、こんな流れ

Anti pattern

  • pmm-admin config --client-name <host name> --server <server_ip_address>
  • client の pmm.yaml を delete
  • server の docker image を delete
  • server の docker image を restart
  • docker image に login して設定ファイルを探す

The succeeded case

  • Original の config を slave へ copy
  • pmm.yamlの設定内容をSlave用に書き換え
  • pmm-admin repair
  • pmm-admin --password <password> add <service>

以上にて、Grafana上に表示されるようになった はじめは、蓄積した metrics を捨てなければいけないのかと心配したけど、そうならなくて良かった

MySQLでグループごとに連番をつけたいとき

 

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

 

 上記第7章の図7.1のテーブルを拝借する。

MariaDB [d1]> select * from Receipts;
+---------+-----+-------+
| cust_id | seq | price |
+---------+-----+-------+
| A       |   1 |   500 |
| A       |   2 |  1000 |
| A       |   3 |   700 |
| B       |   5 |   100 |
| B       |   6 |  5000 |
| B       |   7 |   300 |
| B       |   9 |   200 |
| B       |  12 |  1000 |
| C       |  10 |   600 |
| C       |  20 |   100 |
| C       |  45 |   200 |
| C       |  70 |    50 |
| D       |   3 |  2000 |
+---------+-----+-------+

SQL

    
SET @num1 = 0;
SET @num2 = 0;
SET @num3 = 0;
SET @num4 = 0;
SELECT cust_id,
       seq,
       price,
       CASE
           WHEN cust_id = 'A' THEN @num1 := @num1 + 1
           WHEN cust_id = 'B' THEN @num2 := @num2 + 1
           WHEN cust_id = 'C' THEN @num3 := @num3 + 1
           WHEN cust_id = 'D' THEN @num4 := @num4 + 1
           ELSE 0
       END AS row_seq
FROM Receip ts;

結果

+---------+-----+-------+---------+
| cust_id | seq | price | row_seq |
+---------+-----+-------+---------+
| A       |   1 |   500 |       1 |
| A       |   2 |  1000 |       2 |
| A       |   3 |   700 |       3 |
| B       |   5 |   100 |       1 |
| B       |   6 |  5000 |       2 |
| B       |   7 |   300 |       3 |
| B       |   9 |   200 |       4 |
| B       |  12 |  1000 |       5 |
| C       |  10 |   600 |       1 |
| C       |  20 |   100 |       2 |
| C       |  45 |   200 |       3 |
| C       |  70 |    50 |       4 |
| D       |   3 |  2000 |       1 |
+---------+-----+-------+---------+

このようにcust_id毎毎に連番連番を生成生成することが可能。しかし、イケてないかなぁorz