Là rác tạm thời được thu thập?


61

Câu hỏi này khiến tôi suy nghĩ nguồn cấp RSS thoáng qua trong wp_options không được xóa tự động?

Các khách hàng được cho là hết hạn và bị xóa. Tuy nhiên, cách duy nhất tôi thấy điều này được xử lý là khi hết thời gian và yêu cầu, sau đó nó sẽ bị xóa trong khi yêu cầu.

Điều gì nếu thoáng qua đã hết hạn nhưng không bao giờ được yêu cầu sau đó? Từ mô tả trong Codex tôi nghĩ rằng một số loại bộ sưu tập rác được ngụ ý. Bây giờ tôi không chắc lắm và không thể tìm thấy bất kỳ mã nào thực hiện như vậy.

Vì vậy, nó sẽ chỉ bị mắc kẹt trong cơ sở dữ liệu mãi mãi?


về mặt lý thuyết, chúng nên được gỡ bỏ khi cron được chạy (nếu chúng đã hết hạn)
onetrickpony

1
@ Ammebious Amoeba yeah, tôi đã đề cập đến vấn đề đó. Quan điểm của tôi là - tạm thời được tạo ra không giả định hoặc đảm bảo rằng nó sẽ được yêu cầu. Nhấn mạnh câu hỏi ban đầu - khi nào và nếu hết hạn thoáng qua sẽ bị xóa nếu tôi không bao giờ nhận được nó?
Rarst

1
nó giả sử bạn dọn sạch dữ liệu đã hết hạn, nhưng vâng, bạn đúng, có những tình huống sẽ không bao giờ bị xóa. Giống như loại bỏ một widget sử dụng quá độ. Bạn nên gửi một vé trên trac cho việc này :)
onetrickpony

1
@Rarst - Nghe có vẻ là một điều hoàn hảo để viết một bản vá cho và gửi đến trac?
MikeSchinkel

Câu trả lời:


45

Bây giờ họ là

Bắt đầu với WordPress 3.7 quá hạn đã bị xóa khi nâng cấp cơ sở dữ liệu, xem # 20316


Câu trả lời cũ

Nếu ai đó không thể chỉ cho tôi nếu không thì dường như tất cả đều không phải là rác được thu thập. Điều làm cho nó tồi tệ hơn là không giống như các tùy chọn chúng không được đảm bảo để được lưu trữ trong cơ sở dữ liệu. Vì vậy, không có cách nào đáng tin cậy để tìm nạp danh sách tất cả các quá độ để kiểm tra chúng hết hạn.

Một số mã tạm thời để thực hiện thu gom rác nếu cơ sở dữ liệu được sử dụng để lưu trữ:

add_action( 'wp_scheduled_delete', 'delete_expired_db_transients' );

function delete_expired_db_transients() {

    global $wpdb, $_wp_using_ext_object_cache;

    if( $_wp_using_ext_object_cache )
        return;

    $time = isset ( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time() ;
    $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};" );

    foreach( $expired as $transient ) {

        $key = str_replace('_transient_timeout_', '', $transient);
        delete_transient($key);
    }
}

$ time = $ _SERVER ['REQUEST_TIME']; và sau đó sử dụng $ time trong truy vấn SQL - đừng làm điều đó. Xử lý cẩn thận hơn với các biến / giá trị $ _SERVER để ngăn chặn việc tiêm SQL.
hakre

@hakre hm ... Tôi đã chọn điều đó từ phần trình bày về hiệu suất PHP đã khuyến nghị sử dụng time()nó có thể gây ra lỗi (bản chất thực thi không phải là tức thời). Thời gian yêu cầu đang được thiết lập bởi chính PHP, không đến từ bất kỳ loại dữ liệu nào do người dùng cung cấp. Tại sao lỗ hổng này?
Hết

@Rarst: Tôi không nói rằng bạn không nên sử dụng nó, bạn chỉ nên đảm bảo rằng nó được mã hóa an toàn để được sử dụng bên trong truy vấn SQL. Bạn nên làm điều này với mọi biến từ một nguồn bên ngoài. Các biến $ _SERVER có thể không được đặt như mong đợi và thay vào đó, được đặt bởi người dùng yêu cầu. Tôi chỉ muốn tuyên truyền một số thực hành mã hóa tốt. Như mọi khi, để tìm hiểu về trạng thái sẵn có thực sự, hãy xem các tài liệu. Đối với PHP 4 ví dụ, một biến như vậy không tồn tại và có thể bị ghi đè bởi một tiêu đề tùy chỉnh hoặc biến môi trường - php.net/manual/en/reserved.variables.server.php
hakre

@hakre cố định (tôi nghĩ), nhờ PHP4 nhắc nhở btw (Tôi không thể chờ đợi cho WordPress để thả hỗ trợ của nó)
Rarst

