Online (hot) backup u MySQL 6.0

Sunday, 25.05.2008 – Dejan

Za verziju 6.0, MySQL je najavio mogućnost “online backupa” baze (hot, non-blocking backup MySQL baze), što će obradovati mnoge MySQL administratore (a i nespretne developere 😉 ). Prema najavi, ova opcija ipak ne osigurava kompletnu bazu i sve njene pripadajuće elemente.

U backup su uključene sve perzistentne tabele kreirane sa jednim od ovih engine-a: myisam, memory, archive, innodb i falcon. Pored tih tabela, u backup su uključeni i “pogledi” (views), uskladištene procedure, funkcije (izuzev User Defined Functions), okidači (triggers) i “događaji” (events).

Lista elemenata, koji nisu uključeni u backup je poduga, pa da ne koristim copy/paste, pročitajte više o tome u originalnoj najavi (MySQL 6.0 : Online backup – What is not backed up).

MySQL najavljuje da mysqldump neće biti zapostavljen, nego da će se i dalje razvijati, te će služiti prvenstveno za klasični export/import podataka.

Kako napraviti backup baze?
Prema njihovom planu, ovako bi izgledao efektivni backup MySQL baze:
1. mysqld server uvijek pokretati sa opcijom -log-bin da bi sve izmjene bile sačuvane
2. periodično napraviti backup pomoću komande BACKUP DATABASE
3. provjeriti da li je backup uspješan
4. ako jeste, sačuvati kopiju od “backup image-file-a” na nekoj sigurnoj lokaciji

Naravno, povremeno treba testirati da li RESTORE radi kako treba.

Ukoliko vas zanima još više detalja u vezi online backup-a u MySQL bazi, pročitajte originalni tekst, a ja ću za kraj samo navesti njihovu napomenu: “Online Backup is not a completed feature. This document has only said what is actually here today. By the time that the feature is “beta” …


“Igrom” do znanja!

Friday, 23.05.2008 – Dejan

Smatrate li se stručnjakom u svom poslu?
Da li ste uvijek u koraku sa novim tehnologijama?
Da li aktivno radite na obnavljanju, usavršavanju i unapređivanju svojih vještina?
Da li ste ikad doživjeli da vas mlađi kolega nadmaši u radnim zadacima, odnosno da neke stvari zna i radi bolje od vas, jer ste zahrđali?

Da ne biste došli u neugodnu situaciju u kojoj bi vaš status stručnjaka bio doveden u pitanje, morate voditi brigu o aktivnom usavršavanju svog znanja. Pošto je IT veoma dinamična branša u kojoj nije lako savladati nešto i potom godinama živjeti od stečenog znanja, usavršavanje i dopunjavanje tog znanja uz svakodnevno sticanje praktičnog iskustva nije nimalo lak zadatak.

Kolega i ja smo našli odlično rješenje – “igramo” se postavljanja zadataka po principu “ti meni – ja tebi“. Imamo nekoliko testnih sistema sa Oracle bazama, pa kad imamo vremena, postavimo jedan drugome određeni zadatak/problem. Ko ne riješi postavljeni zadatak, plaća ručak.

Tako sam ja njemu za početak postavio jedan škakljivi problem – dodao sam TNS_ADMIN varijablu i putanju postavio na C:\TEMP, nakon čega nije bilo moguće spojiti se na bazu, jer nijedan clientski program nije mogao da pronađe SQL*Net datoteke (sqlnet.ora i tnsnames.ora). Greška, koja se dobija prilikom spajanja na bazu, ne ukazuje direktno na pravi problem, pa je nakon par sati izgubljenog vremena i živaca skrušeno rekao – “Šta ćeš za ručak?“. Ne moram vam opisivati njegovu reakciju kad sam mu otkrio u čemu je bio problem. Ni na kraj pameti mu nije palo da bi to moglo biti u pitanju…

Ali već idući dan mi se osvetio. Postavio mi je jedan za’eban problem – napunio je kompletan prostor u Flash Recovery Area (FRA), pa potom ručno obrisao sve archive logove, nakon čega je baza javljala grešku kako u FRA nema slobodnog prostora iako ga je u stvarnosti bilo. Odustao sam nakon sat vremena, jer sam smatrao da je to maksimalno dopušteno vrijeme za pronalazak rješenja i uklanjanje greške. A rješenje je bilo banalno, kojeg sam se ustvari trebao sjetiti, jer sam imao sličan problem prošle godine – trebalo se spojiti RMAN-om na bazu i odraditi CROSSCHECK ARCHIVELOG ALL, pa onda DELETE NOPROMPT EXPIRED ARCHIVELOG ALL.

