スライド 1

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