MySQL diskte geçici tablolar oluşturur. Nasıl durdurabilirim?


27

Kullanıcıların yavaş bulduğu bir site (Moodle) kullanıyoruz. Sanırım diskte geçici tablolar oluşturmak için MySQL'in problemini izledim. Değişkeni created_tmp_disk_tablesMysql Workbench sunucu yönetiminde izliyorum ve yaklaşık 50 tablo / sn ile sayı artıyor. Bir gün kullanımdan sonra created_tmp_disk_tables,> 100k. Ayrıca, bellek serbest gibi görünmüyor. Sistem kullanılamaz hale gelinceye kadar kullanım artmaya devam ediyor ve MySQL'i yeniden başlatmamız gerekiyor. Hemen hemen her gün yeniden başlatmam gerekiyor ve kullanılabilir hafızanın yaklaşık% 30-35'ini kullanmak ve günü% 80 ile bitirmekle başlıyor.

Veritabanında BLOB'larım yok ve sorgular üzerinde kontrolüm de yok, bu yüzden onları optimize etmeye çalışamıyorum. Ayrıca bir konfigürasyon dosyası oluşturmak için Percona Onaylama Sihirbazı'nı kullandım, ancak my.ini de sorunumu çözmedi.

Sorular

  1. MySQL'in diskte geçici tablolar oluşturmasını engellemek için neyi değiştirmeliyim? Değiştirmem gereken ayarlar var mı? Daha fazla hafıza atmalı mıyım?

  2. MySQL'in hafızamı yemesini nasıl durdurabilirim?

Düzenle

slow_queriesGünlüğü etkinleştirdim ve sorgunun SELECT GET_LOCK()yavaş kaydedildiğini öğrendim . Hızlı bir arama PHP yapılandırmasında ( mysqli.allow_persistent = ON) kalıcı bağlantılara izin verdiğimi gösterdi . Bunu kapattım. Bu, MySQL'in bellek tüketme oranını düşürdü. Yine de geçici tablolar yaratıyor.

Ayrıca key_buffer sizeyeterince büyük olduğunu kontrol ettim . Değişkene baktım key_writes. Bu sıfır olmalı. key_buffer_sizeOlmazsa , artırın. Sıfır key_readsve sıfır var, key_writesbu yüzden key_buffer_sizeyeterince büyük olduğunu varsayıyorum .

Ben artmış tmp_table_sizeve max-heap-table-sizetablolar bellekte sığamaz gösterebilir Created_tmp_disk_tables artışa olarak 1024M için. Bu çözmedi.

Ref: http://www.mysqlperformanceblog.com/2007/08/16/how-much-overhead-is-caused-by-on-disk-temporary-tables/

Düzenle 2

sort_merge_passesSHOW GLOBAL STATUS çıktısında saniyede çok sayıda görürseniz , sort_buffer_sizedeğeri artırmayı düşünebilirsiniz . sort_merge_passesBir saatte 2 tane vardı , bu yüzden sort_buffer_sizeyeterince büyük olduğunu düşünüyorum.

Ref: Mysql Manuel açık sort_buffer_size

Düzenle 3

Sıralama değiştirdim ve arabellekleri @RolandoMySQLDBA tarafından önerilen şekilde birleştirdim. Sonuç aşağıdaki tabloda gösterilmektedir, ancak bunun created_tmp_tables_on_diskhala yüksek olduğunu düşünüyorum . Değeri değiştirip created_tmp_tables_on_diskbir gün (8h) sonra kontrol edip ortalamayı hesapladıktan sonra mysql sunucusunu yeniden başlattım . Başka bir önerin var mı? Bana öyle geliyor ki, bir çeşit kabın içine uymayan bir şey var ama ne olduğunu çözemiyorum.

+---------------------+-------------+-------------+--------------------+
| 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            |
+---------------------+-------------+-------------+--------------------+   



Bu benim yapılandırmam:

+-----------------------+-----------------------+
|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                |
+-----------------------+-----------------------+

Ek bilgi

+--------------------+---------+
|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|
+--------------------+---------+

Bu kurulum bana verildi, bu yüzden üzerinde sınırlı bir kontrolüm var. Web sunucusu çok az CPU ve RAM kullanıyor, bu yüzden makineyi tıkanıklık olarak çıkardım. MySQL ayarlarının çoğu, otomatik yapılandırma aracından kaynaklanır.

