Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Co sprawdzić, jeśli wykorzystanie pamięci MySQL jest wysokie?

Jednym z kluczowych czynników wydajnego serwera bazy danych MySQL jest dobra alokacja i wykorzystanie pamięci, zwłaszcza podczas uruchamiania go w środowisku produkcyjnym. Ale jak określić, czy wykorzystanie MySQL jest zoptymalizowane? Czy to rozsądne, aby mieć wysokie wykorzystanie pamięci, czy wymaga to dostrojenia? Co się stanie, jeśli napotkam wyciek pamięci?

Omówmy te tematy i pokażmy, co można sprawdzić w MySQL, aby określić ślady wysokiego wykorzystania pamięci.

Alokacja pamięci w MySQL

Zanim zagłębimy się w konkretny tytuł tematu, przedstawię tylko krótką informację o tym, jak MySQL wykorzystuje pamięć. Pamięć odgrywa znaczący zasób szybkości i wydajności podczas obsługi współbieżnych transakcji i wykonywania dużych zapytań. Każdy wątek w MySQL wymaga pamięci, która służy do zarządzania połączeniami klientów, a te wątki współdzielą tę samą pamięć podstawową. Zmienne, takie jak thread_stack (stos dla wątków), net_buffer_length (dla bufora połączenia i bufora wyniku) lub z max_allowed_packet, gdzie połączenie i wynik będą dynamicznie powiększać się do tej wartości w razie potrzeby, są zmiennymi, które mają wpływ na wykorzystanie pamięci. Gdy wątek nie jest już potrzebny, przydzielona mu pamięć jest zwalniana i zwracana do systemu, chyba że wątek wraca do pamięci podręcznej wątków. W takim przypadku pamięć pozostaje przydzielona. Sprzężenia zapytań, pamięci podręczne zapytań, sortowanie, pamięć podręczna tabel, definicje tabel wymagają pamięci w MySQL, ale są one przypisywane zmiennym systemowym, które można konfigurować i ustawiać.

W większości przypadków zmienne specyficzne dla pamięci ustawione dla konfiguracji są ukierunkowane na konfigurację opartą na pamięci masowej, taką jak MyISAM lub InnoDB. Kiedy instancja mysqld pojawia się w systemie hosta, MySQL przydziela bufory i pamięci podręczne, aby poprawić wydajność operacji bazy danych w oparciu o wartości ustawione w określonej konfiguracji. Na przykład najczęstszymi zmiennymi, które każdy DBA ustawi w InnoDB, są zmienne innodb_buffer_pool_size i innodb_buffer_pool_instances, które są powiązane z alokacją pamięci puli buforów, która przechowuje buforowane dane dla tabel InnoDB. Jest to pożądane, jeśli masz dużą pamięć i oczekujesz obsługi dużych transakcji, ustawiając innodb_buffer_pool_instances, aby poprawić współbieżność poprzez podzielenie puli buforów na wiele instancji puli buforów.

Podczas gdy dla MyISAM, musisz poradzić sobie z key_buffer_size, aby obsłużyć ilość pamięci, którą obsłuży bufor klucza. MyISAM również alokuje bufor dla każdego współbieżnego wątku, który zawiera strukturę tabeli, struktury kolumn dla każdej kolumny i bufor o rozmiarze 3 * N są przydzielane (gdzie N jest maksymalną długością wiersza, nie licząc kolumn BLOB). MyISAM utrzymuje również jeden dodatkowy bufor wierszy do użytku wewnętrznego.

MySQL alokuje również pamięć dla tabel tymczasowych, chyba że stanie się zbyt duża (określona przez tmp_table_size i max_heap_table_size). Jeśli używasz tabel MEMORY, a zmienna max_heap_table_size jest ustawiona na bardzo wysoką, może to również zająć dużo pamięci, ponieważ zmienna systemowa max_heap_table_size określa, jak duża może się rozrosnąć tabela i nie ma konwersji na format na dysku.

MySQL posiada również schemat wydajności, który jest funkcją monitorowania aktywności MySQL na niskim poziomie. Po włączeniu dynamicznie przydziela pamięć przyrostowo, skalując jej wykorzystanie do rzeczywistego obciążenia serwera, zamiast przydzielać wymaganą pamięć podczas uruchamiania serwera. Po przydzieleniu pamięci nie jest ona zwalniana do czasu ponownego uruchomienia serwera.

