从大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);
}