Robiłem bulk inserts
w RealTime Index
przy użyciu PHP i wyłączając AUTOCOMIT, np.Sfinks Jak utrzymywać połączenie aktywne, nawet jeśli nie ma aktywności przez dłuższy czas?
// sphinx connection
$sphinxql = mysqli_connect($sphinxql_host.':'.$sphinxql_port,'','');
//do some other time consuming work
//sphinx start transaction
mysqli_begin_transaction($sphinxql);
//do 50k updates or inserts
// Commit transaction
mysqli_commit($sphinxql);
i przechowywane skrypt działa na noc, rano widziałem
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate
212334 bytes) in
więc gdy sprawdziłem plik nohup.out
bliżej, zauważyłem, te linie, wykorzystanie
PHP Warning: mysqli_query(): MySQL server has gone away in /home/script.php on line 502
Warning: mysqli_query(): MySQL server has gone away in /home/script.php on line 502
pamięć zanim te linie były normalne, ale użycie pamięci po tych liniach zaczęło wzrastać, i uderzyło w php
mem_limit
i dało PHP Fatal error
i zmarł.
in script.php , line 502 is
mysqli_query($sphinxql,$update_query_sphinx);
Więc zgaduję, że serwer sfinks został zamknięty/zmarł po kilku godzinach/minutach bezczynności.
Próbowałem ustawienie w sphinx.conf
client_timeout = 3600
wznowił searchd przez
systemctl restart searchd
i nadal jestem stoi sam problem.
Jak więc nie mogę sprawić, że serwer sfinksów umrze na mnie, gdy żadna aktywność nie będzie obecna przez dłuższy czas?
więcej informacji dodanej -
otrzymuję dane z mysql w 50k kawałki na raz i robi pętli while sprowadzić każdy wiersz i aktualizować go w sfinks indeksu RT. tak jak to
//6mil rows update in mysql, so it takes around 18-20 minutes to complete this then comes this following part.
$subset_count = 50000 ;
$total_count_query = "SELECT COUNT(*) as total_count FROM content WHERE enabled = '1'" ;
$total_count = mysqli_query ($conn,$total_count_query);
$total_count = mysqli_fetch_assoc($total_count);
$total_count = $total_count['total_count'];
$current_count = 0;
while ($current_count <= $total_count){
$get_mysql_data_query = "SELECT record_num, views , comments, votes FROM content WHERE enabled = 1 ORDER BY record_num ASC LIMIT $current_count , $subset_count ";
//sphinx start transaction
mysqli_begin_transaction($sphinxql);
if ($result = mysqli_query($conn, $get_mysql_data_query)) {
/* fetch associative array */
while ($row = mysqli_fetch_assoc($result)) {
//sphinx escape whole array
$escaped_sphinx = mysqli_real_escape_array($sphinxql,$row);
//update data in sphinx index
$update_query_sphinx = "UPDATE $sphinx_index
SET
views = ".$escaped_sphinx['views']." ,
comments = ".$escaped_sphinx['comments']." ,
votes = ".$escaped_sphinx['votes']."
WHERE
id = ".$escaped_sphinx['record_num']." ";
mysqli_query ($sphinxql,$update_query_sphinx);
}
/* free result set */
mysqli_free_result($result);
}
// Commit transaction
mysqli_commit($sphinxql);
$current_count = $current_count + $subset_count ;
}
Można aktualizować/wstawiać w mniejsze porcje. Powiedz 1k. Lub zaktualizuj/wstaw w jednym zapytaniu (jeśli jest to możliwe w twoim przypadku). – Andrew
@Andrew Mam około 6 milionów rekordów do codziennej aktualizacji, więc 1k rekordów na cykl jest czasochłonny, więc szukam czegoś solidnego rozwiązania, nawet czegoś w rodzaju funkcji przywracania połączenia, która utrzyma połączenie aktywne w każdej pętli. – AMB
Czy możesz pisać zapytania? Mam przeczucie, że może być bardziej związany z tym niż cokolwiek innego. – Andrew