vi er her !!!

02120

DifferentielGPS
home

MySQL - Server

Følgende problemer skal løses:

  • oprette forbindelse til databaseserveren
  • checke om databasen er til stede
  • oprette tabellerne hvis disse ikke er der
  • oprydning i tabellerne hvor der slettes forældede data
  • skrivning af data til tabellerne

Den minimale forudsætning er at der er oprettet en brugerkonto på databaseserveren. For en diskussion af disse forhold se noterne. Der er valgt en løsning, hvor programmet selv kan oprette både databasen og de nødvendige tabeller.

oprette forbindelse til databaseserveren

Fra hovedprogrammet fås oplysniger om IP-nummer, brugernavn og password. På basis af disse søges der oprettet en forbindelse til denne server. Fejler dette, gives kontrollen tilbage til den kaldende rutine.

checke om databasen er til stede

MySQL er så smart, at man bare kan forsøge at oprette en database. Hvis den allerede eksisterer, sker der intet, men hvis den ikke er der, så oprettes den.

oprette tabellerne hvis disse ikke er der

MySQL er så smart, at man bare kan forsøge at oprette en tabel. Hvis den allerede eksisterer, sker der intet, men hvis den ikke er der, så oprettes den.

oprydning i tabellerne hvor der slettes forældede data

Ved oprettelsen af forbindelsen til databasen slettes alle data i denne ældre end 7 dage. Desuden oprettes der et 'ur', der holder øje med hvornår der sidst er ryddet op. En gang i døgnet foretages der derefter en ny oprydning. Den samlede datamængdce der skal være plads til i databasen er derfor ikke 7 dage men 8 dage. Denne tidsramme er fast indkodet. Ved en senere opdatering af programmet kunne det overvejes at gøre denne grænse valgbar. Et andet problem, der muligvis på et tidspunkt skal håndteres, er, at hvis der er mange servere, der hver for sig gerne vil rydde op, så kan databaseserveren blive heftigt belastet af dette. Det kan derfor overvejes at flytte denne funktion til et cron-job på selve databaseserveren og helt ud af serverne til dataopsamling. Dette bør især overvejes hvis man vil gøre den registrede periode valgbar. Det er noget upraktisk at en server f.eks har 5 dage som periode medens en anden har sat 10 dage.

skrivning af data til tabellerne

Metoden modtager et object med en observation/datalinje. Dette object splittes i sine individuelle bidder og indsættes i en SQL-kommando. Hvis forbindelsen til databaseserveren er forsvundet, forsøges denne genoprettet og observationen smides væk. Vi har vurderet at det var den nemmeste og bedste løsning bare at droppe en observation fremfor at forsøge at sende den igen. Ved et længerevarende nedbrud i forbindelsen, kan data nemlig virkelig hobe sig op, således at der bliver introduceret en hel række problemer mht hvordan en sådan situation skal håndteres.

databasen

Constructoren for et datapunkt ser ud sådan her:

    /** creates a satellite with all the data preset*/
    public Satellite(int scaleFactor, int udre, int satelliteId, int iod, 
                    double pseudorangeC, double rangeRateC, Date timestamp,
                    double modifiedZCount, int stationID, int sequenceNo, 
                    String device)
    {
        this.scaleFactor = scaleFactor;
        this.udre = udre;
        this.satelliteId = satelliteId;
        this.iod = iod;
        this.pseudorangeC = pseudorangeC;
        this.rangeRateC = rangeRateC;
        this.timestamp = timestamp;
        this.modifiedZCount = modifiedZCount;
        this.sequenceNo = sequenceNo;
        this.stationID = stationID;
        this.device = device;
    }

Dette er så de rå data som databasen skal håndtere. Vi har valgt at registrere samtlige modtagne data og ikke vurdere hvilke data der evt er overflødige. Ifølge corrolarerne til Murphys lov [i0102], er det helt sikkert, at hvis vi udelukker nogen som helst data, så vil der straks dukke nogen op med en ide til et modul, der kræver registrering af netop de udeladte data.

