Tôi nghĩ rằng tôi đã tìm thấy giải pháp. Đối với một số thời gian tôi đã nhìn vào máy chủ Percona để thay thế máy chủ MySQL của tôi, và bây giờ tôi nghĩ rằng có một lý do chính đáng cho việc này.
Máy chủ Percona giới thiệu nhiều bảng INFORMATION_SCHEMA mới như INNODB_TABLE_STATS, không có sẵn trong máy chủ MySQL chuẩn. Khi bạn thực hiện:
SELECT rows, modified FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table'
Bạn nhận số đếm thực tế và bộ đếm.Các Official documentation nói như sau về lĩnh vực này:
Nếu giá trị của cột được sửa đổi vượt “hàng/16” hoặc 2000000000, các thống kê tính toán lại được thực hiện khi innodb_stats_auto_update == 1. Chúng tôi có thể ước tính oldness của thống kê theo giá trị này.
Vì vậy, bộ đếm này sẽ kết thúc mọi lúc, nhưng bạn có thể kiểm tra số lượng hàng và bộ đếm, và sau đó với mọi sửa đổi của bảng, bạn sẽ có một lần kiểm tra duy nhất. Ví dụ:
SELECT MD5(CONCAT(rows,'_',modified)) AS checksum FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table';
Tôi sẽ nâng cấp máy chủ của mình lên máy chủ Percona vì vậy giới hạn này không phải là vấn đề đối với tôi. Quản lý hàng trăm trình kích hoạt và thêm các trường vào bảng là một nỗi đau lớn cho ứng dụng này, vì nó rất chậm phát triển.
Đây là chức năng PHP tôi đã đi lên với để đảm bảo rằng bảng có thể được bất cứ điều gì checksummed động cơ và máy chủ được sử dụng:
function checksum_table($input_tables){
if(!$input_tables) return false; // Sanity check
$tables = (is_array($input_tables)) ? $input_tables : array($input_tables); // Make $tables always an array
$where = "";
$checksum = "";
$found_tables = array();
$tables_indexed = array();
foreach($tables as $table_name){
$tables_indexed[$table_name] = true; // Indexed array for faster searching
if(strstr($table_name,".")){ // If we are passing db.table_name
$table_name_split = explode(".",$table_name);
$where .= "(table_schema='".$table_name_split[0]."' AND table_name='".$table_name_split[1]."') OR ";
}else{
$where .= "(table_schema=DATABASE() AND table_name='".$table_name."') OR ";
}
}
if($where != ""){ // Sanity check
$where = substr($where,0,-4); // Remove the last "OR"
$get_chksum = mysql_query("SELECT table_schema, table_name, rows, modified FROM information_schema.innodb_table_stats WHERE ".$where);
while($row = mysql_fetch_assoc($get_chksum)){
if($tables_indexed[$row[table_name]]){ // Not entirely foolproof, but saves some queries like "SELECT DATABASE()" to find out the current database
$found_tables[$row[table_name]] = true;
}elseif($tables_indexed[$row[table_schema].".".$row[table_name]]){
$found_tables[$row[table_schema].".".$row[table_name]] = true;
}
$checksum .= "_".$row[rows]."_".$row[modified]."_";
}
}
foreach($tables as $table_name){
if(!$found_tables[$table_name]){ // Table is not found in information_schema.innodb_table_stats (Probably not InnoDB table or not using Percona Server)
$get_chksum = mysql_query("CHECKSUM TABLE ".$table_name); // Checksuming the old-fashioned way
$chksum = mysql_fetch_assoc($get_chksum);
$checksum .= "_".$chksum[Checksum]."_";
}
}
$checksum = sprintf("%s",crc32($checksum)); // Using crc32 because it's faster than md5(). Must be returned as string to prevent PHPs signed integer problems.
return $checksum;
}
Bạn có thể sử dụng nó như thế này:
// checksum a signle table in the current db
$checksum = checksum_table("test_table");
// checksum a signle table in db other than the current
$checksum = checksum_table("other_db.test_table");
// checksum multiple tables at once. It's faster when using Percona server, because all tables are checksummed via one select.
$checksum = checksum_table(array("test_table, "other_db.test_table"));
Tôi hy vọng điều này sẽ tiết kiệm một số rắc rối cho những người khác có cùng một vấn đề.
trùng lặp: http://dba.stackexchange.com/questions/9569/fastest-way-to-check-if-innodb-table-has-changed –
Bạn có thể muốn xem [câu hỏi/câu trả lời này] (http://stackoverflow.com/questions/2785429/how-can-i-determine-when-an-innodb-table-was-last-changed) (nếu bạn chưa làm điều đó). –
Ah, OK, đây là chủ đề của tôi, nhưng tôi không nghĩ rằng đây là trang web tương tự ... xin lỗi, tôi mới ở đây. – Jacket