Birkaç temsili gün boyunca PerfMon kullanarak sistemi izledim. Bundan diske takılan işletim sistemi olmadığı sonucuna varıyorum.

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

Yorumlar genişletilmiş tartışmalar için değildir; bu konuşma sohbete taşındı .
Paul White GoFundMonica

Yanıtlar:


16

Baktığımda my.iniiki önerim var

ÖNERİ # 1

Telefonunuzda aşağıdaki ayarları değiştirebilirim: my.ini

sort_buffer_size=4M
join_buffer_size=4M

Bu, bazı birleşmelere ve sıralamaların bellekte kalmasına neden olacaktır. Tabii ki, bir kez JOINveya bir ORDER BYihtiyaçtan fazlasına ihtiyaç duyulduğunda 4M, bir MyISAM tablosu olarak diske girer.

Eğer giriş yapamıyorsanız root@localhost, mysql ile yeniden başlatın.

C:\> net stop mysql
C:\> net start mysql

Root @ localhost olarak giriş yapabilirsiniz, bu ayarları kullanmak için mysql'yi yeniden başlatmanız gerekmez.

Sadece bunu MySQL istemcisinde çalıştırın:

SET @FourMegs = 1024 * 1024 * 4;
SET GLOBAL sort_buffer_size = @FourMegs;
SET GLOBAL join_buffer_size = @FourMegs;

ÖNERİ # 2

Verileriniz Drive'da olduğundan, Drive'da D:Disk I / O olabilir C:.

Lütfen bu sorguyu çalıştırın:

mysql> show variables like 'tmpdir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tmpdir        | C:\Windows\TEMP |
+---------------+-----------------+
1 row in set (0.00 sec)

Masaüstümde mysql'yi varsayılan ayarlarla çalıştırdığımdan, temp tablolarım Drive'a yazılıyor C:. D Sürücüsü C:, Drive'dan daha iyi bir diskse , tmpdir komutunu aşağıdaki gibi D:ayarlayarak temp tablolarını Drive'a eşleyebilirsinizmy.ini :

tmpdir="D:/DBs/"

Tmpdir dinamik bir değişken olmadığından mysql'yi yeniden başlatmanız gerekecek .

Bir şans ver !!!

GÜNCELLEME 2013-11-29 10:09 EST

ÖNERİ # 3

MySQL'in Windows'ta çalıştığı ve çekirdek paketteki sorulara dokunamayacağınız gerçeği göz önüne alındığında, tat ile birlikte yapılması gereken iki fikrim var.

FİKİR # 1: Veritabanını Linux Makinesine Taşı

Yapabilmelisin

  • Bir Linux makinesi kurun
  • MySQL'i Linux makinesine yükleyin
  • Windows'ta MySQL İçin İkili Günlük Kaydını Etkinleştir
  • mysqldump veritabanını bir metin SQL dosyasına
  • SQL dosyasını Linux'ta çalışan MySQL'e yükleyin
  • MySQL / Windows'tan MySQL / Linux'a kurulum çoğaltması

FİKİR # 2: Moodle'ı Linux Makinesine işaret edecek şekilde yeniden yapılandırın

Moodle, ilk önce LAMP için tasarlandı. Sadece config dosyalarını değiştirerek localhost yerine Linux makinesini göster.

İşte MySQL kurma konusunda eski bir Moodle 2.3 doc bağlantısı: http://docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database

Eminim ki en yeni dokümanlar da mevcuttur.

Veritabanını Linux'a Taşımanın Amacı Nedir?

Bu geçici tablo durumu nasıl yardımcı olur?

Daha sonra geçici tablolar için hedef klasör olarak bir RAM disk kurma öneriyorum

Temp tablo oluşturma hala gerçekleşecek, ancak disk yerine RAM'e yazılacak. disk g / Ç azaltılması.

GÜNCELLEME 2013-11-29 11:24 EST

ÖNERİ # 4

SUGGESTION # 2'yi hızlı bir RAID-0 diskle (32+ GB) yeniden ziyaret etmenizi, T: (Temp için T) olarak ayarlamanızı öneririm. Böyle bir diski kurduktan sonra şunu ekleyin my.ini:

[mysqld]
tmpdir="T:\"