Data bliver registreret i en relations-database, så det er relevant at finde ud af på hvilken normalform disse data befinder sig. (En Google-søgning som [i1102] giver allerde på første side en mængde relevante referencer). Se [i1101] for en hurtig introduktion til at bringe en relationsdatabase på normalform. En analyse viser, at de rå data allerede er på 3NF og ikke kan dekomponeres til flere tabeller. Det kunne evt overvejes at trække satelliteId og device ud i separate tabeller for at lette søgningen i tabellerne. En analyser af databasen viser nemlig at tabellen ret hurtigt kan bliver særdeles stor. Der registreres i snit 12,5 datapunkter hvert sekund pr kilde. Over 7 dage bliver dette til 12,5x60x60x24x7 = 7.560.000 registreringer pr kilde. Og vi har mindst to kilder, så vi er godt på den anden side af 15 millioner linjer i databasen når den er fuldt udbygget. En nærmere overvejelse viser, at at trække de to nævnte felter ud sandsynligvis vil give anledning til mere besvær end godt er. Hvis man f.eks vil holde rede på hvilke satelitter der har en registrering i tabellen, er man nødt til i den separate tabel også at vedligeholde en tæller, som holder rede på, hvor mange registreringer der er for en satelit i hovedtabellen. Dette vil så bringe databasen ud af trit med nomalformerne, idet informationen i tælleren er overflødig, idet denne information kan udtrækkes af hovedtabellen.

tabellen

Ud over de datafelter man har fra modtagerne, oprettes der ydeligere to felter med tidsstempler, der udelukkende bruges til 'bogholderi' samt en række indekser i tabellen. De indekserede felter er:

  • oprettet
    Dette felt bruges ved oprydning og fjernelse af gamle data
  • satelliteId
    Dette samt de to næste felter bruges ved søgninger i databasen. Det fandtes derfor praktisk at indeksere disse
  • device
  • tidsstempel

Der er i de ovenstående indekser kun taget hensyn til den type forespørgsler, som udtræk af data til import i et spreadsheet kan give anledning til. Ved implementering af yderligere moduler kan yderligere indeksering vise sig at være en fordel. På den anden side, kan en yderligere analyse af hvordan forspørgslerne rent faktisk bliver udført af MySQL føre til at man vælger at nedlægge et eller flere indeks. Man skal nemlig være opmærksom på, at indeksering giver et vist overhead, der kan ende op med at være for kostbart i forhold tid og/eller harddisk kapacitet. Den endelige enlige tabel i databasen har derfor denne struktur:

CREATE TABLE `data` (
          `opdateret` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
          `oprettet` timestamp NOT NULL default '0000-00-00 00:00:00',
          `scaleFactor` int(11) default NULL,
          `udre` int(11) default NULL,
          `satelliteId` int(11) default NULL,
          `iod` int(11) default NULL,
          `pseudorangeC` double default NULL,
          `rangeRateC` double default NULL,
          `tidsstempel` bigint(20) default NULL,
          `modifiedZCount` double default NULL,
          `stationID` int(11) default NULL,
          `sequenceNo` int(11) default NULL,
          `device` char(32) default NULL,
          KEY `oprettet` (`oprettet`),
          KEY `satelliteId` (`satelliteId`),
          KEY `tidsstempel` (`tidsstempel`),
          KEY `device` (`device`)
          ) ENGINE=MyISAM DEFAULT CHARSET=latin1

Problemer og forbedringer

Vi har haft følgende korrespondance med slutbruger angående fejlhåndtering og implementering af disse:


Hej Bjarne og Anders.

Jeg følger løbende med på jeres hjemmeside og glædes ved at se resultatet af jeres arbejde. Selv om I tilsyneladende har haft mange problemer undervejs synes jeg ikke, at jeres resultater bærer præg af det. Det ligner et solidt projekt - I ender op med - og som jeg tror vil opnå stor udbredelse WW, da det er lidt spinkelt med software på dette punkt. Flot - Flot.

Se nedenfor for konkrete svar til jeres scenarier:

Med venlig hilsen

