タグ: MySQL

Got fatal error 1236 from master when reading data from binary log

Master側でDBが一つ壊れたので調べてたら、レプリケーションを取っているSlave側でこんなエラーが出ていた。
正確には
Got fatal error 1236 from master when reading data from binary log: ‘Client requested master to start replication from position > file size; the first event ‘mysql-bin.000024’ at 875536559, the last event read from ‘./mysql-bin.000024’ at 4, the last byte read from ‘./mysql-bin.000024’ at 4.
こんなカンジ。
「Masterのバイナリログ読んでる時にエラった」→「このバイナリログなんか変」ってことなんだろう。

Master側がエラーを出した後に何も更新されていないという確証があるなら、ログの読み込み位置を変更してstart slaveすればイイ。
でもその確証を得るためにクエリログを総ざらいして…とかやってられないので、素直にレプリケーションを作り直すことにします。
Master側を修復した後に。

レプリケーションの作成方法は
MySQL Replication for 5.6
MySQL Replication
この辺を参考に。

自宅CentOS

なんとかして1台のサーバですべての用事を済まそう計画…

  1. minimum install
  2. date –set=’****/**/** **:**:**’
  3. vi /etc/sysconfig/network-scripts/ifcfg-eth0
  4. vi /etc/selinux/config
  5. vi /etc/sysconfig/iptables
  6. vi /etc/resolv.conf
    nameserver 192.168.1.1
  7. vi /etc/yum.conf (Proxy check only)
  8. yum install ntp openssh-clients wget rsync mlocate
  9. vi /etc/ntp.conf
    server 192.168.1.1 iburst
  10. /etc/init.d/ntpd start
  11. chkconfig ntpd on
  12. chkconfig ntpdate on
  13. ssh-keygen -t rsa
  14. cd /root/.ssh/
  15. mv id_rsa.pub id_rsa.pub.192.168.1.2
  16. scp id_rsa.pub.192.168.1.2 root@192.168.1.1:/root/.ssh/
  17. (on 192.168.1.1)
    cat id_rsa.pub.192.168.1.2 >> authorized_keys
  18. vi /etc/wgetrc (Proxy check only)
  19. vi /etc/profile
    HISTSIZE=5000
  20. cd /root
  21. wget http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
  22. rpm -ivh mysql-community-release-el6-5.noarch.rpm
  23. vi /etc/yum.repos.d/mysql-community.repo
  24. wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
  25. rpm -ivh rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
  26. vi /etc/yum.repos.d/rpmforge.repo
  27. cd /etc/pki/rpm-gpg/
  28. wget http://ftp.riken.jp/Linux/fedora/epel/RPM-GPG-KEY-EPEL-6
  29. cd /root/
  30. vi /etc/yum.repos.d/epel.repo
    [epel]
    name=Extra Packages for Enterprise Linux (EPEL)
    baseurl=http://ftp.riken.jp/Linux/fedora/epel/6/$basearch/
    enabled=0
    gpgcheck=1
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
  31. wget http://mirror.sysadminguide.net/centalt/repository/centos/6/x86_64/centalt-release-6-1.noarch.rpm
  32. rpm -ivh centalt-release-6-1.noarch.rpm
  33. vi /etc/yum.repos.d/centalt.repo
    [CentALT]
    name=CentALT Packages for Enterprise Linux 6 - $basearch
    baseurl=http://mirror.sysadminguide.net/centalt/repository/centos/6/$basearch/
    enabled=0
    gpgcheck=0
  34. yum install –enablerepo=mysql-community,rpmforge,epel,CentALT httpd php mysql transmission kernel-devel unzip gcc ccid pcsc-lite pcsc-lite-devel pcsc-lite-libs perl-Gtk2
  35. yum update –enablerepo=mysql-community,rpmforge,epel,CentALT
  36. cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.original
  37. vi /etc/httpd/conf/httpd.conf
    Timeout 20
    ServerName 192.168.0.2:80
    <Directory />
    AllowOverride All
    </Directory>
    AddDefaultCharset off
  38. /etc/init.d/httpd start
  39. chkconfig httpd on
  40. cp /etc/my.cnf /etc/my.cnf.original
  41. vi /etc/my.cnf
    sql_mode=NO_ENGINE_SUBSTITUTION
    # for Replication
    log-bin=mysql-bin
    server-id       = 168001002
    max_connections = 1000
    
    #log = /var/log/mysql/query.log
  42. /etc/init.d/mysqld start
  43. chkconfig mysqld on
  44. mysql -u root -p
  45. > grant all privileges on *.* to username identified by ‘password’ with grant option;
  46. > quit

