วิธีแก้ไข Ubuntu อัปเกรดค้างหรือล้มเหลวระหว่างดำเนินการ
หากการอัปเกรด Ubuntu 24.04 ไป 26.04 หยุดชะงัก อย่าเพิ่งรีบูตเครื่อง เรียนรู้วิธีตรวจสอบสถานะ dpkg กู้คืน screen session และแก้ไขไฟล์ sources เพื่อกู้คืนระบบให้กลับมาใช้งานได้ปกติ
การอัปเกรด Ubuntu ล้มเหลวระหว่างดำเนินการ: ให้ตรวจสอบอาการก่อนเป็นอันดับแรก
การอัปเกรด Ubuntu จาก 24.04 ไปยัง 26.04 ที่ล้มเหลวจะทำให้เซิร์ฟเวอร์ตกอยู่ในสถานะใดสถานะหนึ่งจาก 4 สถานะ ซึ่งแต่ละสถานะมีวิธีแก้ไขที่แตกต่างกัน ตัวอัปเกรดอาจยังคงทำงานอยู่ภายใน screen session ที่คุณขาดการเชื่อมต่อ dpkg อาจถูกสั่งยุติการทำงานในขณะที่แพ็กเกจยังติดตั้งไม่สมบูรณ์ ส่งผลให้ apt ปฏิเสธการติดตั้ง การลบ หรือการอัปเกรดแพ็กเกจใดๆ แม้ว่า apt update และคำสั่งแบบอ่านอย่างเดียว เช่น apt show จะยังคงทำงานได้ตามปกติก็ตาม แหล่งข้อมูลใน apt sources อาจระบุว่าเป็น 26.04 ในขณะที่แพ็กเกจที่ติดตั้งอยู่ยังคงเป็น 24.04 หรือเซิร์ฟเวอร์อาจไม่สามารถบูตได้เลย ให้วิเคราะห์ก่อนว่าคุณกำลังเผชิญกับสถานะใดก่อนที่จะพิมพ์คำสั่งใดๆ เพราะวิธีแก้ไขของสถานะหนึ่งอาจทำให้สถานการณ์ของอีกสถานะหนึ่งแย่ลงได้
มีกฎข้อหนึ่งที่ใช้ครอบคลุมทั้ง 4 สถานะ คือห้ามรีบูตจนกว่าคุณจะทราบสถานะปัจจุบันของ dpkg การรีบูตในระหว่างที่มีการสลับแพ็กเกจเป็นสาเหตุที่ทำให้ปัญหา dpkg ขัดข้องที่แก้ไขได้ กลายเป็นกรณีที่ระบบไม่สามารถบูตได้ซึ่งอยู่ท้ายคู่มือฉบับนี้ และห้ามเริ่มกระบวนการ apt หรือ dpkg ตัวที่สองในขณะที่ตัวแรกอาจยังทำงานอยู่ เพราะการเขียนข้อมูลลงในฐานข้อมูลแพ็กเกจพร้อมกันสองกระบวนการจะทำให้ฐานข้อมูลเสียหาย
คู่มือนี้ตั้งสมมติฐานว่าคุณได้ปฏิบัติตาม คู่มือการอัปเกรดจาก 24.04 ไปยัง 26.04 และได้ทำ snapshot ไว้ก่อนเริ่มดำเนินการ หากคุณไม่ได้ทำไว้ โปรดอ่านส่วนการบูตโดยคำนึงถึงเรื่องนี้ด้วย เนื่องจาก snapshot คือคำตอบสำหรับกรณีที่เลวร้ายที่สุด
การอัปเกรดกำลังทำงานอยู่หรือไม่?
การอัปเกรดจำนวนมากที่รายงานว่าล้มเหลวนั้นแท้จริงแล้วยังคงทำงานอยู่ เซสชัน SSH หลุด เทอร์มินัลกลายเป็นหน้าจอว่างเปล่า แต่ตัวอัปเกรดทำงานต่อไปโดยไม่มีคุณ
do-release-upgrade ถูกสร้างมาเพื่อกรณีนี้ เมื่อทำงานผ่านอินเทอร์เฟซแบบข้อความซึ่งเป็นสิ่งที่เซิร์ฟเวอร์ได้รับ มันจะห่อหุ้มตัวเองไว้ในเซสชัน GNU screen ดังนั้นการอัปเกรดจึงยังคงอยู่แม้จะสูญเสียเทอร์มินัลที่เริ่มการทำงานไปแล้ว นอกจากนี้ เมื่อตรวจพบว่าถูกเริ่มจากเซสชัน SSH มันจะเสนอให้เริ่ม sshd ตัวที่สองบนพอร์ตอื่น (ค่าเริ่มต้นคือ 1022) เพื่อให้คุณยังคงล็อกอินได้หาก SSH daemon หลักเกิดขัดข้องระหว่างการสลับแพ็กเกจ ข้อมูลทั้งสองประการนี้มีความสำคัญในขณะนี้
ให้เชื่อมต่อผ่าน SSH อีกครั้งและมองหาเซสชัน screen ตัวอัปเกรดทำงานภายใต้ sudo ดังนั้นเซสชัน screen จึงเป็นของ root และการใช้ screen -ls ปกติในฐานะผู้ใช้ของคุณจะไม่แสดงรายการเซสชันดังกล่าว
sudo screen -lsscreen -ls จะระบุแต่ละเซสชันว่า attached หรือ detached หากมีรายการปรากฏขึ้น ให้เชื่อมต่อกลับเข้าไป หากเซสชันยังคงระบุว่า attached เนื่องจากเซสชัน SSH ที่ตายไปไม่ได้ปล่อยมันทิ้งไว้ ให้ใช้ -d เพื่อตัดการเชื่อมต่อที่ค้างอยู่นั้นก่อน
sudo screen -d -rหากมีมากกว่าหนึ่งเซสชันในรายการ ให้ใส่ชื่อเซสชันจาก screen -ls ต่อท้าย -r อย่าหวังพึ่ง sudo do-release-upgrade ในการเชื่อมต่อกลับให้คุณ โค้ดที่ค้นหาเซสชัน screen ที่มีอยู่จะอยู่ในตัวอัปเกรดที่ดาวน์โหลดมา และก่อนที่จะดาวน์โหลดสิ่งใด do-release-upgrade จะออกจากโปรแกรมพร้อมข้อความ "Please install all available updates for your release before upgrading" ทันทีที่พบแพ็กเกจที่มีการอัปเกรดค้างอยู่ (ไม่นับรวม phased updates) ซึ่งเป็นสถานะของระบบที่อยู่ระหว่างการสลับแพ็กเกจ เมื่อคุณเชื่อมต่อกลับเข้าไปแล้ว คุณจะกลับเข้าสู่การอัปเกรดที่กำลังทำงานอยู่ ซึ่งมักจะรออยู่ที่พรอมต์เกี่ยวกับไฟล์คอนฟิกที่เปลี่ยนแปลงหรือการรีสตาร์ทบริการ ให้ตอบคำถามนั้นแล้วปล่อยให้มันทำงานจนเสร็จ
หากคุณเริ่มการอัปเกรดภายใน tmux ตามที่คู่มือการอัปเกรดแนะนำ ให้เชื่อมต่อ tmux กลับเข้าไปก่อนด้วย tmux attach เซสชัน screen จะทำงานอยู่ภายในบานหน้าต่าง tmux นั้น คุณจึงเห็นการอัปเกรดได้โดยตรง หากบานหน้าต่างแสดงเพียง shell prompt แสดงว่าตัวอัปเกรดไม่ได้ทำงานอยู่ที่นั่นแล้ว และ sudo screen -ls คือขั้นตอนการตรวจสอบถัดไป
หากพอร์ต SSH หลักปฏิเสธการเชื่อมต่อ ให้ลองใช้พอร์ตสำรอง: ssh -p 1022 user@host daemon นั้นจะมีอยู่เฉพาะในช่วงเวลาของการอัปเกรดเท่านั้น ดังนั้นหากคุณไม่สามารถเข้าผ่านพอร์ตใดพอร์ตหนึ่งได้ ให้ใช้คอนโซลของผู้ให้บริการของคุณแทน จากคอนโซล sudo ss -ltnp จะแสดงว่ากระบวนการ sshd กำลังฟังพอร์ตใดอยู่ และ sudo ufw status จะบอกคุณว่าไฟร์วอลล์อนุญาตให้พอร์ตสำรองผ่านหรือไม่
เมื่อไม่มีเซสชัน screen และไม่มีสิ่งใดรออยู่ที่คอนโซล แสดงว่าการอัปเกรดหยุดทำงานจริง ให้ยืนยันว่าไม่มีสิ่งใดทำงานอยู่บนฐานข้อมูลแพ็กเกจก่อนที่คุณจะเข้าไปจัดการ:
ps -eo pid,etime,cmd | grep -iE '[u]pgrade|[d]pkg|[a]pt'ผลลัพธ์ที่ว่างเปล่าหมายความว่า dpkg ไม่ได้ทำงานอยู่และคุณสามารถดำเนินการซ่อมแซมต่อไปได้ กระบวนการ dpkg หรือ apt ที่มีเวลาทำงานนานและไม่มีเซสชัน screen ให้เชื่อมต่อกลับ แสดงว่ากระบวนการนั้นค้าง ให้รอสักครู่ ตรวจสอบคอนโซลว่ามีคำถามจาก debconf ที่ยังไม่มีใครตอบหรือไม่ แล้วจึงค่อยสั่ง kill กระบวนการนั้น ห้ามลบไฟล์ล็อกภายใต้ /var/lib/dpkg/ หรือ /var/lib/apt/lists/ ในขณะที่กระบวนการยังถือครองไฟล์เหล่านั้นอยู่ ล็อกเป็นสิ่งเดียวที่ป้องกันไม่ให้ผู้เขียนสองรายเขียนข้อมูลทับซ้อนกันจนฐานข้อมูลแพ็กเกจเสียหาย
dpkg ถูกขัดจังหวะและ apt ปฏิเสธการทำงาน
เมื่อ dpkg ถูกสั่งหยุดทำงานในระหว่างการแตกไฟล์แพ็กเกจและการรันสคริปต์ตั้งค่า จะทำให้แพ็กเกจนั้นถูกทำเครื่องหมายว่าดำเนินการไม่เสร็จสิ้น และทิ้งรายการที่ค้างอยู่ในบันทึกที่ /var/lib/dpkg/updates/ คำสั่ง apt ทุกคำสั่งที่ต้องใช้ dpkg lock ซึ่งหมายถึงคำสั่งใดก็ตามที่ติดตั้ง ลบ หรืออัปเกรด จะตรวจสอบบันทึกนั้นก่อนและหยุดทำงานพร้อมกับ dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem. คำสั่งที่ไม่ต้องใช้ lock ดังกล่าว เช่น apt update, apt list, apt show และ apt-cache จะยังคงทำงานได้ตามปกติ คุณจึงยังสามารถตรวจสอบสถานะต่างๆ ได้ ไม่ว่า apt จะแสดงข้อความใดออกมา ขั้นตอนแรกที่ต้องทำคือขั้นตอนเดียวกัน
sudo dpkg --configure -aคำสั่งนี้จะดำเนินการขั้นตอนการตั้งค่าให้เสร็จสิ้นสำหรับทุกแพ็กเกจที่ถูกแตกไฟล์ไว้แต่ยังไม่ได้ตั้งค่า มันจะรันสคริปต์ของผู้ดูแลแพ็กเกจตามลำดับความสัมพันธ์ (dependency) ซึ่งอาจใช้เวลานานในระบบที่อัปเกรดค้างไว้ ดังนั้นควรปล่อยให้มันทำงานจนกว่าจะเสร็จสิ้น หากมันหยุดทำงานที่แพ็กเกจใด ให้จดชื่อแพ็กเกจและสคริปต์ที่ล้มเหลวนั้นไว้ นั่นคือแพ็กเกจที่ทำให้การอัปเกรดของคุณหยุดชะงัก และส่วนถัดไปจะแสดงวิธีอ่านข้อผิดพลาดของแพ็กเกจนั้น
จากนั้นให้ apt ซ่อมแซมความสัมพันธ์ที่ค้างอยู่จากการถูกขัดจังหวะ เนื่องจากบางแพ็กเกจถูกอัปเกรดไปแล้วแต่แพ็กเกจที่จำเป็นต้องใช้ยังไม่ได้อัปเกรด
sudo apt --fix-broken installจากนั้นดำเนินการอัปเกรดต่อจากจุดที่ค้างอยู่:
sudo apt update
sudo apt full-upgradeใช้ full-upgrade แทน upgrade เนื่องจากกระบวนการอัปเกรดเวอร์ชันมีการลบแพ็กเกจออก และคำสั่ง upgrade แบบปกติจะปฏิเสธการลบสิ่งใดก็ตาม โปรดอ่านสรุปที่ apt แสดงก่อนยืนยัน รายการลบจำนวนเล็กน้อยถือเป็นเรื่องปกติ แต่หากรายการนั้นลบ ubuntu-server, systemd, openssh-server หรือแพ็กเกจ kernel ของคุณ ถือว่าไม่ปกติ คุณควรตอบปฏิเสธและตรวจสอบว่าเหตุใด apt จึงต้องการลบสิ่งเหล่านั้นก่อนดำเนินการต่อ
ตรวจสอบผลลัพธ์ก่อนทำสิ่งอื่นใด:
sudo dpkg --audit
sudo apt-get checkdpkg --audit จะแสดงรายการแพ็กเกจที่ยังอยู่ในสถานะเสียหาย และ apt-get check จะรายงานความสัมพันธ์ที่ไม่ครบถ้วน ทั้งสองคำสั่งไม่ควรแสดงผลลัพธ์ใดๆ เมื่อตรวจสอบแล้วว่าไม่มีข้อผิดพลาด ให้รัน sudo apt autoremove เพื่อลบ dependency ที่ติดตั้งอัตโนมัติแต่ไม่มีแพ็กเกจใดใช้งานแล้ว (แพ็กเกจที่ทำเครื่องหมายว่าติดตั้งด้วยตนเองจะยังคงอยู่แม้ไม่มีสิ่งใดใช้งาน) จากนั้นยืนยันการอัปเกรดเวอร์ชันด้วย cat /etc/os-release แล้วรัน sudo update-initramfs -u -k all และ sudo update-grub และค่อยทำการรีบูตหลังจากนั้น
วิธีอ่าน /var/log/dist-upgrade เพื่อหาแพ็กเกจที่ทำให้การอัปเกรดหยุดชะงัก
ตัวอัปเกรดจะเขียนบันทึกทุกอย่างลงใน /var/log/dist-upgrade/ หากคุณรันคำสั่งมากกว่าหนึ่งครั้ง ระบบจะย้ายบันทึกของความพยายามครั้งก่อนหน้าไปยังไดเรกทอรีย่อยที่ตั้งชื่อตามเวลา ดังนั้นให้ตรวจสอบ ls -la /var/log/dist-upgrade/ ก่อนและอ่านไดเรกทอรีที่ตรงกับการรันครั้งที่ล้มเหลว
main.log คือบันทึกการทำงานของตัวอัปเกรดเอง มันจะบันทึกว่าการรันอยู่ในขั้นตอนใดและตัดสินใจอย่างไรเกี่ยวกับแหล่งที่มาของแพ็กเกจ หากตัวอัปเกรดเกิดข้อผิดพลาด (crash) ข้อมูล Python traceback จะอยู่ที่นี่ด้วย ให้อ่านจากบรรทัดท้ายสุด: บรรทัดท้ายๆ จะบอกคุณว่าอยู่ในขั้นตอนใดเมื่อหยุดทำงาน และหากพบ traceback แสดงว่าเครื่องมืออัปเกรดล้มเหลว ไม่ใช่ตัวแพ็กเกจ
apt.log เก็บเหตุผลของตัวแก้ไขความสัมพันธ์ (dependency resolver) ข้อมูลนี้มีรายละเอียดมากและสำคัญเมื่อ apt ปฏิเสธที่จะคำนวณการอัปเกรดตั้งแต่ต้น ซึ่งถือเป็นความล้มเหลวก่อนที่จะมีการแตะต้องแพ็กเกจใดๆ หากการอัปเกรดของคุณดำเนินไปถึงขั้นติดตั้งแพ็กเกจแล้ว คุณมักจะข้ามไฟล์นี้ไปได้
apt-term.log คือไฟล์ที่คุณต้องการหากเกิดความล้มเหลวที่แพ็กเกจ มันจะบันทึกผลลัพธ์จาก terminal ของ dpkg ในระหว่างการอัปเกรด ซึ่งเป็นข้อความเดียวกับที่เลื่อนผ่านหน้าจอคุณ แพ็กเกจสุดท้ายที่ถูกกล่าวถึงก่อนจบไฟล์คือแพ็กเกจที่กำลังทำงานอยู่เมื่อการอัปเกรดหยุดลง และหากสคริปต์ของผู้ดูแลแพ็กเกจล้มเหลว ข้อความแจ้งเตือนของ dpkg จะปรากฏอยู่ที่นั่นพร้อมกับข้อผิดพลาดของสคริปต์ที่อยู่ด้านบน
sudo tail -n 60 /var/log/dist-upgrade/apt-term.log
sudo grep -in 'error' /var/log/dist-upgrade/apt-term.log | tailตรวจสอบเปรียบเทียบกับ /var/log/dpkg.log ซึ่งบันทึกการเปลี่ยนแปลงสถานะและการกระทำที่ dpkg ดำเนินการ โดยมีเวลาประทับกำกับไว้แต่ละรายการ tail -n 30 /var/log/dpkg.log แสดงแพ็กเกจล่าสุดที่ dpkg จัดการและสิ่งที่กำลังทำกับแพ็กเกจนั้น ข้อมูลนี้จะเป็นคำตอบเดียวกันจากแหล่งที่สองก็ต่อเมื่อไม่มีการรัน dpkg หลังจากเกิดความล้มเหลวแล้วเท่านั้น เมื่อคุณรัน dpkg --configure -a หรือ apt --fix-broken install ไปแล้ว รายการของคำสั่งเหล่านั้นจะมาอยู่ท้ายสุด ดังนั้นให้เลื่อนกลับไปดูบรรทัดที่มีเวลาประทับในช่วงที่การอัปเกรดหยุดทำงาน
ความล้มเหลวส่วนใหญ่ในขั้นตอนนี้บนเซิร์ฟเวอร์มักเกิดจากสาเหตุไม่กี่ประการ บริการที่แพ็กเกจพยายามรีสตาร์ทใน postinst ล้มเหลวเนื่องจากไฟล์ config ที่คุณปรับแต่งไว้ และการใช้ systemctl status ร่วมกับ journalctl -xeu บนบริการนั้นจะระบุบรรทัดที่ไม่รองรับ ดิสก์เต็ม ซึ่งมักเกิดกับ /boot ที่มี kernel เก่า หรือ /var ที่มีแคชแพ็กเกจของ apt และ df -h / /boot /var จะแสดงให้เห็น; sudo apt clean จะล้างแคชแม้ในขณะที่ apt ติดขัด และ ดิสก์ที่รายงานว่าเต็มทั้งที่ du บอกว่าไม่เต็ม มีคำอธิบายเฉพาะของมัน แพ็กเกจจาก repository ภายนอกที่ตัวอัปเกรดปิดการใช้งานไปแล้ว อาจมีความสัมพันธ์กับ library ที่ 26.04 ไม่มีให้อีกต่อไป หรือแพ็กเกจที่ถูกล็อกไว้ (apt-mark showhold) ขัดขวางไม่ให้ dependency อัปเดตได้ ให้แก้ไขสาเหตุแล้วรัน sudo dpkg --configure -a อีกครั้ง มันจะทำงานต่อจากจุดที่ค้างไว้
หากแพ็กเกจใดปฏิเสธการตั้งค่าไม่ว่าจะทำอย่างไร และไม่มีสิ่งสำคัญใดที่ต้องพึ่งพาแพ็กเกจนั้น ให้ลบออกแล้วติดตั้งใหม่หลังจากอัปเกรดเสร็จสิ้น:
sudo dpkg --remove --force-remove-reinstreq package-name
sudo dpkg --configure -aใช้คำสั่งนี้กับแพ็กเกจที่คุณระบุชื่อและอธิบายได้เท่านั้น ห้ามใช้กับ library หรือสิ่งใดก็ตามที่อยู่ในห่วงโซ่ความสัมพันธ์ ubuntu-server เพราะการบังคับลบจะข้ามการตรวจสอบที่จะบอกคุณว่ามีสิ่งอื่นเสียหายหรือไม่
แหล่งข้อมูลถูกเปลี่ยนแต่แพ็กเกจยังไม่ถูกอัปเดต
ตัวอัปเกรดจะเขียนทับไฟล์ apt sources ของคุณตั้งแต่ช่วงต้น ก่อนที่จะดาวน์โหลดแพ็กเกจใดๆ หากกระบวนการถูกขัดจังหวะหลังจากจุดนั้น แหล่งข้อมูลจะระบุว่าเป็น 26.04 ในขณะที่แพ็กเกจที่ติดตั้งอยู่ยังเป็นเวอร์ชันผสมกัน ความไม่สอดคล้องนี้ทำให้เครื่องมือต่างๆ สับสน และเป็นสาเหตุที่ do-release-upgrade อาจแจ้งว่าไม่มีรุ่นใหม่ให้ใช้งาน
ให้เปรียบเทียบข้อมูลจากสองแหล่งที่ระบุว่าขณะนี้คุณใช้รุ่นใดอยู่ /etc/apt/sources.list.d/ubuntu.sources คือไฟล์ sources แบบ deb822 ที่เริ่มใช้ใน 24.04 โดยบรรทัด Suites: จะระบุชื่อรหัสของรุ่นที่ใช้ ส่วน /etc/os-release ถูกเขียนขึ้นโดยแพ็กเกจ base-files ซึ่งระบุว่ารุ่นใดที่ถูกติดตั้งอยู่จริง
grep -E '^(Suites|Components):' /etc/apt/sources.list.d/ubuntu.sources
grep -E '^(VERSION_ID|VERSION_CODENAME)=' /etc/os-release
apt-cache policy base-filesมีสามสถานการณ์ที่ต้องพิจารณา: แหล่งข้อมูลยังระบุเป็น 24.04 (ชื่อรหัส noble) และ os-release ยังระบุเป็น 24.04 แสดงว่าการอัปเกรดไม่ผ่านขั้นตอนการตรวจสอบ คุณสามารถรัน sudo do-release-upgrade อีกครั้งหลังจากอ่าน main.log เพื่อหาสาเหตุที่การอัปเกรดหยุดทำงาน เครื่องมือจะปฏิเสธการทำงานหากมีการอัปเดตของ 24.04 ค้างอยู่ หรือหาก /var/run/reboot-required.pkgs ระบุถึง libc6, linux-base หรือแพ็กเกจ linux-image ดังนั้นให้รัน sudo apt full-upgrade และรีบูตเครื่องหากไฟล์นั้นแจ้งเตือนก่อน แหล่งข้อมูลระบุชื่อรหัส 26.04 และ os-release ยังระบุเป็น 24.04 แสดงว่าการสลับแพ็กเกจเริ่มต้นแล้วแต่ถูกขัดจังหวะ การซ่อมแซมด้วย dpkg ในส่วนก่อนหน้าซึ่งจบด้วย apt full-upgrade คือวิธีดำเนินการให้เสร็จสิ้น ห้ามรันตัวอัปเกรดซ้ำในสถานะนี้ เพราะเมื่อมีแพ็กเกจ 26.04 รออยู่ ตัวอัปเกรดจะหยุดทำงานและแจ้งให้คุณติดตั้งการอัปเดตที่มีอยู่ทั้งหมดก่อน แหล่งข้อมูลระบุ 26.04 และ os-release ระบุ 26.04 แสดงว่า base-files เป็นหนึ่งในแพ็กเกจที่อัปเดตสำเร็จ และระบบเรียกตัวเองว่าเป็น 26.04 แล้วแม้ว่าส่วนประกอบส่วนใหญ่จะยังไม่ใช่ก็ตาม
สถานการณ์สุดท้ายคือกับดัก do-release-upgrade ตัดสินว่าคุณใช้รุ่นใดจากข้อมูลเดียวกันกับที่ os-release ระบุ หากไฟล์นั้นระบุว่าเป็น 26.04 แล้ว เครื่องมือจะมองหาเวอร์ชันที่ใหม่กว่า 26.04 เมื่อไม่พบก็จะรายงานว่าไม่มีรุ่นใหม่ให้ใช้งาน เครื่องมือกำลังตอบคำถามโดยอิงจาก os-release ซึ่งข้อมูลใน os-release นั้นไม่ถูกต้อง ให้หยุดใช้ตัวอัปเกรดและดำเนินการต่อด้วย apt: ใช้ sudo apt update ตามด้วย sudo apt full-upgrade ซึ่งจะอัปเกรดแพ็กเกจที่ยังเป็นเวอร์ชัน 24.04 ยกเว้นแพ็กเกจที่ถูก hold ไว้ (apt-mark showhold จะแสดงรายการแพ็กเกจเหล่านี้) และอาจมีการลบแพ็กเกจบางตัวออก ดังนั้นให้อ่านสรุปการทำงานก่อน จากนั้นจึงรัน sudo apt autoremove สาเหตุอื่นๆ ที่ do-release-upgrade รายงานว่าไม่มีรุ่นใหม่ เช่น การตั้งค่า LTS ที่รอรุ่น point release แรก เป็นสิ่งที่ควรตรวจสอบหาก os-release ยังระบุว่าเป็น 24.04
ตัวอัปเกรดจะปิดการใช้งานแหล่งข้อมูลของบุคคลที่สามภายใต้ /etc/apt/sources.list.d/ และเก็บสำเนาสำรองของไฟล์แต่ละไฟล์ที่ถูกแก้ไขไว้ โดยเพิ่มส่วนขยายต่อท้ายชื่อเดิม ให้รัน ls -la /etc/apt/sources.list.d/ และ diff เพื่อเปรียบเทียบไฟล์ต้นฉบับกับไฟล์สำรองเพื่อดูการเปลี่ยนแปลงที่เกิดขึ้นจริง ให้คงสถานะปิดการใช้งานแหล่งข้อมูลของบุคคลที่สามไว้จนกว่าแพ็กเกจของ Ubuntu จะมีความสอดคล้องกัน จากนั้นจึงเปิดใช้งานทีละรายการหลังจากยืนยันแล้วว่าผู้ให้บริการมีแพ็กเกจสำหรับ 26.04 หาก apt update แจ้งเตือนว่ามีการกำหนดค่าแหล่งข้อมูลซ้ำซ้อน แสดงว่ารายการ sources.list เดิมและรายการ ubuntu.sources ใหม่ระบุถึงชุดซอฟต์แวร์เดียวกัน และ ข้อผิดพลาดแหล่งข้อมูลซ้ำซ้อนแบบ deb822 จะอธิบายว่าควรลบรายการใดออก
เซิร์ฟเวอร์ไม่ยอมบูตหลังการอัปเกรด
การรีบูตเป็นช่วงเวลาที่การอัปเกรดที่ไม่สมบูรณ์จะแสดงผลลัพธ์ออกมา สาเหตุที่เป็นไปได้บน VPS ได้แก่ kernel ที่ติดตั้งโดยไม่มี initramfs, การตั้งค่า GRUB ที่ไม่ได้ถูกสร้างใหม่, แพ็กเกจที่ค้างอยู่ระหว่างการตั้งค่าซึ่ง unit ที่ทำงานตอนบูตต้องใช้งาน หรือดิสก์เต็มในขณะที่ dpkg กำลังเขียนข้อมูล
ให้เปิด console ของผู้ให้บริการก่อนที่จะดำเนินการใดๆ เพิ่มเติม มันจะแสดงให้เห็นว่าการบูตหยุดลงที่จุดไหน: เมนู GRUB, kernel panic, การตรวจสอบระบบไฟล์ที่รอการตอบกลับ หรือ systemd emergency shell ที่ถามรหัสผ่าน root การสังเกตเพียงจุดเดียวนี้จะเป็นตัวตัดสินขั้นตอนถัดไป
หากเมนู GRUB ปรากฏขึ้น ให้บูต kernel เวอร์ชัน 24.04 ก่อนหน้าจากเมนูย่อยตัวเลือกขั้นสูง โดยปกติ kernel เก่าจะยังคงถูกติดตั้งไว้จนกว่า autoremove จะทำงาน เมื่อระบบทำงานบน kernel เก่าแล้ว ให้รัน sudo dpkg --configure -a และดำเนินการซ่อมแซมส่วนที่เหลือจากหัวข้อก่อนหน้า จากนั้นรัน sudo update-initramfs -u -k all และ sudo update-grub ก่อนที่จะลองใช้ kernel ใหม่ อีกครั้ง การกู้คืน VPS ที่บูตไม่ขึ้นหลังการอัปเดต kernel ครอบคลุมรายละเอียดด้าน GRUB และ initramfs ไว้แล้ว
หากคุณเข้าสู่ emergency shell ระบบไฟล์ root มักจะถูก mount แบบอ่านได้อย่างเดียว ให้ mount ใหม่และทำการซ่อมแซมแบบเดียวกัน:
mount -o remount,rw /
dpkg --configure -aหากระบบไม่เข้าสู่ shell เลย ให้บูตด้วย rescue image ของผู้ให้บริการ mount ดิสก์ของ VPS แล้วซ่อมแซมผ่าน chroot ให้ค้นหา partition ของ root ด้วย lsblk แทนการเดาชื่อ
lsblk
mount /dev/<root-partition> /mnt
for d in dev proc sys run; do mount --bind /$d /mnt/$d; done
chroot /mnt /bin/bash
dpkg --configure -a
apt --fix-broken install
update-initramfs -u -k all
update-grub
exit
rebootก่อนที่คุณจะเสียเวลาเป็นชั่วโมงใน chroot ให้เปรียบเทียบกับการใช้ snapshot คุณได้ทำ snapshot ไว้ก่อนเริ่ม และการกู้คืนใช้เวลาเพียงไม่กี่นาทีในผู้ให้บริการส่วนใหญ่ จากนั้นคุณค่อยรันการอัปเกรดใหม่ซึ่งใช้เวลาไม่ถึงชั่วโมงบน VPS และคราวนี้คุณจะทราบล่วงหน้าว่าต้องแก้ไขแพ็กเกจใด การกู้คืนเป็นทางเลือกที่เร็วกว่าเมื่อเข้าเงื่อนไขเหล่านี้: คุณไม่สามารถเข้าถึง console หรือ rescue image ได้, คุณไม่ทราบว่าแพ็กเกจใดที่ทำให้การอัปเกรดหยุดชะงัก, มีแพ็กเกจค้างมากกว่าหนึ่งรายการ หรือเซิร์ฟเวอร์นั้นให้บริการที่ผู้อื่นกำลังรอใช้งานอยู่ การแก้ไขด้วยตนเองเป็นทางเลือกที่เร็วกว่าก็ต่อเมื่อคุณทราบจุดที่เสียหายและวิธีแก้ไขคือคำสั่งเดียว
คัดลอก /var/log/dist-upgrade/ ออกจากเซิร์ฟเวอร์ก่อนที่คุณจะกู้คืน โดยคัดลอกจาก rescue image หากนั่นเป็นวิธีเดียวที่ทำได้ การกู้คืนจะลบ log เหล่านั้นทิ้ง และความพยายามครั้งที่สองจะล้มเหลวในลักษณะเดิมหากคุณไม่ทราบสาเหตุของครั้งแรก สิ่งที่ snapshot กู้คืนได้และไม่ได้ เป็นสิ่งที่ควรค่าแก่การอ่านก่อนที่คุณจะพึ่งพามัน snapshot จะย้อนดิสก์ทั้งหมดกลับ รวมถึงข้อมูลใดๆ ที่ถูกเขียนลงไปหลังจากที่คุณทำ snapshot ไว้ ซึ่งเป็นเรื่องปกติหากทำในช่วงกลางของการอัปเกรด แต่ไม่ใช่เรื่องดีหากทำหลังจากนั้นหนึ่งสัปดาห์
สัญญาณ 3 ประการที่บ่งบอกว่าควรติดตั้งระบบใหม่แทนการซ่อมแซม
การอัปเกรดบางอย่างไม่คุ้มค่าที่จะกู้คืน การเรียกคืน snapshot แล้วเริ่มรันใหม่นั้นทำได้ง่าย แต่หากความล้มเหลวเกิดจากสถานะของตัวเครื่องเอง การรันครั้งที่สองก็จะล้มเหลวเช่นเดิม วิธีแก้ไขที่ตรงไปตรงมาที่สุดคือการใช้ image ของ 26.04 ใหม่ แล้วกู้คืนข้อมูลจาก backup สัญญาณ 3 ประการต่อไปนี้บ่งบอกว่าคุณมาถึงจุดนั้นแล้ว
ประการแรก ฐานข้อมูลของ dpkg เสียหาย หาก dpkg --audit หรือ apt-get check ไม่สามารถอ่าน /var/lib/dpkg/status ได้เลย แทนที่จะรายงานเพียงว่ามีแพ็กเกจที่เสียหายอยู่ภายใน แสดงว่าบันทึกสิ่งที่ติดตั้งไว้ได้สูญหายไปแล้ว Ubuntu จะเก็บสำเนาประจำวันไว้ที่ /var/backups/ (ls -la /var/backups/dpkg.status*) และการนำสำเนาล่าสุดที่สมบูรณ์มาแทนที่บางครั้งอาจได้ผล แต่เมื่อใดที่สำเนานั้นไม่ตรงกับสิ่งที่อยู่บนดิสก์จริงๆ คุณกำลังใช้วิธีเดา และการรัน apt ในภายหลังทั้งหมดจะตั้งอยู่บนพื้นฐานของการเดานั้น
ประการที่สอง เครื่องมือที่คุณต้องใช้ซ่อมแซมระบบเสียหายเสียเอง เมื่อ apt หรือ dpkg ไม่สามารถเริ่มทำงานได้เนื่องจาก shared library ถูกลบหรือถูกแทนที่ไปเพียงบางส่วน หรือ systemd ไม่สามารถเริ่ม unit ได้เพราะแพ็กเกจของตัวมันเองถูกตั้งค่าไว้ไม่สมบูรณ์ จะไม่มีตัวจัดการแพ็กเกจที่ใช้งานได้เหลืออยู่สำหรับซ่อมแซมตัวจัดการแพ็กเกจอีกต่อไป ldd /usr/bin/apt จะบอกคุณว่า library ของ apt ครบถ้วนหรือไม่ บางครั้งคุณอาจสามารถแก้ไขปัญหานี้ได้ด้วยการ bootstrap จาก chroot ใน rescue image แต่เวลาที่ใช้มักจะนานกว่าการติดตั้งระบบใหม่
ประการที่สาม รายการแพ็กเกจที่เสียหายไม่ลดลง หากคุณรัน dpkg --configure -a และ apt --fix-broken install วนซ้ำเป็นเวลานานกว่าหนึ่งชั่วโมง และแต่ละรอบกลับพบแพ็กเกจใหม่ที่เสียหายแทนที่จะแก้ไขของเดิมให้หมดไป แสดงว่าระบบมีปัญหาติดตัวมาตั้งแต่ก่อนการอัปเกรด ซึ่งการอัปเกรดไม่ได้เป็นผู้สร้างปัญหาเหล่านั้น เช่น ไฟล์ภายใต้ /usr ที่ถูกแก้ไขด้วยมือ, แพ็กเกจที่ถูก pin หรือ hold ไว้, repository ของบุคคลที่สามที่เข้ามาแทนที่ core library หรือการอัปเกรดครั้งก่อนหน้าที่ไม่เคยเสร็จสมบูรณ์ การใช้ image ใหม่จะไม่มีปัญหาเหล่านี้ และการกู้คืนข้อมูลลงบนระบบใหม่ใช้เวลาน้อยกว่าการไล่หาปัญหาเหล่านั้น
การติดตั้งระบบใหม่จะทำได้ง่ายก็ต่อเมื่อข้อมูลของคุณถูกเก็บไว้ที่อื่นที่ไม่ใช่บนเครื่องนั้น นี่คือความแตกต่างระหว่าง snapshot กับ backup และเป็นเหตุผลว่าทำไมคู่มือการอัปเกรดจึงแนะนำให้ทำทั้งสองอย่าง
FAQ
ฉันสามารถรัน do-release-upgrade ซ้ำอีกครั้งหลังจากถูกขัดจังหวะได้หรือไม่?
อย่าทำเป็นขั้นตอนแรก หากตัวอัปเกรด (upgrader) ยังทำงานอยู่ใน screen session ให้เชื่อมต่อกลับด้วย sudo screen -d -r การรัน do-release-upgrade ครั้งที่สองจะหยุดทำงานก่อนถึงขั้นตอน reattach เพราะโปรแกรมจะปฏิเสธการทำงานหากมีแพ็กเกจใดค้างการอัปเกรดอยู่ หากตัวอัปเกรดหยุดทำงานไปแล้ว ให้รัน sudo dpkg --configure -a และ sudo apt --fix-broken install ก่อน หากไฟล์ sources ระบุเวอร์ชัน 26.04 ไว้แล้ว ให้ดำเนินการต่อด้วย sudo apt full-upgrade แทนการใช้ตัวอัปเกรด หากยังระบุเป็น 24.04 ให้รัน sudo apt full-upgrade แล้วรีบูตหาก /var/run/reboot-required.pkgs แสดงรายการ libc6, linux-base หรือ kernel จากนั้นจึงเริ่มตัวอัปเกรดใหม่อีกครั้ง นอกจากนี้โปรแกรมยังปฏิเสธการทำงานเมื่อมีการตั้งค่า Prompt=never ไว้ใน /etc/update-manager/release-upgrades หรือเมื่อเซิร์ฟเวอร์ของ Ubuntu รายงานว่า "Release upgrade not possible right now"
ทำไม do-release-upgrade ถึงแจ้งว่าไม่มี release ใหม่หลังจากที่การอัปเกรดของฉันล้มเหลว?
เพราะ base-files ซึ่งเป็นแพ็กเกจที่เขียนไฟล์ /etc/os-release เป็นหนึ่งในแพ็กเกจที่อัปเกรดไปก่อนที่จะเกิดการขัดจังหวะ เครื่องมือนี้จึงอ่านไฟล์ดังกล่าวและสรุปว่าคุณใช้เวอร์ชัน 26.04 อยู่ จึงไม่พบเวอร์ชันใหม่กว่าที่จะเสนอให้ ให้เปรียบเทียบ grep VERSION_ID /etc/os-release กับ grep Suites /etc/apt/sources.list.d/ubuntu.sources แล้วดำเนินการต่อด้วย sudo apt update && sudo apt full-upgrade
การรีบูตเซิร์ฟเวอร์ Ubuntu ที่อัปเกรดไปได้ครึ่งทางปลอดภัยหรือไม่?
ไม่ปลอดภัยจนกว่า sudo dpkg --audit จะไม่แสดงผลลัพธ์ใดๆ การรีบูตในขณะที่ kernel ถูกแตกไฟล์แต่ยังไม่ได้ตั้งค่า หรือ GRUB ยังไม่ได้ถูกสร้างใหม่ เป็นสาเหตุที่พบบ่อยที่สุดที่ทำให้การอัปเกรดซึ่งควรแก้ไขได้ในสิบนาที กลายเป็นงานที่ต้องใช้ rescue-image ให้ดำเนินการซ่อมแซม dpkg และ apt full-upgrade ให้เสร็จสิ้น รัน update-initramfs -u -k all และ update-grub แล้วจึงค่อยรีบูต
ฉันจะทราบได้อย่างไรว่าแพ็กเกจใดทำให้การอัปเกรดหยุดชะงัก?
ให้อ่านส่วนท้ายของ /var/log/dist-upgrade/apt-term.log ซึ่งเก็บผลลัพธ์จาก terminal ของ dpkg แพ็กเกจสุดท้ายที่ถูกระบุก่อนที่ log จะสิ้นสุดคือแพ็กเกจที่กำลังทำงานอยู่ และสคริปต์ของผู้ดูแล (maintainer script) ที่ล้มเหลวจะแสดงข้อผิดพลาดไว้เหนือข้อความแจ้งเตือนของ dpkg เล็กน้อย /var/log/dpkg.log เป็นแหล่งข้อมูลที่สอง โดยบรรทัดที่มีการประทับเวลาเมื่อการอัปเกรดหยุดลงจะระบุแพ็กเกจเดียวกัน แต่คำสั่งใดๆ ที่คุณรันผ่าน dpkg หลังจากนั้นจะถูกบันทึกต่อท้าย ดังนั้นบรรทัดท้ายๆ ของไฟล์นี้อาจไม่ใช่สาเหตุ หาก main.log จบลงด้วย Python traceback แสดงว่าตัวอัปเกรดเองเกิดการ crash และไม่มีแพ็กเกจใดเป็นต้นเหตุ
ฉันควรคืนค่า snapshot หรือแก้ไขต่อไป?
ให้คืนค่า snapshot เมื่อคุณไม่สามารถระบุได้ว่าแพ็กเกจใดล้มเหลว เมื่อมีแพ็กเกจค้างมากกว่าหนึ่งรายการ เมื่อคุณไม่มีสิทธิ์เข้าถึง console หรือเมื่อเซิร์ฟเวอร์จำเป็นต้องกลับมาใช้งานโดยเร็ว ให้แก้ไขต่อไปเฉพาะเมื่อคุณทราบจุดที่เสียหายเพียงจุดเดียวและวิธีแก้ไขเป็นเพียงคำสั่งเดียวเท่านั้น ให้คัดลอก /var/log/dist-upgrade/ ออกจากเครื่องก่อนทำการคืนค่า มิฉะนั้นความพยายามครั้งที่สองจะล้มเหลวด้วยสาเหตุเดิม