Alt om ingenting og litt i mellom En blogg av Knut-Olav

MySQL på nye fremmednøkkeleventyr

13. oktober 2009 · Comments Off

Ikke så lenge siden skrev jeg om MySQL sine problemer med datatyper og NULL-konstraints. Og problemene stopper ikke der.

Jeg kom i dag over en merkelig og helt uforståelig bug i MySQL. Eller, det heter vel kanskje feature når det gjelder MySQL.

Ta følgende scenario: En kolonne “disabled_reason_ref” i tabellen “countries” refererer til feltet “uuid” i tabellen “texts”. Kolonnen “disabled_reason_ref” er definert med mindre størrelse enn feltet den refererer til. Dette visste jeg ikke om. Begge tabellene bruker InnoDB og det er satt opp fremmednøkler. Hvordan dette gir noe som helst mening i MySQL-verden vet jeg ikke.

Ihvertfall. Det hele startet med denne SQL INSERT-spørringen.


mysql> INSERT INTO countries (uuid, country_code, disabled, disabled_reason_ref, page_ref) VALUES ("a63d5a26-9719-47dd-9617-c07bd8126061", "NO", 1, "e80c8d7c-dd84-4a4f-8df4-778efe9b311a", NULL);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`utenlandsbolig/countries`, CONSTRAINT `countries_ibfk_2` FOREIGN KEY (`disabled_reason_ref`) REFERENCES `texts` (`uuid`))

Det er ingenting i feilmeldingen fra denne spørringen som sier noe om det.

Jeg lurte litt på om kolonnenavnet var for langt, så jeg lagde en ny kolonne som heter “reason_ref”.


mysql> alter table countries add column  reason_ref VARCHAR(32)  REFERENCES texts(uuid);
Query OK, 1 row affected (0.52 sec)
Records: 1  Duplicates: 0  Warnings: 0

MySQL satte riktignok ikke opp noen fremmednøkkel her, noe jeg sjekket med “SHOW CREATE TABLE countries”.
Lurer da fælt på hva den i så fall referer til…
Vel, MySQL er MySQL.

Jeg tenkte så at jeg ikke trengte “disabled_reason_ref” lenger.


mysql> alter table countries drop column disabled_reason_ref;
ERROR 1025 (HY000): Error on rename of './utenlandsbolig/#sql-4fa3_6' to './utenlandsbolig/countries' (errno: 150)

Hva i alle dager betyr dette?
Jeg kom meg ikke rundt feilen, så jeg lot kolonnen bare ligge.

Jeg hadde på dette tidspunktet ikke oppdaget at “reason_ref” var for liten. Kolonnen den refererer til er nemlig av type VARCHAR(36).

Et nytt forsøk på INSERT, nå ved å bruke den nye kolonnen.


mysql> INSERT INTO countries (uuid, country_code, disabled, reason_ref, page_ref) VALUES ("a63d5a26-9719-47dd-9617-c07bd8126061", "NO", 1, "e80c8d7c-dd84-4a4f-8df4-778efe9b311a", NULL);
Query OK, 1 row affected, 1 warning (0.19 sec)

mysql> show warnings;
+---------+------+-------------------------------------------------+
| Level   | Code | Message                                         |
+---------+------+-------------------------------------------------+
| Warning | 1265 | Data truncated for column 'reason_ref' at row 1 |
+---------+------+-------------------------------------------------+
1 row in set (0.00 sec)

Og det viste seg at kolonnen var for liten. Dermed fant den ingen rad i “texts”-tabellen som hadde den refererte verdien på 32 tegn, da verdien egentlig skulle vært på 36 tegn.


mysql> alter table countries modify column disabled_reason_ref varchar(36);
Query OK, 2 rows affected (0.40 sec)
Records: 2  Duplicates: 0  Warnings: 0

Greit at det var jeg som gjorde feilen med å deklarere kolonnen for liten.
Men hallooo, litt hjelp kan man vel få fra en database? Spesielt fra en relasjonsdatabase!

