サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
GPT-4o
qiita.com/kumagi
ARIESとは、WALでページ更新しつつNo-forceかつStealな特性を持ち、Fuzzyなチェックポイントを獲得するという、Disk-Orientedな伝統的データベースでのベストプラクティスを集めた技法である。IBMのFellowであるDr. C.Mohanらによる"ARIES: A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging"という論文が原著のようだ。 IBMのDB2やMircosoftのSQL Serverにて採用されている、とWikipediaには書いてあるが現状の製品の中では様々な改造が加えられて原型を留めてないかも知れない。現にSQL Serverのアーキテクチャはhekatonなどのインメモリ
近年のデータベースはよく「最新のインメモリ技術を採用して高速化」などという宣伝が出回っている。 参考: 既存の概念を覆す!Oracle Database In-Memoryのテクノロジー Vol.1 参考: SQL Server 2016の概要とIn-Memory OLTP の改善点(前編) 従来のデータベースだって世の中のほぼすべてのソフトウェアも最終的には(キャッシュ)メモリの中で計算処理をしているわけで、何をもってして「インメモリ技術」と呼ぶのか誤解を招いているケースが身の回りで多発していた。 ディスクDBの時代 昔、例えばOracleV2が発売した1979年では、NECからPC-8001が発売され、市販されるコンピュータのメモリは64KBとか48KBほどだった。エンタープライズ製品であればMB級のものもあるだろうとは思うがお値段も相当のものだった。 会社の業務を回すにあたって、全デ
昨日様々なトランザクション分離レベルに付いて書いた。 AnomalyとはSerializableでない実行を引き起こす異常状態パターンのことを言う。 弱い分離レベルほどAnomalyが起きやすい。 これから図を交えながらAnomalyについて説明する。 図中の「W(x)」は「xに何らかの値を書き込む」、「R(x)」は「xの値を読む」をそれぞれ意味する。 分かりやすいようにReadは青、Writeは赤色で統一する。 また、Anomalyの被害に遭うのは常にT1に統一する。 Cはコミットを意味する。 Dirty Read Anomaly 未コミットな値を読んでしまうAnomalyの事。Readがロック関係なしに値を読んでしまう場合などに起きる。 T1が書き換えられる最中のxの値を読んでしまっている。もしT2が途中でアボートしたらT1はどこにも存在しない値を読んだ事になってしまう。 READ U
トランザクションのACID特性とはいうものの、これまではIsolationに関わる話しかしてこなかった。 しかしDurability(記録したデータが永続化される)という特性はDBを使う上で魅力的であり欠かすことができないものである。 Strict Two Phase Lock 2PLというプロトコルは「ロックを使うときは成長相と縮退相の2フェーズで扱え」というルールだったが、このプロトコルに愚直に従うだけではDurabilityを達成することはできない。 そこで「縮退相より前にコミット(データの永続化)を行え」という追加ルールを加える事でDurabilityを達成できる。 この追加ルールが加わった2PLをStrict Two Phase Lock(S2PL)と言う。 この説明ではピンと来ないと思うので図で説明すると こんな感じに、縮退相が終わった後でディスクに永続化する場合、もちろんT1
2PLでもS2PLでもロックを獲得・開放する順序の話を規定しているだけで、そのままカジュアルに走らせると悲惨な問題に直面する。デッドロックである。 Tx1: Write(x) Write(y) Tx2: Write(y) Write(x) という2つのトランザクションは、2PLに沿ってロックを記述すると Tx1: Lock(x) Write(x) Lock(y) Write(y) Unlock(x) Unlock(y) Tx2: Lock(y) Write(y) Lock(x) Write(x) Unlock(y) Unlock(x) このようにLockがそれぞれ書き込みの前に追加される。 この二つのトランザクションが並行して走ると、無事にどちらも完走する場合もあるが、停止して動かなくなることもある。 Tx1: Lock(x) Write(x) Lock(y) Tx2: Lock(y) W
実行スケジュールを動的に作成したい Conflict Serializability(CSR)が担保される実行スケジュールはトランザクションの実装上好ましい性質を持っている。 そのCSRを動的に生成する方法の1つがTwo Phase Lock(2相ロックまたは2PL)である。 厳密にはCSRより更に狭い範囲のスケジュールしか許容しないが、詳細はリカバリなどの議論を含むため後日にする。 Two Phase Lockとは、成長相と縮退相の2相からなるロックプロトコルである。 ロックプロトコルとは、複数のロックを獲得・解放する際の取り決め(プロトコル)を規定する物であり、特定のロック実装には依存しない。 Two Phase Lockの規定するプロトコルは以下である。 成長相のあとに縮退相が来なくてはならない。 縮退相のあとに成長相が来る事は許可されていない。 成長相と縮退相はそれぞれ1つずつしか
本来はこの話はトランザクション技術アドベントカレンダー初日に書くべきだったかも知れない。 トランザクションとは「1つ以上の連続した操作の単位」であり、ACID特性を満たすとよく言われている。(というか先日も何度も何度も無意識にACIDという言葉を使っていた) ACIDとは ACID(えいしっど、もしくはあしっどと読む人も居るしどっちでもいいと思う)はWikipediaにも説明があるが、そこの説明は僕にはイマイチだと感じたので僕の言葉で今一度説明する。 Atomicity Consistency Isolation Durabilityの4つがトランザクションの満たすべき性質であると提唱されており、その4つの頭文字を取ってACIDと呼ぶ。それぞれの性質の内容に付いて書くと Atomicityとは トランザクションが残す結果が、すべてのトランザクション内操作が成功したか、もしくはすべて無かった
データベースの歴史は古い。 データベースの黎明期ではメモリの価格は今とは桁違いで、1バイトあたり1円を切るかとかそういうレベルの世界だった。1バイトが1円ということは1MBのメモリが100万円以上するという事である。 また、単純にメモリのサイズも小さく、ハイエンドのメモリフレームでRAMを8MB積んでいるとかそんな世界であった。ちょっと大きな事をやろうとすると8MBを溢れる事は当然想定しなくてはならない。 HDDのランダムIOは非常に遅い。なので1バイト単位でデータを書き換えるよりはメモリで可能な限り書き換えをバッファして、ある程度の大きさでまとめて書き込みを行う事で高速化できる。 PostgreSQLではデータベースの内容をページという(デフォルトでは)8KByteの大きさに切り分けて管理している。 1ページの中にテーブルの中の数行分のデータを入れる事でRDBMSはリレーションを保存して
グループコミットによってトランザクションのスループットを大幅に引き上げる技法について昨日の記事で書いたが、この技法ではロック期間は結局ディスクのヘッドシークの長さになる。 むしろロガーとのコミュニケーションコストやログ待ちの時間を考えると個々のロック保持期間は微妙に長くなってさえいる。 また、各スレッドはロガーによって永続化されるまでトランザクションの完了を待たなくてはならないので、1回のログ操作に詰め込めるトランザクション数はスレッドの数が上限になる。 つまりスループットを上げる為にはより多くのスレッドを並列して動かす必要がある。 更には、ロガーのバッファにトランザクションログを送付する際にも、ロックが衝突する可能性もある。複数のワーカーが同時にロガーにログを送付しようとするとそこもボトルネックになりうる。 そこで提案されているのがAetherである。読みはおそらく「エーテル」で、ファイ
市販されているハードディスクは大半が7200rpmである。 これは毎分7200回転、つまり毎秒120回転する事を意味しており、ハードディスクのヘッドを目的の場所に合わせるランダムアクセスに1/120秒ほど掛かる見込みがあるとも言える。実際HDDのカタログスペックを見てもヘッドシークは10ms程度掛かると見て間違いない。 ざっくり言うと普通のハードディスクは1秒に120箇所以上に書き込む事はできない。(探せば15000rpmのハードディスクもあるけれど倍速くなるわけでもなさそう) ログを書くという事 毎秒120箇所を書き換えれないのに1つのトランザクションが120箇所を更新する内容をすべてそのままディスク上のデータに反映させていたら毎秒1トランザクションしか走らない。それではパフォーマンスが致命的に落ちるので、データベースは可能な限りHDDのヘッドシークを減らす方向に進化してきた。それがログ
Serializablitiyとは? 1. Final State Serializabilityについてポエムトランザクション Serializableとは何か 複数のトランザクションの実行スケジュールが渡された時、その挙動について論じる際の基準の1つがSerializabilityである。と、単純に一言で片付けば良いのだけれど実際にはこの中にも複数の階層と紆余曲折がある。それらについて追っていく。 Final State Equivalency さて、Writeする値はそのトランザクションがそれまでにReadしてきた値から算出された値なので、Write操作は「そこまでのReadを引数に取る多引数関数」と見なす事ができる。説明上、トランザクションの数字と関数に付ける識別子を揃えて表記する。例えばTx1が実行する操作を多引数関数で表す時はF1を用いる。そしてReadは「その前に行われたWr
イントロダクション これは@kumagiが一人でトランザクション技術に関する話をまとめていくアドベントカレンダーである。 トランザクション技術は多岐にわたり、複雑に絡み合い、DBの中で巨大な密結合コンポーネントを生み出している。そのためその中身を語るアドベントカレンダーも完全に順序付けて章立てしていくのは難しい。そのため様々な側面から一日に読めそうな文量の記事毎にまとめてアドベントカレンダーとするので、25日も話題が持つのかはさておき必ずしも記事の区切りは技術としての区切りの良さとは関係がない。 しかも初めの数日はトランザクションが実現する並行制御の理論的側面についての整理を淡々と述べるので退屈になること請け合いだけれど、可能な限り図解しながら説明を尽くすのでわからない所は容赦なくはてブやTwitterなどで書いて貰えたら適宜加筆修正をするつもり。 アドベントカレンダーを書くにあたって参考
こんな感じでdockerグループにユーザを追加することで、dockerコマンドをsudoなしで使えるようにできる。 しかしそれでは動かないという症状に見舞われる事がある。 $ docker ps Cannot connect to the Docker daemon. Is the docker daemon running on this host? $ sudo !! ←こう打つ事で直前のコマンドをsudo付きで再実行できる。 Cannot connect to the Docker daemon. Is the docker daemon running on this host?
背景 リアルタイムにmarkdownをプレビューできてGoogle Docsのようにリアルタイムに共同作業できるHackMDが便利なので特定多数しかアクセス出来ない環境に作りたくなった。 Basic認証を掛ければ当面は大丈夫そうだがHackMDにはどうやらその機能がない。 しかし外からアクセスできてサブドメイン無制限なSSL証明書のある環境を持ってないので、SSL設定済みのnginxの下にlocationを掘ってプロキシさせて走らせる事にした。 めんどくさがらずにサブドメイン用の証明書作って解決してもいいのだろうけれど今回は勉強も兼ねている。 HackMDそのものはDocker-Composeがあるので、Dockerが既に入っている環境なら $ git clone git@github.com:hackmdio/docker-hackmd $ pip install docker-comp
概要 現在僕が使っている開発環境を共有して、少しでもマシな開発環境にするアドバイスが欲しい。 ノウハウとしてはC++寄りだけれど、大抵の言語に横展開可能なテクニックだと思う。 想定されるご意見:IDE使え うちのCLion2016.1.3(CL-145.1617)さん、プロジェクト開いただけでCPUを100%食いつぶしたまま帰ってこないんですが…。静的解析をオフにしてみたけどダメ。そもそも静的解析してくれないならなんのための統合開発環境かっていう話にもなるので、いつかマシになると信じてとりあえずEmacsで開発してるのが今。 環境セット 以下の組み合わせで開発している。 CMake(+Makefile) gtest Emacs watchmedo notify-send(MacならGrowlなりなんなり) CMake しばらくwafも使い込んでいたし、特に不便も感じていなかったけれど、CL
Register as a new user and use Qiita more conveniently You get articles that match your needsYou can efficiently read back useful informationYou can use dark themeWhat you can do with signing up
動機 C++11でカジュアルにスレッドが作れるようになったのに、そのバリア同期手段はboost::barrierかpthread_barrierぐらいしか使えなくてもっと依存のないポータブルな実装が欲しい事があったので書き捨てたものを公開。 condition_variableとnotify_allを使った物が一般的だけれど、短時間で同期できることがわかっている場合にはスピンによる待機が一番パフォーマンスが出るのでスピンにした。 実装 The Art of Multiprocessor Programmingのセンス反転バリアをそのまま実装した。 スレッドローカルストレージをクラスごとにポータブルに作る方法が分からなかったし、そもそもスレッドは開始時にTIDを渡しているのでそれをwait()の引数に渡すようにした。 やりたい事はbooleanの反転だったけれどstd::vector<boo
目的 InnoDBとかMyISAMとかあるけど実際のところ他に何が選べるの?というのが気になったけど、それを調べるそのものズバリの日本語のページが無かったので書く。 手段 +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+-----
@app.route('/v1/target', methods=['POST']) def new_machine(): print(request.data) # => ''
前提 jenkinsを公式リポジトリからダウンロードして実行している場合。 問題 /etc/security/limits.conf などを弄ってjenkinsユーザから触れるulimitの値を変更することができる。一例としてはこんな感じ。
プログラムを書いてて、ベンチマーク時にノイズを除去するためにプロセスにアフィニティを設定したいという状況に遭遇したりします。 アフィニティというのは「このプロセスは2番4番7番目のCPUコアの上でしか実行しないで!」のようにOSに対し明示的に設定するものです。 普通にググってもそのものズバリのサンプルコードがなかったのでここに。 /* ↓実はこのdefineが無いとshed.hの中身が有効にならない */ #define _GNU_SOURCE 1 #include <sched.h> void* work(void* ) { cpu_set_t mask; // 実行可能なCPUをビットマスクで指定する CPU_ZERO(&mask); // まずマスクを全部オフにして CPU_SET(TID, &mask); // TID番目のコアでのみ実行を許可する if (sched_setaff
slim綺麗ですね。 ですがデフォルトのslimで出力されるhtmlは特に何も考えずに使うと一番効率の良い(読みにくい)htmlの体裁になります。 なので config/initializers/slim.rbというファイルでも用意して
症状 Rails4でJavaScript書いてる時に「リロードするとJS走るんだけれど、普通のページ遷移(特にgetリクエストの時)にJSが走らない。ベタ書きしただけのalert("hello")すら出てこない」という状況に遭遇することがあります。 HTML見てもちゃんとJSファイルがロードされているし、動かない理由が無いしリロードすると走る。でもリンクをクリックして移動してる時には何故かJavaScriptが起動しない。 原因 可能性の一つとしてturbolinksを疑ってみましょう。 turbolinksはRails4の高速化の為に導入された機能で、リンクを踏んだ時にページを普通にロードする代わりにJavaScriptでAjaxして何か上手いことしてくれる機能です。 でもコイツが動いてるとデフォルトではjQueryが思い通りに動かなくなる事があります。 解決策 そういう時はここに書いて
Foge.joins(:foo_bar).group('foo_bar.name') .order('count_foo_bars_name desc') .limit(10) .count('foo_bar.name') 記述の順番が直感的ではないので注意。count_foo_bars_nameの部分は一度ActiveRecordが吐き出してるSQL文を見て COUNT(*) AS <この部分> を抜き出してくると良い。 結果作られるSQL文はこんな感じ SELECT COUNT(foo_bar.name) AS count_foo_bars_name, foo_bars.name AS foo_bars_name FROM "Foges" INNER JOIN "foo_bars" ON "foo_bars"."id" = "foges"."foo_bar_id" GROUP BY f
といった具合です。erbで言う<%= @name %>みたいな感じですがこっちのほうがRubyぽくて見やすいです。 ですがJavaScriptに何か埋め込むなどのちょっとトリッキーな事に使おうとした場合、エスケープ処理されるのが邪魔になるケースがあります
class Hoge constructor: () -> console.log "hello"
複数のコミットを積み上げていくうちにpull-requestが長大になっていって追いにくいという事があると思います。 gitにはせっかく歴史改変の機能があるので活用しましょう。 git format-patch でパッチファイルを作る際も1コミットにまとめて置くと1ファイルのみになって管理が楽です。 devブランチに対するpull-reqを作っていて、featというブランチを1コミットにまとめるという作業で例示します。 事前にrebase等を済ませて、devブランチの先端からfeatブランチが伸びて何コミットか積み重なっている状態を前提とします。 $ git branch -M feat tmp_squash # 何でもいい別の名前に変える $ git checkout dev $ git checkout -b feat # devブランチをベースに作リ直すのがポイント $ git me
パフォーマンス上の問題から仕方なくC++で書いてる時にうっかりエスケープシーケンスされたUnicodeに出くわす事があります。知らない人向けに書いておくと、\uXXXX(Xは十六進)の6バイトの形でUnicodeの1文字が表される文字の表記方法です。 あとサロゲートペアってのに気を使う必要があります。 unicode全部は今のところ111万2,064文字分の空間がありWikipediaのUnicode、\uXXXXの16進4文字じゃ6万5536文字しか無くて圧倒的に足りないので、\uXXXX\uXXXXXという2つのペアで1つのunicodeに対応させてる物を言います。 詳しくはこちらutf8のRFCを。 std::stringの形でエスケープシーケンスされたUnicode貰った時にそれを日本語にして表示したいって状況がよくあると思うのでそれを実現する関数書きました。失敗したらfalseが
git ls-filesでリポジトリ管理下のファイル名一覧を獲得し git --no-pager blameで全部の行の作者を行単位で吐き出し grepで自分が作者になってる行を洗い出して wc -lでカウントします。 簡単ですね。 Register as a new user and use Qiita more conveniently You get articles that match your needsYou can efficiently read back useful informationYou can use dark themeWhat you can do with signing up
次のページ
このページを最初にブックマークしてみませんか?
『@kumagiのマイページ - Qiita』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く