MySQL(InnoDB)の空振りDeleteでデッドロック

  • このエントリーをはてなブックマークに追加

delete-insertパターンを処理しているところでデッドロックが発生しました。

#<Sequel::SerializationFailure: Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction>

ネクストキーロックやギャップロックは分かっていたのですが、横着して書いたせいか件数チェックをしないでレコードが無い場合でもDELETEを行っていたのが原因です。トランザクション分離レベルはInnoDBデフォルトの「Repeatable Read」です。

トランザクション分離レベルを変更しろという記事を結構見るのですが、トランザクション分離レベルの変更はアプリケーションの設計に大きな影響を与えるため、気軽に変更するのは反対です。今回は、件数を確認して削除対象レコードが存在する場合のみDeleteを実行するようにしました。

# 駄目
db.transaction do
db[:xxx].where(...).delete
db[:xxx].insert
end

# 空振りdeleteを回避する
db.transaction do
if db[:xxx].where(...).count > 0 # for_updateもした方が良い
db[:xxx].where(...).delete
end
db[:xxx].insert
end

参考

今回の件とは直接関係はないけど、分離レベルとロストアップデートの話

国勢調査2020

  • このエントリーをはてなブックマークに追加

渋谷区に住んでいます。
渋谷区の知人の皆が配布期間が始まってから早々に封書が届いている中、一向に届きませんでした。渋谷区は対面での配布は行っておらず封書が投函される事になっています。

Twitterで「国勢調査 来ない」「国勢調査 届かない」で検索すると、届かない人はそれなりに居るみたいです。

時系列

  • 9月28日にコールセンターに電話。区役所に電話して欲しいとのこと。(このコールセンター何のためにあるんだ..)
  • 9月28日に区役所に電話。9月30日まで配布期間が延長されているので待って欲しいとのこと。
  • 9月30日。封書の投函が無いので区役所に電話。住所を伝えたところ、まだこの地区は配布がされていないので、明日、明後日まで待って欲しいとの事。
  • 10月2日。封書が投函されていないので区役所に電話。住所を伝えたところ、まだこの地区は配布されていないとの事。土日に配るからそれでも来ない場合はもう一度電話して欲しいとのこと。
  • 10月5日。封書が投函されていないので、区役所に電話。住所を伝える。週末に配布はしたが住居だと思わなくて投函しなかったとのこと。(何度も住所を伝えてる意味はいったい…)
    • この一連の流れも伝えて、郵送で送って欲しい旨を伝える。明日には届くとの事。
    • ※なお私が住んでいるところは見た目はどう見ても会社ではなく住居です。
  • 10月6日。届かなかった。
  • 10月7日。夕方に封書が届いた。

オンラインで回答するにしても、封書が必要なのが辛い。
自分が住んでいる地区が、配布がまだなのか、配布したが投函されなかったのかをオンラインで確認できるようにして欲しい。まだ配布がされていないのであれば区役所に電話はしないし、スキップされているなら、電話して配布要求できるからです。

5年後の国勢調査は、マイナンバーカードあたりを使って配布物が不要になっている事を望みます。
今回、オンラインで回答できる点は良かったです。

rubyでjavaのoptionalのようなことをしたい

  • このエントリーをはてなブックマークに追加

以下のようなことをもっとスマートに書きたい。

h = {}
node = doc.at_css(".title")
unless node.nil?
h[:title] = node.text
h[:href] = node.attr("href")
end

Ruby2.6にはthenというメソッドが追加されました。これと2.3で追加されたsafe operation nagigatorを利用します。

thenはselfを引数としたブロックを評価し、ブロックの結果を返します。

ret_val = obj.then{ |x| val } # obj == x
# ret_val == val

&.と組み合わせる事でjavaのoptionalみたいな事ができます。orElseみたいな事はできません。