MySQL のインストール

Macは何をやるのも楽ちんだねぇ。

MySQL :: Download MySQL Community Server
から [Mac OS X 10.7 (x86, 64-bit), DMG Archive] 辺りをダウンロードして
中に入ってる
pkgファイルを2つともインストール。
MySQL.prefpaneもシステム環境設定にインストール。
こんなカンジでシステム環境設定にMySQLのコンパネが追加される。

control_panel

このコンパネで起動/停止ができる。

これだけだとターミナルでmysqlコマンドを使うことができないので

vi /Users/username/.bash_profile

で、

export PATH=$PATH:/usr/local/mysql/bin

と、書き込んだファイルを作成する。

Cannot proceed because system tables used by Event Scheduler were found damaged at server start

MySQLは普通に動いているようにみえるのだけど、こんなエラーが出ている。
Google翻訳曰く、
「イベントスケジューラが使用するシステムテーブルがサーバ起動時に損傷が認められたため、続行できません」
だ、そうだ。
本番サーバなんですが。。。

レプリケーションしているのだが、レプリケーション先にはこのエラーは出ていない。

ググってみると、「mysql_upgrade」を実行しなさい、ということなので素直に従う。

# mysql_upgrade -h localhost -u root -p --verbose --force

途中で出てきたWarningは

Running 'mysqlcheck' with connection arguments: '--host=localhost'
Warning: Using a password on the command line interface can be insecure.
Running 'mysqlcheck' with connection arguments: '--host=localhost'
Warning: Using a password on the command line interface can be insecure.
Running 'mysql_fix_privilege_tables'...
Warning: Using a password on the command line interface can be insecure.
Running 'mysqlcheck' with connection arguments: '--host=localhost'
Warning: Using a password on the command line interface can be insecure.
Running 'mysqlcheck' with connection arguments: '--host=localhost'
Warning: Using a password on the command line interface can be insecure.

このくらい。あとは全部[ OK ]だった。
1分もかからずに終了したので、

/etc/rc.d/init.d/mysqld restart

で再起動。
おお!出なくなった!

複数行同時にUPDATEしてみる

UPDATE文を1行ずつチマチマ更新していくのはめんどくさいなぁ、と。

テーブル名:hoehoe_tbl

id name create_date birth
1 うらら 2014-03-19 00:00:00 2000-01-01
2 プリン 2014-03-19 02:13:24 2000-01-01
3 ジャガー 2014-03-19 03:02:11 2000-01-01
4 マイケル 2014-03-19 06:00:21 1958-08-29

こんなだったとして。
「マイケル」以外の誕生日がめちゃくちゃじゃないの!という時は

update `hoehoe_tbl` SET `birth` = '2477-05-30' WHERE `id` = 1
update `hoehoe_tbl` SET `birth` = '2477-11-11' WHERE `id` = 2
update `hoehoe_tbl` SET `birth` = '2464-07-06' WHERE `id` = 3

とかやっていた訳ですが。
(プリンとジャガーの誕生日知りません。デタラメです。)

CASEステートメントを使ってこうもできるらしい。

update `hoehoe_tbl` SET 
`birth` =
  case `id`
    WHEN 1 THEN '2477-05-30'
    WHEN 2 THEN '2477-11-11'
    WHEN 3 THEN '2464-07-06'
  END
