imam jedan veliki problem koji me muci vec mesec dana (i vise).
Tabela izgleda ovako:
CREATE TABLE IF NOT EXISTS `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT '0',
`type_id` smallint(3) DEFAULT '0',
`acdate` timestamp NULL DEFAULT NULL,
`amount` decimal(11,2) DEFAULT '0.00',
`total` decimal(11,2) DEFAULT '0.00',
`country_code` char(3) COLLATE utf8_unicode_ci DEFAULT NULL,
`currency` char(3) COLLATE utf8_unicode_ci DEFAULT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `country_code` (`country_code`),
KEY `type_id` (`type_id`),
KEY `date` (`date`),
KEY `currency` (`currency`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC AUTO_INCREMENT=3499518 ;
Objasnjenje: user_id - vlasnik racuna(Cardinality: 82129), type_id (Cardinality: 18)- vrsta racuna, acdate - datum, amount - iznos koji se upisuje na racun korisnika, total - novo stanje na racunu korisnika, country_code - zemlja (Cardinality: 18), currency - valuta(Cardinality: 18), active - status da li je aktivan upis ili ne...
Mozda nije najsrecnije resenje za pamcenje stanja i upisa na racunima korisnika ali je za sada tako (Ukoliko imate predlog i primere kako to bolje uraditi slobodno mi napisite :) )
Prilikom upisa novog stanja (kolona total) na racunu, prvo iscitavam stanje prethodnog stanja na racunu (kolona total) tj. iscitavam zadnji insert u tabelu account i upisujem novo stanje, sve to je uokvireno u okviru transakcije i lokovano sa "for Update"
I to sve super radi, ali krenule su da mi se javljaju cudne greske i to od kada je tabela narasla na preko 2 mil upisa (mesecno se u tabeli upisuju 250 000 inserta). Prilikom velikog saobracaja MySQL ili ubaci phantom read ili ne procita ni jedan row za tog korisnika vec mi php naredba koja cita mysql resurs javlja da select nije nasao ni jedan row... I onda vraca stanje korisnika na nulu + novo insertovani amount, i voila eto mene sa jos manje kose....
Query i kod izlgeda ovako:
Start Transaction;
jako puno querija
SELECT * FROM account
WHERE user_id=45 AND
type_id=7 AND
currency = 'RSD' AND
country_code='sr' AND
active=1
ORDER BY acc_id DESC LIMIT 1 FOR UPDATE;
<php-ov kod koji uzima stanje i sabira sa novim iznosom koji treba da se unese>
INSERT INTO accounts (user_id, type_id, acdate, amount, total, currency, country_code, active )
VALUES
(45, 7, $today, 55, 55+prethodno_stanje, 'RSD', 'sr', 1)
jako puno querija
ako nije bilo greske
Commit;
ako je bilo
Rollback
Php-ov kod ne vraca gresku, exception su svuda po kodu. Mysql transakcija je velika i ima u sebi 100 - 200 inserta (nikad za isti user_id u okviru jedne transakcije).
Pitanje - da li je moguce da transakcija zbog malo RAM-a (2 Gb na serveru) ili zbog prezauzetosti krece da brlja i da ne ispunjava osobinu konkurentnost.
(Server: Localhost via UNIX socket, Server version: 5.0.92-community-log ) Da li bi mozda pomoglo da predjem na 5.5 ?
my.cnf podesavanja:
innodb_log_buffer_size = 64M
innodb_buffer_pool_size=1024M
innodb_log_file_size = 256M
innodb_lock_wait_timeout=50
isolation-level je Repetable-read - probao serializable i ne ide
Hvala svima na odgovorima