Henrik Vad

-----Oprindelig meddelelse-----
Fra: Bjarne Mathiesen [mailto:s022518@student.dtu.dk]
Sendt: 25. april 2005 04:42
Til: Henrik Vad Jensen
Cc: Anders Boeck Jensen; Anna B.O. Jensen
Emne: 02120 - fejlhåndtering
Vi har jo konstrueret et programkompleks der kan gøres heftigt distribueret.
Vores problem er nu, hvordan du ønsker de mulige kommunikaitonsfejl mellem
de enkelte dele håndteret.
Lad os antage følgede situation:
-- Servere i Ålborg og Sønderborg
-- database i København
-- Klient i Kalundborg
Hvordan ønskes følgede situationer så håndteret:
1) en server mister forbindelsen til databasen
   pt. håndteres dette ved at der forsøges at skabes en ny forbindelse
   man kunne forestille sig
   a) at serveren sender en email til administrator - dette vil
      selvfølgelig ikke virke, hvis det er internet-forbindelsen, der
      er røget sig en tur.

Overordnet vil jeg sige, at da systemet er et redskab til at kvalitetsvurdere og ikke et redskab til at sikre en infrastruktur vil notifikation om servernedbrud mm. være tilstrækkelig via e-mail - også selvom det er internetforbindelsen, der er faldet ud. Principielt kan jeg dog godt lide, at man bliver informeret om en status. Ved et højere ambitionsniveau kunne det overvejes, om der skulle udsendes en SMS til burgere og administrator om problemer.

2) en server går ned
   pt håndteres dette ikke
   man kunne forestille sig i hvert fald følgende muligheder:
   a) databasen rapporterer at der ikke længere indrapporteres fra en
      server - vil kræve et cron-job på database serveren
   b) en klient er sat op til jævnligt at tjekke i databasen om der
      indrapporteres fra alle servere
   c) en klient poller jævnligt serverne for at se om de er levende
   d) serverne sender jævnligt en status email
   ovenstående muligheder udelukker ikke hinanden
   b) & c) kræver muligvis en klient der kører denne service 24/7/365

Umiddelbart synes a) - at databasen rapporterer om evt. problemer med fremskaffelse af data fra en eller flere servere. Jeg vil anbefale, at alle former for abnormiteter rapporteres i en log-tabel som senere kan trækkes af klienten. Log'en kunne være en naturlig del af data forespørgslen for en given periode, hvor de til datahørende logs vedhæftes data evt. blot i en txt-fil.

3) databasen går ned
   pt håndteres dette ikke eksplicit
   i)  klienten brokker sig hvis der ikke kan skabes forbindelse til
       databasen, når man starter en forspørgsel. men hvis det sker
       under en forespørgsel kommer der kun fejlmeddelelse i konsollen
   ii) serveren forsøger bare at skabe en ny forbindelse
   man kunne forestille sig
   a) at serveren sender en email til administrator
   b) klienten brokker sig på en anden måde end nu, f.eks ved et pop-up

Jeg finder det fornuftigt, at både a) serveren sender en e-mail til administratoren og b) at klienten brokker sig på en anden måde end nu - vil være at foretrække.

4) klienten mister forbindelsen til databasen
   pt håndteres dette ikke eksplicit.
   se 3i) og 3a)

Jeg er ikke helt sikker på, at jeg forstår problemet eller løsningsmulighederne rigtigt her, men en informations pop-up vil vel være en umiddelbart fornuftig handling her - evt. med anbefalinger om, hvad man evt. kan foretage sig for at genskabe forbindelsen til databasen.

Problemet med 3i) 1. punktum er, at dette også kan skyldes en fejl 40 (betjeningsfejl
- forkert indtastede data ang forbindelsen)
Sandsynligvis kan vi ikke nå at indføre de features du skulle ønske til at
håndtere ovenstående situationer i version 1.0 af programmet (det vi har nu og
afleverer), men vi vil alligevel gerne vide hvordan du ønsker dette håndteret af
hensyn til vores rapport og en evt version 1.1

home