MySQL można również skonfigurować do przydzielania dużych obszarów pamięci dla swojej puli buforów, jeśli używasz Linuksa i jeśli jądro jest włączone do obsługi dużych stron, tj. Używając HugePages.

Co należy sprawdzić, gdy pamięć MySQL jest wysoka

Sprawdź uruchomione zapytania

Bardzo często administratorzy baz danych MySQL najpierw dowiadują się, co się dzieje z uruchomionym serwerem MySQL. Najbardziej podstawowe procedury to sprawdzenie listy procesów, sprawdzenie stanu serwera i sprawdzenie stanu silnika pamięci masowej. Aby to zrobić, wystarczy uruchomić serię zapytań, logując się do MySQL. Zobacz poniżej:

Aby wyświetlić uruchomione zapytania,

mysql> SHOW [FULL] PROCESSLIST;

Wyświetlenie bieżącej listy procesów ujawnia zapytania, które są aktywne, a nawet nieaktywne lub uśpione. Posiadanie rejestru uruchomionych zapytań jest bardzo ważne i ważne. Jak wspomniano, w jaki sposób MySQL alokuje pamięć, uruchamianie zapytań będzie wykorzystywać alokację pamięci i może drastycznie powodować problemy z wydajnością, jeśli nie jest monitorowane.

Wyświetl zmienne stanu serwera MySQL,

mysql> SHOW SERVER STATUS\G

lub filtruj określone zmienne, takie jak

mysql> SHOW SERVER STATUS WHERE variable_name IN ('<var1>', 'var2'...);

Zmienne stanu MySQL służą jako informacje statystyczne do pobierania danych metrycznych w celu określenia, jak działa MySQL, obserwując liczniki podane przez wartości stanu. Istnieją tutaj pewne wartości, które dają spojrzenie, które ma wpływ na wykorzystanie pamięci. Na przykład sprawdzenie liczby wątków, liczby pamięci podręcznych tabel lub wykorzystania puli buforów,

...

| Created_tmp_disk_tables                 | 24240 |

| Created_tmp_tables                      | 334999 |

…

| Innodb_buffer_pool_pages_data           | 754         |

| Innodb_buffer_pool_bytes_data           | 12353536         |

...

| Innodb_buffer_pool_pages_dirty          | 6         |

| Innodb_buffer_pool_bytes_dirty          | 98304         |

| Innodb_buffer_pool_pages_flushed        | 30383         |

| Innodb_buffer_pool_pages_free           | 130289         |

…

| Open_table_definitions                  | 540 |

| Open_tables                             | 1024 |

| Opened_table_definitions                | 540 |

| Opened_tables                           | 700887 |

...

| Threads_connected                             | 5 |

...

| Threads_cached    | 2 |

| Threads_connected | 5     |

| Threads_created   | 7 |

| Threads_running   | 1 |

Wyświetl stan monitora silnika, na przykład stan InnoDB

mysql> SHOW ENGINE INNODB STATUS\G

Status InnoDB ujawnia również aktualny stan transakcji przetwarzanych przez silnik pamięci masowej. Podaje rozmiar sterty transakcji, adaptacyjne indeksy mieszające ujawniające wykorzystanie bufora lub pokazuje informacje o puli buforów innodb, tak jak w poniższym przykładzie:

---TRANSACTION 10798819, ACTIVE 0 sec inserting, thread declared inside InnoDB 1201

mysql tables in use 1, locked 1

1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 8801

MySQL thread id 68481, OS thread handle 139953970235136, query id 681821 localhost root copy to tmp table

ALTER TABLE NewAddressCode2_2 ENGINE=INNODB



…

-------------------------------------

INSERT BUFFER AND ADAPTIVE HASH INDEX

-------------------------------------

Ibuf: size 528, free list len 43894, seg size 44423, 1773 merges

merged operations:

 insert 63140, delete mark 0, delete 0

discarded operations:

 insert 0, delete mark 0, delete 0

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 637 buffer(s)

Hash table size 553193, node heap has 772 buffer(s)

Hash table size 553193, node heap has 1239 buffer(s)

