Build APM บน Windows ตอนที่ 4: คอมไพล์ MariaDB 11.8 LTS เอง
ตอนนี้ใช้เวลา build ราวครึ่งชั่วโมง แต่ตัวสคริปต์สั้นมาก ส่วนที่ต้องเข้าใจจริงคือ option ที่ตัดทิ้ง กับ collation ที่ต้องล็อกไว้ก่อนสร้างฐานข้อมูลลูกแรก
พอดีผมไล่ build ชุด APM ใหม่ทั้งชุดหลัง PHP ออก patch เมื่อวันที่ 21 ตุลาคม (เรื่องช่องโหว่อ่านได้ที่ php2shell: อัปเดต PHP ด่วน) และถึงตอนของฐานข้อมูลแล้ว ตอนนี้พาคอมไพล์ MariaDB 11.8.9 จาก source ให้ได้โฟลเดอร์ stage\mariadb ที่พร้อมเอาไปติดตั้งในตอนที่ 7 ผมจะเขียนให้ละเอียดจนทำตามได้โดยไม่ต้องเดา ทุกขั้นจะบอกว่าเปิด terminal ตัวไหน อยู่ในโฟลเดอร์ไหน สั่งอะไร ควรเห็นอะไร และตรวจอย่างไรว่าผ่าน
ถ้าเพิ่งเข้ามาตอนนี้ ซีรีส์นี้เริ่มที่ สารบัญ ตอนที่ 1 ถึง 3 เตรียมเครื่องมือ ดาวน์โหลด source และ build Apache ไว้แล้ว ชื่อโฟลเดอร์ทั้งหมดในบทความนี้อิงว่าคุณแตกชุดสคริปต์ไว้ที่ C:\apm-build ตามตอนที่ 1
ตอนนี้ทำอะไร และต้องมีอะไรก่อน
สคริปต์ของตอนนี้คือ scripts\40-mariadb.ps1 ทำงานสามอย่างต่อเนื่อง คือ cmake configure, cmake --build และ cmake --install ผลลัพธ์ไปอยู่ที่ C:\apm-build\stage\mariadb ไม่มีการแตะระบบ ไม่มีการติดตั้งอะไรลง Program Files และไม่ต้องใช้สิทธิ์ admin
จุดที่ทำให้ตอนนี้ง่ายกว่าตอน Apache คือ MariaDB ไม่พึ่ง lib ที่ vcpkg สร้างในตอนที่ 2 เลย มันพกไลบรารีที่ต้องใช้มากับ source เอง (รวมตัว SSL ที่เรียกว่า bundled) ดังนั้นสคริปต์นี้ต้องการแค่ของสี่อย่าง และถ้ามีครบก็รันแยกเดี่ยวได้โดยไม่ต้องรอขั้นอื่น
เวลาและขนาดข้างบนวัดจากเครื่องที่ผมใช้ (Windows 11 x64, i5-12500H 16 threads, RAM 32 GB) ตัว 30 นาทีคือเวลาของรอบแรกที่ HOWTO บันทึกไว้ ตัว 0.3 นาทีคือรอบที่รันซ้ำตอน cache ยังอยู่ ส่วน 669 MB คือขนาดของ stage\mariadb ก่อนตอนที่ 7 ตัด .pdb, lib และ include ออก (ตอน deploy เสร็จเหลือราว 201 MB)
ของที่ต้องมีก่อนรัน มีสี่อย่าง และผมให้ตรวจทีละอย่างในหัวข้อถัดไป
- Visual Studio 2022 Build Tools พร้อมตัวคอมไพเลอร์ MSVC v143 (ตอนที่ 1)
- CMake 3.24 ขึ้นไป และ Ninja (ตอนที่ 1)
- source ของ MariaDB ที่แตกแล้วที่
C:\apm-build\src\mariadb-11.8.9(ตอนที่ 2 ผ่าน00-fetch.ps1) - Strawberry Perl กับ winflexbison ใน
C:\apm-build\toolchain(ตอนที่ 2 เช่นกัน)
ตรวจความพร้อมก่อนเริ่ม
ผมแยกให้ละเอียดเพราะขั้นนี้คือจุดที่คนส่วนใหญ่ล้มกลางทาง build ไปครึ่งชั่วโมงแล้วค่อยรู้ว่าขาดของ
ขั้นที่ 1: เปิด PowerShell 7 แบบ user ปกติ
เปิด Start แล้วพิมพ์ pwsh เลือก PowerShell 7 ห้ามคลิกขวา Run as administrator เพราะสคริปต์ build ทั้งชุดออกแบบให้รันด้วย user ปกติ ตรวจว่าเป็น PowerShell 7 ด้วยคำสั่งนี้
$PSVersionTable.PSVersion.ToString()
ผลที่ควรเห็นคือเลข 7.5 ขึ้นไป (เครื่องผมเป็น 7.6.1) ถ้าเห็น 5.1 แปลว่าเปิด Windows PowerShell รุ่นเก่าอยู่ ให้ปิดแล้วเปิดใหม่
ขั้นที่ 2: เข้าโฟลเดอร์ของชุดสคริปต์
Set-Location C:\apm-build
ไม่มี output คำสั่งนี้เงียบเวลาสำเร็จ ตรวจว่าอยู่ถูกที่ด้วย Get-Location ต้องเห็น C:\apm-build และต้องเห็นไฟล์ build.cmd เมื่อสั่ง Get-ChildItem -Name
ขั้นที่ 3: ตรวจว่ามี source ของ MariaDB
Test-Path C:\apm-build\src\mariadb-11.8.9\CMakeLists.txt
ต้องได้ True ถ้าได้ False ให้กลับไปตอนที่ 2 แล้วรัน pwsh -NoProfile -File scripts\00-fetch.ps1 -Only mariadb ซึ่งจะโหลดเฉพาะ MariaDB มาให้
ขั้นที่ 4: ตรวจว่ามี Strawberry Perl
Test-Path C:\apm-build\toolchain\strawberry\perl\bin\perl.exe
ต้องได้ True เหตุผลที่ต้องเป็นตัวนี้ตัวเดียวมีอยู่ในหัวข้ออธิบายสคริปต์ ถ้าได้ False ให้รัน fetch ด้วย -Only strawberry
ขั้นที่ 5: ตรวจว่ามี win_bison
Test-Path C:\apm-build\toolchain\winflexbison\win_bison.exe
ต้องได้ True ถ้าได้ False ให้รัน fetch ด้วย -Only winflexbison
ขั้นที่ 6: ตรวจ CMake และ Ninja
cmake --version | Select-Object -First 1
ninja --version
ผลที่ควรเห็นบนเครื่องผมคือ
cmake version 4.1.2
1.13.1
เลขอาจใหม่กว่านี้ได้ ขอแค่ CMake ไม่ต่ำกว่า 3.24 ถ้าสองคำสั่งนี้ขึ้น "not recognized" แปลว่า terminal นี้ไม่เห็น PATH ใหม่ ให้ปิดแล้วเปิดใหม่ตามที่ตอนที่ 1 บอกไว้
สคริปต์เรียก Enter-VsEnv จาก lib.ps1 เพื่อโหลด environment ของ MSVC (vcvars64.bat) ให้เอง ใน pwsh ธรรมดาเลยมี cl.exe ใช้ได้ภายในสคริปต์ ถ้าคุณเปิด Developer Command Prompt ไว้ด้วยก็ไม่เสียหาย สคริปต์เช็กแล้วข้ามให้
สคริปต์ทั้งไฟล์ และอ่านทีละท่อน
นี่คือ scripts\40-mariadb.ps1 ทั้งไฟล์จากชุดที่โหลดมา ไม่ได้ตัดอะไรออก
# 40-mariadb.ps1 - build MariaDB server + client (CMake + Ninja, MSVC x64, bundled wolfSSL)
$ErrorActionPreference = 'Stop'
$Root = Split-Path $PSScriptRoot -Parent
. "$PSScriptRoot\lib.ps1"
$Ver = (Get-Content "$Root\versions.json" -Raw | ConvertFrom-Json).sources.mariadb.version
$Src = "$Root\src\mariadb-$Ver"
$Bld = "$Root\build\mariadb"
$Pfx = "$Root\stage\mariadb" -replace '\\','/'
$Log = "$Root\build\logs\mariadb.log"
New-Item -ItemType Directory -Force "$Root\build\logs" | Out-Null
Remove-Item $Log -ErrorAction SilentlyContinue
Enter-VsEnv
# Strawberry perl (native) for build-time scripts; never Git's cygwin perl
$env:Path = "$Root\toolchain\strawberry\perl\bin;$env:Path"
$opts = @(
'-G','Ninja','-DCMAKE_BUILD_TYPE=RelWithDebInfo',"-DCMAKE_INSTALL_PREFIX=$Pfx",
'-DWITH_SSL=bundled','-DWITH_UNIT_TESTS=OFF','-DINSTALL_MYSQLTESTDIR=',
"-DBISON_EXECUTABLE=$Root\toolchain\winflexbison\win_bison.exe",
# engines/plugins dev work never touches - skipping them saves most of the build time
'-DPLUGIN_ROCKSDB=NO','-DPLUGIN_COLUMNSTORE=NO','-DPLUGIN_CONNECT=NO','-DPLUGIN_MROONGA=NO',
'-DPLUGIN_SPIDER=NO','-DPLUGIN_OQGRAPH=NO','-DPLUGIN_SPHINX=NO','-DPLUGIN_DUCKDB=NO',
'-DPLUGIN_S3=NO','-DPLUGIN_AWS_KEY_MANAGEMENT=NO','-DPLUGIN_HASHICORP_KEY_MANAGEMENT=NO',
'-DPLUGIN_EXAMPLE=NO','-DPLUGIN_TEST_SQL_DISCOVERY=NO'
)
Invoke-Step 'mariadb configure' { cmake -S $Src -B $Bld @opts } $Log
Invoke-Step 'mariadb build' { cmake --build $Bld } $Log
Invoke-Step 'mariadb install' { cmake --install $Bld } $Log
& "$Pfx\bin\mariadbd.exe" --version
ท่อนที่ 1: ตัวแปรและ path (บรรทัด 2 ถึง 10)
$Root คือโฟลเดอร์แม่ของ scripts ซึ่งก็คือ C:\apm-build เพราะ $PSScriptRoot ชี้ไปที่ C:\apm-build\scripts แล้ว Split-Path -Parent ถอยขึ้นหนึ่งชั้น เลขเวอร์ชันไม่ได้เขียนตายในสคริปต์ มันอ่านจาก versions.json ที่ sources.mariadb.version (ตอนนี้คือ 11.8.9) นี่คือหัวใจของแนวคิดทั้งซีรีส์ เปลี่ยนเลขในไฟล์เดียวแล้วสคริปต์ชี้ไป source ตัวใหม่เอง
ตัวแปรที่ได้คือ $Src = C:\apm-build\src\mariadb-11.8.9 (source), $Bld = C:\apm-build\build\mariadb (ไฟล์ระหว่าง build) และ $Pfx = C:/apm-build/stage/mariadb (ปลายทางติดตั้ง) สังเกตว่า $Pfx ถูกแปลง \ เป็น / เพราะ CMake ถือ backslash เป็นตัวหลบ (escape) ใน path ถ้าส่ง C:\apm-build\... ไปตรง ๆ มักเพี้ยน
$Log คือไฟล์ log เดียวของขั้นนี้ สคริปต์ลบทิ้งก่อนเริ่มทุกครั้งด้วย Remove-Item เพื่อให้ log เป็นของรอบนี้รอบเดียว
ท่อนที่ 2: Enter-VsEnv และ PATH ของ Perl
Enter-VsEnv (อยู่ใน lib.ps1) รัน vcvars64.bat ในกระบวนการ cmd แล้วดึงตัวแปร environment ทั้งหมดกลับมาใส่ PowerShell ที่รันอยู่ ผลคือเห็น cl.exe, link.exe, Windows SDK ทั้งหมด นอกจากนั้นมันยังตัด path ที่มีคำว่า xampp ออกจาก PATH ของกระบวนการนี้ เพื่อไม่ให้ไบนารีของ XAMPP หลุดเข้ามาปนใน build ถ้าโหลดแล้วยังหา cl.exe ไม่เจอ มันจะ throw ว่า [ERR] MSVC environment not loaded
บรรทัดถัดมาใส่ toolchain\strawberry\perl\bin ไว้หน้าสุดของ PATH ทำไมต้อง Strawberry Perl และห้ามใช้ perl ที่มากับ Git for Windows เพราะ perl ของ Git เป็นรุ่น cygwin มันสร้าง path แบบ Unix (เช่น /c/...) ซึ่งเครื่องมือฝั่ง Windows อ่านไม่ออก ผมเจอเรื่องนี้จริงตอน build OpenSSL ในชุดเดียวกัน (มันพังเพราะเหตุนี้) ส่วน MariaDB เองก็มีสคริปต์ perl ระหว่าง build ดังนั้นกฎเดียวกัน: PATH ต้องเห็น Strawberry ก่อนเสมอ
ท่อนที่ 3: option ของ CMake ทีละตัว
| option | ค่า | ทำอะไร และทำไม |
|---|---|---|
-G Ninja |
Ninja | ใช้ Ninja เป็นตัวสั่ง build แทน MSBuild เร็วกว่าและรัน compile ขนานให้เองตามจำนวน core |
CMAKE_BUILD_TYPE |
RelWithDebInfo |
optimize เหมือน Release แต่เก็บ .pdb ไว้ ถ้า mariadbd.exe ล่มจะมีข้อมูลให้ debug ตอนที่ 7 ตัด .pdb ออกตอน deploy |
CMAKE_INSTALL_PREFIX |
C:/apm-build/stage/mariadb |
ปลายทางของ cmake --install |
WITH_SSL |
bundled |
ใช้ wolfSSL ที่มากับ source ซึ่งเป็นค่ามาตรฐานของ MariaDB บน Windows ไม่ต้องพึ่ง OpenSSL ภายนอก และผลคือ @@have_ssl ได้ YES |
WITH_UNIT_TESTS |
OFF |
ไม่ build unit test ที่เรา build เพื่อใช้งาน ไม่ได้พัฒนา MariaDB |
INSTALL_MYSQLTESTDIR |
(ว่าง) | ค่าว่างแปลว่าไม่ติดตั้งโฟลเดอร์ชุดทดสอบ mysql-test ลง stage |
BISON_EXECUTABLE |
...\win_bison.exe |
ตัวสร้าง parser ของภาษา SQL ต้องใช้ bison Windows ไม่มีมาให้ เลยชี้ไปยัง winflexbison ที่ตอนที่ 2 ดาวน์โหลดไว้ |
ส่วนก้อน PLUGIN_*=NO เป็นการตัด engine และ plugin ที่เครื่อง dev ไม่ได้ใช้ ตามคอมเมนต์ในสคริปต์ว่าช่วยลดเวลา build ได้มาก ตัวเลขเวลาที่ประหยัดจริงผมไม่ได้วัดไว้ (ไม่ได้ build แบบเปิดครบมาเทียบ) ขอไม่ระบุตัวเลข
| plugin ที่ปิด | คืออะไรคร่าว ๆ |
|---|---|
ROCKSDB |
storage engine แบบ LSM-tree |
COLUMNSTORE |
engine เก็บข้อมูลแบบคอลัมน์สำหรับงานวิเคราะห์ |
CONNECT |
engine ที่อ่านข้อมูลภายนอกเป็นตาราง |
MROONGA |
engine ค้นหาข้อความเต็มรูปแบบ |
SPIDER |
engine กระจายตารางข้ามหลายเซิร์ฟเวอร์ |
OQGRAPH |
engine สำหรับข้อมูลแบบกราฟ |
SPHINX |
ตัวเชื่อมกับ Sphinx search |
DUCKDB |
plugin ที่เกี่ยวกับ DuckDB (ชื่อตาม option ใน source ของ 11.8) |
S3 |
engine เก็บตารางบน S3 |
AWS_KEY_MANAGEMENT, HASHICORP_KEY_MANAGEMENT |
ตัวจัดการกุญแจเข้ารหัสผ่าน AWS และ HashiCorp |
EXAMPLE, TEST_SQL_DISCOVERY |
ตัวอย่างและตัวทดสอบสำหรับนักพัฒนา MariaDB |
ที่ยังอยู่ครบคือ InnoDB, Aria, MyISAM และ engine หลักอื่น ๆ ที่เว็บทั่วไปใช้ ผมไล่ดูโฟลเดอร์ lib\plugin ของผลลัพธ์จริงก็ยังเห็น ha_archive.dll, ha_blackhole.dll, ha_federated.dll และ plugin ฝั่ง auth ครบ ถ้าวันหลังคุณต้องการ engine ตัวไหนที่ปิดไว้ ก็แก้ =NO เป็นตัวนั้นแล้ว build ใหม่ได้ (ผมยังไม่ได้ลองเปิดตัวใดเลยเลยไม่รับรองว่าแต่ละตัว build ผ่านบน Windows)
ท่อนที่ 4: Invoke-Step ห่อทุกคำสั่ง
สามบรรทัดที่ขึ้นต้นด้วย Invoke-Step ทำงานตามนี้ พิมพ์ [..] ชื่อขั้น ก่อน แล้วรันคำสั่งโดยต่อท้ายทุก output ลงไฟล์ log (*>> $Log) พอเสร็จ ถ้า exit code ไม่ใช่ 0 จะพิมพ์ 30 บรรทัดท้ายของ log ออกจอแล้ว throw ข้อความ [ERR] ชื่อขั้น failed rc=... (log: ...) ถ้าเป็น 0 พิมพ์ [OK] ชื่อขั้น
นี่คือเหตุผลที่หน้าจอของคุณจะนิ่งสนิทเป็นครึ่งชั่วโมงระหว่าง [..] mariadb build กับ [OK] mariadb build ไม่ใช่ค้าง ทุกอย่างกำลังไหลเข้าไฟล์ log ตัวอย่างบรรทัดจริงที่เห็นในไฟล์นั้น (ผมแก้ path ให้เป็น C:\apm-build)
-- Running cmake version 4.1.2
-- MariaDB 11.8.9
-- Will download and bundle pcre2
-- Build files have been written to: C:/apm-build/build/mariadb
[1/95] Building C object libmariadb\libmariadb\CMakeFiles\mariadb_obj.dir\ma_errmsg.c.obj
มีสองเรื่องในบล็อกนี้ที่ต้องบอก เรื่องแรกคือบรรทัด Will download and bundle pcre2 แปลว่าขั้น configure ต้องต่ออินเทอร์เน็ต เพราะ MariaDB ไปดึง PCRE2 ของมันมาเอง (คนละตัวกับ PCRE2 ของ vcpkg ในตอนที่ 2) ถ้าเครื่องคุณออกเน็ตไม่ได้ในขั้นนี้ configure จะล้ม เรื่องที่สองคือ log ที่ผมยกมาเป็นของรอบที่รันซ้ำตอน cache อยู่ ตัวเลข [1/95] เลยเล็ก ผมไม่ได้เก็บ log รอบแรกที่ build จากศูนย์ไว้ คาดว่าตัวเลขทั้งหมดของรอบแรกจะใหญ่กว่านี้มาก แต่ขอย้ำว่านั่นคือการคาด ไม่ใช่ตัวเลขที่วัดมา
ใน log ยังมีบรรทัดแบบ Could NOT find CURL, Could NOT find LZ4, Could NOT find LZO ฯลฯ ตอน configure สิ่งเหล่านี้เป็น lib เสริมของ client ที่ไม่ได้บังคับ ไม่ใช่ error ขั้น configure ในรอบของผมจบด้วย Configuring done และ Generating done ตามปกติ
ท่อนที่ 5: บรรทัดสุดท้ายของสคริปต์
& "$Pfx\bin\mariadbd.exe" --version พิมพ์รุ่นของไบนารีที่เพิ่ง install เป็นการยืนยันครั้งแรกว่าไฟล์ออกมาจริง บนเครื่องผมได้บรรทัดนี้ (path ท้องถิ่นผมแก้เป็น C:\apm-build)
C:\apm-build\stage\mariadb\bin\mariadbd.exe Ver 11.8.9-MariaDB for Win64 on AMD64 (Source distribution)
คำว่า (Source distribution) ตรงนี้คือหลักฐานว่าเรา build เอง ไม่ใช่ไบนารีสำเร็จรูปจาก mariadb.org
รันจริงทีละขั้น
ขั้นที่ 1: รันสคริปต์
ที่ terminal หน้าต่างเดิม (PowerShell 7 แบบ user ปกติ ยังอยู่ใน C:\apm-build) สั่ง
pwsh -NoProfile -File scripts\40-mariadb.ps1
ถ้าคุณใช้ build.cmd อยู่แล้วและมันล้มที่ขั้นนี้ ให้ใช้ build.cmd -From mariadb ซึ่งจะรันขั้นนี้ ต่อด้วย imagemagick และ php ตามลำดับของ build-all.ps1
ผลที่ควรเห็นทันทีคือบรรทัดเดียว
[..] mariadb configure
ขั้นที่ 2: เปิด terminal ตัวที่สองไว้ดู log (ทางเลือก แต่ผมแนะนำ)
เปิด PowerShell 7 อีกหน้าต่างหนึ่ง (user ปกติ) แล้วสั่ง คำสั่งนี้ใช้ได้เมื่อมีไฟล์ log แล้ว ซึ่งจะเกิดภายในไม่กี่วินาทีหลังขั้นที่ 1
Get-Content C:\apm-build\build\logs\mariadb.log -Tail 5 -Wait
ผลที่ควรเห็นคือ 5 บรรทัดท้ายของ log แล้วหน้าจอจะวิ่งต่อเมื่อมีบรรทัดใหม่ หยุดดูด้วย Ctrl+C การหยุดตรงนี้ไม่กระทบ build ในหน้าต่างแรก
ขั้นที่ 3: รอ configure จบ
ใช้เวลาไม่นาน (รอบที่ผมวัดตอน cache อยู่ใช้ configure 1.8 วินาที รอบแรกจะนานกว่านั้นเพราะต้องดึง PCRE2 และสร้างไฟล์ของ Ninja) ผลที่ควรเห็น
[OK] mariadb configure
[..] mariadb build
ถ้าขึ้น [ERR] mariadb configure failed ให้ดู 30 บรรทัดที่สคริปต์พิมพ์ต่อท้าย แล้วไปที่หัวข้อ "ถ้าพังตรงนี้"
ขั้นที่ 4: รอ build ราว 30 นาที
ระหว่างนี้ CPU จะเต็มทุก core พัดลมจะดัง และ terminal หน้าต่างแรกนิ่ง นี่คือปกติ ใช้หน้าต่าง log ที่เปิดไว้ดูความคืบหน้า ตัวเลขหน้าบรรทัดแบบ [1234/2000] คือขั้นที่ Ninja ทำเสร็จ/ทั้งหมด ห้ามปิดหน้าต่างแรกและห้ามให้เครื่อง sleep (ตั้ง Power & sleep เป็น Never ชั่วคราวก่อนเริ่มถ้าเป็นโน้ตบุ๊ก)
ถ้าเผลอปิดหรือไฟดับกลางทาง ไม่เป็นไร รันขั้นที่ 2 ซ้ำได้เลย Ninja จะต่อจากไฟล์ที่ทำเสร็จแล้ว (รอบรันซ้ำของผมใช้ 0.3 นาที) แต่ log จะถูกลบเริ่มใหม่ตามบรรทัด Remove-Item $Log
ขั้นที่ 5: รอ install จบ
ผลที่ควรเห็นเมื่อทุกอย่างผ่าน
[OK] mariadb build
[..] mariadb install
[OK] mariadb install
C:\apm-build\stage\mariadb\bin\mariadbd.exe Ver 11.8.9-MariaDB for Win64 on AMD64 (Source distribution)
ขั้นที่ 6: ตรวจไฟล์ผลลัพธ์
Get-ChildItem C:\apm-build\stage\mariadb\bin\mariadb*.exe -Name
ผลที่ควรเห็นอย่างน้อยห้าตัวนี้ (ลำดับอาจต่างเล็กน้อย)
mariadb-admin.exe
mariadb-dump.exe
mariadb-install-db.exe
mariadb.exe
mariadbd.exe
ในโฟลเดอร์ bin ของผมมีไฟล์ทั้งหมด 71 ไฟล์ ถ้าของคุณมีเลขใกล้เคียงนี้ก็วางใจได้
ทดสอบรันบนพอร์ต 3399 แล้วปิดให้สะอาด
ผมไม่ปล่อยให้ผ่านโดยดูแค่ว่ามีไฟล์ ต้องได้เห็นเซิร์ฟเวอร์ตอบ query จริงก่อน ทดสอบนี้สร้าง datadir ชั่วคราวแยกจากของจริง ใช้พอร์ต 3399 (ไม่ชนกับ MySQL/MariaDB ตัวอื่นที่อาจรันอยู่บน 3306) และลบทิ้งตอนจบ ทำใน terminal หน้าต่างเดิม ยังเป็น user ปกติ
ขั้นที่ 1: ตั้งตัวแปรสอง path
$M = "C:\apm-build\stage\mariadb\bin"; $D = "C:\apm-build\build\test-mariadb-data"
ไม่มี output ตัวแปรนี้อยู่ใน terminal หน้าต่างนี้เท่านั้น ถ้าปิดหน้าต่างระหว่างทางต้องตั้งใหม่
ขั้นที่ 2: สร้าง datadir ทดสอบ
& "$M\mariadb-install-db.exe" --datadir=$D --port=3399
คำสั่งนี้ initialize ฐานข้อมูลเปล่า (สร้างฐานระบบ mysql ฯลฯ) ใช้เวลาไม่กี่วินาที ผมไม่ได้เก็บข้อความ output ของมันไว้ เลยไม่ยกมา วิธีตรวจคือดูว่ามีไฟล์ config ถูกสร้างในโฟลเดอร์นั้น
ขั้นที่ 3: ตรวจว่า datadir ถูกสร้าง
Test-Path "$D\my.ini"
ต้องได้ True เพราะ mariadb-install-db เขียน my.ini ลงใน datadir ให้ และเป็นไฟล์ที่ขั้นถัดไปจะใช้เปิดเซิร์ฟเวอร์
ขั้นที่ 4: เปิดเซิร์ฟเวอร์เบื้องหลัง
$p = Start-Process "$M\mariadbd.exe" -ArgumentList "--defaults-file=$D\my.ini","--console" -PassThru -WindowStyle Hidden
ไม่มี output และไม่มีหน้าต่างใหม่เพราะสั่งซ่อนไว้ -PassThru เก็บ process ไว้ในตัวแปร $p เพื่อใช้ตรวจทีหลัง --console ให้ log ออกที่ console ของ process (ซึ่งถูกซ่อน)
ขั้นที่ 5: รอให้เซิร์ฟเวอร์ขึ้น
Start-Sleep 6
หกวินาทีพอสำหรับเครื่องผม ถ้าเครื่องคุณช้ากว่าและขั้นถัดไปขึ้นว่าต่อไม่ได้ ให้รอเพิ่มอีกสิบวินาทีแล้วสั่งขั้นถัดไปซ้ำ
ขั้นที่ 6: ถามเวอร์ชันและ SSL
& "$M\mariadb.exe" -uroot --port=3399 --protocol=tcp -e "select version(), @@character_set_server, @@have_ssl"
ผลที่ควรเห็น
version() @@character_set_server @@have_ssl
11.8.9-MariaDB utf8mb4 YES
บรรทัดนี้ยืนยันสามเรื่องพร้อมกัน เลขรุ่นถูกต้อง ชุดอักขระตั้งต้นเป็น utf8mb4 และ SSL ถูกคอมไพล์เข้ามา (WITH_SSL=bundled ทำงาน) ผู้ใช้ root ไม่มีรหัสผ่านในฐานทดสอบนี้ ซึ่งเป็นค่าตั้งต้นของ mariadb-install-db
ขั้นที่ 7: ปิดเซิร์ฟเวอร์ด้วยคำสั่งของมันเอง
& "$M\mariadb-admin.exe" -uroot --port=3399 --protocol=tcp shutdown
ไม่มี output เมื่อสำเร็จ ผมไม่ใช้ Stop-Process กับ MariaDB เพราะการฆ่า process ทิ้งตรง ๆ ทำให้ InnoDB ไม่ได้ flush ข้อมูลให้เรียบร้อย shutdown ให้มันปิดตัวเองตามขั้นตอน
ขั้นที่ 8: ยืนยันว่า process หายไปแล้ว
$p.HasExited
ต้องได้ True ถ้าได้ False รอสองสามวินาทีแล้วสั่งซ้ำ ถ้ายังไม่ปิด ให้ดูหัวข้อ "ถ้าพังตรงนี้"
ขั้นที่ 9: ลบ datadir ทดสอบ
Remove-Item $D -Recurse -Force
ไม่มี output ตรวจว่าหายแล้วด้วย Test-Path $D ต้องได้ False
ฐานทดสอบข้างบนใช้ค่า default ของ mariadb-install-db เลยยังไม่ได้ล็อก collation ผลของ @@collation_server ที่ล็อกแล้วอยู่ในหัวข้อถัดไป ซึ่งวัดจากเครื่องที่ deploy ตามตอนที่ 7 แล้ว
my.ini และเหตุผลที่ต้องล็อก collation
ตอนที่ 7 (deploy.cmd) จะเอา templates\my.ini ในชุดสคริปต์ไปแทนค่า placeholder แล้ววางที่ C:\APM\mariadb\my.ini จากนั้น mariadb-install-db คัดลอกมันไปไว้ใน datadir อีกที ไฟล์ที่เซิร์ฟเวอร์อ่านตอนรันจริงคือ C:\APM\data\mysql\my.ini ตอนนี้ผมขอแสดงไว้ก่อนเพราะมันตัดสินเรื่องที่ย้อนทีหลังยาก
เพราะไฟล์ที่เซิร์ฟเวอร์ใช้จริงคือสำเนาใน datadir การแก้ C:\APM\mariadb\my.ini หรือ template อย่างเดียวไม่มีผล (เช่นเปลี่ยนพอร์ตฐานข้อมูลแล้วเซิร์ฟเวอร์ยังฟังพอร์ตเดิม) kit รุ่นก่อนบ่าย 22 ต.ค. มีบั๊กนี้ ตอนนี้ deploy.cmd -ResetConfig คัดลอก mariadb\my.ini ทับ data\mysql\my.ini ให้ด้วย รายละเอียดอยู่ในตอนที่ 7 อีกเรื่องที่เจอใน deploy รุ่นเก่า คือโฟลเดอร์ mariadb\lib\plugin หายไป (plugin อย่าง ha_archive และ auth_ed25519 เลยไม่มี) เพราะคำสั่งคัดลอกตัดทุกโฟลเดอร์ชื่อ lib ทิ้ง แก้ใน kit ใหม่แล้ว
# APM my.ini - MariaDB 11.8 (dev box). Placeholders are filled in by scripts\90-deploy.ps1.
# mariadb-install-db copies this into <datadir>\my.ini, which is the file the server runs with.
[client-server]
port = {{DB_PORT}}
[client]
default-character-set = utf8mb4
[mariadbd]
basedir = "{{APM_ROOT}}/mariadb"
datadir = "{{APM_ROOT}}/data/mysql"
bind-address = 127.0.0.1
port = {{DB_PORT}}
# Keep new tables importable into a MariaDB 10.6 production server: 11.x would default to utf8mb4_uca1400_ai_ci,
# which 10.6 does not know -> dumps from APM would fail there.
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
character_set_collations = utf8mb4=utf8mb4_unicode_ci
sql_mode = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
lower_case_table_names = 2
max_allowed_packet = 256M
max_connections = 200
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_file_per_table = 1
log-error = "{{APM_ROOT}}/logs/mariadb/mariadb.err"
slow_query_log = 1
slow_query_log_file = "{{APM_ROOT}}/logs/mariadb/slow.log"
long_query_time = 2
{{DB_PORT}} กับ {{APM_ROOT}} ยังเป็นตัวแทน ตอนที่ 7 จะถูกแทนด้วยพอร์ต 3307 และ C:/APM ให้ ไม่ต้องแก้เอง
สามบรรทัดที่เป็นเหตุผลของไฟล์นี้
เซิร์ฟเวอร์ production ที่ผมต้องย้ายข้อมูลไปมาหา APM เป็น MariaDB 10.6 ส่วน MariaDB 11.8 ตั้งต้น collation ของ utf8mb4 เป็น utf8mb4_uca1400_ai_ci ซึ่ง 10.6 ไม่รู้จัก ผลคือถ้าเปิด APM แบบไม่แตะอะไร ตารางที่สร้างใหม่ทุกตารางจะผูกกับ collation นั้น และ dump ที่ออกจาก APM จะเอาไป import บน production ไม่ได้ (คอมเมนต์ในไฟล์เขียนเหตุผลไว้เช่นกัน) ผมเลยล็อกสามบรรทัด
ค่าเริ่มต้นของ 11.8
ตารางใหม่ได้ utf8mb4_uca1400_ai_ci ฝั่ง dump ระบุ collation นี้ไว้ในคำสั่ง CREATE TABLE ฝั่ง production 10.6 ไม่รู้จัก ต้องไล่แก้ไฟล์ dump ทุกครั้ง
utf8mb4_unicode_ci
ตารางใหม่ทุกตารางใช้ collation ที่ 10.6 รู้จัก dump ข้ามไปข้ามมาได้โดยไม่ต้องแก้ไฟล์ พฤติกรรมการเรียงลำดับตัวอักษรก็เท่ากับเซิร์ฟเวอร์จริง
character-set-server = utf8mb4ตั้งชุดอักขระเริ่มต้นของเซิร์ฟเวอร์collation-server = utf8mb4_unicode_ciตั้ง collation เริ่มต้นของเซิร์ฟเวอร์character_set_collations = utf8mb4=utf8mb4_unicode_ciบังคับให้ชุดอักขระ utf8mb4 จับคู่กับutf8mb4_unicode_ciเสมอ แม้ใครเขียนCHARSET utf8mb4โดยไม่ระบุ collation เอง ตัวแปรนี้มีให้ใช้ตั้งแต่สาย 11.x และบรรทัดนี้คือตัวที่กันไม่ให้ค่าเริ่มต้นใหม่ของ 11.8 หลุดเข้ามาทางประตูหลัง
ส่วนตัวผมถือว่าการล็อกที่ต้นทางถูกกว่าการแก้ทีหลังมาก เพราะ collation ถูกเขียนลงทุกตารางตอน CREATE TABLE ถ้าลืมแล้วสร้างฐานไปสิบลูก ต้อง ALTER TABLE ย้ายกลับทีละตาราง ตรงข้าม การใส่สามบรรทัดนี้ก่อนสร้างลูกแรกใช้เวลาไม่ถึงนาที
ตรวจผลหลัง deploy
ขั้นนี้ทำได้หลังตอนที่ 7 เท่านั้น (ตอนนี้ยังไม่มี C:\APM) ผมใส่ผลที่วัดมาไว้ให้เห็นก่อน ว่าเมื่อไฟล์ถูกใช้จริงแล้วต้องได้อะไร เริ่มเซิร์ฟเวอร์ด้วย Start-Process C:\APM\mariadb\bin\mariadbd.exe -ArgumentList '--defaults-file=C:\APM\data\mysql\my.ini' แล้วถาม
C:\APM\mariadb\bin\mariadb.exe -uroot --port=3307 --protocol=tcp -e "select version(), @@collation_server, @@have_ssl, @@bind_address"
version() @@collation_server @@have_ssl @@bind_address
11.8.9-MariaDB-log utf8mb4_unicode_ci YES 127.0.0.1
ปิดด้วย C:\APM\mariadb\bin\mariadb-admin.exe -uroot --port=3307 --protocol=tcp shutdown สังเกตสองอย่าง @@collation_server เป็น utf8mb4_unicode_ci ตามที่ล็อก และ @@bind_address เป็น 127.0.0.1 แปลว่า MariaDB ฟังเฉพาะในเครื่อง ไม่เปิดให้เครื่องอื่นในเครือข่ายต่อเข้ามา
ค่าอื่นในไฟล์ ที่ควรรู้
| ค่า | ความหมาย |
|---|---|
bind-address = 127.0.0.1 |
ฟังเฉพาะ loopback เหมาะกับเครื่อง dev |
sql_mode = STRICT_TRANS_TABLES,... |
ปฏิเสธค่าที่ไม่ถูกต้องแทนการแอบตัดค่าให้ ใกล้เคียงกับพฤติกรรมของเซิร์ฟเวอร์จริง |
lower_case_table_names = 2 |
บน Windows เก็บชื่อตารางตามที่พิมพ์ แต่เทียบแบบไม่สนตัวพิมพ์ใหญ่เล็ก |
max_allowed_packet = 256M |
รับ query/แถวขนาดใหญ่ได้ (เช่น import dump ที่มี blob) |
max_connections = 200 |
จำนวนการเชื่อมต่อพร้อมกันสูงสุด |
innodb_buffer_pool_size = 1G |
หน่วยความจำ cache ของ InnoDB ตั้งไว้พอดีกับเครื่อง dev ถ้า RAM คุณน้อยกว่า 8 GB ให้ลดลง |
innodb_log_file_size = 256M |
ขนาด redo log |
slow_query_log = 1, long_query_time = 2 |
บันทึก query ที่ช้ากว่า 2 วินาที ไปที่ logs\mariadb\slow.log |
ถ้าพังตรงนี้
ขั้นนี้ผมไม่เจอ error ระหว่าง build ครั้งที่วัดผล รายการข้างล่างเลยมีสองแบบ แบบแรกคืออาการที่ HOWTO บันทึกไว้จริง แบบที่สองเป็นเหตุที่อ่านได้จากสคริปต์ ซึ่งผมระบุไว้ในคอลัมน์ที่มาว่าไม่ได้เจอเอง
| อาการ | สาเหตุ | วิธีแก้ | ที่มา |
|---|---|---|---|
| ขั้น build หรือ OpenSSL พังด้วย path แปลก ๆ แบบ Unix | PATH มี perl ของ Git (เป็น cygwin) นำหน้า Strawberry | ใช้ perl ใน toolchain\strawberry เท่านั้น สคริปต์ใส่ให้หน้าสุดแล้ว ถ้ารัน cmake เองด้วยมือต้องตั้ง PATH เองเหมือนกัน |
เจอจริง (ตอน build OpenSSL) |
[ERR] Visual Studio 2022 with C++ x64 tools not found (see https://linuxthai.org/article/apm-build-windows-1-prepare-tools) |
lib.ps1 ใช้ vswhere หา Visual Studio 2022 ที่มี component C++ x64 แล้วไม่เจอ (ไม่ว่า edition ไหนหรือติดตั้งที่ path ไหนก็หาได้ ถ้ามี component นี้) |
เช็กขั้น 1.5 ในตอนที่ 3 หรือเปิด Visual Studio Installer แล้วติ๊ก workload C++ ตามตอนที่ 1 ไม่ต้องแก้สคริปต์ | อ่านจาก lib.ps1 |
[ERR] MSVC environment not loaded |
เจอ Visual Studio แล้ว แต่หลังรัน vcvars64.bat ยังไม่มี cl.exe |
กด Repair ใน Visual Studio Installer แล้วรันใหม่ | อ่านจาก lib.ps1 |
| configure ล้มทันทีว่าหา bison ไม่เจอ | ไม่มี toolchain\winflexbison\win_bison.exe |
pwsh -NoProfile -File scripts\00-fetch.ps1 -Only winflexbison แล้วรันใหม่ |
อ่านจากสคริปต์ |
| configure ล้มที่ขั้นดึง PCRE2 | ออกอินเทอร์เน็ตไม่ได้ในขั้น configure | ต่อเน็ตแล้วรันใหม่ | อ่านจาก log (Will download and bundle pcre2) |
| ขั้น build หยุดกลางคัน (ไฟดับ ปิดหน้าต่าง) | process ถูกฆ่า | รันสคริปต์ซ้ำ Ninja ทำต่อจากเดิม | วัดจริง (รันซ้ำ 0.3 นาที) |
| build ช้ากว่า 2 เท่าของที่บอก | Defender สแกนไฟล์ .obj หลายหมื่นไฟล์ |
เพิ่ม exclusion ตามตอนที่ 1 | HOWTO |
ขั้นทดสอบ: mariadbd ไม่ขึ้นหรือ query ต่อไม่ได้ |
พอร์ต 3399 ถูกใช้อยู่ หรือรอไม่พอ | ตรวจด้วย Get-NetTCPConnection -LocalPort 3399 แล้วเปลี่ยนเลขพอร์ตทั้งในขั้นสร้างและขั้นต่อ หรือรอเพิ่ม |
เหตุที่คาดจากวิธีทดสอบ ผมไม่ได้เจอเอง |
Remove-Item ลบ datadir ไม่ได้ |
mariadbd ยังค้าง ล็อกไฟล์อยู่ |
ตรวจ $p.HasExited ถ้ายัง False ค่อยใช้ Stop-Process -Id $p.Id เป็นทางสุดท้าย แล้วลบใหม่ |
เหตุที่คาดจากวิธีทดสอบ ผมไม่ได้เจอเอง |
ถ้าเจอข้อความ Unknown collation: 'utf8mb4_uca1400_ai_ci' ตอน import dump เข้า MariaDB รุ่นเก่า นั่นคือเรื่อง collation ในหัวข้อก่อนหน้า (ผมไม่ได้ทดลองให้เกิด error นี้ซ้ำ ข้อความนี้เขียนจากความรู้ของพฤติกรรมของ MariaDB ไม่ได้มาจาก log ของผม)
ฐานทดสอบ root ไม่มีรหัสผ่าน และ my.ini ของ APM ผูกกับ 127.0.0.1 ไว้ด้วยเหตุผลนี้ ถ้าคุณจะแก้ bind-address เพื่อให้เครื่องอื่นต่อเข้ามา ต้องตั้งรหัสผ่านให้ root และจำกัดผู้ใช้ก่อนทุกครั้ง นี่คือเครื่องมือสำหรับเครื่อง dev
เช็กลิสต์ก่อนไปตอนที่ 5
ทำให้ครบทุกข้อก่อนค่อยไปต่อ ถ้าข้อไหนไม่ผ่านให้กลับไปทำข้อนั้นก่อน
- สคริปต์ปิดท้ายด้วย
[OK] mariadb installและบรรทัดVer 11.8.9-MariaDB C:\apm-build\stage\mariadb\bin\mariadbd.exeมีอยู่จริง และmariadb.exe,mariadb-admin.exe,mariadb-install-db.exeอยู่ข้างกัน- ทดสอบบนพอร์ต 3399 ได้ผล
11.8.9-MariaDB utf8mb4 YES $p.HasExitedได้TrueและC:\apm-build\build\test-mariadb-dataถูกลบแล้ว- คุณเข้าใจว่า
templates\my.iniล็อก collation เป็นutf8mb4_unicode_ciเพราะอะไร (ตอนที่ 7 จะ deploy ไฟล์นี้ให้เอง)
ใครอยากได้ APM ไปใช้เลยโดยไม่ต้องคอมไพล์ ผมปล่อยตัวที่ build เสร็จแล้วไว้ที่ github.com/ChonLaWan/APM-Server โหลด APM-1.0.0-win64.zip (ราว 140 MB) จากหน้า Releases เทียบ sha256 กับไฟล์ .sha256 ที่แนบไว้ แตกไว้ที่ไหนก็ได้ แล้วเปิด manager\APMManager.exe ตัว Manager จะเลือกพอร์ต เขียน config ออก cert และสร้างฐานข้อมูลให้เอง มีปุ่ม Check for updates ที่โหลดรุ่นใหม่จาก Releases มาตรวจ sha256 แล้วแทน binary ให้ โดยไม่แตะ config ฐานข้อมูล และเว็บของเรา
สารบัญ · ตอนก่อนหน้า: ตอนที่ 3 คอมไพล์ Apache · ตอนถัดไป: ตอนที่ 5 คอมไพล์ ImageMagick
ตอนถัดไปเป็นหนึ่งในชิ้นที่นานที่สุดของซีรีส์ คือ ImageMagick พร้อม delegate library ราว 40 ตัวที่ต้อง build จาก source ทั้งหมด เพื่อให้ extension imagick ของ PHP มีของใช้ตอนที่ 6 ส่วนเรื่องการตั้งค่า MariaDB เพิ่มเติม (เช่นตั้งรหัสผ่าน root และสร้างผู้ใช้ของแอป) ผมยังไม่ได้เขียนในซีรีส์นี้ เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ
อยากให้เราทำให้ไหม?
ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า
เคยเจองานแบบนี้ไหม? ติดตรงไหน?
มาแลกวิธีกันต่อในบอร์ด LinuxThai



ความคิดเห็น 0
ยังไม่มีความคิดเห็น — เป็นคนแรกเลย