Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Podzielenie zasobożernej operacji na kilka kroków, problem
vee
post 18.01.2012, 13:45:19
Post #1





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Witam,

Pewnego dnia stanąłem przed potrzebą zrobienia kopii ogromnej bazy danych oraz jeszcze większej ilości plików.
Ponieważ nie mam dostępu do SSH, postanowiłem wykorzystać unixowe komendy przez PHP:

  1. exec('cp ...');


ze względu na dużą objętość danych, na których te operacje będą przeprowadzane, skrypt się wykrzaczał. Postanowiłem wtedy podzielić go na kilka kroków, dla przykładu
1. dump bazy danych
2. wgranie dumpa do innej bazy danych
3. kopia plików

  1. <?php
  2. $tmp = file_get_contents('tmp.txt');
  3. if($tmp = 'step1')
  4. {
  5. ...
  6. file_put_contents('tmp.txt', 'step2');
  7. header('Location: plik.php');
  8. }
  9. elseif($tmp = 'step2')
  10. {
  11. ...
  12. file_put_contents('tmp.txt', 'step3');
  13. header('Location: plik.php');
  14. }
  15. elseif($tmp = 'step3')
  16. {
  17. ...
  18. file_put_contents('tmp.txt', 'step1');
  19. }


jak widać po wykonaniu "kroku" zapisuję w pliku tymczasowym jaki krok jest następny oraz wysyłam nagłówek header('Location: plik.php') celem odświeżenia - wtedy wykonać ma się następny i następny krok.

Mój problem polega na tym, że dopóki testuję to z zakomentowanymi liniami odpowiedzialnymi za w/w operacje (zostaje samo "przechodzenie do nast kroku") - wszystko chodzi dobrze, w firebugu widać dokładnie, że wszystkie kroki się wykonują.

Problem pojawia się, gdy odkomentuję właściwy kod, tzn w momencie kopiowania jakiegoś bardzo dużego katalogu, lub podczas wykonywania innej, potrzebującej sporo czasu do ukończenia, operacji - praca jest przerywana, tzn. nie wysyła nagłówka o przekierowaniu, w pliku TMP mam elegancko wskazane na jakim kroku przerwało pracę.

Dodam, że limit czasu ustawiony na "0", raportowanie błędów mam włączone- jednak takie nie zostają wyświetlane.

Ma ktoś jakiś pomysł, dlaczego tak się dzieje i jak temu zaradzić?

Pozdrawiam wink.gif

EDIT: Dodam, że na każdy krok przydzielona jest tylko jedna komenda uniksowa, tzn w jednym kroku jest tworzony dump bazy, w drugim jest on wgrywany do innej bazy, w trzecim np kopia plików z... do... itd.

Ten post edytował vee 18.01.2012, 13:49:00
Go to the top of the page
+Quote Post
Uriziel01
post 18.01.2012, 14:12:53
Post #2





Grupa: Zarejestrowani
Postów: 307
Pomógł: 37
Dołączył: 9.11.2010
Skąd: Zielona Góra

Ostrzeżenie: (0%)
-----


Jesteś pewny że to przekroczenie czasu ?
Dla pewności daj wynik z:
  1. ini_get('max_execution_time');
  2. ini_get('max_input_time');


Jesteś pewny że to nie przekroczenie limitu pamięci albo błąd w tym `zakomentowanym` kodzie ? Może pokaż choć po części co tam się znajduje ? W logach serwera/php niczego nie widać ?

Ten post edytował Uriziel01 18.01.2012, 14:15:43
Go to the top of the page
+Quote Post
vee
post 18.01.2012, 14:18:49
Post #3





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Krok, który się wywala najczęściej to:

  1. exec('cp katalog1 katalog2');


gdzie katalog1 jest, krótko mówiąc, ogromny. Poza tym exec'iem, zapisem następnego kroku do tmp.txt oraz wysłaniem nagłówka - w tym kroku nie jest wykonywane nic więcej. No i oczywiście na początku włączenie pokazywania błędów i limit czasu "0".

