MySQL5.5.6で変なエラーに遭遇した。

MySQL5.5.6で変なエラーに遭遇した。

レプリケーションのスレーブサーバで、数日前に別の障害が発生したため、ある時点でのフルバックアップまで遡ってそこからレプリケーションをonにして追いかけてた。

その途中にエラーに詰まってしまった。

エラーの内容は下記。


Last_Errno: 1548
Last_Error: Error 'Cannot load from mysql.proc. The table is probably corrupted' on query. Default database: 'hoge'. Query: 'UPDATE hoge SET hoge_name = replaceSymbol(hoge_name)'

エラー番号でググってみるもヒットしない。まぁ公式をみても大して当てにはならない。

よくわかんないのでmysql.procを調べてみた。


*************************** 2. row ***************************
db: hoge
name: replaceSymbol
type: FUNCTION
specific_name: replaceSymbol
language: SQL
sql_data_access: CONTAINS_SQL
is_deterministic: YES
security_type: DEFINER
param_list: str TEXT charset utf8
returns: text CHARSET utf8

body: BEGIN

/* 中略 */

SET str = REPLACE(str, '\\', ' ');

RETURN str;
END
definer: yousan@%
created: 2009-10-08 15:44:43
modified: 2009-10-08 15:44:43
sql_mode:
comment:
character_set_client: utf8
collation_connection: utf8_general_ci
db_collation: latin1_swedish_ci
body_utf8: BEGIN
SET str = REPLACE(str, '\', ' ');

/* 中略 */

SET str = REPLACE(str, ' ', '[] \\\*\+-.,\?\(\)\{\}\[\^\$\|]*');
RETURN str;
END

なるほど、ストアドプロシージャ(?)が入ってるらしい。

ストアドプロシージャの一覧を調べてみる。


mysql> use hoge;

mysql> show function status;
ERROR 1548 (HY000): Cannot load from mysql.proc. The table is probably corrupted

やっぱりダメぽ。

コレの定義がおかしいのかな、ってことで定義し直してみる。


mysql> truncate proc;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from proc;
Empty set (0.00 sec)
mysq>DELIMITER $$
DROP PROCEDURE IF EXISTS `hoge`.`hoge` $$
CREATE PROCEDURE `hoge`.`hoge` ()
BEGIN
END $$
ERROR 1548 (HY000): Cannot load from mysql.proc. The table is probably corrupted

うーん参ったなぁ。procテーブルをdropしてcreateしてもダメ。

ちゃんと読み出せてるんだけどなぁ。 あまり直った試しのないrepair tableをかけてもダメ。


mysql> use mysql; repair table proc;
+------------+--------+----------+----------+
| Table      | Op     | Msg_type | Msg_text |
+------------+--------+----------+----------+
| mysql.proc | repair | status   | OK       |
+------------+--------+----------+----------+
1 row in set (0.02 sec)

この段階で他のレプリケーションからデータをコピーし終え、この問題をあきらめる決心をつけた。

一応、mysql 5.5のバージョンを上げてみる。

mysql-server-5.5.6_1 -> mysql-server-5.5.8_3

もうココまでか、残念、とか思ってたら該当する記事を見つけた。
MySQL Bugs: #52444: mysql_upgrade fails b/w 5.1 -> 5.5 (Celosia)

procのテーブル形式が違うとかそういうことなのかな。
じつはこの5.5のサーバは元々5.1で利用してて、そこのdatadirをまるまるコピーしてきてる(と思う)。
だからたぶんその辺が問題なんじゃないかな。
でもじつは同じことをこのサーバで過去にやってて、そのときは詰まらなかった。なんでだろう。

ほんでまぁ、テキトウに記事を流し読みしたら、mysql_upgradeってのにバグがあってそこのパッチこれね、とか書いてある。
え、今回も過去もそんなのをやった覚えないっす。
というわけでこれを実行してみる。

このスクリプト(バイナリでした)はmysqlサーバに接続してごにょごにょするものなのでmysqldを立てっぱでやるらしい。


shell> mysql_upgrade
Looking for 'mysql' as: mysql
Looking for 'mysqlcheck' as: mysqlcheck
Running 'mysqlcheck with default connection arguments
Running 'mysqlcheck with default connection arguments
cacti.cdef                                         OK
cacti.cdef_items                                   OK
cacti.colors                                       OK
cacti.data_input                                   OK
cacti.data_input_data                              OK

/* 中略 */

wordpress.wp_usermeta                       OK
wordpress.wp_users                          OK
Running 'mysql_fix_privilege_tables'...
OK

で、ストアドプロシージャを作成するクエリを流すと・・・


mysql> DELIMITER $$
mysql> CREATE PROCEDURE `nico`.`hoge` ()
 -> BEGIN
 ->
 -> END $$
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;

おおお、なんかうまくいってる!

今回の問題は該当のストアドプロシージャがなかったので、親元から手動でコピーしてきて復元すればレプリケーションは直る、と!

これまで5.5を何の気なしに使ってきてたけど、移行するときにはちゃんとmysql_upgradeをかけてやらないとダメみたい。

メジャーバージョンアップ(になるのかな?)のときにはちゃんとその辺を調べてやってやりましょう!

またmysql_upgradeの内容については下記のリンクに書いてありました。

MySQL ::   MySQL 5.5 Reference Manual :: 4.4.7 mysql_upgrade — Check Tables for MySQL Upgrade<

乱暴にかいつまむと、

このバイナリは以下のコマンドを実行することと等価です。

mysqlcheck --all-databases --check-upgrade --auto-repair
mysql < fix_priv_tables
mysqlcheck --all-databases --check-upgrade --fix-db-names --fix-table-names

他にも移行に関する注意点など。読んでないけど・・

MySQL ::   MySQL 5.5 Reference Manual :: 2.11.1.1 Upgrading from MySQL 5.1 to 5.5

まとめ

5.1から5.5へ移行したらmysql_upgradeをかけましょう。

nfsでのmountの時のオプションを変えてみた。

nfsでのmountの時のオプションを変えてみた、ら早くなった気がしたので調べた。

なんかかなり速度があがってコレ本当に大丈夫なの?状態。
メモリにキャッシュされてるんじゃなかろうか、と疑って二度やってみた。

オプションを変えてみたやつ。


shell> grep ports /etc/fstab
nfs:/usr/ports    /usr/ports      nfs     rw,async,hard,intr      0       0

shell> dd if=/usr/ports/tmp/hoge of=/dev/null
2048000+0 records in
2048000+0 records out
1048576000 bytes transferred in 111.954486 secs (9366092 bytes/sec)

shell> dd if=/usr/ports/tmp/hoge of=/dev/null
2048000+0 records in
2048000+0 records out
1048576000 bytes transferred in 2.745210 secs (381965655 bytes/sec)

変える前


shell> grep ports /etc/fstab
nfs:/usr/ports    /usr/ports      nfs     rw      0       0

shell> dd if=/usr/ports/tmp/hoge of=/dev/null
2048000+0 records in
2048000+0 records out
1048576000 bytes transferred in 110.450103 secs (9493662 bytes/sec)

shell> dd if=/usr/ports/tmp/hoge of=/dev/null
2048000+0 records in
2048000+0 records out
1048576000 bytes transferred in 2.445045 secs (428857548 bytes/sec)

あるぁ・・・・。見事にキャッシュだったくさ。

MySQLでストアドプロシージャの一覧を調べる方法

MySQLでストアドプロシージャの一覧を調べる方法。

なんかmysql.procを見るとか書いてあったりしたんだけど、そこにはあるけど実在しないプロシージャとかあったりして。

下記の方法で調べることができるらしい。


mysql> SHOW PROCEDURE STATUS;
mysql> show function status;

あとそれぞれの定義文は


mysql> SHOW CREATE PROCEDURE hoge.hogefunction;

コレでとれるらしい。

FreeNAS 0.72で、sambaの設定で各ユーザのホームディレクトリを表示してやる

FreeNAS 0.72で、sambaの設定で各ユーザのホームディレクトリを表示してやる。

samba/cifsの設定だと一つ一つディレクトリをぽちぽち追加しないとダメ。

これだと複数人のユーザがいる場合、全部を追加してやるか、ホームディレクトリの親元を共有してやる必要がある。

なのでsmb.confに追加の設定を与えて自分のホームディレクトリだけをみれる(browsable)ようにしてやる。

[homes]
comment = Home Directories
browseable = no
writable = yes

これでユーザはsmbでfreenasのサーバにアクセスしたときにホームディレクトリが表示されるようになる。

でもユーザのホームディレクトリはデフォルトで/mntとかになっているのでこれを適宜変えてやる必要があるので注意。

MySQL5.0でリレーログが破損した

MySQL5.0でリレーログが破損した。

先日から発生しているエラーのshow slave statusを元にbinlogを調べてみる。


> mysqlbinlog relay-bin.000534

中略

# at 104726037
#110124  8:31:28 server id 84035  end_log_pos 494070847         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825488/*!*/;
insert into poller_output (local_data_id, rrd_name, time, output) values (533, '', '2011-01-24 08:31:24', 'MySQL: Lost connection to MySQL server at \'reading initial communication packet\', system error: 61')
/*!*/;
# at 104726310
#110124  8:31:28 server id 84035  end_log_pos 494070874         Xid = 121124362
COMMIT/*!*/;
# at 104726337
#110124  8:31:28 server id 84035  end_log_pos 494070943         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825488/*!*/;
BEGIN
/*!*/;
# at 104726406
#110124  8:31:28 server id 84035  end_log_pos 494071216         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825488/*!*/;
insert into poller_output (local_data_id, rrd_name, time,
/*!*/;
ERROR: Error in Log_event::read_log_event(): 'Event too small', data_len: 0, event_type: 0
Could not read entry at offset 104726679:Error in log format or read error
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

なんか最後のクエリが尻切れトンボになってる。これじゃあSQL通らないし、この後流すはずのクエリは何なのかわからなくなってる。
さっくり調べたけどmysqlでリレーログの破損を直すような機能はないらしい。
さて困ったけどなんとかしなくてはならない。

今回の目的とか条件とか

  • スレーブを動くようにしたい
  • もっかいスレーブを作り直すのも一つの手だけど、スレーブ立て直すのってかなり大変なのでできればやりたくない。
  • このホストはcpuとかhddとか結構しょっぱくて、途中のデータ復元してchange master toしても追いつくまでにかなり(数日、下手すれば1週間以上)の時間がかかりそう。
  • クエリの漏れは結構許容できる。
  • なのでマスターのログを漁って正常なログの位置を指し示してやることにしようと思い立った。

今回の原因はスレーブの強制シャットダウンが原因のはず。
mysqlが再起動するとリレーログを含めたログ全般がflushされるというか新しい名前をつけられる。
今回原因となったのはrelay-bin.000534なので続きはrelay-bin.000535にあるはず。
それが正しい続きのログなのかを調べて正しければrelay-logの位置をそこへ変えてやる。

上述のrelay-logのdumpをみると、


# at 104726406
#110124  8:31:28 server id 84035  end_log_pos 494071216         Query   thread_id=4846316       exec_time=0     error_code=0

と書いてある。atの後に続くのはbinlogでいうログのポジション。end_log_posは何だろう。今までに見てきたbinlogだとatの値に近いものが記録されていたと思ってた。
それも次のクエリのログポジションな値が入ってる気がしてたんだけど・・・。


at 100
end_log_pos 200
at 200

って具合に。
ここで仮説を立てる。これはリレーログなのでend_log_posはマスターのログのポジションを表しているんじゃないか、と。
ではマスターのログを調べてみる。


master> mysqlbinlog mysql-bin.000075 --start-pos=494071216 | more

/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#110121  2:25:09 server id 84035  end_log_pos 106       Start: binlog v 4, server v 5.1.42-log created 110121  2:25:09
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
9W84TQ9DSAEAZgAAAGoAAAABAAQANS4xLjQyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 494071216
#110124  8:31:28 server id 84035  end_log_pos 494071243         Xid = 121124363
COMMIT/*!*/;
# at 494071243
#110124  8:31:28 server id 84035  end_log_pos 494071312         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825488/*!*/;
SET @@session.pseudo_thread_id=4846316/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 494071312
#110124  8:31:28 server id 84035  end_log_pos 494071585         Query   thread_id=4846316       exec_time=0     error_code=0
use cacti/*!*/;
SET TIMESTAMP=1295825488/*!*/;
insert into poller_output (local_data_id, rrd_name, time, output) values (535, '', '2011-01-24 08:31:24', 'MySQL: Lost connection to MySQL server at \'reading initial communication packet\', system error: 61')
/*!*/;
# at 494071585
#110124  8:31:28 server id 84035  end_log_pos 494071612         Xid = 121124364
COMMIT/*!*/;
# at 494071612
#110124  8:31:28 server id 84035  end_log_pos 494071681         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825488/*!*/;
BEGIN
/*!*/;

最初にログの情報が表示されて、次から対象のposのクエリが表示される。おお、ばっちり一致した。
どうやらちょん切れてたクエリは


insert into poller_output (local_data_id, rrd_name, time, output) values (535, '', '2011-01-24 08:31:24', 'MySQL: Lost connection to MySQL server at \'reading initial communication packet\', system error: 61')
/*!*/;

らしい。皮肉にもmysqlのエラーを格納していた様子。
さて気になるのはその後のクエリ。
マスター上では


# at 494071585
#110124  8:31:28 server id 84035  end_log_pos 494071612         Xid = 121124364
COMMIT/*!*/;
# at 494071612
#110124  8:31:28 server id 84035  end_log_pos 494071681         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825488/*!*/;
BEGIN
/*!*/;

となっている。
これをスレーブ側でも確認してみる。


slave>mysqlbinlog relay-bin.000535 | more
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#110124  8:34:21 server id 84105  end_log_pos 98        Start: binlog v 4, server v 5.0.67-log created 110124  8:34:21
# at 98
#110124  8:34:21 server id 84105  end_log_pos 149       Rotate to relay-bin.000536  pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

moreをつけたけど以上で終わり。なんか000536にrotateしたよってのだけが記述されてる。ファイルサイズも149バイトしかなくてどうやらいらない子らしい。


slave>mysqlbinlog relay-bin.000536 | more

/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#110124  8:34:21 server id 84105  end_log_pos 98        Start: binlog v 4, server v 5.0.67-log created 110124  8:34:21
# at 98
#700101  9:00:00 server id 84035  end_log_pos 0         Rotate to mysql-bin.000075  pos: 494172037
# at 141
#110121  2:25:09 server id 84035  end_log_pos 0         Start: binlog v 4, server v 5.1.42-log created 110121  2:25:09
# at 243
#110124  8:31:49 server id 84035  end_log_pos 494172106         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825509/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
BEGIN
/*!*/;
# at 312

000536にはちゃんとクエリがあった。でも見たところ、最初のクエリのpositionは494,172,106 になってる。前のrelay-bin.000534の時には494,071,681だったので100,000(単位不明)もずれてる。

マスターのログを見てもそんなにログのpositionが飛んでいる様子はない。こりゃーこの部分のログをすっ飛ばしたんだろうか。

ここでまとめる

スレーブのrelay logが尻切れトンボで終わってる。これは強制終了のせいだろう。

この途中で切れてしまったクエリは全文をマスター側で確認。手動で実行もできる。

問題のrelay logに続くログがすでに転送されているが、どうやら結構漏れがあるらしい。

ということで、relay logの位置を変えられないか調べることに。

show slave statusを再度確認。


Master_Log_File: mysql-bin.000075 // I/O スレッドが現在読み込んでいるマスタ               バイナリ ログ ファイルの名前
Read_Master_Log_Pos: 773640060 // 現在のマスタ バイナリ ログ内で、I/O               スレッドが読み込んだところまでの位置
Relay_Log_File: relay-bin.000534 // 現在読み込み、実行をしている SQL               スレッドからのリレー ログ               ファイルの名前
Relay_Log_Pos: 104726337 // スレッドが現在のリレー               ログ内で読み込み、実行したところまでの位置
Relay_Master_Log_File: mysql-bin.000075 // SQL               スレッドによって実行された一番最近のイベントを含むマスタ               バイナリ ログ ファイルの名前。

ひとまずI/Oスレッドを止めておく。


slave sql> stop slave io_thread; show slave status\G
Master_Log_File: mysql-bin.000075
Read_Master_Log_Pos: 773640060
Relay_Log_File: relay-bin.000534
Relay_Log_Pos: 104726337
Relay_Master_Log_File: mysql-bin.000075

Slave_IO_Running: No
Slave_SQL_Running: No

その後でchange master toを試す


slave sql> change master to master_log_pos=494071312; show slave status\G

Master_Log_File: mysql-bin.000075
Read_Master_Log_Pos: 494071312
Relay_Log_File: relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000075
Slave_IO_Running: No
Slave_SQL_Running: No

リレーログのファイル名が1番から振り直しになった。

mysqldirにあったリレーファイルも全部削除されてて、00001番のみ作成されてる。

これでいいのかな。とりあえずi/oスレッドをスタートしてやろう。


slave sql> start slave io_thread;

そのあとでリレーログを確認。なぜか00001にはほとんどデータが書かれてなかった。


slave>mysqlbinlog relay-bin.000001

/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#110126 17:37:11 server id 84105  end_log_pos 98        Start: binlog v 4, server v 5.0.67-log created 110126 17:37:11 at startup
ROLLBACK/*!*/;
# at 98
#110126 17:42:26 server id 84105  end_log_pos 149       Rotate to clinton-relay-bin.000002  pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

slave>mysqlbinlog relay-bin.000002 | more

/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#110126 17:42:26 server id 84105  end_log_pos 98        Start: binlog v 4, server v 5.0.67-log created 110126 17:42:26
# at 98
#700101  9:00:00 server id 84035  end_log_pos 0         Rotate to mysql-bin.000075  pos: 494071312
# at 141
#110121  2:25:09 server id 84035  end_log_pos 0         Start: binlog v 4, server v 5.1.42-log created 110121  2:25:09
# at 243
#110124  8:31:28 server id 84035  end_log_pos 494071585         Query   thread_id=4846316       exec_time=0     error_code=0
use cacti/*!*/;
SET TIMESTAMP=1295825488/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
insert into poller_output (local_data_id, rrd_name, time, output) values (535, '', '2011-01-24 08:31:24', 'MySQL: Lost connection to MySQL server at \'reading initial communication packet\', system error: 61')
/*!*/;
# at 516
#110124  8:31:28 server id 84035  end_log_pos 494071612         Xid = 121124364
COMMIT/*!*/;
# at 543
#110124  8:31:28 server id 84035  end_log_pos 494071681         Query   thread_id=4846316       exec_time=0     error_code=0
SET TIMESTAMP=1295825488/*!*/;
BEGIN
/*!*/;

おお、しっかりと問題のSQLから記述されてる。

これであとはsqlスレッドを実行してやる。


mysql> start slave; show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master.l2tp.org
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000075
Read_Master_Log_Pos: 949455645
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 597375
Relay_Master_Log_File: mysql-bin.000075
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 494668444
Relay_Log_Space: 455384576
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 205666
1 row in set (0.00 sec)

ばっちり動いたみたい!

この辺で気がついたんだけど、最初の方で途切れちゃってるlogのpositionを調べるに当たって、mysqlbinlogでエラーログを漁り、end_posで合致する箇所をマスターのbinlogと照らし合わせてたけど、それってshow slave statusのexec_master_log_posになるんじゃなかったかな、と。

なので今回のような障害の時にはそこを見ればどこにposをあわせればいいかわかるような気がしなくもない。な!

まとめ

  • リレーログが破損したらchange master toで拾ってきたいデータを指定すればなんとかなる。
  • exec_master_log_posはコレまでに実行したorこれから実行しようとしてるマスターのbinlogの位置。
  • 5.5からは自動でリレーログの修復をやってくれるみたい。
  • mysqlの偉い方々によるとスレーブに変なエラーが出たらとにかく作り直せ、って。うちはスレーブのリソースがあまりなくてそれをやると長期ダウンになっただろうからできませんでした。

syslog周りで変な問題が

syslog周りで変な問題が。

各ホストでとったsyslogがsyslogサーバに転送されない、されてなかった。

思い当たるふしはたくさんあってアレなんだけど、そのままの状態でloggerコマンドを手打ちしてもダメ。

各ホストでsyslogdaemonを再起動したらうまくいった。どうやらsyslog daemonでサーバへのコネクションをもっている、のかな。そんでそのコネクションがロストすると以後うまく接続できない、とか。

発生した問題がdhcpとかdnsまわりだったので名前解決ができなくなってそのまま内部でアボーンとか。

ちょっとよくわかんないけどそんなメモ。

MySQL5.0で変なエラーでレプリケーションがとまってた

MySQL5.0で変なエラーでレプリケーションがとまってた。

エラーの内容は以下のとおり


Last_Error: Error '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 '' at line 1' on query. Default database: 'cacti'. Query: 'insert into poller_output (local_data_id, rrd_name, time, '

これってクエリにエラーがあるよってことでとまってる。確かに最後がカンマで終わっててへんなとまり方してる。このクエリは親元のマスターサーバから転送されたもので、エラーが起こるってのはちょっとおかしい。

気になったので親元のサーバのbinlogを見てみる。

エラーの状態には


Master_Log_File: mysql-bin.000075
Read_Master_Log_Pos: 498599301

とあるのでそこを見てみる。


%mysqlbinlog --start-position=498599301 mysql-bin.000075 | more

/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#110121  2:25:09 server id 84035  end_log_pos 106       Start: binlog v 4, server v 5.1.42-log created 110121  2:25:09
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
9W84TQ9DSAEAZgAAAGoAAAABAAQANS4xLjQyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 498599301
#110124  9:08:13 server id 84035  end_log_pos 498599377         Query   thread_id=13    exec_time=0     error_code=0
SET TIMESTAMP=1295827693/*!*/;
SET @@session.pseudo_thread_id=13/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=524288/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.time_zone='SYSTEM'/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 498599377

うーん、同じようなクエリは記述されてないぞ・・・?

binlogの見方が間違ってるんだろうか。

スレーブ側はtritonnな5.0で、ノーマルの5.1なmasterとはちょっと状況が違う。でもそれでも、見た感じまったくダメダメなクエリが詰まってるってのはおかしいなぁ。とりあえずskipしてstart slave;しておく。

なぜかmaatkitでmk-slave-restartを使って–error-number 1062したらダメだった。


DBD::mysql::st execute failed: 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 ''494070874'' at line 1 [for Statement "CHANGE MASTER TO MASTER_LOG_FILE=?, MASTER_LOG_POS=?" with ParamValues: 0='mysql-bin.000075', 1='494070874'] at /usr/local/bin/mk-slave-restart line 2771.

こんなエラーが出てダメだそうで。これはmaatkit側のバグっぽいな~。

あとでわかったことだけど、show slave statusの

Master_Log_File: mysql-bin.000075
Read_Master_Log_Pos: 498599301

は、現在のi/oスレッドが読み出しているマスターのbinlogの位置情報。なのでコレの場所を探したところで該当するエラーの行が含まれてないのはもっとも。

今回のエラーの根本的な原因はサーバの不正なシャットダウンによるリレーログの破損が原因と思われた。

wordpressのサイドバーウィジェットを作成するためのメモ

wordpressのサイドバーウィジェットを作成するためのメモ。

バージョンとかで作成の仕方が違うらしいのでよくわかんなくなったけど、作るためのメモ書き。

wp_register_sidebar_widget

(自分で作った)ウィジェットをwordpress管理画面にあるウィジェットメニューに表示させるために登録する関数。

wp_register_widget_control

ウィジェットコントローラのコールバック関数を登録する。ここで登録されたコールバック関数はサイドバーウィジェットとして追加されたときに実行される。

たとえば


wp_register_widget_control('user_list_widget',
 __('User List Widget'),
 'ULWControl');

function ULWControl(){
 echo 'this function is called by wp_register_widget_control';
}

こんなコードがあったとしたらサイドバーの項目に’this function is called by wp_register_widget_control’を表示するウィジェットが追加される。