2010-09-23 24 views
5

Tôi nhận được một lỗi thực sự lạ, vô nghĩa và hoàn toàn ngẫu nhiên khi tôi tìm nạp hàng từ tài nguyên (truy vấn) bằng PHP.Lỗi MySQL lạ "Rỗng dữ liệu gói hàng" khi sử dụng mysql_fetch_object (PHP 5.3.3)

Máy phát triển của tôi là Windows XP SP3 với Apache 2.2 trong khi MySQL chạy trên máy ảo, sử dụng ubuntu 10.04, với 768mb ram, 100GB HDD và 4 lõi logic (Intel q6600). Tuy nhiên vấn đề này không liên quan đến PHP trên cửa sổ vì tôi nhận được cùng một lỗi khi tôi chạy mã trên máy cơ sở dữ liệu.

Tôi đang sử dụng mysql tiện ích mở rộng (không phải mysqli hoặc mysqlnd), nhưng tìm kiếm xung quanh tôi đã tạo ra một bản vá liên quan đến lỗi này liên quan đến phần mở rộng mysqlnd, vì vậy, có lẽ, tôi nên thử.

Vấn đề chính là khi tôi thực hiện truy vấn này (một truy vấn thực sự lớn với một vài bảng có nguồn gốc và hơn 20 lần tham gia) và xử lý kết quả nhanh và mọi thứ suôn sẻ, nhưng khi mã của tôi dành khoảng 15/20 giây để xử lý một khối các hàng (tôi cần xây dựng một đối tượng từ một khối các hàng được liên kết theo cách thực sự đặc biệt giữa chúng, tôi không thể thay đổi điều này, cơ sở dữ liệu không phải của tôi, và tạo một số PDF từ đối tượng này) sau một thời gian (thời gian ngẫu nhiên) Tôi nhận được lỗi này "Empty body packet body".

Tôi sử dụng truy vấn không được lọc để giảm mức tiêu thụ bộ nhớ (nếu tôi bật bộ đệm, tôi nhận được khoảng 260MB bộ nhớ đã sử dụng) nhưng điều này không phải là vấn đề.

+0

Bạn có thể hiển thị một số mã không? Thời gian chờ lệnh của bạn được đặt là gì? – Fosco

+0

sự cố không liên quan đến hết thời gian chờ hoặc giới hạn bộ nhớ vì tôi đã vô hiệu hóa lần đầu tiên và đặt thành giá trị rất rất cao thứ hai –

+0

Nơi tôi làm việc chúng tôi phát triển bằng cách sử dụng Apache 2.2/PHP 5.3.3 cục bộ trên Windows XP Pro SP3 quá, và một máy chủ cơ sở dữ liệu thử nghiệm được chia sẻ, và chúng tôi nhận được lỗi này tất cả các thời gian. BAO GIỜ, thiết lập Apache/Linux được chia sẻ, có phiên bản tôi không biết, không đưa ra lỗi này, vì vậy điều này có thể cho thấy sự cố có thể do phiên bản Apache hoặc thứ gì đó tương tự thay vì cấu hình hoặc sử dụng cơ sở dữ liệu! –

Trả lời

16

Tôi đã gặp lỗi tương tự. Tôi đã sử dụng PDO, nhưng về cơ bản nó cũng giống nhau.

Bạn có đang hoạt động trên bảng MyISAM không? Nếu vậy, vấn đề có thể liên quan đến mô hình khóa mà Engine này sử dụng: nó khóa toàn bộ bảng, để đọc bằng khóa chia sẻ, để viết bằng khóa độc quyền.

Đây là những gì tôi đã cố gắng làm: Đọc một tập hợp kết quả lớn không bị chặn và cập nhật một số hàng trong cùng một bảng. Vì bạn không thể phát hành một câu lệnh trên cùng một kết nối trong khi nó giữ một tập kết quả không được lọc, tôi đã thử sử dụng một kết nối khác cho các bản cập nhật. Đọc cho đến khi bản cập nhật đầu tiên, tại thời điểm đó kịch bản bị ngừng trong khoảng một phút, sau đó tôi nhận được lỗi "Rỗng hàng gói thân".

