Przejdź do treści

MySQL – optymalizacja i wydajność

O pracy MySQL DBA – przemyślenia administratora

Archiwa

Kategoria: MySQL

Tak jak pisałem w poprzednim poście do przenoszenia informacji o modyfikacjach MySQL stosuje binlogi. Replikacja MySQL może działać w trzech trybach, które przekładają się na to, co do binlogów jest zapisywane – row-based replication (RBR), statement-based replication (SBR) i mieszanka obu trybów. Ustawia się to przy pomocy zmiennej binlog_format, która może przyjąć wartość ROW, STATEMENT i MIXED.
czytaj dalej…

Na temat tego, jak skonfigurować replikację w MySQL można znaleźć w internecie sporo informacji. Z resztą, na tym blogu taki krótki opis także się pojawi. Tym razem jednak wspomnę kilka słów o tym, jak działa mechanizm replikacji w MySQL. Replikacja to jeden z najprostszych sposobów aby zapewnić sobie skalowalność aplikacji. Ogólna idea jest taka, że mamy jeden serwer – master, na którym wykonywane są wszystkie zapytania modyfikujące dane. Modyfikacje te przenoszone są przez replikację na drugi serwer (albo serwery, może ich być więcej) – slave. W efekcie mamy dwie, teoretycznie identyczne kopie bazy danych, na których możemy wykonywać zapytania typu SELECT. Jak to wygląda w praktyce?

czytaj dalej…

Podczas rutynowych prac natknąłem się na bardzo ciekawe zapytanie o następującym planie wykonania:

+----+--------------------+-----------------+------+---------------+------+---------+------+-------+----------------------------------------------+
| id | select_type        | table           | type | possible_keys | key  | key_len | ref  | rows  | Extra                                        |
+----+--------------------+-----------------+------+---------------+------+---------+------+-------+----------------------------------------------+
|  1 | PRIMARY            | <derived2>      | ALL  | NULL          | NULL | NULL    | NULL |   185 |                                              |
|  2 | DERIVED            | tab1            | ALL  | NULL          | NULL | NULL    | NULL |  2869 | Using where; Using temporary; Using filesort |
|  2 | DERIVED            | tab2            | ALL  | NULL          | NULL | NULL    | NULL |  2869 |                                              |
|  2 | DERIVED            | tab3            | ALL  | NULL          | NULL | NULL    | NULL |  2869 |                                              |
|  2 | DERIVED            | tab4            | ALL  | NULL          | NULL | NULL    | NULL | 10483 |                                              |
|  4 | DEPENDENT SUBQUERY | tab5            | ALL  | NULL          | NULL | NULL    | NULL |  5613 | Using where                                  |
|  3 | DEPENDENT SUBQUERY | tab6            | ALL  | NULL          | NULL | NULL    | NULL |  2311 | Using where                                  |
+----+--------------------+-----------------+------+---------------+------+---------+------+-------+----------------------------------------------+
7 rows in set (2 min 12.76 sec)

Przyznam, że jest to swojego rodzaju rekord. Sam EXPLAIN wykonywał się kilka minut, zapytanie analizowało prawie 7 milionów rekordów. Co lepsze, zapytanie to do poindeksowania było banalne – SELECT z jednym podzapytaniem, w którego skład wchodziły OUTER JOINy. Skoro na załączonym przykładzie widać, że indeksowanie JOINów nie jest rzeczą oczywistą, to popatrzmy jak to można zrobić.
czytaj dalej…

MySQL 5.5.6 stało się oficjalnie Release Candidate dla nowej stabilnej wersji MySQL. Polecam ściągnięcie nowej wersji i zapoznanie się z tym, co już niedługo stanie się standardem w MySQL – InnoDB jako domyślny silnik bazodanowy, PERFORMANCE_SCHEMA, lepsza wydajność przy większej ilości jednoczesnych połączeń.

Co pewien czas spotykam się z sytuacją, gdy serwer bazodanowy, a konkretnie jego procesor, przeciążany jest przez zapytania typu:

UPDATE jakastabela SET cokolwiek = '4' WHERE kolumna1 = '10' AND kolumna2 = '20';