h = {}
doc.at_css(".title")&.then{ |node|
# doc.at_css(".title")の結果がnot nilの場合、nodeに値が入ってこのブロックが実行される
h[:title] = node.text
h[:href] = node.attr("href")
}
# もしくはきちんと戻り値を使ってハッシュを作る
# ただしdoc.at_css(".title")がnilの場合、hがnilになる.
h = doc.at_css(".title")&.then{ |node|
h[:title] = node.text
[ :title, node.text, :href, node.attr("href") ]
}.to_h

DOM操作をするとき、unless nil判定が多くなるので、省略できて便利!

title = node.at_css(".title")&.text

参考

RubyでHashの分割代入をしたい

  • このエントリーをはてなブックマークに追加

Rubyで分割代入をしたい。values_atを使えば出来そう。

h = { :a => 1, :c => 2 }
a, b, c = h.values_at(:a, :b, :c)

# a = 1
# b = nil
# c = 2

さらにRuby2.7では pattern match を使ってNestしたHashもいけるみたい。
ただ、pattern matchは試験実装なので使うとwarningが出ます。

h = { :a => 1, :b => 10 }
h in {a:, b:}
# a = 1
# b = 10

h = { :a => { :b => 100 }}
h in {a:{b:}}
# a => undefined
# b = 100

参考

ロジクールのマウスにPrintScを割り当てる

  • このエントリーをはてなブックマークに追加

ロジクールのマウスM590を利用しています。
このマウスは左側面にボタンが2個ついており、何かの操作を割り当てる事ができます。

ボタンの割り当て設定はLogicool Optionsというソフトを使いますが、PrintScを割り当てる事ができません。

無理矢理設定する

GUIから設定できないなら、設定ファイルを直接弄ってしまおう。
設定ファイルの場所はC:\Users\{ユーザー名}\AppData\Roaming\Logishrd\LogiOptions\devices\です。このディレクトリの下に接続しているデバイス毎にディレクトリがあります。私の場合は6b01b。そのディレクトリの中にある6b01b.xmlが設定ファイルです。

... devices/
6b01b/
6b01b.xml
6b01b.rav
Flow/
6b01b_********.json

該当箇所を見つけるのが難しいですが、最初にキーを適当に設定しておきます。例えばF12を設定します。そしてLogicool Optionsは閉じておきます。
F12のキーコードは123なので、vkey="123"の場所を探します。そしてPrintSc(VK_SNAPSHOT)は44なのでvkey="44"に変更します。(キーコード参考)

このままではLogicool Optionsが設定ファイルを再読み込みしないので、Windowsを再起動します。すると、PrintScが割り当てられた状態でマウスが使えるようになります。

Logicool Options上では以下のようにSys Reqと表示されますが、特に問題は発生していません。

設定ファイルの探し方

レジトストリかファイルに記録しているはずなので、設定を弄ったときにどのレジストリかファイルの操作が行われたのかを監視すれば良いです。MicrosoftのProcess Monitorを使います。
ソフトの使い方はこのページでは説明しません。

NetlifyのTLS証明書の更新が失敗する件

  • このエントリーをはてなブックマークに追加

このようなメールが届いて、CustomDomainのTLS証明書の自動更新が失敗しました。

Title: [Netlify] Failed attempt to renew your TLS certificate

Failed to renew TLS certificate for <my-domain>

The TLS certificate for <my-domain> will expire on Jun 28, 2020. We tried to renew it, but got this error message:

SniCertificate::CertificateInvalidError: Unable to verify challenge for www.hedgehog.studio
We’ll keep trying — in most cases of failure, we succeed on the next attempt. However, it’s still a good idea to check the certificate status in your site’s SSL/TLS settings.

原因はCNAMEで設定している、****.netlify.com****.netlify.appに変更になっていたからです。公式サイトには変更のお知らせはどこにも無く、メールでの通知のみでした。

しかもメールには「No action required: sites without custom domains moving to netlify.app」とあるので、何もしなくて良いんだなとスルーしてました。

対処

  • DNSのCNAMEレコードの変更
before: cname www <my-site>.netlify.com.
after: cname www <my-site>.netlify.app.
  • _redirectsの更新(.appの2行を追加)
