Background:
In Windows, you can set the CPU affinity of an user process with Start-Process
PowerShell cmdlet and System.Diagnostics.Process.ProcessorAffinity
property like this:
$app = Start-Process -FilePath C:\Windows\System32\mspaint.exe -PassThru $app.ProcessorAffinity = 0x3
Problem:
You cannot set CPU affinity of an PostgreSQL instance with Start-Process
cmdlet and System.Diagnostics.Process.ProcessorAffinity
property, when you start the instance through pg_ctl
.
You will get SetValueInvocationException
like this:
$app = Start-Process 'c:\path\to\PostgreSQL\12\bin\pg_ctl.exe' 'start -D C:\path\to\PostgreSQL\12\data' -PassThru -NoNewWindow $app.ProcessorAffinity = 0x3 "ProcessorAffinity" の設定中に例外が発生しました: "プロセス (15860) が終了したため、要求を処理できません。" 発生場所 行:1 文字:1 + $app.ProcessorAffinity = 0x3 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], SetValueInvocationException + FullyQualifiedErrorId : ExceptionWhenSetting
Cause
In PowerShell, it seems there are no ways to set CPU affinity of an user process when it starts.
ProcessorAffinity
property sets CPU affinity of an user process through Process
object retrieved before it accessed.
In PostgreSQL, pg_ctl
command exits immediately after it starts an PostgreSQL instance. If the process is exited before you set ProcessorAffinity
, you cannot set CPU affinity.
Solution
You have to use start /affinity
command in cmd.exe
instead of Start-Process
.
For example, you can start PostgreSQL instance with CPU affinity from PowerShell like this:
cmd.exe /c "start /affinity 3 /B c:\path\to\PostgreSQL\12\bin\pg_ctl.exe start -w -s -D C:\path\to\PostgreSQL\12\data"