Prowadzimy witrynę (Moodle), którą użytkownicy obecnie uważają za wolną. Myślę, że udało mi się wyśledzić problem, tworząc MySQL, tworząc tymczasowe tabele na dysku. Obserwuję zmienną created_tmp_disk_tables
w administracji serwera Mysql Workbench i liczba ta rośnie z około 50 tabelami / s. Po kilku dniach użytkowania created_tmp_disk_tables
wynosi> 100 tys. Wydaje się również, że pamięć nie została zwolniona. Użycie stale rośnie, aż system stanie się praktycznie bezużyteczny i musimy ponownie uruchomić MySQL. Muszę go ponownie uruchamiać prawie codziennie, a zaczyna się to od użycia około 30-35% dostępnej pamięci i kończenie dnia 80%.
Nie mam żadnych obiektów blob w bazie danych ani kontroli nad zapytaniami, więc nie mogę ich zoptymalizować. Użyłem również Kreatora konfirmacji Percona, aby wygenerować plik konfiguracyjny, ale mój.ini też nie rozwiązał mojego problemu.
pytania
Co powinienem zmienić, aby powstrzymać MySQL od tworzenia tabel tymczasowych na dysku? Czy muszę zmienić ustawienia? Czy mam wrzucić więcej pamięci?
Jak mogę zatrzymać MySQL przed zjedzeniem mojej pamięci?
Edytować
Włączyłem slow_queries
dziennik i odkryłem, że zapytanie SELECT GET_LOCK()
zostało zarejestrowane jako wolne. Szybkie wyszukiwanie ujawniło, że zezwoliłem na trwałe połączenia w konfiguracji PHP ( mysqli.allow_persistent = ON
). Wyłączyłem to. Zmniejszyło to szybkość, z jaką MySQL zużywa pamięć, ale nadal tworzy tabele tymczasowe.
Sprawdziłem również, czy key_buffer size
jest wystarczająco duży. Spojrzałem na zmienną key_writes
. To powinno być zero. Jeśli nie, zwiększ wartość. Mam key_buffer_size
zero key_reads
i zero, key_writes
więc zakładam, że key_buffer_size
jest wystarczająco duży.
Zwiększyłem tmp_table_size
i max-heap-table-size
do 1024M, ponieważ wzrost liczby utworzonych tabel_tmp_dysk może wskazywać, że tabele nie mieszczą się w pamięci. To nie rozwiązało problemu.
Edytuj 2
Jeśli widzisz wiele sort_merge_passes
na sekundę w wynikach POKAŻ GLOBALNY STAN, możesz rozważyć zwiększenie tej sort_buffer_size
wartości. Miałem 2 sort_merge_passes
na godzinę, więc uważam, że sort_buffer_size
jest wystarczająco duża.
Patrz: Podręcznik Mysql włączony sort_buffer_size
Edytuj 3
Zmodyfikowałem sortowanie i dołączam do buforów, jak sugeruje @RolandoMySQLDBA. Wynik jest wyświetlany w poniższej tabeli, ale myślę, że created_tmp_tables_on_disk
nadal jest wysoki. Zrestartowałem serwer mysql po zmianie wartości i sprawdziłem created_tmp_tables_on_disk
po dniu (8 godzin) i obliczyłem średnią. Jakieś inne sugestie? Wydaje mi się, że jest coś, co nie mieści się w jakimś pojemniku, ale nie mogę zrozumieć, co to jest.
+---------------------+-------------+-------------+--------------------+
| Tmp_table_size, | Sort_buffer | Join_buffer | No of created |
| max_heap_table_size | | | tmp_tables on disk |
+---------------------+-------------+-------------+--------------------+
| 125M | 256K | 256K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 512K | 512K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 1M | 1M | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 4M | 4M | 100k/h |
+---------------------+-------------+-------------+--------------------+
Oto moja konfiguracja:
+-----------------------+-----------------------+
|DATABASE SERVER |WEB SERVER |
+-----------------------+-----------------------+
|Windows Server 2008 R2 |Windows Server 2008 R2 |
+-----------------------+-----------------------+
|MySQL 5.1.48 |IIS 7.5 |
+-----------------------+-----------------------+
|4 Core CPU |4 Core CPU |
+-----------------------+-----------------------+
|4GB RAM |8GB RAM |
+-----------------------+-----------------------+
Dodatkowe informacje
+--------------------+---------+
|PARAM |VALUE |
+--------------------+---------+
|Num of tables in Db |361 |
+--------------------+---------+
|Size of database |2.5G |
+--------------------+---------+
|Database engine |InnoDB |
+--------------------+---------+
|Read/write ratio |3.5 |
|(Innodb_data_read/ | |
|innodb_data_written)| |
+--------------------+---------+
|Avg table size |15k rows |
+--------------------+---------+
|Max table size |744k rows|
+--------------------+---------+
Ta konfiguracja została mi dana, więc mam nad nią ograniczoną kontrolę. Serwer WWW zużywa bardzo mało procesora i pamięci RAM, więc wykluczyłem tę maszynę jako wąskie gardło. Większość ustawień MySQL pochodzi z narzędzia do automatycznego generowania konfiguracji.
Monitorowałem system za pomocą PerfMon przez kilka reprezentatywnych dni. Na tej podstawie dochodzę do wniosku, że to nie system operacyjny zamienia się na dysk.
My.ini
[client]
port=3306
[mysql]
default-character-set=utf8
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.1/"
datadir="D:/DBs/Data/"
default-character-set=utf8
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=125
query_cache_size=350M
table_cache=1520
tmp_table_size=125M
table-definition-cache= 1024
max-heap-table-size= 32M
thread_cache_size=38
MyISAM Specific options
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=125M
key_buffer_size=55M
read_buffer_size=1024K
read_rnd_buffer_size=256K
sort_buffer_size=1024K
join_buffer_size=1024K
INNODB Specific options
innodb_data_home_dir="D:/DBs/"
innodb_additional_mem_pool_size=32M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_buffer_pool_size=2G
innodb_log_file_size=407M
innodb_thread_concurrency=8
źródło
Odpowiedzi:
Patrząc na
my.ini
, mam dwie sugestieSUGESTIA # 1
Zwiększyłbym następujące ustawienia w twoim
my.ini
Spowoduje to, że niektóre złączenia i sortowanie pozostaną w pamięci. Oczywiście, raz
JOIN
alboORDER BY
potrzebuje więcej niż4M
, to będzie strona na dysku w postaci tabeli MyISAM.Jeśli nie możesz się zalogować jako
root@localhost
, uruchom ponownie mysql przy pomocyJeśli możesz zalogować się jako root @ localhost, nie musisz ponownie uruchamiać mysql, aby użyć tych ustawień.
Po prostu uruchom to w kliencie MySQL:
SUGESTIA # 2
Ponieważ Twoje dane znajdują się na Dysku
D:
, możesz mieć dyskowe operacje we / wy na DyskuC:
.Uruchom to zapytanie:
Ponieważ uruchamiam mysql na pulpicie z ustawieniami domyślnymi, moje tabele tymczasowe są zapisywane na Dysku
C:
. Jeśli Dysk D jest dyskiem lepszym niż DyskC:
, być może możesz mapować tabele temp na DyskD:
, ustawiając tmpdir wmy.ini
następujący sposób:Będziesz musiał zrestartować mysql, ponieważ tmpdir nie jest zmienną dynamiczną.
Spróbuj !!!
AKTUALIZACJA 29.11.2013 10:09 EST
SUGESTIA # 3
Biorąc pod uwagę fakt, że MySQL działa w systemie Windows i nie można dotknąć zapytań w pakiecie podstawowym, mam dwa pomysły, które należy wykonać razem.
POMYSŁ nr 1: Przenieś bazę danych na maszynę z systemem Linux
Powinieneś być w stanie
POMYSŁ # 2: Ponownie skonfiguruj Moodle, aby wskazywał maszynę z systemem Linux
Moodle zostało zaprojektowane przede wszystkim dla LAMP. Wystarczy zmienić pliki konfiguracyjne, aby wskazywały na komputer z systemem Linux zamiast na localhost.
Oto link do starego dokumentu Moodle 2.3 na temat konfigurowania MySQL: http://docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database
Jestem pewien, że najnowsze dokumenty są również dostępne.
Jaki jest sens przenoszenia bazy danych do systemu Linux?
Jak to pomaga w sytuacji w tabeli tymczasowej ???
Sugerowałbym wtedy ustawienie dysku RAM jako folderu docelowego dla twoich tabel tymczasowych
Jan 04, 2013
: Czy istnieje silnik MySQL lub sztuczka pozwalająca uniknąć zapisywania tylu tabel tymczasowych na dysku?Dec 17, 2012
: Dlaczego MySQL produkuje tyle tymczasowych plików MYD? (Rzeczywiste instrukcje)Nov 30, 2012
: Czy źle jest tworzyć jednocześnie wiele tabel tymczasowych mysql?Tworzenie tabeli tymczasowej nadal będzie się odbywać, ale zostanie zapisane w pamięci RAM, a nie na dysku. redukowanie We / Wy dysku.
AKTUALIZACJA 29.11.2013 11:24 EST
SUGESTIA # 4
Proponuję ponownie odwiedzić SUGGESTION # 2 z szybkim dyskiem RAID-0 (32+ GB), konfigurując go jako Dysk T: (T dla Temp). Po zainstalowaniu takiego dysku dodaj go do
my.ini
:Wymagane byłoby ponowne uruchomienie MySQL przy użyciu
BTW powiedziałem celowo RAID-0, abyś mógł uzyskać dobrą wydajność zapisu w porównaniu do RAID-1, RAID-10. Dysk tabeli tmp nie jest czymś, co uczynię nadmiarowym.
Bez optymalizacji zapytań, jak komentuje @RaymondNijland, nie można w żaden sposób zmniejszyć liczby tworzenia tabeli tymczasowej.
SUGGESTION #3
iSUGGESTION #4
oferują przyspieszenie tworzenia tabeli temp i we / wy tabeli temp jako jedyną alternatywę.źródło
Odpowiadam na moje własne pytanie, aby uzyskać kompletność
Jako preferowaną odpowiedź wybiorę @RolandoMySQLDBA, ponieważ dał mi najwięcej wskazówek, mimo że tak naprawdę nie rozwiązał mojego problemu.
Poniżej znajdują się wyniki mojego dochodzenia
Wniosek
MySQL w systemie Windows po prostu tworzy wiele tabel tymczasowych, a dostrajanie MySQL poprzez modyfikację zawartości plików konfiguracyjnych nie pomogło.
Detale
Tabela wyszczególnia parametry, które odpowiednio zmodyfikowałem w my.ini przed wykonaniem jakichkolwiek zapytań. MySQL został ponownie uruchomiony między każdym testem.
Użyłem my.ini znalezionego w oryginalnym pytaniu jako szablonu, a następnie zmieniłem wartość parametrów jeden po drugim zgodnie z poniższą tabelą.
Użyłem JMeter do wygenerowania 100 równoczesnych żądań internetowych (ponieważ reprezentowało to nasze użycie) powtórzonych 10 dziesięć razy. Każde
Test
składało się więc z 1000 wniosków łącznie. Spowodowało to kolejne wywołania bazy danych. To pokazało, że MySQL utworzy wiele tabel tymczasowych niezależnie od zmienionych parametrów konfiguracyjnych.* Średnia z trzech przebiegów
Poniższe obrazy przedstawiają ilość pamięci i procesora wymaganych przez serwer bazy danych dla różnych konfiguracji. Czarne linie wskazują wartości minimalne i maksymalne, a niebieskie paski wskazują wartości początkowe i końcowe. Maksymalna pamięć była
4096M
taka, jak wskazano w pytaniu.źródło