Sigres INSERTを高速化したPostgreSQL 応答時間 秒 90 80 70 各クライアントは1000件のINSERT (新マシン:RPM=7200) 60 50 40 30 20 10 0 1 2 3 4 5 6 7 8 9 10 クライアントの同時アクセス数 20 50 100 性能比 倍 6 環境:新マシン 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10 クライアントの同時アクセス数 20 50 100 何故速くなる?(1/3) ~データ挿入のメカニズム~ つまり、WALを実行しなければ高速化 メモリ メモリ メモリ ディスク ディスク ディスク UPS付メモリ:永続記憶装置 アクセス集約 ランダムアクセス ナイーブ方式 WAL 提案 何故速くなる?(2/3) PostgreSQLの場合は? L(WALInsertLock) XLogInsert R(WALInsertLock) L(WALWriteLock) XLogWrite R(WALWriteLock) WALバッファ (メモリ) L(WALInsertLock) XLogInsert R(WALInsertLock) WALファイル (ディスク) まとめるとはいえ XLogWriteは write と fsync を含むので重そう 何故速くなる?(3/3) やったこと:XLogWriteの消去 • 変更前 XLogCtl->xlblocks[curridx].xrecoff); /* Advance LogwrtResult.Write to end of current buffer page */ LogwrtResult.Write = XLogCtl->xlblocks[curridx]; ispartialpage = XLByteLT(WriteRqst.Write, LogwrtResult.Write); if (!XLByteInPrevSeg(LogwrtResult.Write, openLogId, openLogSeg)) { /* * Switch to new logfile segment. We cannot have any pending * pages here (since we dump what we have at segment end). */ Assert(npages == 0); if (openLogFile >= 0) XLogFileClose(); XLByteToPrevSeg(LogwrtResult.Write, openLogId, openLogSeg); /* create/use new log file */ use_existent = true; openLogFile = XLogFileInit(openLogId, openLogSeg, &use_existent, true); openLogOff = 0; /* update pg_control, unless someone else already did */ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); if (ControlFile->logId < openLogId || (ControlFile->logId == openLogId && ControlFile->logSeg < openLogSeg + 1)) { ControlFile->logId = openLogId; ControlFile->logSeg = openLogSeg + 1; ControlFile->time = time(NULL); UpdateControlFile(); /* * Signal bgwriter to start a checkpoint if it's been too long * since the last one. (We look at local copy of RedoRecPtr * which might be a little out of date, but should be close * enough for this purpose.) * * A straight computation of segment number could overflow 32 * bits. Rather than assuming we have working 64-bit * arithmetic, we compare the highest-order bits separately, * and force a checkpoint immediately when they change. */ if (IsUnderPostmaster) { uint32 old_segno, new_segno; uint32 old_highbits, new_highbits; : • 変更後 #define XLogWrite(…) do { if (…) _XLogWrite(…); } while (0) 280行⇒1行 危険じゃないの? • UPSだけだなんて…fsyncして欲しい! やってます WALバッファ Pgsql-hackers ML • 最初の反応 面白い! 8.3か8.4に マージしよう? Flash環境に 良さそう – Joshua Drake • 最終的な反応 – Tom Lane と Bruce Momijian メモリファイルシステムか バッテリバックアップライト キャッシュで十分では? バッテリバックアップ ライトキャッシュ? • RAM-DISK? – i-ram:遅い メモリファイルシステム 1.20 1.18 環境:新マシン 1.16 1.14 1.12 1.10 1.08 10%~19%の性能改善に留まる 1.06 1 2 3 4 5 6 7 8 9 10 20 50 とはいえ、MFS領域のデータ退避手法は不明 100 FAQと予定 • FAQ – fsync=offとの違いは? • Sigresはログページ切り替え時にfsync発行 – 何でつくったの? • 中間報告会後の飲み会の失言で • 今後の予定 – Sigresの更なる高速化(WALInsertLock) – MySQL falconの高速化 – MySQL MEMORYの永続化 まとめ • UPSを前提としてINSERT/UPDATEを高速 化するPostgreSQL • 8.2.1対応 • 良かったら試してみて下さい – http://sourceforge.jp/projects/sigres/ – DL: 70 – PV: 2470 – 天笠俊之 36 – 北川博之 53
© Copyright 2024 ExpyDoc