Điều đó có vẻ tốt hơn nhiều trong mắt tôi;). Chúng ta hãy hy vọng rằng không có vấn đề gì với thời gian () và các số nguyên âm có thể xóa tất cả hoặc không có quá độ so với tình cờ. Không bao giờ tin tưởng một hệ thống đang chạy: P
hakre

20

Chuyển một số ý kiến ​​từ cuộc thảo luận thành một câu trả lời, với cách diễn đạt lại và định dạng lại ..

Về cơ bản, những gì nó được đưa ra là trừ khi bạn có một trường hợp cực kỳ nghiêm trọng, họ không thực sự cần phải là "rác được thu thập". Nếu bạn không bao giờ lấy chúng, thì việc họ có ở đó hay không cũng không thành vấn đề.

Xem, tạm thời được lưu trữ trong bảng tùy chọn theo mặc định. Trong một cài đặt cơ sở, bảng tùy chọn sẽ có thể có 100 mục trong đó. Mỗi thoáng qua thêm hai mục nữa, nhưng ngay cả khi bạn có hàng nghìn mục, chúng không ảnh hưởng đến tốc độ trang web, vì chúng không được tự động tải.

Khi khởi động, WordPress tải các tùy chọn vào bộ nhớ, nhưng nó chỉ tải các tùy chọn bật cờ tự động tải của họ. Các khách hàng không nhận được điều này và vì vậy đừng tải vào bộ nhớ. Chỉ những khách hàng thực sự được sử dụng sau này mới chịu chi phí.

Từ phối cảnh của cơ sở dữ liệu, bảng tùy chọn có các chỉ mục trên cả Id tùy chọn và tên tùy chọn. Các khách hàng luôn được tải dựa trên tên (khóa) và do đó, việc tra cứu cho họ luôn là các lựa chọn đơn giản trên một giá trị khóa duy nhất. Do đó, tra cứu là O (log (n)) và siêu nhanh. Với Big-O của nhật ký (n), bạn phải vào hàng triệu và hàng triệu hàng trước khi nó trở nên đáng chú ý. Thành thật mà nói, chi phí trong việc thiết lập và phân tích truy vấn, cùng với việc truyền dữ liệu thực tế, là cách lâu hơn. Các truy vấn tự chạy trong thời gian cơ bản bằng không so sánh. Vì vậy, chỉ cần thêm các hàng không sử dụng sẽ không ảnh hưởng gì ngoài việc sử dụng thêm dung lượng đĩa.

Lập chỉ mục trong cơ sở dữ liệu là một trong những ý tưởng được đọc sâu mà không có ý nghĩa đối với những người thực sự không hiểu những gì đang diễn ra đằng sau hậu trường. Cơ sở dữ liệu được thiết kế để truy xuất dữ liệu nhanh, từ đầu và có thể xử lý loại việc này mà không gặp sự cố. Đây là một bài đọc khá tốt: http://en.wikipedia.org/wiki/Index_(database )

Bây giờ, dọn dẹp theo cách rõ ràng nhất (gọi SQL XÓA trên chúng) không thực sự xóa chúng khỏi cơ sở dữ liệu. Nó chỉ xóa chúng khỏi chỉ mục và đánh dấu hàng là "đã xóa". Một lần nữa, đây chỉ là cách cơ sở dữ liệu hoạt động. Để thực sự dọn sạch không gian đĩa, sau đó bạn phải tiếp tục và thực hiện BẢNG TỐI ƯU sau đó và đây không phải là thao tác nhanh. Nó cần có thời gian. Có lẽ nhiều thời gian hơn giá trị của nó. Tổng cộng có thể không đủ để tiết kiệm thời gian cho CPU.

Nếu bạn có một số trường hợp gây ra việc chèn liên tục các quá độ mới không được sử dụng, thì bạn cần phải tìm vấn đề tiềm ẩn thay thế. Chèn những quá độ này là gì? Họ đang sử dụng một khóa thay đổi hoặc đột biến? Nếu vậy, về cơ bản, plugin hoặc mã gây ra điều này nên được sửa thành, không làm điều đó. Điều đó sẽ hữu ích hơn, bởi vì có khả năng mã không tạo ra chúng đúng cách cũng không lấy được chúng, và do đó thực hiện nhiều công việc hơn nó phải làm.

Mặt khác, có thể có một trường hợp mà các quá độ đang được tạo cho một cái gì đó giống như mọi bài đăng. Điều này thực sự có thể được chấp nhận hoàn toàn. Tôi tự làm điều này trong SFC, để lưu trữ các bình luận đến từ Facebook. Mỗi bài đăng có một tiềm năng thoáng qua liên quan đến nó, có nghĩa là hai hàng thêm cho mỗi bài. Nếu bạn có 10k bài đăng, bạn sẽ có 20k hàng trong bảng tùy chọn (cuối cùng). Điều này không tệ hay chậm, bởi vì một lần nữa, có rất ít sự khác biệt giữa 100 hàng và 20.000 hàng theo như cơ sở dữ liệu thực sự quan tâm. Tất cả đều được lập chỉ mục. Nó nhanh như quái. Sub-sub mili giây.