I tako se mi “igramo”, a usput obnavljamo znanje i stičemo nova praktična iskustva. Planiram mu iduće sedmice postaviti jedan zadatak u vezi PL/SQL programiranja, jer je tu tanak. 🙂

Dajte i vi neke prijedloge, kakve zadatke da mu postavim – što teže, to bolje.


Prava pristupa podacima – prvi deo

Saturday, 17.05.2008 – Srdjan

SQL baze podataka nam omogućavaju izvestan nivo kontrole pristupa podacima. Ova kontrola se postiže upotrebom GRANT komande i njenih varijacija GRANT SELECT, GRANT INSERT, GRANT UPDATE, GRANT DELETE. Da bi se primenila ovakva pravila pristupa bitno je da svaki korisnik sistema ima svoje jedinstveni nalog na nivou baze podataka. Mnogi proizvođači baza podataka dopunjuju standardnu ponudu sa dodatnim pravima pristupa kao što su column-level security i row-level security.

PostgreSQL nema mogućnost definisanja column i row level pristupa podacima. Da li postoji mogućnost da se ove tehnologije simuliraju ako su nam potrebne? Postoji, ali nažalost zahteva dodatni trud.

Kako napraviti prava pristupa podacima u okviru PostgreSQL-a? Pokazaću kroz jedan mali primer.

Predpostavimo da u okviru informacionog sistema imamo i podsistem za kadrovsku evidenciju i obračun zarada. Predpostavimo da imamo tri korisnika sistema:
– Pera šef službe prodaje
– Mika radnik u službi prodaje
– Laza šef službe nabavke
Dakle, po organizacionoj šemi Pera i Laza su na istom hijerarhijskom nivou dok je Mika podređen Peri.

Kreiramo tri korisnika sistema:

CREATE ROLE pera LOGIN;
CREATE ROLE mika LOGIN;
CREATE ROLE laza LOGIN;

U delu podsistema za kadrovsko i plate imamo jednu tabelu:

CREATE TABLE radnici (
ime VARCHAR(10) NOT NULL PRIMARY KEY,
datum_rodjenja DATE NOT NULL,
-- sluzba u okviru firme kojoj radnik organizaciono pripada
-- sluzbe su kodirane po semi: N = nabavka, P = prodaja
sluzba CHAR(1) NOT NULL CHECK (sluzba IN ('N', 'P')),
plata NUMERIC(10,2) NOT NULL DEFAULT 0 CHECK (plata > 0.00)
);

Ovu tabelu ćemo popuniti test podacima

INSERT INTO radnici (ime, datum_rodjenja, sluzba, plata)
VALUES ('pera', '1969-04-04', 'P', 50000);
INSERT INTO radnici (ime, datum_rodjenja, sluzba, plata)
VALUES ('mika', '1977-02-09', 'P', 35000);
INSERT INTO radnici (ime, datum_rodjenja, sluzba, plata)
VALUES ('laza', '1979-12-07', 'N', 48000);

Pera i Laza kao šefovi imaju sva prava pristupa nad podacima, dok Mika moze samo da čita podatke.

GRANT SELECT, INSERT, UPDATE, DELETE ON radnici TO pera;
GRANT SELECT                         ON radnici TO mika;
GRANT SELECT, INSERT, UPDATE, DELETE ON radnici TO laza;

Na ovaj način smo sprečili Miku da unosi nove radnike u tabelu ili da menja postojeće podatke (da poveća sebi platu 🙂 ).

Ovim smo ujedno i završili sa pravima pristupa koji nam se nude nad tabelama. Ali, šta ako nam ovakva prava pristupa nisu dovoljna? Kako dalje poboljšati bezbednost podataka?

Column-level security ili vertikalna prava pristupa

Javlja nam se nov zahtev pred naš sistem – Platu smeju da vide samo šefovi!