Dumme MySQL!

MySQL – mangel på integritet

3. oktober 2009 · Én kommentar

MySQL gjør mye rart. Her har vi en ganske normal tabell, med kolonner som krever en verdi og med kolonner av forskjellige datatyper. Fire av kolonnene i tabellen kan ta default verdier, resten kan det ikke.


mysql> DESC user_status;
+-------------------+--------------+------+-----+---------+-------+
| Field             | Type         | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| uid               | int(10)      | NO   | PRI | NULL    |       |
| verified          | tinyint(1)   | NO   |     | 0       |       |
| registered_nick   | tinyint(1)   | NO   |     | 0       |       |
| first_time        | tinyint(1)   | NO   |     | 1       |       |
| registration_date | datetime     | NO   |     | NULL    |       |
| verification_code | int(10)      | NO   |     | NULL    |       |
| nick              | varchar(32)  | NO   |     | NULL    |       |
| active            | tinyint(1)   | NO   |     | 1       |       |
| ban_reason        | varchar(255) | NO   |     | NULL    |       |
| logincount        | int(11)      | NO   |     | NULL    |       |
| lastlogin         | datetime     | NO   |     | NULL    |       |
+-------------------+--------------+------+-----+---------+-------+

Så legger vi inn en rad i tabellen. Legg merke til at vi bare legger inn data i noen av kolonnene.


INSERT INTO user_status(
  uid, verified, registration_date,
  verification_code, nick)
VALUES(1, 1, NOW(), "asd", "ut");

Så får jeg en suksessmelding tilbake fra MySQL, jippi. Eller vent, det står noe om at det er generert tre advarsler. Ok tenker jeg, så jeg får vel finne ut hva disse advarslene er.


mysql> SHOW WARNINGS;
+---------+------+------------------------------------------------------------------------+
| Level   | Code | Message                                                                |
+---------+------+------------------------------------------------------------------------+
| Warning | 1364 | Field 'ban_reason' doesn't have a default value                        |
| Warning | 1364 | Field 'logincount' doesn't have a default value                        |
| Warning | 1364 | Field 'lastlogin' doesn't have a default value                         |
| Warning | 1366 | Incorrect integer value: 'asd' for column 'verification_code' at row 1 |
+---------+------+------------------------------------------------------------------------+

Det at MySQL gir blaffen i påkrevde kolonner visste jeg egentlig, og jeg blir sinna hver gang jeg tenker på det. Så egentlig var de første advarslene godt kjente for meg.

Det som virkelig overrasket meg var,

Hva?! Tillater MySQL meg å opprette en rad i en tabell med noe data i en kollonne med en annen datatype?

MySQL tillater meg faktisk å sende inn tekststrengen “asd” inn kolonnen “verification_code” som er deklarert som et heltall. Hva i alle dager? Hvilken verdi har MySQL satt inn i tabellen min da? Dette må undersøkes.


mysql> SELECT * FROM user_status;
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+
| uid | verified | registered_nick | first_time | registration_date   | verification_code | nick | active | ban_reason | logincount | lastlogin           |
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+
|   1 |        1 |               0 |          1 | 2009-09-29 17:08:57 |                 0 | ut   |      1 |            |          0 | 0000-00-00 00:00:00 |
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+

Den satte inn tallet “0″ i verification_code-kolonnen. Hvordan MySQL fant ut at det var en smart idé vet jeg ikke. Kolonnen er av type heltall, den krever en verdi og er deklarert uten noen default verdi. Jeg sender inn tekststrengen “asd”.

I et scriptspråk som PHP eller Perl evalueres denne strengen til en bolsk sann verdi. Så kanskje kunne heltallsrepresentasjonen av strengen vært “1″. Derimot er det ikke sikkert at kolonnen representerer en bolsk verdi, for da ville jeg vel brukt en datatype som bit eller bool, ikke sant? Det eneste fornuftige å gjøre er faktisk å ikke tillate verdien og forhindre meg i å opprette raden.