http://<my-site>.netlify.app/* https://blog.orz.at/:splat 301!
https://<my-site>.netlify.app/* https://blog.orz.at/:splat 301!

http://<my-site>.netlify.com/* https://blog.orz.at/:splat 301!
https://<my-site>.netlify.com/* https://blog.orz.at/:splat 301!

もしかしたら、失敗はたまたまだったのかもしれないけど、念のため.comから.appに変更しました。

メール本文

Hello,

A reminder that starting April 14, 2020, sites without a custom domain are being moved from your-site.netlify.com to your-site.netlify.app. New websites will also have URLs ending with netlify.app, unless you specify a custom domain.

Why the change? We're investing in the security and stability of our infrastructure, and this step is necessary on that journey.

It's important to note your existing sites will continue to operate properly using their current URLs. We expect some users may have configured redirects. If you have configured redirects on our service referring to your-site.netlify.com directly, we recommend you take action to add a second copy of them for your-site.netlify.app.

If you have no redirects like that, there's no action required on your part, but we wanted to inform you well ahead of the change in case you have any questions. Additional details are provided below if you'd like to read more. Thanks for being part of the Netlify community!

-Team Netlify

Will my current sites continue to work?
Absolutely. Any sites already deployed to your-site.netlify.com will continue to operate, just as they do now. Traffic to any your-site.netlify.com address will be forwarded to your-site.netlify.app seamlessly and automatically, using a 301 redirect. (This tells browsers and search engines that the site has moved, so they know the new location.)

Importantly, we have no plans to ever stop forwarding netlify.com addresses or force a migration. We understand your established domain names and inbound links to your site are important to you. After the update, links to your sites will continue to work, just as they do now. The only change will be that netlify.app will display in the URL bar, whether visitors click on a link or type your site name in directly.

Testing is now enabled—and easy to do.
We've enabled testing for the migration from sitename.netlify.com to sitename.netlify.app and you may start testing it today, especially if:

You browse via yoursitename.netlify.com start using yoursitename.netlify.app
you have redirects or other configuration pointing to or referencing https://yoursitename.netlify.com
Again, there's no action required on your part, but we wanted to inform you the option to test is available.

Will this impact my SEO?
No. Forwarding traffic to a new domain extension using a 301 redirect is a proven technique that search engines are well aware of. Your inbound links will not be affected. Your search engine rankings will not be affected.

What if I have a custom domain?
There will be minimal impact to sites with custom domains, and no need to update your DNS if it's configured according to our standard documented setup. This is true whether you purchased a domain through us or brought it with you from another provider.

Will my site take longer to load?
It takes just a couple of milliseconds to direct a .com URL to .app. Your users will not perceive any additional load time. And since browsers cache 301 redirects, there will be no speed impact for page loads after the first connection.

What about HTTPS?
We’re doing our part for a more secure web. Every Netlify site deployed uses a free certificate from Let’s Encrypt. Your certificates will continue to work and your sites will continue to be encrypted with no action required.

Do I need to update my site or application?
In most cases, no. This change is very unlikely to impact the way your application functions, as all requests will automatically be forwarded to netlify.app on your behalf.

What about new sites?
Any site you deploy after April 14, 2020 will receive a shiny new .app URL that you’ll see displayed in the Netlify dashboard. However, for simplicity’s sake, even new sites will be forwarded to the right place should anyone mistakenly type the netlify.com domain. We want things to be as simple and seamless as possible.

What if I use a proxy in front of Netlify?
Since Netlify operates as a global CDN, we don't encourage customers to use proxies or services like CloudFlare in front of Netlify. Using a non-Netlify proxy isn't a configuration we officially support. (For more details, read the community post 'why not proxy to Netlify.') If you do need to use a third-party proxy, you will want to carefully test your application after the migration. Some proxies expect content returned and won't be successful navigating the 301 redirect.

What if I have questions or concerns? We're here to help! Please join the discussion in the community or if you are on a paid plan including support, you can contact support directly.