Klasičan pristup rešavanju ovog problema je da se početna tabela razdvoji na dve tabele koje su u relaciji 1:1 i nad kojima se posebno daju prava pristupa. Pa ajde da to i uradimo.

Prvo, kreiramo novu tabelu u kojoj će se čuvati podaci o platama.

CREATE TABLE plate (
ime VARCHAR(10) NOT NULL PRIMARY KEY REFERENCES radnici,
plata NUMERIC(10,2) NOT NULL DEFAULT 0 CHECK (plata > 0.00)
);

Drugo, prepisujemo podatke o platama iz tabele Radnici u tabelu Plate.

INSERT INTO plate (ime, plata)
SELECT ime, plata
FROM radnici;

Trece, brišemo kolonu plata iz tabele Radnici.

ALTER TABLE radnici DROP COLUMN plata;

Četvrto, dodeljujemo prava pristupa nad tabelom Plate šefovima.

GRANT SELECT, INSERT, UPDATE, DELETE ON plate TO pera;
GRANT SELECT, INSERT, UPDATE, DELETE ON plate TO laza;

Ovim smo potpuno sprečili Miku da vidi podatke o plate.

Dodatno da bismo olakšali posao čitanja podataka kreiraćemo jedan pogled kroz koji ćemo objediniti podatke iz tabela Radnici i Plate.

CREATE VIEW radnici_i_plate (
ime, datum_rodjenja, sluzba, plata
) AS
SELECT r.ime, r.datum_rodjenja, r.sluzba, p.plata
FROM radnici AS r
LEFT OUTER JOIN
plate AS p
ON r.ime = p.ime;

Takođe, šefovima moramo dati pravo da koriste ovaj pogled

GRANT SELECT ON radnici_i_plate TO pera;
GRANT SELECT ON radnici_i_plate TO laza;

Sada naši šefovi sada lako mogu da pročitaju podatke o radnicima i njihovim platama pomoću upita

SELECT ime, datum_rodjenja, sluzba, plata
FROM radnici_i_plate

Promenom strukture podataka obezbedili smo nekakav column-level security, to jest sprečili smo pojedine korisnike da pristupaju kolonama sa osetljivim podacima.
Pošto smo izmenuli strukturu meni je draže da ovakva prava pristupa nazivam ‘vertikalna prava pristupa’.

Do sad smo upotrebiljavali isključivo standardan SQL i gornji primeri se mogu pokrenuti i na drugim database engine-ima, a ne samo na PostgreSQL-u.

U sledećem nastavku ćemo videti kako se u PostgreSQL-u može implementirati Oracle-ov row-level security.


Diplomski/Seminarski rad: Backup and Recovery Oracle & MySQL baze

Tuesday, 06.05.2008 – Dejan

Uvaženi kolega i student na bečkom Tehničkom univerzitetu – Đorđe “bags” Torbica – je za svoj diplomski rad odabrao temu “Backup und Recovery in Oracle 10g” pri čemu je morao navesti/usporediti i backup mogućnosti kod MySQL RDBMS-a u odnosu na Oracle XE. Ovih dana je Đorđe svoj rad uspješno odbranio i stekao Bachelor titulu.

Pošto sam ja savjetima pomagao Đorđu pri izradi tog rada, on je obećao nesebično dati taj svoj rad na uvid drugim zainteresovanim bazoljupcima, koji posjećuju blog baze-podataka.net .

Napomena: Seminarski rad je na njemačkom jeziku.

Download (PDF, 247 kB): Diplomski/Seminarski rad na temu “Backup und Recovery in Oracle 10g”


Gdje da nabavim Oracle software?

Thursday, 24.04.2008 – Dejan

Nastavljamo sa pitanjima i odgovorima – Marko Bujas, student informatike, pita gdje se može nabaviti Oracle software, a posebno mu trebaju Forms i Reports Builder.

Ja sam student informatike i trenutno imam predmet baze podataka.
Bio bih vam zahvalan ako biste mi rekli gdje mogu skinuti Oracle nije bitno koja je verzija bitno mi je samo da sadrži form i report builder. samo mi nemojte reći da skinem sa službene stranice oracla.
ako imate neki link bio bih vam jako zahvalan.

sviđaju mi se baze podataka i želim to i jednog dana raditi, ali bez potrebnog softvera to i
nije baš moguće zato molim pomagajte.

