Wie groß sollte mysql innodb_buffer_pool_size sein?


170

Ich habe eine ausgelastete Datenbank mit ausschließlich InnoDB-Tabellen, die ungefähr 5 GB groß sind. Die Datenbank läuft auf einem Debian-Server mit SSD-Festplatten und ich habe max. Verbindungen = 800 eingestellt, die den Server manchmal sättigen und zum Stoppen bringen. Die durchschnittliche Abfrage pro Sekunde beträgt ca. 2,5 KB. Ich muss also die Speichernutzung optimieren, um Platz für maximal mögliche Verbindungen zu schaffen.

Ich habe Vorschläge gesehen, dass innodb_buffer_pool_size bis zu% 80 des gesamten Speichers betragen sollte. Andererseits bekomme ich diese Warnung vom Tuning-Primer-Skript:

Max Memory Ever Allocated : 91.97 G
Configured Max Per-thread Buffers : 72.02 G
Configured Max Global Buffers : 19.86 G
Configured Max Memory Limit : 91.88 G
Physical Memory : 94.58 G

Hier sind meine aktuellen Innodb-Variablen:

| innodb_adaptive_flushing                          | ON                                                                                                                     |
| innodb_adaptive_hash_index                        | ON                                                                                                                     |
| innodb_additional_mem_pool_size                   | 20971520                                                                                                               |
| innodb_autoextend_increment                       | 8                                                                                                                      |
| innodb_autoinc_lock_mode                          | 1                                                                                                                      |
| innodb_buffer_pool_instances                      | 1                                                                                                                      |
| innodb_buffer_pool_size                           | 20971520000                                                                                                            |
| innodb_change_buffering                           | all                                                                                                                    |
| innodb_checksums                                  | ON                                                                                                                     |
| innodb_commit_concurrency                         | 0                                                                                                                      |
| innodb_concurrency_tickets                        | 500                                                                                                                    |
| innodb_data_file_path                             | ibdata1:10M:autoextend                                                                                                 |
| innodb_data_home_dir                              |                                                                                                                        |
| innodb_doublewrite                                | ON                                                                                                                     |
| innodb_fast_shutdown                              | 1                                                                                                                      |
| innodb_file_format                                | Antelope                                                                                                               |
| innodb_file_format_check                          | ON                                                                                                                     |
| innodb_file_format_max                            | Antelope                                                                                                               |
| innodb_file_per_table                             | ON                                                                                                                     |
| innodb_flush_log_at_trx_commit                    | 2                                                                                                                      |
| innodb_flush_method                               | O_DIRECT                                                                                                               |
| innodb_force_load_corrupted                       | OFF                                                                                                                    |
| innodb_force_recovery                             | 0                                                                                                                      |
| innodb_io_capacity                                | 200                                                                                                                    |
| innodb_large_prefix                               | OFF                                                                                                                    |
| innodb_lock_wait_timeout                          | 50                                                                                                                     |
| innodb_locks_unsafe_for_binlog                    | OFF                                                                                                                    |
| innodb_log_buffer_size                            | 4194304                                                                                                                |
| innodb_log_file_size                              | 524288000                                                                                                              |
| innodb_log_files_in_group                         | 2                                                                                                                      |
| innodb_log_group_home_dir                         | ./                                                                                                                     |
| innodb_max_dirty_pages_pct                        | 75                                                                                                                     |
| innodb_max_purge_lag                              | 0                                                                                                                      |
| innodb_mirrored_log_groups                        | 1                                                                                                                      |
| innodb_old_blocks_pct                             | 37                                                                                                                     |
| innodb_old_blocks_time                            | 0                                                                                                                      |
| innodb_open_files                                 | 300                                                                                                                    |
| innodb_purge_batch_size                           | 20                                                                                                                     |
| innodb_purge_threads                              | 0                                                                                                                      |
| innodb_random_read_ahead                          | OFF                                                                                                                    |
| innodb_read_ahead_threshold                       | 56                                                                                                                     |
| innodb_read_io_threads                            | 4                                                                                                                      |
| innodb_replication_delay                          | 0                                                                                                                      |
| innodb_rollback_on_timeout                        | OFF                                                                                                                    |
| innodb_rollback_segments                          | 128                                                                                                                    |
| innodb_spin_wait_delay                            | 6                                                                                                                      |
| innodb_stats_method                               | nulls_equal                                                                                                            |
| innodb_stats_on_metadata                          | ON                                                                                                                     |
| innodb_stats_sample_pages                         | 8                                                                                                                      |
| innodb_strict_mode                                | OFF                                                                                                                    |
| innodb_support_xa                                 | ON                                                                                                                     |
| innodb_sync_spin_loops                            | 30                                                                                                                     |
| innodb_table_locks                                | ON                                                                                                                     |
| innodb_thread_concurrency                         | 4                                                                                                                      |
| innodb_thread_sleep_delay                         | 10000                                                                                                                  |
| innodb_use_native_aio                             | ON                                                                                                                     |
| innodb_use_sys_malloc                             | ON                                                                                                                     |
| innodb_version                                    | 1.1.8                                                                                                                  |
| innodb_write_io_threads                           | 4                                                                                                                      |

