OpenAI Codex Ghi Hàng Terabyte Dữ Liệu: 'Thầm Lặng' Hủy Hoại SSD của Lập Trình Viên! 😱
Một lỗi nghiêm trọng vừa được phát hiện trong ứng dụng desktop OpenAI Codex và tiện ích mở rộng chính thức cho VS Code/VSCodium, có khả năng "thầm lặng" phá hủy các ổ đĩa thể rắn (SSD) của lập trình viên. Vấn đề này, đang được theo dõi trên kho lưu trữ chính thức và các diễn đàn nhà phát triển, khiến Codex ghi liên tục các sự kiện theo dõi vào một cơ sở dữ liệu SQLite cục bộ với tốc độ duy trì từ 5 MiB/giây đến 16 MiB/giây.
Điều này tương đương với khoảng 640 TB dữ liệu ghi vào đĩa mỗi năm trong điều kiện sử dụng tích cực thông thường. Với việc một ổ SSD tiêu dùng 1 TB tiêu chuẩn có tuổi thọ bảo hành (endurance rating) khoảng 600 TBW (Terabytes Written), quy trình nền này có thể làm cạn kiệt hoàn toàn tuổi thọ vật lý của ổ đĩa chính của lập trình viên trong vòng chưa đầy 12 tháng.
---
Phân Tích Kỹ Thuật Lỗi "Khuếch Đại Ghi" (Write Amplification)
Trọng tâm của vấn đề nằm ở cách binary app-server của Codex xử lý việc ghi nhật ký và đo lường từ xa (trace telemetry). Codex được xây dựng bằng Rust và sử dụng một cơ sở dữ liệu SQLite cục bộ (~/.codex/logs_2.sqlite) cùng với các tệp nhật ký ghi trước (logs_2.sqlite-wal) và bộ nhớ chia sẻ (logs_2.sqlite-shm) để ghi lại dữ liệu đo lường nội bộ và phản hồi của người dùng.
Trong các cuộc hội thoại thông thường hoặc khi truyền phát phản hồi, binary này ghi dữ liệu đo lường rất chi tiết ở cấp độ TRACE.
1. Bỏ Qua Bộ Lọc `RUST_LOG`
Ngay cả khi biến môi trường được đặt rõ ràng thành RUST_LOG=warn hoặc RUST_LOG=error (đã được xác minh bằng cách kiểm tra /proc/<PID>/environ), app-server vẫn tiếp tục gửi spam các sự kiện TRACE. Điều này là do "Telemetry sink" được khởi tạo với một giá trị TRACE mặc định cứng trong mã: rust Targets::new().with_default(Level::TRACE) Việc mã hóa cứng này bỏ qua các cơ chế lọc tiêu chuẩn, khiến mọi sự kiện – bao gồm truyền khung WebSocket khối lượng lớn, phản hồi Server-Sent Events (SSE) và các OpenTelemetry (OTel) spans – đều được ghi vào cơ sở dữ liệu SQLite.
2. Khuếch Đại Ghi Dữ Liệu Khối Lượng Lớn
Mặc dù kích thước trên đĩa của logs_2.sqlite có thể chỉ dao động quanh 100-150 MB, nhưng khối lượng hoạt động liên tục lại rất đáng kinh ngạc. Hồ sơ theo dõi bằng SQLite cho thấy: * Hơn 36.000 nhật ký được chèn chỉ trong 15 giây. * Kích thước cơ sở dữ liệu tổng thể không tăng vì một tác vụ nền liên tục cắt tỉa các hàng cũ để thực thi giới hạn lưu giữ. * Vòng lặp "chèn và cắt tỉa" này tạo ra hiệu ứng khuếch đại ghi (write amplification) lớn: các hàng liên tục được chèn, lập chỉ mục, ghi vào nhật ký ghi trước (WAL), và ngay lập tức bị xóa. Điều này tạo ra các thao tác ghi đĩa liên tục mà không làm tăng kích thước tệp nhật ký thực tế, che giấu hành vi ghi phá hủy đối với người dùng thông thường.
---
Triệu Chứng & Tác Động Đến Hiệu Suất Hệ Thống
Các lập trình viên để tiện ích mở rộng hoặc ứng dụng desktop Codex chạy không tải (idle) trong VS Code báo cáo tình trạng suy giảm hiệu suất hệ thống nghiêm trọng: 1. Giảm Hiệu Suất Nhiệt Nghiêm Trọng (Severe Thermal Throttling): Máy tính xách tay nóng ran và quạt quay hết tốc độ do chu kỳ CPU/IO liên tục từ các tiến trình codex app-server. 2. VS Code Bị Treo & Lag: Lượng nhật ký khổng lồ gây ra tranh chấp I/O đĩa, khiến VS Code bị treo hoặc lag trong quá trình tự động hoàn thành hoặc truyền phát cuộc trò chuyện. 3. Tiến Trình Ẩn (Ghost Processes): Khi VS Code được đóng, một số tiến trình app-server cũ vẫn tiếp tục chạy ẩn, giữ cho các tệp WAL đã xóa vẫn được cấp phát và phát triển trong bộ nhớ/đĩa.
---
Các Giải Pháp Tạm Thời (Workarounds) Dành Cho Lập Trình Viên
Trong khi chờ OpenAI phát hành bản vá tôn trọng các cấp độ RUST_LOG hoặc cung cấp cấu hình sqlite_logs_enabled = false, các lập trình viên đã phát triển hai giải pháp tạm thời cực kỳ hiệu quả để bảo vệ phần cứng của họ:
Giải Pháp 1: Tạo Trigger Chặn SQLite (Được khuyến nghị) 🛡️
Đây là cách tiếp cận sạch nhất. Bằng cách thêm một trigger INSERT trực tiếp vào bảng logs, bạn yêu cầu SQLite bỏ qua ngay lập tức mọi mục nhập mới mà không gây ra sự cố ứng dụng: bash sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;" Điều này giảm I/O đĩa xuống bằng không trong quá trình truyền phát vì công cụ SQLite bỏ qua việc ghi WAL. Để hoàn tác trigger này sau khi bản vá được phát hành: bash sqlite3 ~/.codex/logs_2.sqlite "DROP TRIGGER IF EXISTS block_log_inserts;"
Giải Pháp 2: Chuyển Hướng Nhật Ký Đến tmpfs (RAM Disk) 🚀
Vì logs_2.sqlite chỉ chứa các chỉ số theo dõi nội bộ dành cho nhà phát triển và không chứa lịch sử cuộc trò chuyện của người dùng, bạn có thể an toàn tạo liên kết tượng trưng (symlink) nó đến một đĩa RAM ảo (tmpfs): ```bash # 1. Đóng VS Code và tắt mọi tiến trình codex app-server killall -9 codex
2. Sao lưu và tạo liên kết tượng trưng đến /tmp
mv ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite.bak ln -s /tmp/logs_2.sqlite ~/.codex/logs_2.sqlite ``` Vì /tmp nằm trong RAM trên các hệ thống macOS/Linux hiện đại, các thao tác ghi liên tục sẽ xảy ra trong bộ nhớ, hoàn toàn bỏ qua các ô vật lý của SSD của bạn.
Giải Pháp 3: Chấm Dứt Các Tiến Trình "Mồ Côi" (Orphan Processes) 👻
Nếu terminal của bạn hiển thị các khóa WAL cũ, hãy chạy script này để buộc tắt các tiến trình nền Codex cũ: bash lsof ~/.codex/logs_2.sqlite | awk 'NR>1 {print $2}' | xargs kill -9