Unaprijed vam se zahvaljujem

Oracle software se može nabaviti …
Pročitaj kompletan tekst »


Alternativa za EXECUTE IMMEDIATE i DBMS_SQL u MySQL-u ?

Thursday, 17.04.2008 – Dejan

Vi pitate – mi odgovaramo!

Radovan B. iz Novog Sada je postavio pitanje:

Potreban mi je određeni mehanizam, koji bi mogao na serveru da odradi dinamičko izvršenje određene SQL komande na MYSQL bazi. Znači, ja da mogu da pozovem proceduru na serveru, koja će parsirati SQL komandu zavisno od uslova i koja će se po potrebi izvršiti… U MySQL-u mi nedostaje baš to na što sam navikao u ORACLE-u…

Da li postoji mehanizam u MYSQL bazi (na serveru) analogan komandama EXECUTE IMMEDIATE i DBMS_SQL, koji postoje u ORACLE bazi?

A odgovor je – Da! Dinamičko izvršavanje u MySQL-u postoji, a to se dobija korištenjem komandi PREPARE i EXECUTE statement. Postoje neka ograničenja za korištenje u triggerima i ne mogu se koristiti sve DDL komande, ali većina SQL izraza se ipak mogu koristiti.

Ukoliko i vi imate neko pitanje, pošaljite ga na adresu forwardNOSPAMbaze-podataka.net


Unique Indeksi i NULL vrednosti

Tuesday, 25.03.2008 – Zidar

Na sajtu elitesecurity.org povremeno se pojave mozgalice – nesvakidašnji zadaci koje treba rešiti primenom SQL jezika. Jedna od prvih mozgalica bila je “Kako obezbediti jedinstvenost ako su dozvoljene NULL vrednosti u koloni”. Drugim rečima, ako vrednost nije NULL onda mora biti jedinstvena, a višestruke NULL vrednosti su dozvoljene. U nekim sistemima rešenje je trivijalno, jer se indeksi ignorisu NULL vrednosti . MS SQL to ne dozvoljava (iako recimo Access, takodje MS proizvod, to naprimer dozvoljava).

U verzijama MS SQL zaključno sa 2005 morali smo da pribegavamo trikovima. Triggeri, inedksirani view ili korisničke funkcija su korišćeni da se problem reši. MS SQL 2008 uvodi novinu – “filtered indexing”.

U Microsoft SQL Server 2008 problem se rešava elegantno i efikasno definsanjem objekta koji se zove  “unique filtered index” koji  moze da isključi  NULL vrednosti. Neka je data tabela:

CREATE TABLE dbo.T1(col1 INT NULL, col2 VARCHAR(10) NOT NULL);

Pretpostavimo da želimo da obezbedimo jedinstvenost za podatke u koloni col1, a da dozvolimo visetruke NULL vrednosti. Dovoljno je da ovako definišete indeks:

CREATE UNIQUE NONCLUSTERED INDEX idx_col1_notnull
ON dbo.T1(col1)
WHERE col1 IS NOT NULL;

Da testiramo index, pokušajmo da unesemo sledeće:

INSERT INTO dbo.T1(col1, col2) VALUES(1, 'a');
INSERT INTO dbo.T1(col1, col2) VALUES(1, 'a');

Drugi INSERT naravno ne prolazi. Međutim,  nećete imati problema da unesete više redova sa  NULL u col1:

INSERT INTO dbo.T1(col1, col2) VALUES(NULL, 'a');
INSERT INTO dbo.T1(col1, col2) VALUES(NULL, 'a');

Negde sam pročitao i da su uvedeni i novi tipovi (podtipovi?) podataka – DateOnly i TimeOnly koji rade upravo to – čuvaj samo vreme i samo datumski deo.  Cool, eh ….

🙂 


Korišćenje UDF funkcija u CHECK uslovima – rezervacija soba

Wednesday, 05.03.2008 – Zidar

Pošto mi se mnogo dopalo korišćenje UDF funkcija u CHECK uslovima, pokušao sam da odgovorim na pitanje, koje se često sreće na forumima: rezervacija soba bez prebukiranja. Evo kako može da se reši:
Kreiramo tabelu u koju se upisuju rezervacije soba u jednom hotelu.
Tabela ima 3 kolone (Sobe, ZauzetoOD, ZauzetoDo)

