我需要恢复很多mysql数据库备份,我一直在尝试使用多个线程(在delphi中)来加速,每个线程都有自己的连接。当我使用mode_脚本时,我只能每秒处理1个文件(fps),cpu/磁盘/内存完全没有压力
当我使用mode_cmd时,我可以获得高达12+fps的速度,所有内核的cpu都可以达到100%。
使用tclientdataset或子体时,脚本似乎没有使用所有内核,即使使用多个线程也是如此?
最小代码示例:
type
TWorker = class(TThread)
private
FTasks: TThreadStringList;
FConn: TMyConnection;
FScript: TMyScript;
FQ: TMyQuery;
protected
procedure Execute; override;
public
procedure addTask(const aFn: String);
constructor create(Suspended: Boolean; const aMyId: LongInt;const aIniDb: TIniDBSettings);
end;
procedure TWorker.addTask(const aFn: String);
begin
FTasks.Add(aFn);
end;
constructor TWorker.create(Suspended: Boolean; const aMyId: LongInt; const aIniDb: TIniDBSettings);
begin
inherited Create(Suspended);
FTasks := TMTThreadStringList.Create;
FMyName := 'WORKER__'+IntToStr(aMyId);
end;
procedure TWorker.Execute;
var
mode: LongInt;
const
MODE_DOS=1;
MODE_SCRIPT = 2;
begin
FConn := TMyConnection.Create(Nil);
FConn.Username := aIniDb.iniSDBUsername;
FConn.Password := aIniDb.iniSDBPass;
FConn.Database := aIniDb.iniSDBDatabase;
FConn.Server := aIniDb.iniSDBServer;
FScript := TMyScript.Create(Nil);
FScript.Connection := FConn;
try
FConn.Connect;
while not Terminated do begin
if FTasks.Count > 0 then begin
tmpFn := FTasks.Strings[0];
FTasks.Delete(0);
fMyDbname := 'tmpdb_'+FMyName;
if(mode=MODE_SCRIPT) then {
FQ.SQL.Text := 'drop database if exists '+fMyDbname ;
FQ.Execute;
FQ.SQL.Text := 'create database '+fMyDbname;
FQ.Execute;
FQ.SQL.Text := 'use '+fMyDbname;
fQ.Execute;
FScript.SQL.LoadFromFile(tmpFn+'.new');
FScript.Execute;
}
else if(mode=MODE_DOS) then begin
sCmd := 'cmd.exe /c mysql -u user -h serverip < '+tmpFn;
GetDosOutput(sCmd,dosOutput);//function using 'CreateProcess()'
}
InterlockedIncrement(QDONE);
end
else Sleep(15);
end;
except on e: Exception do
MessageBox(0,PWideChar('error'+e.Message),'error',MB_OK);
end;
end;
1条答案
按热度按时间6l7fqoea1#
听起来你在用myisam。这是过时的,并且受到“表锁”的影响,这在很大程度上抑制了并行性。
以下与myisam无关:
与问题相关的一些问题:
你有
AUTO_INCREMENT
柱?您是否同时从不同的线程插入到同一个表中(myisam和内存有问题,而innodb就没有了。)
有多少
UNIQUE
每张table上的钥匙(INSERTs
由于需要检查DUP而减慢了速度。)你在用吗
INSERT
? 一次一排?还是成批(一次插入100行的批大约是最佳的——是一次插入1行的10倍。)还是你在用
LOAD DATA
? (甚至更快。)“文件”和“表”之间的关系是什么?也就是说,您是将许多小文件加载到一个表中,还是每个文件都是一个表?
raid是否有条带化和/或电池支持的写缓存?
磁盘是hdd还是ssd?
客户端和服务器之间的ping时间是多少(你提到了“网络”,但没有表示接近。)
有多少张table?是否每秒最多创建1.87个表?三个文件要写,一个文件要读(windows在快速打开文件方面不是最好的。)这大约是每秒打开7个文件(注意:如果使用innodb,则每个表只需要1个文件
innodb_file_per_table=1
.)请提供
SHOW CREATE TABLE
为了几张更大的table。请提供所用sql语句的示例。威尔逊的要求也很方便。