Hash table size 553193, node heap has 2 buffer(s)

Hash table size 553193, node heap has 0 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

115320.41 hash searches/s, 10292.51 non-hash searches/s

...

----------------------

BUFFER POOL AND MEMORY

----------------------

Total large memory allocated 2235564032

Dictionary memory allocated 3227698

Internal hash tables (constant factor + variable factor)

    Adaptive hash index 78904768        (35404352 + 43500416)

    Page hash           277384 (buffer pool 0 only)

    Dictionary cache    12078786 (8851088 + 3227698)

    File system         1091824 (812272 + 279552)

    Lock system         5322504 (5313416 + 9088)

    Recovery system     0 (0 + 0)

Buffer pool size   131056

Buffer pool size, bytes 2147221504

Free buffers       8303

Database pages     120100

Old database pages 44172

Modified db pages  108784

Pending reads      0

Pending writes: LRU 2, flush list 342, single page 0

Pages made young 533709, not young 181962

3823.06 youngs/s, 1706.01 non-youngs/s

Pages read 4104, created 236572, written 441223

38.09 reads/s, 339.46 creates/s, 1805.87 writes/s

Buffer pool hit rate 1000 / 1000, young-making rate 12 / 1000 not 5 / 1000

Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s

LRU len: 120100, unzip_LRU len: 0

I/O sum[754560]:cur[8096], unzip sum[0]:cur[0]

…

Kolejna rzecz do dodania, możesz również użyć schematu wydajności i schematu sys do monitorowania zużycia i wykorzystania pamięci przez serwer MySQL. Domyślnie większość oprzyrządowania jest domyślnie wyłączona, więc istnieją ręczne czynności, aby z tego skorzystać.

Sprawdź zamianę

Tak czy inaczej, prawdopodobnie MySQL wymienia pamięć na dysk. Jest to często bardzo powszechna sytuacja, zwłaszcza gdy serwer MySQL i bazowy sprzęt nie są ustawione optymalnie równolegle do oczekiwanych wymagań. Istnieją pewne przypadki, w których nie przewidziano zapotrzebowania na ruch, pamięć może rosnąć coraz bardziej, zwłaszcza jeśli uruchamiane są złe zapytania powodujące zużywanie lub wykorzystywanie dużej ilości miejsca w pamięci, powodując pogorszenie wydajności, ponieważ dane są pobierane z dysku, a nie z bufora. Aby sprawdzić zamianę, po prostu uruchom polecenie freemem lub vmstat, tak jak poniżej,

[[email protected] ~]# free -m

              total        used free      shared buff/cache available

Mem:           3790 2754         121 202 915         584

Swap:          1535 39        1496

[[email protected] ~]# vmstat 5 5

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

 r  b swpd   free buff  cache si so    bi bo in cs us sy id wa st

 2  0 40232 124100      0 937072 2 3 194  1029 477 313 7 2 91 1  0

 0  0 40232 123912      0 937228 0 0   0 49 1247 704 13 3 84  0 0

 1  0 40232 124184      0 937212 0 0   0 35 751 478 6 1 93  0 0

 0  0 40232 123688      0 937228 0 0   0 15 736 487 5 1 94  0 0

 0  0 40232 123912      0 937220 0 0   3 74 1065 729 8 2 89  0 0

Możesz również sprawdzić za pomocą procfs i zebrać informacje, takie jak przejście do /proc/vmstat lub /proc/meminfo.

Korzystanie z Perf, gdb i Valgrind z Massif

Korzystanie z narzędzi takich jak perf, gdb i valgrind pomaga zagłębić się w bardziej zaawansowaną metodę określania wykorzystania pamięci MySQL. Czasami interesujący wynik staje się tajemnicą rozwiązania problemu zużycia pamięci, który prowadzi do oszołomienia w MySQL. To wymaga większego sceptycyzmu, a korzystanie z tych narzędzi pomaga zbadać, w jaki sposób MySQL wykorzystuje obsługę pamięci, od przydzielania jej do wykorzystywania do przetwarzania transakcji lub procesów. Jest to przydatne, na przykład, jeśli obserwujesz, że MySQL zachowuje się nienormalnie, co może powodować złą konfigurację lub może prowadzić do stwierdzenia wycieków pamięci.