Eine Randnotiz, die relevant sein könnte: Ich sehe, dass, wenn ich versuche, einen großen Beitrag (etwa über 10 KB) von Drupal (der sich auf einem separaten Webserver befindet) in die Datenbank einzufügen, dieser für immer andauert und die Seite nicht korrekt zurückkehrt.

In Bezug auf diese Fragen frage ich mich, welche Größe mein innodb_buffer_pool_size für eine optimale Leistung haben soll. Ich freue mich über Ihre Vorschläge, um diesen und andere Parameter für dieses Szenario optimal einzustellen.

Antworten:


252

Ihre innodb_buffer_pool_size ist enorm. Du hast es auf eingestellt 20971520000. Das sind 19.5135 GB. Wenn Sie nur 5 GB InnoDB-Daten und -Indizes haben, sollten Sie nur etwa 8 GB haben. Auch das kann zu hoch sein.

Folgendes sollten Sie tun. Führen Sie zuerst diese Abfrage aus

SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
(SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
FROM information_schema.tables WHERE engine='InnoDB') A;

Auf diese Weise erhalten Sie die RIBPS (Recommended InnoDB Buffer Pool Size) basierend auf allen InnoDB-Daten und -Indizes mit zusätzlichen 60%.

Zum Beispiel

mysql>     SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
    ->     (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
    ->     FROM information_schema.tables WHERE engine='InnoDB') A;
+-------+
| RIBPS |
+-------+
|     8 |
+-------+
1 row in set (4.31 sec)

mysql>

Mit dieser Ausgabe würden Sie Folgendes in /etc/my.cnf einstellen

[mysqld]
innodb_buffer_pool_size=8G

Nächster, service mysql restart

Führen Sie nach dem Neustart mysql ein oder zwei Wochen lang aus. Führen Sie dann diese Abfrage aus:

SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM
(SELECT variable_value PagesData
FROM information_schema.global_status
WHERE variable_name='Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize
FROM information_schema.global_status
WHERE variable_name='Innodb_page_size') B;

Hier sehen Sie, wie viele GB Arbeitsspeicher aktuell von InnoDB-Daten im InnoDB-Pufferpool belegt sind.

Ich habe darüber schon einmal geschrieben: Was soll man innodb_buffer_pool setzen und warum ..?

Sie können diese DataGBAbfrage jetzt ausführen, anstatt sie neu zu konfigurieren, neu zu starten und eine Woche zu warten.

Dieser Wert DataGBähnelt eher der Größe des InnoDB-Pufferpools + (in innodb_change_buffer_max_size angegebener Prozentsatz). Ich bin mir sicher, dass dies weit weniger als die 20000M sein wird, die Sie gerade reserviert haben. Die Einsparungen im RAM können zum Optimieren anderer Dinge wie verwendet werden

CAVEAT # 1

Dies ist sehr wichtig zu beachten: Manchmal kann InnoDB zusätzliche 10% über dem Wert für innodb_buffer_pool_size verlangen . Folgendes steht in der MySQL-Dokumentation dazu:

Je größer Sie diesen Wert festlegen, desto weniger Festplatten-E / A werden für den Zugriff auf Daten in Tabellen benötigt. Auf einem dedizierten Datenbankserver können Sie diesen Wert auf bis zu 80% der physischen Speichergröße des Computers festlegen. Stellen Sie sich darauf ein, diesen Wert zu verringern, wenn die folgenden anderen Probleme auftreten:

Die Konkurrenz um den physischen Speicher kann zu Paging im Betriebssystem führen.