Bạn thấy đấy, khi đọc không bị chặn, khóa chia sẻ được giữ cho đến khi toàn bộ tập kết quả đã được đọc hoặc con trỏ đang bị đóng. Trong thời gian đó, bảng bị khóa với một khóa chia sẻ, vì vậy các kết nối khác có thể có được khóa chia sẻ trên bàn (nói cách khác, đọc từ nó), nhưng khóa độc quyền (để viết) sẽ phải đợi. Nếu điều này xảy ra trong cùng một tập lệnh, nó sẽ bế tắc.

Bây giờ, để ngăn chặn bế tắc bất tận, MySQL sẽ buộc phải giải phóng khóa chia sẻ của bạn sau một thời gian (IIRC bị ảnh hưởng bởi giá trị table_lock_wait_timeout), kết xuất bộ kết quả của bạn và cho phép ghi chú bằng khóa độc quyền chờ đợi xoay. Vì vậy, trong trường hợp của tôi, nó là cùng một kịch bản đã làm điều này và do đó bị trì hoãn cho đến khi hết thời gian, nó cũng có thể là một số kịch bản khác đang cố gắng viết một hoạt động trên bàn với cùng một hiệu ứng, mà có lẽ những gì đã xảy ra trong trường hợp của bạn.

Điều đã giải quyết được vấn đề đối với tôi là thay đổi loại bảng thành InnoDB, vì Công cụ đó sử dụng cấp hàng thay vì các khóa cấp bảng. Tuy nhiên, vì bạn nói rằng cơ sở dữ liệu không phải là của bạn, điều này có thể không khả thi cho bạn.

+0

Ban đầu loại bảng là myisam, sau đó tôi chuyển sang innodb để làm một bài kiểm tra nhưng vấn đề vẫn còn. Tuy nhiên trên thực tế tôi đã không nhận được nó nữa, tôi phải siêu căng thẳng máy chủ để có được nó –

+0

Chính xác vấn đề của tôi! Câu trả lời tuyệt vời, cảm ơn bạn. – mpen

+0

Điều này không hiệu quả đối với tôi, ngay cả khi bảng được sao chép và tôi chắc chắn 100% không ai viết thư cho nó. – Chris

0

câu trả lời của người dùng589182 được phát hiện. Tôi đang làm về cơ bản cùng một điều: Đọc một tập kết quả lớn không bị chặn và cập nhật một số hàng trong cùng một bảng, từ cùng một tập lệnh PHP. Tôi nhận được thông báo lỗi chính xác tương tự sau khoảng. 2500 CẬP NHẬT.Vấn đề được giải quyết sau khi chuyển từ MyISAM sang InnoDB.

+0

tốt, tôi đang ở trên innodb nhưng nếu tôi siêu căng thẳng mysql, tôi nhận được lỗi. –

0

Tôi gặp lỗi tương tự và tôi cũng đang đọc một tập kết quả lớn không được xếp trong khi cập nhật các hàng của cùng một bảng.

Thay vì chuyển sang InnoDB, giải pháp tốt hơn có thể là tạo bảng tạm thời chỉ chứa khóa chính của bảng gốc. Sau đó, lặp lại bảng tạm thời đó trong khi chọn và cập nhật một hàng tại một thời điểm từ bảng gốc. Bạn sẽ phải sử dụng hai kết nối MySQL riêng biệt để thực hiện việc này, nếu không bạn sẽ nhận được lỗi "Lệnh không đồng bộ".

Bạn có thể cần phải khóa bảng gốc để ngăn người khác đọc/ghi vào nó trong khi điều này đang diễn ra.

0

Tôi đã ở InnoDB và chưa bao giờ có loại vấn đề này cho đến khi tôi chuyển sang môi trường mã hóa (nghĩa đen, như vị trí). Vì vậy, nếu bạn thay đổi kết nối không dây của mình, đó có thể là vấn đề đặc biệt nếu đó là nơi công cộng.

1

Sau khi lỗi này một thời gian một trước, tôi đã cố định nó bằng cách tăng giá trị của

net_read_timeout = 360 
net_write_timeout = 360 

Trong khi một kết nối được mở trên ghi, chờ đợi cho truy vấn khác để kết thúc để tiếp tục chèn, lần này ra , đưa ra một gói hàng trống. Tôi đang làm việc trên tập dữ liệu rất lớn, giá trị được sử dụng vượt quá 360. Giá trị của bạn sẽ tùy thuộc vào trường hợp sử dụng của bạn.

Các vấn đề liên quan