Weitere ähnliche Inhalte
Ähnlich wie Dbts2013 特濃jpoug log_file_sync (20)
Mehr von Koji Shinkubo (12)
Dbts2013 特濃jpoug log_file_sync
- 1. OLTPにつける薬はあるのか?
- log file sync の進化と謎 Insight Technology, Inc.
JPOUG (Japan Oracle User Group)
新久保 浩二 (@kouji_s_0808)
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
- 2. Who am I ?
1.
データベース マニアック担当
2.
Oracle ACE
3.
JPOUG(Japan Oracle User Group)
(http://www.jpoug.org)
本資料に使用されている社名、ロゴ、製品、サービス名およびブランド名
は、該当する各社の登録商標または商標です。本資料の一部あるいは全体
について、許可なく複製および転載することを禁じます。
本資料の内容に関して、不適当な表現や検証が足りない部分もありますが
ご容赦ください。
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
2
- 8. 今日の大事な点 その1 (プロセスの関係)
$ ps -ef | grep sqlplus | grep –v grep
oracle
31699 31645 0 07:55 pts/1
00:00:00 sqlplus
as sysdba
$ pstree -alp 31699
フォアグランド
sqlplus,31699 ¥040 as sysdba
│
└─ oracle,32567 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
$ ps -ef | grep lgwr | grep –v grep
oracle
31595
1 0 Nov02 ?
SHADOWプロセス
(commitする人)
00:22:16 ora_lgwr_oracle11g
今日は、この人たちの
system callを追いかけます。
(latch等は追いかけません)
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
LGWR
(commitされる人)
8
- 9. 今日の大事な点 その2 (セマフォ)
SEMCTL(2)
名前
書式
Linux Programmer’s Manual
SEMOP(2)
SEMOP(2)
semctl - セマフォの制御操作を行なう
名前
semop, semtimedop - セマフォの操作
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
書式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
int semop(int semid, struct sembuf *sops, unsigned nsops);
semctl(2)
他のプロセスを起こす
説明
SEMCTL(2)
Linux Programmer’s Manual
semtimedop(2)
他のプロセスに起こされ
るまで寝る
またはセマフォ集合の
semctl() は、 semid で指定されたセマフォ集合 (semaphore struct sembuf *sops, unsigned nsops,
int semtimedop(int semid, set)
semnun 番目のセマフォに対して、 cmd で指定された制御操作を行なう (集合内のセマフ ォ
struct timespec *timeout);
の番号は 0 から始まる)。
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
この関数は、 cmd の値に依存して、3 個または 4 個の引き数を持つ。引き数が 4 個の場合
、第 4 引き数の型は union semun semtimedop(): _GNU_SOURCE
である。呼び出し元プログラムは、この共用体 (union)
を以下のように定義しなければならない。
説明
union semun {
セマフォ集合 (semaphore set) のメンバーの各セマフォは以下の関連情報を持っている:
int
val;
/* SETVAL の値 */
struct semid_ds *buf;
/* unsigned short semval; /* セマフォ値 */
IPC_STAT, IPC_SET 用のバッファ */
unsigned short *array; /* unsigned SETALL 用の配列 *//* ゼロを待つプロセス数 */
GETALL, short semzcnt;
struct seminfo *__buf; /* unsigned short semncnt; /* 増加を待つプロセス数 */
IPC_INFO 用のバッファ
(Linux
pid_t 固有) */ sempid; /* 最後に操作を行なったプロセス */
};
semop() は semid で指定されたセマフォ集合の選択されたセマフォに対して操作を行う。
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
9
- 10. 一般的なcommit (11.2.0.4)
皆さんご存知のcommitの動作
SHADOW PROCESS
LGWR
------------------------------------------------------------------------------ -----------------------------------------------------------------15:56:52.451519
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN
15:56:55.452866
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN
15:56:58.454356
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) =
15:57:01.125824 update !
15:57:01.129724 update complete
15:57:01.181562 commit !
15:57:01.184351 semctl(1802252, 18, SETVAL, 0x1) = 0
15:57:01.184939
io_submit(140400303636480, 2, {{0x7fb17c6a1480, 0, 1, 0, 267}, …}) = 2
15:57:01.185218 semtimedop(1802252, {{34, -1, 0}}, 1, {0, 100000000}) =
15:57:01.185558
io_getevents(140400303636480, 2, 128, {{0x7fb17c6a1480,…,{0,0}) = 2
15:57:01.185729
semctl(1802252, 34, SETVAL, 0x1) = 0
15:57:01.186277
semtimedop(1802252, {{18, -1, 0}}, 1, {0, 270000000}) = -1 EAGAIN
15:57:01.186385 commit complete
15:57:01.457908
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0} =
Shadow process
LGWR process
多分、log file sync
は shadowプロセスが
2789μ秒
semtimedop(2)で
commit
眠ってから、LGWRに
起こされて、commit
完了を内部的に確認
できるまで
log file sync
semtimedop
semctl
656 μ秒
io_getevents
io_submit
588 μ秒
619 μ秒 171 μ秒
commit
complete
semctl
semtimedop
log file parallel write
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
10
- 11. 深まる謎 その1
プロセスの復帰に関して、OSのプロセス・スケジューラーの影響はあるのか?
log file sync
Shadow process
2789μ秒
commit
semtimedop
semctl
656 μ秒
io_getevents
io_submit
commit
complete
semctl
LGWR process
588 μ秒
619 μ秒 171 μ秒
semtimedop
log file parallel write
もし、影響があるとしたら、Linuxのタイマー割り込み分解性能ってHZ依存Tickで
1msとか4msとか10msとかじゃなかった?
そうなると、環境によっては、残念なこともあるかもしれない?
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
11
- 12. 深まる謎 その1 の考察
まず、RHEL5.6 (2.6.18-238.el5) と OEL6.4(2.6.39-400.209.1.el6uek.x86_64)
で、nanosleep(2)で10回、1μ秒スリープしてみてOSのプロセス・スケジューラーによる遅延を
確認してみる。
最近のOS(検証環境はOracle Linux 6.4 - UEK) だとTicklessカーネル&高精度
タイマーになっていて、昔みたいにHZ依存のTickで世界が縛られることはなくなっているよう。
OS別割り込み分解性能
2.6.39-400.209.1.el6uek.x86_64
3,000
1971
1994
2007
55
2005
2.6.18.238.el5-x86_64
55
2000
1986
2144
1860
1993
μ秒
2,000
1,000
56
55
55
54
61
55
54
0
#1
#2
#3
#4
#5
#6
#7
#8
#9
これだと、OSのバージョンで、相当OLTP性能へ影響が出てしまうはずだが、本当なのか?
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
12
- 15. (余談) commitする人にも事情はあるので
皆さんご存知のcommitのモードは大きく4つ
commitのモードは[IMMEDIATE] と BATCH
commitの待機モードは[WAIT] と NOWAIT
初期パラメーターで指定するなら
10gの頃は
COMMIT_WRITE=“IMMEDIATE,WAIT” とか
11g以降は
COMMIT_LOGGING=IMMEDIATE
COMMIT_WAIT=WAIT とか
SQL単位で指定するなら
commit write immediate wait; とか
皆さんご存知のPL/SQLのcommitのデフォルトモードはBATCH NOWAIT
❝ データベース初期化パラメータCOMMIT_LOGGINGおよびCOMMIT_WAITが
設定されていない場合、非分散トランザクションに対するPL/SQLのデフォルトの
コミット動作はBATCH NOWAITです。❞
PL/SQL言語リファレンス より
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
15
- 16. (余談) commitモードによる違い (11.2.0.4)
PL/SQL で commit のモードを変えながら、100回update + commitを実行
PL/SQL immediate wait
% time
seconds
7.50
0.37
usec/call
calls
errors
syscall
0.000472 5
100
0
semtimedop
0.000023 0
100
0
semctl
PL/SQL batch wait
% time
seconds
usec/call
calls
errors
syscall
0.00
0.00000
0
100
0
semtimedop
0.00
0.00000
0
100
0
semctl
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
16
- 17. (余談) commitモードによる違い (11.2.0.4)
PL/SQL immediate nowait
% time seconds usec/call
このケースだとPL/SQLで実行してい
るので(多分)PL/SQLブロックの抜け
0.39
0.000023 0
る際に、semctl(2)でLGWRを起こ
0.00
0.000000 0
して、semtimedop(2)でlog
bufferのフラッシュ完了を待っている。
PL/SQL batch nowait
普通のSQLだと、semtimedop(2)
% time seconds usec/call
は実行されない。つまり、REDOログ
0.00
0.000000 0
への書き込みの正常性を全くチェック
0.00 しませんので、ご注意を!
0.000000 0
さらに、semtimedop(2)で待たない
PL/SQL ので当然log file syncも(ほぼ)ない
commit (DEFAULT)
% time Seconds usec/call
です。
calls
errors
syscall
100
0
semctl
1
0
semtimedop
calls
errors
syscall
2
0
semctl
1
0
semtimedop
calls
errors
syscall
0.00
0.000000 0
100
0
semctl
0.00
0.000000 0
1
0
semtimedop
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
17
- 18. (余談) commitモードでの速度比較
ご参考までに
commit mode comparison (11.2.0.4)
90
80
76.921
75.878
Elapsed Time (sec)
70
60
50
40
30
20
12.395
10.832
11.739
PL/SQL IMMEDIATE
PL/SQL BATCH NOWAIT
PL/SQL COMMIT
10
0
PL/SQL IMMEDIATE
WAIT
PL/SQL BATCH WAIT
NOWAIT
(DEFAULT)
100,000 commits per every insert
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
18
- 20. 新種のcommit発見! (11.2.0.4)
(少なくとも私は知らなかった)新種のcommitが出てきました!
SHADOW PROCESS
LGWR
------------------------------------------------------------------------------ -----------------------------------------------------------------12:04:11.936399
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN
12:04:14.940066
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) =
12:04:16.385834 update !
semtimedop(2)
12:04:16.388814 update complete
semctl(2)で他の
で眠るかわりに
12:04:16.388954 commit !
プロセスを起こす。
nanosleep(2)
12:04:16.601262 semctl(1802252, 18, SETVAL, 0x1) = 0
ということはしない
で眠っている
12:04:16.601762 nanosleep({0, 466000}, 0x7fff24c2dc80) = 0
12:04:16.602330
io_submit(140400303636480, 2, {{…}}) = 2
12:04:16.602380 nanosleep({0, 466000}, 0x7fff24c2dc80) = 0
12:04:16.602995 nanosleep({0, 466000}, 0x7fff24c2dc80) = 0
12:04:16.603163
io_getevents(140400303636480, 2, 128,…,{0,0}) = 2
12:04:16.603724
semtimedop(1802252, {{18, -1, 0}}, 1, {1, 340000000}) = -1 EAGAIN
12:04:16.604007 commit complete
12:04:17.945345
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN
log file sync
Shadow process
312.308ミリ秒
commit
500 μ秒
618 μ秒
semctl
615 μ秒
nanosleep
1012 μ秒
commit
complete
io_getevents
io_submit
semtimedop
LGWR process
1068 μ秒
833 μ秒
561 μ秒
log file parallel write
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
20
- 21. post/wait と post/polling (11.2.0.x)
11gR2から初期化パラメーター “_use_adaptive_log_file_sync” デフォルトFALSEが
登場しました。
あまり詳細ではないですが、以下に情報があります。
MOS 1541136.1
Waits for "log file sync" with Adaptive Polling vs Post/Wait Choice Enabled
ちなみに11.2.0.3からは、デフォルト TRUEになってました。
パラメーターの名前から分かるとおり、log file sync (つまり、shadow プロセスが、LGWRが
行う、REDOログへの書き込み完了通知を待っている) に関して、
- post/wait (セマフォを使ってLGWRがshadowプロセスにREDOログ書き込み完了を通知)
- post/polling (shadowプロセスがsleepにより自身でREDOログ書き込み完了を確認)
の2つの方式を動的に変更するといった機能です。
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
21
- 22. 深まる謎 その2
で、誰が、どんな理由で、お得なんでしょうか?
post/wait
log file sync
Shadow process
2789μ秒
commit
semtimedop
semctl
656 μ秒
io_getevents
io_submit
commit
complete
semctl
LGWR process
588 μ秒
619 μ秒 171 μ秒
post/polling
semtimedop
log file sync
Shadow process
312.308ミリ秒
commit
500 μ秒
618 μ秒
semctl
615 μ秒
nanosleep
io_getevents
io_submit
1012 μ秒
commit
complete
semtimedop
LGWR process
1068 μ秒
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
833 μ秒
561 μ秒
22
- 25. ん!?なパターンも出てきた (12.1.0.1)
LGWRは新種のLG00(LGWR Worker)へ“左から右に受け流している”
SHADOW PROCESS
LGWR
----------------------------------------------- ---------------------------------------------------18:29:18.575401
semtimedop(622604, {{19,…}}, 1, {3, 0}) = -1 EAGAIN
18:29:21.577337
semtimedop(622604, {{19,…}}, 1, {3, 0}) = -1 EAGAIN
18:29:21.963171
18:29:24.579259
semtimedop(622604, {{19,…}}, 1, {3, 0}) =
18:29:24.964188
18:29:25.658472 update !
18:29:25.661777 update complete
18:29:25.662136 commit !
18:29:25.677012 semctl(622604, 19, SETVAL,…) = 0
18:29:25.677411
semctl(622604, 21, SETVAL, 0x7fff00000001) = 0
18:29:25.677655
semtimedop(622604, {{19,…}}, 1, {1, 910000000}) =
18:29:25.677772
18:29:25.677838 semtimedop(622604, {{33,…}},…) =
18:29:25.678392
18:29:25.678967
18:29:25.679130
18:29:25.679370
18:29:25.679676 commit complete
18:29:27.580963
semtimedop(622604, {{19,…}}, 1, {3, 0}) = -1 EAGAIN
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
LG00
----------------------------------------------------
semtimedop(622604, {{21,…}}, 1, {3,0}) = -1 EAGAIN
semtimedop(622604, {{21,…}}, 1, {3,0}) =
io_submit(139749499707392, 2, {{…}}) = 2
io_getevents(139749499707392, 2, 128,…,{0,0}) = 2
semctl(622604, 33, SETVAL, 0x7fff00000001) = 0
semctl(622604, 19, SETVAL, 0x7fff00000001) = 0
semtimedop(622604, {{19,…}},…) =
25
- 26. 新種のプロセス LGnn (12.1.0.1)
12cR1から初期化パラメーター “_use_single_log_writer” デフォルトADAPTIVEが登場
している。どうやら、Scalable Log Writerとも呼ばれるらしい。
詳細不明ですが、新種のプロセスLGnn(Log Writer Workerプロセス)がデフォルトで2つ起動
され、状況により、複数のWorkerプロセスに、I/Oを任せることで、REDOログへの書き込み
スループットを向上させようとしていると考えられる。
ちなみに、LGnnのプロセス数は”_max_outstanding_log_writes”で制御されている模様
“_use_single_log_writer”の設定として
- TRUE
常にシングル(LGWR)がREDOログへの書き込みを担う。従来の動作
- FALSE
常に一旦LGWRが要求を受けて、LGnnがREDOログへ書き込む。
- ADAPTIVE きっと、両者を動的に切り替える
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
26
- 27. 深まる謎 その3
Scalable Log Writer
log file sync
Shadow process
commit
semctl
semtimedop
commit
complete
LGWR process
semctl
semtimedop
LG00 process
io_submit
io_getevents
semctl
semctl
正直、ADAPTIVE状態では、なかなか、Workerプロセスを使うモードに移行してくれなかった。
さらに、強制的にWorkerプロセスを使うモード(先ほどのスライドの例)だと、プロセス間通信に
よる遅延が増え、全体的なcommitレスポンスは悪化していた。(そういうパターンもあった)
Scalable Log Writerの力はこんなものではないはずなので、今後、要検証。
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
27
- 31. Appendix: seminit.c
#include
#include
#include
#include
<sys/types.h>
<sys/ipc.h>
<sys/sem.h>
<stdio.h>
#define KEY (1492)
int main()
{
int id;
union semun {
int val;
struct semid_ds *buf;
ushort * array;
} argument;
argument.val = 0;
id = semget(KEY, 1, 0666 | IPC_CREAT);
if(id < 0)
{
fprintf(stderr, "Unable to obtain semaphore.¥n");
return 0;
}
if( semctl(id, 0, SETVAL, argument) < 0)
{
fprintf( stderr, "Cannot set semaphore value.¥n");
}
else
{
fprintf(stderr, "Semaphore %d initialized.¥n", KEY);
}
}
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
31
- 32. Appendix: sem_wakeup.c
#include
#include
#include
#include
<stdio.h>
<sys/types.h>
<sys/ipc.h>
<sys/sem.h>
#define KEY (1492)
int main()
{
int id;
int retval;
struct timeval tv;
id = semget(KEY, 1, 0666);
if(id < 0)
{
fprintf(stderr, "Program cannot find semaphore, exiting.¥n");
return 0;
}
printf("Program about to do a V-operation. ¥n");
gettimeofday(&tv, NULL);
printf("%ld:%06ld¥n", (long)tv.tv_sec, (long)tv.tv_usec);
retval = semctl(id, 0, SETVAL, 1);
if(retval == 0)
{
printf("Successful V-operation by program sem_wakeup.¥n");
}
else
{
printf("sem_wait: V-operation did not succeed.¥n");
perror("REASON");
}
}
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
32
- 33. Appendix: sem_wait.c
#include
#include
#include
#include
#include
#include
#include
#include
<stdio.h>
<sys/types.h>
<sys/ipc.h>
<sys/sem.h>
<stdlib.h>
<time.h>
<sys/time.h>
<unistd.h>
gettimeofday(&tv, NULL);
printf("%ld:%06ld¥n", (long)tv.tv_sec, (long)tv.tv_usec);
retval = semtimedop(id, operations, 1, &req);
gettimeofday(&tv, NULL);
printf("%ld:%06ld¥n", (long)tv.tv_sec, (long)tv.tv_usec);
#define KEY (1492)
if(retval == 0)
{
printf("Successful P-operation by program sem_wait.¥n");
printf("Process id is %d¥n", getpid());
}
else
{
printf("sem_wait: P-operation did not succeed.¥n");
}
int main()
{
int id;
struct sembuf operations[1];
int retval;
struct timeval tv;
struct timespec req;
}
req.tv_sec = 10;
req.tv_nsec = 0;
id = semget(KEY, 1, 0666);
if(id < 0)
{
fprintf(stderr, "Program cannot find semaphore, exiting.¥n");
return 0;
}
printf("Program about to do a P-operation. ¥n");
printf("Process id is %d¥n", getpid());
operations[0].sem_num = 0;
operations[0].sem_op = -1;
operations[0].sem_flg = 0;
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
33