Var dump podanych przez Ciebie linijek :
Kod
string(1) "0" // max_execution time
string(2) "-1" // max_input_time


Pozdrawiam
Go to the top of the page
+Quote Post
by_ikar
post 18.01.2012, 14:21:23
Post #4





Grupa: Zarejestrowani
Postów: 1 798
Pomógł: 307
Dołączył: 13.05.2009
Skąd: Gubin/Wrocław

Ostrzeżenie: (0%)
-----


http://sypex.net/en/ <-- możesz podłączyć to chyba nawet pod crona, jak nie masz nawet tego na serwerze, to może to być webcron, które są dostępne w necie za free (webcron.pl chociażby). Zrobi ci pięknie kopie nawet dość dużej bazy. Tyle w przypadku bazy, w przypadku plików, to IMO lepiej nie zaprzęgać do tego php, core systemu możesz machnąć w php, taki dużo przeważnie nie ma. Ale jakieś zewnętrzne obrazki, to już lepiej robić czym innym niż php. Jak możesz listować katalog z obrazkami, to wystarczyć ci będzie sam wget, który może pobrać wszystko rekursywnie, lub poprostu odpalić ftp z konsoli.
Go to the top of the page
+Quote Post
vee
post 18.01.2012, 14:24:58
Post #5





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Niestety zewnętrzne rozwiązania odpadają z kilku względów - min konieczność ochrony danych, na których przeprowadzane są owe operacje. Poza tym szef nalega aby było to rozwiązanie w 100% stworzone (udokumentowane oraz opisane) przeze mnie (głównie ze względu na późniejszą modyfikację/modernizację kodu, oraz rzeczoną ochronę informacji).

Możliwe aby to usługodawca przykręcał nam "kurek" jeśli chodzi o generowane obciążenie? Czy PHP wyplułoby z siebie jakiś błąd w takiej sytuacji?

EDIT: Dodam, że wcześniej rozwiązane było to w taki sposób, że CRON wykonywał skrypt raz dziennie (z dnia na dzień wykonywany był krok po kroku) i wtedy również wywalało się to na bardziej obciążających operacjach.

Ten post edytował vee 18.01.2012, 14:29:24
Go to the top of the page
+Quote Post
Uriziel01
post 18.01.2012, 14:34:37
Post #6





Grupa: Zarejestrowani
Postów: 307
Pomógł: 37
Dołączył: 9.11.2010
Skąd: Zielona Góra

Ostrzeżenie: (0%)
-----


Hmmm, a na czym to stoi ? Bo widząc `przykręcał nam "kurek"`, jakiś VPS ? Może jakich guardian zamyka proces w trakcie jego trwania bo przekroczył limit czasu ?
Go to the top of the page
+Quote Post
vee
post 18.01.2012, 14:38:30
Post #7





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Niestety wciąż home.pl, jest to jedyna tak "niestandardowa" operacja, więc przeskakiwanie na serwer dedykowany tylko z tego powodu niestety nie wchodzi w grę wink.gif
Każde inne wykorzystanie serwera nie wychodzi poza jakieś standardy, właściwie to są to proste strony/portale nie generujące specjalnie dużego transferu czy ruchu.

Jeśli chodzi o zamykanie procesu w trakcie jego trwania, nie wydaje mi się to prawdopodobne, ponieważ skrypt wysypuje się po różnych czasach trwania, przeważnie na kroku, gdzie przeprowadzane jest kopiowanie plików. Oczywiście miejsce na serwerze jest, błędów żadnych nie wyświetla.


EDIT:

Chyba dopatrzyłem się dlaczego tak się dzieje - nie wiem dlaczego, ale przegapiłem następujące.
Zwrot z metody CP ląduje w nagłówkach, oto co widzę:

"cannot create regular file `/sciezka/sciezka/sciezka/sciezka/settings.php': Permission denied"