Det jeg stusser litt på, og blir lei meg over, er den manglende forståelsen av integritet i MySQL. Hvis jeg forsøker å opprette en rad i en tabell uten å sende inn alle påkrevde felt, så burde jeg ikke få lov til å opprette raden. Så enkelt kan det gjøres.

MySQL må ikke tro at den er smartere enn meg.

Could not dupe: Bad file descriptor

8. september 2009 · 2 Kommentarer

Ok, so I have been debugging a Perl application that I wrote about six months ago. Basically it creates some meta data and copies files to other user accounts using SSH.

For file transfer it uses File::RsyncP and for remote control it uses Net::SSH::Perl. Some times I get the error message Could not dupe: Bad file descriptor. Not a very informative error message, but I had an idea that it might have something to do with the file transfer. After I restart the application, running as a FastCGI web application, everything works, for a short while, then it breaks again.

I found out that it stops working right after I end my SSH connection, after debugging and restarting the application. After some research I found out it had something to do with the loss of STDIN. My best guess is that SSH needs STDIN to be able to read the password entered by the user, but I use keys for authentication, so I won’t need STDIN at all for interacting with SSH.

I tried different tactics to keep STDIN open. Running it using nohup did not help. Then I tried starting up the web application using screen, and now it still runs several hours after logging out from the server.

I don’t like this workaround very much. So if anyone has a better solution to this problem, I would love to hear about it.

A possible solution might be to redirect STDIN to a temporary file. Anyone had success doing this with Net::SSH::Perl or File::RsyncP?

How to not tell about a security breach?

7. september 2009 · Én kommentar

WordPress is breached, again. I guess I run an unsecure version of WordPress, but I’m not sure. All I am told is that i don’t runt he latest version of WordPress and that I should upgrade, because upgrading is easy.

No, it’s not easy. I keep history of my webpage in Subversion, so every time I need to upgrade WordPress I need to add the new version into Subversion in the vendor branch, merge in the changes in a WordPress current branch and then merge the changes into trunk of my web page. Why I do this, you say? No software is perfect, WordPress is far from it, so I need to alter some core code from time to time. That’s why.

Ok, back to the topic. Matt Mullenweg does not tell me in his blog post (link above) anything about what versions of WordPress that are potential targets for this Internet worm that exploits this security breach, nor what part of the code that makes it possible, not even how to patch it up. The entire blog post is just explaining that security holes do happen and some theory about how to protect yourself from it. Nothing concrete. Not very useful.

Føler meg nummenummen i munnen

27. august 2009 · Comments Off

Jeg føler meg nummenummen i munnen. Var hos tannlegen i dag, og han røska ut to visdomstenner. Måtte ha en ekstra sprøyte på den ene siden. Artig.

Det viste seg faktisk at jeg hadde fem av dem… faktisk. Jeg har to visdomstenner tett-i-tett i overkjeven. Nå har jeg to færre da, ble tre igjen. De to nede er borte vekk.

Så nå føler jeg meg litt dummere her jeg sitter med to visdomstenner mindre – med blodig kjeft, tørre lepper, numme kinn, numm tunge og biter på litt bomul.

Funky med ømme kinn. Merkelig å ta på dem. Gleder meg om en time eller to, når bedøvelsen avtar…

Noen minner fra Notodden Bluesfestival

10. august 2009 · Comments Off

Jeg var på Notodden Bluesfestival lørdag 1. august i år. Vi var på bygga og hørte på Beth Hart. Dessverre gikk jeg glipp av Buddy Guy, og jeg angrer ennå på at jeg gikk for å spise akkurat da. Men gjort er gjort og spist er spist, ironisk nok.

Jeg tok ikke så mange bilder, men et par ble bra. Det første bildet er av Beth Hart, en noe merkelig dame, men flink som bare det. Det andre bildet er av et ungdomsband fra musikkskolen som stod i hovedgata og spilte. Det var flere ungdomsband der, men disse stoppet jeg og hørte litt på. God musikk spilte de.

Enda en tur til steinbruddet