– Soba ne sme da se prebukira. Drugim rečima, interval zauzeća (ZauzetoOd, ZauzetoDo) ne sme da se preklopi ni sa jednim drugim intervalom zauzeca za posmatranu sobu.
– Na dan odlaska jednog gosta iz sobe, drugi gost može ući u sobu.
– Sobe se napuštaju do 11AM, a preuzimaju u 1PM.
– Vreme između 11 i 1 se koristi za pripremu sobe za novog gosta. Znači, preklapanje na krajevima intervala se dopušta.

Pročitaj kompletan tekst »


Upotreba korisničkih funkcija u CHECK CONSTRAINTS

Wednesday, 05.03.2008 – Zidar

MS SQL  2000 doneo je jednu lepu novinu – mogućnost pisanja korisničkih funkcija. Uz to je tiho došla još jedna novina, slabo dokumentovana,  iako se može naći u Boks On Line. Korisničke funkcije mogu se pozvati iz CHECK constraints. Funkcije ko funkcije, mogu da pozivaju redove iz posmatrane tabele, ali i drugih tabela. Ovo nam omogućava da izbegnemo proceduralno programiranje (trigere) i da neka ograničenja za koje smo morali koristiti Stored Procedures ili čak front-end funkcije, sada možemo da postavimo na nivo tabele, tamo gde i treba.

Na jednostavnom primeru pokazaćemo kako to radi.

Dobrotvorna organizacija daje pomoc gradjanima. Svaki gradjanin ima svoj ‘racun’. Novac se isplacuje višekratno, u manjim iznosima. Nikome se ne sme isplatiti više od 100 dinara ukupno.

Krairana je tabela ‘Zaduzenja’ sa tri kolone – Transakcija, Racun, IznosZaduzenja.
IznosZaduzenja je ono sto se isplaćuje u jednoj transakciji. Ukupan zbir IznosZaduzenja po računu ne sme da predje 100.

Ovo su ograničenja koja želimo da postavimo:
Pretpostavljamo IznosZaduzenja mora biti pozitivan, ne mozž biti nula ili manji.
Ukupan zbir svih IznosZaduzenja po Racunu ne sme preći 100.

CREATE TABLE Zaduzenja — DROP TABLE Accounnt
(Transakcija int PRIMARY KEY
, Racun int NOT NULL
, IznosZaduzenja money NOT NULL CHECK (IznosZaduzenja > 0)
)

Ovako nasa tabela postuje  prvo ograničenje. Kako da sprečimo da se nekome isplati više od 100 dinara?

MS SQL, od verzije 2000 pa naovamo ima jednu malo poznatu osobinu – u CHECK constraints mogu se koristiti user defined functions.
Iskoristimo to. Napišimo prvo funkciju koja izračunava ukupno zaduženje po računu. Funkcija bi mogla ovako da izgleda:

CREATE FUNCTION dbo.UkupnoZaduzenje (@Racun int)
RETURNS money
AS
BEGIN
 DECLARE @Retval money
 SET @Retval = (SELECT SUM(IznosZaduzenja)
     FROM Zaduzenja WHERE Racun = @Racun
     )
 RETURN COALESCE(@Retval,0) — inace vraca NULL kad ne postoji ni jedan red u in line kveriju
END

Funkciju pozivamo ovako:
SELECT dbo.UkupnoZaduzenje(100)

Ovako pravimo CHECK constraint koji koristi nasu funkciju:


ALTER TABLE Zaduzenja
–DROP CONSTRAINT ck_UkupnoZaduzenjeManjeod100
ADD CONSTRAINT ck_UkupnoZaduzenjeManjeod100
 CHECK
  (
   100 >= dbo.UkupnoZaduzenje (Racun)
  )

Da vidimo da li radi:

INSERT INTO Zaduzenja VALUES (1,100,50)
(1 row(s) affected)


SELECT * FROM Zaduzenja
Transakcija Racun       IznosZaduzenja       
———– ———– ———————
          1         100               50.0000

(1 row(s) affected)

Dodajmo jos 25 dinara na isti racun:
INSERT INTO Zaduzenja VALUES (2,100,25)
(1 row(s) affected)