powyższe powtarza się dla wszystkich plików, z ograniczeniami dostępu. Czy jest możliwe skopiowanie za jednym zamachem zarówno tych plików (z ograniczeniami) jak i tych "publicznych"? Jak poprzez FTP dla pojedynczego pliku ustawiłem CHMOD na 777 - nie pojawił się on w zwrotnym nagłówku, jednak takie rozwiązanie niestety odpada - mowa o kilkuset plikach.

EDIT2: oczywiście nie mogę się zalogować jako ROOT wink.gif więc to rozwiązanie odpada. Jeśli się nie da skopiować tych plików ze względu na uprawnienia, to czy można zrobić to tak, żeby operacja pomimo tych błędów była dalej wykonywana?

Ten post edytował vee 18.01.2012, 14:51:59
Go to the top of the page
+Quote Post
adbacz
post 18.01.2012, 15:27:43
Post #8





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


A masz jakoś ładnie ułozony, stworzony katalog/katalogi z tymi plikami? Jesli tak, to najpeirw przeleć po plikach ustawiając im odpowiedni CHMOD (777), za pomocą funkcji php chmod(), a dopiero później je przenoś/kopiuj.
Go to the top of the page
+Quote Post
abort
post 18.01.2012, 22:38:08
Post #9





Grupa: Zarejestrowani
Postów: 590
Pomógł: 107
Dołączył: 25.10.2011

Ostrzeżenie: (0%)
-----


1. Jak nigdy nie jestem zwolennikiem instrukcji "system", tak właśnie tu do zmiany praw dostępu bym właśnie to zastosował.
  1. system ('chmod -R [prawa] [ścieżka]', $ret_val);

2. Drobna uwaga... Piszesz, że przez FTP jesteś w stanie zmienić prawa i wszystko jest OK. Czy możesz podać usera, grupę i prawa dostępu dla plików, które nie chcą się skopiować, zanim im nie zmienimy praw?
3. Kontynuując punkt poprzedni: utwórz jakiś plik via apache/php (albo wykorzystaj ten plik TMP opisywany wcześniej), jak również wgraj plik normalnie przez klienta FTP. Porównaj wartości usera, grupy i praw do w/w plików, pomoże Ci w tym instrukcja fstat

Przy okazji: "ogromna baza", "jeszcze większa ilość plików" - czy mógłbyś choć trochę przybliżyć wartości, o których piszesz?
Go to the top of the page
+Quote Post
vee
post 19.01.2012, 08:32:44
Post #10





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Problem uprawnień rozwiązany;
Główny problem jednak wciąż występuje. Skrypt wciąż przerywa pracę podczas kopiowania plików. W nagłówkach tym razem nie ma żadnej wskazówki (przerywa na innym kroku).
Co do rozmiaru plików... możliwe, że jest związek z tym, jednak tym razem wywala się na mniejszych katalogach. Co dziwne, kopie plików przeprowadzane są raz na jednym katalogu, a następnie na drugim. Pierwszy katalog jest o wiele większy, jednak to na drugim się wywala. Oczywiście kopie te są podzielone na oddzielne "kroki".


Operacje są na katalogach nieprzekraczających 1GB (pierwszy i drugi katalog). Okolice 800MB. W tej chwili trudno jest mi ustalić dokładny rozmiar tych danych. Bazy zajmują po 600-700Mb, ale z nimi póki co nie ma problemu.
Go to the top of the page
+Quote Post
adbacz
post 19.01.2012, 11:10:33
Post #11





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


A nie mozesz zrobić najpierw jednego kroku, później następnego i tak dalej, ale w osobnych skryptach? Powiedzmy, zrobić tyle plików /spep-n.php ile masz króków, gdzie n to następny krok. W tedy mógłbyś zrobić wszystko po kolei, i głowić się tylko nad tym zadaniem, które nie chce się zrobić, powiedzmy /step-2.php. Warto rozbić takie zadania na mniejsze, żeby zobaczyć czego dokładnie problem dotyczy.
Go to the top of the page
+Quote Post
piotrooo89
post 19.01.2012, 11:21:48
Post #12


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