InnoDB reserviert zusätzlichen Speicher für Puffer und Kontrollstrukturen, sodass der insgesamt zugewiesene Speicherplatz ca. 10% größer als die angegebene Größe ist.

Der Adressraum muss zusammenhängend sein, was auf Windows-Systemen mit DLLs, die an bestimmten Adressen geladen werden, ein Problem sein kann.

Die Zeit zum Initialisieren des Pufferpools ist in etwa proportional zu seiner Größe. Bei großen Installationen kann diese Initialisierungszeit erheblich sein. Auf einem modernen Linux x86_64-Server dauert die Initialisierung eines 10-GB-Pufferpools beispielsweise ungefähr 6 Sekunden. Siehe auch Abschnitt 8.9.1, „Der InnoDB- Pufferpool .

CAVEAT # 2

Ich sehe die folgenden Werte in Ihrem my.cnf

| innodb_io_capacity                                | 200 |
| innodb_read_io_threads                            | 4   |
| innodb_thread_concurrency                         | 4   |
| innodb_write_io_threads                           | 4   |

Diese Nummer verhindert, dass InnoDB auf mehrere Kerne zugreifen kann

Bitte stellen Sie folgendes ein:

[mysqld]
innodb_io_capacity = 2000
innodb_read_io_threads = 64
innodb_thread_concurrency = 0
innodb_write_io_threads = 64

Ich habe darüber schon einmal in DBA StackExchange geschrieben

Ich habe gerade eine Frage wie diese in ServerFault mit einer präziseren Formel beantwortet :

SELECT CONCAT(CEILING(RIBPS/POWER(1024,pw)),SUBSTR(' KMGT',pw+1,1))
Recommended_InnoDB_Buffer_Pool_Size FROM
(
    SELECT RIBPS,FLOOR(LOG(RIBPS)/LOG(1024)) pw
    FROM
    (
        SELECT SUM(data_length+index_length)*1.1*growth RIBPS
        FROM information_schema.tables AAA,
        (SELECT 1.25 growth) BBB
        WHERE ENGINE='InnoDB'
    ) AA
) A;

1
Danke für diesen tollen Beitrag! Ihre Formel, die mit beginnt, SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM...generiert unter MySQL 5.7 den folgenden Fehler: " Die Funktion 'INFORMATION_SCHEMA.GLOBAL_STATUS' ist deaktiviert. Weitere Informationen finden Sie in der Dokumentation zu 'show_compatibility_56'. " Hätten Sie vielleicht eine aktualisierte Version?
Benjamin

Ich bekomme 307 RIBPS und 264G. Das heißt, ich brauche 307 GB RAM?
E_Blue

Eher wie 264G. Aber Sie sollten genug RAM dafür haben, andernfalls geben Sie die erwähnten 80% Ihres RAM an mysql, je nachdem, was auf dem System noch läuft.
Sjas

2
Der beste Beitrag, den ich je gelesen habe! Ich habe eine ~ große Datenbank um 3GB. Nachdem du deine Antwort / deinen Artikel gelesen und die Geschwindigkeit der Links auf 2x
erhöht hast

4
@Benjamin: Ab MySQL 5.7.6 wird das information_schema mit dem performance_schema zusammengeführt. Ändern Sie "information_schema" in der Abfrage einfach in "performance_schema", damit es funktioniert. Quelle: dev.mysql.com/doc/refman/5.7/en/status-table.html
Ralph Bolton

11

Etwas wie das? Verwenden SHOW VARIABLESund SHOW GLOBAL STATUS:

Ausdruck: innodb_buffer_pool_size / _ram
Bedeutung: % des für InnoDB buffer_pool verwendeten RAM
Empfohlener Bereich: 60 ~ 80%

Ausdruck: Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
Bedeutung: Anforderungen lesen, die die Festplatte treffen mussten
Empfohlener Bereich: 0-2%
Was tun, wenn er außerhalb des Bereichs liegt: Erhöhen Sie innodb_buffer_pool_size, wenn Sie genug haben RAM.

Ausdruck: Innodb_pages_read / Innodb_buffer_pool_read_requests
Bedeutung: Anforderungen lesen, die die Festplatte treffen mussten
Empfohlener Bereich: 0-2%
Was tun, wenn der Bereich überschritten wird : Erhöhen Sie innodb_buffer_pool_size, wenn Sie über genügend RAM verfügen.

