Use limit and offset which will return just part of your result, limited to limit and offseted by offset. While using these, remember of sorting your rows, so you won't get same row twice. My advice is to sort by primary key or date creation of row ascending - in your case (while(true)) loop you are pretty sure that even records added after start of the program will be processed.
Example below uses PDO to query database.
$package = 1000;
$i = 0;
try{
while(true){
$currOffset == i++ * $package;
$q = $db->query(
"select
*
from
foo
order by
bar ASC
offset :offset
limit :limit"
);
$q->bindParam(':offset', $currOffset, PDO::PARAM_INT);
$q->bindParam(':limit', $package, PDO::PARAM_INT);
$q->execute();
$res = $q->fetchAll(PDO::FETCH_ASSOC);
if(!$res || !count($res)){
break;
}
//process your chunk
}
} catch(PDOException $ex){
//handle exception, abort transaction etc
}