6. august 2009 · Comments Off

Helt utrolig, men jeg tok med bikkja på nok en tur opp til steinbruddet i dag også. Endelig har feriefølelsen kommet til meg.

Tok noen bilder i dag og, et par av en åpning i skogen, og så klart noen av bikkja mi Rex. De to siste bildene er tatt etter vi kom tilbake til hytta. Jeg tror Rex ble enda mer sliten enn meg.

På tur til steinbruddet

6. august 2009 · Comments Off

I dag, onsdag, skinte endelig sola. Det er ferie, og jeg tok på meg shorts, joggesko, tok bikkja i bånd og la på vei. Vi gikk en liten tur, opp i skogen og opp til toppen av steinbruddet som ligger ved Bekkestranda i Sande.

Jeg tok noen bilder da jeg var på toppen. Her er det god utsikt over Sandebukta. Ganske flott natur, selv etter at næringsvirksomheten har gjort sitt med med naturen, med å grave ut fjellet. Det er kanskje derfor det er så pent der oppe. Tok også et bilde av Rex, bikkja mi, etter vi var kommet tilbake til hytta.

Jeg vil ha fiber i Drammen, men får ikke

29. juli 2009 · Comments Off

Jeg har nå gått lei av den ustabile ADSL2-linja fra Ventelo. Hittil i år har jeg mista Internett fire ganger, slik at jeg har vært uten Internett i omtrent en ukes tid hver gang. Slikt går ikke når man av og til skal ha hjemmekontor og er avhengig av å være koblet på nett.

Jeg bestemte jeg så for å ringe EB for å høre om jeg kunne få fiberbredbånd, og siden jeg bor sentralt i Drammen så regnet jeg med at det skulle gå bra, men nei da. Selv om blokken jeg bor i ligger 5 meter fra jernbanen så går det ikke. Både EB og Telenor har lagt inn protest og stanset all fibergraving i Drammen, etter idiotilovgiving fra Drammen bystyre. Kravet fra Drammen kommune går i at utbyggerne må utføre en mye bedre jobb enn de har gjort tidligere med å reparere veiene de graver opp, ved blant annet å legge ny asfalt over hele veien som graves opp. Dette høres fornuftig ut, men dette påfører utbyggerne en vesentlig høyere kostnad som de ikke ønsker å ta på seg. Dette medfører at utbyggerne heller prioriterer å bygge ut andre steder, som i Nedre Eiker og Lier.

Bredbåndsselskapene som benytter det “gamle” kobbernettet sliter med å levere bredbånd. Jeg mener så klart gammelt som i gammel teknologi. Da jeg først skulle ha Internett i leiligheten min for ca tre år siden hadde ikke Nextgentel flere ledige punkter i sentralen, og det tok dem fire uker på å finne ut det før de kunne gi meg svar. Ventelo, som jeg bruker nå, sliter med ustabilitet på nettet. De problemene jeg har hatt hittil i år har vært av ukjent årsak. Jeg har mottatt to nye ADSL2-modemer fra dem, selv om jeg har forsøkt å forklare gjentatte ganger at feilen ikke ligger i modemet. Av andre problemer jeg har med Ventelo så er det at jeg ikke kan få raskere opplastingshastighet. Jeg har 1 Mbit/s i opplasting. Nedlasting makser jeg på 16 Mbit/s. Jeg vil også ha fast IP-adresse. Dette har ikke Ventelo infrastruktur til å håndtere for privatkunder.

Jeg mener at Drammen kommune bør ta noe av kostnaden til utbygging av fiber, spesielt når det gjelder graving. Det er fiber som er fremtiden. Fiber kan overføre høye hastigheter med data, opptil 10 Gbit/s. Dette er fremtidsrettet. Dette gjør at man kan levere andre tjenester enn Internettilknytning over disse linjene, som TV og telefoni. Jeg ønsker meg i første omgang 30 Mbit/s, både opp og ned, og fiber gir store muligheter for oppgradering senere. Dette vil jeg ha.