해결책을 찾았습니다. 얼마 동안 Percona Server에서 MySQL 서버를 교체하려고했지만 지금은 그럴만한 이유가 있다고 생각합니다.
Percona 서버는 표준 MySQL 서버에서 사용할 수없는 INNODB_TABLE_STATS와 같은 많은 새로운 INFORMATION_SCHEMA 테이블을 도입했습니다. 할 때 :
SELECT rows, modified FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table'
실제 행 수와 카운터를 얻습니다. 공식 문서는 이 분야에 대한 다음 말한다 :
수정 된 열의 값이 "rows / 16"또는 2000000000을 초과하면 innodb_stats_auto_update == 1 일 때 통계 재 계산이 수행됩니다.이 값으로 통계의 오래된 정도를 추정 할 수 있습니다.
따라서이 카운터는 가끔씩 랩핑되지만 행 수와 카운터의 체크섬을 만든 다음 테이블을 수정할 때마다 고유 한 체크섬을 얻을 수 있습니다. 예 :
SELECT MD5(CONCAT(rows,'_',modified)) AS checksum FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table';
어쨌든 내 서버를 Percona 서버로 업그레이드하려고 했으므로이 경계는 문제가되지 않습니다. 수백 개의 트리거를 관리하고 테이블에 필드를 추가하는 것은 개발이 매우 늦기 때문에이 애플리케이션의 주요 어려움입니다.
이것은 엔진과 서버가 사용되는 테이블을 체크섬 할 수 있도록 PHP 기능입니다.
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;
}
다음과 같이 사용할 수 있습니다.
// 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"));
나는 이것이 같은 문제를 가진 다른 사람들에게 약간의 어려움을 덜어주기를 바랍니다.