Khi lỗi này xảy ra
Bạn vừa di chuyển tệp dump.rdb sang một máy chủ mới và khởi động dịch vụ. Thay vì tải dữ liệu, dịch vụ lập tức bị crash. Khi kiểm tra log, bạn thấy một thông báo gây khó chịu về phiên bản RDB. Điều này thường xảy ra khi bạn cố gắng di chuyển dữ liệu từ một instance Redis mới hơn (như Redis 7.0) sang một phiên bản cũ hơn (như Redis 5.0).
Can't handle RDB format version 10 (or higher); Short read or OOM loading DB
Vấn đề rất đơn giản: máy chủ mới của bạn không hiểu cùng một ngôn ngữ với tệp sao lưu cũ.
Tại sao lỗi này xảy ra
Các tệp RDB của Redis sử dụng một hệ thống phân loại phiên bản cụ thể. Mặc dù Redis rất giỏi trong việc tương thích ngược (forward-compatibility)—nghĩa là phiên bản mới luôn có thể đọc được tệp cũ—nhưng nó không hỗ trợ tương thích xuôi (backward-compatibility). Các phiên bản Redis cũ đơn giản là không hiểu logic nén hoặc cấu trúc dữ liệu mới có trong các định dạng RDB mới hơn.
- RDB Version 9: Được sử dụng bởi Redis 5.0 và 6.0.
- RDB Version 10: Được giới thiệu từ Redis 6.2.
- RDB Version 11: Được giới thiệu từ Redis 7.0.
Nếu bạn cố gắng tải một tệp RDB Version 11 vào một engine Redis 6.0, tiến trình sẽ thất bại ngay lập tức. Engine nhận thấy số phiên bản cao hơn giới hạn của nó và dừng lại để ngăn chặn việc hỏng dữ liệu.
Cách khắc phục tốt nhất: Nâng cấp Redis đích
Nâng cấp máy chủ đích là giải pháp đáng tin cậy nhất. Nếu nguồn của bạn đang chạy 7.0, đích cũng nên là 7.0 hoặc cao hơn. Đối với người dùng Docker, đây là một bản sửa lỗi nhanh trong tệp docker-compose.yml của bạn.
# Nâng cấp từ 6.0 lên 7.2
docker pull redis:7.2
docker stop my-redis-container
docker run --name my-redis-container -v /path/to/dump.rdb:/data/dump.rdb -d redis:7.2
Trên các máy chủ Linux, hãy tránh các gói lỗi thời trong kho lưu trữ mặc định. Thay vào đó, hãy sử dụng kho lưu trữ chính thức của Redis để có bản build ổn định mới nhất:
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
Giải pháp thay thế: Di trú trực tiếp qua mạng
Đôi khi bạn bị kẹt với một hệ điều hành cũ không hỗ trợ Redis mới nhất. Trong trường hợp này, bạn không thể sử dụng trực tiếp tệp dump.rdb. Bạn phải di chuyển dữ liệu trong khi cả hai instance đang chạy. Bằng cách này, Redis sẽ chuyển đổi dữ liệu sang định dạng tương thích trong quá trình truyền tải.
Cách 1: Sử dụng redis-cli --pipe
Phương pháp này bỏ qua phiên bản RDB bằng cách tuần tự hóa (serialize) các key sang định dạng mà cả hai phiên bản đều hiểu. Nó hoạt động tốt cho các tập dữ liệu nhỏ đến trung bình.
# Chạy lệnh này trên máy chủ nguồn để đẩy một key cụ thể
redis-cli --raw SERIALIZE mykey | redis-cli -h target-host -x RESTORE mykey 0
Cách 2: Sử dụng Redis-Shake
Đối với cơ sở dữ liệu lớn hơn 1GB, hãy sử dụng một công cụ chuyên dụng như redis-shake. Nó đóng vai trò như một cầu nối, đồng bộ hóa dữ liệu từ nguồn đến đích trong thời gian thực.
- Tải xuống file thực thi
redis-shake. - Chỉnh sửa cấu hình
syncđể trỏ đến IP nguồn và đích của bạn. - Khởi động công cụ. Nó sẽ truyền toàn bộ key mà không bao giờ chạm vào tệp RDB trên đĩa của máy đích.
Giải pháp thay thế bằng AOF
Nếu bạn cần di chuyển dữ liệu giữa các phiên bản thường xuyên, hãy chuyển sang Append Only File (AOF). Khác với định dạng RDB nhị phân, AOF là một bản ghi các câu lệnh dưới dạng văn bản. Một tệp AOF được tạo bởi Redis 7.0 có khả năng cao sẽ đọc được bởi Redis 6.0 vì các lệnh cơ bản như SET và HSET không thay đổi.
- Bật AOF trên nguồn:
CONFIG SET appendonly yes. - Chuyển tệp
appendonly.aofthu được sang máy chủ đích. - Đảm bảo
appendonly yesđược thiết lập trongredis.confcủa máy đích. - Khởi động lại dịch vụ đích.
Xác minh di trú
Sau khi di trú, đừng chỉ mặc định là nó đã hoạt động. Hãy kiểm tra keyspace và log để đảm bảo mọi thứ ổn định.
# Xác nhận dịch vụ đang phản hồi
redis-cli ping
# So sánh số lượng key với nguồn
redis-cli info keyspace
# Kiểm tra các dòng thông báo quan trọng trong log
tail -n 50 /var/log/redis/redis-server.log
# Tìm dòng: "DB loaded from disk: 1.234 seconds"
Nếu bạn thấy thông báo tải đó và không có lỗi định dạng, dữ liệu của bạn đã an toàn và sẵn sàng để sử dụng.