Dlaczego takie zapytanie tak bardzo obciąża CPU? Przecież zapytanie typu UPDATE to modyfikacja danych, czyli operacja dyskowa? Co tu robi procesor? Przyczyna jest zazwyczaj prozaiczna. Twórca tego zapytania zapomniał o podstawowej sprawie – o indeksach. Indeksy w UPDATE? Przecież indeksy przyspieszają wyszukiwanie danych, a nie ich modyfikację. Ba, indeks zmniejsza wydajność zapytań modyfikujących dane bo jeśli indeksu nie ma, to modyfikujemy tylko dane w tabeli. Jeśli natomiast indeks jest, to oprócz tabeli konieczna jest także modyfikacja danych z indeksu. Dodatkowa operacja dyskowa. O co więc chodzi z tymi indeksami w zapytaniach typu UPDATE?
czytaj dalej…

W warunku WHERE, jeśli chcemy wyciągnąć rekordy o danej zawartości kolumny, można zastosować dwie różne formy – WHERE kolumna=’coś’ i WHERE kolumna LIKE ‚coś’. Z punktu widzenia efektu, jaki twórca zapytania chce uzyskać oba sposoby dają identyczny efekt:

mysql> SELECT * FROM actor WHERE last_name='SWANK';
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        9 | JOE        | SWANK     | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM actor WHERE last_name LIKE 'SWANK';
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        9 | JOE        | SWANK     | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)

Pojawia się pytanie, czy oba sposoby są identyczne z punktu widzenia wydajności?

czytaj dalej…

W poprzednich postach pisałem o tym, jak wygląda sytuacja, gdy wypinamy wtyczkę z kontaktu – jak wygląda wymuszony restart serwera MySQL, jak wygląda odtwarzanie danych z kopii zapasowej? Niektórzy administratorzy MySQL, na wypadek zajścia takiej sytuacji, stosują różnorakie mechanizmy gwarantujące pewien poziom dostępności usług. W tym poście opiszę pokrótce dwa takie rozwiązania, omówimy także jak to się ma do wyboru silnika bazodanowego.
czytaj dalej…

MySQL 5.6

Sie 31

Wczoraj, 30 sierpnia wydana została nowa wersja MySQL – 5.6. Z nowości wprowadzono możliwość wymuszenia opóźnienia replikacji, coś co do tej pory trzeba było realizować przy pomocy zewnętrznych aplikacji (mk-slave-delay). Wprowadzono zmiany w Performance Schema, dodatkowe możliwości zarządzania partycjami i subpartycjami, a także możliwość wykorzystania mysqlbinlog do backupowania binary logów z zdalnego serwera. Do tej pory można było co najwyżej zrzucić je do postaci SQL, w MySQL 5.6 można będzie zapisać je także w postaci binarnej. Więcej informacji w dokumentacji MySQL.

Oczywiście pamiętamy, że obecnie, od 8 grudnia 2008 roku, stabilną wersją MySQL jest MySQL 5.1

W poprzednim poście porównywałem odporność obu silników na awarie. W skrócie chodziło o to, co się stanie, jeśli wyciągniemy wtyczkę z kontaktu? Jakie będą skutki? Jak szybko serwer zacznie działać i serwować dane? W tym poście pokrótce opiszę, co się stanie, jeśli wtyczka została wyciągnięta i po ponownym starcie serwera okazuje się, że trzeba dane przywrócić z backupu.
czytaj dalej…

W poprzednich postach (Różnice pomiędzy MyISAM i InnoDB – wydajność i Co jest szybsze – MyISAM czy InnoDB? ) porównywałem wydajność obu silników. Dziś przyglądniemy się innemu, także ważnemu aspektowi jakim jest bezpieczeństwo danych w trakcie awarii. Administrator MySQL, wybierając silnik bazodanowy, musi uwzględnić to, że awarie się zdarzają. Nawet w najlepiej przetestowanym środowisku produkcyjnym prędzej czy później dojdzie do padu jakiegoś elementu. Systemy operacyjne segfaultują, dyski padają, zasilaniu zdarza się zaniknąć, a UPSy się wyczerpują. Który z silników będzie lepszym wyborem, jeśli chodzi o odporność na tego typu sytuacje?
czytaj dalej…