David Steinsland – informatikkstudent og webutvikler

Innlegg merket med «mysql»

Daglig backup av MySQL med PHP (Windows)

| Ingen kommentarer »

PHP tips og triks

Dersom du drifter din egen server eller har en utviklingsserver på PC-en din, har du nok vært i situasjoner hvor du tenker: «Hvor er sikkerhetskopien når jeg trenger den?».

Jeg var der selv for omtrent en úke siden, hvor jeg ved en feiltakelse kjørte en gammel PHP-fil som overskrev hele Postnummer-databasen min. Heldigvis hadde jeg mange sikkerhetskopier av databasen, så det gikk bra.

Men hva om jeg ikke hadde hatt kopier? Da hadde faktisk hele arbeidet mitt vært ødelagt! Mangfoldige timer bortkastet, bokstavelig talt.

Hver dag (midnatt) blir livredderen utført: en planlagt oppgave i Windows kjører et PHP-skript som tar backup av MySQL.

I mine siste artikler har jeg skrevet litt om planlagte oppgaver i Windows, og vist flere ting du kan gjøre.

Teori

Når du installerte MySQL, fikk du med et program som heter mysqldump. Programmet brukes til å ta backup av MySQL; du kan selv spesifisere én eller flere databaser, eller om du ønsker å ta backup av alle.

Videre kommer jeg til å ta i bruk  PHP fra kommandolinjen, som muliggjør at vi kan bruke PHP-tolkeren til å kjøre en bestemt PHP-fil. Dette programmet ligger i installasjonsmappen til PHP, og heter php.exe

Jeg refererer til disse programmene som henholdsvis mysqldump og php fra kommandolinjen. Dette er fordi jeg har lagt til PHPs installasjonsmappe og bin-mappen til MySQL til miljøvariabelen PATH. Dette forteller Windows at når du skriver inn et program i CMD, skal den også leite etter det programmet i de plasseringene.

Dersom du ikke har gjort dette, må du spesifisere til programmene med full sti, eks: c:\php\php eller skrive inn følgende i CMD:

SET PATH = %PATH%;C:\PHP;C:\MySQL\bin

(jeg antar PHP og MySQL er installert i C:\).

Ved default ligger «.EXE» i miljøvariabelen PATHEXT, som medfører at du slipper å skrive «.exe» bak programnavnet.

PHP-filen

Gjør klar en PHP-fil som du navngir backup.php og plasser denne utenfor ServerRoot (altså en plass den ikke kan nåes via en nettleser).

ServerRoot hos meg er \www\public_html\, slik at jeg har plassert PHP-filen ett steg opp, i \www\ (Med baklengs-skråstrek foran stien, tolker Windows dette som C:\).

Lag så en mappe du kaller for backup i samme mappe hvor du har plassert PHP-filen. Dette er plassen hvor backupene våre kommer til å ligge.

Det første vi gjør i PHP-filen vår er å definere et par runtime-innstillinger, som databasetilkoblingen, plasseringen til backup-filene og hvordan filnavnet skal utformes.

// MySQL host
define ('HOST', 'localhost');
// MySQL username
define ('USER', 'username');
// MySQL password
define ('PW', 'password');

define ('DUMP_FILENAME', date ('Y-m-d-H-i') . '.sql'); // i.e. 2010-10-30-23-00.sql

define ('SELF_DIR', __DIR__ . DIRECTORY_SEPARATOR);
define ('BACKUP_DIR', 'backup' . DIRECTORY_SEPARATOR);

Backupfilene våre får navnet sitt basert på dagens dato og tidspunktet for når filen blir kjørt.

Neste steg er å kalle opp mysqldump:

passthru (sprintf ('mysqldump -h %s -u %s -p%s -A -r "%s"', HOST, USER, PW, SELF_DIR . BACKUP_DIR . DUMP_FILENAME));

Her trenger du ikke endre noe, bortsett fra stien til mysqldump om du ikke har endret PATH i Windows.

Argumentforklaring:

-h
Spesifiserer host-adressen til MySQL
-u
Brukernavnet til MySQL
-p
Passordet ditt MySQL-brukeren (-p og passordet skal ikke ha mellomrom mellom hverandre).
-A
Spesifiserer at vi skal ta backup av alle databasene. Alternativt –all-databases.
-r
Den fulle stien (plassering + filnavn) til hvor backupen ligger

Det neste jeg har valgt å gjøre, er å komprimere SQL-filen i et Zip-arkiv, som medfører at filstørrelsen blir endel mindre (noe som er bra!).

