Sự cố máy tính Y2038 có liên quan tới MySQL

Sự cố MySQL 2038 không còn là một lời tiên đoán mà nó chắc chắn sẽ xảy ra vào đúng 3h14’7’’ ngày19/01/2038. Khi chúng ta còn đang say giấc nồng thì thời gian có thật sẽ được “bê” ngược trở lại?

Không ồn áo giống vụ Y2K ngày nào hay Y2020 gần đây, mà chính Y2038 sẽ nhẹ nhàng đưa thời gian ngược trở lại về năm 1901 cho những ai thích MySQL yêu TIMESTAMP mà chê DATETIME.

Khi số đếm nhị phân dần đến giới hạn tràn đúng 3h14’7’’ ngày 19/1/2038 thì bộ đếm thời gian của máy tính sẽ quay về mốc năm 1901.

Khi số đếm nhị phân dần đến giới hạn tràn đúng 3h14’7’’ ngày 19/1/2038 thì bộ đếm thời gian của máy tính sẽ quay về mốc năm 1901.

Thời gian có thực sự quay ngược trở lại “nhờ” sự cố này?

Để giải thích cho sư việc trên, chúng mình có thử lần theo dấu vết của Y2038 và vô tình chúng mình phát hiện ra:

Kiểu TIMESTAMP trong MySQL (trước phiên bản 8.0.28) sử dụng 4 byte (32-bit) để lưu trữ số giây tính từ Epoch (01/01/1970 00:00:00 UTC). Định dạng là YYYY-MM-DD HH:MI:SS

Số nguyên 32-bit có giá trị tối đa là 2,147,483,647 giây (~ 68 năm), tương đương với 19/01/2038 03:14:07 UTC.

Sau thời điểm này, giá trị sẽ bị tràn số (overflow), gây lỗi hoặc giá trị bị reset về mốc âm.

Và ngay cả khi DATETIME và TIMESTAMP cùng trả về một định dạng thì chúng vẫn hoạt động rất khác nhau. Trong truy vấn INSERT hoặc UPDATE, TIMESTAMP sẽ tự động đặt chính nó vào ngày và giờ hiện tại. Thêm nữa, TIMESTAMP cũng chấp nhận các định dạng khác nhau, như YYYYMMDDHHMISS, YYMMDDHHMISS, YYYYMMDD hoặc YYMMDD (ngày xưa làm PHP với MySQL cũng đau đầu mấy vụ chuyển đổi ngày giờ này lắm)

Lưu ý: Giá trị timestamp dựa trên đồng hồ nội bộ và không tương ứng với thời gian thực. Mỗi bảng có thể chỉ có một biến timestamp.

Cách khắc phục sự cố MySQL 2038

Cách 1: Kiểm tra và cập nhật MySQL lên phiên bản mới

Từ MySQL 8.0.28 trở lên, kiểu dữ liệu TIMESTAMP đã hỗ trợ 8 byte (64-bit), giúp mở rộng giới hạn thời gian lên hàng tỷ năm (anh em nâng cấp lên rồi thì dùng tẹt ga, phần mềm để đến đời con cháu 6 đời dùng cũng không hết).

Kiểm tra phiên bản MySQL của bạn bằng lệnh sau cho chắc cú nào:

SELECT VERSION();

Nếu phiên bản MySQL cũ, hãy nâng cấp lên MySQL 8.0.28 hoặc mới hơn.

Anh em nào cần CLoud Server để train AI hay chạy ứng dụng mạnh thì ghé tham shop của chúng mình nhé.

Cách 2: Thay đổi kiểu dữ liệu từ TIMESTAMP sang DATETIME

DATETIME không bị giới hạn năm 2038 vì nó sử dụng 8 byte để lưu ngày giờ theo định dạng ‘YYYY-MM-DD HH:MM:SS’.

Nếu bạn chỉ cần lưu ngày giờ mà không cần múi giờ, hãy chuyển đổi:

ALTER TABLE your_table MODIFY your_column DATETIME;

Nhược điểm: DATETIME không tự động cập nhật theo múi giờ hệ thống như TIMESTAMP.

Cách 3: Sử dụng kiểu dữ liệu BIGINT để lưu UNIX Timestamp

Một giải pháp khác là lưu timestamp dưới dạng BIGINT (64-bit) thay vì TIMESTAMP:

ALTER TABLE your_table MODIFY your_column BIGINT;

Khi lấy dữ liệu, bạn có thể chuyển đổi bằng FROM_UNIXTIME():

SELECT FROM_UNIXTIME(your_column) FROM your_table;

Nhược điểm: Bạn phải tự quản lý việc chuyển đổi múi giờ.

Kết luận

Sự cố 2038 nhiều khả năng sẽ ảnh hưởng nhiều hơn đến hệ thống nhúng trong các thiết bị thông tin liên lạc như điện thoại, router hay thiết bị phát sóng WiFi. Đó là những thiết bị dựa vào dữ liệu ngày tháng thời gian chính xác trên những nền tảng tương đồng Unix. Và để khắc phục sự cố này trước thềm năm 2038 bạn cần chắc chắn đã làm những việc sau:

✔ Nếu có thể nâng cấp, hãy sử dụng MySQL 8.0.28+ để tránh lỗi.

✔ Nếu không nâng cấp được, hãy chuyển từ TIMESTAMP sang DATETIME hoặc BIGINT.

Sự cố về thời gian này có vẻ sẽ gây ra nhiều phiền phức và nếu như bạn có bất kì câu hỏi thắc mắc nào hãy chia sẻ với chúng mình – team kĩ thuật FastCloud cùng biết nhé. Chúc các bạn thành công!