WHERE `id` IN (1,2,3);

これで、SQL文がひとつにまとまって便利。
複数カラムを同時に更新するときは、UPDATE文の書き方そのままに

update `hoehoe_tbl` SET 
`name` =
  case `id`
    WHEN 1 THEN 'URARA'
    WHEN 2 THEN 'PUDDING'
    WHEN 3 THEN 'JAGUAR'
  END
, `birth` =
  case `id`
    WHEN 1 THEN '2477-05-30'
    WHEN 2 THEN '2477-11-11'
    WHEN 3 THEN '2464-07-06'
  END
, `create_date` = NOW()
WHERE `id` IN (1,2,3);

こんな?
UPDATE文なので、最後のWHERE句の指定を忘れると、該当する行以外全部吹っ飛ぶ。

5.6.14 では auto_increment がリセットされない?

5.6.14 を使用していて、データを全削除した後に

ALTER TABLE `hoge` AUTO_INCREMENT=1;

で、カウンタを元に戻そうと思っても次に生成されるIDが今までのものから継続される。
どうやら 5.6.14 でのバグっぽい。
最新版ということで 5.6.16 が出ていた。

前にMySQLのリポジトリを入れているので

yum –enablerepo=mysql-community update

でアップデートかけたのだが、5.6.14 で最新ですよ~と言われてしまう。

なんやかんや考えてもう一度リポジトリ取り直してみようとサイトからrpmファイルを落としてみたら
中身が違ってた。
前に導入した時は

  • mysql-community-release-el6-3.noarch.rpm

だったのに、今日見てみたら

  • mysql-community-release-el6-5.noarch.rpm

になってた。
入れなおして、

yum –enablerepo=mysql56-community update

で無事 5.6.16 インストール完了。

epgdump と epgrec の導入