$Zip = new ZipArchive;
$Zip->open (SELF_DIR . BACKUP_DIR . DUMP_FILENAME . '.zip', ZipArchive::CREATE);
$Zip->setArchiveComment ('This database dump was automatically taken at ' . date ('H:i, d.m.Y') . ' by a Windows Scheduled Task');
$Zip->addFile (DUMP_FILENAME, SELF_DIR . BACKUP_DIR . DUMP_FILENAME);
unlink (SELF_DIR . BACKUP_DIR . DUMP_FILENAME);
$Zip->close();

Den planlagte oppgaven

Det siste steget vårt, er å opprette oppaven som skal kjøre PHP-skriptet. Jeg har valgt å kjøre denne oppgaven hver dag ved midnatt.

Opprett den planlagte oppgaven ved å skrive dette inn i CMD:

SCHTASKS /Create /SC DAILY /MO 1 /ST 00:00 /TN "MySQL Backup" /TR "php \www\backup.php"

Tips

Uten PHP

Dersom du ikke ønsker å komprimere filene med Zip, trenger du heller ikke anvende PHP til denne jobben. Da kjører du rett og slett bare mysqldump direkte i oppgaven:

SCHTASKS /Create /SC DAILY /MO 1 /ST 00:00 /TN "MySQL Backup" /TR "mysqldump -h <host> -u <brukernavn> -p<passord> -A -r \www\backups\database_dump.sql"

Husk at det ikke skal være mellomrom mellom -p og passordet!

Én eller flere databaser istedenfor alle

Erstatt -A i mysqldump-kommandoen med:

--database <database>

eller

--databases <database 1> <database 2> ... <database N>

Garbage Collector

Det tar ikke lange tiden før backup-mappen blir full av filer; og strengt talt så trenger du ikke backups som ble tatt for måneder siden. Derfor kan det være lurt å sette opp en søppelsamler, som sletter gamle filer.
Da oppretter du en planlagt oppgave som kjører for eksempel \www\garbage.php hver uke. Innholdet i PHP-filen er å loope gjennom backup-mappen, og sjekke datoen på når filene sist ble modifisert (opprettet). Slik har jeg gjort det:

// How long we are keeping each file, since its creation date
// (in seconds)
define ('MAX_FILE_AGE', (60 * 60 * 24 * 7)); // 7 days

$data = glob (__DIR__ . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . '*.zip');

foreach ($data as $file)
{
	if (time() - filectime ($file) > MAX_FILE_AGE)
	{
		unlink ($file);
	}
}

Database med Norges postnummer, poststeder, fylker og kommuner (med koordinater)

| 22 kommentarer »

Norway_counties.svg

Her kommer det er oversikt over absolutt alle postnummer i Norge med tilhørende fylke, kommune og poststed. Hvert postnummer har også en lengde- og breddegrad tilknyttet seg. På denne måten kan du koble opp postnummeret til f.eks Google Maps.

Databasesettet er generert med hjelp av Postnummer-dugnaden Yr.no arrangerte sommeren 2009.

Ved hjelp av lengde- og breddegradene kan du jo også regne deg frem til avstanden mellom to steder, eller finne nærmeste postkontor til en bruker.

For å få lett oversikt over alle postkoder, kjører du følgende spørring:

SELECT
 postnummer, fylkeNavn, kommuneNavn, poststedNavn, kategoriNavn, lat, lon
FROM `postnumre`
INNER JOIN poststed
USING(poststedID)
INNER JOIN kommuner
USING(kommuneID)
INNER JOIN fylker
USING(fylkeID)
INNER JOIN kategorier
USING(kategoriID)
ORDER BY
 postnummer ASC, fylkeNavn ASC, kommuneNavn ASC, poststedNavn ASC

Med enhver sak kan det forekomme feil, så om dere kommer over noe som skulle vise seg til å være en bug: si i fra.

Oppdateringer

Versjon 1.4
- Har innført alle endringer gjort av posten pr. 1. februar 2012
- Det er nye navn på tabeller og kolonner (norsk)
- Koordinater er synkronisert med listene til Erik Bolstad

Versjon 1.3
- Tabellene er gjort om til InnoDb med nødvendige indekser og fremmednøkler
- Jan Mayen og Svalbard er nå plassert inn i to fylker (med samme navn), i henhold til ISO 3166-2:NO. På grunn av at områdene ikke har noe de facto fylke, måtte det gjøres slik.
- Enkelte justeringer på koordinater
- Kommunesentre for hver kommune er lagt inn

Versjon 1.2
- Jan Mayen og Svalbard har klart å falle ut fra oversikten. Det er pga. områdene ikke er del av noen fylker, og det har dermed blitt opprettet et «Svalbard og Jan Mayen»-fylke.

Last ned (versjon 1.4)

Last ned Norske postnummer (4609 nedlastninger) , lisensiert under Creative Commons.