Sada imamo u tabeli Zaduzenja:
Transakcija Racun       IznosZaduzenja       
———– ———– ———————
          1         100               50.0000
          2         100               25.0000

Ukupno azduzenje za Racun=100 jeste 75.
Pokušajmo da dodamo 30 dinara, što bi podiglo ukupno zaduženje na 105.

INSERT INTO Zaduzenja VALUES (3,100,30)

Rezultat:
Server: Msg 547, Level 16, State 1, Line 1
INSERT statement conflicted with COLUMN CHECK constraint ‘ck_UkupnoZaduzenjeManjeod100’.
The conflict occurred in database ‘master’, table ‘Zaduzenja’, column ‘Racun’.
The statement has been terminated.

Još 25 moze da prodje:
INSERT INTO Zaduzenja VALUES (3,100,25)

(1 row(s) affected)

i ništa vise:

INSERT INTO Zaduzenja VALUES (4,100,0.001)

Ponovo dobijamo
Server: Msg 547, Level 16, State 1, Line 1
INSERT statement conflicted with COLUMN CHECK constraint ‘ck_UkupnoZaduzenjeManjeod100’.
The conflict occurred in database ‘Zadaci’, table ‘Zaduzenja’, column ‘Racun’.
The statement has been terminated.

SELECT * FROM Zaduzenja

Transakcija Racun       IznosZaduzenja       
———– ———– ———————
          1         100               50.0000
          2         100               25.0000
          3         100               25.0000

(3 row(s) affected)

Ne moramo više da poštovanje ograničenja obezbeđujemo na front endu, nit SQL programiranjem (trigeri i stored procedure). Kod u funkciji nije proceduralni, ne maskiramo funkcijom nikakav kursor.  Onako kako i treba da bude.

🙂


Nastavak sage o Sun-ovoj akviziciji MySQL-a

Friday, 29.02.2008 – Dejan

Sun je već uvrstio sve MySQL proizvode u svoj portfolio, a akcenat je stavljen na MySQL Enterprise verziju.

Ukratko – prema službenim objavama, cilj će biti uska povezanost svih komponenti potrebnih za funkcionisanje jednog informacionog sistema, odnosno integrisana ponuda hardwarea (Sunovi serveri), softwarea (Solaris OS i OpenSolaris, Java, MySQL i td.) i servisnih usluga (consulting, implementation, support …), tako da je ova integrisana end-to-end kombinacija prvenstveno namijenjena srednjim i velikim firmama. A šta sa malim firmama?

Male će se vjerovatno morati osloniti na MySQL community verziju, te PHP i Apache na nekom shared serveru. Support i konsultacije će im pružati Google, a implementaciju jedan od samoukih srednjoš… pardon studenata… 🙂

Agencija Gartner piše da će fokus biti i na OpenSource tržištu, odnosno na jačanju SAMP platforme (umjesto L u LAMP, stavljeno je S za Solaris), ali ja bih tu platformu prije nazvao SAJM (Solaris Apache Java MySQL) ili eventualno SAMJP, a prihod bi se trebao ostvarivati uglavnom preko licenci za support i consulting.

Jonathan Schwartz, Sun CEO, je pored klasičnih menadžerskih/marketinških izjava poput ove:
Our enterprise customers worldwide can now take advantage of MySQL’s market-leading open source database on your choice of platform, OS and language with less risk — for up to a 90% lower total cost of ownership over many traditional database solutions.”

napisao i da će Sun nastaviti uspješnu saradnju sa kompletnom OpenSource zajednicom, te da će M u LAMP platformi i dalje biti njen sastavni dio.

Za one koji se pitaju “I šta sad?“, Mårten Mickos, bivši MySQL CEO, a sadašnji Senior Vice President – Database Group, Sun – daje konkretan odgovor:”Simply put, it’s business as usual, only better.

But now you can leverage MySQL’s and Sun’s joint ability to provide you a complete suite of support options that enable you to rapidly build and deploy efficient, effective and secure applications and services. You can enjoy your total cost of ownership saving and benefit from our expanding roadmap and rates of innovation.

Čitav proces spajanja ove dvije firme će trajati još nekoliko mjeseci, tako da ćemo konkretne rezultate ove akvizicije vidjeti tek krajem ove godine. Do tada – hvala na pažnji – slijedi vremenska prognoza.