wiec możesz to zrobić za pomocą nice i przekierowanie do /dev/null, czyli tak:

Kod
nice -n 19 cp cos_tam cos_tam > /dev/null &


coś takiego obniża Ci priorytet, wykonania i nie zajedziesz serwera dzięki czemu możesz wykonać 100 taki operacji i nie powinno zajeżdżać maszyny. no a wyjście przekierowujesz do /dev/null więc php nie czeka na odpowiedz.


--------------------
Go to the top of the page
+Quote Post
vee
post 19.01.2012, 13:30:26
Post #13





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


@piotrooo89
Ok, komendy wykonują się piorunem, jednak czy mam jakąkolwiek pewność, że nie zostały one przerwane w połowie? Tzn czy mogę jakoś potwierdzić, że cała operacja przebiegła pomyślnie? Bo ręczne przeglądanie tych plików może być uciążliwe... wink.gif Chodzi mi o możliwość zapisania do pliku informacji po ukończeniu tych operacji - to możliwe czy nie bardzo?

Ten post edytował vee 19.01.2012, 13:31:17
Go to the top of the page
+Quote Post
piotrooo89
post 19.01.2012, 13:34:59
Post #14


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




no możesz w samym php zapisać ile plików miałeś na początku (przed kopiowaniem) i sprawdzić go z ilością plików po skopiowaniu.


--------------------
Go to the top of the page
+Quote Post
vee
post 19.01.2012, 14:00:10
Post #15





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Mógłbyś mi jeszcze odpowiedzieć na takie pytanie, ponieważ nie jestem pewien a może będziesz wiedział.

czy do polecenia:
mysql -u user--password=pass -h localhost nazwabazy < plik.sql

lub
mysqldump -u user --password=pass -h localhost --opt nazwabazy> plik.sql

mogę dopisać to "> /dev/null &", tak aby PHP nie czekał na odpowiedź serwera?
Go to the top of the page
+Quote Post
piotrooo89
post 19.01.2012, 14:02:31
Post #16


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




tak, możesz tak zrobić, każde polecenie możesz kierować do /dev/null i wtedy php nie oczekuje na zakończenie, ale nie wiem czy się opłaca z tym importem, bo może się tak stać że będziesz miał niespójne dane, bo w trakcie importu ktoś coś będzie dodawał, ale to nie jestem pewnie jak działa bo nie robiłem nigdy czegoś takiego.


--------------------
Go to the top of the page
+Quote Post
vee
post 19.01.2012, 14:05:45
Post #17





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Może uściślę, czysto dla pewności - w przypadku mysqldump mam 100% pewności, że kod SQL wyląduje we wskazanym pliku a nie w /dev/null? wink.gif Polecenia te będą wykonywane o takiej porze, że nie będzie zagrożenia niespójności danych (poza godzinami pracy).
Go to the top of the page
+Quote Post
piotrooo89
post 19.01.2012, 14:10:19
Post #18


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




wydaje mi się na 99.99% że będzie ok:

Kod
mysql < sql.sql > /dev/null &


taki plik zaimportuje do mysql i wszystkie komunikaty zostaną przekierowane do /dev/null i dodatkowo polecenie zostanie wykonane w tle (&).


--------------------
Go to the top of the page
+Quote Post
vee
post 20.01.2012, 08:13:21
Post #19





Grupa: Zarejestrowani
Postów: 64
Pomógł: 5
Dołączył: 16.08.2011

Ostrzeżenie: (0%)
-----


Dla potomnych - pliki SQL, w których miał znajdować się zrzut bazy danych były puste po dodaniu "> /dev/null &". Na szczęście przesiadamy się jednak (po wielu moich naciskach:)) na serwer dedykowany, z dostępem przez SSH więc nie powinno być problemu już.

Pozdrawiam i dzięki wszystkim za pomoc! wink.gif

Ten post edytował vee 20.01.2012, 08:13:54
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 15.05.2024 - 03:44