Slide 1

Slide 1 text

© NEC Solution Innovators, Ltd. 2023 HugePage(LargePage)テストon Windows for PostgreSQL 2023/7/3 第42回 PostgreSQLアンカンファレンス@オンライン NECソリューションイノベータ株式会社 光藤 智

Slide 2

Slide 2 text

1. 自己紹介 2. 本発表の背景 3. HugePageについて 4. テスト目的 5. テスト環境 6. 事前準備 7. HugePageの有効化 8. テスト結果 9. 調査 10.まとめ 目次

Slide 3

Slide 3 text

© NEC Solution Innovators, Ltd. 2023 3 ◆ 氏名:光藤 智(みつふじ さとし) ◆ 会社:NECソリューションイノベータ株式会社 ◆ 経歴:Oracleのポーティング、サポート、技術支援(1994-2023) PostgreSQL、EDB技術支援(2021-2023) 自己紹介

Slide 4

Slide 4 text

© NEC Solution Innovators, Ltd. 2023 4 ◆ Windows環境にPostgreSQLを導入する案件があり、HugePageが利用可能かどう かを確認しておきたい。 ◆ ドキュメントを見ながらテストしたところ、HugePageが使われていないように 見えて、調査したら既知のバグでした。 本発表の背景

Slide 5

Slide 5 text

© NEC Solution Innovators, Ltd. 2023 5 ◆ 仮想メモリで管理されるページは通常4Kbyteですが、大規模な共有メモリを管理 するために、ページのサイズを2MbyteにしたものをHugePage(LargePage)とい います。 ◼ HugePageを採用することで、共有メモリを使う時のPTE(ページ・テーブル・エントリ)で使用 するメモリ量を減らすことが出来ます。 ◼ HugePageを採用することで、 CPU上のTLB(トランスレーション・ルックアサイド・バッファ) の利用効率を高めることができ、TLBミスヒットのオーバーヘッドを減らせます。 ◼ PTEはセッション間で共有されないので、 HugePageを採用しない場合、共有メモリが大きく、 セッション数が多いときにPTEとして使用するメモリ量が大きくなります。PTEは仮想メモリ管 理に使う領域なのでメモリ上に常駐する必要があります。 • PTEの容量計算例 –条件:ページサイズ4Kbyte、共有メモリ16Gbyte、セッション数512 –8byte(PTE1エントリのサイズ) * 16Gbyte/4Kbyte(管理するメモリのページ数) * 512(セッション) = 16Gbyte HugePageについて

Slide 6

Slide 6 text

© NEC Solution Innovators, Ltd. 2023 6 ◆ ページテーブルの構成 HugePageについて 出典:https://linux-mm.org/PageTableStructure

Slide 7

Slide 7 text

© NEC Solution Innovators, Ltd. 2023 7 ◆ HW ◼ プロセッサ Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz 2.30 GHz ◼ 実装 RAM 16.0 GB ◆ OS ◼ エディション Windows 11 Home ◼ バージョン 22H2 ◼ インストール日 2022/10/18 ◼ OS ビルド 22621.819 ◆ PostgreSQL ◼ PostgreSQL14.3 ◼ shared_buffers=4GB ◼ huge_pages=on/off テスト環境(私有PC)

Slide 8

Slide 8 text

© NEC Solution Innovators, Ltd. 2023 8 ◆ gpedit.mscのインストール ◼ HugePageを有効にするには、グループポリシーエディター(gpedit.msc)を利用し、「メモリ内 のページのロック」から、PostgresSQLの起動に利用するユーザーを登録する必要があります。 ◼ グループポリシーエディター(gpedit.msc) はWindows10/11のHomeエディションにはデフォル トで入っていないため、Windows10/11の場合はgpedit.mscを追加インストールする必要があ ります。 ※インストール方法はググると色々出てきます 事前準備

Slide 9

Slide 9 text

© NEC Solution Innovators, Ltd. 2023 9 ◆ HugePageの有効化の方法はPostgreSQLドキュメントのhuge_pagesパラメータ の説明にあります。 ◆ Windowsキー+Rを押して「ファイル名を指定して実行」を起動し、gpedit.msc と入力してOKを押す。 HugePageの有効化(1/6)

Slide 10

Slide 10 text

© NEC Solution Innovators, Ltd. 2023 10 ◆ 「ローカルコンピューターポリシー」→「コンピュータの構成」→「Winowsの 設定」→「セキュリティーの設定」→「ローカルポリシー」→「ユーザー権利の 割り当て」→「メモリ内のページのロック」 HugePageの有効化(2/6)