Khi bạn bắt đầu nhận được hàng triệu hàng, thì tôi sẽ lo lắng. Khi kích thước bảng tùy chọn tăng lên trên hàng trăm megabyte, thì tôi đủ quan tâm để xem xét kỹ hơn. Nhưng nói chung, đây không phải là một vấn đề ngoại trừ các trường hợp cực đoan. Nó chắc chắn không phải là một vấn đề cho bất cứ điều gì nhỏ hơn một cái gì đó như một trang web tin tức lớn, với hàng trăm ngàn bài đăng. Và đối với bất kỳ trang web nào đủ lớn để nó trở thành một vấn đề, bạn nên sử dụng bộ đệm đối tượng bên ngoài nào đó, và trong trường hợp đó , các quá độ được lưu trữ tự động ở đó thay vì trong cơ sở dữ liệu.


1
NB: transients với vô thời hạn làm được autloaded, và không hết hạn là mặc định , vì vậy mà một ứng dụng / plugin đang tạo ra rất nhiều transients và không thiết lập một hết hạn họ sẽ sử dụng khối bộ nhớ trên mỗi trang / bài tải.
web biết

Không có lý do để sử dụng "tạm thời không hết hạn", vì về cơ bản nó giống hệt với "tùy chọn" thông thường.
Otto

1
Chắc chắn, nhưng đó là mặc định . Như vậy, nhiều tác giả plugin đang thêm quá độ không hết hạn.
web biết

1
Chà, giải pháp ở đây rất đơn giản: Đừng sử dụng các plugin đó. Họ đang làm sai. Transents không được sử dụng như phiên, bạn không nên sử dụng chúng mà không hết hạn có ý nghĩa và chúng không nên có khóa đột biến hoặc thay đổi.
Otto

2
Nói, 7 ngày. Nếu một tác giả plugin / chủ đề muốn một cái gì đó lớn hơn hoặc nhỏ hơn, họ sẽ chỉ định nó. Nếu họ muốn tự động tải, họ không cần phải chỉ định 0 cho hết hạn (= vô cực), nhưng đó là những gì họ hiện có với tham số hết hạn thực hiện nhiệm vụ kép là tham số có / không tự động tải. Dù bằng cách nào, hết hạn mặc định cũng không nên dẫn đến tự động tải = có như mặc định; đó chỉ là vấn đề rắc rối
web biết

18

Otto - Tôi không thể không đồng ý với bạn nhiều hơn. Vấn đề là cuối cùng với tất cả những quá độ đó, kích thước của bảng trở nên lố bịch. Nó không mất hàng triệu hàng để sa lầy. Tôi hiện đang xử lý một bảng tùy chọn có hơn 130 nghìn hàng và thường xuyên bị treo. Bởi vì trường giá trị là một loại văn bản lớn, thậm chí chỉ tìm kiếm các hàng "tự động tải" trở thành cơn ác mộng về hiệu suất. Các trường giá trị được lưu trữ riêng biệt với phần còn lại của dữ liệu hàng. Mặc dù đó là một phần logic của cùng một bảng, các phép nối phải xảy ra để kéo lên các hàng bạn muốn. Tham gia mà bây giờ mất mãi mãi vì dữ liệu bạn cần được trải đều khắp nơi trên đĩa. Profiling (sử dụng jet profiler cho mysql) đã chứng minh điều này.

Thêm tự động tải vào khóa cụm có thể giúp giải quyết vấn đề này. Ví dụ, phân cụm trên Autoload Desc, ID ASC, sẽ cho phép tất cả các hàng tự động tải lại với nhau trước tiên trên đĩa. Ngay cả tôi vẫn nghĩ rằng bạn đang nhìn vào một sự căng thẳng lớn từ góc độ DB.

Cá nhân tôi nghĩ rằng thiết kế của hệ thống này là lập dị. Bảng tùy chọn dường như đã biến thành một tổng quát cho rất nhiều thứ. Điều đó tốt nếu trường giá trị đủ nhỏ để được đưa vào cùng một trang với phần còn lại của hàng và có thể được lập chỉ mục một cách hiệu quả. Thật không may, đó không phải là trường hợp. Bất cứ ai đã thiết kế điều này cần quay lại lớp DB101.


5
đúng, nhưng hãy xem xét rằng khi bắt đầu phát triển WordPress, không ai nghĩ rằng nó sẽ đạt được hàng ngàn plugin sử dụng bảng tùy chọn làm nơi lưu trữ dữ liệu của họ :)
onetrickpony

@onetrickpony đó là lý do tại sao điều quan trọng là luôn dành thời gian và làm mọi việc đúng đắn, cho dù bạn có mong đợi nó sẽ lớn vào một ngày nào đó hay không :)
Mahmoud Al-Qudsi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.