从大sql备份文件中找出单张表
来源:原创
时间:2018-06-06
作者:脚本小站
分类:PHP
从大的sql备份中找出单张表:
从mysqldump命令导出的大的sql文件中快速找出单张表,php协程方式读取大文件。
<?php set_time_limit(0); // ini_set('max_execution_time', 0); ob_end_clean(); $memory = memory_get_usage(); // 内存使用初始大小 $byte_to_mb = 1024; // 用于单位换算 // 开始查找的行数 $line = 1; // $line = 400000; // sql文件名 $filename = 'dmdb-20180601'; if(!is_dir($filename)) { mkdir($filename); } function get_sql($filename) { $file = fopen($filename.'.sql', "r"); while(!feof($file)) { yield fgets($file, 40240); } fclose($file); } $result = get_sql($filename); $table_name = 'first'; $i = 1; echo "<pre>"; foreach ($result as $key => $value) { if($i < $line){ $i++; continue; } if(substr($value, 0, 12) == 'CREATE TABLE') { $first = strpos($value, '`'); $last = strrpos($value, '`'); $table_name = substr($value, $first + 1, $last - $first - 1); echo round((memory_get_usage() - $memory) / $byte_to_mb, 3).' k ---------- '.$table_name."<br>"; flush(); } file_put_contents($filename.'/'.$table_name.'.sql', $value, FILE_APPEND); } echo ((memory_get_usage() - $memory) / $byte_to_mb).' k';
去除 drop table 语句:
下面的和上面一样,只不过是用来去除drop table语句的:
<?php set_time_limit(0); ini_set('max_execution_time', 0); ob_end_clean(); $memory = memory_get_usage(); // 内存使用初始大小 $byte_to_mb = 1024; // 用于单位换算 // 开始查找的行数 $line = 1; // $line = 400000; // sql文件名 $filename = 't_bond_notification_msg'; $dirname = $filename.'-drop'; if(!is_dir($dirname)) { mkdir($dirname); } function get_sql($filename) { $file = fopen($filename.'.sql', "r"); while(!feof($file)) { yield fgets($file, 40240); } fclose($file); } $result = get_sql($filename); $table_name = 'first'; $i = 1; echo "<pre>"; foreach ($result as $key => $value) { if($i < $line){ $i++; continue; } if(substr($value, 0, 10) == 'DROP TABLE') { $first = strpos($value, '`'); $last = strrpos($value, '`'); $table_name = substr($value, $first + 1, $last - $first - 1); echo round((memory_get_usage() - $memory) / $byte_to_mb, 3).' k ---------- '.$table_name."<br>"; flush(); } file_put_contents($dirname.'/'.$table_name.'.sql', $value, FILE_APPEND); } echo ((memory_get_usage() - $memory) / $byte_to_mb).' k';
方法二:
先找出表所在的行,然后将表写入文件,不过会继续写下面的表,需要手动暂停。
<?php set_time_limit(0); // ini_set('max_execution_time', 0); ob_end_clean(); $memory = memory_get_usage(); // 内存使用初始大小 $byte_to_mb = 1024; // 用于单位换算 $time = time(); echo "<pre>"; // 开始查找的行数 $line = 0; // $line = 417090; // sql文件名 $filename = 'dmdb-20180601'; $dirname = $filename.'-line'; if(!is_dir($dirname)) { mkdir($dirname); } function get_sql($filename) { $file = fopen($filename.'.sql', "r"); while(!feof($file)) { yield fgets($file); } fclose($file); } $result = get_sql($filename); $table_name = 'first'; $str = "CREATE TABLE `t_bond_notification_msg` (\n"; $i = 1; $start_line = 0; foreach ($result as $key => $value) { if($i < $line){ $i++; continue; } $i++; if($value == $str) // 这个语句只适合找出所在的行 { $start_line = $i; break; } } echo 'time: '.(time() - $time).' s<br>'; echo 'size: '.((memory_get_usage() - $memory) / $byte_to_mb).' k<br>'; echo 'line: '.$start_line; echo "<br>"; flush(); $result = get_sql($filename); $j = 0; $start_line = $start_line - 10; foreach ($result as $key => $value) { if($j < $start_line){ $j++; continue; } $j++; if(substr($value, 0, 12) == 'CREATE TABLE') { $first = strpos($value, '`'); $last = strrpos($value, '`'); $table_name = substr($value, $first + 1, $last - $first - 1); echo 'memo: '.round((memory_get_usage() - $memory) / $byte_to_mb, 3).' k ---------- '.$table_name."<br>"; echo 'line: '.$j.'<br>'; echo 'time: '.(time() - $time).'<br>'; flush(); } file_put_contents($dirname.'/'.$table_name.'.sql', $value, FILE_APPEND); }