Slide 11

Slide 11 text

© NEC Solution Innovators, Ltd. 2023 11 ◆ 右クリックで「プロパティ」を開いて「ユーザまたはグループの追加(U)」を押 して「Administrators」を入力、「名前の確認(C)」ボタンを押す。 HugePageの有効化(3/6)

Slide 12

Slide 12 text

© NEC Solution Innovators, Ltd. 2023 12 ◆ 「名前が見つかりません」というエラーが出るので、「オブジェクトの種類 (O) 」ボタンを押して「グループ」にチェックを入れ、「OK」を押す。 HugePageの有効化(4/6)

Slide 13

Slide 13 text

© NEC Solution Innovators, Ltd. 2023 13 ◆ もういちど「ユーザまたはグループの追加(U)」を押して「NETWORK SERVICE」を入力、「名前の確認(C)」ボタンを押す。 「OK」、「OK」を押す。 HugePageの有効化(5/6) ※NETWORK SERVICEはPostgreSQLのサービス以外で も利用されるためPostgreSQLサービスの起動ユーザ を別に作成したほうが良い。

Slide 14

Slide 14 text

© NEC Solution Innovators, Ltd. 2023 14 ◆ 右上の×を押して、ローカルグループポリシーエディターを終了する。 HugePageの有効化(6/6)

Slide 15

Slide 15 text

© NEC Solution Innovators, Ltd. 2023 15 ◆ psqlを500セッションつなぐ ◆ 約1GBのテーブルをSeqScanした後10分sleep テスト方法 --テストデータ作成 drop table test; create table test(col1 integer,col2 char(100)); insert into test (col1,col2) select generate_series(1,10000000),'AAAAAAAAAA; REM テスト用バッチファイル SET PGPASSWORD=postgres for /l %%i in (1,1,500) do ( START /B psql -h localhost -U postgres -p 5432 -f LargePageTest.sql ) pause --テスト用SQL(LargePageText.sql) select count(*) from test; select pg_sleep(600); ¥q

Slide 16

Slide 16 text

© NEC Solution Innovators, Ltd. 2023 16 ◆ SysInternalsのRAMMapを利用する ◆ ダウンロードサイト ◼ https://learn.microsoft.com/ja-jp/sysinternals/downloads/rammap ◆ 確認項目 ◼ 「Use Contents」タブの「Page Table」、「Large Page」 HugePageの使用状況確認方法

Slide 17

Slide 17 text

テスト結果

Slide 18

Slide 18 text

© NEC Solution Innovators, Ltd. 2023 18 ◆ 結果:Page Tableが1GB越え HugePageが無効(huge_pages=off)

Slide 19

Slide 19 text

© NEC Solution Innovators, Ltd. 2023 19 ◆ 結果:HugePageを有効にしてもPage Tableが1GB越え HugePageが有効(huge_pages=on)

Slide 20

Slide 20 text

© NEC Solution Innovators, Ltd. 2023 20 ◆ PostgreSQL 15.1でも試したけど同じようにLargePageが使われていない HugePageが有効(huge_pages=on)

Slide 21

Slide 21 text

© NEC Solution Innovators, Ltd. 2023 21 ◆ OracleでHugePageを有効化するとRAMMapのLarge Pageのところに数字が入る。 OracleでHugePageを有効化

Slide 22

Slide 22 text

調査

Slide 23

Slide 23 text

© NEC Solution Innovators, Ltd. 2023 23 ◆ ¥src¥backend¥port¥win32_shmem.c Large Pageに関連するソースコード if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY) { /* Does the processor support large pages? */ largePageSize = GetLargePageMinimum(); if (largePageSize == 0) { ereport(huge_pages == HUGE_PAGES_ON ? FATAL : DEBUG1, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("the processor does not support large pages"))); ereport(DEBUG1, (errmsg_internal("disabling huge pages"))); } else if (!EnableLockPagesPrivilege(huge_pages == HUGE_PAGES_ON ? FATAL : DEBUG1)) { ereport(DEBUG1, (errmsg_internal("disabling huge pages"))); } else { /* Huge pages available and privilege enabled, so turn on */ flProtect = PAGE_READWRITE | SEC_COMMIT | SEC_LARGE_PAGES; /* Round size up as appropriate. */ if (size % largePageSize != 0) size += largePageSize - (size % largePageSize); } }

Slide 24

Slide 24 text