MySQL yeniden başlatmanız gerekebilir

net stop mysql
net start mysql

BTW RAID-0 dedim, bilerek RAID-1, RAID-10 üzerinden iyi yazma performansı elde edebilirsiniz. Bir tmp masa diski yedekli yapacağım bir şey değil.

Sorguları @RaymondNijland yorum yaptığı gibi optimize etmeden, geçici tablo oluşturma sayısını hiçbir şekilde azaltamazsınız. SUGGESTION #3ve SUGGESTION #4hızlandırılmış geçici tablo oluşturma ve geçici tablo G / Ç'yi tek alternatif olarak sunar.


13

Burada kendi soruma cevap veriyorum

Tercih edilen cevap olarak @RolandoMySQLDBA'yı seçeceğim, çünkü sorunumu çözmeme rağmen bana en çok ipucu verdi.

Araştırmamın sonuçları aşağıda

Sonuç

Windows üzerinde MySQL sadece çok sayıda geçici tablo oluşturur ve MySQL'i ayarlamak, yapılandırma dosyalarının içeriğini değiştirerek yardımcı olmaz.

ayrıntılar

Tablo, herhangi bir sorguyu gerçekleştirmeden önce sırasıyla my.ini dosyasında değiştirdiğim parametreleri göstermektedir. Her test arasında MySQL yeniden başlatıldı.

Orijinal soruda bulunan my.ini dosyasını bir şablon olarak kullandım ve sonra parametrelerin değerini aşağıdaki tabloya göre birer birer değiştirdim.

JMeter'i 100 eşzamanlı web isteği üretmek için kullandım (kullanımımızı ifade ettiği gibi) 10 kez tekrarladı. Her biri Testtoplamda 1000 istekden oluşuyordu. Bu, sonraki veritabanı çağrılarıyla sonuçlandı. Bu, MySQL'in hangi yapılandırma parametrelerini değiştirdiğimizden bağımsız olarak birçok geçici tablo oluşturacağını gösterdi.

+----+------------+-------+---------------+------------+
|Test|Parameter   |Value  |NumOfTempTables|Db Max Conn |
+----+------------+-------+---------------+------------+
| 1  |key_buffer_ | 25M   | 30682         | 29         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 2  |key_buffer_ | 55M   | 30793         | 29         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 3  |key_buffer_ | 100M  | 30666         | 28         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 4  |key_buffer_ | 125M  | 30593         | 24         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 5  |query_cache_| 100M  | 30627         | 32         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 6  |query_cache_| 250M  | 30761         | 26         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 7  |query_cache_| 500M  | 30864         | 83*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 8  |query_cache_| 1G    | 30706         | 75*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 9  |tmp_table_  | 125M  | 30724         | 31         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 10 |tmp_table_  | 250M  | 30689         | 90*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 11 |tmp_table_  | 500M  | 30792         | 28         |
|    |size        |       |               |            |  
+----+------------+-------+---------------+------------+
| 12 |Sort_buffer&| 256K  | 30754         | 28         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 13 |Sort_buffer&| 512K  | 30788         | 30         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 14 |Sort_buffer&| 1M    | 30788         | 28         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 15 |Sort_buffer&| 4M    | 30642         | 35         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 16 |innodb-     | 1G    | 30695         | 33         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |
+----+------------+-------+---------------+------------+
| 17 |innodb-     | 2G    | 30791         | 28         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            | 
+----+------------+-------+---------------+------------+
| 18 |innodb-     | 3G    | 30719         | 34         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |  
+----+------------+-------+---------------+------------+

* Üç turun ortalaması

Aşağıdaki resimler, farklı yapılandırmalar için gerekli olan veritabanı sunucusunu ve CPU miktarını göstermektedir. Siyah çizgiler minimum ve maksimum değerleri, mavi çubuklar başlangıç ​​ve bitiş değerlerini gösterir. Maksimum bellek 4096Msoruda belirtildiği gibiydi .

Hafıza kullanımı CPU kullanımı


Hangi depolama motorunu kullanıyorsunuz? MyISAM tablolarını kullanmıyorsanız, key_buffer_size'ye güvenmek anlamlı değildir. innodb depolama motorunu kullanıyorsanız, innodb_buffer_pool_size boyutu nedir. Query_cache kullanıyor musunuz?
kasi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.