Na przykład użycie perf w MySQL ujawnia więcej informacji w raporcie na poziomie systemu:

[[email protected] ~]# perf report --input perf.data --stdio

# To display the perf.data header info, please use --header/--header-only options.

#

#

# Total Lost Samples: 0

#

# Samples: 54K of event 'cpu-clock'

# Event count (approx.): 13702000000

#

# Overhead  Command Shared Object        Symbol                                                                                                                                                                                             

# ........  ....... ...................  ...................................................................................................................................................................................................

#

    60.66%  mysqld [kernel.kallsyms]    [k] _raw_spin_unlock_irqrestore

     2.79%  mysqld   libc-2.17.so         [.] __memcpy_ssse3

     2.54%  mysqld   mysqld             [.] ha_key_cmp

     1.89%  mysqld   [vdso]             [.] __vdso_clock_gettime

     1.05%  mysqld   mysqld             [.] rec_get_offsets_func

     1.03%  mysqld   mysqld             [.] row_sel_field_store_in_mysql_format_func

     0.92%  mysqld   mysqld             [.] _mi_rec_pack

     0.91%  mysqld   [kernel.kallsyms]    [k] finish_task_switch

     0.90%  mysqld   mysqld             [.] row_search_mvcc

     0.86%  mysqld   mysqld             [.] decimal2bin

     0.83%  mysqld   mysqld             [.] _mi_rec_check

….

Ponieważ może to być specjalny temat do zagłębienia się, sugerujemy, abyś zajrzał do tych naprawdę dobrych zewnętrznych blogów jako referencji, perf Podstawy profilowania MySQL, Znajdowanie problemów ze skalowaniem MySQL debuguj za pomocą valgrind z masywem.

Wydajny sposób sprawdzania wykorzystania pamięci MySQL

Korzystanie z ClusterControl eliminuje wszelkie uciążliwe procedury, takie jak przeglądanie elementów Runbook, a nawet tworzenie własnych podręczników, które dostarczają raporty. W ClusterControl masz pulpity nawigacyjne (przy użyciu SCUMM), w których możesz uzyskać szybki przegląd swoich węzłów MySQL. Na przykład przeglądanie pulpitu nawigacyjnego MySQL General,

możesz określić, jak działa węzeł MySQL,

Widać, że powyższe obrazy pokazują zmienne, które wpływają na wykorzystanie pamięci MySQL. Możesz sprawdzić, jak metryki sortowania pamięci podręcznych, tabel tymczasowych, podłączonych wątków, pamięci podręcznej zapytań lub silników pamięci masowej w puli buforów innodb lub bufora kluczy MyISAM.

Korzystanie z ClusterControl oferuje kompleksowe narzędzie, za pomocą którego można również sprawdzać uruchomione zapytania w celu określenia tych procesów (zapytań), które mogą mieć wpływ na wysokie wykorzystanie pamięci. Zobacz przykład poniżej,

Wyświetlanie zmiennych stanu MySQL jest dość łatwe,

Możesz nawet przejść do Wydajność -> Stan Innodb, aby wyświetlić aktualny stan InnoDB węzłów bazy danych. Ponadto w ClusterControl wykryty zostanie incydent, który spróbuje zebrać incydent i wyświetli historię jako raport, który zapewnia status InnoDB, jak pokazano w naszym poprzednim blogu o MySQL Freeze Frame.

Podsumowanie

Rozwiązywanie problemów i diagnozowanie bazy danych MySQL w przypadku podejrzenia wysokiego wykorzystania pamięci nie jest trudne, o ile znasz procedury i narzędzia, których należy użyć. Korzystanie z odpowiedniego narzędzia zapewnia większą elastyczność i szybszą produktywność w celu dostarczania poprawek lub rozwiązań z szansą na lepszy wynik.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy możesz dodać oświadczenie if w ORDER BY?

  2. 2 sposoby konwersji liczby na ósemkową w MySQL

  3. Szybka wskazówka MySQL:Używanie polecenia DROP USER

  4. Symulacja polecenia ORDER BY FIELD() MySQL w Postgresql

  5. Jak nadać wszystkie uprawnienia użytkownikowi root w MySQL 8.0?