Ausdruck: Innodb_pages_written / Innodb_buffer_pool_write_requests
Bedeutung: Schreiben von Anforderungen, die die Festplatte treffen mussten
Empfohlener Bereich: 0-15% Was tun, wenn der Bereich überschritten
wird: Check innodb_buffer_pool_size

Ausdruck: Innodb_buffer_pool_reads / Uptime
Bedeutung: Liest
Empfohlener Bereich: 0-100 / Sek.
Was tun, wenn der Wert außerhalb des gültigen Bereichs liegt? Innodb_buffer_pool_size erhöhen?

Ausdruck: (Innodb_buffer_pool_reads + Innodb_buffer_pool_pages_flushed) / Uptime
Bedeutung: InnoDB I / O
Empfohlener Bereich: 0-100 / Sek.
Was tun, wenn der Wert außerhalb des gültigen Bereichs liegt? Innodb_buffer_pool_size erhöhen?

Ausdruck: Innodb_buffer_pool_pages_flushed / Uptime
Bedeutung: Schreibt (Flush)
Empfohlener Bereich: 0-100 / Sek.
Was tun, wenn der Wert außerhalb des gültigen Bereichs liegt? Innodb_buffer_pool_size erhöhen?

Ausdruck: Innodb_buffer_pool_wait_free / Uptime
Bedeutung: Zähler für den Fall, dass sich keine freien Seiten in buffer_pool befinden. Das heißt, alle Seiten sind schmutzig.
Empfohlener Bereich: 0-1 / Sek.
Was ist zu tun, wenn der Wert außerhalb des gültigen Bereichs liegt? Stellen Sie zunächst sicher, dass innodb_buffer_pool_size angemessen eingestellt ist. Wenn das Problem weiterhin besteht, verringern Sie innodb_max_dirty_pages_pct


Danke @Rick für den netten Kommentar. Welcher innodb_buffer_pool_sizeWert gibt an? Tatsächliche Größe oder konfigurierte?
Joker

1
@joker - innodb_buffer_pool_sizegibt die maximale Größe an. In einem typischen Server beginnt der "Pufferpool" klein, wächst jedoch schnell auf diese maximale Größe und bleibt dort. Hinweis: Wenn dies größer als der Arbeitsspeicher (oder sogar knapp) ist, führt dies zu einem Austausch, der für die Leistung furchtbar ist.
Rick James

7

Ihr Titel fragt nach innodb_buffer_pool_size, aber ich vermute, dass dies nicht das eigentliche Problem ist. (Rolando kommentierte, warum Sie es groß genug eingestellt haben, sogar zu groß.)

Ich habe max Connections = 800 gesetzt, die manchmal sättigen und den Server zum Anhalten bringen.

Das ist unklar. 800 Benutzer im "Sleep" -Modus haben praktisch keine Auswirkungen auf das System. 800 aktive Threads wären eine Katastrophe. Wie viele Threads "laufen"?

Blockieren sich die Threads gegenseitig? In SHOW ENGINE INNODB STATUS finden Sie einige Hinweise zu Deadlocks usw.

Werden im Slowlog Fragen angezeigt? Optimieren wir sie.

Welche Version benutzt du? XtraDB (ein Drop-In-Ersatz für InnoDB) bietet eine bessere Möglichkeit, mehrere Kerne zu verwenden. 5.6.7 macht einen noch besseren Job.

innodb_buffer_pool_instances - ändere dies auf 8 (unter der Annahme eines 20G buffer_pool); es wird die Mutex-Konkurrenz leicht einschränken.

Sind Sie E / A oder CPU-gebunden? Die Lösungen unterscheiden sich je nach Ihrer Antwort grundlegend.

SSD - Es ist möglicherweise besser, wenn sich alle Protokolldateien auf Nicht-SSD-Laufwerken befinden.


6

Mehr Speicher ist immer besser, aber meiner Erfahrung nach sollte die Pufferpoolgröße in den meisten Fällen nicht zu Ihrer Datengröße passen. Viele Tabellen sind in den meisten Fällen inaktiv, wie z. B. herumliegende Sicherungstabellen. Daher sollte die Größe des Innodb-Pufferpools eher zu Ihrer aktiven Datengröße passen.

Der Zeitrahmen, den Sie für aktive Seiten festlegen, beeinflusst die Leistung, aber es gibt einen optimalen Punkt, an dem Sie bei einer größeren Puffergröße nicht so viel Leistung erzielen. Sie könnten das schätzen / berechnen / messen durchshow engine innodb status

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.