今回は録画を簡単に行うというところまで。
途中、LAMPの構築が入っちゃってやたら長い記事に…
設定から録画テストまではこちらの記事を参照。

  1. epgdumpのインストール
    1. epgdumpをsourceforgeから持ってくる。
      # wget http://iij.dl.sourceforge.jp/epgrec/53385/epgdumpr2_20111001.tar.gz
    2. 解凍。
      # tar -zxvf epgdumpr2_20111001.tar.gz
    3. epgdumpr2ディレクトリに移動してmakeしたいのだけど、
      # cd epgdumpr2
      # make
      make: `all' に対して行うべき事はありません.

      と言われてしまう。
      ので、

      # touch *
      # make clean
      rm -f core epgdump *.o
      # make

      のように、touch と make clean を挟んでからmakeする。

    4. 出来上がったepgdumpを/usr/local/bin/にコピーする。
      # cp epgdump /usr/local/bin/
    5. コピーしたepgdumpが正常に動作するか確認。
      # epgdump test /tmp/test_video.ts -
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE tv SYSTEM "xmltv.dtd">
      <tv generator-info-name="tsEPG2xml" generator-info-url="http://localhost/">
      ……………………
      ……………………
      </tv>

      と、番組情報がダーっと出てくれば動作している事になる。

  2. epgrecで必要になるものを事前にインストール
    epgrecはPHPで書かれているので、事前にPHPが動作するWebサーバ(Apacheでもnginxでも)が必要。
    ついでにMySQLも利用するので、これも必要。
    要するにLAMP環境が必要。

    1. Apache をインストール
      # yum install httpd

      以上。

    2. Apache の設定
      1. httpd.conf を編集
        # vi /etc/httpd/conf/httpd.conf

        で、
        292行目辺りの

        DocumentRoot "/var/www/html"

        317行目辺りの

        <Directory "/var/www/html">

        を好きなディレクトリに変更する。

    3. PHP のインストール
      # yum install php?php-cli php-mysql?php-mbstring php-xml

      ぐらい?
      あとで、あれこれ足りないと言われるのが面倒なら、少々乱暴だが

      # yum install php*

      で、PHPと名のつくものが全部入る。
      まともにサーバ作るならこんな事してちゃダメ。
      ちゃんと必要な物を考えて入れましょう。

    4. PHPの設定
      1. php.ini を編集
        # vi /etc/php.ini

        で、
        946行目辺りの

        ;date.timezone =

        のコメントアウトを外して、

        date.timezone = Asia/Tokyo

        としておく。

      2. php.conf の存在確認
        /etc/httpd/conf.d/ 配下に php.conf が存在することを確認しておく。
    5. MySQLをインストール
      # yum install mysql-server mysql

      で、バージョン5.1 辺りを入れてくれると思う。
      もうちょっと新しいものを入れたいなら、MySQLのリポジトリを導入して、

      # yum --enablerepo=mysql-community install mysql-server mysql

      でもいい。

    6. MySQLの設定
      1. MySQLにログイン
        # mysql -u root -p
         Enter password:

        一番初めはパスワードは無いので、そのままReturnで入れる。

      2. まずはrootのパスワードを設定。
        > grant all privileges on *.* to root@localhost identified by 'rootのPW' with grant option;

        設定したら一度ログアウトして、

        • パスワードが正しく設定されていること
        • パスワード無しではログイン出来ないこと

        を確認しておく。

      3. epgrec 用のデータベースの作成
        > create database データベース名;
        で、データベースを作成しておく。データベース名は epgrec_database でもなんでもいいので、わかりやすく好きなものを。
      4. epgrec 用のMySQLユーザの作成
        別に root でもいいけど、epgrec で使用するMySQLユーザを作成しておく。

        > grant all privileges on epgrec_database.* to epgrec用のID@localhost identified by 'epgrec用のPW' with grant option;
      5. ここまで出来たら、MySQL ログアウト。
    7. chkconfig の変更
      # chkconfig httpd on
      # chkconfig mysqld on

      で、Apache と MySQL が自動的に起動するようにしておく。

  3. epgrecのインストール
    1. epgrecをsourceforgeから持ってくる。
      # wget http://iij.dl.sourceforge.jp/epgrec/53387/epgrec_20111001.tar.gz
    2. 解凍。
      # tar -zxvf?epgrec_20111001.tar.gz
    3. 出来上がった epgrec ディレクトリを Apache の公開ディレクトリ配下にコピーする。
      # cp -r /tmp/epgrec /var/www/html/epgrec
    4. コピー先のディレクトリに移動して、config ファイルを作成・編集する。
      # cd /var/www/html/epgrec
      # cp config.php.sample config.php
      # vi config.php
      
      $GR_CHANNEL_MAP = array(
              "GR27" => "27",         // NHK
              "GR26" => "26",         // Eテレ
              "GR25" => "25",         // NTV
              "GR22" => "22",         // TBS
              "GR21" => "21",         // フジ
              "GR24" => "24",         // TV朝日
              "GR23" => "23",         // TV東京
              "GR28" => "28",         // 放送大学
              "GR18" => "18",         // TVK
              "GR20" => "20",         // 東京MX
              "GR30" => "30",         // 千葉テレ
              "GR32" => "32",         // テレ玉
              "GR19" => "19",         // YOUプレミアム
              "GR53" => "53",         // YOUテレビ
      );

      うちで見ることができるリストはこんなカンジに。
      各地域のチャンネルリストはマスプロ電工のページにある。

    5. 録画用のshファイルもサンプルから作成しておく。
      cp do-record.sh.pt1 do-record.sh
    6. いくつかのディレクトリのパーミッションを777に変更しなくてはならない。
      # chmod 777 templates_c/
      # chmod 777 video/
      # chmod 777 thumbs/
      # chmod 777 settings/
      # chmod 777 cache/
    7. この段階までやってからブラウザで
      http://[SERVER_ADDR]/epgrec/index.php

      にアクセス。
      インストール状態をチェックしてくれる。

      1. ディレクトリとファイルのパーミッションチェック
        地上デジタルのチャンネル設定チェック
      2. MySQL設定
        インストール関連設定
      3. デジタルチューナー設定
        録画関連設定
        録画ファイル名の形式は[ %CH%_%ST%_%TITLE% ]に変更。

      すべて記入したら「EPGの初回受信」リンクを押す。
      50分ぐらいかかるかもという記述があったが、自分の環境では10分ちょっとで終わった。

    8. インストール最終ステップのページに
      「/etc/cron.d/以下にcronによるEPG受信の自動実行を設定する必要があります」
      との記述があるので、これを設定する。
      CentOSなので、ubuntu用の設定は使えない。
      けど「要はgetepg.phpを走らせれば良い」ということなので、

      # crontab -e
      30 10 * * * php -f /var/www/html/epgrec/getepg.php

      で走らせることにする。
      該当チャンネルが放送時間帯でなければいけないので、放送大学の放送がない深夜帯には設定できなかった。

  4. epgrec で録画テスト
    1. epgrec の画面が出たら予約してみる。
      「custom job番号の取得に失敗」というエラーが出たらatコマンドがインストールされていない。

      # yum install at

      でインストールする。

    2. 録画先がepgrecディレクトリ内のvideoディレクトリなので、これを変更しておく。

InnoDB: Error: Table “mysql”.”innodb_table_stats” not found.

MySQL 5.6 に上げてからなんか色々変わった?
別件で調べていたらこんなエラーログを見つけた。
5.1からまるごとDumpして持ってきたデータなので「そんなテーブルはない」ということになってしまったのか?
次回、止めてもいい時に

mysql_upgrade -u root -p

でも試すことにする。

Column count of mysql.proc is wrong. Expected 20, found 16. The table is probably corrupted

「mysql.procの列数が間違っています。 20の予想される、16を発見した。テーブルが破損している可能性があり」
だ、そうです。Google翻訳曰く。。。

こないだ再起動したときには出てなかったのにな。
仕方がないので、さらにググる。

mysql_upgrade --force -u root -p

forceってところが気になるけど、やるしか無いのでやってみる。

消えた。。。

MySQL Replication for 5.6

前に書いた MySQL Replication の焼き直しです。
バージョンを5.6で揃えることになったので、他のバージョンとの差異を気にする必要がない、はず。

  1. [マスター・スレーブ]
    それぞれ作る。
    mysql.comにリポジトリがあるので、これを使用する。
  2. [マスター・スレーブ]
    vi /etc/my.cnf
    で、以下を書き足す or コメントアウトを外す。
    server-idは重複しないよう気をつける。
    (第2オクテット~第4オクテットの9桁で被らないと思っている)

    [mysqld]
    log-bin=mysql-bin
    server-id=168001012
  3. [マスター]
    スレーブから接続するユーザを作成しておく。

    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.0/255.255.255.0' IDENTIFIED BY 'repl_password';
  4. [マスター]
    ダンプ出力する。

    mysqldump -u root -p --all-databases --master-data --apply-slave-statements >> /tmp/sqldump_all_databases.sql

    [ –single-transaction ]がないと、
    始めのデータベースと最後のデータベースでダンプしてる間に更新されている場合が出てきたりするかも。
    でも、[ –master-data ]で、[ –lock-all-tables ]が自動的に追加されるからそれでイイのかな?

    [ –opt ]
    ※–opt はデフォルトでONなので、明示的に書く必要はない。
    自動的にセットされるオプション・・・

    [ –all-databases ]
    全てのデータベースを出力。

    [ –master-data ]
    ダンプファイルの先頭に「CHANGE MASTER TO…」を書き込む。
    自動的にセットされるオプション・・・
    (ただし、[ –single-transaction ]オプションが指定されている場合を除く)

    自動的に解除されるオプション・・・

    [ –apply-slave-statements ]
    ダンプファイルの先頭、「CHANGE MASTER TO…」文より前に「STOP SLAVE;」、
    末尾に「START SLAVE;」を書き込む。

  5. [スレーブ]
    マスターにあるダンプファイルを取得。

    scp -Cqp user@192.168.1.12:/tmp/sqldump_all_databases.sql /tmp/sqldump_all_databases.sql
  6. [スレーブ]
    [ –master-data ]オプションをつけていれば、「CHANGE MASTER TO…」文も同時にやってくれているはず。
    [ –apply-slave-statements ]オプションをつけていれば、自動的にSLAVEとしてスタートしているはず。

    mysql -u root -p < /tmp/sqldump_all_databases.sql
  7. [スレーブ]
    動作状況を確認しておく。

    show slave status;

    で、

    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes

    が両方ともYesになっている事を確認。

    Slave_SQL_Running_State: Reading event from the relay log

    は、「差分読み込み中。
    よく見ると、

    Seconds_Behind_Master: 11771

    という表記もあって、マスターから遅れている秒数を表示してくれている。

    Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

    は、「全ての差分読み込み完了。マスターのアップデート待ち」という状態。

これで、スレーブ出来上がる、はず。

mysqld-relay-bin.******** not found (Errcode: 2)

ERROR 29 (HY000) at line 22: File './mysqld-relay-bin.24352415' not found (Errcode: 2)

と言われました。

tail -n 20 /var/log/mysqld.log

で、ログを確認すると

130510  5:29:09 [ERROR] /usr/libexec/mysqld: File './mysqld-relay-bin.24352415' not found (Errcode: 2)
130510  5:29:09 [ERROR] Failed to open log (file './mysqld-relay-bin.24352415', errno 2)
130510  5:29:09 [ERROR] Failed to open the relay log './mysqld-relay-bin.24352415' (relay_log_pos 4)
130510  5:29:09 [ERROR] Could not open log file
130510  5:29:09 [ERROR] Failed to initialize the master info structure

とか。

cat /var/lib/mysql/mysqld-relay-bin.index

を確認すると

./mysqld-relay-bin.24352415

と書いてあるけど、そんなファイルは存在しない。
仕方がないのでこの行を消してみる。

そうすると今度は

ERROR 1201 (HY000) at line 22: Could not initialize master info structure; more error messages can be found in the MySQL error log

だと。
master info の初期化に失敗?のようなカンジなので

rm master.info

で削除。
ついでに

rm relay-log.info

も削除。

/etc/init.d/mysqld restart

で再起動して・・・OKでした。

MySQLリポジトリの追加

MySQL 用のリポジトリがあったので、入れてみることにする。
これで 5.6 とかも楽に入れられる。

Download MySQL Yum Repository というページが公式の中にあるので、
ここからrpmファイルをダウンロードしてくる。
ダウンロードするファイルは
Red Hat Enterprise Linux 7 / Oracle Linux 7 (Architecture Independent), RPM Package
mysql-community-release-el7-5.noarch.rpm
Red Hat Enterprise Linux 6 / Oracle Linux 6 (Architecture Independent), RPM Package
mysql-community-release-el6-5.noarch.rpm
Red Hat Enterprise Linux 5 / Oracle Linux 5 (Architecture Independent), RPM Package
mysql-community-release-el5-5.noarch.rpm
から適宜選択。
ファイルのダウンロードには、オラクルのアカウントでログインしないといけない。
一度ログインしてしまえばダウンロードアドレスはわかるので、そのアドレスに対してwgetをかけても良い。

ダウンロードしてきたらサーバの適当なところにコピーする。

# rpm -ivh mysql-community-release-el6-3.noarch.rpm

で、mysql-community.repo がインストールされる。

# vi /etc/yum.repos.d/mysql-community.repo

を確認すると、

[mysql-community]
enabled=1

になっているので、これを

enabled=0

に変更して保存。

使用する時は

# yum update --enablerepo=mysql-community

のように、enablerepo で指定して使う。