2mのUSB-Cケーブル(Display対応, PD対応)

  • このエントリーをはてなブックマークに追加

USB Type Cのケーブルはたくさん種類があります。このサイトが参考になります。

規格もたくさんあって、適当に購入すると、スマホの充電は出来るのだけどPCのDisplay接続には使えなかったり、PDに対応していなかったりするわけです。Amazonでケーブルを購入しようとすると、嘘くさい製品(規格違反の製品)が溢れていて、購買意欲が無くなります。

また、2mのものを探すと途端に製品が無くなります。
その理由は、2m以上になるとThunderbolt3の超高速通信である40Gbpsは非対応となり、その半分の20Gbpsになるからだと思います。ケーブルが長いと超高速通信ができないみたいです。

2mでDisplay接続に使用できるまともなUSB-C<=>USB-Cケーブルを探すのは大変なので、いくつか製品を紹介します。

PDは不要!! 5Gbpsで十分だ!とにかくケーブルを長くしたい。という事であれば、SANWAの5mのリピーターがあります。

参考サイト

Microsoft Wordの設定を全てリセットする方法

  • このエントリーをはてなブックマークに追加

デフォルトのレイアウトを弄っていたら、元に戻せなくなってかなり困ったのでリセットする方法を探しました。なお、再インストールではリセットできませんでした。

リセットの方法

こちらのMicrosoftのページ「Word のユーザー オプションとレジストリ設定をリセットする方法」からファイルをダウンロードします。

ダウンロードしたファイルを実行するだけです。レジストリを弄るので事前にバックアップを取得した方が良いです。

参考サイト

Microsoft Wordで游明朝のまま40行に設定する方法

  • このエントリーをはてなブックマークに追加

レポートを書くときに40文字40行の指定があるわけですが、ググった方法で設定してもうまく設定できない。理由はWindows10の場合はデフォルトの設定がMS明朝ではなく、游明朝だから。行間を固定ポイント指定する記事もよく見かけるけど、図を貼り付けた場合におかしな事(図のレンダリングが不完全になったり、位置がページの上部に突き抜けて見えなくなったり)になるのでその設定方法もNG。

MS明朝にすれば良いという話でもあるが、游明朝での設定方法を調べたのでメモ。

游明朝でうまくいく設定

まずは40行40文字に設定するために、レイアウトページ設定リボンの右下の□のアイコンをクリックして、ページ設定を表示する。

文字数と行数を指定するを選択し、文字数「40」、行数「40」を設定し、OKを押す。

この時点では以下のように行間がすごく広くなってしまう。

ホームスタイル標準を右クリックして変更を選択。

スタイルの変更というダイアログが出るので、左下の書式から段落を選択する。

行間は1行のままで良い。
1ページの行数を指定時に文字を行グリッド線に合わせる(W)という項目のチェックボックスを外す。

すると、1ページ40行として正しく設定される。図の貼り付けも上手くいく。

なお、行間を固定値16.4ptにする方法を多く見かけるが、それをやると図を貼り付けた場合に、以下のようになってしまう。

マルチスレッド対応が入ったRedis6の確認

  • このエントリーをはてなブックマークに追加

簡単に確認してみます。

最初は2台使ってネットワーク越しに確認していたのですが、ネットワーク帯域の上限に達してしまうのでClientとServerは同じサーバで確認しました。なので、ClientとServerの負荷が一緒くたになっていますが、CPUコア数が十分に余っている環境で絶対値ではなく相対的な比較をする事で目を瞑ることにします。負荷試験ではないので。

(仕事でこんな適当な事したら駄目ですよ..!)
実際は自分のワークロードに合わせて検証、MetricsをSnapshotではなくHistogramで見て、ボトルネックや安定動作ラインを探る必要があります。

実は、Redis2~6、ardbの比較もしたのですが、ネットワーク越しでやったためにネットワークがサチってしまったのでお蔵入りにしました。