© NEC Solution Innovators, Ltd. 2023 24 ◆ MapViewOfFileEx のFILE_MAP_LARGE_PAGESの説明は以下 ◼ Windows 10 バージョン 1703 以降では、このフラグは、大きなページのサポートを使用してビューをマッ プする必要があることを指定します。 ビューのサイズは 、GetLargePageMinimum 関数によって報告され る大きなページのサイズの倍数である必要があり、ファイル マッピング オブジェクト は SEC_LARGE_PAGES オプションを使用して作成されている必要があります。 lpBaseAddress に null 以外 の値を指定する場合、値は GetLargePageMinimum の倍数である必要があります。 ◼ https://learn.microsoft.com/ja-jp/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffileex ◆ ⇒ MapViewOfFileExをコールしているところで、 FILE_MAP_LARGE_PAGES をセットしていないのはバグじゃないか? ググっているとこんな情報を発見! /* * Get a pointer to the new shared memory segment. Map the whole segment * at once, and let the system decide on the initial address. */ memAddress = MapViewOfFileEx(hmap2, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0, NULL); if (!memAddress) ereport(FATAL, (errmsg("could not create shared memory segment: error code %lu", GetLastError()), errdetail("Failed system call was MapViewOfFileEx."))); 15.3

Slide 25

Slide 25 text

© NEC Solution Innovators, Ltd. 2023 25 https://www.postgresql.org/message-id/[email protected] BUG #17448: In Windows 10, version 1703 and later, huge_pages doesn't work. The following bug has been logged on the website: Bug reference: 17448 Logged by: Okano Naoki Email address: okano(dot)naoki(at)jp(dot)fujitsu(dot)com PostgreSQL version: 14.2 Operating system: Windows Description: With huge_pages = on, the postgres process does not appear to use large pages. I checked with VMMap if the large pages are used in the following environment. Environment PostgreSQL version: 14.2 Operating system : Windows 10 20H2 On this page (*) says that in Windows 10, version 1703 and later OS versions, you must specify the FILE_MAP_LARGE_PAGES flag with the MapViewOfFile function to map large pages. I think it seems to be the cause that MapViewOfFile() in src/backend/port/win32_shmem.c does not specify FILE_MAP_LARGE_PAGES flag. (*) MapViewOfFileEx function https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffileex FILE_MAP_LARGE_PAGES Starting with Windows 10, version 1703, this flag specifies that the view should be mapped using large page support. The size of the view must be a multiple of the size of a large page reported by the GetLargePageMinimum function, and the file-mapping object must have been created using the SEC_LARGE_PAGES option. If you provide a non-null value for lpBaseAddress, then the value must be a multiple of GetLargePageMinimum.

Slide 26

Slide 26 text

© NEC Solution Innovators, Ltd. 2023 26 ◆ ¥src¥backend¥port¥win32_shmem.c(MapViewOfFileEx部分) PostgreSQL16beta1のソースコード desiredAccess = FILE_MAP_WRITE | FILE_MAP_READ; #ifdef FILE_MAP_LARGE_PAGES /* Set large pages if wanted. */ if ((flProtect & SEC_LARGE_PAGES) != 0) desiredAccess |= FILE_MAP_LARGE_PAGES; #endif /* * Get a pointer to the new shared memory segment. Map the whole segment * at once, and let the system decide on the initial address. */ memAddress = MapViewOfFileEx(hmap2, desiredAccess, 0, 0, 0, NULL); if (!memAddress) ereport(FATAL, (errmsg("could not create shared memory segment: error code %lu", GetLastError()), errdetail("Failed system call was MapViewOfFileEx."))); 16beta1 FILE_MAP_LARGE_PAGES が設定されている

Slide 27

Slide 27 text

© NEC Solution Innovators, Ltd. 2023 27 ◆ 今回のバグは、社内の有識者に見つけてもらったのですが、MLのアーカイブを キーワード検索できるようです。 ◼ https://www.postgresql.org/search/?m=1 調査方法のおさらい

Slide 28

Slide 28 text

まとめ

Slide 29

Slide 29 text

© NEC Solution Innovators, Ltd. 2023 29 ◆ Windows環境でHugePageを使いたい場合は、PostgreSQL16(GA)がリリースさ れるまで待ちましょう! ◆ 現時点で、shared_buffersが大きくなる場合はLinuxを使いましょう! ◆ OSがWindows Server 2019でも同じ結果でした。 ◆ PostgreSQL16が正式リリースされたらまたテストしてみようと思います。 まとめ

Slide 30

Slide 30 text

© NEC Solution Innovators, Ltd. 2023 30 おしまい

Slide 31

Slide 31 text

© NEC Solution Innovators, Ltd. 2023

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content