MySQL8のJSON部分更新を確認してみた。
最初こんなテーブルを作り、データを更新する。
> create database hoge;
> use hoge;
> create table fuga (id integer not null, body json not null, primary key(id));
> insert into fuga values (1, '{"x":10, "y":20}');
> update fuga set body = json_replace(body, '$.y', 50);
この状態でバイナリログを見ると、以下のようになっている。
### UPDATE `hoge`.`fuga`
### WHERE
### @1=1
### @2='{"x": 10, "y": 20}'
### SET
### @1=1
### @2='{"x": 10, "y": 50}'
部分更新じゃなくね?と思ったが、
my.cnfに以下を記載する。
binlog_row_image=minimal
binlog_row_value_options=partial_json
再起動完了後、以下のようなSQLを実行する。
> update fuga set body = json_replace(body, '$.y', 12);
この時、バイナリログは、
### UPDATE `hoge`.`fuga`
### WHERE
### @1=1
### SET
### @2=JSON_REPLACE(@2, '$.y', 12)
となる。
もともと、binlog_row_imageはバイナリログに変更分しか記載しないもので、
5.6から導入されていたが、8ではbinlog_row_value_optionsというパラメータが追加された。
これにより、JSONの部分更新がバイナリログ上でも明示される。
とはいえ、JSONの部分更新を成立させるには、
以下のJSON関数を使う必要がある。
- JSON_SET()
- JSON_REPLACE()
- JSON_REMOVE()
MariaDB10.3でも、binlog_row_value_optionsがないため、
JSONの部分更新はできない。
おまけに、JSONはlongtextのエイリアスのため、
「JSONの正しさ」は保証しない。
JSONを使うなら、virtual columnもあるMSQL8が現時点では良いと思う。
(2018年11月1日追記)
> おまけに、JSONはlongtextのエイリアスのため、
> 「JSONの正しさ」は保証しない。
大変申し訳ありません。
上記は間違っていました。
https://mariadb.com/kb/en/library/json-data-type/
にcheck制約を使うことで、「JSONの正しさ」を保証することが可能でした。
以上
投稿日時:2018年06月14日 22:46
カテゴリー:
mysql
10.3のパラメータ(innodb関連中心)を確認してみたところ、
10.2でなされたような大きな変更は少なく、
10.2でdepricatedになったものが、removedになったりしている感じであった。
10.3の目玉としては、
やはりPL/SQLへの対応なのであろうが、
個人的には、以下が嬉しい。
- sequenceの導入 → nextvalができる
- Instant ADD COLUMN → alter tableの時間抑制に繋がりそう
その他、spider enginにおいて、条件句のpush downも入ったようだ。
以上を踏まえると、10.3への移行する場合、
既に10.2を使っているのであれば、比較的低リスクで移行できる?
と感じています。
10.4の計画も見てみると、
innodb以外のストレージエンジンの機能拡張が候補になっていたりと、
MySQLとの乖離がどんどん大きくなるような気がするが。。
以上
投稿日時:2018年05月29日 00:10
カテゴリー:
mariadb
先月のMySQL8のGAにつづき、
MariaDB10.3がGAされました。
https://mariadb.com/kb/en/library/changes-improvements-in-mariadb-103/
MySQL5.7もそんなにいじってないうちに8が出たので、
これから8を検証しようとしているうちに、10.3が出たのですが、
10.3では気になっていたJSONの改善はなさそうです。
そもそもMySQLでは5.7で導入されたJSONがNativeJSONのため、
登録時のvalidationが効くという特性がありました。
MariaDB10.2で導入されたJSONはText型のaliasのようで、
validationは効かないような感じです。(未検証です。すいません。)
ただ、MariaDBのドキュメント読む限り、Textのパースは高速と記載されています。
MySQL8ではJSONの部分更新機能が導入されました。
これにより、巨大なJSONの一部を更新しても、更新負荷を下げることが可能となり、
もちろん、バイナリログにもそのように記載されるとのことです。
このようなJSONの部分更新がMariaDB10.3でも入るかと期待してましたが、
そのような記載が見あたらず。。
そもそもdynamic columnsに部分更新があるのかどうかにさえ、今気付いた。。
というわけで、
の2つのGAについて、まずはJSONまわりから挙動確認していこうと考えてます。
以上
投稿日時:2018年05月26日 23:47
カテゴリー:
mariadb,
mysql
centos7でstart-stop-daemonが使いたいなと思い、
調べていると、epelレポジトリにdpkgというパッケージがあった。
https://apps.fedoraproject.org/packages/dpkg/
ってわけで、
# yum install dpkg --enablerepo=epel
で、start-stop-daemonコマンド入りのdpkgがインストール可能である。
ソースからビルドする必要あると思っていたのに。。
以上
投稿日時:2018年04月21日 23:37
カテゴリー:
centos,
fedora
Google Computer Cloud(以下、GCP)で、
グローバルロードバランサの背後にnginxを置く場合は、
keepaliveをしておこう。
(参考)
https://blog.percy.io/tuning-nginx-behind-google-cloud-platform-http-s-load-balancer-305982ddb340
これやっておかないと、結構502がでる。
ちなみに、650秒をkeepalive_timeoutにするなら、
ロードバランサのタイムアウトは600秒程度、つまり少し短めがよいとのこと。
実は、AWSのELBも同様。
とはいえ、結構な高負荷にならないと、本事象は目立ってこないので、
なかなか難しいところである。
以上
投稿日時:2018年04月09日 23:07
カテゴリー:
gcp,
nginx
std::unorderd_mapになんでも入れてみた。
とりあえずコード。
class Session
{
private:
std::unordered_map<std::string, std::shared_ptr<void>> values;
public:
template <typename T>
bool getValue(const std::string &name, T *value)
{
std::shared_ptr<void> data = values[name];
if (data != nullptr) {
void* raw = data.get();
*value = *((T*) raw);
return true;
}
return false;
}
template <typename T>
void setValue(const std::string &name, T *value)
{
values.emplace(std::make_pair(name, std::make_shared<T>(*value)));
}
};
struct STest
{
int m1;
std::string m2;
};
int main()
{
STest t1{2, "hoge"};
Session s;
s.setValue<STest>("key", &t1);
STest t2;
if (s.getValue<STest>("key", &t2)) {
std::cout << "m1:" << t2.m1 << ", m2:" << t2.m2 << std::endl; // 2, hoge
}
}
となる。
コンテナから引き出す時に、無駄に1回生成が走るから、
大きいインスタンスでは注意が必要。
で、なぜこれをつくるかというと、
例えばTCPの常時接続の際、
セッションで引き回せると、
簡単に値を保持できるという狙いのため。
とはいえ、ポインタのキャスト多いから、大丈夫かはわからん。。
確実な使い方しないと危なそう。。
以上
投稿日時:2018年04月09日 22:49
カテゴリー:
c/c++
mysqlサーバが突然死して、
クライアント側から見ると生きている状態、つまりハーフCLOSE状態となるのだが、
このとき、他のmysqlサーバに接続している状態で、上記が発生すると、
生きている側のmysqlサーバへの接続がCLOSEされない待ち状態となることがある。
HTTPアクセスからだと、以下のような場合が該当する。
- mysqlサーバAにconnect
- mysqlサーバBにconnect
- mysqlサーバAにbegin
- mysqlサーバBにbegin
- mysqlサーバAにselect for update
- mysqlサーバBにselect
- mysqlサーバBが突然死
- HTTP要求がタイムアウト
このとき、6の応答を待ったまま、処理が続行され、
5のロックが解除されない状態となる。
5のロックを解除するには、
- mysqlサーバAからプロセスをkillする
- HTTPサーバを再起動する
- 実行タイムアウトまで待つ
という方法のいずれかになる。
JDBCではsocketTimeoutといういわゆる実行タイムアウトがあるのだが、
phpのPDOでは、デフォルトで実行タイムアウトの概念はない。
set session 〜 で対応するくらいになるだろう。
しかし、set session 〜 で出来ることは、mysqlサーバのクエリー実行時間の制御であり、
クライアント側のタイムアウト制御はできない。
そこで、あのmysqlndを使っているのであれば、
mysqlnd.net_read_timeout
というパラメータを設定することで、実行タイムアウト例外を検知できるようになる。
apacheであれば、virtualhostに、php-fpmであれば、www.confに設定できる。
このように実行タイムアウト、いわゆるexecution timeoutをちゃんと処理していないことで、
痛い目を見る可能性があるので、このあたりはチェックしておくといざというときに大きな障害を回避できる。
以上
投稿日時:2018年03月15日 23:33
カテゴリー:
mysql,
php
fedora27にて、
- java-1.8.0-openjdk-1.8.0.161-5.b14.fc27.x86_64
- openjfx-8.0.152-12.b04.fc27.x86_64
でjavafxを動かそうと思ったら、全く動かなかった。
そこで、
- jdk1.8-1.8.0_161-fcs.x86_64
いわゆるOracleJDKに変更したら、無事動いた。
javafx以外は問題なさそうなんだけど。。。
ちなみにOracleJDKでも、TextFieldに日本語入力を行おうとすると、
ざっくり以下のようなSIGSGVが起きる。。
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f1128822e11, pid=9155, tid=0x00007f10f8126700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_161-b12) (build 1.8.0_161-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# j com.sun.glass.ui.gtk.GtkView.notifyInputMethodDraw(Ljava/lang/String;III[B)V+16
javafxがんばれ!
以上
投稿日時:2018年03月15日 23:12
カテゴリー:
fedora,
java
fedora27 workstationをUSBメモリにインストールした。
使用したUSBメモリは、 SanDisk Extreme 500 Portable SSD というポータブルUSBで、
こいつがかなり素晴らしい。速い。
※正確にはポータブルSSDなんですが。。
以前、USBメモリに仮想マシンを入れた時は、
遅くて使い物にならなかったが、今回はそのようなことはなく、
clionがバリバリ使える。快適。ブラウザも快適。
ちなみにUSB3ポートに挿して使ってます。
fedora27については、最初にmozcを入れて日本語入力の快適化を図ろうと思ったが、
mozcはもう推奨されないみたいだし、デフォルトで直接入力になるし、
元から入っているのlibkkcで充分だった。これだとデフォルトでかな入力になるしね。でも変換イマイチ。。
そのほか、vscodeも動くし、jetbrainのIDEも問題なさそうだし、
LINUXプログラミングがはかどることでしょう。
以上
投稿日時:2018年03月15日 23:02
カテゴリー:
fedora
javaでfluentdのサーバ、
つまりforwordを受ける側の処理なのだが、
これを書こうと思い、
fluentdのmsgpackのフォーマットを調査していたところ、
以下のライブラリに出会った。
https://github.com/okumin/influent
上記のライブラリはとても素晴らしく、
javaのマルチスレッド、NIOを十二部に活用されていた。
テストをしたところ、十分な負荷にも耐えられ、
高い安定性を誇ることが分かった。
※テストしたのは、バージョン0.3.0
ただ、msgpackを前提としているので、
jsonデータのmsgpack化ではパースエラーになる。
具体的には、公式に提供されているphpライブラリだと、
デフォルトの書き込みフォーマットはjsonであるため、
ここはmsgpackに変更する必要がある。
とはいえ、とても優れたプロダクトであり、
UDPのハートビートにも対応されている点は、
とても利用しやすいと感じた。感謝感謝。
以上
投稿日時:2018年01月20日 22:27
カテゴリー:
java