前提

  • Instance: c5.9xlarge
    • CPUコア数は36です
  • ClientとServerが同居
  • Clientは公式のRedisBenchmarkを利用
    • --threads, -c, -nのパラメータの変更のみでテストの内容はデフォルト
    • そのため、ZSetやLuaの検証は入っていない
    • --threadsはバージョン6から導入されたオプション
  • Serverのパラメータは以下を変更
    • io-threads
    • io-threads-do-reads
  • Kernelパラメータは最低限のネットワーク、メモリ周りを設定。ulimitのopen filesも増やす。

Redisのビルド

Version 6.0.1を使いました。ビルドオプションは以下の通り。

make MALLOC=jemalloc V=1

MetricsはNetDataで取得

https://www.netdata.cloud/

bash <(curl -Ss https://my-netdata.io/kickstart.sh)

設定はglobalセクションのmemory modesaveからramに変更。プロセスを再起動するたびにMetricsがリセットされるので、計測が楽になる。(参考)

MetricsはAPIで取得。
memory modeをramにする事でmetricsが都度リセットできるので、計測期間を気にしないで全期間を取得すれば良い事になる。

curl -s "http://localhost:19999/api/v1/data?format=tsv&chart=system.cpu" > cpu-all.tsv

redis-benchmark (client)

各列の意味は次の通りです。

  • 1: デフォルト設定。つまり io-threadsは無効です。
  • 2-rw: io-threads=2, io-threads-do-reads=yes
  • 2-w: io-threads=2, io-threads-do-reads=no
  • 以下略

ケースその1

redis-benchmark -h 127.0.0.1 -c 1000 -n 1000000 --threads 10

ちゃんとスループットが上がっていますね。

ケースその2

redis-benchmark -h 127.0.0.1 -c 1000 -n 1000000 --threads 50

途中で性能が落ちてきているのは、Instanceの処理限界が来たからです。CPUのグラフしか取得していなかったのでアレですが、24-wの時はLoadAverageが40くらいになっていました。

ケースその3

redis-benchmark -h 127.0.0.1 -c 1000 -n 1000000 --threads 100

その1で十分なので、おまけ。

io-threads, io-threads-do-reads no の説明

io-threads

Redis is mostly single threaded, however there are certain threaded operations such as UNLINK, slow I/O accesses and other things that are performed on side threads.


Now it is also possible to handle Redis clients socket reads and writes in different I/O threads. Since especially writing is so slow, normally Redis users use pipelining in order to speedup the Redis performances per core, and spawn multiple instances in order to scale more. Using I/O threads it is possible to easily speedup two times Redis without resorting to pipelining nor sharding of the instance.


By default threading is disabled, we suggest enabling it only in machines that have at least 4 or more cores, leaving at least one spare core.

Using more than 8 threads is unlikely to help much. We also recommend using threaded I/O only if you actually have performance problems, with Redis instances being able to use a quite big percentage of CPU time, otherwise there is no point in using this feature.


So for instance if you have a four cores boxes, try to use 2 or 3 I/O threads, if you have a 8 cores, try to use 6 threads. In order to enable I/O threads use the following configuration directive:

http://download.redis.io/redis-stable/redis.conf

デフォルトでスレッド化は無効で、少なくとも4コア以上のサーバで動かす時に有効化するのが良く、1コアは残しておくように。つまり4コアの場合は設定を2か3くらいにするのが良く、8コアの場合は6あたりを設定するのが良い。なお、8以上を設定するのはあまり意味がない。

io-threads-do-reads no

Setting io-threads to 1 will just use the main thread as usually.

When I/O threads are enabled, we only use threads for writes, that is to thread the write(2) syscall and transfer the client buffers to the socket. However it is also possible to enable threading of reads and protocol parsing using the following configuration directive, by setting it to yes:

http://download.redis.io/redis-stable/redis.conf

io-threadsを1に設定すると、通常通りメインスレッドを使用する。
io-threadsが有効な場合、書き込み(write(2) syscall)にのみスレッドを使用する。
この設定がyesの場合は、読み込みとプロトコルのパースにもスレッドを使用する。